I am receiving this error from Quartus when trying to compile:
Error (10200): Verilog HDL Conditional Statement error at
time_of_day_FSM.v(166): cannot match operand(s) in the condition to
the corresponding edges in the enclosing event control of the always
construct
Here is some background. I am making a clock, and for this always block, I want to increment and set certain values to resemble the behavior of a clock in the format of hh:mm:ss. I have a clock source that goes high every millisecond, and am using a counter to set the secondPassed reg.
I want the code in the block to update every time a second passes, like a clock, or KEY[2] is pressed on my board (down = 0), as this is what the user uses to increment the hours, minutes, or seconds when setting the clock time. Here is the always block in question (sorry for the nested if statements, I can't think of a better way to do it):
// every second. Used just to keep time going. Independent of states.
always #(posedge secondPassed, negedge KEY[2], negedge KEY[0]) begin
if(KEY[0] == 0) begin
hr1 <= 1;
hr0 <= 2;
min1 <= 0;
min0 <= 0;
sec1 <= 0;
sec0 <= 0;
end
else if(secondPassed == 1 || KEY[2] == 0) begin // I don't care about explicitly stating the conditions, as the sensitivity list covers that right?
if(sec0 == 9) begin
sec0 <= 0;
if(sec1 == 5) begin
sec1 <= 0;
if(min0 == 9) begin
min0 <= 0;
if(min1 == 5) begin
min1 <= 0;
if(hr1 == 1) begin
if(hr0 == 2) begin
hr0 <= 1; // go to 1 o'clock
hr1 <= 0;
end
else hr0 <= hr0 + 1;
end
else hr0 <= hr0 + 1;
end
else min1 <= min1 + 1;
end
else min0 <= min0 + 1;
end
else sec1 <= sec1 + 1;
end
else begin
sec0 <= sec0 + 1;
end
just_flashed <= ~just_flashed;
end // end big else
end // end always
My question is: Why does the Quartus compiler complain if I try to make the non-reset scenario JUST AND ELSE, like this:
// every second. Used just to keep time going. Independent of states.
always #(posedge secondPassed, negedge KEY[2], negedge KEY[0]) begin
if(KEY[0] == 0) begin
hr1 <= 1;
hr0 <= 2;
min1 <= 0;
min0 <= 0;
sec1 <= 0;
sec0 <= 0;
end
else begin // this is causing the issue. compiler complains .
// same logic to drive clock as above
just_flashed <= ~just_flashed;
end // end big else
end // end always
I feel I have seen many examples where people simply use and else begin end for their code. My code seems to want my to EXPLICITLY restate the conditions of the sensitivity list for the else if. Any explanation? I am new to large verilog projects.
You are mixing combinational logic and synchronous logic in the always block and this is bad habit of coding. Generally, there are 2 main always blocks in most designs.
A combinational:
always#(*) // * adds anything under this always block to sensitivity list.
begin // Which makes this always block combinational.
count_reg_d <= somelogic;
end
Then these combinational logic is assigned to proper registers in the sequental
always block:
always#(posedge clk, negedge rst)
begin
if(~rst)
count_reg_q <= 0;
else
begin
count_reg_q <= count_reg_d;
end
end
By coding this way you avoid mixed always blocks, and the code is much more readable and closer to hardware that is being synthesized. So if you update the always blocks' sensitivity list properly the problems has to be solved.
Related
I got a problem when bistreaming. The project is to create a clock with a 1:2 duty cycle. There are no problems during Synthesis and Implementation. I tried a few ways to solve it. But they didn't work well.
module clock_div(clk, clk_out);
input clk;
output reg clk_out;
integer count1, count2;
reg clk_div;
always#(posedge clk)
begin
count1 <= count1 + 1;
if(count1 == 16666667)
begin
count1 <= 0;
clk_div <= ~clk_div;
end
end
always#(clk_div)
begin
count2 <= count2 + 1;
if(count2 == 1)
begin
clk_out <= ~clk_out;
end
else if(count2 == 3)
begin
count2 <= 0;
clk_out <= ~clk_out;
end
end
endmodule
The message that Vivado gave is as follows:
[DRC 23-20] Rule violation (LUTLP-1) Combinatorial Loop - 231 LUT
cells form a combinatorial loop.
This can create a race condition.
Timing analysis may not be accurate.
The preferred resolution is to modify the design to remove
combinatorial logic loops.
To allow bitstream creation for designs with combinatorial logic loops
(not recommended), use this command: set_property SEVERITY {Warning}
[get_drc_checks LUTLP-1].
NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl
command), add this command to a .tcl file and add that file as a pre-
hook for write_bitstream step for the implementation run.
clk_out_reg_i_3, clk_out_reg_i_4, clk_out_reg_i_5, clk_out_reg_i_7,
clk_out_reg_i_8, clk_out_reg_i_10, clk_out_reg_i_11, clk_out_reg_i_12,
clk_out_reg_i_13, clk_out_reg_i_14, clk_out_reg_i_15,
clk_out_reg_i_16, clk_out_reg_i_17, clk_out_reg_i_20, clk_out_reg_i_21
(the first 15 of 231 listed).
I would appreciate it if someone can help me.
This is wrong:
always#(clk_div) // <<== WRONG!!!!
begin
count2 <= count2 + 1;
if(count2 == 1)
begin
clk_out <= ~clk_out;
end
else if(count2 == 3)
begin
count2 <= 0;
clk_out <= ~clk_out;
end
end
You are using an incomplete sensitivity list. This gives a mismatch between simulation and synthesis. For all code that you want to synthesize use a complete sensitivity list or even easier use :always#( * )
If you use that in the section above you will find that your simulation no longer works. It will get in an infinite loop. Which is exactly the combinatorial loop the tool is complaining about.
To solve this you should put all code into the top section:
always#(posedge clk)
begin
count1 <= count1 + 1;
if(count1 == 16666667)
begin
count1 <= 0;
// Here you should make your 2:1 clock(s!)
// I leave that as an exercise to you
end
end
Problem:
As you divide by 16666667 you will not get a 2:1 clock but more a 33333334:1 clock.
Unless you wanted a 2:1 clock between clk_div and clk_out, but clk_div is not coming out. In that case make both clk_div and clk_out in the above marked section
I have to design an infrared transmitter using a FPGA and Verilog.
One of the conditions is to send a packet every 10Hz , I have a counter that creates a secondary clock at 10Hz from the master clock (100MHz).
The packet contains Start-Gap-Select-Gap-Right-Gap-Left-Gap-Forward-Gap-Backwards-Gap. I have a FSM that do this transition at the postive edge of the 10Hz secondary clock.
Each of these blocks within the packet has its size, with Gap being just empty space that separates them. The direction blocks have bigger size when selected and smaller otherwise.
With the condition that the receiver has a pulse frequency of 36kHz I have another counter that reduces the master clock to 36kHz which i use to generate the pulse sizes for the Start, Select etc. and make the output led 1 while the counter counts up to that size (for cases start, select..) and 0 for Gap state.
However when I look at the LED through my smartphone camera it shows it is on all the time which is what I expect to see as it should send packets 10 times per second.
The problem is that the car is not moving at all, my question is is this the correct logic of doing the things or I am missing something?
Thanks
Requested code:
The counter for the 36kHz pulse
always#(posedge CLK) begin
if(RESET) begin
Counter <= 0;
SEC_CLK <= 0;
end
else if(Counter == 2778) begin
Counter <= 0;
SEC_CLK <= 1'b1;
end
else begin
Counter <= Counter + 1;
SEC_CLK <= 1'b0;
end
end
The 10Hz counter, don't know whether is good to reduce the 36kHz or use the Master Clock, but it is a nice round number so I used the Master CLock
always#(posedge CLK) begin
if(sec_counter == 100000) begin
sec_counter <= 0;
send <= 1;
end
else begin
sec_counter <= sec_counter +1;
send <= 0;
end
end`
The FSM LOGIC:
always#(Curr_State) begin
case(Curr_State)
1'd0: begin //START
Next_State <= 1'd1;
Previous_State <= Next_State;
max_count <= StartBurstSize;
flag <= 0;
end
1'd1: begin //GAP
if(Previous_State <= 1'd7)
Next_State<=1'd0;
else
Next_State <= Previous_State +1;
max_count <= GapSize;
flag <= 1;
IR_LED = 1'b1;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
end
1'd2: begin //SELECT
Next_State <= 1'd1;
Previous_State <= Curr_State;
max_count <= CarSelectBurstSize;
IR_LED = 1'b0;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
end
1'd3: begin //RIGHT
if(BTNR)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
1'd4: begin //LEFT
if(BTNL)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
1'd5: begin //FORWARD
if(BTNU)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
1'd6: begin //Backwards
if(BTND)
max_count <= AsserBurstSize;
else
max_count <= DeAssertBurstSize;
Next_State <= 1'd1;
Previous_State <= Curr_State;
flag <= 0;
if(change)
Curr_State <= Next_State;
else
Next_State <= Curr_State;
IR_LED = 1'b1;
end
endcase
end
SENDING THE PULSES TO THE IR LED
always#(posedge SEC_CLK) begin
if(send) begin
if(Pcounter == max_count) begin //COUNTING BLOCK SIZE
Pcounter <= 0;
IR_LED=1'b0;
end
else begin
if(flag)
IR_LED=1'b0; //GAP
else
IR_LED=1'b1;
Pcounter <= Pcounter+1;
end
end
end
There is no reset on sec_counter, so the behavior could be unpredictable (unless you specified an initial value when you declared the reg). Since you didn’t include the declaration portion of the code, it’s difficult to tell.
Your state machine design is a little unusual and I think you are not getting the behavior you expect. Generally state machines are coded in one of two ways. One method places the next_state calculation into a combinatorial block with all the state machine inputs and the current state in the sensitivity list of the block. A second synchronous always block (i.e. the sensitivity list posedge clk) of code assigns the next_state to the current_state at the posedge of the state machine clock. A second method uses a single synchronous always block for both the state machines and outputs. In this case there is no next_state variable, you simply assign the new value directly to the state variable, making sure to assign the state value for each branch of a case or if/else statement. The second version can run faster since all outputs are registered, the first version uses less logic and I personally find it easier to decode. Since your design is very slow, I’d suggest using that first version.
Your state machine doesn’t actually hold state since no clock is in use—so it’s not actually a state machine. Try running it off your clk signal. Also, make sure to handle the clock domain crossing properly to avoid metastability issues.
I don't know if you still care about this question, but in your case statements you have something like
1'd2: begin //SELECT
or even
Previous_State <= 1'd7
However, 1'd means a decimal number 1-bit wide, so it cannot ever be anything different than 0 or 1, the most significant bits just get discarded.
Have you tried to simulate this?
the picture indicates what I want the output signal is: the high signal double and the low signal keep same.
I wrote the code like:
integer x=0, count_valid=1, count_down=0;
reg valid_1, valid_reg;
always#(posedge clk)
begin
if(tag==1) begin
if(valid) begin
count_valid <= count_valid +1;
x<=x+1;
valid_reg <= 1;
end
else begin
x<=0;
count_down <= count_down+1;
if(count_valid>0) begin
valid_reg <= 1;
count_valid <= count_valid -1;
end
else if(count_down>0) begin
valid_reg <= 0;
count_down <= count_down-1;
end
end
end
else begin
valid_reg <= valid;
if (valid) x<=x+1;
else x<=0;
end
valid_1 <= valid_reg;
end
valid is the original signal in the picture and valid_reg is the modified signal. the count_valid is used to count how many cycles for high and use it to sub one to achieve the doubling. then count_down is for counting the cycles of low signal. but I realized when valid high the valid_reg will high.
can anyone give me some idea how to make the low signal run same cycles in output signal? any idea is also great.
You didn't mention if the input signal was periodic or not. Given the fact that your output is stretched over time, if the input is not periodic, then you would need infinite storage to keep track of what the input signal looked like. If it is periodic, or quasi-periodic, you can do something like below.
Keep track of the high count and low count in one block, and generate the output signal in another block, using the current registered values of the counts. Getting the output's first edge to line up with the input's is kind of tricky, requiring a mux, selected depending on whether it's the first time through the loop or not.
integer count, count_q, countdown, countdown_q, outcount;
logic valid_q, valid_reg, out_q;
logic new;
always #(posedge clk or negedge reset_n)
begin
if(~reset_n)
begin
if(~reset_n)
begin
new <= 1;
valid_q <= 0;
count_q <= 0;
countdown_q <= 0;
end
else
begin
valid_q <= valid;
if(valid & ~valid_q)//rising edge
begin
count <= 1;
countdown_q <= countdown;
end
else if(~valid & valid_q)//falling edge
begin
new <= 0;
count_q <= count;
countdown <= 1;
end
else if(valid)
count <= count+1;
else
countdown <= countdown+1;
end
end
end
always #(posedge clk or negedge reset_n)
begin
if(~reset)
begin
outcount <= 0;
out_q <= 0;
end
else
begin
if(new & valid & ~valid_q)
begin
out_q <= 1;
outcount <= 2;//valid_reg is already high here
end
else
if(out_q && (outcount == (count_q<<1)))
begin
out_q <= 0;
outcount <= 1;
end
else if(~out_q && (outcount == (countdown_q)))
begin
out_q <= 1;
outcount <= 1;
end
else
outcount <= outcount + 1;
end
end
assign valid_reg = new? valid : out_q;//this gets your initial rising edge lined up
I'm implementing a simple serializer in Verilog, but I do not understand the nuances of when blocking assigns can cause problems. I'm specifically having trouble understanding part of this answer. "However, you should never use blocking assignments for synchronous communication, as this is nondeterministic."
I'm building a block that takes, as an input:
A bit clock
A 5-bit parallel data input (the value to be serialized)
A "Data valid" signal that indicates valid 5-bit data is present
As an output, I have:
Serial data out
A "Complete" signal that indicates it's time for a new 5-bit value
A "Transmitting" signal that's high whenever there's valid serial data going out on the bus
Whenever data valid goes high, the block starts outputting the 5-bit value, one bit a time, starting at the next rising edge of the bit clock. When the last bit is out on the wire, the block signals "complete" so a new 5-bit value can be made available.
Omitting some of the reset logic, the code to do this looks like this:
always # (posedge clk) begin
if(shiftIndex == 0) begin
if(dataValid == 1) transmitting = 1; //Blocking assign
else transmitting = 0; //Blocking assign
end
//Need the blocking assign up above to get this part to run
//for the 1st bit
if(transmitting == 1) begin
shiftIndex <= shiftIndex + 1;
dataOut <= data5b[shiftIndex];
if(shiftIndex == 4) begin
complete <= 1;
shiftIndex <= 0;
end
else begin
complete <= 0;
end
end
end
Now, I can write the block with all non-blocking assigns, but I feel that it hurts readability. That would look something like this:
always # (posedge clk) begin
if(shiftIndex == 0) begin
if(dataValid == 1) begin
transmitting <= 1; //Non-blocking now
shiftIndex <= shiftIndex + 1; //Duplicated code
dataOut <= data5b[shiftIndex]; //Duplicated code
complete <= 0; //Duplicated code
end
else transmitting <= 0;
end
//Now, this only runs for the 2nd, 3rd, 4th, and 5th bit.
else if(transmitting == 1) begin
shiftIndex <= shiftIndex + 1;
dataOut <= data5b[shiftIndex];
if(shiftIndex == 4) begin
complete <= 1;
shiftIndex <= 0;
end
else begin
complete <= 0;
end
end
end
Both appear to do what I want in simulation, and I favor the 1st one because it's easier for me to read but since I don't understand why using blocking assignments for synchronous communication is nondeterministic, I'm worried that I've coded up a ticking time bomb
The Question: Am I doing something wrong in the 1st code that's going to blow up when I try to synthesize this? Is the 2nd code preferable despite being a bit harder (for me anyway) to read? Is there some 3rd thing I should be doing?
When using the blocking (=) assignment the value is available to use in the next line of code. This implies it is combinatorial and not driven from a flip-flop.
In simulation it looks like it is driven from a flip-flop because the block is only evaluated on positive clock edge, in reality it is not which might break the interface.
I am of the faction which says never mix styles, as it can be a problem in code reviews and refactoring. The refactor, if a module needs to output a new signal and it is seen that it already exists they just change to be an output. At first glance looked like it was a flip-flop because it was in a always #(posedge clk block.
Therefore I would recommend to NOT mix styles, but pull out the section that is combinatorial and put it in its own block. Does this still meet your requirements? if not then you would have had problem.
I do not see how data valid is controlled but it can change the output transmitting, potentially transmitting could also glitch as it is from a combinatorial decode, not driven cleanly from a flip-flop. The receiving interface might be async, glitches could cause lock up etc.
always #* begin
if(shiftIndex == 0) begin
if(dataValid == 1) transmitting = 1; //Blocking assign
else transmitting = 0; //Blocking assign
end
end
always # (posedge clk) begin
if(transmitting == 1) begin
shiftIndex <= shiftIndex + 1;
dataOut <= data5b[shiftIndex];
if(shiftIndex == 4) begin
complete <= 1;
shiftIndex <= 0;
end
else begin
complete <= 0;
end
end
end
As far as correctness is concerned, there is no problem with mixing blocking and non-blocking assignments, but you need to have a clear understanding of which signal is sequential and which signal is combinational block (note that the inputs of this combinational block come either from other sequential blocks or primary inputs). Also, you need to decide if you want any latches in your design or not.
If you use blocking assignments for a variable that you don't mean to be sequential, make sure to always assign to it, otherwise, it might be interpreted as a sequential element.
In your first code, you don't assign to transmitting when (shiftIndex != 0). This implies the previous value of transmitting should be used when (shiftIndex != 0), hence it would be a sequential element. But you need its value in the current clock, hence you used a blocking assignment.
Below is another version of your code, where firstBit_comb for the first bit is used and is always assigned to.
always # (posedge clk) begin
//Default value to avoid sequentials. Will be overwritten later if necessary
firstBit_comb = 0;
if(shiftIndex == 0) begin
if(dataValid == 1) begin
transmitting_seq <= 1;
firstBit_comb = 1;
end
else begin
transmitting_seq <= 0;
firstBit_comb = 1;
end
end
//Need the blocking assign up above to get this part to run
//for the 1st bit
if(firstBit_comb || transmitting_seq) begin
shiftIndex <= shiftIndex + 1;
dataOut <= data5b[shiftIndex];
if(shiftIndex == 4) begin
complete <= 1;
shiftIndex <= 0;
end
else begin
complete <= 0;
end
end
end
It is however more clear if you separate sequential and combinational blocks. Note that the next state of your sequential elements is often an output of a combinational block.
//combinational block
always_comb
begin
//The default value of next state is the previous state
transmitting_next = transmitting_seq;
//The default value of firstBit_comb=0. It would be overwritten if necessary
firstBit_comb = 0;
if(shiftIndex == 0 && dataValid == 1) begin
firstBit_comb = 1;
transmitting_next = 1;
end
else begin
firstBit_comb = 0;
transmitting_next = 0;
end
end
//Sequential block
always # (posedge clk) begin
//update transmitting_seq with its next state
transmitting_seq <= transmitting_next;
if(firstBit_comb || transmitting_seq) begin
shiftIndex <= shiftIndex + 1;
dataOut <= data5b[shiftIndex];
if(shiftIndex == 4) begin
complete <= 1;
shiftIndex <= 0;
end
else begin
complete <= 0;
end
end
end
I know that I should be using a non-blocking assignments in sequential always assignments. However, I accidentally happen to use a blocking assignment in part of my code, here it is:
reg tb_strobe = 0;
reg [9:0] tb_strobe_cnt = 0;
reg tb_sync = 0;
always#(posedge tb_clkh)
begin
if (~tb_resetl) begin
tb_strobe <= 0;
tb_strobe_cnt <= 0;
tb_sync <= 0;
end
else begin
if (tb_strobe_cnt == 1022) begin
tb_strobe <= 1;
tb_strobe_cnt <= tb_strobe_cnt + 1;
end else if (tb_strobe_cnt == 1023) begin
tb_strobe <= 0;
tb_strobe_cnt <= 0;
end else begin
tb_strobe <= 0;
tb_strobe_cnt <= tb_strobe_cnt + 1;
end
if (tb_strobe == 1) begin
tb_sync = 1; // <-- this is the mistakenly used blocking assignment
end else begin
end
end
end
And then my simulator behaves unpredictably, and once I fixed that assignment to be a non-blocking one, it started working fine !!!!
I am curious as to what was wrong with the above (in my specific code)?
In the way that I used it, since I am only calling tb_sync once in my code, I wasn't expecting any unpredictable behavior...
And tb_sync is not being assigned anywhere else in the code. Any idea what is wrong?
Non-blocking assignments are used to prevent race conditions between multiple processes that write and read the same variable on the same clock edge. It just takes one process that writes, and another process that reads the same variable on the same clock edge to create that race. Your example does not show the process that reads tb_sync, but I'm assuming that's where the race is.