When I try to synthesize my verilog project i get the following errors:
ERROR:Xst:2634 - "shiftman.v" line 15: For loop stop condition should depend on loop variable or be static.
ERROR:Xst:2634 - "shiftman.v" line 22: For loop stop condition should depend on loop variable or be static.
I think I understand what causes the error, but I can't find a way to fix it.
module shiftman(in,sh,out);
input[47:0] in;
input[8:0] sh;
output[47:0] out;
reg[47:0] out;
reg[7:0] r;
reg i;
always#(in or sh)
begin
r=sh[7:0];
out=in;
if(sh[8]==0)
for(i=0; i<r; i=i+1)
begin
out[23:0]={1'b0,out[23:1]};
end
else
for(i=0; i<r; i=i+1)
begin
out[47:24]={1'b0,out[47:25]};
end
end
endmodule
The reason your synthesis is failing is because you cannot uses variable-iteration loops in synthesizable code. When synthesizing, the tool will attempt to unroll the loop, but it cannot do this if the termination condition for the loop is not static or determinable at synthesis. Your condition i <= r is such a condition as we cannot unroll the loop without knowing r, which is an input to the module and thus, not static.
In order to fix this, youll need to rewrite your code in a way that the synthesis tool can process. By the looks of it, you are simply logically shifting either the top or bottom of in by sh[7:0] depending on sh[8]. In order to do this, you don't need looping at all, but can use the >> (logical right shift operator). So, your always block would look more like this:
always #(*) begin
out = in;
if (sh[8])
out[47:24] = in[47:24] >> sh[7:0];
else
out[23:0] = in[23:0] >> sh[7:0];
end
Related
First of all, sorry for my English skills.
I am studying Verilog and I have this code
module paralelo_serie ( data_in,clk, D_serie, nSyn, Done );
input wire [12:0] data_in;
input clk;
output reg D_serie, nSyn, Done;
genvar i;
84 if (data_in == 0) Done= 1;
else....
When I try to compile this code, I get this error message:
Error: (vlog-13069) C:/Users/Pedro/Documents/master/asignaturas/primer cuatrimestre/Metodologia de diseño y herramientas cad/proyecto digital/proyecto digital.v(84): near "=": syntax error, unexpected '='.
Error: C:/Users/Pedro/Documents/master/asignaturas/primer cuatrimestre/Metodologia de diseño y herramientas cad/proyecto digital/proyecto digital.v(84): (vlog-13205) Syntax error found in the scope following 'Done'. Is there a missing '::'?
I am a beginner at this language and I don't know what happened. I get this error a few times in the code, but I can solve it sometimes by changing the reg to wire and other time change blocking assignment to no blocking... I don't really know how I can fix and really I am getting frustrated... please help, you are my last hope...
Sorry I forgotten, I use modelsim 10.4 student version
AS toolic has mentioned the 84 looks like it was just an accidental cut and paste from your code.
If statements, unless they are for the generate statement need to be contained with in a process ( some call it a block ). This can be an initial or an always.
For combinatorial logic :
always #* begin
if (data_in == 0) begin
Done = 'b1;
end
else begin
Done = 'b0;
//...
end
end
Not defining Done in the else branch will result in a latch being created.
While learning I would recommend using begin end statements and indenting code well as this helps clarify the structure of code and makes typos a bit easier to spot.
If Done was left as a wire you could just have used:
assign Done = (data_in == 0) ;
On the other hand if you wanted Done to be driven synchronously :
always #(posedge clk) begin
if (data_in == 0) begin
Done <= 'b1;
end
else begin
//...
end
end
Note the change to non-blocking (<=) assignments to correctly simulate a flip-flops behaviour. As Done is a full flip flop (stateful) then there is no need for the synthesis tool to add a latch if it is not specified in the else branch, it will just retain its value.
I am trying to write an "inverter" function for a 2's compliment adder. My instructor wants me to use if/else statements in order to implement it. The module is supposed to take an 8 bit number and flip the bits (so zero to ones/ones to zeros). I wrote this module:
module inverter(b, bnot);
input [7:0] b;
output [7:0]bnot;
if (b[0] == 0) begin
assign bnot[0] = 1;
end else begin
assign bnot[0] = 0;
end
//repeat for bits 1-7
When I try and compile and compile it using this command I got the following errors:
vcs +v2k inverter.v
Error-[V2005S] Verilog 2005 IEEE 1364-2005 syntax used.
inverter.v, 16
Please compile with -sverilog or -v2005 to support this construct: generate
blocks without generate/endgenerate keywords.
So I added the -v2005 argument and then I get this error:
vcs +v2k -v2005 inverter.v
Elaboration time unknown or bad value encountered for generate if-statement
condition expression.
Please make sure it is elaboration time constant.
Someone mind explaining to me what I am doing wrong? Very new to all of this, and very confused :). Thanks!
assign statements like this declare combinatorial hardware which drive the assigned wire. Since you have put if/else around it it looks like you are generating hardware on the fly as required, which you can not do. Generate statements are away of paramertising code with variable instance based on constant parameters which is why in this situation you get that quite confusing error.
Two solutions:
Use a ternary operator to select the value.
assign bnot[0] = b[0] ? 1'b0 : 1'b1;
Which is the same as assign bnot[0] = ~b[0].
Or use a combinatorial always block, output must be declared as reg.
module inverter(
input [7:0] b,
output reg [7:0] bnot
);
always #* begin
if (b[0] == 0) begin
bnot[0] = 1;
end else begin
bnot[0] = 0;
end
end
Note in the above example the output is declared as reg not wire, we wrap code with an always #* and we do not use assign keyword.
Verliog reg vs wire is a simulator optimisation and you just need to use the correct one, further answers which elaborate on this are Verilog Input Output types, SystemVerilog datatypes.
I am completely new to verilog and I have to know quite a bit of it fairly soon for a course I am taking in university. So I am play around with my altera DE2 board and quartis2 and learning the ins and outs.
I am trying to make a counter which is turned on and off by a switch.
So far the counter counts and resets based on a key press.
This is my error:
Error (10119): Verilog HDL Loop Statement error at my_first_counter_enable.v(19): loop with non-constant loop condition must terminate within 250 iterations
I understand I am being asked to provide a loop variable, but even doing so I get an error.
This is my code:
module my_first_counter_enable(SW,CLOCK_50,LEDR,KEY);
input CLOCK_50;
input [17:0] SW;
input KEY;
output [17:0] LEDR;
reg [32:0] count;
wire reset_n;
wire enable;
assign reset_n = KEY;
assign enable = SW[0];
assign LEDR = count[27:24];
always# (posedge CLOCK_50 or negedge reset_n) begin
while(enable) begin
if(!reset_n)
count = 0;
else
count = count + 1;
end
end
endmodule
I hope someone can point out my error in my loop and allow me to continue.
Thank you!
I don't think you want to use a while loop there. How about:
always# (posedge CLOCK_50 or negedge reset_n) begin
if(!reset_n)
count <= 0;
else if (enable)
count <= count + 1;
end
I also added non-blocking assignments <=, which are more appropriate for synchronous logic.
The block will trigger every time there is a positive edge of the clock. Where you had a while loop does not mean anything in hardware, it would still need a clock to drive the flip flops.
While loops can be used in testbeches to drive stimulus
integer x;
initial begin
x = 0;
while (x<1000) begin
data_in = 2**x ; //or stimulus read from file etc ...
x=x+1;
end
end
I find for loops or repeat to be of more use though:
integer x;
initial begin
for (x=0; x<1000; x=x+1) begin
data_in = 2**x ; //or stimulus read from file etc ...
end
end
initial begin
repeat(1000) begin
data_in = 'z; //stimulus read from file etc (no loop variable)...
end
end
NB: personally I would also add begin end to every thing to avoid adding extra lines later and wondering why they always or never get executed, especially while new to the language. It also has the added benefit of making the indenting look a little nicer.
always# (posedge CLOCK_50 or negedge reset_n) begin
if(!reset_n) begin
count <= 'b0;
end
else if (enable) begin
count <= count + 1;
end
end
Title
Error (10119): Verilog HDL Loop Statement error at : loop with non-constant loop condition must terminate within iterations
Description
This error may appear in the Quartus® II software when synthesis iterates through a loop in Verilog HDL for more than the synthesis loop limit. This limit prevents synthesis from potentially running into an infinite loop. By default, this loop limit is set to 250 iterations.
Workaround / Fix
To work around this error, the loop limit can be set using the VERILOG_NON_CONSTANT_LOOP_LIMIT option in the Quartus II Settings File (.qsf). For example:
set_global_assignment -name VERILOG_NON_CONSTANT_LOOP_LIMIT 300
I have the following code:
always # (clk) begin
for (1=0,i<150, i++) begin
abc[i] = xyz[i];
end
end
Question: If I want to get value of abc[8] (set of 8th iteration with the assign statement), how can I do that?
I did like below:
reg [31:0] abc;
wire [31:0] jkl;
always # (clk) begin
for (1=0,i<150, i++) begin
abc[i] = xyz[i];
end
end
assign jkl = abc[8];
$display ("value is 0x%x\n", jkl);
I have an error, can you please suggest me something?
Seems like you have misunderstanding of how for loops work in Verilog. In Verilog, you are defining hardware which operates in parallel at all times. The for loop is just a handy way to express something. You should not think of it as iterating.
What your expression means is something like this:
Assign abc[i] from xyz[i] for all values of i from 0 to 149, on every clock cycle
If you really want to iterate, you need to create a counter which increments on each cycles and use that instead of a for loop.
Now, you are probably getting error messages due to some of your other errors:
You cannot put a $display outside of a sequential code block. That is, it needs to be inside an always or forever block or similar.
You are assigning jkl (a 32-bit value) from abc[8] which is a single bit
You are assigning abc[0] to abc[149] in the for loop, but abc is only 32-bits wide
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