How to control a flag in two different procedural blocks in verilog? - verilog

I want to rise a flag once I enter procedural block#1, and I want to reset it to zero in another procedural block. Of course I get an error saying the flag is driven by too many drivers. How can I overcome this problem?
Block 1, sensitive to sw (FPGA board switches):
always # (sw)
flag =1;
begin
case (sw)
8'bxxxxxx01: x2= 13'd1249;
8'bxxxxxx10: x2= 13'd2499;
8'bxxxxxx11: x2= 13'd3749;
endcase
end
Block 2, sensitive to CLK:
always # (posedge CLK)
begin
if (counter2 == x2)
begin
counter2 <=0;
flag=0;
end
else
counter2 <= counter2 +1;
end
Assuming all initialization are taken care of.

One method is to have set and reset flags and a FSM which listens to these flags.
localparam S_RESET = 2'b0;
localparam S_SET = 1'b1;
reg state;
always #(posedge clk) begin
case ({flag_set, flag_reset})
2'b00 : state <= state;
2'b01 : state <= S_RESET;
2'b10 : state <= S_SET;
2'b11 : state <= S_SET; //Choose priority
endcase
end
But to note that always # (sw) should be written as always #(*) ie with an automatic sensitivity list. This represents a combinatorial block of hardware, all outputs should be based on inputs (or flipflops).
I hope this makes it clear that:
always # (sw)
flag =1;
does not represent hardware and will not be synthesisable. flag is based on triggering the simulator not a value based on an input.

Related

Verilog FSM being optimised away

