compiling Verilog code in Quartus - verilog

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.

Related

Yosys: Multiple edge sensitivities for asynchronous reset

I am teaching myself verilog, bare with me. :)
I have a clock line called enable coming from a clock divider I created.
I also have a rst button on my devboard.
I would like to modify the following code to react to rst button presses by turning off my leds:
always # (posedge enable) begin
if (leds == 8'b11111111) begin
leds <= 8'b00000000;
end else begin
leds <= 8'b11111111;
end
end
I added my rst button as an additional edge sensitivity and caught it in an if statement:
always # (posedge enable or negedge rst) begin
if (leds == 8'b11111111 || ~rst) begin
leds <= 8'b00000000;
end else begin
leds <= 8'b11111111;
end
end
When I synthesize this for ice40 using yosys, I get the following error: ERROR: Multiple edge sensitive events found for this signal
If it helps, the previous line of yosys output suggests that this always block is translated to a dff cell during synthesis.
I have seen several examples of people including asynchronous resets in their always blocks, so I am curious if somebody can teach me what I am violating in my case, as a novice to verilog/digital-logic.
Thank you so much!
A lot of synthesizers expect the code to follow certain coding styles. If your synthesizer supports async-reset then try making the reset logic exclusive.
always # (posedge enable or negedge rst) begin
if (~rst) begin
leds <= 8'b00000000;
end else if (leds == 8'b11111111) begin
leds <= 8'b00000000;
end else begin
leds <= 8'b11111111;
end
end
Your leds == 8'b11111111 || ~rst is logically equivalent. I haven't used a synthesizer smart enough to recognize it as logically equivalent.

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

Verilog Design Problems

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.

Can you use/manipulate same output/reg variable in multiple always blocks?

always # (posedge clk) begin
if (x) begin
count <= count + 1'b1;
end
end
always # (posedge clk) begin
if (y) begin
count <= count - 2'b10;
end
end
always # (negedge clk) begin
if (x) begin
count <= count - 1'b1;
end
end
always # ( count ) begin
...do something... ;
end
Can I us the variable count inside multiple always block?
Is this a good design practice?
Why/Where should/should not use this method?
How does the simulator/synthesizer do the calculations for that variable 'count'?
Does the compiler throw error if I do this?
Can I us the variable count inside multiple always block?
Not in RTL code NO.
Is this a good design practice?
"good design practice" is not a well defined term. You might use it in a test-bench but not in the format you use. In that case you must make sure that all always conditions are mutual exclusive.
Why/Where should/should not use this method?
You could use it if you have about 10 years experience in writing code. Otherwise don't. As to "should" never!
How does the simulator/synthesizer do the calculations for that variable 'count'?
The synthesizer will refuse your code. The simulator will assign a value just as you described. Which in your code means: you have no idea which assignment is executed last so the result is unpredictable.
Does the compiler throw error if I do this?
Why ask if you can try?
I'm not a hardware designer, but this is not good. Your 3 always blocks will all infer a register and they will all drive the count signals.
You can read signals in multiple blocks, but you should only write to them in a single block.
In most cases you don't want to have multi-drivers. If you have something like a bus with multiple possible masters then you will want multi-drivers, but they need to drive the bus through tri-states and you need to ensure that the master has exclusive access.
Mixing posedge and negedge is not a good idea.
With a single block you might write something like this (which appropriate macros or parameter for UP1, DOWN1 and DOWN2).
always #(posedge clk or negedge reset_n)
begin
if (reset_n == 1'b0)
begin
count <= 32'b0;
end
else
begin
case (count_control)
UP1: count <= count + 1'b1;
DOWN2: count <= count - 2'b10;
DOWN1: count <= count - 1'b1;
endcase
end
end
No. You can't have assignments to a net from multiple always block.
Here is the synthesis result of 2 implementation in Synopsys Design Compiler
ASSIGNMENTS FROM MULTIPLE ALWAYS BLOCK.
module temp(clk, rst, x, y, op);
input logic clk, rst;
logic [1:0] count;
input logic x, y;
output logic [1:0] op;
assign op = count;
always # (posedge clk) begin
if (x) begin
count <= count + 2'd1;
end
end
always # (posedge clk) begin
if (y) begin
count <= count - 2'd2;
end
end
always # (negedge clk) begin
if (x) begin
count <= count - 2'd1;
end
end
endmodule
// Synthesis Result of elaborate command -
Error: /afs/asu.edu/users/k/m/s/kmshah4/temp/a.sv:16: Net 'count[1]' or a directly connected net is driven by more than one source, and not all drivers are three-state. (ELAB-366)
Error: /afs/asu.edu/users/k/m/s/kmshah4/temp/a.sv:16: Net 'count[0]' or a directly connected net is driven by more than one source, and not all drivers are three-state. (ELAB-366)
ASSIGNMENTS WITH SINGLE ALWAYS BLOCK.
module temp(clk, rst, x, y, op);
input logic clk, rst;
logic [1:0] count;
input logic x, y;
output logic [1:0] op;
assign op = count;
always # (clk)
begin
if (clk)
begin
case ({x, y})
2'b01 : count <= count - 2'd2;
2'b10 : count <= count + 2'd1;
default : count <= count;
endcase
end
else
begin
count <= (x) ? (count - 2'd1) : count;
end
end
endmodule
// Synthesis Result of elaborate command -
Elaborated 1 design.
Current design is now 'temp'.
1

Verilog generate/genvar in an always block

I'm trying to get a module to pass the syntax check in ISE 12.4, and it gives me an error I don't understand. First a code snippet:
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
genvar c;
generate
always #(posedge sysclk) begin
for (c = 0; c < ROWBITS; c = c + 1) begin: test
temp[c] <= 1'b0;
end
end
endgenerate
When I try a syntax check, I get the following error message:
ERROR:HDLCompiler:731 - "test.v" Line 46: Procedural assignment to a
non-register <c> is not permitted.
I really don't understand why it's complaining. "c" isn't a wire, it's a genvar. This should be the equivalent of the completely legal syntax:
reg [3:0] temp;
always #(posedge sysclk) begin
temp[0] <= 1'b0;
temp[1] <= 1'b0;
temp[2] <= 1'b0;
temp[3] <= 1'b0;
end
Please, no comments about how it'd be easier to write this without the generate. This is a reduced example of a much more complex piece of code involving multiple ifs and non-blocking assignments to "temp". Also, don't just tell me there are newer versions of ISE, I already know that. OTOH, if you know it's fixed in a later version of ISE, please let me know which version you know works.
You need to reverse the nesting inside the generate block:
genvar c;
generate
for (c = 0; c < ROWBITS; c = c + 1) begin: test
always #(posedge sysclk) begin
temp[c] <= 1'b0;
end
end
endgenerate
Technically, this generates four always blocks:
always #(posedge sysclk) temp[0] <= 1'b0;
always #(posedge sysclk) temp[1] <= 1'b0;
always #(posedge sysclk) temp[2] <= 1'b0;
always #(posedge sysclk) temp[3] <= 1'b0;
In this simple example, there's no difference in behavior between the four always blocks and a single always block containing four assignments, but in other cases there could be.
The genvar-dependent operation needs to be resolved when constructing the in-memory representation of the design (in the case of a simulator) or when mapping to logic gates (in the case of a synthesis tool). The always #posedge doesn't have meaning until the design is operating.
Subject to certain restrictions, you can put a for loop inside the always block, even for synthesizable code. For synthesis, the loop will be unrolled. However, in that case, the for loop needs to work with a reg, integer, or similar. It can't use a genvar, because having the for loop inside the always block describes an operation that occurs at each edge of the clock, not an operation that can be expanded statically during elaboration of the design.
You don't need a generate bock if you want all the bits of temp assigned in the same always block.
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always #(posedge sysclk) begin
for (integer c=0; c<ROWBITS; c=c+1) begin: test
temp[c] <= 1'b0;
end
end
Alternatively, if your simulator supports IEEE 1800 (SytemVerilog), then
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always #(posedge sysclk) begin
temp <= '0; // fill with 0
end
end
If you do not mind having to compile/generate the file then you could use a pre processing technique. This gives you the power of the generate but results in a clean Verilog file which is often easier to debug and leads to less simulator issues.
I use RubyIt to generate verilog files from templates using ERB (Embedded Ruby).
parameter ROWBITS = <%= ROWBITS %> ;
always #(posedge sysclk) begin
<% (0...ROWBITS).each do |addr| -%>
temp[<%= addr %>] <= 1'b0;
<% end -%>
end
Generating the module_name.v file with :
$ ruby_it --parameter ROWBITS=4 --outpath ./ --file ./module_name.rv
The generated module_name.v
parameter ROWBITS = 4 ;
always #(posedge sysclk) begin
temp[0] <= 1'b0;
temp[1] <= 1'b0;
temp[2] <= 1'b0;
temp[3] <= 1'b0;
end
Within a module, Verilog contains essentially two constructs: items and statements. Statements are always found in procedural contexts, which include anything in between begin..end, functions, tasks, always blocks and initial blocks. Items, such as generate constructs, are listed directly in the module. For loops and most variable/constant declarations can exist in both contexts.
In your code, it appears that you want the for loop to be evaluated as a generate item but the loop is actually part of the procedural context of the always block. For a for loop to be treated as a generate loop it must be in the module context. The generate..endgenerate keywords are entirely optional(some tools require them) and have no effect. See this answer for an example of how generate loops are evaluated.
//Compiler sees this
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
genvar c;
always #(posedge sysclk) //Procedural context starts here
begin
for (c = 0; c < ROWBITS; c = c + 1) begin: test
temp[c] <= 1'b0; //Still a genvar
end
end
for verilog just do
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always #(posedge sysclk) begin
temp <= {ROWBITS{1'b0}}; // fill with 0
end
To put it simply, you don't use generate inside an always process, you use generate to create a parametrized process or instantiate particular modules, where you can combine if-else or case. So you can move this generate and crea a particular process or an instantiation e.g.,
module #(
parameter XLEN = 64,
parameter USEIP = 0
)
(
input clk,
input rstn,
input [XLEN-1:0] opA,
input [XLEN-1:0] opB,
input [XLEN-1:0] opR,
input en
);
generate
case(USEIP)
0:begin
always #(posedge clk or negedge rstn)
begin
if(!rstn)
begin
opR <= '{default:0};
end
else
begin
if(en)
opR <= opA+opB;
else
opR <= '{default:0};
end
end
end
1:begin
superAdder #(.XLEN(XLEN)) _adder(.clk(clk),.rstm(rstn), .opA(opA), .opB(opB), .opR(opR), .en(en));
end
endcase
endmodule

Resources