简体   繁体   中英

verilog RTL 'case' width defined in a parameter?

I'm using a generate block to create a pipelined mux: Is there a way to parameterize the cases in the case statement?

module  muxNto1byW(
  input                                     clk,
  input                                     reset,
  input   wire[(SELECT_WIDTH-1):0]          select,
  input   wire[(DATA_WIDTH*NUM_INPUTS-1):0] din,
  output  reg[(DATA_WIDTH-1):0]             y
);

/* 4 LUT_WIDTH = 6, SEL DATA_INPUTS = 2 */
parameter SELECT_WIDTH = LUT_WIDTH - DATA_INPUTS; 

...

generate 

/* some for loops */

    //  register this stage's muxes  
    reg[(DATA_WIDTH-1):0] pipelineStage;

    //  assign values to each mux in this stage
    always@(posedge reset or posedge clk)
      if( reset )
        pipelineStage <= {DATA_WIDTH{1'b0}};
      else
      begin
      if( i == 0 )          // Stage 0 evaluates the inputs
        case ( select[(SELECT_BITS_PER_STAGE-1):0] )
          2'b00 : /* do something */
          2'b01 : /* do something different */
          2'b10 : /* you get the picture */
          2'b11 : /* the last case */
        endcase
endgenerate

SELECT_BITS_PER_STAGE in my target technology is 2, so the cases are 2 bits wide 00, 01, 10 , 11

How can write this code so that if a different technology can only implement a 2 to 1 mux, (SELECT_BITS_PER_STAGE == 1), the case statement automatically changes to:

case (    )
 1'b0: /* do something */
 1'b1: /* do something different
endcase

That use of generate does not look very clean, I would take the code you are trying to wrap up and turn it into a sub-module. The generate can then make multiple instantiations of the sub-module and wire them up. The generate can then set parameters as required on instances. This breaks the problem down into the generate and then the module scaling correctly.

How can write this code so that if a different technology can only implement a 2 to 1 mux,

This is a slightly confusing statement to me. Are you referring to changing you RTL based on the libraries available for synthesis? Synthesis will be able to implement you implied logic from available 2 to 1 muxes, combining 3 of them to create a 4 to 1.

RTL should be independent of the library used for synthesis, its portability is an advantage.

If you mean RTL which can have its functionality expanded based on a parameters then I would zero pad the MSBs of select so that the case statement was unaffected, except having unreachable states.

parameter SELECT_BITS_PER_STAGE = 1;
localparam SELECT_MAX_WIDTH     = 2;

localparam SELECT_EXTEND_BY = SELECT_MAX_WIDTH-SELECT_BITS_PER_STAGE;

wire select_ext = { {SELECT_EXTEND_BY{1'b0}}, select};

alway @* begin //just putting case statement in valid syntax
//...
    case ( select_ext )
      2'b00 : /* do something */
      2'b01 : /* do something different */
      2'b10 : /* you get the picture */
      2'b11 : /* the last case */
      default : /* catch all when select larger than 2 bits */
    endcase
//...
end

NB: if you remove the width and base from the case statements they are interpreted as decimal values (probably integer width). Below is valid: I would not normally do this but might make sense in a context where the width of the select can change based on params.

    case ( select_ext )
      0 : /* do something */
      1 : /* do something different */
      2 : /* you get the picture */
      3 : /* the last case */
      default : /* catch all when select larger than 2 bits */
    endcase

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM