Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] How to use bidirectional IO, need it for I2C?

Status
Not open for further replies.

kenleigh

Member level 1
Joined
Jan 3, 2011
Messages
36
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
1,525
I am trying to implement something similar to an I2C master on the Spartan 6.
My questions are

1. Is there any reference implementation of a I2C master in Verilog by Xilinx or any third party?

2. In the unlikely event that there isn't such an implementation and I have to dish out my own, how do I configure a pin to behave bidirectional and sometimes configure it as input and sometimes as output.
Any idea out to do it in Verilog?
 
Last edited:

you can declare a pin as inout and try it.
 

I suppose you have to place the three-state buffer between the transmitter and the line itself. When you are about to receive, you merely disconnect the transmitter by forcing it's output to 'Z'. The receiver doesn't need this, it would be always connected.
Correct me if I'm wrong, please.
 

I suppose you have to place the three-state buffer between the transmitter and the line itself. When you are about to receive, you merely disconnect the transmitter by forcing it's output to 'Z'. The receiver doesn't need this, it would be always connected.
Correct me if I'm wrong, please.


The current module declaration is something like this

Code:
module i2cwrite(
 input rst,
 input clk,
 input [7:0] data,
 output scl,
 ??? sda
)
 //body here
endmodule

do I need to do something like this

Code:
inout sda

to make sda bidirectional?

Once I make it bidirectional how to set it as input?

will something like this make it an input?

Code:
sda <= 1'bz; //put sda in high impedance mode
 

The current module declaration is something like this

do I need to do something like this

Code:
inout sda

to make sda bidirectional?
Yes, something like that. I don't quite remember Verilog, but I think there is "inout" port direction specifier.

Once I make it bidirectional how to set it as input?

will something like this make it an input?

Code:
sda <= 1'bz; //put sda in high impedance mode
Yes. In a transmitter module.
The line is not input or output. It's just a line. It hase some voltage you can read from it. You can also try to set voltage on it (with a transmitter), but it can lead to a kind of short circuit if another transmitter is active on the line.
By making your transmitter's output 'Z' you effectively disconnect it to let transmitter on the other end work.
 

When I do something like

"inout sda"

The hdl compiler flags an error saying cannot

"Non-net port sda cannot be of mode inout"

Any idea why this error is occurring?


Another point is I want to make "sda" as an input so that I can read the data sent by the data sent by the slave on the same line. By I haven't any clue of how to read the sda into a reg inside the FPGA?
 
Last edited:

When I do something like

"inout sda"

The hdl compiler flags an error saying cannot

"Non-net port sda cannot be of mode inout"

Any idea why this error is occurring?
I'm gonna need to search the Internet. Like I said, don't remember Verilog. Obviously, you need to declare this line as a net, but I don't remember the exact syntax.

Another point is I want to make "sda" as an input so that I can read the data sent by the data sent by the slave on the same line. By I haven't any clue of how to read the sda into a reg inside the FPGA?
You can read the line anytime you want. Just connect it to the input of your module and do what you want to do.
 

You are talking now about basic Verilog syntax issues rather than I2C related questions.
"Non-net port sda cannot be of mode inout"
Means the pin is not connected correctly in the design.
how to read the sda into a reg inside the FPGA?
by an assignment, e.g. xx <= sda
Referring to your original questions, you'll find various I2C master designs on the internet, e.g. from opencores.org. But they tend to be more complex than you'll need for a basic interface, I fear. In any case, you should have a good Verilog text book or compiler manual at hand. If you're working with Xilinx, the Synopsys Verilog HDL compiler manual is very detailed and a good tutorial, I think.
 
You are talking now about basic Verilog syntax issues rather than I2C related questions.

Means the pin is not connected correctly in the design.

Any idea, how to solve this?
 

Post the code of your module

This is the skeleton of the module.

Code:
module i2cwrite(
 input rst,
 input clk,
 input [7:0] data,
 output scl,
 output sda
)

	reg   sda;
	reg   scl;

 //other variables

 //body here

endmodule

Now if I change the line "output sda" to "inout sda" I get the error.
 

Because it's "reg". Should be wire.

After changing

"reg sda" to "wire sda"

I get errors

"Procedural assignment to a non-register <sda> is not permitted." at locations where data is being assigned to sda.

For instance sda <= 1;
 

By Verilog specification, inout must be of the net_type, which in this case means wire, not register. Some Verilog compilers however accepts also regs for inout.

Your port declaration style is somewhat unusual, ether all, or no parameters of each pin are expected to be defined in the port list.

P.S.:
After changing
"reg sda" to "wire sda"
I get errors
sda has to assigned primarly by a conditional assignment, something like
Code:
assign sda = (sda_reg)?1'b0:1'bz;
or an equivalent conditional assignment used in an always block.
please consider, that I'm mostly using VHDL and not very familiar to Verilog
 
Last edited:

Your port declaration style is somewhat unusual, ether all, or no parameters of each pin are expected to be defined in the port list.

I'm sorry, I didn't get what you meant to say here.
 

Your port declaration style is somewhat unusual, ether all, or no parameters of each pin are expected to be defined in the port list.
As I was taught in the university, there are two styles of Verilog module declaration: an "old" one and a "new" one. They differ by the style of ports declaration. As far as I know, both types are supported by most, if not all, modern compilers.
 

Your style is corresponding to neither of them. According to the "new" style, the reg goes into the port declaration list.

Code:
 output reg scl,
 output reg sda
 

As I was taught in the university, there are two styles of Verilog module declaration: an "old" one and a "new" one. They differ by the style of ports declaration. As far as I know, both types are supported by most, if not all, modern compilers.

What is the old style and what is new? Any examples of each or any reference would help?

---------- Post added at 17:51 ---------- Previous post was at 17:51 ----------

Your style is corresponding to neither of them.

What is the right style?
 

Your style is corresponding to neither of them. According to the "new" style, the reg goes into the port declaration list.

Code:
 output reg scl,
 output reg sda
Hm, you are right. Apparently, some compilers allow mixing...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top