Is an asynchronous counter made in Verilog synthesizable? - asynchronous

the question in it itself is simple. Is it possible to synthesize an Asynchronous counter in Verilog?
More explanation:
So for example, if I have something like the following code, is it possible to synthesize it?
always #(posedge clk) begin
//rst
if(!rst)begin
enable <=0;
end else begin
enable <= 1;
end
end
//action loop
always #(state) begin
case (state)
0:begin
cnt <= cnt
end
1: begin
cnt <= cnt + 1;
next_state <= 1;
end
default: begin
cnt <= cnt;
end
endcase
end
//state loop
always #(next_state, control, enable) begin
if(enable)begin
if(!control) begin
state <= next_state;
end else begin
state <= 0;
end
end
end
Here the general idea is that the counter will go asynchronously while the input control flag is 0, if it is 1 then the counter will be stopped until the input control flag becomes 0 again.
Note: I know I could try and synthesize the code and see what happens. But before that, I would like to know more and see if people have tried it.
Thanks for reading!!

Your action loop can't be properly synthesized.
What it is doing when state == 1?
Your state loop is synthesizable except but you will produce a latch (to store the value when enable == 0). This block is something that could be done using combinational logic '=' instead of non-blocking assignment '<='.

Related

Unwanted Asynchronous Reset

I have written the following VHDL code with the assumption that it will generate a counter with a synchronous reset! however, when I looked at the elaborated design in Vivado 2020.2, the counter has an ASYNCHRONOUS reset! The process should not get evaluated without seeing the rising/falling edges of the clock! How did the tool infer an asynchronous reset?!
PS. count is defined as an unsigned signal (not std_logic_vector)
Any explanation is greatly appreciated!
process(clk)
begin
if rst='1' then
count <= (others => '0');
elsif rising_edge(clk) then
count <= count + 1;
end if;
end process;
Synthesis tools generally ignore the sensitivity list, and create the logic from design patterns in the code. In your code, the rst branch overrides the clock branch, hence it creates an asynchronous reset. In addition, the reset is not reliant on clk.
To create a synchronous reset, the rst branch should be inside the clock branch as the reset should only occur on a clock edge.
process(clk)
begin
if rising_edge(clk) then
count <= count + 1;
if rst = '1' then
count <= (others => '0');
end if;
end if;
end process;

How to preserve a value in a case statement in verilog

When designing finite state machines in verilog, I find myself writing code like this a lot to preserve a value in a particular state.
always#(state, a, b) begin
case(state) begin
S1: a = b;
S2: a = a; // preserve a;
endcase
end
This is necessary because if I don’t specify a value for each register in the sensitivity list, the compiler will infer a latch. To me this feels like a code smell, but I’m not experienced enough to know for sure. Is this the best way to preserve a value in verilog?
Preserve state means to create a latch, which is a device that do exactly that.
a=a is a null statement and you should not use it at all.
Do not use sensetivity lists in the always block, they are error prone, use #* instead.
And, for latches, you should use non-blocking assignments.
Your latch case statement should look like the following:
always#(*) begin
case(state) begin
S1: a <= b;
S2: // do nothing about 'a', a will not change.
endcase
end
in general the FSM scheme use in industry uses clocks and looks like the following:
always#(posedge clk) begin
case(state) begin
S1: begin
next_state <= S2;
a <= b;
end
S2: // do nothing about 'a', a will not change.
....
endcase
end
assign state = next_state;

How should I go about resetting my reset signal in Verilog?

