Verilog Design Problems - verilog

How to fix multiple driver , default value and combinational loop problems in the code below?
always #(posedge clk)
myregister <= #1 myregisterNxt;
always #* begin
if(reset)
myregisterNxt = myregisterNxt +1;
else if(flag == 1)
myregister = myregister +2;
end

right there are at least 3 issues in your code:
you are driving myregister within 2 different always blocks. Synthesis will find multiple drivers there. Simulation results will be unpredictable. The rule: you must drive a signal within a single always block.
you ave a zero-delay loop over myregisterNxt = myregisterNxt +1. Since you are using a no-flop there, it is a real loop in simulation and in hardware. You need to break such loops with flops
#1 delay is not synthesizable and it is not needed here at all.
You have not described what you were trying to build and it is difficult to figure it out from our code sample. In general, reset is used to set up initial values. So, something like the following could be a template for you.
always #(posedge clk) begin
if (reset)
myregister <= 0;
else
myregister <= myregister + increment;
end
always #* begin
if (flag == 1)
increment = 1;
else
increment = 2;
end
the flop with posedge clk and nonblocking assignments will not be in a loop.

Related

Find Maximum Number present in Verilog array

I have tried writing a small verilog module that will find the maximum of 10 numbers in an array. At the moment I am just trying to verify the correctness of the module without going into specific RTL methods that will to do such a task.
I am just seeing a a couple of registers when I am synthesizing this module. Nothing more that that. Ideally the output should be 7 which is at index 4 but I am seeing nothing neither on FPGA board or in the test bench. What I am doing wrong with this ?
module findmaximum(input clk,rst,output reg[3:0]max, output reg[3:0]index);
reg [3:0]corr_Output[0:9];
always#(posedge clk or posedge rst)
if(rst)
begin
corr_Output[0]=0;
corr_Output[1]=0;
corr_Output[2]=0;
corr_Output[3]=0;
corr_Output[4]=0;
corr_Output[5]=0;
corr_Output[6]=0;
corr_Output[7]=0;
corr_Output[8]=0;
corr_Output[9]=0;
end
else
begin
corr_Output[0]=0;
corr_Output[1]=0;
corr_Output[2]=0;
corr_Output[3]=0;
corr_Output[4]=7;
corr_Output[5]=0;
corr_Output[6]=0;
corr_Output[7]=0;
corr_Output[8]=0;
corr_Output[9]=0;
end
integer i;
always#(posedge clk or posedge rst)
if(rst)
begin
max=0;
index=0;
end
else
begin
max = corr_Output[0];
for (i = 0; i <= 9; i=i+1)
begin
if (corr_Output[i] > max)
begin
max = corr_Output[i];
index = i;
end
end
end
endmodule
Looking are your code, the only possible outputs are max=0,index=0 and a clock or two after reset max=7,index=4. Therefore, your synthesizer is likely optimizing the code with equivalent behavior with simpler logic.
For your find max logic to be meaningful, you need to change the values of corr_Output periodically. This can be done via input writes, LFSR (aka pseudo random number generator), and or other logic.
Other issues:
Synchronous logic (updated on a clock edge) should be assigned by with non-blocking (<=). Combinational logic should be assigned with blocking (=). When this guideline is not followed there is a risk of behavior differences between simulation and synthesis. In the event you need to compare with intermediate values (like your original max and index), then you need to separate the logic into two always blocks like bellow. See code bellow.
Also, FPGAs tend to have limited asynchronous reset support. Use synchronous reset instead by removing the reset from the sensitivity list.
always#(posedge clk) begin
if (rst) begin
max <= 4'h0;
index <= 4'h0;
end
else begin
max <= next_max;
index <= next_index;
end
always #* begin
next_max = corr_Output[0];
next_index = 4'h0;
for (i = 1; i <= 9; i=i+1) begin // <-- start at 1, not 0 (0 is same a default)
if (corr_Output[i] > next_max) begin
next_max = corr_Output[i];
next_index = i;
end
end
end

Blocking assignments in always block verilog?

