Is there a way in Verilog or SystemVerilog to insert generate statement inside case statement to generate all the possible input combinations. For example a typical use case would be for a N:1 mux.
case(sel)
generate
for(i = 0; i < N; i += 1)
i: out = q[i];
endgenerate
endcase
I tried this, but the tool gives error. An alternate syntax is available which is
out <= q[sel];
But, my tool is not understanding this(the mux is fully decoded) and generating combinational loops. I can use if statement to get the expected mux. But, I was wondering if there was a better way to do it.
You can't mix a for and a case like that. If you're just trying to write a multiplexer, have a look at this older question: How to define a parameterized multiplexer using SystemVerilog
The only difference there is that the select signal is supposed to be onehot encoded. For your case you would have:
always_comb begin
out = 'z;
for (int i = 0; i < N; i++) begin
if(sel == i)
out = q[i];
end
Related
I want to be able to create a shift from right to left everytime I press a button, but my simulation says my bits is not shifting.
this is the code I wrote:
module Sipo(KEY0, qIN, qOUT, LEDsipo);
input KEY0;
output reg [5:0] qIN;
output reg [5:0] qOUT;
output [6:0] LEDsipo;
assign LEDsipo[0] = qIN[0];
assign LEDsipo[1] = qIN[1];
assign LEDsipo[2] = qIN[2];
assign LEDsipo[3] = qIN[3];
assign LEDsipo[4] = qIN[4];
assign LEDsipo[5] = qIN[5];
assign LEDsipo[6] = KEY0;
always #(KEY0) begin
if (KEY0 == 1)
qIN = 6'b000000;
qOUT[0] <= KEY0;
qOUT[1] <= qOUT[0];
qOUT[2] <= qOUT[1];
qOUT[3] <= qOUT[2];
qOUT[4] <= qOUT[3];
qOUT[5] <= qOUT[4];
if (qOUT == 7'b111111)
qOUT[0] = 0;
qOUT[1] = 0;
qOUT[2] = 0;
qOUT[3] = 0;
qOUT[4] = 0;
qOUT[5] = 0;
qIN = qOUT;
end
endmodule
The result I got in the simulation is that LEDsipo[0] was responding to KEY0, but the rest of the LEDsipo was not. I don't see why my bits are not shifting.
It is dificult to test your code without a testbench, which you have not provided, but I thik that you rissue is an extra exposure to python.
Verilog does not understand indentation as scope indicators and requires begin/end to indicats scopes. So, my guess is that you have at least several issues:
missing begin/end: if (KEY0 == 1) begin...end
incorrect mix of non-blocing/non-blocking assignments mix
Incorrect coding of your latch
bad use of veriog syntax
so, though it is corret, you can avoid using separate bits:
assign LEDsipo[6:0] = {KEY0, qIN[5:0]};
do not use sensititivity lists in the latch, it will not synthesize correctly in your case. Use always #* instead. Well, and begin/end.
I do not know why you need qIn, but it makes no sense to initialize it to 0 in the first place. Also, it is not a part of the latch and should be moved out of the always block.
always #* begin
if (KEY0 == 1) begin // need begin/end for multiple statements
// qIN <= 6'b000000; -- why do you need it?
qOut[5:0] <= {qOut[4:0], KEY0};
if (qOUT == 7'b111111) // can omit begin/end for a single statement
qOut <= 6'b0;
end
end
assign qIn = qOut;
Since you have not provide any testbench, I did not test the code.
I will give a small snippet of what I mean:
input [31:0] for_terminate;
for(i = 0; i < for_terminate; i = i + 1)
....
Clearly, this is a small piece of code, but I think it illustrates my idea. Is this possible?
I assume you actually ask: can this be synthesized. The answer is NO.
A for loop is unrolled in compile time. (See also here ) As such the start, increment and end value must be known when you compile. This also means it is good practice to limit your for loop range. The following code is legal, can be synthesized, but will not fit in your FPGA or ASIC:
for (i=0; i<4294967296; i=i+1)
begin
// Make some logic
...
You can make the equivalent with an if:
for (i=0; i<MAXIMUM_LOOP; i=i+1)
begin
if (i<for_terminate)
begin
...
The logic for all MAXIMUM_LOOP cases will be generated, but each will have a condition which checks the value of for_terminate. Seeing that your for_terminate is 32 bits wide, I think you should limit that somewhat.
I would like to know more information about Generate statements I know that you can replicate modules, and always blocks (like in the other post) but,
Would it be possible to create a parametrized case like this?
always # (negedge clk)
begin
if (state==1)
begin
case(CS_sel)
begin
generate
genvar i;
for (i=0; i<N_DACS; i=i+1)
begin: for1
i:begin
num <= mod_in[(i+1)*BITS-1:i*BITS];
div <= mod_out[(i+1)*BITS-1:i*BITS];
end // i:
end // for1
endgenerate
default: begin
num <= mod_in[BITS-1:0];
div <= mod_out[BITS-1:0];
end // default
end // case (CS_sel)
endcase // case (CS_sel)
end // if (state==1)
end // always
First of all, I would like to know if this is possible and how could I do it,
After this, if you know another option to create a synchronous multiplexer in verilog, it would be great!
Thank you!
The generate block cannot be used inside a always block but have to be placed outside. So one has actually the possiblity to build multiple different always block and chose between them via generate if constructs.
But just by looking at the given code I suggest the use of a different approach using proper slicing with fixed width and flexible offset:
if(CS_sel < N_DACS) begin
num <= mod_in[BITS*CS_sel +:BITS];
div <= mod_out[BITS*CS_sel +:BITS];
end else begin
//default stuff
num <= mod_in[BITS-1:0];
div <= mod_out[BITS-1:0];
end
This works because it is effectively similar to
wire [BITS-1:0] subset0;
assign subset0 = mod_in >> (BITS*CS_sel);
[...]
num <= subset0[BITS-1:0];
The direct use of something like mod_in[(i+1)*BITS-1:i*BITS] is not possible as this would theoretically allow for flexible width which (standard) verilog does not support by now to the best of my knowledge.
I have following code snippet where a temp variable is used to count number of 1s in an array:
// count the number 1s in array
logic [5:0] count_v; //temp
always_comb begin
count_v = arr[0];
if (valid) begin
for (int i=1; i<=31; i++) begin
count_v = arr[i] + count_v;
end
end
final_count = count_v;
end
Will this logic create a latch for count_v ? Is synthesis tool smart enough to properly synthesize this logic? I am struggling to find any coding recommendation for these kind of scenarios.
Another example:
logic temp; // temp variable
always_comb begin
temp = 0;
for (int i=0; i<32; i++) begin
if (i>=start) begin
out_data[temp*8 +: 8] = in_data[i*8 +: 8];
temp = temp + 1'b1;
end
end
end
For any always block with deterministic initial assignment, it will not generate latch except logic loop.
Sorry Eddy Yau, we seem to have some discussions going on regarding your post.
Here is some example code:
module latch_or_not (
input cond,
input [3:0] v_in,
output reg latch,
output reg [2:0] comb1,
output reg [2:0] comb2
);
reg [2:0] temp;
reg [2:0] comb_loop;
// Make a latch
always #( * )
if (cond)
latch = v_in[0];
always #( * )
begin : aw1
integer i;
for (i=0; i<4; i=i+1)
comb_loop = comb_loop + v_in[i];
comb2 = comb_loop;
end
always #( * )
begin : aw2
integer i;
temp = 7;
for (i=0; i<4; i=i+1)
temp = temp - v_in[i];
comb1 = temp;
end
endmodule
This is what came out if it according to the Xilinx Vivado tool after elaboration:
The 'latch' output is obvious. You will also notice that temp is not present in the end result.
The 'comb_loop' is not a latch but even worse: it is a combinatorial loop. The output of the logic goes back to the input. A definitely NO-NO!
General rule: if you read a variable before writing to it, then your code implies memory of some sort. In this case, both the simulator and synthesiser have to implement storage of a previous value, so a synthesiser will give you a register or latch. Both your examples write to the temporary before reading it, so no storage is implied.
Does it synthesisie? Try it and see. I've seen lots of this sort of thing in production code, and it works (with the synths I've used), but I don't do it myself. I would try it, see what logic is created, and use that to decide whether you need to think more about it. Counting set bits is easy without a loop, but the count loop will almost certainly work with your synth. The second example may be more problematical.
I am try to generate some conditions in a case statement in Verilog.
I have a parameter known as MANT_WIDTH and the number of conditions in the case statement depends on the value of MANT_WIDTH
for example I have
always #(*) begin
case (myvariable)
{MANT_WIDTH{1'b1}}:
begin new_variable = {1'b0, {MANT_WIDTH{1'b1}}}; end
genvar n;
generate
for (n = 2; n <= MANT_WIDTH-1; n = n+1) begin: NORMALIZE
{(MANT_WIDTH-n){1'b0}},{n{1'b1}}}:
begin new_variable = {{n{1'b1}},1'b0;
end
endgenerate
default:
begin new_variable = {(MANT_WIDTH+1){1'b0}}; end
endmodule
end
there might be some conditions in this code that don't make sense (incorrect bit widths, etc.) but the gist of what I am trying to do is here.
The problem I am having is that I am getting the following errors when I try to simulate this code using ncverilog:
for (n = 2; n <= MANT_WIDTH-1; n = n+1) begin: NORMALIZE
|
ncvlog: *E, ILLPRI (fpmodule.v,278|6): illegal expression primary [4.2(IEEE)]
also I get illegal lvalue syntax [9.2[IEEE)]
I need to count leading zeros. I didn't actually paste my real code, I just need some way to count leading zeros, but I have a few special cases that will have to put outside of a for loop.
THANK YOU SO MUCH!
It is not legal to use a generate in an always block. They are only valid in the module declaration scope.
module;
//Valid here
endmodule
I have a parameter known as MANT_WIDTH and the number of conditions in
the case statement depends on the value of MANT_WIDTH
There is no way to directly control the number of case statements using a parameter.
I can't tell what you're trying to calculate(new_variable = {myvariable,1'b0}?) but rarely do you need generate loops to achieve a shift of some sort nor does it look like you need leading zeros here.
I resorted to using the following compiler directives:
`ifdef
`else
`endif
So therefore I could define a block a code as such:
`define MYMACRO 1;
`ifdef MYMACRO
// some code
`else
`ifdef ANOTHERMACRO
// different code
`endif
`endif