Case statement in VHDL test bench takes decremented value - case

I am working on a project using VHDL and I am facing a problem during one of my test benches. I testing all input combinations for a combinational component using a for loop in my stimulus process, but I have a case statement inside the foor loop which is not behaving the way I wish it to.
This is the code segment that isn't behaving the way I want it to:
for i in 0 to 20 loop
case opcode is
when "01001" | "01010" | "01100" | "01110" | "10000" =>
d <= '0';
wait for period;
d <= '1';
when "00010" | "00100" | "00101" | "00110" | "10001" | "10010" | "10011" =>
d <= '1';
when others =>
d <= '0';
end case;
wait for period;
opcode <= opcode + 1;
end loop;
As an example, I expect d to become 1 when opcode is 00010. In the simulation, however, d becomes 1 when opcode becomes 00011 rather than 00010 (same for all other cases too), as if the value the case statement checks is decremented by 1. I changed opcode inside the case statement to opcode+1 and it worked correctly. I do know that VHDL is a hardware description language and that its behavior differs from a programming language, but I still cannot wrap my head around why this is happening, and would like an explanation.

The update to the opcode signal is not 'sensed' by the simulator until it hits a wait statement. Adding wait for 0 ns; at the start of the loop fixes the problem.

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;

Is an asynchronous counter made in Verilog synthesizable?

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 '<='.

VHDL asynch ripple counter glitch

