1

I'm looking to be able to parametric some behavioral level Verilog using the generate block. The module is for a re-configurable readout and FIFO block, mainly so we can code this up one and just use a parameter at the top level.

Lets say we have:

always @(posedge write_out_clk or posedge RESETN)
 begin
   if (RESETN)          
    SENSE_ADDR <= 0;
   else if (enb[0] == 1)
        SENSE_ADDR <= 1;   // for example but may be some other wire/bus etc
   else if (enb[1] == 2)
        SENSE_ADDR <= 1;   // for example but may be some other wire/bus etc
   else
    SENSE_ADDR <= SENSE_ADDR;
   end
 end

This is behavioral so the specifics of implementation are left to the compiler with user given timing constraints etc. This works for 'n' else-if statements within the block if I hard code them, currently synthesis and simulation are both working for 16 statements.

My question however is how to parameterise this using generate? Clearly if 'n=8' its not too much of a big deal to hard code it. What if 'n=64' or 'n=128' etc. Seems a shame to hard code it if the rest of the module is fully parameterized using the generate for 'n'...

I have tried doing something like:

genvar elseif_generate;
generate
   for (elseif_generate=0; elseif_generate<FIFO_SUB_BLOCKS; elseif_generate=elseif_generate+1)
   begin: elseif_generate_logic
   always @(posedge write_out_clk or posedge RESETN)
    begin
    if (RESETN)
        SENSE_ADDR <= 0;
    else if (enb[elseif_generate] == 1)
        SENSE_ADDR <= some_wire[elseif_generate];
    else
        SENSE_ADDR <= SENSE_ADDR;
    end
   end
endgenerate

This however leads to Multi-source errors for the output wire 'SENSE_ADDR'. This leads me to the further question. Clearly a generate block is not suitable here but how would I go about implementing parameterised code replication for this block? Basically I want the functionality of the behavioral, hard coded if-else always block in a parameterised form...

2 Answers 2

1

Does this serve your needs? No generate required.

module mux #(
        parameter WIDTH = 5,
        parameter NUM   = 2,
        parameter NUMLG = $clog2(NUM)
    ) (
        input [NUMLG -1:0] sel,
        input [WIDTH - 1:0] in [0:NUM-1],
        output [WIDTH - 1:0] out
    );

    assign out = in[sel];

endmodule

If your simulator doesn't support SystemVerilog that well you'll have to modify this to blow out the input array but the concept is the same.

Sign up to request clarification or add additional context in comments.

Comments

1

You don not need a generate block. Add a combination always block to calculate next_SENSE_ADDR that will be flopped to SENSE_ADDR.

always @(posedge write_out_clk or posedge RESETN)
 begin
   if (RESETN)          
    SENSE_ADDR <= 0;
   else
    SENSE_ADDR <= next_SENSE_ADDR;
 end

integer idx;
always @* begin // @(SENSE_ADDR or enb or some_wire)
  next_SENSE_ADDR = SENSE_ADDR; // default, value if enb is all 0
  // count down because lsb has higher priority
  for ( idx=FIFO_SUB_BLOCKS-1; idx>=0; idx-- ) begin
    if ( enb[idx] )
      next_SENSE_ADDR = some_wire[idx];
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.