I have 2 always blocks, one that counts the number of clock cycles that have passed capable of asynchronous reset and another that triggers the reset signal on the negedge of some input signal.
always#(posedge clock or posedge reset)
begin: ClockCounter
if(reset == 1)
begin
clock_cnt = 1;
end
else
begin
clock_cnt = clock_cnt + 1;
end
end
always#(negedge pulse_in)
begin: Receiver
negedge_cnt = negedge_cnt + 1;
reset = 1;
.......Code goes on
end
end module
What I want to do is set the reset signal to 0 once the clock_cnt has been reset to 1 so it can continue counting in the following clock cycle. If I try to insert a reset = 0; after clock_cnt = 1; I get an issue with multiple drivers to the same signal. Does anybody have any idea how to do this?
Unless there is a really important reason to do so, and you have guaranteed glitchless combinational logic, you should not use asynchronous resets to clear registers. The typical approach would be to use a synchronous clear signal rather than use the asynchronous reset.
Heres what the code would look like:
always #(posedge clk or posedge reset) begin
if (reset) begin // Note that you need to separate the asynchronous reset and synchronous clear logic (ie, dont do 'if (reset | clr)')
counter <= 1; // Use non-blocking assignment for clocked blocks
end
else begin
if (clr) begin
counter <= 1;
end
else begin
counter <= counter + 1;
end
end
end
always #(posedge clk) begin // You need to synchronize your input pulse, Im assuming its synchronous to your clock, otherwise youll need a synchronizer
if (prev_pulse_in & ~pulse_in) begin
negedge_cnt <= negedge_cnt + 1;
clr <= 1;
end
else begin
clr <= 0;
end
prev_pulse_in <= pulse_in;
end
My solution was
always#(posedge clock or posedge reset)
begin: ClockCounter
if(reset == 1)
begin
clock_cnt = 1;
reset_flag = 1;
end
else
begin
clock_cnt = clock_cnt + 1;
reset_flag = 0;
end
end
always#(negedge pulse_in or posedge reset_flag)
begin
reset = 1;
if(reset_flag == 1)
reset = 0;
end

VHDL RS-232 Receiver

