cannot use an input for if statement in Verilog - verilog

I am trying to pass an integer value to a module, but the IF statement does not work with the parameter. It throws the following error. I am new to Verilog so I have no idea how to make this work.
Error (10200): Verilog HDL Conditional Statement error at clock_divider.v(17):
cannot match operand(s) in the condition to the corresponding edges in the enclosing
event control of the always construct
clock_divider.v module
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always # (posedge clk or negedge rst_n)
begin
if(clockHandler == 0)
begin div_helper = DIV_CONST;
end
else
begin div_helper = DIV_CONST_faster;
end
if (!rst_n)
begin div <= 0;
en <= 0;
end
else
begin
if (div == div_helper)
begin div <= 0;
en <= 1;
end
else
begin div <= div + 1;
en <= 0;
end
end
end
always # (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
clk_o <= 1'b0;
end
else if (en)
clk_o <= ~clk_o;
end
endmodule
main.v module
reg clockHandler = 1;
// 7-seg display mux
always # (*)
begin
case (SW[2:0])
3'b000: hexdata <= 16'h0188;
3'b001: hexdata <= register_A ;
3'b010: hexdata <= program_counter ;
3'b011: hexdata <= instruction_register ;
3'b100: hexdata <= memory_data_register_out ;
3'b111: hexdata <= out;
default: hexdata <= 16'h0188;
endcase
if(SW[8] == 1)
begin
clockHandler = 1;
end
else
begin
clockHandler = 0;
end
end
HexDigit d0(HEX0,hexdata[3:0]);
HexDigit d1(HEX1,hexdata[7:4]);
HexDigit d2(HEX2,hexdata[11:8]);
HexDigit d3(HEX3,hexdata[15:12]);
clock_divider clk1Hzfrom50MHz (
clockHandler,
CLOCK_50,
KEY[3],
clk_1Hz
);

It's my understanding that the first statement in a verilog always block must be the if(reset) term if you're using an asynchronous reset.
So the flop construct should always look like this:
always # (posedge clk or negedge rst_n) begin
if(~rst_n) begin
...reset statements...
end else begin
...all other statements...
end
end
So for your case you should move the if(clockHandler==0) block inside the else statement, because it is not relevant to the reset execution. Even better would be to move it into a separate combinational always block, since mixing blocking and nonblocking statements inside an always block is generally not a good idea unless you really know what you're doing. I think it is fine in your case though.

To add to Tim's answer - the original code (around line 17, anyway) is valid Verilog.
What it's saying is "whenever there's a rising edge on clk or a falling edge on rst_n, check clockHandler and do something" (by the way, get rid of the begin/ends; they're redundant and verbose). The problem comes when you want to implement this in real hardware, so the error message is presumably from a synthesiser, which needs more than valid Verilog. The synth suspects that it has to build a synchronous element of some sort, but it can't (or won't, to be precise) handle the case where clockHandler is examined on an edge of both clk and rst_n. Follow the rules for synthesis templates, and you won't get this problem.

is this a compilation error or synthesis error? i used the same code to see if it compiles fine, and i din get errors.. Also, it is recommended to use "<=" inside synchronous blocks rather than "="

You're using the same flop construct for two different things. Linearly in code this causes a slipping of states. I always place everything within one construct if the states rely on that clock or that reset, otherwise you require extra steps to make sure more than one signal isn't trying to change your state.
You also don't need the begin/end when it comes to the flop construct, Verilog knows how to handle that for you. I believe Verilog is okay with it though, but I generally don't do that. You also don't have to use it when using a single statement within a block.
So your first module would look like this (if I missed a block somewhere just let me know):
clock_divider.v module (edited)
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always # (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div <= 0;
en <= 0;
clk_o <= 1'b0;
end
else if(en)
begin
clk_o <= ~ clk_o;
if(clockHandler == 0)
begin
div_helper = DIV_CONST;
end
else
begin
div_helper = DIV_CONST_faster;
end
else
begin
if (div == div_helper)
begin
div <= 0;
en <= 1;
end
end
else
begin
div <= div + 1;
en <= 0;
end
end
end
end module
If that clk_o isn't meant to be handled at the same time those other operations take place, then you can separate everything else with a general 'else' statement. Just be sure to nest that second construct as an if-statement to check your state.
And also remember to add always # (posedge clk or negedge rst_n) to your main.v module as Tim mentioned.

