Assinging inout port to inout in both directions

2.7k Views Asked by At

For simulation purposes, using Verilog, I would like to create a block that only has 2 inout ports (say left and right) and will be transmitting signals either from left to right or from right to left. It can be assumed that the block will be active only during the transition and will be waiting for inputs for the rest of the time. But I'm not allowed to use any other ports. So the module definition will be something like this in theory:

module blackbox(inout left, inout right)
  assign left = right;
  assign right = left;

  specify
    (left => (right:1'b1)) = 7;
    (right => (left:1'b1)) = 8;
  endspecify
endmodule

Is there a solution for this?


As a 2nd question, The problem can be simplified by determining the direction after the placement. For example, if the block placed in one location it will always transmit signal from left to right but in another location it can be from right to left. Would it be possible to somehow code this inside the module?

Thanks,

2

There are 2 best solutions below

4
On BEST ANSWER

In Verilog

module blackbox(inout .left(internal), inout .right(internal));
 wire internal;
  specify
    (left => (right:1'b1)) = 7;
    (right => (left:1'b1)) = 8;
  endspecify
endmodule

or

 module blackbox(inout left, right);
     tran t(left,right); // some simulators might require this to work with specify block
      specify
        (left => (right:1'b1)) = 7;
        (right => (left:1'b1)) = 8;
      endspecify
    endmodule

In SystemVerilog:

 module blackbox(inout left, right)
   alias left = right;
      specify
        (left => (right:1'b1)) = 7;
        (right => (left:1'b1)) = 8;
      endspecify
 endmodule

For your second question, I'm not sure why you would need this for a simulation model, or how you would get placement information into the netlist.

1
On

You should use tri-state signals, just like in real hardware:

assign A_inout = direction_is_A_to_B ? A_out : 1'bz;
assign B_inout = direction_is_A_to_B ? 1'bz  : B_out;

Then you can safely connect A_inout to B_inout;

The input is a copy of A_inout, but it may be clearer to explicitly use a signal:

assign A_in = A_inout;

Normally all that is done inside a bi-directional pad:

module bi_pad (
    inout  P,
    input  I,
    input  tri,
    output O
);

   assign P = tri ? 1'bz : O;
   assign I = P;

endmodule

You can use parameter to determine the direction but you must know when the block is instantiated which direction it must have. There is no feedback from e.g. a place & route tool to do it for you.