I have been trying to design an RS-232 receiver taking an FSM approach. I will admit that I do not have a very well-rounded understanding of VHDL, so I have been working on the code on the fly and learning as I go. However, I believe I've hit a brick wall at this point.
My issue is that I have two processes in my code, one to trigger the next state and the other to perform the combinational logic. My code is as follows:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ASyncReceiverV4 is
Port ( DataIn : in STD_LOGIC;
Enable : in STD_LOGIC;
CLK : in STD_LOGIC;
BadData : out STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (7 downto 0));
end ASyncReceiverV4;
architecture Behavioral of ASyncReceiverV4 is
type states is (StartBitCheck, ReadData, StopBitCheck);
signal currentState, nextState : states;
begin
process(CLK)
begin
if rising_edge(CLK) then
currentState <= nextState;
end if;
end process;
process(CLK)
variable counter : integer := 0;
variable dataIndex : integer := 0;
begin
case currentState is
when StartBitCheck =>
if Enable = '1' then
if (DataIn = '0' and counter < 8) then
counter := counter + 1;
elsif (DataIn = '0' and counter = 8) then
BadData <= '0';
nextState <= ReadData;
counter := 0;
else
nextState <= StartBitCheck;
end if;
end if;
when ReadData =>
if Enable = '1' then
if counter < 16 then
counter := counter + 1;
elsif (counter = 16 and dataIndex < 8) then
DataOut(dataIndex) <= DataIn;
counter := 0;
dataIndex := dataIndex + 1;
elsif dataIndex = 8 then
dataIndex := 0;
nextState <= StopBitCheck;
else
nextState <= ReadData;
end if;
end if;
when StopBitCheck =>
if Enable = '1' then
if DataIn = '1' then
if counter < 16 then
counter := counter + 1;
nextState <= StopBitCheck;
elsif counter = 16 then
counter := 0;
nextState <= StartBitCheck;
end if;
else
DataOut <= "11111111";
BadData <= '1';
nextState <= StartBitCheck;
end if;
end if;
end case;
end process;
end Behavioral;
For whatever reason, based on my simulations, it seems that my processes are out of sync. Although things are only supposed to occur at the rising edge of the clock, I have transitions occurring at the falling edge. Furthermore, it seems like things are not changing according to the value of counter.
The Enable input is high in all of my simulations. However, this is just to keep it simple for now, it will eventually be fed the output of a 153,600 Baud generator (the Baud generator will be connected to the Enable input). Hence, I only want things to change when my Baud generator is high. Otherwise, do nothing. Am I taking the right approach for that with my code?
I can supply a screenshot of my simulation if that would be helpful. I am also not sure if I am including the correct variables in my process sensitivity list. Also, am I taking the right approach with my counter and dataIndex variables? What if I made them signals as part of my architecture before any of my processes?
Any help on this would be very much so appreciated!
The easiest way to fix this, while also producing the easiest to read code, would be to move to a 1-process state machine like so (warning: not complied may contain syntax errors):
entity ASyncReceiverV4 is
Port ( DataIn : in STD_LOGIC;
Enable : in STD_LOGIC;
CLK : in STD_LOGIC;
BadData : out STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (7 downto 0));
end ASyncReceiverV4;
architecture Behavioral of ASyncReceiverV4 is
type states is (StartBitCheck, ReadData, StopBitCheck);
signal state : states := StartBitCheck;
signal counter : integer := 0;
signal dataIndex : integer := 0;
begin
process(CLK)
begin
if rising_edge(CLK) then
case state is
when StartBitCheck =>
if Enable = '1' then
if (DataIn = '0' and counter < 8) then
counter <= counter + 1;
elsif (DataIn = '0' and counter = 8) then
BadData <= '0';
state <= ReadData;
counter <= 0;
end if;
end if;
when ReadData =>
if Enable = '1' then
if counter < 16 then
counter <= counter + 1;
elsif (counter = 16 and dataIndex < 8) then
DataOut(dataIndex) <= DataIn;
counter <= 0;
dataIndex <= dataIndex + 1;
elsif dataIndex = 8 then
dataIndex <= 0;
state <= StopBitCheck;
end if;
end if;
when StopBitCheck =>
if Enable = '1' then
if DataIn = '1' then
if counter < 16 then
counter <= counter + 1;
elsif counter = 16 then
counter <= 0;
state <= StartBitCheck;
end if;
else
DataOut <= "11111111";
BadData <= '1';
state <= StartBitCheck;
end if;
end if;
end case;
end if;
end process;
end Behavioral;
Note that while this no longer contains language issues, there are still odd things in the logic.
You cannot enter the state StopBitCheck until counter is 16 because the state transition is in an elsif of counter < 16. Therefore, the if counter < 16 in StopBitCheck is unreachable.
Also note that the state transition to StopBitCheck happens on the same cycle that you would normally sample data, so the sampling of DataIn within StopBitCheck will be a cycle late. Worse, were you ever to get bad data (DataIn/='1' in StopBitCheck), counter would still be at 16, StartBitCheck would always go to the else clause, and the state machine would lock up.
Some more explanation on what was wrong before:
Your simulation has things changing on the negative clock edge because your combinatorial process only has the clock on the sensitivity list. The correct sensitivity list for the combinatorial process would include only DataIn, Enable, currentState, and your two variables, counter and dataIndex. Variables can't be a part of your sensitivity list because they are out of scope for the sensitivity list (also you do not want to trigger your process off of itself, more on that in a moment).
The sensitivity list is, however, mostly just a crutch for simulators. When translated to real hardware, processes are implemented in LUTs and Flip Flops. Your current implementation will never synthesize because you incorporate feedback (signals or variables that get assigned a new value as a function of their old value) in unclocked logic, producing a combinatorial loop.
counter and dataIndex are part of your state data. The state machine is simpler to understand because they are split off from the explicit state, but they are still part of the state data. When you make a two process state machine (again, I recommend 1 process state machines, not 2) you must split all state data into Flip Flops used to store it (such as currentState) and the output of the LUT that generates the next value (such as nextState). This means that for your two process machine, the variables counter and dataIndex must instead become currentCounter, nextCounter, currentDataIndex, and nextDataIndex and treated like your state assignment. Note that if you choose to implement changes to keep a 2-process state machine, the logic errors mentioned above the line will still apply.
EDIT:
Yes, resetting the counter back to 0 before moving into StopBitCheck might be a good idea, but you also need to consider that you are waiting the full 16 counts after sampling the last data bit before you even transition into StopBitCheck. It is only because counter is not reset that the sample is only off by one clock instead of 16. You may want to modify your ReadData action to transition to StopBitCheck as you sample the last bit when dataIndex=7 (as well as reset counter to 0) like so:
elsif (counter = 16) then
DataOut(dataIndex) <= DataIn;
counter <= 0;
if (dataIndex < 7) then
dataIndex <= dataIndex + 1;
else
dataIndex <= 0;
state <= StopBitCheck;
end if;
end if;
A pure state machine only stores a state. It generates its output purely from the state, or from a combination of the state and the inputs. Because counter and dataIndex are stored, they are part of the state. If you wanted to enumerate every single state you would have something like:
type states is (StartBitCheck_Counter0, StartBitCheck_counter1...
and you would end up with 8*16*3 = 384 states (actually somewhat less because only ReadData uses dataIndex, so some of the 384 are wholly redundant states). As you can no doubt see, it is much simpler to just declare 3 separate signals since the different parts of the state data are used differently. In a two process state machine, people often forget that the signal actually named state isn't the only state data that needs to be stored in the clocked process.
In a 1-process machine, of course, this isn't an issue because everything that is assigned is by necessity stored in flip flops (the intermediary combinational logic isn't enumerated in signals). Also, do note that 1-process state machines and 2-process state machines will synthesize to the same thing (assuming they were both implemented correctly), although I'm of the opinion that is comparatively easier to read and more difficult to mess up a 1-process machine.
I also removed the else clauses that maintained the current state assignment in the 1-process example I provided; they are important when assigning a combinational nextState, but the clocked signal state will keep its old value whenever it isn't given a new assignment without inferring a latch.
First Process runs just on CLK rising edge, while the second one runs on both CLK edge (because runs on every CLK change).
You use 2 process, “memory-state” and “next-state builder”, the first must be synchronous (as you done) and the second, normally, is combinatorial to be able to produce next-state in time for next CLK active edge.
But in your case the second process needs also to run on every CLK pulse (because of variable counter and index), so the solution can be to run the first on rising-edge and the second on falling-edge (if your hardware support this).
Here is your code a little bit revisited, I hope can be useful.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ASyncReceiverV4 is
Port ( DataIn : in STD_LOGIC;
Enable : in STD_LOGIC;
CLK : in STD_LOGIC;
BadData : out STD_LOGIC := '0';
DataOut : out STD_LOGIC_VECTOR (7 downto 0) := "00000000");
end ASyncReceiverV4;
architecture Behavioral of ASyncReceiverV4 is
type states is (StartBitCheck, ReadData, StopBitCheck);
signal currentState : states := StartBitCheck;
signal nextState : states := StartBitCheck;
begin
process(CLK)
begin
if rising_edge(CLK) then
currentState <= nextState;
end if;
end process;
process(CLK)
variable counter : integer := 0;
variable dataIndex : integer := 0;
begin
if falling_edge(CLK) then
case currentState is
when StartBitCheck =>
if Enable = '1' then
if (DataIn = '0' and counter < 8) then
counter := counter + 1;
elsif (DataIn = '0' and counter = 8) then
BadData <= '0';
nextState <= ReadData;
counter := 0;
else
nextState <= StartBitCheck;
end if;
end if;
when ReadData =>
if Enable = '1' then
if counter < 15 then
counter := counter + 1;
elsif (counter = 15 and dataIndex < 8) then
DataOut(dataIndex) <= DataIn;
counter := 0;
dataIndex := dataIndex + 1;
elsif dataIndex = 8 then
dataIndex := 0;
nextState <= StopBitCheck;
else
nextState <= ReadData;
end if;
end if;
when StopBitCheck =>
if Enable = '1' then
if DataIn = '1' then
if counter < 15 then
counter := counter + 1;
nextState <= StopBitCheck;
elsif counter = 15 then
counter := 0;
nextState <= StartBitCheck;
end if;
else
DataOut <= "11111111";
BadData <= '1';
nextState <= StartBitCheck;
end if;
end if;
end case;
end if;
end process;
end Behavioral;
This is a 0x55 with wrong stop bit receive data simulation

