4

Say I instantiate a parametrized number instances in an array and each of these instances produces an 8-bit output value if it is selected. What would be the best way to wire these outputs together?

I currently use tri-state buffers as in the following example:

module foo(output wire [7:0] out);
parameter N = 4;
bar bars[0:N-1] (.out(out));
endmodule

module bar(output wire [7:0] out);
wire selected = ...;
wire [7:0] value = ...;
assign out = selected ? value : 8'bz;
endmodule

Here the logic ensures the selected signal will be 1 for one and only one instance.

This all works fine in the simulator as well as in an FPGA. However, since I get warnings about this construct while synthesizing and, as I understand, Xilinx removed internal tri-state buffers in newer FPGAs, I was wondering what the preferred way is to connect these output buses together.

I was thinking about changing the output assignment to

assign out = selected ? value : 8'b0;

and then OR-ing the outputs together. However, I'm not sure how to do this since the size of the OR-gate depends on a parameter.

mtvec
  • 210
  • 2
  • 11
  • 1
    A mux circuit is the best solution to the BUS problem. – Michael Karas Jun 24 '13 at 12:44
  • @MichaelKaras: You're right. The only problem with that approach is that, in my example, module `foo` should know about all the `selected` signals from the instantiations of `bar` to be able to implement the MUX. I was hoping to not have to route these signals outside of `bar`. – mtvec Jun 24 '13 at 13:02
  • Maybe you can pass in an address bus upon which the selection is made. That bus input could be more than wide enough to cover all the possible selects that you would need. – Michael Karas Jun 24 '13 at 13:31

2 Answers2

2

Purely answering how to create a parametrised width zero. hopefully another answer can cover the best practise for multiple drivers.

localparam DATA_W = 8;
i = {8{'1b0}} ;

or

i = 'b0 ; //RHS width is matched to LHS, early version limited to 32bits

or

i = '0;  //Introduced in 2012 SystemVerilog simplest way to x every bit : 'x
pre_randomize
  • 1,180
  • 6
  • 11
1

You don't mention the synthesis tools you are using, I'm basing this on Quartus II.

When you use tri-state buses internal to the design, they are eliminated to suite the bi-state logic available. The tools push along the output-enable bit and add both rx and tx versions of the signal if required, then insert muxes at appropriate interconnect points. You probably get warnings if it's possible for multiple drivers to occur, since the resolution of priority in that case is indeterminate.

I would consider it poor design to rely on this behaviour for internal logic connections. Sadly to replace this you have no choice but to add the hi-z/driving signal explicitly to the interface between foo and bar and do the muxing yourself.

When you use tri-state logic over device pin, the oe/rd/wr signals are routed out the design to the IO banks where true tri-state drivers are available.

shuckc
  • 3,012
  • 14
  • 19