cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Norian
Visitor
Visitor
755 Views
Registered: ‎05-22-2021

Counter takes an unexpected value on initialization.

Jump to solution

Hi,

I would like my counter cpt to take the value of 0 at initialization but it takes the value 2:

Capture d’écran du 2021-05-22 22-22-23.pngI think this is due to the baudrate_clk process in my testbench but I don't know how to fix it.

This is what my testbench looks like:

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 15.05.2021 18:28:17
-- Design Name: 
-- Module Name: tb_UART_RX - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity tb_UART_RX is
--  Port ( );
end tb_UART_RX;

architecture Behavioral of tb_UART_RX is
component UART_RX
    Port(clk, rst, RX: in std_logic;
        parity: in std_logic_vector(1 downto 0);
        timeout_value: in std_logic_vector(31 downto 0);
        error_parity,timeout: out std_logic;
        RXREG: out std_logic_vector(7 downto 0));
end component;

component baudclk
    Port ( clk, rst : in STD_LOGIC;
           baudrate_clk_ticks: in std_logic_vector(31 downto 0);
           baudclk : out STD_LOGIC);
end component;
signal sRX,clkbaudrate,serror_RX,stimeout,sclk: std_logic := '0';
signal stimeout_value: std_logic_vector(31 downto 0) := "11111111111000000000000000000000";
signal sbaud_tick_clk: std_logic_vector(31 downto 0);
signal strame: std_logic_vector(10 downto 0) := "11011010100"; 
signal rdata: std_logic_vector(7 downto 0) := "00000000";
signal cpt,sparity_value: integer := 0;
signal sparity : std_logic_vector(1 downto 0) := "00";

begin
    sbaud_tick_clk <= std_logic_vector(to_unsigned(868,32));
    sRX<=strame(cpt);
    c1: baudclk port map(clk => sclk, rst => '0',baudrate_clk_ticks => sbaud_tick_clk, baudclk => clkbaudrate);
    c2: UART_RX port map(clk =>clkbaudrate, rst => '0', RX => sRX, parity => sparity, timeout_value =>stimeout_value, error_parity =>serror_RX,timeout => stimeout,RXREG =>rdata);
    
    stimulis:process
    begin
        sclk <= '0';
        wait for 10ns;
        sclk <= '1';
        wait for 10ns;
    end process;
    
    baudrate_clk:process(clkbaudrate)
    begin
        cpt <= cpt +1;
        if cpt >= 10 then
            cpt <= 0;
        end if;
    end process;
    
    simulis_parity:process
    begin
        sparity_value <= sparity_value +1;
        sparity <= std_logic_vector(to_unsigned(sparity_value,2));
        wait for 400us;
    end process;
    
end Behavioral;

Could you help me to solve my problem please ?

Thanks in advance

0 Kudos
1 Solution

Accepted Solutions
joancab
Teacher
Teacher
725 Views
Registered: ‎05-11-2015

Aren't you missing a clock here?

 

    baudrate_clk:process(clkbaudrate)
    begin
        cpt <= cpt +1;
        if cpt >= 10 then
            cpt <= 0;
        end if;
    end process;

 

Are you trusting the process to be done at every change in clkbaudrate for being in the sensitivity list?

View solution in original post

7 Replies
joancab
Teacher
Teacher
726 Views
Registered: ‎05-11-2015

Aren't you missing a clock here?

 

    baudrate_clk:process(clkbaudrate)
    begin
        cpt <= cpt +1;
        if cpt >= 10 then
            cpt <= 0;
        end if;
    end process;

 

Are you trusting the process to be done at every change in clkbaudrate for being in the sensitivity list?

View solution in original post

Norian
Visitor
Visitor
662 Views
Registered: ‎05-22-2021

Hi,

Thanks for your help.

You were right, the process was started unexpectedly because of clkbaudrate.

I am trying to simulate UART communication with a baudrate of 115200 so I modified the testbench like this:

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 15.05.2021 18:28:17
-- Design Name: 
-- Module Name: tb_UART_RX - Behavioral
-- Project Name: 
-- Target Devices: 
-- Tool Versions: 
-- Description: 
-- 
-- Dependencies: 
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
----------------------------------------------------------------------------------


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity tb_UART_RX is
--  Port ( );
end tb_UART_RX;