RS232 transmitter module in vhdl latches?

I'm trying to write RS232 transmitter module in vhdl for Spartan. According to simulation in Xilinx, it seems to be working fine, but when i try to deploy it on device, it simply doesn't work. I have found out that it might be problem with latches, but somehow I'm not able to pinpoint them. I'm using 50 Mhz clock and the bit rate of transmission is 115200 bs.
This is my vhdl code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_arith.all; -- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity nadajnikRS is
Port ( start : in STD_LOGIC;
reset : in STD_LOGIC;
clk : in STD_LOGIC;
DI : in STD_LOGIC_VECTOR(7 downto 0);
RS_TX : out STD_LOGIC;
busy : out STD_LOGIC);
end nadajnikRS;
architecture Behavioral of transRS is
signal register : STD_LOGIC_VECTOR(8 downto 0) := (others => '1' );
signal counter : INTEGER range 0 to 9 := 0;
signal baud_clk : STD_LOGIC := '0';
signal ready : STD_LOGIC := '0';
type states is (working, free);
signal state: states := free;
signal baud_counter : INTEGER range 0 to 220 := 215;
begin
baud_clock: process (clk)
begin
if rising_edge(clk) then
if (ready = '1') then
if (baud_counter < 218) then
if (baud_counter = 217) then
baud_clk <= '1';
end if;
baud_counter <= baud_counter+1;
else
baud_counter <= 0;
baud_clk <= '0';
end if;
else
baud_counter <= 0;
end if;
end if;
end process baud_clock;
shiftregister : process (baud_clk)
begin
if rising_edge(baud_clk) then
if (state = free) then
RS_TX <= '0';
register (7 downto 0) <= DI;
else
RS_TX <= register(0);
register <= '1' & register(8 downto 1);
end if;
end if;
end process shiftregister;
bitcounter : process (baud_clk)
begin
if rising_edge(baud_clk) then
counter <= counter + 1;
if (counter = 10) then
counter <= 1;
end if;
end if;
end process bitcounter;
shiftstate: process (reset, counter, start)
begin
if (reset = '1') then
ready <= '0';
end if;
if (start = '1') then
ready <= '1';
state <= free;
end if;
if (counter = 1 ) then
state <= working;
elsif (counter = 10) then
state <= free;
end if;
end process;
statemachine : process (state)
begin
case state is
when working => busy <= '1';
when free => busy <= '0' ;
end case;
end process statemachine;
end Behavioral;
During synthesis I get two latch warnings:
Xst:737 - Found 1-bit latch for signal <ready>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 1-bit latch for signal <state_0>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
I tried to eliminate them by adding additional if statements, but nothing seems to work.
I will be grateful for any help,
Ghaad
A process describing a register should have exactly one signal in the sensitivity list, clk (possibly a reset signal as well if you use asynchronous resets), since a register is only sensitive to a single event, namely a clock edge.
Thus your process sensitivity list baud_clock: process (clk,ready) and shiftregister : process (baud_clk, state) already indicate that you have a problem.
When describing a register, always make sure that your if(rising_edge(clk)) surrounds ALL of the described logic. A simple registered process should look like this:
process(clk) begin
-- NO LOGIC HERE
if(rising_edge(clk)) then
if(reset='1') then
-- Synchronous reset logic here.
else
-- All other logic here.
end if;
end if;
-- NO LOGIC HERE
end process;
Look at your 'shiftstate' process, which is responsible for driving 'ready'. How does it drive 'ready' when 'reset' is not 1, and 'start' is not 1? You haven't told it, so it keeps 'ready' unchanged in those cases. That's what 'latch' means: the process needs to remember what 'ready' was before, and keep it the same; your code therefore infers a memory. Make sure that 'ready' is driven in all branches; you can do this easily with a default assignment at the top.
Having said that, your code has multiple other issues. Did someone suggest in another thread that you shouldn't have your rising edge detection inside an if statement? Or was that someone else? Go back and read it again.
Try to fill all the posibilities of if statements so that for every run the program will know which value correspond to a variable. If statement has almost always go with else or elsif options to not produce latches..
A latch can occur when a process is allowed to go from start to finish without the driven outputs being assigned a value. That is if you have any conditional statements in your process and your outputs are driven inside these conditional statements then there a high chance that the outputs may never be driven. To avoid this it is good practice to place a concurrent statement at the beginning of your process to ensure your outputs are being set at least once. This will tell your synthesiser not to create a latch.

Resources