VHDL signal does not change value - vhdl

I am currently trying to implement a state machine with 5 different states. Basically, I want to stay in one state, wait for some time, move on to the next state, wait for a different amount of time, get into the next state etc....
For now I implemented a counter which generates a 1s signal from a 1ms signal that I create in the testbench. I created one process that determines the next state and one that upgrades the current state from the next state. The signal which does not behave as I expected is: next_stateHS which should upgrade stateHS. The code in question is in the process called "hsNextState". What I also can't explain is that the signal "startCounter" behaves as expected. This signal receives a new value in the same else - case as the signal "next_StateHS"
I will now add the code for the state machine and the test bench and a picture of the simulated waveform.
State machine:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity ampel is
port
(
clk : in std_ulogic;
reset : in std_ulogic;
enable : in std_ulogic;
haupt : out std_ulogic_vector(2 downto 0);
neben : out std_ulogic_vector(2 downto 0)
);
end ampel;
architecture ampel_behave of ampel is
--Codierung
-- idle = 000
-- gruen = 001
-- gelb = 010
-- rot = 011
-- rot_gelb = 100
signal stateHS, stateNS : std_ulogic_vector(2 downto 0) := (others => '0');
signal next_stateHS, next_stateNS : std_ulogic_vector(2 downto 0) := (others => '0');
signal startCounter : std_ulogic := '0';
signal counter : unsigned(9 downto 0) := (others => '0'); --für clk = 1ms im Testbench
signal count_seconds : unsigned(3 downto 0) := (others => '0');
begin
counterProcess : process(clk, reset, enable, startCounter)
begin
if enable = '0' or reset = '1' or startCounter = '0' then
counter <= (others => '0');
count_seconds <= (others => '0');
elsif rising_edge(clk) then
if counter < "1111101000" then
counter <= counter + 1;
else
counter <= (others => '0');
count_seconds <= count_seconds + 1;
end if;
end if;
end process counterProcess;
outputProcessHS : process(stateHS, reset, enable)
begin
if enable = '0' or reset = '1' then
haupt <= "000";
else
case (stateHS) is
when "000" =>
haupt <= "000";
when "001" =>
haupt <= "001";
when "010" =>
haupt <= "010";
when "011" =>
haupt <= "011";
when "100" =>
haupt <= "100";
when others =>
haupt <= "000";
end case;
end if;
end process outputProcessHS;
outputProcessNS : process(stateNS, reset, enable)
begin
if enable = '0' or reset = '1' then
neben <= "000";
else
case (stateNS) is
when "000" =>
neben <= "000";
when "001" =>
neben <= "001";
when "010" =>
neben <= "010";
when "011" =>
neben <= "011";
when "100" =>
neben <= "100";
when others =>
neben <= "000";
end case;
end if;
end process outputProcessNS;
hsNextState : process(reset, enable, stateHS, count_seconds)
begin
if enable = '0' or reset = '1' then
next_stateHS <= "000";
else
case (stateHS) is
when "000" =>
next_stateHS <= "001";
startCounter <= '1';
when "001" =>
if count_seconds < "1110" then
next_stateHS <= "001";
else
next_stateHS <= "010";
startCounter <= '0';
end if;
when "010" =>
next_stateHS <= "011";
when "011" =>
next_stateHS <= "100";
when "100" =>
next_stateHS <= "001";
when others =>
next_stateHS <= "000";
end case;
end if;
end process hsNextState;
hsState : process(reset, enable, next_stateHS, count_seconds)
begin
if enable = '0' or reset = '1' then
stateHS <= "000";
else
stateHS <= next_stateHS;
end if;
end process hsState;
-- nsStateProcess : process(reset, enable, stateNS, count_seconds)
-- begin
-- if enable = '0' or reset = '1' then
-- next_stateNS <= idle;
-- else
-- case (stateNS) is
-- when idle =>
-- next_stateNS <= gruen;
-- when gruen =>
-- next_stateNS <= gelb;
-- when gelb =>
-- next_stateNS <= rot;
-- when rot =>
-- next_stateNS <= rot_gelb;
-- when rot_gelb =>
-- next_stateNS <= gruen;
-- when others =>
-- next_stateNS <= idle;
-- end case;
-- end if;
-- stateNS <= next_stateNS;
-- end process nsStateProcess;
end ampel_behave;
Test Bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity ampel_tb is
end ampel_tb;
architecture test of ampel_tb is
component ampel
port
(
clk : in std_ulogic;
reset : in std_ulogic;
enable : in std_ulogic;
haupt : out std_ulogic_vector(2 downto 0);
neben : out std_ulogic_vector(2 downto 0)
);
end component;
signal clk : std_ulogic := '0';
signal reset : std_ulogic := '0';
signal enable : std_ulogic := '1';
signal haupt, neben : std_ulogic_vector(2 downto 0);
signal count_cycles : unsigned (19 downto 0) := (others => '0');
begin
ampel_1 : ampel port map
(
clk => clk,
reset => reset,
enable => enable,
haupt => haupt,
neben => neben
);
clock_signal : process
begin
if count_cycles < "0011100000000000000" then
clk <= '0';
wait for 500 us;
clk <= '1';
wait for 500 us;
count_cycles <= count_cycles + 1;
else
wait;
end if;
end process clock_signal;
end test;

