EmbDev.net

Forum: FPGA, VHDL & Verilog Newbie question about 'inout'


von Kenny M. (kennym)


Rate this post
useful
not useful
I'm using a vendor provided module which declares it's data bus as 
"inout". The module is defined by the vendor with this module header:
1
module I2C_Top (
2
       SDA,SCL,
3
       Clock,Reset_L,
4
       CS_L, RW_L,INTR_L, 
5
       A0,A1,A2, 
6
       DATA);       
7
8
9
10
// i2c signals
11
inout SDA, SCL;   
12
13
// microprocessor signals
14
input Clock;      // MP clock
15
input Reset_L;      // Reset, active low
16
input A0, A1, A2;     // Address bits for register selection
17
input CS_L;        // Chip select, active low  
18
input RW_L;        // Read/Write, write active low
19
output INTR_L;      // Interrupt request, active low
20
inout [7:0] DATA;    // data bus to/from attached devices (note: Data(7) is MSB


I can't quite figure out how to define a register or wire in my own 
verilog code that uses this module.

If I define as:
reg [7:0] data;
and connect my data to the modules DATA like this:
I2C_Top myI2C(.... .DATA(data))

The I get errors when trying to write to the databus: "concurrent 
assignment to non-net data is not permitted"

If I define as :
wire [7:0] data;
reg [7:0] data_reg;
assign data = data_reg;

Then I get an error during synthesis:
"net data[7] is constantly driven from multiple places"

What's the correct way to use the "DATA" member of the module so I can 
read from it, and write to it?

Sorry if this is such a dumb-ass question, but I'm just trying to get my 
head around the right way to interface to an inout signal in another 
module.

von Lattice User (Guest)


Rate this post
useful
not useful
Kenny Millar wrote:
> I'm using a vendor provided module which declares it's data bus as
> "inout".

Which (i****) vendor?
Modern FPGAs or even ASICs don't have bidirectional signals inside the 
chip, only at the IO cells (pins).

This allows to resolve the multiple assignment issue:
1
assign data = ~rw ? data_reg : 8'bz;

but be aware the the synthesiser tries to resolve it into a multiplexer. 
This may not work in every case.

von Kenny M. (kennym)


Attached files:

Rate this post
useful
not useful
Thanks for the reply.
The vendor is Lattice, the device is MachXO2

Neither 'data' nor 'DATA' in my project appear on any physical pins.
The module that Lattice provides, is declared as shown in my original 
post as:
1
module I2C_Top (SDA,SCL,Clock,Reset_L,
2
       CS_L, RW_L,INTR_L, 
3
       A0,A1,A2, 
4
       DATA);

And in the body of that module as:
1
inout [7:0] DATA;

So my question is, how should I declare the register which connects to 
'DATA' so that sometimes I can write to it, and sometimes I can read 
from it?

I'm not explaining this very well! I will try to attach the Lattice 
datasheet.

The Lattice code is from their library at
http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/IntellectualProperty/ReferenceDesigns/ReferenceDesigns02/I2CBusMaster.aspx


I'm trying to build a simple state machine that will set up the I2C 
Slave address and byte count and the data byte, and then transmit the 
byte. This is all done by placing values on A0,A1,A2 and data on DATA 
and then setting the RW_L and CS_L nets. Once you set it going you 
should then poll the DATA register for a specific bit being set which 
means "done". So sometimes I need to write to DATA and sometimes I need 
to read from it.

I will attach my top module, but unfortunately I can't attach the 
Lattice code because it's licensed (although you can download it all at 
the link I gave above).

My code seems to work up to a point, but I'm not sure I am sampling the 
DATA bit correctly, at state 8'd12 in my code.

von eingast (Guest)


Rate this post
useful
not useful
These are the tristate buffers for the SCL and SDA lines (which are 
required for the I2C bus).
1
assign SCL = SCL_CK ? 1'b0 : 1'bz;
2
3
assign SDA = (SDA_EN_1 | SDA_EN_2 | SDA_EN_3) ? 1'b0 : 1'bz;

If you have all the source code you can always dig down in "MPU_to_I2C" 
and remove the tristate buffer there. Then move up a data_in and 
data_out through the hierarchy to avoid having tristate at all in the 
DATA line.

von Kenny M. (kennym)


Rate this post
useful
not useful
Thank you - I think I am getting somewhere now.

von Lattice User (Guest)


Rate this post
useful
not useful
Kenny Millar wrote:
> Thanks for the reply.
> The vendor is Lattice, the device is MachXO2
>

RD1005 is a sample to implement an I2C Device to be connected and 
controlled by an external µC.

But since it is provided as source you can easily change it to separate 
in and out data lines.

But instead you can also use RD1046 instead, (a Wishbone based 
implementation).

Another option is to use the hard I2C block of the MachXO2.

von Kenny M. (kennym)


Rate this post
useful
not useful
Thanks again.
Yes I looked at the wishbone implementation, but I was hoping to make 
the simplest possible implementation.

The EFB can only be accessed via Wishbone, I think.

von Lattice User (Guest)


Rate this post
useful
not useful
Kenny Millar wrote:
> Thanks again.
> Yes I looked at the wishbone implementation, but I was hoping to make
> the simplest possible implementation.

Wishbone only sounds complicated, it is quite simple.
RD1046 has also the advantage of being a single HDL language, you can 
choose either Verilog or VHDL.

RD1005 is mainly VHDL with a Verilog wrapper and requires a mixed 
language environment. So far only Lattice provides this in the "free" no 
cost version.

The place to convert from single inout data bus to separate in and out 
busses is burries in a VHDL module.

>
> The EFB can only be accessed via Wishbone, I think.

Yes.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.