Re: parametric code question

From: Shalom Bresticker (Shalom.Bresticker@motorola.com)
Date: Tue Nov 18 2003 - 04:20:41 PST

  • Next message: Steven Sharp: "Re: parametric code question"

    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.