Related

VHDL Vivado Combinatorial Loop Alert

I am trying to implement a simple ALU:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity simple_alu is
Port (
clk : in std_logic;
rst : in std_logic;
op : in std_logic_vector (1 downto 0);
in0 : in std_logic_vector (31 downto 0);
in1 : in std_logic_vector (31 downto 0);
res : out std_logic_vector (31 downto 0);
done_flag : out std_logic
);
end simple_alu;
architecture Behavioral of simple_alu is
type state_type is (start, add, sub, mul, pow, done);
signal state, next_state : state_type := start;
signal status : std_logic := '0';
signal inter, shift_reg, zero : std_logic_vector (31 downto 0) := (others => '0');
begin
SYNC_PROC: process (clk, rst)
begin
if (rst = '0') then
if rising_edge(clk) then
state <= next_state;
res <= inter;
done_flag <= status;
end if;
else
state <= start;
res <= (others => '0');
done_flag <= '0';
end if;
end process;
--MEALY State-Machine - Outputs based on state and inputs
OUTPUT_DECODE: process (state, in0, in1, shift_reg)
variable result, temp : std_logic_vector (31 downto 0);
variable flag : std_logic := '0';
begin
shift_reg <= in1;
temp := temp;
flag := flag;
result := result;
case state is
when start =>
result := std_logic_vector(to_signed(1, 32));
temp := in0;
flag := '0';
when add => result := std_logic_vector(signed(in0) + signed(in1));
when sub => result := std_logic_vector(signed(in0) - signed(in1));
when mul => result := std_logic_vector(resize(signed(in0) * signed(in1), 32));
when pow =>
if (shift_reg(shift_reg'low) = '1') then
result := std_logic_vector(resize(signed(result) * signed(temp), 32));
else
result := result;
end if;
temp := std_logic_vector(resize(signed(temp) * signed(temp), 32));
shift_reg <= std_logic_vector(shift_right(signed(shift_reg), 1));
when done =>
result := result;
flag := '1';
when others =>
end case;
inter <= result;
status <= flag;
end process;
NEXT_STATE_DECODE: process (state, op, shift_reg, zero, rst) -- rst indicates that one input (op, in0 or in1) changed
begin
--declare default state for next_state to avoid latches
next_state <= state; --default is to stay in current state
case (state) is
when start =>
case (op) is
when "00" => next_state <= add;
when "01" => next_state <= sub;
when "10" => next_state <= mul;
when "11" => next_state <= pow;
when others => next_state <= done;
end case;
when add => next_state <= done;
when sub => next_state <= done;
when mul => next_state <= done;
when pow =>
if (shift_reg = zero) then
next_state <= done;
else
next_state <= pow;
end if;
when done =>
if (rst = '1') then
next_state <= start;
end if;
when others =>
end case;
end process;
end Behavioral;
This seems to be working, at least in this testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity simple_alu_tb is
end simple_alu_tb;
architecture Behavioral of simple_alu_tb is
component simple_alu is
Port (
clk : in std_logic;
rst : in std_logic;
op : in std_logic_vector (1 downto 0);
in0 : in std_logic_vector (31 downto 0);
in1 : in std_logic_vector (31 downto 0);
res : out std_logic_vector (31 downto 0);
done_flag : out std_logic
);
end component;
signal clk : std_logic := '0';
signal rst : std_logic := '0';
signal op : std_logic_vector (1 downto 0) := (others => '0');
signal in0 : std_logic_vector (31 downto 0) := (others => '0');
signal in1 : std_logic_vector (31 downto 0) := (others => '0');
signal res : std_logic_vector (31 downto 0) := (others => '0');
signal done_flag : std_logic := '0';
constant clk_period : time := 1 ns;
begin
--Instantiate the Unit Under Test (UUT)
uut: simple_alu Port Map (
clk => clk,
rst => rst,
op => op,
in0 => in0,
in1 => in1,
res => res,
done_flag => done_flag
);
-- Clock process definitions
clk_process :process
begin
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
end process;
stim_proc: process
begin
wait for 2*clk_period;
rst <= '1';
wait for clk_period;
rst <= '0';
wait for 4*clk_period;
op <= "00"; -- add
in0 <= std_logic_vector(to_signed(12, 32));
in1 <= std_logic_vector(to_signed(3, 32));
rst <= '1';
wait for clk_period;
rst <= '0';
wait for 2*clk_period;
assert (res = std_logic_vector(to_signed(15, 32))) report "addition failed" severity failure;
wait for 4*clk_period;
op <= "01"; -- sub
in0 <= std_logic_vector(to_signed(12, 32));
in1 <= std_logic_vector(to_signed(3, 32));
rst <= '1';
wait for clk_period;
rst <= '0';
wait for 2*clk_period;
assert (res = std_logic_vector(to_signed(9, 32))) report "subtraction failed" severity failure;
wait for 4*clk_period;
op <= "10"; -- mul
in0 <= std_logic_vector(to_signed(12, 32));
in1 <= std_logic_vector(to_signed(3, 32));
rst <= '1';
wait for clk_period;
rst <= '0';
wait for 2*clk_period;
assert (res = std_logic_vector(to_signed(36, 32))) report "multiplication failed" severity failure;
wait for 4*clk_period;
op <= "11"; -- pow
in0 <= std_logic_vector(to_signed(12, 32));
in1 <= std_logic_vector(to_signed(7, 32));
rst <= '1';
wait for clk_period;
rst <= '0';
wait for 4*clk_period;
assert (res = std_logic_vector(to_signed(35831808, 32))) report "power failed" severity failure;
wait for 4*clk_period;
op <= "11"; -- pow
in0 <= std_logic_vector(to_signed(12, 32));
in1 <= std_logic_vector(to_signed(6, 32));
rst <= '1';
wait for clk_period;
rst <= '0';
wait for 4*clk_period;
assert (res = std_logic_vector(to_signed(2985984, 32))) report "power failed" severity failure;
wait;
end process;
end Behavioral;
I would like to implement that as AXI4-lite component. So I generate the wrapper, adapt the write process and instantiate my module as follows:
...
process (S_AXI_ACLK)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
-- command_reg <= (others => '0');
-- done_flag <= '0';
slv_reg1 <= (others => '0');
slv_reg2 <= (others => '0');
-- slv_reg3 <= (others => '0');
else
loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
if (slv_reg_wren = '1') then
case loc_addr is
when b"00" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-4) loop -- write to command register only
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 0
command_reg(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"01" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 1
slv_reg1(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when b"10" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 2
slv_reg2(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
-- when b"11" => -- do not write to reg3
-- for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
-- if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- -- Respective byte enables are asserted as per write strobes
-- -- slave registor 3
-- slv_reg3(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
-- end if;
-- end loop;
when others =>
command_reg <= command_reg;
done_flag <= done_flag;
slv_reg1 <= slv_reg1;
slv_reg2 <= slv_reg2;
-- slv_reg3 <= slv_reg3;
end case;
end if;
end if;
end if;
end process;
...
-- Add user logic here
-- byte0 byte1 byte2 byte3
slv_reg0 <= done_flag & "0000000" & "00000000" & "00000000" & command_reg;
alu : simple_alu
port map (
clk => S_AXI_ACLK,
rst => slv_reg_wren, -- reset on every write to a register, high active
op => command_reg(1 downto 0),
in0 => slv_reg1,
in1 => slv_reg2,
res => slv_reg3,
done_flag => done_flag
);
-- User logic ends
But when I try to generate the bitstream for my wrapper design which includes the Zync UltraScale+ MPSoC, AXI Interconnect, Processor System Reset and my AXI Peripheral I get the following error:
ERROR: [DRC LUTLP-1] Combinatorial Loop Alert: 1 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate. The preferred resolution is to modify the design to remove combinatorial logic loops. If the loop is known and understood, this DRC can be bypassed by acknowledging the condition and setting the following XDC constraint on any one of the nets in the loop: 'set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets <myHier/myNet>]'. One net in the loop is design_1_i/simple_alu_0/U0/simple_alu_v1_0_S00_AXI_inst/alu/state[0]_i_2_n_0. Please evaluate your design. The cells in the loop are: design_1_i/simple_alu_0/U0/simple_alu_v1_0_S00_AXI_inst/alu/state[0]_i_2.
ERROR: [DRC LUTLP-1] Combinatorial Loop Alert: 1 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate. The preferred resolution is to modify the design to remove combinatorial logic loops. If the loop is known and understood, this DRC can be bypassed by acknowledging the condition and setting the following XDC constraint on any one of the nets in the loop: 'set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets <myHier/myNet>]'. One net in the loop is design_1_i/simple_alu_0/U0/simple_alu_v1_0_S00_AXI_inst/alu/state[1]_i_3_n_0. Please evaluate your design. The cells in the loop are: design_1_i/simple_alu_0/U0/simple_alu_v1_0_S00_AXI_inst/alu/state[1]_i_3.
Please excuse the huge amount of code, I couldn't find a way to show the error with a smaller example.
I tried the solution proposed here:
set_property SEVERITY {Warning} [get_drc_checks LUTLP-1]
But that did nothing. I also tried setting set_property ALLOW_COMBINATORIAL_LOOPS TRUE for the two nets but that leaves me unsure about the functionality of my circuit. I am using Vivado v2018.3, my target is the Ultra96 from Avnet. Any clues?
EDIT: I have updated the code to reflect the current implementation, I get warnings about latches for result_reg, flag_reg and temp_reg. How do I resolve those?
After a long struggle I finally came up with this solution:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity simple_alu is
Port (
clk : in std_logic;
rst : in std_logic;
op : in std_logic_vector (1 downto 0);
in0 : in std_logic_vector (31 downto 0);
in1 : in std_logic_vector (31 downto 0);
res : out std_logic_vector (31 downto 0);
done_flag : out std_logic
);
end simple_alu;
architecture Behavioral of simple_alu is
type state_type is (start, add, sub, mul, pow, done);
signal state, next_state : state_type := start;
signal result, next_result, temp, next_temp, shift_reg, next_shift_reg, zero : std_logic_vector (31 downto 0) := (others => '0');
signal next_done_flag : std_logic := '0';
begin
SYNC_PROC: process (clk, rst)
begin
if rising_edge(clk) then
if (rst = '1') then
state <= start;
else
state <= next_state;
res <= next_result;
result <= next_result;
temp <= next_temp;
shift_reg <= next_shift_reg;
done_flag <= next_done_flag;
end if;
end if;
end process;
--MEALY State-Machine - Outputs based on state and inputs
OUTPUT_DECODE: process (state, result, in0, in1, temp, shift_reg)
begin
next_done_flag <= '0';
next_result <= result;
next_shift_reg <= shift_reg;
next_temp <= temp;
case state is
when start =>
next_result <= std_logic_vector(to_signed(1, 32));
next_temp <= in0;
next_shift_reg <= in1;
when add => next_result <= std_logic_vector(signed(in0) + signed(in1));
when sub => next_result <= std_logic_vector(signed(in0) - signed(in1));
when mul => next_result <= std_logic_vector(resize(signed(in0) * signed(in1), 32));
when pow =>
if (shift_reg(shift_reg'low) = '1') then
next_result <= std_logic_vector(resize(signed(result) * signed(temp), 32));
else
next_result <= result;
end if;
next_temp <= std_logic_vector(resize(signed(temp) * signed(temp), 32));
next_shift_reg <= std_logic_vector(shift_right(signed(shift_reg), 1));
when done => next_done_flag <= '1';
when others =>
end case;
end process;
NEXT_STATE_DECODE: process (state, op, shift_reg, zero)
begin
--declare default state for next_state to avoid latches
next_state <= state; --default is to stay in current state
case (state) is
when start =>
case (op) is
when "00" => next_state <= add;
when "01" => next_state <= sub;
when "10" => next_state <= mul;
when "11" => next_state <= pow;
when others => next_state <= done;
end case;
when add => next_state <= done;
when sub => next_state <= done;
when mul => next_state <= done;
when pow =>
if (shift_reg = zero) then
next_state <= done;
else
next_state <= pow;
end if;
when done =>
when others =>
end case;
end process;
end Behavioral;
The problem was that I did not understand how hardware description works, now I know a little (at least I hope so..). Especially how clocked and unclocked processes are connected (save intermediate results in registers). I will leave this question up just in case another beginner stumbles upon the same issue. If you think I should remove it, please state that in a comment and I will do so.
Here are some resources that helped me:
this question and in particular the accepted answer
some rules I picked up somewhere:
Don't read from the signals to which you write.
Have a correct sensitivity list (all signals that you read should be in the sensitivity list)
Make sure that all signals to which your write are assigned in every path. (for example: in each branch of an if-else-statement)
For processes which use variable, make sure every variable is initialized a default value before reading it (in another variable or signal ).

VHDL Parametric Division Circuit - Book: FPGA Prototyping by VHDL Examples, Pong Chu

I'm trying to follow an example on my VHDL book. Its name is FPGA Prototyping by VHDL Examples, Pong Chu. It has a Divider Circuit example in Chapter 6, Listing 5. I understood the general idea of a division operation. To verify the module I wrote a testbench and I saw that it doesn't work properly. If anyone could explain to me where the problem is, I would be very appreciated.
Here are the codes of module and testbench.
Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Divider is
generic(W: integer := 8;
CBIT: integer := 4 );
Port ( clk, reset : in STD_LOGIC;
start : in STD_LOGIC;
dvsr, dvnd : in STD_LOGIC_VECTOR (W-1 downto 0);
ready, done_tick : out STD_LOGIC;
quo, rmd : out STD_LOGIC_VECTOR (W-1 downto 0));
end Divider;
architecture Behavioral of Divider is
type state_type is (idle, op, last, done);
signal state_reg, state_next: state_type;
signal rh_reg, rh_next: UNSIGNED(W-1 downto 0) := (others => '0');
signal rl_reg, rl_next: STD_LOGIC_VECTOR(W-1 downto 0) := (others => '0');
signal rh_temp: UNSIGNED(W-1 downto 0) := (others => '0');
signal d_reg, d_next: UNSIGNED(W-1 downto 0) := (others => '0');
signal n_reg, n_next: UNSIGNED(CBIT-1 downto 0) := (others => '0');
signal q_bit: STD_LOGIC;
begin
-- FSMD State and Data Registers
process(clk, reset)
begin
if reset = '1' then
state_reg <= idle;
rh_reg <= (others => '0');
rl_reg <= (others => '0');
d_reg <= (others => '0');
n_reg <= (others => '0');
elsif rising_edge(clk) then
state_reg <= state_next;
rh_reg <= rh_next;
rl_reg <= rl_next;
d_reg <= d_next;
n_reg <= n_next;
end if;
end process;
-- FSMD Next-State Logic and Data Path Logic
process(state_reg, n_reg, rh_reg, rl_reg, d_reg, start, dvsr, dvnd, q_bit, rh_temp, n_next)
begin
ready <= '0';
done_tick <= '0';
state_next <= state_reg;
rh_next <= rh_reg;
rl_next <= rl_reg;
d_next <= d_reg;
n_next <= n_reg;
case state_reg is
when idle =>
ready <= '1';
if start = '1' then
rh_next <= (others => '0');
rl_next <= dvnd; -- Dividend
d_next <= UNSIGNED(dvsr); -- Divisor
n_next <= TO_UNSIGNED(W+1, CBIT); -- Index
state_next <= op;
end if;
when op =>
--Shift rh and rl left
rl_next <= rl_reg(W-2 downto 0) & q_bit;
rh_next <= rh_temp(W-2 downto 0) & rl_reg(W-1);
--Decrease index
n_next <= n_reg - 1;
if(n_next = 1) then
state_next <= last;
end if;
when last =>
rl_next <= rl_reg(W-2 downto 0) & q_bit;
rh_next <= rh_temp;
state_next <= done;
when done =>
state_next <= idle;
done_tick <= '1';
end case;
end process;
-- Compare and Subtract
process(rh_reg, d_reg)
begin
if rh_reg <= d_reg then
rh_temp <= rh_Reg - d_reg;
q_bit <= '1';
else
rh_temp <= rh_reg;
q_bit <= '0';
end if;
end process;
-- Output
quo <= rl_reg;
rmd <= STD_LOGIC_VECTOR(rh_reg);
end Behavioral;
Testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_Divider is
-- Port ( );
end tb_Divider;
architecture Behavioral of tb_Divider is
signal clk, reset, start, ready, done: STD_LOGIC;
signal dvsr, dvnd: STD_LOGIC_VECTOR(7 downto 0);
signal quo, rmd: STD_LOGIC_VECTOR(7 downto 0);
component Divider is
port( clk, reset : in STD_LOGIC;
start : in STD_LOGIC;
dvsr, dvnd : in STD_LOGIC_VECTOR (7 downto 0);
ready, done_tick : out STD_LOGIC;
quo, rmd : out STD_LOGIC_VECTOR (7 downto 0));
end component Divider;
begin
UUT: Divider port map( clk => clk, reset => reset, start => start, dvsr => dvsr, dvnd => dvnd,
ready => ready, done_tick => done, quo => quo, rmd => rmd);
process
begin
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
end process;
process
begin
start <= '0';
dvnd <= x"00";
dvsr <= x"00";
wait for 100 ns;
start <= '1';
dvnd <= x"C8";
dvsr <= x"0A";
wait for 10 us;
end process;
end Behavioral;
Result of Testbench:

State machine and unsigned signal

I have a few problems with a fairly simple state machine I made. No matter what I do, the signal startS1, startS2, enS and mS always stays unsigned in simulation even when I hit the reset button and I can't figure out why. There's a component in the mix, but I did test the component and it works perfectly. I hope you can help me!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity machine_etat is
generic (N_bit : integer := 8);
Port ( LOAD : in STD_LOGIC_VECTOR (N_bit-1 downto 0);
RESET : in STD_LOGIC;
START : in STD_LOGIC;
CLK : in STD_LOGIC;
OUTPUT : out STD_LOGIC_VECTOR (N_bit-1 downto 0));
end machine_etat;
architecture Behavioral of machine_etat is
TYPE machine is (IddleT, DepartT, LoadT, ShiftT, EndT);
SIGNAL Etat1, Etat2 : machine:= IddleT;
SIGNAL mS: STD_LOGIC_VECTOR (1 downto 0);
SIGNAL enS : STD_LOGIC;
SIGNAL outputS : STD_LOGIC_VECTOR (N_bit-1 downto 0);
component Reg_decal is
generic (N_bit : integer := N_bit);
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
EN : in STD_LOGIC;
M : in STD_LOGIC_VECTOR (1 downto 0);
LOAD : in STD_LOGIC_VECTOR (N_bit-1 downto 0);
OUTPUT : out STD_LOGIC_VECTOR (N_bit-1 downto 0));
end component;
SIGNAL startS1, startS2 : STD_LOGIC;
begin
OUTPUT <= outputS;
Reg_dec: Reg_decal
generic map (N_bit => N_bit)
port map (CLK => CLK,
RESET => RESET,
EN => enS,
M => mS,
LOAD => LOAD,
OUTPUT => outputS);
Machine1: process (CLK)
begin
if RESET = '1' then
enS <= '0';
mS <= "00";
startS1 <= '0';
startS2 <= '0';
Etat1 <= IddleT;
elsif rising_edge(CLK) then
CASE Etat1 is
WHEN IddleT =>
if startS1 = '1' OR START = '1' then
Etat1 <= DepartT;
else
Etat1 <= IddleT;
end if;
WHEN DepartT =>
Etat1 <= LoadT;
startS1 <= '0';
WHEN LoadT =>
mS <= "11";
enS <= '1';
Etat1 <= ShiftT;
WHEN ShiftT =>
mS <= "00";
Etat1 <= EndT;
WHEN EndT =>
enS <= '0';
startS2 <= '1';
Etat1 <= IddleT;
WHEN Others =>
Etat1 <= IddleT;
end CASE;
end if;
end process;
Machine2: process (CLK)
begin
if RESET = '1' then
Etat2 <= IddleT;
elsif rising_edge(CLK) then
CASE Etat2 is
WHEN IddleT =>
if startS2 = '1' then
Etat2 <= DepartT;
else
Etat2 <= IddleT;
end if;
WHEN DepartT =>
startS2 <= '0';
Etat2 <= LoadT;
WHEN LoadT =>
enS <= '1';
Etat2 <= ShiftT;
WHEN ShiftT =>
mS <= "01";
Etat2 <= EndT;
WHEN EndT =>
Etat2 <= IddleT;
startS1 <= '1';
WHEN Others =>
end CASE;
end if;
end process;
end Behavioral;
Add RESET to your process sensitivity list.

Issue in Quartus Post synthesis -- output is obtaining as xxxxxxxx

I have written a vhdl code and I want to run it in FPGA, The code is working fine in ghdl and also in the Quartus 2 pre synthesis(RTL simulation) , but when i am running in gatelevel simulation, it is showing data_out as xxxxxxx .I cant able figure out what is the problem. Can anyone help me?
--- device code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end entity SimpleCalculator;
architecture behave of SimpleCalculator is
----------------------------------
-- defining main state consisting of states of main thread
----------------------------------
type main_state is (main_idle,main_read0,main_read1,main_read2,main_read3,main_read4,main_calc);
signal next_mainstate: main_state;
-- below code creates two dimensional
-- array of 8 inputs with 16 bits each
type inputs_bit is array(0 to 4) of std_logic_vector(3 downto 0);
signal input_array : inputs_bit;
signal calc_start : std_logic;
signal calc_done : std_logic;
------------------------------
-- defining signals and states for calc thread
------------------------------
type calc_state is (calc_idle,calc_check_inputs,calc_running,calc_error);
signal calcstate : calc_state;
-----------------------------
begin
main: process(clk,reset,data_valid,next_mainstate,calc_done)
variable nstate:main_state;
--variable count: integer:=0;
begin
nstate := next_mainstate;
case next_mainstate is
when main_idle =>
if(data_valid = '1' ) then
nstate:= main_read0;
else
nstate:= main_idle;
end if;
when main_read0 =>
input_array(0) <= data_in;
nstate:=main_read1;
when main_read1 =>
input_array(1) <= data_in;
nstate:=main_read2;
when main_read2 =>
input_array(2) <= data_in;
nstate:=main_read3;
when main_read3 =>
input_array(3) <= data_in;
nstate:=main_read4;
when main_read4 =>
input_array(4) <= data_in;
nstate:=main_calc;
calc_start <= '1';
when main_calc =>
calc_start <= '0';
if(calc_done ='1') then
nstate:= main_idle;
else
nstate:=main_calc;
end if;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
next_mainstate <= main_idle;
else
next_mainstate <= nstate;
end if;
end if;
end process main;
------------------------------------------------
--calc fsm
---------------------------------------------
calc: process(clk,reset,calc_start,calcstate)
variable nstate:calc_state;
begin
nstate := calcstate;
case calcstate is
when calc_idle =>
if(calc_start = '1') then
nstate := calc_check_inputs;
else
nstate := calc_idle;
end if;
when calc_check_inputs =>
if(input_array(0) = "1010" and input_array(1) < "1010" and input_array(2) > "1011"
and input_array(3) < "1010" and input_array(4) = "1011") then
nstate := calc_running;
else
nstate := calc_error;
end if;
-- check for correct sequence
when calc_error =>
data_out <= "11111111";
when calc_running =>
case input_array(2) is
when "1100" =>
data_out <= std_logic_vector(unsigned(input_array(1)) * unsigned(input_array(3)) ) after 1 ns;
when "1101" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) + unsigned(input_array(3)) ) after 1 ns;
when "1110" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) - unsigned(input_array(3)) ) after 1 ns;
when "1111" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) / unsigned(input_array(3)) ) after 1 ns;
when others => null;
end case;
calc_done <='1';
nstate := calc_idle;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
calcstate <= calc_idle;
else
calcstate <= nstate;
end if;
end if;
end process calc;
end behave;
--- **testbench**
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
entity Simplecalculator_tb is
end entity;
architecture behave of Simplecalculator_tb is
signal data_in : std_logic_vector(3 downto 0);
signal data_valid : std_logic:= '0';
signal data_out : std_logic_vector(7 downto 0);
signal clk, reset: std_logic:= '0';
file stimulus_file: text is in "calci_inputs.txt";
file result_file: text is in "calci_result.txt";
component SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end component;
begin
-- 10 ns clock.
clk <= not clk after 5 ns;
process
variable L: line;
variable next_number_input: bit_vector(3 downto 0);
variable next_number_output: bit_vector(7 downto 0);
begin
reset <= '1';
data_valid <= '0';
wait until clk ='1';
reset <= '0';
data_valid <= '1';
wait until clk ='1';
data_valid <= '0';
while( not endfile(stimulus_file)) loop
readline(stimulus_file,L);
read(L,next_number_input);
data_in <= To_StdLogicVector(next_number_input);
wait until clk='1';
assert false report "Sent item " severity note;
end loop;
assert false report "Sent all items " severity note;
wait for 20 ns;
assert false report "Received done " severity note;
readline(result_file,L);
read(L,next_number_output);
if(data_out = To_StdLogicVector(next_number_output)) then
assert false report "SUCCESS: got the correct result." severity note;
else
assert false report "FAILURE: incorrect result! " severity ERROR;
end if;
wait;
end process;
dut : SimpleCalculator port map
( data_in => data_in, data_valid => data_valid, data_out => data_out, clk => clk,
reset => reset);
end behave;
---input file
1010
0111
1110
0010
1011
-- output file content
00000101
I have changed my code and the testbench and I have included the even the delays, but still I am getting the same xxxx error...Can anyone pls help me what is wrong in the code..what else I need to change.Thanks in advance
------ modified code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end entity SimpleCalculator;
architecture behave of SimpleCalculator is
----------------------------------
-- defining main state consisting of states of main thread
----------------------------------
type main_state is (main_idle,main_read0,main_read1,main_read2,main_read3,main_read4,main_calc);
signal next_mainstate: main_state;
-- below code creates two dimensional
-- array of 8 inputs with 16 bits each
type inputs_bit is array(0 to 4) of std_logic_vector(3 downto 0);
signal input_array : inputs_bit;
signal calc_start : std_logic;
signal calc_done : std_logic;
------------------------------
-- defining signals and states for calc thread
------------------------------
type calc_state is (calc_idle,calc_check_inputs,calc_running,calc_error);
signal calcstate : calc_state;
-----------------------------
begin
main: process(clk,reset,data_valid,next_mainstate,calc_done)
variable nstate:main_state;
--variable count: integer:=0;
begin
nstate := next_mainstate;
case next_mainstate is
when main_idle =>
if(data_valid = '1' ) then
nstate:= main_read0;
else
nstate:= main_idle;
end if;
when main_read0 =>
input_array(0) <= data_in after 2 ns;
nstate:=main_read1;
when main_read1 =>
input_array(1) <= data_in after 2 ns;
nstate:=main_read2;
when main_read2 =>
input_array(2) <= data_in after 2 ns;
nstate:=main_read3;
when main_read3 =>
input_array(3) <= data_in after 2 ns;
nstate:=main_read4;
when main_read4 =>
input_array(4) <= data_in after 2 ns;
nstate:=main_calc;
calc_start <= '1' after 2 ns;
when main_calc =>
calc_start <= '0' after 2 ns;
if(calc_done ='1') then
nstate:= main_idle;
else
nstate:=main_calc;
end if;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
next_mainstate <= main_idle;
else
next_mainstate <= nstate;
end if;
end if;
end process main;
------------------------------------------------
--calc fsm
---------------------------------------------
calc: process(clk,reset,calc_start,calcstate)
variable nstate:calc_state;
begin
nstate := calcstate;
case calcstate is
when calc_idle =>
if(calc_start = '1') then
nstate := calc_check_inputs;
else
nstate := calc_idle;
end if;
when calc_check_inputs =>
if(input_array(0) = "1010" and input_array(1) < "1010" and input_array(2) > "1011"
and input_array(3) < "1010" and input_array(4) = "1011") then
nstate := calc_running;
else
nstate := calc_error;
end if;
-- check for correct sequence
when calc_error =>
data_out <= "11111111";
when calc_running =>
case input_array(2) is
when "1100" =>
data_out <= std_logic_vector(unsigned(input_array(1)) * unsigned(input_array(3)) ) after 1 ns;
when "1101" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) + unsigned(input_array(3)) ) after 1 ns;
when "1110" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) - unsigned(input_array(3)) ) after 1 ns;
when "1111" =>
data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) / unsigned(input_array(3)) ) after 1 ns;
when others => null;
end case;
calc_done <='1' after 2 ns;
nstate := calc_idle;
when others => null;
end case;
if(clk'event and clk = '1') then
if(reset = '1') then
calcstate <= calc_idle;
else
calcstate <= nstate;
end if;
end if;
end process calc;
end behave;
-- new testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
entity Simplecalculator_tb is
end entity;
architecture behave of Simplecalculator_tb is
signal data_in : std_logic_vector(3 downto 0):= (others => '0');
signal data_valid : std_logic:= '0';
signal data_out : std_logic_vector(7 downto 0);
signal clk, reset: std_logic:= '0';
file stimulus_file: text is in "/home/student/pavanpalla/lab_5/calci_inputs.txt";
file result_file: text is in "/home/student/pavanpalla/lab_5/calci_result.txt";
component SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end component;
begin
-- 10 ns clock.
clk <= not clk after 20 ns;
process
variable L: line;
variable next_number_input: bit_vector(3 downto 0);
variable next_number_output: bit_vector(7 downto 0);
begin
reset <= '1';
data_valid <= '0';
wait until clk ='1';
reset <= '0' after 2 ns;
data_valid <= '1' after 2 ns;
wait until clk ='1';
data_valid <= '0' after 2 ns;
while( not endfile(stimulus_file)) loop
readline(stimulus_file,L);
read(L,next_number_input);
data_in <= To_StdLogicVector(next_number_input) after 10 ns;
wait until clk='1';
assert false report "Sent item " severity note;
end loop;
assert false report "Sent all items " severity note;
wait for 50 ns;
assert false report "Received done " severity note;
readline(result_file,L);
read(L,next_number_output);
if(data_out = To_StdLogicVector(next_number_output)) then
assert false report "SUCCESS: got the correct result." severity note;
else
assert false report "FAILURE: incorrect result! " severity ERROR;
end if;
wait;
end process;
dut : SimpleCalculator port map
( data_in => data_in, data_valid => data_valid, data_out => data_out, clk => clk,
reset => reset);
end behave;
I am also attaching the images of presynthesis and postsynthesis. I cant able to figure out where I am giving wrong
presynthesis
post_synthesis
Gate-level simulation includes timing for design primitives, for example flip-flops, so setup and hold time for data to flip-flops must be respected, and otherwise the flip-flops may generate 'X' on the output.
The test bench code is not written with this in mind; for example:
wait until clk ='1';
reset <= '0';
The reset is removed 0 ps after rising edge of clk, and depending on the implementation there may be hold-time requirement for the synchronous design reset.
This can be addressed by running at a "slow" clock and only change data "far" from the rising clk edge. This is acceptable since design timing should be verified through Static Timing Analysis (STA) and not simulation; post-synthesis simulation is only to get a good feeling that the design is OK, but it is unrealistic to verify design timing through test cases.
You may also consider writing the processes as either clocked process or combinatorial process, since this generally will make design easier to write, read, and debug. The calc process is an example of a process both updating on rising edge of clk and on calcstate.

Configuring an RS232 to USB cable with VHDL

i'm in the process of configuring an RS232 to USB cable with VHDL and i seem to have a problem. I don't know how to configure a dual-port RAM. I have attempted searching on answers to that and i found some code but i don't completely understand how to apply this code. This code can be found in this link --> http://www.asic-world.com/examples/vhdl/ram_dp_ar_aw.html.
Please help as soon as possible, i'm in desperate need of this information.
----------------------------------------------------------------------------------
-- Create Date : 14:06:22 12/08/2013
-- Designer Name : Sarin anand k
-- Module Name : UART - Behavioral
-- Project Name : RS232 transmitter
----------------------------------------------------------------------------------
-- spartan 3 starter kit
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
library UNISIM;
use UNISIM.VComponents.all;
entity uart is
port(
sys_clk : in std_logic; --50Mhz
reset : in std_logic;
data_in : in std_logic_vector(7 downto 0); -- switch
load : in std_logic; --push button
Tx : out std_logic
);
end uart;
architecture Behavioral of uart is
type T_state is (IDLE,STORAGE,START, DATA, STOP);
-- baud rate = 115200, bit duration required is 1/115200 = 8680 ns
-- for a 50MHz clock, period is 20 ns. So each bit is 8680/20 = 434 clock cycles
constant bit_dur : std_logic_vector(15 downto 0) := X"01B3"; -- 434 clocks
constant start_bit : std_logic := '0';
constant stop_bit : std_logic := '1';
signal baud_cnt : std_logic_vector(23 downto 0) := X"000000"; -- 115200
signal baud_en : std_logic;
signal temp : std_logic_vector(7 downto 0);
signal baud_rate_cnt : std_logic_vector(7 downto 0):=(others => '0');
signal bit_cnt_start : std_logic;
signal baud_flag : std_logic;
signal state : T_state;
begin
-----------------------------------------------------------------------------------------------------
---- baud clock
------------------------------------------------------------------------------------------------------
baud_rate: process(sys_clk) begin
if rising_edge(sys_clk) then
if (reset = '1') then
baud_cnt <= X"000000";
baud_en <= '0';
end if;
if (baud_cnt = bit_dur)then
baud_en <= '1'; -- data in flag
baud_cnt <= X"000000";
elsif(bit_cnt_start = '1') then
baud_cnt<= baud_cnt + '1';
baud_en <= '0';
end if;
end if;
end process baud_rate;
---------------------------------------------------------------------------------------------------------------
-- baud clock counter
----------------------------------------------------------------------------------------------------------------
baud_counter: process(sys_clk) begin
if(rising_edge (sys_clk)) then
if(reset = '1') then
baud_rate_cnt <=( others => '0');
baud_flag <= '0';
end if;
if( baud_rate_cnt = "1000") then
baud_flag <= '1';
baud_rate_cnt <=( others => '0');
elsif( state = DATA and baud_en ='1') then
baud_rate_cnt <= baud_rate_cnt + '1';
baud_flag <= '0';
end if;
end if;
end process baud_counter;
--------------------------------------------------------------------------------------------------------------------
-- State machine to control the data flow
----------------------------------------------------------------------------------------------------------------------
control_flow: process (sys_clk) begin
if(rising_edge (sys_clk)) then
if (reset = '1') then
bit_cnt_start <= '0';
state <= IDLE;
end if;
case state is
when IDLE =>
state <= STORAGE;
when STORAGE =>
if (load = '1') then
state <= START;
bit_cnt_start <= '1';
end if;
when START =>
if (baud_en ='1') then
state <= DATA;
end if;
when DATA =>
if ((baud_en ='1') and (baud_flag = '1')) then
state <= STOP;
end if;
when STOP =>
if (baud_en = '1') then
state <= IDLE;
bit_cnt_start <= '0';
end if;
when others =>
state <= IDLE;
end case;
end if;
end process control_flow;
------------------------------------------------------------------------------------------------------------------------
-- Data Transmission
-------------------------------------------------------------------------------------------------------------------------
data_trans: process (sys_clk) begin
if (rising_edge(sys_clk)) then
if (reset = '1') then
temp <= (others => '0');
end if;
-- Data Mux
case state is
when IDLE =>
temp <= (others => '0');
when STORAGE =>
temp <= data_in;
when START =>
Tx <= start_bit;
when DATA =>
Tx <= temp(0);
if ( baud_en = '1') then
temp <= '0' & temp(7 downto 1) ;
Tx <= temp(0);
end if;
when STOP =>
Tx <= stop_bit;
when others =>
Tx <= '1';
end case;
end if;
end process data_trans;
end Behavioral;

Resources