New to Verilog, Basys3 board and Vivid 2021.2.
Trying to implement a typical stopwatch with Stop/Start and Lap/Reset buttons.
A divider produces 1kHz and 100Hz clock from the board clock, 100Hz is for button debounce (and seven segment display multiplexing, next todo), the 1kHz drives a 20 bit 5 x 4 bit BCD counter, the low 16 bits of which drive a latch to freeze the display, the latch drives the 16 on board LEDs.
I've test 'wired' this up and the modules perform as expected. It's only when I add the FSM I run into trouble.
The FSM is simple, the two buttons determine the state changes and the state sets three outputs to control the counter.
The state module as been through many versions, tried using buttons in the sensitivity list, tried with button edges and levels, tried *, tried blocking and non-blocking assignments, can't get it right. The current error is:
[Synth 8-3332] Sequential element (state/transfer_reg) is unused and will be removed from module stopwatch.
The error changes but it's always Synth 8-3332 removing something, even curr_state or next_state.
The RTL synthesis schematic shows exactly what I expect, later schematics show the two buttons, 16 LEDs and nothing in between.
I'm lost at this stage, have I missed something fundamental?
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
//
// Create Date: 02/02/2022 0800
//
// Module Name: state
// Project Name: Stop Watch
// Target Devices: BASYS 3
//
// state machine
//
// inputs:
// start-stop button via debounce (both edg and level are available)
// lap-reset buttonvia debounce (both edg and level are available)
//
// outputs:
// control 4 x 4 bit BCD counters and output latch
// clear state
// enabvble couter to count
//. transfer counter value to latch
//
////////////////////////////////////////////////////////////////////////////////
module state (
input clk,
input lap_reset,
input start_stop,
output reg clear,
output reg enable,
output reg transfer
);
// state encodings
localparam
RESET_0 = 3'd0,
STOPPED_1 = 3'd1,
RUNNING_2 = 3'd2,
PRELAP_3 = 3'd3,
LAP_4 = 3'd4;
// state reg
reg[2:0] curr_state;
reg[2:0] next_state;
// setup
initial
begin
curr_state <= RESET_0;
next_state <= RESET_0;
enable <= 0;
clear <= 0;
transfer <= 0;
end
// sync state transitons to clk
// always # (posedge clk)
// begin
// curr_state <= next_state;
// end
// state machine
always # (posedge clk)
begin
curr_state <= next_state;
case (curr_state)
RESET_0:
begin
// init, stop counter, clear counter
// transfer count to latch
enable <= 0;
clear <= 1;
transfer <= 1;
next_state <= STOPPED_1;
end
STOPPED_1:
begin
// stop counter, clear counter
enable <= 0;
clear <= 0;
transfer <= 0;
if (start_stop)
next_state <= STOPPED_1;
else if (lap_reset)
next_state <= RESET_0;
else
next_state <= curr_state;
end
RUNNING_2:
begin
// start or continue counting
// transfer count to latch
enable <= 1;
clear <= 0;
transfer <= 1;
if (start_stop)
next_state <= STOPPED_1;
else if (lap_reset)
next_state <= PRELAP_3;
else
next_state <= curr_state;
end
PRELAP_3:
begin
// start or continue counting
// don't update latch
enable <= 1;
clear <= 0;
transfer <= 0;
next_state <= LAP_4;
end
LAP_4:
begin
// continue counting
// transfer counter to latch
enable <= 1;
clear <= 0;
transfer <= 1;
if (start_stop)
next_state <= RUNNING_2;
else if (lap_reset)
next_state <= PRELAP_3;
else
next_state <= curr_state;
end
default:
begin
enable <= 0;
clear <= 0;
transfer <= 0;
next_state <= RESET_0;
end
endcase
end
endmodule
Getting somewhere at last, thankyou all.
After correcting a logical error and a couple of constants 0'b0 which make little sense (the compiler didn't complain about them) and doing suggested fixes my stopwatch works.
The SM structure is the 3 blocks, sync transitions, next state 'gotos' and state actions. I started with the suggested always # (*) but had to change to a posedge clk for it to work, not sure why.
Got rid of the inferred latches and now understand why they come about.
About generating a reset signal, I assume the Artix chip has one but it doesn't get a mention in the supplied xdc file, I was trying to simulate a reset held low (active) then going high a short time later, determined by a clock divider - which should have a reset... Also read Xilinx WP272 which tells a different story.
Thanks again.
Just from www.javatpoint.com/verilog-initial-block:
"An initial block is not synthesizable and cannot be converted into a
hardware schematic with digital elements. The initial blocks do not
have more purpose than to be used in simulations. These blocks are
primarily used to initialize variables and drive design ports with
specific values."
I am not sure now about the code for that FPGA, but in common ASICs I would remove the "initial" code section, which you use to implement the reset behaviour and add an actual reset section in the always#.
always#(posedge clk)
begin
if (rst) begin
// do the reset
curr_state <= RESET_0;
next_state <= RESET_0;
enable <= 0;
clear <= 0;
transfer <= 0;
end else begin
// the rest
end
end
EDITED:
Never leave a signal without a default value, as it will infer latches instead of flip-flops, which create problems when inferring sequential logic (of course latches are useful in some scenarios).
When one wants to build a finite state machine (FSM) there are two common approaches: Mealy and Moore. I will explain how the sequential logic should be implemented with a Moore FSM:
A synchronous always# block to write the state: cur_state <= next state.
A combinational block to generate next_state value based on cur_state and inputs.
A combinational block to generate outputs based on the state.
always#(posedge clk, rst)
begin
if (rst = '1') begin
cur_state <= State_0;
end else begin
cur_state <= next_state;
end
end
always_comb(cur_state, my_inputA)
begin
if (cur_state = State_0) begin
if(my_inputA)
next_state = State_1;
else
next_state = Stage_0;
end else if (cur_state = State_1) begin
next_state = State_2;
end
end
always_comb(cur_state)
begin
if (cur_state = State_0) begin
my_outputA = '1';
end else if (cur_state = State_1) begin
my_outputA = '0';
end else if (cur_state = State_2) begin
my_outputA = '1';
end
end

"ERROR: multiple drivers on net" when setting a register on both positive and negative edges