architecture Behavioral of tb_UART_RX is
component UART_RX
    Port(clk, rst, RX: in std_logic;
        parity: in std_logic_vector(1 downto 0);
        timeout_value: in std_logic_vector(31 downto 0);
        error_parity,timeout,end_reception: out std_logic;
        RXREG: out std_logic_vector(7 downto 0));
end component;

component baudclk
    Port ( clk, rst : in STD_LOGIC;
           baudrate_clk_ticks: in std_logic_vector(31 downto 0);
           baudclk : out STD_LOGIC);
end component;
signal sRX,clkbaudrate,serror_RX,stimeout,sclk,send_reception: std_logic := '0';
signal stimeout_value: std_logic_vector(31 downto 0) := "11111111111000000000000000000000";
signal sbaud_tick_clk: std_logic_vector(31 downto 0);
signal strame: std_logic_vector(10 downto 0) := "11011010100"; 
signal rdata: std_logic_vector(7 downto 0) := "00000000";
signal sparity_value: integer := 0;
signal cpt: integer := 0;
signal sparity : std_logic_vector(1 downto 0) := "00";

begin
    sRX<=strame(cpt);
    sbaud_tick_clk <= std_logic_vector(to_unsigned(868,32));
    c1: baudclk port map(clk => sclk, rst => '0',baudrate_clk_ticks => sbaud_tick_clk, baudclk => clkbaudrate);
    c2: UART_RX port map(clk =>clkbaudrate, rst => '0', RX => sRX, parity => sparity, timeout_value =>stimeout_value, error_parity =>serror_RX,end_reception => send_reception, timeout => stimeout,RXREG =>rdata);
    
    stimulis:process
    begin
        sclk <= '0';
        wait for 10ns;
        sclk <= '1';
        wait for 10ns;
    end process;
    
    baudrate_clk:process
    begin
        wait for 8.7us;
        cpt <= cpt +1;        
        if cpt >= 10 then
            cpt <= 0;
        end if;     
    end process;
    
    simulis_parity:process
    begin
        sparity_value <= sparity_value +1;
        sparity <= std_logic_vector(to_unsigned(sparity_value,2));
        wait for 400us;
    end process;
    

end Behavioral;

In this way the counter works correctly.

Again thanks for your help

0 Kudos
joancab
Teacher
Teacher
640 Views
Registered: ‎05-11-2015

Nevertheless, if you ever want that thing synthesizable you´ll need to implement a proper process with a clock, not a simulational delay.

I avoid non-synthesizable HDL as much as possible. It's fine for a very initial sort of 'proof of concept' but, imo, as there is an important gap between simulation and reality, I don't spend much time on that imaginary World. But it's just my approach, others may differ and have a point.

drjohnsmith
Teacher
Teacher
591 Views
Registered: ‎07-09-2009

re simulation @joancab

its the only way to see whats happening inside your design, 

     we design in a 9 state logic language, but in the real chip is 1 or 0, 

        simulation is reality.

 

What I do agree on, is separating synthesisable code and none synthesisable code into different entities,

     Test benches almost by default have to be none synthesizable, as they tend to include clock generators, 

        and lots of print statements  / conditional tests that can not be done in the FPGA.

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
joancab
Teacher
Teacher
522 Views
Registered: ‎05-11-2015

@drjohnsmith testbenches, obviously are non-synthesizable. And needed. What I don't understand is why people write non-synthesizable functions that will never run in real silicon.

0 Kudos
Norian
Visitor
Visitor
507 Views
Registered: ‎05-22-2021

Hi,

Of course I only use delays in my testbench. I completely simulate the sending of the frame in the testbench for my tests, my synthesizable components are the baudclk (clock for the UART_RX component) and UART_RX components.

richardhead
Scholar
Scholar
484 Views
Registered: ‎08-01-2012

@drjohnsmith @joancab 

I would usually follow the mantra of separating synth/tb code into separate entities. But it can be very useful to embed things like assertions in synthesisable code to kill a simulation when something illegal happens so its easy to trace back from point of failure. This often requires non-synthesisable functions (like using OSVVM Alerts). But you can easily put the --synthesis translate_off/on gates around it.

I also have packages with synthesisable code alongside what is clearly simulation stuff, purely because it makes life easier. Like having access types of synthesisable array types in the same package - again synthesis gated.