Related

Shortests version to choose posedge/negedge sensitivity from module parameter?

I want to build a Verilog module so that the user can select the sensitivity of some input clock signal by a module parameter. As an example, I wrote the following counter which can either count up on posedge or negedge selected by parameter clockEdge.
module Counter (clk, reset, value);
parameter clockEdge = 1; // react to rising edge by default
input clk;
input reset;
output reg [7:0] value;
generate
if(clockEdge == 1) begin
always #(posedge clk or posedge reset) begin
if (reset) begin
value <= 0;
end else begin
value <= value + 1;
end
end
end else begin
always #(negedge clk or posedge reset) begin
if (reset) begin
value <= 0;
end else begin
value <= value + 1;
end
end
end
endgenerate
endmodule
This principle is working, however I don't like that the implementation is basically copy and paste for both variants. What would be a shorter version without duplication?
Simplest is to invert the clock with an exor gate. Then use that clock in an always section:
wire user_clock;
assign user_clock = clk ^ falling_edge;
always #(posedge user_clock) // or posedge/negedge reset/_n etc.
test_signal <= ~ test_signal;
If falling_edge is 0 then user_clock and clk have the same polarity and the data is clocked at nearly the same time as you have a rising edge of clk.
If falling_edge is 1 then user_clock and clk have the opposite polarity and the data is clocked nearly the same time as the falling edge of clk.
Be careful when you change the polarity of falling_edge as it can generate runt clock pulses! Safest is to use a gated clock: stop the clock, switch polarity, then start it again.
In both cases user_clock will lag the system clk by small amount. The amount depends on the delay of the exor-gate.
Here is a simulation+:
+test_signal was set to zero in an initial statement.
I think that cut-n-paste in this tiny example is ok, though verilog has some instruments to make it easier for more complicated cases, namely functions and macros. You can use them as well, i.e.
function newValue(input reset, input reg[7:0] oldValue);
if (reset) begin
newValue = 0;
end else begin
newValue = value + 1;
end
endfunction
generate
if(clockEdge == 1) begin
always #(posedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end else begin
always #(negedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end
endgenerate
the other possibility is to use macros with or without paramenters. Methodology-wise macros are usually worse than functions, though here is an extreme example, though in my opinion it makes the code less readable and could have issues with debugging tools.
`define NEW_VALUE(clk_edge) \
always #(clk_edge clk or posedge reset) begin\
if (reset) begin\
value <= 0;\
end else begin\
value <= value + 1;\
end\
end
generate
if(clockEdge == 1) begin
`NEW_VALUE(posedge)
end else begin
`NEW_VALUE(negedge)
end
endgenerate
Implementing custom clock reg that follows posedge or negedge of clk might be one way to do it. This seems to work well on my machine :)
reg myclk;
always#(clk) begin
if(clk) begin
myclk = clockEdge? 1 : 0; #1 myclk = 0;
end else begin
myclk = clockEdge? 0 : 1; #1 myclk = 0;
end
end
always#(posedge myclk or posedge reset) begin
if(reset)
cnt <= 0;
else
cnt <= cnt+1;
end

Verilog Event control statements

I currently have this code(below) for a debouncer for a button on an fpga, however I am getting an error that says "Multiple event control statements in one always/initial process block are not supported in this case." whenever I try to synthesize the desgin. The line that causes the problem is the #(posedge clk) but I'm wondering how exactly to replace this logic. What I essentially require is always # (quarter & posedge clk)as the sensitivity list for the first always block but this does not work either. I am fairly new to the language so I'm still working out a few syntax kinks.Snippet of Code is below:
always #(quarter)
begin
#(posedge clk)
begin
if (quarter != new) begin new <= quarter; count <= 0; end
else if (count == DELAY) cleanq <= new;
else count <= count+1;
end
end
instead of always
#(posedge event1)
#(posedge event2)
create aflag (1bit reg) event2done : reg event2done; initial event2done=0;
always#(posedge event1)
begin if (!event2done & event 2)
// event2done=1; + type ur code
else if(event2done & !event 2)
event2done =0; end
pseudo code:
always#(something1)
#(something2)
do something
Look in the comments to see explanation as to why this isn't synthesizable
always #(posedge clk)
/* over here you'll have to set the default values
for everything that's being changed in this always block,
you'll otherwise generate latches. Which is likely
not what you want */
begin
if (quarter != new) begin new <= quarter; count <= 0; end
else if (count == DELAY) cleanq <= new;
else count <= count+1;
end
I don't have access to my verilog rig at the moment so I can't confirm the syntax correctness

Triangle waveform verilog

I'm trying to get a triangle waveform, but my code doesn't work! I think the "if conditions" are organised wrong but I can't find the mistake My wave goes up like it should be and it falls down by 90° after achieving the top
module pila(clk,res,out2);
input clk,res;
output [0:7]out2;
reg [0:7]out2;
always #(posedge clk)
begin
if (res)
begin
if(out2<=8'b11111111)
out2=out2+1;
else if(out2>=8'b00000000)
out2=out2-1;
else out2=8'b00000000;
end
else out2=8'b00000000;
end
endmodule
module testbench;
reg clk,res;
wire [0:7]out2;
pila Sevo(clk,res,out2);
always #2 clk=~clk;
initial
begin
clk=0;res=0;
#2 res=1;
end
initial #5000 $finish;
endmodule
You need some signal to indicate which direction you are currently counting. Also use the non-blocking assignment operator <= rather than the blocking assignment operator =.
module pila(clk,res,out2);
input clk,res;
output [0:7]out2;
reg [0:7]out2 = 8'h00;
reg count_down = 1'b0;
always #(posedge clk)
begin
if (count_down == 1'b0)
begin
if (out2==8'b11111111) // check for top of count
begin
count_down <= 1'b1;
out2<=out2-1;
end
else
out2<=out2+1;
end
else
begin
if(out2==8'b00000000) // check for bottom of count
begin
count_down <= 1'b0;
out2<=out2+1;
end
else
out2<=out2-1;
end
end
endmodule
The if(out2<=8'b11111111) condition is always evaluating to true. This is because out2 range is 0 to 255. Try adding another flop to control the direction, for example downup where 1 means decrement and 0 means increment.
if (out2 == 8'h00) begin
downup <= 1'b0; // up
out2 <= 8'h01;
end
else if (out2 == 8'hFF) begin
downup <= 1'b1; // down
out2 <= 8'hFE;
end
else if (downup) begin // down
out2 <= out2 - 1;
end
else begin // up
out2 <= out2 + 1;
end
Other issues:
Use non-blocking assignment (<=) for synchronous logic.
Typically reset (and set) conditions are declared before synchronous logic assignment
Little-Endian ([7:0]) is more commonly used for packed arrays (previously known as vectors) then Big-Endian ([0:7]), http://en.wikipedia.org/wiki/Endianness
Working example: http://www.edaplayground.com/x/4_b

My Verilog behavioral code getting simulated properly but not working as expected on FPGA

I wrote a behavioral program for booth multiplier(radix 2) using state machine concept. I am getting the the results properly during the program simulation using modelsim, but when I port it to fpga (spartan 3) the results are not as expected.
Where have I gone wrong?
module booth_using_statemachine(Mul_A,Mul_B,Mul_Result,clk,reset);
input Mul_A,Mul_B,clk,reset;
output Mul_Result;
wire [7:0] Mul_A,Mul_B;
reg [7:0] Mul_Result;
reg [15:0] R_B;
reg [7:0] R_A;
reg prev;
reg [1:0] state;
reg [3:0] count;
parameter start=1 ,add=2 ,shift=3;
always #(state)
begin
case(state)
start:
begin
R_A <= Mul_A;
R_B <= {8'b00000000,Mul_B};
prev <= 1'b0;
count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add:
begin
case({R_B[0],prev})
2'b00:
begin
prev <= 1'b0;
end
2'b01:
begin
R_B[15:8] <= R_B[15:8] + R_A;
prev <= 1'b0;
end
2'b10:
begin
R_B[15:8] <= R_B[15:8] - R_A;
prev <= 1'b1;
end
2'b11:
begin
prev <=1'b1;
end
endcase
end
shift:
begin
R_B <= {R_B[15],R_B[15:1]};
count <= count + 1;
end
endcase
end
always #(posedge clk or posedge reset)
begin
if(reset==1)
state <= start;
else
begin
case(state)
start:
state <= add;
add:
state <= shift;
shift:
begin
if(count>7)
state <= start;
else
state <=add;
end
endcase
end
end
endmodule
You have an incomplete sensitivity list in your combinational always block. Change:
always #(state)
to:
always #*
This may be synthesizing latches.
Use blocking assignments in your combinational always block. Change <= to =.
Good synthesis and linting tools should warn you about these constructs.
Follow the following checklist if something does work in the simulation but not in reality:
Did you have initialized every register? (yes)
Do you use 2 registers for one working variable that you transfer after each clock (no)
(use for state 2 signals/wires, for example state and state_next and transfer after each clock state_next to state)
A Example for the second point is here, you need the next stage logic, the current state logic and the output logic.
For more informations about how to proper code a FSM for an FPGA see here (go to HDL Coding Techniques -> Basic HDL Coding Techniques)
You've got various problems here.
Your sensitivity list for the first always block is incomplete. You're only looking at state, but there's numerous other signals which need to be in there. If your tools support it, use always #*, which automatically generates the sensitivity list. Change this and your code will start to simulate like it's running on the FPGA.
This is hiding the other problems with the code because it's causing signals to update at the wrong time. You've managed to get your code to work in the simulator, but it's based on a lie. The lie is that R_A, R_B, prev, count & Mul_Result are only dependent on changes in state, but there's more signals which are inputs to that logic.
You've fallen into the trap that the Verilog keyword reg creates registers. It doesn't. I know it's silly, but that's the way it is. What reg means is that it's a variable that can be assigned to from a procedural block. wires can't be assigned to inside a procedural block.
A register is created when you assign something within a clocked procedural block (see footnote), like your state variable. R_A, R_B, prev and count all appear to be holding values across cycles, so need to be registers. I'd change the code like this:
First I'd create a set of next_* variables. These will contain the value we want in each register next clock.
reg [15:0] next_R_B;
reg [7:0] next_R_A;
reg next_prev;
reg [3:0] next_count;
Then I'd change the clocked process to use these:
always #(posedge clk or posedge reset) begin
if(reset==1) begin
state <= start;
R_A <= '0;
R_B <= '0;
prev <= '0;
count <= '0;
end else begin
R_A <= next_R_A;
R_B <= next_R_B;
prev <= next_prev;
count <= next_count;
case (state)
.....
Then finally change the first process to assign to the next_* variables:
always #* begin
next_R_A <= R_A;
next_R_B <= R_B;
next_prev <= prev;
next_count <= count;
case(state)
start: begin
next_R_A <= Mul_A;
next_R_B <= {8'b00000000,Mul_B};
next_prev <= 1'b0;
next_count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add: begin
case({R_B[0],prev})
2'b00: begin
next_prev <= 1'b0;
end
.....
Note:
All registers now have a reset
The next_ value for any register defaults to it's previous value.
next_ values are never read, except for the clocked process
non-next_ values are never written, except in the clocked process.
I also suspect you want Mul_Result to be a wire and have it assign Mul_Result = R_B[7:0]; rather than it being another register that's only updated in the start state, but I'm not sure what you're going for there.
A register is normally a reg, but a reg doesn't have to be a register.

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