I was following a tutorial on SPI master in Verilog. I've been debugging this for about three hours now and cannot get it to work.
I've been able to break down the issue into a minimum representative issue. Here are the specifications:
We have two states, IDLE and COUNTING. Then, on the clock positive edge, we check:
If the state is IDLE, then the counter register is set to 0. If while in this state the dataReady pin is high, then the state is set to COUNTING and the counter is set to all 1s.
If the state is COUNTING, the state remains COUNTING as long as counter is not zero. Otherwise, the state is returned to IDLE.
Then, we count on the negative edge:
On the negative edge of clock if state is COUNTING, then decrement counter.
Here's the code I came up with to fit this specification:
// look in pins.pcf for all the pin names on the TinyFPGA BX board
module top (
input CLK, // 16MHz clock
input PIN_14,
output LED, // User/boot LED next to power LED
output USBPU // USB pull-up resistor
);
// drive USB pull-up resistor to '0' to disable USB
assign USBPU = 0;
reg [23:0] clockDivider;
wire clock;
always #(posedge CLK)
clockDivider <= clockDivider + 1;
assign clock = clockDivider[23];
wire dataReady;
assign dataReady = PIN_14;
parameter IDLE = 0, COUNTING = 1;
reg state = IDLE;
reg [3:0] counter;
always #(posedge clock) begin
case (state)
IDLE: begin
if (dataReady)
state <= COUNTING;
end
COUNTING: begin
if (counter == 0)
state <= IDLE;
end
endcase
end
always #(negedge clock) begin
if (state == COUNTING)
counter <= counter - 1;
end
always #(state) begin
case (state)
IDLE:
counter <= 0;
COUNTING:
counter <= counter;
endcase
end
assign LED = counter != 0;
endmodule
With this, we get the error:
ERROR: multiple drivers on net 'LED' (LED_SB_DFFNE_Q.Q and LED_SB_DFFNE_Q_1.Q)
Why? There is literally only one assign statement on the LED.
First of all it would not be easy to come up with a synthesizable model in such a case. But, you do not need any negedge logic to implement your model. Also you made several mistakes and violated many commonly accepted practices.
Now about some problems in your code.
By using non-blocking assignment in the clock line you created race condition in the simulation which will probably cause incorrect simulation results:
always #(posedge CLK)
clockDivider <= clockDivider + 1; // <<< this is a red flag!
assign clock = clockDivider[23];
...
always #(posedge clk)
you incorrectly used nbas in your always block
always(#state)
... counter <= conunter-1; // <<< this is a red flag again!
your state machine has no reset. Statements like reg state = IDLE; will only work in simulation and in some fpgas. It is not synthesizable in general. I suggest that you do not use it but provide a reset signal instead.
Saying that, i am not aware of any methodology which would use positive and negative edges in such a case. So, you should not. All your implementation can be done under the posedge, something like the following. However
always #(posedge clock) begin
if (reset) begin // i suggest that you use reset in some form.
state <= IDLE;
counter <= 0;
end
else begin
case (state)
IDLE: begin
if (dataReady) begin
state <= COUNTING;
counter <= counter - 1;
end
end
COUNTING: begin
if (counter == 0)
state <= IDLE;
else
counter <= counter - 1;
end
endcase
end
end
I hope i did it right, did not test.
Now you do not need the other two always blocks at all.

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 code, same structure, same style. How come one works but the other doesnt? Where did I go wrong?

I will get straight to the point. I have a simple counter that is trying to
mimic how a clock works pretty much. I have a module called counter60sec and another one called counter12hr
counter12hr
module counter12hr(reset, hourInc, overflowOut, hrCounter);
input reset;
input hourInc;
output overflowOut;
output [3:0] hrCounter;
reg overflowOut;
reg [3:0] hrCounter; //0'b1101 == 13 hours
//Initialize counter
initial begin
overflowOut = 1'b0;
hrCounter = 4'b0; //once hour reaches 12:59:59, it is supposed to go back to zero
end
//Everytime hrInc is one, increment hrCounter
always#(negedge reset or posedge hourInc) begin
overflowOut = 1'b0;
if(reset == 1'b0) begin
overflowOut = 1'b0;
hrCounter = 4'b0;
end
else begin
if (hourInc == 1'b1) begin
hrCounter = hrCounter + 1'b1;
end
end
end
always#(negedge hrCounter) begin
if (hrCounter == 4'b1100) begin
overflowOut = 1'b1;
hrCounter = 4'b0;
end
end
endmodule
counter60sec
module counter60sec(reset, secInc, minOut, secCounter);
input reset;
input secInc;
output minOut;
output [5:0] secCounter;
reg [5:0] secCounter; //0'b111100 == 60 seconds.
reg minOut;
//Initialize counter
initial begin
minOut = 1'b0;
secCounter = 6'b0;
end
//Everytime secInc is one, increment secCounter
always#(posedge secInc or negedge reset) begin
minOut = 1'b0;
if(reset == 1'b0) begin
minOut = 1'b0;
secCounter = 6'b0;
end
else begin
if (secInc == 1'b1) begin
secCounter = secCounter + 1'b1;
end
end
end
//output minOut to 1 to signal minute increase when secCounter hits 111100 in binary
always#(negedge secCounter) begin
if(secCounter == 6'b111100) begin
minOut = 1'b1;
secCounter = 6'b0;
end
end
endmodule
I have test bench set up for both. The counter60sec one works fine (Where when secCounter is at value of 60, the minOut becomes 1). The counter12hr follows the same concept, but the value of overflowOut never becomes 1.
For my hrCounter conditional statement in counter12hr.v, I have tried both 4'b1101 and 4'b1100 and neither of them worked. (Trying to get the overflowOut to become one when the hrCounter hits 13)
I've spent hours on this, taking break to relax my eyes etc. I still can't see where I am going wrong. Any help would be appreciated
you have a few issues. The main one is that you have a multiple-driven register in both cases:
always#(negedge reset or posedge hourInc) begin
overflowOut = 1'b0;
...
always#(negedge hrCounter) begin
if (hrCounter == 4'b1100) begin
overflowOut = 1'b1;
the overflowOut is driven from 2 different alsways blocks. Same as minOut in the second counter. The order in which those statements are executed is undefined and the resulting value would depend on the order.
You need to restructure your program in such a way that the registers are assigned in a single always block only.
Secondly, i think, that you have a logic bug, assigning your overflow to '0' in the first statement of the first block (same as in the second one).
Thirdly, you should have uset non-blocking assighments '<=' in finlal assignments to the registers.
something like the following should work.
always#(negedge reset or posedge hourInc) begin
if(reset == 1'b0) begin
hrCounter <= 4'b0;
overflowOut <= 1'b0;
end
else begin
if (hrCounter == 4'b1100) begin
overflowOut <= 1'b1;
hrCounter <= 4'b0;
end
else
hrCounter <= hrCounter + 1'b1;
overflowOut <= 1'b0;
end
end
end
Your code is wrong in so many ways...
Most likely it does not work because of:
#(negedge hrCounter)
You are using a vector but #... works with bits. So it will look at the LS bit only.
As to your code:first and most start using a clock. Do not use posedge and negedge of your signals to drive the other signals.
You use:
always#(posedge secInc ...
...
if (secInc == 1'b1)
Remove the 'if'. you have that condition already in your always statement. (But the signal should not be the 'always' anyway, it should be your clock)
Remove the 'initial' sections You have a reset which defines the start condition.
If you have an active low reset reflect that in the name. Call it reset_n or n_reset anything but 'reset' which is per convention a positive reset signal.
If your drive ANYTHING from an edge, be it from a clock or from other signals, use non-blocking assignments "<="
Do not use your generated signal edges to generate other signals. As mentioned use a clock for everything an in the clocking section use an if. Also do not drive signals from different 'always'. You can never know in which order they are executed and then you have a race condition. Thus the clear and the increment are all in one always block:
if (secCounter == 6'b111100) begin
minOut <= 1'b1;
secCounter <= 6'b0;
end
else
secCounter <= secCounter + 6'b000001;
Because of the timing aspect you now have to go to 59 not 60. Which is as you should expect as digital clocks and watches run from 00 to 59, not 00 to 60. You are allowed to use decimal numbers which will, again, make the code more readable: 6'd59, 4'd11

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.

Resources