Verilog if statement assign error - verilog

I'm trying to learn verilog having done C++ before. As a learning exercise I'm trying to flash turn an LED on after seeing 10 button presses. I also have an additional reset button that starts the 10 count again. What ever I try I can't get it to compile. Can anyone point me in the right direction?
My code is:
module led_counter (button, nreset, led);
input button, nreset;
output led;
reg counter[4:0]; // to hold the current count
always # (negedge nreset) begin
counter <= 0; // Just reset counter
end
always # (negedge button) begin
if (counter == 10) begin // see if the button has been pressed 10 times
led_state <= 1; // turn the led on
end
else begin
led_state <= 0; // the led is off
counter <= counter + 1;
end
end
assign led = led_state;
endmodule

led_state is not declared, it should be a reg.
To have something more concise I would also regroup the two processes into one. It would make it look like a synchronous process with asynchronous reset, i.e. triggered by a clock and reseted on falling edge of a reset.
always # (posedge button or negedge nreset) begin
if(~nreset) //reset counter when nreset is low
counter <= 0;
else begin //do something on posedge of button
//Do something//
end //end process
It would also be more likely to be synthesized.

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

Timers and LEDs in Verilog

I have a question about using timers and clocks in Verilog. I want to set up a custom reg to compare to an accumulator, which will control the state of an LED. The board uses inverse logic, so 0 is high on the LED. There are a few concepts I just need some clarification on. The clock is 100 MHz.
always #(posedge clk100 or negedge reset_)
begin
cust_LED_counter <= (cust_LED_counter<cust_LED_timer) ? cust_LED_counter + 1'b1 : 16'd0;
cust_LED_timer1 <= (cust_LED_counter == cust_LED_timer);
if(!reset_)
begin
cust_LED1 <= 'b0;
cust_LED_timer <= 'd0;
cust_LED_timer1 <= 'd0;
end
else
begin
cust_LED1 <= ~cust_LED_timer1;
end
end
For the accumulator, what is the action that resets it and allows for blinking to happen? Would it not hit the cust_LED_timer value and stay at that high reading?
I think I'm misunderstanding how a FPGA clock operates. Assuming this would cause a blinking action in the LED, it would mean some timer hit the upper limit and reset; however, I'm not sure if this would take place in the counter portion of the code, or instead would occur where the clock/reset is defined.
Also, based on how this layout looks it wouldn't be a uniform blink, in terms of equal time on and off. Is there a way to implement such a system for custom input?
Here's a simple module that should blink the LED with a 50-50 duty cycle for an arbitrary number of clocks (up to 2^26)
module blink(input clk, input rst, input [25:0] count_max, output LED);
reg [25:0] counter, next_count;
assign LED = counter < count_max >> 1;
always #(posedge clk or posedge rst)
begin
if (rst)
counter <= 0;
else
counter <= next_count;
end
always #* begin
if (counter < count_max - 1)
next_count = counter + 1;
else
next_count = 0;
end
endmodule // blink
Let me know if this doesn't compile! I don't have a verilog compiler where I'm writing this from at the moment!

"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.

How to program a delay in Verilog?

