I have a simple module that uses a few different states. The Problem I am encountering is say if I want to stay at the same state for multiple clock cycles.
In this case, my current state is synchronous and updates on clock cycle. It executes that always block which goes from state 0 -> state 1. Then once pstate reaches state 1, I attempt to have it wait to reach the next state. The reason for this is to collect data off of the data_int input. I don't care what the data is, but I need to read off it for 2 clock cycles.
I believe this doesn't work however because in the first case, I set the next state to the same value as it previously was, so it is unable to trigger. The reason I don't think I could just also add 'data_int' to the trigger list, is because its possible it remains the same value for a clock cycle and thus the always block wouldn't trigger.
I'm wondering if there is another way to do this, I guess essentially I need the always block to retrigger on clock edge as well..
module TestModule(
input clk, rst, data_int);
reg [2:0] pstate = 0;
reg [2:0] nstate = 0;
ref [2:0] count = 0;
always#(pstate) begin
//only fires when pstate is assigned to a different value?
//would I make a internal clock to constantly have this always run?
if(pstate == 0) begin
nstate <= 1;
end
else if(pstate == 1) begin
//stay at this state for multiple clock cycles
//collect data off of data_int
count = count + 1;
if(count > 2) begin
nstate <= 2;
end else begin
nstate <= 1;
end
end
end
always#(posedge clk, posedge rst) begin
if(rst) begin
pstate <= 0;
end
else begin
pstate <= nstate;
end
end
pay attention to the usage of = and <=.
count is never reset, if you want to enter pstate == 3'h1 state multiple times.
use always#(*) to save your life. synthesis tools will respect the logic inside the always block, but simulation tools won't, which will lead to simulation mismatches.
The following code is based on my understanding of your question.
reg [2:0] pstate;
reg [2:0] nstate;
reg count; // 1-bit 'count' is enough to count 2 cycles
always#(posedge clk or posedge rst)begin
if(rst)begin
pstate <= 3'h0;
end
else begin
pstate <= nstate;
end
end
always#(*)begin
case(pstate)
3'h0: nstate = 3'h1;
3'h1:begin // lasts 2 cycles
if(count)begin
nstate = 3'h2;
end
else begin
nstate = 3'h1;
end
3'h2: (....)
default: (....)
end
endcase
end
always#(posedge clk or posedge rst)begin // 'count' logic
if(rst)begin
count <= 1'h0;
end
else if((pstate == 3'h1) & count)begin // this branch is needed if you don't
// count to the max. value of 'count'
count <= 1'b0;
end
else if(pstate == 3'h1)begin
count <= ~count; // if 'count' is multi-bit, use 'count + 1'
end
end
Related
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
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.
I'm a begginer of Verilog. I read a several materials about recommended Verilog coding styles like this paper and stackoverflow's questions.
Now, I learned from them that "two always block style" is recommended; separate a code into two parts, one is a combinational block that modifies next, and the another is a sequential block that assigns it to state reg like this.
reg [1:0] state, next;
always #(posedge clk or negedge rst_n)
if (!rst_n)
state <= IDLE;
else
state <= next;
always #(state or go or ws) begin
next = 'bx;
rd = 1'b0;
ds = 1'b0;
case (state)
IDLE : if (go) next = READ;
else next = IDLE;
...
And here is my question. All example codes I found have only one pair of registers named state and next.
However, if there are multiple regs that preserve some kinds of state, how should I write codes in this state-and-next style?
Preparing next regs corresponding to each of them looks a little redundant because all regs will be doubled.
For instance, please look at an UART sender code of RS232c I wrote below.
It needed wait_count, state and send_buf as state regs. So, I wrote corresponding wait_count_next, state_next and send_buf_next as next for a combinational block. This looks a bit redundant and troublesome to me. Is there other proper way?
module uart_sender #(
parameter clock = 50_000_000,
parameter baudrate = 9600
) (
input clk,
input go,
input [7:0] data,
output tx,
output ready
);
parameter wait_time = clock / baudrate;
parameter send_ready = 10'b0000000000,
send_start = 10'b0000000001,
send_stop = 10'b1000000000;
reg [31:0] wait_count = wait_time,
wait_count_next = wait_time;
reg [9:0] state = send_ready,
state_next = send_ready;
reg [8:0] send_buf = 9'b111111111,
send_buf_next = 9'b111111111;
always #(posedge clk) begin
state <= state_next;
wait_count <= wait_count_next;
send_buf <= send_buf_next;
end
always #(*) begin
state_next = state;
wait_count_next = wait_count;
send_buf_next = send_buf;
case (state)
send_ready: begin
if (go == 1) begin
state_next = send_start;
wait_count_next = wait_time;
send_buf_next = {data, 1'b0};
end
end
default: begin
if (wait_count == 0) begin
if (state == send_stop)
state_next = send_ready;
else
state_next = {state[8:0], 1'b0};
wait_count_next = wait_time;
send_buf_next = {1'b1, send_buf[8:1]};
end
else begin
wait_count_next = wait_count - 1;
end
end
endcase
end
assign tx = send_buf[0];
assign ready = state == send_ready;
endmodule
I think you did a good job and correctly flopped the variables. The issue is that without flops you would have a loop. i.e. if you write something like the following, the simulation will loop and silicon will probably burn out:
always_comb wait_count = wait_count - 1;
So, you need to stage this by inserting a flop:
always_ff #(posedge clk)
wait_count <= wait_count - 1;
Or in your case you you used an intermediate wait_count_next which is a good style:
always_ff #(posedge clk)
wait_count_next <= wait_count;
always_comb
wait_count = wait_count_next;
You might or might not have an issue with the last assignments. Which version of the signals you want to assign to tx and ready? the flopped one or not?
And yes, you can split theses blocks in multiple blocks, but in this case there seems to be no need.
And yes, the other style would be write everything in a single flop always block. But this will reduce readability, will be more prone to your errors and might have synthesis issues.
I am creating a vending machine in verilog. There is one button on the FPGA board to act as the coin inserter, every time the button is pushed it will add a 'quarter' to the total amount the user can spend, and display the total on the left and right seven segment displays.
Ex.
1st button push : 25 cents
2nd button push : 50 cents
3rd button push : 75 cents
4th button push : $1.00 (10 on the seven segment display).
Wont increment after the 4th button press.
input quarterIn,
output reg [4:0] state,
output reg [4:0] next_state,
output reg totalChange,
output reg [7:0] RSSD,
output reg [7:0] LSSD
);
/***coin implementation***/
parameter
c0 = 0,
c1 = 1,
c2 = 2,
c3 = 3,
c4 = 4;
always #(posedge clock)
begin
state = next_state;
end
always # (quarterIn or totalChange)
begin
case(totalChange)
0: begin if(quarterIn == 1) totalChange = 1; state = c1; end
1: begin if(quarterIn == 1) totalChange = 2; state = c2; end
2: begin if(quarterIn == 1) totalChange = 3; state = c3; end
3: begin if(quarterIn == 1) totalChange = 4; state = c4; end
4: begin if(quarterIn == 1) totalChange = 4; state = c4; end
endcase
end
I am getting stuck on how to keep count of the button clicks. I can see the first value on the seven segment display, but am unsure as to how to increment the total coins. I couldn't find any sort of information on this from trying to research on my own.
From what I understood, you need a saturating counter to keep track of the button presses.
In order to count, you need a clock in the system:
input clock;
And you'll need a reset signal to initialize the counter to a known value, zero in this case:
input reset;
And the counter (equivalent to the state variable, let me just call it num_push):
reg [2:0] num_push;
The saturating counter can be specified this way:
always #(posedge clock) begin
if (reset) begin // Active high, synchronous reset
num_push <= 3'b0;
end else begin
if (quarterIn == 1'b1 && num_push != 3'b100) begin
num_push <= num_push + 3'b1;
end
end
end
This will synthesize to a counter with a count-enable on your FPGA and the enable will be equal to quarterIn == 1'b1 && num_push != 3'b100. You could press reset to start over.
Now, there are a few issues to be addressed before we put this on an FPGA. First of all, quarterIn needs to be synced for metastability:
reg quarterIn_f;
reg quarterIn_sync;
always #(posedge clock) begin
quarterIn_f <= quarterIn;
quarterIn_sync <= quarterIn_f;
end
We should use only quarterIn_sync in the design and never quarterIn directly. You should do the same with for the reset signal as well.
Second, the signals that come from the keys need to be debounced. Debouncing is a whole topic in itself, so I'll skip it for the time being :(
Another thing is that the clock needs to be pulled from the onboard clock generator circuitry and this clock will be running at a few MHz. A typical button-press lasts for about 500ms and this means our counter will sample a few hundred thousand keypresses in a single press. To avoid this, we should count the edge of quarterIn_sync, and not the level:
wire quarterIn_edge;
req quarterIn_sync_f;
always #(posedge clock) begin
if (reset) begin
quarterIn_sync_f <= 1'b0;
end else begin
quarterIn_sync_f <= quarterIn_sync;
end
end
assign quarterIn_edge = quarterIn_sync & ~quarterIn_sync_f; // Detects rising edge
Now, replace the quarterIn in the saturating counter code with quarterIn_edge:
always #(posedge clock) begin
if (reset) begin
num_push <= 3'b0;
end else begin
if (quarterIn_edge == 1'b1 && num_push != 3'b100) begin
num_push <= num_push + 3'b1;
end
end
end
And we're done!
I have the following code
module POLY(CLK,RESET_n,IN_VALID,IN,OUT_VALID,OUT);
input CLK,RESET_n,IN_VALID;
input [ 3:0] IN;
output OUT_VALID;
output [12:0] OUT;
reg OUT_VALID;
reg [12:0] OUT;
reg OUT_VALID_w;
reg [12:0] OUT_w;
reg [ 1:0] COUNT_IN, COUNT_IN_w;
reg [ 2:0] COUNT_DO, COUNT_DO_w;
always #(posedge CLK or negedge RESET_n)
begin
if(!RESET_n)
begin
COUNT_IN <= 2'd0;
COUNT_DO <= 3'd0;
end
else
begin
COUNT_IN <= COUNT_IN_w;
COUNT_DO <= COUNT_DO_w;
end
end
always #(*)
begin
if(IN_VALID == 1'b0)
begin
if(COUNT_DO == 3'd7)
begin
COUNT_DO_w = COUNT_DO;
end
else
begin
COUNT_DO_w = COUNT_DO + 1'b1;
end
end
else
begin
COUNT_DO_w = 3'd0;
end
end
I want to ask is that why COUNT_DO doesn't jump to 1 in 14ns?
I think that due to the sensitive list in the second always block is COUNT_DO and IN_VALID,
so at start, the reset signal trigger first always block and set the COUNT_DO = 0, which change the COUNT_DO value from high impedence to 0. So, it triggers the second always block COUNT_DO_w = 0 + 1 = 1. And , in the next postive edge clock, which trigger the first always block to do COUNT_DO <= COUNT_DO_w. But it seems to delay one clock to assign it(22ns). I have tried to figure it out but still cannot, why it delay one clock?
Thx in advance.
At time=14ns, reset is asserted (RESET_N=0), which means COUNT_DO=0 in the 1st always block. At time t=20ns, you release reset and COUNT_DO remains at 0. At time=22ns, you have your 1st posedge CLK which assigns COUNT_DO to COUNT_DO_w. The time at which COUNT_DO changes is controlled only by the 1st always block, not the 2nd.