From: Shalom Bresticker (Shalom.Bresticker@motorola.com)
Date: Tue Nov 18 2003 - 04:20:41 PST
First, thanks.
All the solutions you have given are synthesizable, but probably give less
optimal results.
decoded_mux = selects[i] ? data[i] : decoded_mux;
could also have been written as
if (selects[i]) decoded_mux = data[i] ;
We're starting to try to write paramterized code here,
and we are finding that in some cases Verilog-2001 and SystemVerilog
don't give us enough power to do it as we would like.
Verilog-2001 adds multi-dimensional arrays and generates.
SystemVerilog adds the ability to pass arrays in ports.
But because a generate instantiates only a complete statement,
we are finding ourselves limited and it frustrates us.
This is the difference between the way we defined generates and a true text
pre-processor.
Shalom
Steven Sharp wrote:
> I can see several possible approaches, though I don't know how happy a
> synthesis tool would be with them.
>
> 1. Use a function call on the RHS of the continuous assignment, or use a
> combinational always block, so that you can use a for-loop to do this.
>
> function decoded_mux;
> input [N:1] selects, data;
> integer i;
> begin
> decoded_mux = 1'b0;
> for (i = N; i > 0; i = i - 1)
> decoded_mux = selects[i] ? data[i] : decoded_mux;
> end
>
> assign z = decoded_mux(a, b);
>
> If overwriting the same value repeatedly in the loop is undesirable,
> the function can be rewritten as:
>
> function decoded_mux;
> input [N:1] selects, data;
> reg [N+1:1] mux_outs;
> integer i;
> begin
> mux_outs[N+1] = 1'b0;
> for (i = N; i > 0; i = i - 1)
> mux_outs[i] = selects[i] ? data[i] : mux_outs[i+1];
> decoded_mux = mux_outs[1];
> end
>
>
> 2. Use a generate-for to generate the multiple mux levels required.
> This is similar to the second function above, because it requires
> that each mux have its own separate bit to write its result into.
>
> wire [N+1:1] mux_outs;
> assign mux_outs[N+1] = 1'b0; // The value if all selects are false
>
> generate
> genvar i;
> for (i = 1; i <= N; i = i + 1) begin:muxes
> assign mux_outs[i] = a[i] ? b[i] : mux_outs[i+1];
> end
> endgenerate
>
> assign z = mux_outs[1];
>
> If you wanted to show off, and confuse people, you could replace
> the generate-for with a recursive instantiation (terminated with a
> generate-if).
>
> 3. Use some math tricks to get the desired results. I doubt a synthesis
> tool would produce reasonable results for this, but maybe it would get
> optimized into something good. It relies on the fact that (a & ~(a-1))
> produces a mask containing only the least significant true bit from a.
>
> assign z = a ? |((a & ~(a-1)) & b) : 1'b0;
>
> Since this uses a reduction-OR of an AND with the lowest true bit, it
> will not have identical X behavior to a conditional operator version.
> It will be more pessimistic in some situations.
>
> If you know that the select bits in "a" are mutually exclusive, so that
> you don't need a priority select, this is simpler of course. You just
> need
>
> assign z = |(a & b);
>
> Steven Sharp
> sharp@cadence.com
-- Shalom Bresticker Shalom.Bresticker@motorola.com Design & Reuse Methodology Tel: +972 9 9522268 Motorola Semiconductor Israel, Ltd. Fax: +972 9 9522890 POB 2208, Herzlia 46120, ISRAEL Cell: +972 50 441478
This archive was generated by hypermail 2.1.4
: Tue Nov 18 2003 - 04:16:07 PST
and
sponsored by Boyd Technology, Inc.