now I know in Verilog, to make a sequential logic you would almost always have use the non-blocking assignment (<=) in an always block. But does this rule also apply to internal variables? If blocking assignments were to be used for internal variables in an always block would it make it comb or seq logic?
So, for example, I'm trying to code a sequential prescaler module. It's output will only be a positive pulse of one clk period duration. It'll have a parameter value that will be the prescaler (how many clock cycles to divide the clk) and a counter variable to keep track of it.
I have count's assignments to be blocking assignments but the output, q to be non-blocking. For simulation purposes, the code works; the output of q is just the way I want it to be. If I change the assignments to be non-blocking, the output of q only works correctly for the 1st cycle of the parameter length, and then stays 0 forever for some reason (this might be because of the way its coded but, I can't seem to think of another way to code it). So is the way the code is right now behaving as a combinational or sequential logic? And, is this an acceptable thing to do in the industry? And is this synthesizable?
```
module scan_rate2(q, clk, reset_bar);
//I/O's
input clk;
input reset_bar;
output reg q;
//internal constants/variables
parameter prescaler = 8;
integer count = prescaler;
always #(posedge clk) begin
if(reset_bar == 0)
q <= 1'b0;
else begin
if (count == 0) begin
q <= 1'b1;
count = prescaler;
end
else
q <= 1'b0;
end
count = count - 1;
end
endmodule
```
You should follow the industry practice which tells you to use non-blocking assignments for all outputs of the sequential logic. The only exclusion are temporary vars which are used to help in evaluation of complex expressions in sequential logic, provided that they are used only in a single block.
In you case using 'blocking' for the 'counter' will cause mismatch in synthesis behavior. Synthesis will create flops for both q and count. However, in your case with blocking assignment the count will be decremented immediately after it is being assigned the prescaled value, whether after synthesis, it will happen next cycle only.
So, you need a non-blocking. BTW initializing 'count' within declaration might work in fpga synthesis, but does not work in schematic synthesis, so it is better to initialize it differently. Unless I misinterpreted your intent, it should look like the following.
integer count;
always #(posedge clk) begin
if(reset_bar == 0) begin
q <= 1'b0;
counter <= prescaler - 1;
end
else begin
if (count == 0) begin
q <= 1'b1;
count <= prescaler -1;
end
else begin
q <= 1'b0;
count <= count - 1;
end
end
end
You do not need temp vars there, but you for the illustration it can be done as the following:
...
integer tmp;
always ...
else begin
q <= 1'b0;
tmp = count - 1; // you should use blocking here
count <= tmp; // but here you should still use NBA
end

System verilog: if loop inside always block not executing

I wrote a piece of code to assert a signal (val_changed) synchronously when another 64-bit signal (val) changes value by more than a threshold. Later this signal need to be de-asserted based on a third signal's (adj_in_prog) negedge.
Here clk and val are inputs to the block.
logic [63:0] val_reg;
always #(posedge clk) begin
val_reg <= val;
end
always #(posedge clk) begin
if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
val_changed <= 1'b1;
#(negedge adj_in_prog);
val_changed <= 1'b0;
end
I understand that the above method is not the cleanest of ways to do it, but since this is test-bench code and so I don't need to synthesis this, thought of experimenting. But this code is not working as val_changed is not going 1. I would like to know why the if loop won't execute. As per me, val_changed should have gone high at the clock edge where marker is positioned in the waveform attached. Can someone please help? (waveform values are in hex)
in your case at the very first posedge of clk the second always block starts executing and processes the 'if' statement. Then it sticks at the #(negedge adj_in_prog) statement, waiting for the event. On the next clock edge it will continue waiting and will not re-enter and evaluate the 'if' statement, and so on. So, this explains why it is not progressing.
so, assuming that the adj_in_prog is turned on at val_changed changing to one, the following should work for you.
always #(posedge clk) begin
if ((val - val_reg) > 64'hFFFFF) //Threshold = 64'hFFFFF
val_changed <= 1'b1;
else if (!adj_in_prog);
val_changed <= 1'b0;
end

Verilog Loop Condition

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

compiling Verilog code in Quartus

I'm new to verilog HDL and my first project is to implement a simple stopwatch counter using a set of registers. I'm using Altera Quartus.
When I tried compiling the code below, I keep getting an error for each and everyone of the registers. one of the error messages looks like this:
Error (10028): Can't resolve multiple constant drivers for net "sec0[3]" at test_interface.v(127)
Anyone can help? The code simulates fine in Modelsim.
Here's the fragment of code that's causing problems:
always # (posedge clk)
if (qsoutput == 1)
sec0 = sec0 + 1;
else if (sec0 == 4'b1010) begin
sec1 = sec1 + 1;
sec0 = 4'b0000;
end else if (sec1 == 4'b0110) begin
min0 = min0 + 1;
sec1 = 4'b0000;
end else if (min0 == 4'b1010) begin
min1 = min1 + 1;
min0 = 4'b0000;
end else if (min1 == 4'b0110) begin
sec0 = 4'b0000;
sec1 = 4'b0000;
min0 = 4'b0000;
min1 = 4'b0000;
end
Based on your code in Dropbox, you are assigning registers in multiple always blocks. This is illegal for synthesis and cosponsors to the Altera Quartus error message is referring to. A reg type should only be assigned with in one always block.
As an example, sec0 is defined in always #(posedge reset_reg) and the code provided in your question. The code in Dropbox is even worse because you split the counter logic into 4 separate always blocks that assign sec0.
I suggest you put all sec* and min* resisters one clock synchronous always block with an asynchronous:
always(#posedge clk or posedge reset_reg)
begin
if(reset_reg)
begin
// ... asynchronous reset code ...
end
else
begin
// ... synchronous counter code ...
end
end
This paper goes into detail about good verilog coding practices for synthesis:
http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
Other issues you will have:
Use non-blocking (<=) when assigning registers. This is discussed in Cliff's paper mentioned earlier.
Get rid of the initial block. I understand some FPGA synthesizers allow it and some ignore it. It is a better practice to have an asynchronous to put everything into a known and predictable value.
The block starting with always # (clk or start_reg or lap_reg or reset_reg) has a bizarre sensitivity list and will likely give you problems. you wither want #(*) if you want combination logic or #(posedge clk or posedge reset_reg) for synchronous flops.
Very rarely dual edge flops are used. The line always # (posedge clk or negedge clk) should be always # (posedge clk) for synchronous or always #(*) for combination logic.

Resources