0
\$\begingroup\$

I am trying to create an n-bit barrel shifter using the diagram in the answer to this question: https://stackoverflow.com/questions/26551049/vhdl-n-bit-barrel-shifter

I've read that if the variable in a for loop has a single name, then each loop iteration has a separate scope and a separate variable; however, I'm not sure whether the rows in my barrel module will be created in the same style as the reference diagram from above. This is my barrel module:

module barrel
 #(parameter n = 8; parameter control = $clog2(n))
 (input logic[n-1:0] data, input logic [control-1:0] select,
 output logic [n-1:0] result);
 for(genvar i = 0; i < control; i++) begin : label
 logic [n-1:0] tempResult;
 always_comb
 if(i == 0) row #(n,2**i) shiftLevel(data,select[i],tempResult);
 else if(i == control-1) row #(n,2**i) shiftLevel(label[i-1].shiftLevel.tempResult,select[i],result);
 else row #(n,2**i) shiftLevel(label[i-1].shiftLevel.tempResult,select[i],tempResult);
 end
endmodule

My question is this: will the labeled for loop preserve the row modules that I create in each iteration? Or does each row get destroyed once the iteration finishes?

Here are the other modules that I'm using to implement this:

row module:

module row
 #(parameter n=8, parameter shift=4) // n is the number of bits
 // shift is the max amount of shift at this level
 (input logic [n-1:0] data,
 input logic select,
 output logic [n-1:0] end);
 for(genvar i = 0; i < n; i++) begin : label
 logic [1:0] dataTemp;
 always_comb
 dataTemp[0] <= data[i]; // 0 option of the mux is set to the normal data value
 if(i+shift < n) dataTemp[1] <= data[i+shift]; // assigns the shifted bit
 else dataTemp[0] <= 0; // assigns 0
 mux2 bit(dataTemp,select,end[i]); // Assembles a mux for a bit of the row output
endmodule

2-1 Mux module:

module mux2(input logic [1:0] data, select,
 output logic y);
 assign y = select ? data[1] : data[0];
endmodule
asked Nov 27, 2014 at 17:27
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The SystemVerilog generate statements are elaborated at compile time, they are not procedural code. That means they are processed much like a macro or `ifdef statement, except that they can evaluate parameters, understand scope, and create new scopes. You need to get rid of the always_comb construct. The if/else if/else is also a generated block that produces only one row instance per iteration. Assuming n=8, then you will get three generated for-loop blocks named label[0], label[1], and label[2]. Your code get elaborated as if you could have written something like the following(assuming n gets overridden to 16.:

module barrel
 #(parameter n = 8; parameter control = $clog2(n))
 (input logic[n-1:0] data, input logic [control-1:0] select,
 output logic [n-1:0] result);
 logic [n-1:0] logic[0].tempResult;
 logic [n-1:0] logic[1].tempResult;
 logic [n-1:0] logic[2].tempResult;
 row #(n,1) logic[0].shiftLevel(
 data,select[0],label[0].tempResult);
 row #(n,2) label[1].shiftLevel(
 label[0].tempResult,select[1],label[1].tempResult);
 row #(n,4) label[1].shiftLevel(
 label[1].tempResult,select[2],label[2].tempResult);
 row #(n,8) label[3].shiftLevel(
 label[2].tempResult,select[3],result);
endmodule

Note that you could not declare identifiers (the variable names or the module instance names) with the label[x]. prefix without using the generate block construct.

Greg
4,4881 gold badge23 silver badges32 bronze badges
answered Nov 28, 2014 at 20:30
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.