9
\$\begingroup\$

I'm wanting eventually to interface some memory to my fpga. This will require pins on the fpga that can both read data and write output to the ram.

I'm far away from doing any of that yet, but as a learning exercise wanted make a simple module in verilog that when a direction signal is '1' output a signal to a pin, and when it is '0' reads a value from that pin.

But I can't get anything to compile. I'm not completely inexperienced with verilog but feel I'm missing something fundamental here rather than just having a simple typo in my example.

This code doesn't compile, I'm looking for either how to make it work, or even just a pointer to what I'm fundamentally missing to make bidirectional signals work. If it matters I'm using xilinx tools and plan to synthesize this to an xc3s50 or similar.

// This doesn't compile...
module test(
    input  clock,           // The standard clock
     input  direction,  // Direction of io, 1 = set output, 0 = read input
     input  data_in,        // Data to send out when direction is 1
     output data_out,       // Result of input pin when direction is 0
     inout  io_port     // The i/o port to send data through
     );

always @(posedge clock)
begin

    // If direction is 1 then set 
    if (direction == 1)
    begin
        io_port <= data_out;
    end

    if (direction == 0)
    begin
         data_in <= io_port;
    end
end

endmodule

edit The errors I get are -

ERROR:HDLCompilers:247 - "test.v" line 16 Reference to scalar wire 'io_port' is not a legal reg or variable lvalue
ERROR:HDLCompilers:106 - "test.v" line 16 Illegal left hand side of nonblocking assignment
ERROR:HDLCompilers:247 - "test.v" line 21 Reference to scalar wire 'data_in' is not a legal reg or variable lvalue
ERROR:HDLCompilers:106 - "test.v" line 21 Illegal left hand side of nonblocking assignment
\$\endgroup\$

1 Answer 1

11
\$\begingroup\$

Inouts are actually "wire" so you can't use any procedural/sequential assignments (where the left hand side must be a reg). Generally speaking:

  • input : internally must always be of type net, externally the inputs can be connected to a variable of type reg or net.
  • output : internally can be of type net or reg, externally the outputs must be connected to a variable of type net.
  • inout : internally or externally must always be type net, can only be connected to a variable net type.

A common approach is to have an "enable" signal for the output of your inout, and to drive to high impedance if the output is not enabled. In your case direction is playing that role.

So try this instead:

module test(
    input  clk,      // The standard clock
    input  direction,  // Direction of io, 1 = set output, 0 = read input
    input  data_in,    // Data to send out when direction is 1
    output data_out,   // Result of input pin when direction is 0
    inout  io_port     // The i/o port to send data through
    );

    reg a, b;    

    assign io_port  = direction ? a : 1'bz;
    assign data_out = b;

    always @ (posedge clk)
    begin
       b <= io_port;
       a <= data_in;
    end

endmodule

The hardware corresponding to the above code would look something like this:

enter image description here

\$\endgroup\$
5
  • \$\begingroup\$ Ah I see. Thank you.I completely forgot about z states. Although this will always set data_in to be the data I'm sending won't it and not the value of the pin? \$\endgroup\$ Commented Jun 3, 2012 at 18:15
  • \$\begingroup\$ @JohnBurton I changed the verilog to be a little more like I think what you were going for. \$\endgroup\$
    – vicatcu
    Commented Jun 3, 2012 at 18:19
  • \$\begingroup\$ The updated code (and picture) will pass io_port to data_out when direction is low and will pass data_in to io_port (and data_out one cycle later) when direction is high. \$\endgroup\$
    – vicatcu
    Commented Jun 3, 2012 at 18:38
  • \$\begingroup\$ what software are u using to produce that synthesis output? \$\endgroup\$
    – sybreon
    Commented Jun 4, 2012 at 0:49
  • \$\begingroup\$ @sybreon heh, I just used Eagle schematic capture to hack a drawing together. \$\endgroup\$
    – vicatcu
    Commented Jun 4, 2012 at 1:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.