2 counters, counting states of Bit stream

Discussion in 'VHDL' started by brandon.spiteri@gmail.com, Jun 6, 2013.

  1. Guest

    I need to implement 2 counters that counts 1's and 0's of an incoming bit stream.
    However I have a problem that not even the clock is generated on ModelSim and all the signals
    are labeled as 'no data'. Is there a problem in my code or is it related to some configuration or settings?

    This is my code;

    --bit_counter.vhd

    LIBRARY ieee;
    -- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
    use ieee.std_logic_1164.all;

    -- SIGNED and UNSIGNED types, and relevant functions
    use ieee.numeric_std.all;


    entity bit_counter is

    port(Start : in std_logic := '0' ; --was in
    Reset : in std_logic := '1';
    Clock : in std_logic := '0';
    Bit_stream : in std_logic := '0';

    Q_H, Q_L : out std_logic_vector (3 downto 0)
    );


    end entity bit_counter;

    architecture RTL of bit_counter is

    --type state_type is (IDLE, Bit_is_high, Bit_is_low);

    --signal initBitH, initBitL, BitH, BitL : std_logic;
    signal cnt_L, cnt_H : integer range 0 to 15;


    begin

    count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)

    begin

    Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
    Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));

    if(Reset = '0') then
    cnt_H <= 0;
    cnt_L <= 0;

    elsif (Start = '1') then
    if(rising_edge(Clock)) then

    if (Bit_stream = '1') then
    cnt_H <= cnt_H + 1;
    cnt_L <= cnt_L;
    elsif (Bit_stream = '0') then
    Cnt_H <= Cnt_H;
    Cnt_L <= Cnt_L + 1;
    end if;
    end if;
    end if;



    end process;

    end architecture RTL;

    --bit_counter_test.vhd

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    use ieee.std_logic_unsigned.all;

    entity bit_counter_test is
    end Entity bit_counter_test;

    Architecture behavioral of bit_counter_test is

    Signal Bit_stream, Clock : std_logic := '0';
    Signal Reset_count, Start_count : std_logic := '1';
    Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');

    begin

    UUT : entity work.bit_counter
    port map (

    Bit_stream => Bit_stream,
    Start => Start_count,
    Reset => Reset_count,
    Clock => Clock);


    CLK_process :process
    begin
    for C in 30 downto 0 loop
    Clock <= NOT Clock after 5ns;
    end loop;
    end process;

    Signals : process

    Begin

    for I in 30 downto 0 loop
    wait for 10 ns;
    Start_count <= '1';
    Reset_count <= '1';
    Bit_stream <= '0';


    end loop ;

    wait for 10 ns;

    for J in 30 downto 0 loop
    wait for 10 ns;
    Start_count <= '1';
    Reset_count <= '1';
    Bit_stream <= '1';

    end loop ;

    wait;
    end process;



    end Architecture behavioral;

    In the past I already managed to simulate combinational logic with model sim so clock wasn't involved. It seams that the problem is I am not using the clock correctly..
    , Jun 6, 2013
    #1
    1. Advertising

  2. Guest

    Am Donnerstag, 6. Juni 2013 03:32:16 UTC+2 schrieb Brandon Spiteri:
    > I need to implement 2 counters that counts 1's and 0's of an incoming bit stream.
    >
    > However I have a problem that not even the clock is generated on ModelSim and all the signals
    >
    > are labeled as 'no data'. Is there a problem in my code or is it related to some configuration or settings?
    >
    >
    >
    > This is my code;
    >
    >
    >
    > --bit_counter.vhd
    >
    >
    >
    > LIBRARY ieee;
    >
    > -- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
    >
    > use ieee.std_logic_1164.all;
    >
    >
    >
    > -- SIGNED and UNSIGNED types, and relevant functions
    >
    > use ieee.numeric_std.all;
    >
    >
    >
    >
    >
    > entity bit_counter is
    >
    >
    >
    > port(Start : in std_logic := '0' ; --was in
    >
    > Reset : in std_logic := '1';
    >
    > Clock : in std_logic := '0';
    >
    > Bit_stream : in std_logic := '0';
    >
    >
    >
    > Q_H, Q_L : out std_logic_vector (3 downto 0)
    >
    > );
    >
    >
    >
    >
    >
    > end entity bit_counter;
    >
    >
    >
    > architecture RTL of bit_counter is
    >
    >
    >
    > --type state_type is (IDLE, Bit_is_high, Bit_is_low);
    >
    >
    >
    > --signal initBitH, initBitL, BitH, BitL : std_logic;
    >
    > signal cnt_L, cnt_H : integer range 0 to 15;
    >
    >
    >
    >
    >
    > begin
    >
    >
    >
    > count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)
    >
    >
    >
    > begin
    >
    >
    >
    > Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
    >
    > Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));
    >
    >
    >
    > if(Reset = '0') then
    >
    > cnt_H <= 0;
    >
    > cnt_L <= 0;
    >
    >
    >
    > elsif (Start = '1') then
    >
    > if(rising_edge(Clock)) then
    >
    >
    >
    > if (Bit_stream = '1') then
    >
    > cnt_H <= cnt_H + 1;
    >
    > cnt_L <= cnt_L;
    >
    > elsif (Bit_stream = '0') then
    >
    > Cnt_H <= Cnt_H;
    >
    > Cnt_L <= Cnt_L + 1;
    >
    > end if;
    >
    > end if;
    >
    > end if;
    >
    >
    >
    >
    >
    >
    >
    > end process;
    >
    >
    >
    > end architecture RTL;
    >
    >
    >
    > --bit_counter_test.vhd
    >
    >
    >
    > library ieee;
    >
    > use ieee.std_logic_1164.all;
    >
    > use ieee.numeric_std.all;
    >
    > use ieee.std_logic_unsigned.all;
    >
    >
    >
    > entity bit_counter_test is
    >
    > end Entity bit_counter_test;
    >
    >
    >
    > Architecture behavioral of bit_counter_test is
    >
    >
    >
    > Signal Bit_stream, Clock : std_logic := '0';
    >
    > Signal Reset_count, Start_count : std_logic := '1';
    >
    > Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
    >
    >
    >
    > begin
    >
    >
    >
    > UUT : entity work.bit_counter
    >
    > port map (
    >
    >
    >
    > Bit_stream => Bit_stream,
    >
    > Start => Start_count,
    >
    > Reset => Reset_count,
    >
    > Clock => Clock);
    >
    >
    >
    >
    >
    > CLK_process :process
    >
    > begin
    >
    > for C in 30 downto 0 loop
    >
    > Clock <= NOT Clock after 5ns;
    >
    > end loop;
    >
    > end process;
    >
    >
    >
    > Signals : process
    >
    >
    >
    > Begin
    >
    >
    >
    > for I in 30 downto 0 loop
    >
    > wait for 10 ns;
    >
    > Start_count <= '1';
    >
    > Reset_count <= '1';
    >
    > Bit_stream <= '0';
    >
    >
    >
    >
    >
    > end loop ;
    >
    >
    >
    > wait for 10 ns;
    >
    >
    >
    > for J in 30 downto 0 loop
    >
    > wait for 10 ns;
    >
    > Start_count <= '1';
    >
    > Reset_count <= '1';
    >
    > Bit_stream <= '1';
    >
    >
    >
    > end loop ;
    >
    >
    >
    > wait;
    >
    > end process;
    >
    >
    >
    >
    >
    >
    >
    > end Architecture behavioral;
    >
    >
    >
    > In the past I already managed to simulate combinational logic with model sim so clock wasn't involved. It seams that the problem is I am not using the clock correctly..


    Hi Brandon.
    so many loops... you may end up in a knot. :)

    Think about what you are doing in your clock process:
    You have a signal assignment that gets overwritten a number of times in the loop.
    The after statement will just add one event to the event list, but this is not accumulating. It will just be overwritten.
    Instead you may use this:
    Clock <= NOT Clock;
    wait for 5ns;

    Hint:
    The loops in your stimuli process can be simplified.
    after you set some variable you can just use
    wait for 30*10ns; -- 30 can be replaced by any other number.
    To avoid problems that may arise when you have signal changes on the rising clock edge, you can either use an initial delay that puts the signal chanses clearly out of phase :
    e.g. wait for 3 ns; -- put this in the beginning of your stimuli list.

    There are other methods like implementing a clock counter and using a synchronous process with a case to select the time for signal assignments:

    sig1 <= '0'; --default assignment
    case clockcount is
    when 5 => sig1<= '1';
    when 7 to 9 => sig1<= '1';
    -- and so on


    Another thing:
    aside from the asynchronous reset you shouldn't have statements outside the synchronous parts.

    The assignments for Q_L and Q_H can be placed outside the process, thus becoming concurrent assignments.


    elsif (Start = '1') then
    if(rising_edge(Clock)) then

    should be rewritten as:
    elsif(rising_edge(Clock)) then
    if (Start = '1') then

    Ranged integers work well, but there may come a time where you want to handle more than 32 bits. While you are using numeric_std anyway you could also declare the counting signals like this:
    signal cnt_L, cnt_H : unsigned(3 downto 0);

    This way your type conversions become shorter and you never get into the hazzle of "integer overflow errors". The unsigned type would simply roll over to 0.
    Still adding integers to unsigned type signals works, so no further code changes are needed.

    Have a nice simulation
    Eilert
    , Jun 6, 2013
    #2
    1. Advertising

  3. Thanks a lot for your help. I managed to simulate the test bench and I got what I wanted.

    Now I need to implement this on an FPGA. I have the board driver and I modified it accordingly like
    I did for other small projects.

    My friend told me that to implement it on an FPGA, the vhdl code needs some minor tweaking but I do not know what he was referring to. In the board driver I used debouncing for the 2 tact switches; Bit_stream and clock.

    Can you guide me what tweaking is needed? thanks

    This is my code;

    --bit_counter.vhd

    LIBRARY ieee;
    -- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
    use ieee.std_logic_1164.all;

    -- SIGNED and UNSIGNED types, and relevant functions
    use ieee.numeric_std.all;


    entity bit_counter is

    port(Start : in std_logic := '0' ; --was in
    Reset : in std_logic := '1';
    Clock : in std_logic := '0';
    Bit_stream : in std_logic := '0';

    Q_H, Q_L : out std_logic_vector (3 downto 0) := (others => '0')
    );


    end entity bit_counter;

    architecture RTL of bit_counter is


    signal cnt_L, cnt_H : integer range 0 to 15;

    begin
    Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
    Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));

    count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)

    begin

    if(Reset = '0' ) then
    cnt_H <= 0;
    cnt_L <= 0;

    elsif (rising_edge(Clock)) then
    if(Start = '1') then

    if (Bit_stream = '1') then
    cnt_H <= cnt_H + 1 ;
    cnt_L <= cnt_L ;


    elsif (Bit_stream = '0') then
    Cnt_L <= Cnt_L + 1 ;
    Cnt_H <= Cnt_H ;

    end if;
    end if;
    end if;


    end process;

    end architecture RTL;

    --bit_counter_test.vhd

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    use ieee.std_logic_unsigned.all;


    entity bit_counter_test is
    end Entity bit_counter_test;

    Architecture behavioral of bit_counter_test is

    Signal Bit_stream, ext_Clock : std_logic := '0';
    Signal Reset_count, Start_count : std_logic := '1';
    Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
    Signal Endsim : std_logic := '0';
    begin

    UUT : entity work.bit_counter
    port map (

    Bit_stream => Bit_stream,
    Start => Start_count,
    Reset => Reset_count,
    Clock => ext_Clock,
    Q_L => Q_L,
    Q_H => Q_H);


    CLK_process :process
    begin
    if(EndSim = '0') then
    ext_Clock <= NOT ext_Clock;
    wait for 2ns;
    end if;
    end process;

    Signals : process

    Begin

    wait for 0.5 ns;
    Start_count <= '1';
    Reset_count <= '1';

    for I in 15 downto 0 loop
    Bit_stream <= '1';
    wait for 4 ns;
    Bit_stream <= '0';
    wait for 4 ns;

    end loop ;

    EndSim <= '1';
    wait;
    end process;

    end Architecture behavioral;

    --boarddriver.vhd

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use work.QuantumBaseSupport.all;

    entity BoardDriver is
    Port (
    BUTTON : in STD_LOGIC_VECTOR(3 downto 0);
    DIP : in STD_LOGIC_VECTOR(7 downto 0);
    RESET : in STD_LOGIC; --Active Low
    CLK0 : in STD_LOGIC; --20MHz input
    CLK2 : in STD_LOGIC;

    -- Output ports
    COM : out STD_LOGIC_VECTOR(3 downto 0);
    FND_EN : out STD_LOGIC;
    LED : out STD_LOGIC_VECTOR(7 downto 0);
    SEGMENTS : out STD_LOGIC_VECTOR(7 downto 0);
    EXPANSION : out STD_LOGIC_VECTOR(26 downto 0)
    );
    end BoardDriver;

    architecture RTL of BoardDriver is

    alias Button1 is BUTTON(0);
    alias Button2 is BUTTON(1);
    alias Button3 is BUTTON(2);
    alias Button4 is BUTTON(3);

    alias DIP1 is DIP(0);
    alias DIP2 is DIP(1);
    alias DIP3 is DIP(2);
    alias DIP4 is DIP(3);
    alias DIP5 is DIP(4);
    alias DIP6 is DIP(5);
    alias DIP7 is DIP(6);
    alias DIP8 is DIP(7);

    alias LED1 is LED(0);
    alias LED2 is LED(1);
    alias LED3 is LED(2);
    alias LED4 is LED(3);
    alias LED5 is LED(4);
    alias LED6 is LED(5);
    alias LED7 is LED(6);
    alias LED8 is LED(7);

    signal ButtonDB_stream : std_logic;
    signal ButtonDB_clk : std_logic;

    begin

    EXPANSION <= (others => 'Z');

    DeBounce_stream : entity work.SwDebounce
    port map( Clock => CLK0,
    Reset => Reset,
    Input => Button1,
    Debounced_out => ButtonDB_stream
    );
    DeBounce_clk : entity work.SwDebounce
    port map( Clock => CLK0,
    Reset => Reset,
    Input => Button1,
    Debounced_out => ButtonDB_clk
    );
    Count_Bits: entity work.bit_counter
    Port map(
    Reset => Reset,
    Clock => ButtonDB_clk,
    Bit_stream => ButtonDB_stream,
    Start => DIP1,
    Q_L => LED (3 downto 0),
    Q_H => LED (7 downto 4)

    );

    end architecture RTL;
    Brandon Spiteri, Jun 6, 2013
    #3
  4. Andy Guest

    A few more tips...

    General:

    You don't need () around conditions in if-statements.

    bit_counter:

    Remove all but clock and reset from sensitivity list.

    Remove assignments to self for clk_L and Clk_H.

    You can combine if-statements for rising_edge() and start:

    if rising_edge(clock) and start = '1' then

    Testbench:

    Insert an "else wait;" statement before "end if;" in your clock driver process. This keeps it from running in an endless, zero-delay loop when endsim becomes '1'.

    But I usually drive the clock from a concurrent assignment:

    ext_clock <= not ext_clock after 2 ns when endsim = '0';

    Pace the testbench by using "wait for falling_edge(clk);" instead of 'wait for 4 ns;" This keeps it syncrhonized to the clock no matter what.

    Andy
    Andy, Jun 6, 2013
    #4
  5. rickman Guest

    On 6/6/2013 12:01 PM, Brandon Spiteri wrote:
    > Thanks a lot for your help. I managed to simulate the test bench and I got what I wanted.
    >
    > Now I need to implement this on an FPGA. I have the board driver and I modified it accordingly like
    > I did for other small projects.
    >
    > My friend told me that to implement it on an FPGA, the vhdl code needs some minor tweaking but I do not know what he was referring to. In the board driver I used debouncing for the 2 tact switches; Bit_stream and clock.
    >
    > Can you guide me what tweaking is needed? thanks


    Tweaking for synthesis after simulation is not a good idea. If changes
    are made to the code to be synthesized, it would need to be simulated
    again to make sure nothing functional has changed.

    The only thing I see that should be changed is your sensitivity list
    that contains not only the clock and the async reset, but other inputs
    to the process. These should not be included in the sensitivity list
    because of how the sensitivity list works. Any change to any of the
    signals in the list cause the process to run. There are cases where
    this will cause the simulation results to be different from the way the
    synthesized hardware to work.

    I think I see one mistake in your code. You use Button1 as input to
    both debounce circuits. I assume one should be Button1 and the other
    Button2?

    I wouldn't change the use of parens in IF statements. They clearly
    delineate the expression being evaluated just like using a period at the
    end of a sentence. I also wouldn't worry about using assignments of
    signals to themselves when you want the value of a FF to remain
    unchanged. This is redundant since if nothing is specified it is
    assumed that the signal will hold a value, but specifying it can make
    some code more clear. In other words, it is a judgement call by the
    author and I would never criticize this.

    Rick



    > This is my code;
    >
    > --bit_counter.vhd
    >
    > LIBRARY ieee;
    > -- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
    > use ieee.std_logic_1164.all;
    >
    > -- SIGNED and UNSIGNED types, and relevant functions
    > use ieee.numeric_std.all;
    >
    >
    > entity bit_counter is
    >
    > port(Start : in std_logic := '0' ; --was in
    > Reset : in std_logic := '1';
    > Clock : in std_logic := '0';
    > Bit_stream : in std_logic := '0';
    >
    > Q_H, Q_L : out std_logic_vector (3 downto 0) := (others => '0')
    > );
    >
    >
    > end entity bit_counter;
    >
    > architecture RTL of bit_counter is
    >
    >
    > signal cnt_L, cnt_H : integer range 0 to 15;
    >
    > begin
    > Q_H<= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
    > Q_L<= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));
    >
    > count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)
    >
    > begin
    >
    > if(Reset = '0' ) then
    > cnt_H<= 0;
    > cnt_L<= 0;
    >
    > elsif (rising_edge(Clock)) then
    > if(Start = '1') then
    >
    > if (Bit_stream = '1') then
    > cnt_H<= cnt_H + 1 ;
    > cnt_L<= cnt_L ;
    >
    >
    > elsif (Bit_stream = '0') then
    > Cnt_L<= Cnt_L + 1 ;
    > Cnt_H<= Cnt_H ;
    >
    > end if;
    > end if;
    > end if;
    >
    >
    > end process;
    >
    > end architecture RTL;
    >
    > --bit_counter_test.vhd
    >
    > library ieee;
    > use ieee.std_logic_1164.all;
    > use ieee.numeric_std.all;
    >
    > use ieee.std_logic_unsigned.all;
    >
    >
    > entity bit_counter_test is
    > end Entity bit_counter_test;
    >
    > Architecture behavioral of bit_counter_test is
    >
    > Signal Bit_stream, ext_Clock : std_logic := '0';
    > Signal Reset_count, Start_count : std_logic := '1';
    > Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
    > Signal Endsim : std_logic := '0';
    > begin
    >
    > UUT : entity work.bit_counter
    > port map (
    >
    > Bit_stream => Bit_stream,
    > Start => Start_count,
    > Reset => Reset_count,
    > Clock => ext_Clock,
    > Q_L => Q_L,
    > Q_H => Q_H);
    >
    >
    > CLK_process :process
    > begin
    > if(EndSim = '0') then
    > ext_Clock<= NOT ext_Clock;
    > wait for 2ns;
    > end if;
    > end process;
    >
    > Signals : process
    >
    > Begin
    >
    > wait for 0.5 ns;
    > Start_count<= '1';
    > Reset_count<= '1';
    >
    > for I in 15 downto 0 loop
    > Bit_stream<= '1';
    > wait for 4 ns;
    > Bit_stream<= '0';
    > wait for 4 ns;
    >
    > end loop ;
    >
    > EndSim<= '1';
    > wait;
    > end process;
    >
    > end Architecture behavioral;
    >
    > --boarddriver.vhd
    >
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.ALL;
    > use IEEE.NUMERIC_STD.ALL;
    > use work.QuantumBaseSupport.all;
    >
    > entity BoardDriver is
    > Port (
    > BUTTON : in STD_LOGIC_VECTOR(3 downto 0);
    > DIP : in STD_LOGIC_VECTOR(7 downto 0);
    > RESET : in STD_LOGIC; --Active Low
    > CLK0 : in STD_LOGIC; --20MHz input
    > CLK2 : in STD_LOGIC;
    >
    > -- Output ports
    > COM : out STD_LOGIC_VECTOR(3 downto 0);
    > FND_EN : out STD_LOGIC;
    > LED : out STD_LOGIC_VECTOR(7 downto 0);
    > SEGMENTS : out STD_LOGIC_VECTOR(7 downto 0);
    > EXPANSION : out STD_LOGIC_VECTOR(26 downto 0)
    > );
    > end BoardDriver;
    >
    > architecture RTL of BoardDriver is
    >
    > alias Button1 is BUTTON(0);
    > alias Button2 is BUTTON(1);
    > alias Button3 is BUTTON(2);
    > alias Button4 is BUTTON(3);
    >
    > alias DIP1 is DIP(0);
    > alias DIP2 is DIP(1);
    > alias DIP3 is DIP(2);
    > alias DIP4 is DIP(3);
    > alias DIP5 is DIP(4);
    > alias DIP6 is DIP(5);
    > alias DIP7 is DIP(6);
    > alias DIP8 is DIP(7);
    >
    > alias LED1 is LED(0);
    > alias LED2 is LED(1);
    > alias LED3 is LED(2);
    > alias LED4 is LED(3);
    > alias LED5 is LED(4);
    > alias LED6 is LED(5);
    > alias LED7 is LED(6);
    > alias LED8 is LED(7);
    >
    > signal ButtonDB_stream : std_logic;
    > signal ButtonDB_clk : std_logic;
    >
    > begin
    >
    > EXPANSION<= (others => 'Z');
    >
    > DeBounce_stream : entity work.SwDebounce
    > port map( Clock => CLK0,
    > Reset => Reset,
    > Input => Button1,
    > Debounced_out => ButtonDB_stream
    > );
    > DeBounce_clk : entity work.SwDebounce
    > port map( Clock => CLK0,
    > Reset => Reset,
    > Input => Button1,
    > Debounced_out => ButtonDB_clk
    > );
    > Count_Bits: entity work.bit_counter
    > Port map(
    > Reset => Reset,
    > Clock => ButtonDB_clk,
    > Bit_stream => ButtonDB_stream,
    > Start => DIP1,
    > Q_L => LED (3 downto 0),
    > Q_H => LED (7 downto 4)
    >
    > );
    >
    > end architecture RTL;
    >
    >



    --

    Rick
    rickman, Jun 6, 2013
    #5
  6. Guest

    Am Donnerstag, 6. Juni 2013 03:32:16 UTC+2 schrieb Brandon Spiteri:
    > I need to implement 2 counters that counts 1's and 0's of an incoming bit stream.
    >
    > However I have a problem that not even the clock is generated on ModelSim and all the signals
    >
    > are labeled as 'no data'. Is there a problem in my code or is it related to some configuration or settings?
    >
    >
    >
    > This is my code;
    >
    >
    >
    > --bit_counter.vhd
    >
    >
    >
    > LIBRARY ieee;
    >
    > -- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
    >
    > use ieee.std_logic_1164.all;
    >
    >
    >
    > -- SIGNED and UNSIGNED types, and relevant functions
    >
    > use ieee.numeric_std.all;
    >
    >
    >
    >
    >
    > entity bit_counter is
    >
    >
    >
    > port(Start : in std_logic := '0' ; --was in
    >
    > Reset : in std_logic := '1';
    >
    > Clock : in std_logic := '0';
    >
    > Bit_stream : in std_logic := '0';
    >
    >
    >
    > Q_H, Q_L : out std_logic_vector (3 downto 0)
    >
    > );
    >
    >
    >
    >
    >
    > end entity bit_counter;
    >
    >
    >
    > architecture RTL of bit_counter is
    >
    >
    >
    > --type state_type is (IDLE, Bit_is_high, Bit_is_low);
    >
    >
    >
    > --signal initBitH, initBitL, BitH, BitL : std_logic;
    >
    > signal cnt_L, cnt_H : integer range 0 to 15;
    >
    >
    >
    >
    >
    > begin
    >
    >
    >
    > count: process(Start, Reset, Clock, Bit_stream, cnt_L, cnt_H)
    >
    >
    >
    > begin
    >
    >
    >
    > Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
    >
    > Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));
    >
    >
    >
    > if(Reset = '0') then
    >
    > cnt_H <= 0;
    >
    > cnt_L <= 0;
    >
    >
    >
    > elsif (Start = '1') then
    >
    > if(rising_edge(Clock)) then
    >
    >
    >
    > if (Bit_stream = '1') then
    >
    > cnt_H <= cnt_H + 1;
    >
    > cnt_L <= cnt_L;
    >
    > elsif (Bit_stream = '0') then
    >
    > Cnt_H <= Cnt_H;
    >
    > Cnt_L <= Cnt_L + 1;
    >
    > end if;
    >
    > end if;
    >
    > end if;
    >
    >
    >
    >
    >
    >
    >
    > end process;
    >
    >
    >
    > end architecture RTL;
    >
    >
    >
    > --bit_counter_test.vhd
    >
    >
    >
    > library ieee;
    >
    > use ieee.std_logic_1164.all;
    >
    > use ieee.numeric_std.all;
    >
    > use ieee.std_logic_unsigned.all;
    >
    >
    >
    > entity bit_counter_test is
    >
    > end Entity bit_counter_test;
    >
    >
    >
    > Architecture behavioral of bit_counter_test is
    >
    >
    >
    > Signal Bit_stream, Clock : std_logic := '0';
    >
    > Signal Reset_count, Start_count : std_logic := '1';
    >
    > Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
    >
    >
    >
    > begin
    >
    >
    >
    > UUT : entity work.bit_counter
    >
    > port map (
    >
    >
    >
    > Bit_stream => Bit_stream,
    >
    > Start => Start_count,
    >
    > Reset => Reset_count,
    >
    > Clock => Clock);
    >
    >
    >
    >
    >
    > CLK_process :process
    >
    > begin
    >
    > for C in 30 downto 0 loop
    >
    > Clock <= NOT Clock after 5ns;
    >
    > end loop;
    >
    > end process;
    >
    >
    >
    > Signals : process
    >
    >
    >
    > Begin
    >
    >
    >
    > for I in 30 downto 0 loop
    >
    > wait for 10 ns;
    >
    > Start_count <= '1';
    >
    > Reset_count <= '1';
    >
    > Bit_stream <= '0';
    >
    >
    >
    >
    >
    > end loop ;
    >
    >
    >
    > wait for 10 ns;
    >
    >
    >
    > for J in 30 downto 0 loop
    >
    > wait for 10 ns;
    >
    > Start_count <= '1';
    >
    > Reset_count <= '1';
    >
    > Bit_stream <= '1';
    >
    >
    >
    > end loop ;
    >
    >
    >
    > wait;
    >
    > end process;
    >
    >
    >
    >
    >
    >
    >
    > end Architecture behavioral;
    >
    >
    >
    > In the past I already managed to simulate combinational logic with model sim so clock wasn't involved. It seams that the problem is I am not using the clock correctly..


    Hi Brandon,
    one little question concerning your debouncer :
    It is clocked with 20 MHz.
    Does it have an internal counter to further reduce the sampling rate of the switch/button signals?
    Otherwise you would take samples every 50ns and since debouncers normally have just a few stages the debouncing period then will be just a few hundred ns.
    Switches/buttons tend to have bouncing times in the micro to milliseconds range.

    So please check this before you are wondering about strange hardware behavior.

    Have a nice synthesis
    Eilert
    , Jun 7, 2013
    #6
  7. I modified the sensitivity list as you specified and I had 8 warnings, one for each signal which I removed. But there was no errors. Is there a particular reason why we leave only Reset and Clock?

    Can I eliminate the warnings? thanks for pointing out the button1 issue..

    Regarding the self assigning to cnt_H and cnt_L, I was advised to do this to avoid extra memory elements. I do not know if this is true.
    Brandon Spiteri, Jun 7, 2013
    #7
  8. Hi Eilert,
    thanks for pointing that out. I should have shown this file as well:
    I think this is sufficient..

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use work.QuantumBaseSupport.all;

    entity ClockDiv_Gen is
    Generic( Source : integer := BoardClock; --20MHz
    Destination : integer := 200); --100Hz
    Port ( Reset : in STD_LOGIC;
    Clock : in STD_LOGIC;
    refresh_Clock : out STD_LOGIC);
    end ClockDiv_Gen;

    architecture RTL of ClockDiv_Gen is

    begin
    process(Reset,Clock)
    variable Counter : integer range 0 to (Source/(Destination * 2)) := 0;
    variable Cout : std_logic := '0';
    begin
    if (Reset = '0') then
    refresh_Clock <= '0';
    elsif rising_edge(Clock) then
    Counter := Counter + 1;
    if (Counter = (Source/(Destination * 2))) then
    Cout := not Cout;
    Counter := 0;
    end if;
    end if;
    refresh_Clock <= Cout;
    end process;

    end RTL;
    Brandon Spiteri, Jun 7, 2013
    #8
  9. Hi Andy,
    thanks for the tips :) I managed to implement them all. Exceptthe wait for falling_edge(clk); part.

    Quartus is giving me the error when I try to compile:

    Error (10511): VHDL Qualified Expression error at bit_counter_test.vhd(49):falling_edge type specified in Qualified Expression must match time type that is implied for expression by context

    I think this is because ext_clock is declared as std_logic and this expression is expecting type time. I tried to modify the type to time in the general and testbech however, it seems that then I have to change all the logic of the code.. Is this the case?

    thanks

    Brandon
    Brandon Spiteri, Jun 7, 2013
    #9
  10. rickman Guest

    On 6/7/2013 3:09 AM, Brandon Spiteri wrote:
    > I modified the sensitivity list as you specified and I had 8 warnings, one for each signal which I removed. But there was no errors. Is there a particular reason why we leave only Reset and Clock?


    I can't say since I don't know what the errors are. They aren't because
    the signals belong in the sensitivity list.


    > Can I eliminate the warnings? thanks for pointing out the button1 issue..


    What are the errors?


    > Regarding the self assigning to cnt_H and cnt_L, I was advised to do this to avoid extra memory elements. I do not know if this is true.


    That is only true for combinatorial logic processes. This process is
    sequential, no? When you write, "elsif (rising_edge(Clock)) then", you
    are describing a register. All of the signals assigned inside of this
    IF will be remembered in FFs regardless.

    If you have a combinatorial process without an edge or level
    sensitivity, you want all of the inputs (signals on the right side of
    the assignments) in the sensitivity list (or you can just use "all" in
    VHDL 2008 or later) and you need to make sure signals that are assigned
    values are assigned values for all conditions to avoid generating
    registers. Inadvertent latches are not uncommon.

    Does that make sense?

    --

    Rick
    rickman, Jun 8, 2013
    #10
  11. rickman Guest

    On 6/7/2013 3:16 AM, Brandon Spiteri wrote:
    > Hi Andy,
    > thanks for the tips :) I managed to implement them all. Except the wait for falling_edge(clk); part.
    >
    > Quartus is giving me the error when I try to compile:
    >
    > Error (10511): VHDL Qualified Expression error at bit_counter_test.vhd(49): falling_edge type specified in Qualified Expression must match time type that is implied for expression by context
    >
    > I think this is because ext_clock is declared as std_logic and this expression is expecting type time. I tried to modify the type to time in the general and testbech however, it seems that then I have to change all the logic of the code.. Is this the case?


    How about showing the code? I expect this is something in a test bench
    since I can't imagine time and a falling_edge spec would be mixed in
    synthesized code.

    --

    Rick
    rickman, Jun 8, 2013
    #11
  12. On Saturday, 8 June 2013 01:35:31 UTC+2, rickman wrote:
    > On 6/7/2013 3:16 AM, Brandon Spiteri wrote:
    >
    > > Hi Andy,

    >
    > > thanks for the tips :) I managed to implement them all. Except the wait for falling_edge(clk); part.

    >
    > >

    >
    > > Quartus is giving me the error when I try to compile:

    >
    > >

    >
    > > Error (10511): VHDL Qualified Expression error at bit_counter_test.vhd(49): falling_edge type specified in Qualified Expression must match time type that is implied for expression by context

    >
    > >

    >
    > > I think this is because ext_clock is declared as std_logic and this expression is expecting type time. I tried to modify the type to time in the general and testbech however, it seems that then I have to change all the logic of the code.. Is this the case?

    >
    >
    >
    > How about showing the code? I expect this is something in a test bench
    >
    > since I can't imagine time and a falling_edge spec would be mixed in
    >
    > synthesized code.
    >
    >
    >
    > --
    >
    >
    >
    > Rick


    The test bench is the same one in my first post. The warnings are:

    Warning (10492): VHDL Process Statement warning at bit_counter.vhd(43): signal "Start" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
    Brandon Spiteri, Jun 8, 2013
    #12
  13. пÑтница, 7 Ð¸ÑŽÐ½Ñ 2013 г., 11:12:17 UTC+4 пользователь Brandon Spiteri напиÑал:
    > Hi Eilert,
    >
    > thanks for pointing that out. I should have shown this file aswell:
    >
    > I think this is sufficient..
    >
    >
    >
    > library IEEE;
    >
    > use IEEE.STD_LOGIC_1164.ALL;
    >
    > use IEEE.NUMERIC_STD.ALL;
    >
    > use work.QuantumBaseSupport.all;
    >
    >
    >
    > entity ClockDiv_Gen is
    >
    > Generic( Source : integer := BoardClock; --20MHz
    >
    > Destination : integer := 200); --100Hz
    >
    > Port ( Reset : in STD_LOGIC;
    >
    > Clock : in STD_LOGIC;
    >
    > refresh_Clock : out STD_LOGIC);
    >
    > end ClockDiv_Gen;
    >
    >
    >
    > architecture RTL of ClockDiv_Gen is
    >
    >
    >
    > begin
    >
    > process(Reset,Clock)
    >
    > variable Counter : integer range 0 to (Source/(Destination * 2)) := 0;
    >
    > variable Cout : std_logic := '0';
    >
    > begin
    >
    > if (Reset = '0') then
    >
    > refresh_Clock <= '0';
    >
    > elsif rising_edge(Clock) then
    >
    > Counter := Counter + 1;
    >
    > if (Counter = (Source/(Destination * 2))) then
    >
    > Cout := not Cout;
    >
    > Counter := 0;
    >
    > end if;
    >
    > end if;
    >
    > refresh_Clock <= Cout;
    >
    > end process;
    >
    >
    >
    > end RTL;


    Are you use refresh_Clock for clocking your scheme? I don't think that is agood idea. Xilinx prohibit this technic. I think you should use dedicated primitives to clock generating that use dedicated clock nets.

    If I can't use clock primitives or I don't want it, I use a simple entity that generate strobe signal that '0' several clock periods and then '1' one period and so on.
    Then I use it

    if (rising_edge(Clock)) and (strobe = '1') then
    do_what_you_want;
    end if;

    This strobe signal reduce speed of do_what_you_want code without changing of frecuency of Clock.
    Ilya Kalistru, Jun 8, 2013
    #13
  14. rickman Guest

    On 6/8/2013 3:17 AM, Brandon Spiteri wrote:
    > On Saturday, 8 June 2013 01:35:31 UTC+2, rickman wrote:
    >> On 6/7/2013 3:16 AM, Brandon Spiteri wrote:
    >>
    >>> Hi Andy,

    >>
    >>> thanks for the tips :) I managed to implement them all. Except the wait for falling_edge(clk); part.

    >>
    >>>

    >>
    >>> Quartus is giving me the error when I try to compile:

    >>
    >>>

    >>
    >>> Error (10511): VHDL Qualified Expression error at bit_counter_test.vhd(49): falling_edge type specified in Qualified Expression must match time type that is implied for expression by context

    >>
    >>>

    >>
    >>> I think this is because ext_clock is declared as std_logic and this expression is expecting type time. I tried to modify the type to time in the general and testbech however, it seems that then I have to change all the logic of the code.. Is this the case?

    >>
    >>
    >>
    >> How about showing the code? I expect this is something in a test bench
    >>
    >> since I can't imagine time and a falling_edge spec would be mixed in
    >>
    >> synthesized code.
    >>
    >>
    >>
    >> --
    >>
    >>
    >>
    >> Rick

    >
    > The test bench is the same one in my first post. The warnings are:
    >
    > Warning (10492): VHDL Process Statement warning at bit_counter.vhd(43): signal "Start" is read inside the Process Statement but isn't in the Process Statement's sensitivity list


    Sorry, there is no way I can relate "line 43" to the contents of your
    previous post. You need to post the text in a format that preserves the
    lines and replace tabs with spaces so the text isn't all skewed across
    the screen. I'm happy to help, but I don't want to have to dig the info
    out of your posts. Or repost the code pointing to the offending line.

    Looking at the original code I do see a couple of lines at the beginning
    of the count: process (good that you name your processes) that I think
    should not be there.

    Q_H <= std_logic_vector(to_unsigned(Cnt_H, Q_H'length));
    Q_L <= std_logic_vector(to_unsigned(Cnt_L, Q_L'length));

    These are in the clocked process, but not inside the reset or the
    clocked clauses and so are combinatorial statements. They will not
    function in simulation the way they will work in the hardware. Move
    them outside of the process maybe? I'm not sure what your intent is
    with these. Looking at the code I think they need to be concurrent
    statements outside of the clocked process. That may be confusing the
    tools.

    Oh, I see the problem... another problem. You have swapped the enable
    and the clock edge test. The enable (Start = '1') needs to be inside
    the clock test clause.

    elsif (rising_edge(Clock)) then
    if (Start = '1') then
    ...
    --

    Rick
    rickman, Jun 9, 2013
    #14
  15. " The enable (Start = '1') needs to be inside
    the clock test clause. " That solved the problem :) .. thanks a lot. Below is my modified code;



    LIBRARY ieee;

    use ieee.std_logic_1164.all;


    use ieee.numeric_std.unsigned;

    use IEEE.std_logic_unsigned.all;

    entity bit_counter is

    port(Start : in std_logic := '0' ; --was in
    Reset : in std_logic := '1';
    Clock : in std_logic := '0';
    Bit_stream : in std_logic := '0';

    Q_H, Q_L : out std_logic_vector (3 downto 0) := (others => '0')
    );


    end entity bit_counter;

    architecture RTL of bit_counter is

    signal cnt_L, cnt_H : STD_LOGIC_VECTOR (3 downto 0) := "0000";

    begin

    Q_H <= Cnt_H;
    Q_L <= Cnt_L;

    count: process(Reset, Clock)

    begin

    if(Reset = '0' ) then
    cnt_H <= "0000";
    cnt_L <= "0000";

    elsif (rising_edge(Clock)) then


    if (start = '1' and Bit_stream = '1') then
    cnt_H <= cnt_H + 1 ;
    cnt_L <= cnt_L ;


    elsif (start = '1' and Bit_stream = '0') then
    Cnt_L <= Cnt_L + 1 ;
    Cnt_H <= Cnt_H ;

    end if;
    end if;


    end process;

    end architecture RTL;

    _________________________________________________________________________________________________

    Regarding the test bench code below, do you think there is a better way to test my above code?
    Do you think this is sufficient?

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    use ieee.std_logic_unsigned.all;


    entity bit_counter_test is
    end Entity bit_counter_test;

    Architecture behavioral of bit_counter_test is

    Signal Bit_stream, ext_Clock : std_logic := '0';
    Signal Reset_count, Start_count : std_logic := '1';
    Signal Q_H, Q_L : std_logic_vector (3 downto 0) := (others => '0');
    Signal Endsim : std_logic := '0';
    begin

    UUT : entity work.bit_counter
    port map (

    Bit_stream => Bit_stream,
    Start => Start_count,
    Reset => Reset_count,
    Clock => ext_Clock,
    Q_L => Q_L,
    Q_H => Q_H);


    CLK_process :process
    begin
    if(EndSim = '0') then
    ext_Clock <= NOT ext_Clock;
    wait for 2ns;
    else wait;
    end if;
    end process;

    Signals : process

    Begin

    wait for 0.5 ns;
    Start_count <= '1';
    Reset_count <= '1';

    for I in 18 downto 0 loop
    Bit_stream <= '1';
    wait for 4 ns;
    Bit_stream <= '0';
    wait for 4 ns;

    end loop ;

    Reset_count <= '0';
    Start_count <= '1';
    wait for 4 ns;
    Reset_count <= '1';

    for J in 8 downto 0 loop
    Bit_stream <= '1';
    wait for 4 ns;
    Bit_stream <= '0';
    wait for 4 ns;
    end loop;

    Start_count <= '0';
    wait for 20 ns;
    Start_count <= '1';

    for K in 8 downto 0 loop
    Bit_stream <= '1';
    wait for 4 ns;
    Bit_stream <= '0';
    wait for 4 ns;
    end loop;

    EndSim <= '1';
    wait;
    end process;

    end Architecture behavioral;
    Brandon Spiteri, Jun 9, 2013
    #15
  16. Andy Guest

    Brandon,

    wait until falling_edge(clk); -- not wait "for"

    Use "until" for conditions, "for" for time.

    Andy
    Andy, Jun 10, 2013
    #16
  17. Andy Guest

    Rick,

    This illustrates why I advise not using self assignments. People start using them because they heard it did something useful (and they even saw it on the interweb), and nobody really knows what purpose they serve. A self assignment will NEVER prevent inferrence of a latch, but it may actually createone!

    These crutches keep new users from learning what actually causes a latch: Astorage device is inferred when the RTL description requires remembering avalue stored at a previous time (or delta-cycle). If that previous time was a previous clock edge, a register is inferred; if not, a latch is inferred.

    When we read code, we assume that it is needed. That assumption is false inthis case. A self assignment is NEVER needed, but its presence implies it is needed. Otherwise, why would the author have typed it? If you want to leave it in for misguided self-documentation, at least comment it as unnecessary.

    BTW, I use "if" and "then" (also if/generate, while/loop, or when/else) to clearly delineate a conditional expression. There may be parenthesis withinin the expression that do not delineate the entire expression, so parentheses alone do not provide that service. However, I sometimes use them to "help" the editor format multi-line conditional expressions more clearly.

    But the latter is a matter of style, and less of substance (no additional operation by the simulator or the synthesis tool is implied). Many users assume that since other languages require it, it must be required in VHDL too,which is incorrect. Use them if you wish, but not because they are required, that's all.

    Andy
    Andy, Jun 10, 2013
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    1,750
    Timothy Bendfelt
    Jan 19, 2007
  2. Replies:
    9
    Views:
    968
    Juha Nieminen
    Aug 22, 2007
  3. john

    Stream states questions

    john, Sep 8, 2007, in forum: C++
    Replies:
    37
    Views:
    940
    James Kanze
    Sep 11, 2007
  4. edwardfredriks

    counting up instead of counting down

    edwardfredriks, Sep 6, 2005, in forum: Javascript
    Replies:
    6
    Views:
    199
    Dr John Stockton
    Sep 7, 2005
  5. Jeff.M
    Replies:
    6
    Views:
    172
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page