I'm trying to make a morse code display using an led. I need a half second pulse of the light to represent a dot and a 1.5 second pulse to represent a dash.
I'm really stuck here. I have made a counter using an internal 50MHz clock on my FPGA. The machine I have to make will take as input a 3 bit number and translate that to a morse letter, A-H with A being 000, B being 001 and so on. I just need to figure out how to tell the FPGA to keep the led on for the specified time and then turn off for about a second (that would be the delay between a dot pulse and a dash pulse).
Any tips would be greatly appreciated.
Also, it has to be synthesizable.
Here is my code. It's not functioning yet. The error message it keeps giving me is:
Error (10028): Can't resolve multiple constant drivers for net "c3[0]"
at part4.v(149)
module part4 (SELECT, CLK, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, CLK, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; //goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3; //keeps track of the index we are on in the code.
reg [3:0] STATE; //register to keep track of states in the state machine
reg done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1 to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
parameter START= 4'b000, DOT= 4'b001, DASH= 4'b010, DELAY= 4'b011, IDLE=
4'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always #(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==8'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
COUNT2 <= 0;
else if ((COUNT2==2)&&(halfsecflag==1))
begin
COUNT2 = 0;
dashflag=1;
end
else if (halfsecflag==1)
COUNT2= COUNT2+1;
end
always #(RESET) //asynchronous reset
begin
STATE=IDLE;
end
always#(STATE) //State machine
begin
done=0;
case(STATE)
START: begin
led = 1;
if (i) STATE = DOT;
else STATE = DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE = DELAY;
else if (ending) STATE= IDLE;
else STATE=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE = DELAY;
else if (ending)
STATE = IDLE;
else STATE = DASH;
end
DELAY: begin
led = 0;
if ((halfsecflag)&&(ending))
STATE=IDLE;
else if ((halfsecflag)&&(~ending))
begin
done=1;
STATE=START;
end
else STATE = DELAY;
end
IDLE: begin
c3=0;
if (CLK) STATE=START;
else STATE=IDLE;
end
default: STATE = IDLE;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: length=2'b01;
B: length=2'b11;
C: length=2'b11;
D: length=2'b10;
E: length=2'b00;
F: length=2'b11;
G: length=2'b10;
H: length=2'b11;
default: length=2'bxx;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: code= 4'b0001;
B: code= 4'b1110;
C: code= 4'b1010;
D: code= 4'b0110;
E: code= 4'b0001;
F: code= 4'b1011;
G: code= 4'b0100;
H: code= 4'b1111;
default: code=4'bxxxx;
endcase
end
always #(posedge CLK)
begin
if (c3==length)
begin
c3<=0; ending=1;
end
else if (done)
c3<= c3+1;
end
endmodule
I have been reading your code and there are many issues:
The code is not formatted.
You did not provide a test-bench. Did you write one?
"Can't resolve multiple constant drivers for net" Search on stack exchange for the error message. It has been asked many times.
Use always #(*) not e.g. always #(STATE) you are missing signals like i, halfsecflag, ending. But see point 6: You want the STATE in a clocked section.
Where you use always #(posedge CLK) you must use non-blocking assignments: <=.
There are many places where you use always #(posedge CLK) where you want to use always #(*) (e.g. where you set length and code) Opposite you want to use a posedge CLK where you work with your STATE.
Use one clock and one clock only. Do not use CLK and CLOCK_50. Use either one or the other.
Take care of your vector sizes. This 8'd25000000 is wrong as you can no fit 25000000 in 8 bits.
Your usage of halfsecflag is excellent! I have see many times where people think they can use always #(halfsecflag) which is a recipe for disaster!
Below you find a small piece of your code which I have re-written.
All assignments are non-blocking <=
halfsecflag is essential to operate the code only every half a second, so I put that by itself in a separate if at the top. I would use that throughout the code.
All register are reset, both COUNT2 and dashflag.
dashflag was set to 1 but never set back to 0. I fixed that.
I specified the vector sizes. It makes the code "Lint proof".
Here is it:
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1'b1)
begin
COUNT2 <= 2'd00;
dashflag <= 1'b0;
end // reset
else if (halfsecflag) // or if (halfsecflag==1'b1)
begin
if (COUNT2==2'd2))
begin
COUNT2 <= 2'd0;
dashflag <=1'b1;
end
else
begin
COUNT2 <= COUNT2+2'd1;
dashflag <=1'b0;
end
end // clocked
end // always
Start fixing the rest of your code the same way. Write a test-bench, simulate and trace on a waveform display where things go wrong.
Normally you would build the finite state machine to produce the output. That machine would have some stages, like reading the input, mapping it to a sequence of morse code element, shifting out the elements to output buffer, waiting for conditions to move to the next morse element. You will need some timer that would produce one morse time unit intervals, and depending on the FSM stage you will wait one, three or seven time units. The FSM will spin in the waiting stage, it doesn't "magically" sleeps in some fpga-produced delay, there's no such things.
Okay a year later, I know exactly what one should do if they want to create a delay in their verilog program! Essentially, what you should do is create a timer using one of the clocks on your FPGA. For me on my Altera DE1-SoC, the timer I could use is the 50MHz clock known as CLOCK_50. What you do is make a timer module that triggers on the positive (or negative, doesn't matter) edge of the 50MHz clock. Set up a count register that holds a constant value. For example, reg [24:0] timer_limit = 25'd25000000; This is a register that can hold 25 bits. I've set this register to hold the number 25 million. The idea is to flip a bit every time the value in this register is exceeded. Here's some pseudocode to help you understand:
//Your variable declarations
reg [24:0] timer_limit = 25'd25000000; //defining our timer limit register
reg [25:0] timer_count = 0; //See note A
reg half_sec_clock;
always#(posedge of CLOCK_50) begin
if timer_count >= timer_limit then begin
reset timer_count to 0;
half_sec_clock = ~half_sec_clock; //toggle your half_sec_clock
end
Note A: Setting it to zero may or may not initialize count, it's always best to include a reset function that clears your count to zero because you don't know what the initial state is when you're dealing with hardware.
This is the basic idea of how to introduce timing into your hardware. You need to use an onboard clock on your device, trigger on the edge of that clock and create your own slower clock to measure things like seconds. The example above will give you a clock that triggers periodically every half second. For me, this allowed me to easily make a morse code light that could flash on either 1 half second count, or 3 half seconds. My best advice to you beginners is to work in a modular fashion. For example build your half second clock and then test it out to see if you can get a light on your FPGA to toggle once every half second (or whatever interval you want). :) I really hope this is the answer that helps you. I know this is what I was looking for when I originally posted this question so long ago.

Block of code inside always block is being executed without the input changing in the sensitivity list

Whenever the input to the sensitivity list is a variable (which is an input to the module; a button on the FPGA) the block of code gets executed regardless of the fact whether the value of this variable has changed or not, even though the block of code inside the always block should only be executed when the value of the variable given to it as a parameter in its sensitivity list changes; hence being called sensitivity list.
The block of code is as follows:
always #(in)
begin
count = count + 1;
end
in: input taken from a button on the FPGA
Is our block of code wrong in some way, or should the sensitivity list only take posedge or negedge?
I'm not familiar with the rules/practices of writing asynchronous logic, but here's my 2 cents on dealing with button presses:
Try writing a debounce module to detect when the button is pressed, then use the result of the debounce module as the enable signal for your counter. The sensitivity list of the counter in this case would be based on posedge clk.
Here's an explanation for why you need the debounce module.
The debounce module works as follows: let's say to register a button press the button is held down for 3ms and released for another 3ms. (Feel free to play with the time.) Therefore, we need two counters: pressed and released. The pressed counter counts to 3ms then sets the condition to allow the release counter to start counting. Once the release counter has reached 3ms, then the button has been registered as pressed.
module debounce(
clk,
button_input,
button_pressed
);
// Input and output ports
input clk, button_input;
output button_pressed;
reg button_pressed;
// Signals for pressed and released counters
reg [15:0] pressed_out, pressed_next_out, released_out, released_next_out;
reg pressed_enable, pressed_reset, released_enable, released_reset;
reg pressed_ok, released_ok;
// Counter for when button is pressed down
// Increment counter
always # (*) begin
if (button_input) begin
pressed_next_out = pressed_out + 1'b1;
end else begin
pressed_next_out = 16'h00000;
end
end
// Flop incremented value
always # (posedge clk)
pressed_out <= pressed_next_out;
// Check if button was pressed (3ms)
always # (posedge clk) begin
if (&pressed_out) begin
pressed_ok <= 1;
end else if (released_ok) begin
pressed_ok <= 0;
end
end
// Counter for when button is released
// Increment counter
always # (*) begin
if (~button_input && pressed_ok) begin
released_next_out = released_out + 1'b1;
end else begin
released_next_out = 16'b0;
end
end
// Flop incremented value
always # (posedge clk)
released_out <= released_next_out;
// Check if button was released (3ms)
always # (posedge clk) begin
if (&released_out) begin
released_ok <= 1;
end else begin
released_ok <= 0;
end
end
// Check if button was pressed and released
always # (posedge clk)
button_pressed <= pressed_ok && released_ok;
endmodule

Resources