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:
module I2C_Top (
// i2c signals
inout SDA, SCL;
// microprocessor signals
input Clock; // MP clock
input Reset_L; // Reset, active low
input A0, A1, A2; // Address bits for register selection
input CS_L; // Chip select, active low
input RW_L; // Read/Write, write active low
output INTR_L; // Interrupt request, active low
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 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
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:
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.
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
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
I'm not explaining this very well! I will try to attach the Lattice
The Lattice code is from their library at
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.
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
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
Another option is to use the hard I2C block of the MachXO2.
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
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.