Pregunta

In a generate loop, you often need to connect the first iteration of wires to your inputs (or some unique set of wires) before the array stuff kicks in. Pasted below is a snippet from my parameterizable OR-Reduce module (my assignment requires structural verilog, so oOUt = |adjA is not legal).

for(i=0; i<depth; i=i+1) begin : lvl
  localparam iWidth = p2Width>>i;
  localparam oWidth = iWidth>>1;
  wire [oWidth-1:0] tmp;
  if(i==0) begin
    or2$ reduce [oWidth-1:0]
      (tmp, adjA[iWidth/2-1:0], adjA[iWidth-1:iWidth/2]);
  end else begin
    or2$ reduce [oWidth-1:0]
      (tmp, lvl[i-1].tmp[iWidth/2-1:0], lvl[i-1].tmp[iWidth-1: iWidth/2]);
  end
end

I have to put this nasty if-statement to catch the first iteration and connect it to the inputs. The problem is that I can't just change the initial i value to 1 and declare a lvl[0].tmp outside of the for-loop. Here's what I think would look nicer if it were legal.

wire [p2Width-1] lvl[0].tmp;
or2$ reduce [oWidth-1:0]
  (lvl[0].tmp, adjA[iWidth/2-1:0], adjA[iWidth-1:iWidth/2]);
for(i=1; i<depth; i=i+1) begin : lvl
  localparam iWidth = p2Width>>i;
  localparam oWidth = iWidth>>1;
  wire [oWidth-1:0] tmp;
  or2$ reduce [oWidth-1:0]
    (tmp, lvl[i-1].tmp[iWidth/2-1:0], lvl[i-1].tmp[iWidth-1: iWidth/2]);
end

Is there a way to clean up my generate loop?

¿Fue útil?

Solución

You can declare your input array to be one entry wider than required. I find this often results in more readable code:

logic [N_LEVELS:0]      block_inputs;     // Last entry not used, optimised away
logic [N_LEVELS-1:0]    block_outputs;

// Start of pipeline
assign block_inputs[0] = stage1_input;

genvar i;
generate
for (i=0; i<N_LEVELS; i++) begin: levels
    some_block i_some_block (
        .data       (block_inputs[i]),
        .result     (block_outputs[i])
    );

    assign block_inputs[i+1] = block_outputs[i];
end
endgenerate

assign final_result = block_outputs[N_LEVELS-1];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top