Here is a design for 4-bit asynchronous ripple counter (using T flip flop however I didn't define a component for Tff and just coded the behavior of circuit regarding T signals).
Following are the questions:
1.) inout ports, I first defined Q as inout (since it's obviously my output and the bits are also used as clk inputs to their following flip flops). Still, when I wanted to simulate my code, the Q output was UUUU which makes sense cause I had to initialize it with the number I wanted my count to begin with. Though I didn't know how to set an inout initial value (I tried Process ... Q <= "0000"; wait; end process but it didn't work)!
2.) In order to solve the above-mentioned problem I changed my inout port to out (Q_out) and defined Q as a signal, this worked BUT...my counter only changed the Q(0) bit and not the others...thus it counts like: 0,1,0,1,0,1,...
3.) I want to debug this code. I tried another style, instead of a 4-bit output I defined 4 1-bit output signals (Q_out1 to Q_out2) in addition to 4 internal signals Q0 to Q1 and this perfectly works
I just want to know why the first style (Q as a 4_bit vector) didn't work out.
thanks in advance for your help.
Here is my code and its test bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity four_bit_Asynch_Counter is
Port ( T0,T1,T2,T3 : in STD_LOGIC;
clk : in STD_LOGIC;
Q_out: out STD_LOGIC_VECTOR (3 downto 0));
end four_bit_Asynch_Counter;
architecture Behavioral of four_bit_Asynch_Counter is
signal Q : STD_LOGIC_VECTOR (3 downto 0) := "0000";
begin
Process (clk,Q(0),Q(1),Q(2))
begin
if (falling_edge(clk)) then
if (T0 = '1') then
Q(0) <= not Q(0);
else
Q(0) <= Q(0);
end if;
end if;
if (falling_edge(Q(0))) then
if (T1 = '1') then
Q(1) <= not Q(1);
else
Q(1) <= Q(1);
end if;
end if;
if (falling_edge(Q(1))) then
if (T2 = '1') then
Q(2) <= not Q(2);
else
Q(2) <= Q(2);
end if;
end if;
if (falling_edge(Q(2))) then
if (T3 = '1') then
Q(3) <= not Q(3);
else
Q(3) <= Q(3);
end if;
end if;
Q_out <= Q;
end Process;
end Behavioral;
--------------- Test Bench------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb_counter IS
END tb_counter;
ARCHITECTURE behavior OF tb_counter IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT four_bit_Asynch_Counter
PORT(
T0 : IN std_logic;
T1 : IN std_logic;
T2 : IN std_logic;
T3 : IN std_logic;
clk : IN std_logic;
Q_out : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal T0 : std_logic := '1';
signal T1 : std_logic := '1';
signal T2 : std_logic := '1';
signal T3 : std_logic := '1';
signal clk : std_logic := '0';
--Outputs
signal Q_out : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: four_bit_Asynch_Counter PORT MAP (
T0 => T0,
T1 => T1,
T2 => T2,
T3 => T3,
clk => clk,
Q_out => Q_out
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
The TL;DR answer is that q(3) doesn't show up in your process sensitivity list.
architecture behavioral of four_bit_asynch_counter is
signal q: std_logic_vector (3 downto 0) := "0000";
begin
process (clk, q(0), q(1), q(2))
begin
if falling_edge(clk) then
if t0 = '1' then
q(0) <= not q(0);
-- else
-- q(0) <= q(0);
end if;
end if;
if falling_edge(q(0)) then
if t1 = '1' then
q(1) <= not q(1);
-- else
-- q(1) <= q(1);
end if;
end if;
if falling_edge(q(1)) then
if t2 = '1' then
q(2) <= not q(2);
-- else
-- q(2) <= q(2);
end if;
end if;
if falling_edge(q(2)) then
if t3 = '1' then
q(3) <= not q(3);
-- else
-- q(3) <= q(3);
end if;
end if;
q_out <= q;
end process;
end architecture behavioral;
For your process sensitivity list you've discovered a feature in how the sensitivity list is constructed from the expression consisting of primaries - clk, q(0), q(1), q(2).
From IEEE Std 1076 -1993, 8.1 Wait statement:
...
The sensitivity set is initially empty. For each primary in the condition of the condition clause, if the primary is
-- A simple name that denotes a signal, add the longest static prefix of the name to the sensitivity set
-- A selected name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set
-- An expanded name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set
-- An indexed name whose prefix denotes a signal, add the longest static prefix of the name to the sensitivity set and apply this rule to all expressions in the indexed name
...
...
This rule is also used to construct the sensitivity sets of the wait statements in the equivalent process statements for concurrent procedure call statements( 9.3 ), concurrent assertion statements ( 9.4 ), and concurrent signal assignment statements ( 9.5 ).
If a signal name that denotes a signal of a composite type appears in a sensitivity list, the effect is as if the name of each scalar subelement of that signal appears in the list.
...
I only included elements of the rule that are of interest here, the first covers the clock the last element shown covers the std_logic_vector elements specified by selected names.
It helps to understand what is meant by the longest static prefix. This explained in -1993 6.1 Names.
The primaries (indexed names) are static names (q(0), q(1), q(2)), every expression that's part of each indexed name is static.
This means the longest static prefix is the indexed name comprising each primary.
And this leaves q(3) dangling in the breeze for the process signal assignment statement:
q_out <= q;
Without sensitivity to q(3) the value of q_out is not updated until the next event in the sensitivity list, which happens to be on clk:
There are two ways to cure this, you could move the q_out assignment outside the process statement, where it becomes a concurrent signal assignment (with an elaborated equivalent process with a sensitivity list set to q), or you can change the sensitivity list in the present process:
process (clk, q)
So that q_out is updated for an event on q(3) (noting the last quoted paragraph in 8.1 above).
This behavior hold true for later revisions of the standard as well.
With the process sensitivity list is fixed:
Your counter behaves properly.
Also note I commented out the redundant else assignments to the q(0), q(1), q(2) and q(3) a signal will hold it's value until assigned and these are sequential (clocked) statements. Also eliminated the redundant parentheses pairs.
When implementing counters in realisable hardware (either ASIC or FPGA) you should never use a ripple counter. By using the flip-flop output as a clock to the next you will have sub-optimal timing, the tools will not be able to accurately validate the setup and hold times and you are not able to take advantage of dedicated clock routing. In general asynchronous design is a bad idea for real implementations.
A true synchronous design will be much better for synthesis and is much easier to infer in the VHDL code.
Examples of Counter implementations
See the above link for both verilog and vhdl examples of counter implementation.

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