如何使用VHDL通用计数器我已在我的代码中给出了如何创建正常的测试平台

我正在学习VHDL,并尝试使用该通用计数器来处理时钟信号。作业包括以安全的方式模拟交通信号灯,同时还提供夜间模式(在途中呈红色闪烁,另一方呈黄色)以及左转弯模式/信号。不幸的是,我不确定如何实际使用gen_counter以及在我的代码中要调出什么内容,以确保其正确运行。这是我要使用的通用计数器:

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

entity gen_counter is
-- we are using the generic construct to allow this counter to be generic.
generic (
        wide : positive; -- how many bits is the counter
        max  : positive  -- what is the max value of the counter ( modulus )
        );
port (
        clk  :in  std_logic; -- system clock
        data     :in  std_logic_vector( wide-1 downto 0 ); -- data in for parallel load,use unsigned(data) to cast to unsigned
        load     :in  std_logic; -- signal to load data into i_count i_count <= unsigned(data);
        enable :in  std_logic; -- clock enable
        reset_n  :in  std_logic; -- reset to zeros use i_count <= (others => '0' ) since size depends on generic
        count    :out std_logic_vector( wide-1 downto 0 ); -- count out
        term     :out std_logic -- maximum count is reached
        );
end;

architecture rtl of gen_counter is
signal i_count : unsigned (wide-1 downto 0); 

begin

count <= std_logic_vector(i_count); 

counter: process(clk,reset) begin
  if (reset_n='1') then -- active high reset
     i_count <= (others => '0'); -- set counter to 0's
     term    <= '0';  -- want the terminal count off on reset
  elsif (rising_edge(clk)) then
    term <='0';
    if (load = '1') then  -- load takes priority
           i_count <= unsigned(data);
    elsif (enable = '1') then -- if enabled the counter is running.
       if (i_count=max) then -- the max value is hit,synchronously set to '0's
          term <='1'; -- we only want this active for 1 clock cycle
         i_count<=(others=>'0');
       else -- increment the counter
          term <= '0'; -- disable to term count,so only high for 1 clock cycle
         i_count <= i_count + 1;
      end if; 
    end if;
   end if;
end process;

end;

下面是我现在尝试使用通用计数器的方式。在我的实体base中,我使用通用并调用初始的宽和最大值(50MHz时钟)。我需要1、2、4和6秒计数器。由于时钟为50MHz,因此我将widemax的初始设置值用于1秒计数器。对于其余部分,我使用了一个4位计数器。在状态机中,我使用“ term”信号作为计数器,这是我认为可能导致问题的原因

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

entity base is 
generic (
  sim_wide : positive := 28;         --width
  sim_max  : positive := 50000000   --max value
  ); 
port (
    --clocks
    MAX10_CLK1_50           :   in      std_logic;

    --seven seg
    HEX0,HEX1,HEX2,HEX3,HEX4,HEX5        :   out std_logic_vector(6 downto 0);
    --general human interface
    KEY                     :   in      std_logic_vector(1 downto 0);
    SW                          :   in      std_logic_vector(9 downto 0);
    LEDR                        :   out std_logic_vector(9 downto 0)
    );

end entity;-- End entity    

architecture lite of base is
--state types
    type north is (north_green,north_yellow,north_red,north_ltgn,north_ltyw,north_night0,north_night1,north_start,nwait);
    type east is (east_green,east_yellow,east_red,east_ltgn,east_ltyw,east_night0,east_night1,ewait);

    signal ncurrent_state: north;
    signal nnext_state: north;
    signal ecurrent_state: east;
    signal enext_state: east;

-- signals to be used
    signal enable_pulse_every_one_second: std_logic;    --enables a pulse every 1 second
    signal enable_pulse_every_two_second: std_logic;    --enables a pulse every 2 seconds
    signal enable_pulse_every_four_second: std_logic;   --enables a pulse every 4 seconds
    signal enable_pulse_every_six_second: std_logic;    --enables a pulse every 6 seconds
    signal reset_n: std_logic;          --reset signal
    signal temp_reset_n: std_logic;

    signal night: std_logic;        --night mode signal
    signal temp_night: std_logic;
    signal ltmode: std_logic;       --left turn mode signal
    signal temp_ltmode: std_logic;
    signal nstart: std_logic;       --north/south start signal
    signal estart: std_logic;       --east/west start signal

--clock values
    signal one_second_count_value: std_logic_vector(3 downto 0);    --count for 1 second
    signal two_second_count_value: std_logic_vector(3 downto 0);    --count for 2 seconds
    signal four_second_count_value: std_logic_vector(3 downto 0);   --count for 4 seconds
    signal six_second_count_value: std_logic_vector(3 downto 0);    --counter for 6 seconds

--output signals for seven seg cntrl
    signal nout0        :std_logic_vector(3 downto 0);
    signal eout5        :std_logic_vector(3 downto 0);

--components
component gen_counter is
generic (
    wide: positive; 
    max: positive  
    );
port (                                                      --port declaration
    clk: in std_logic;
    data: in std_logic_vector(wide-1 downto 0 );
    load: in std_logic;
    enable: in std_logic;
    reset_n: in std_logic;
    count: out std_logic_vector(wide-1 downto 0 );
    term: out std_logic);
end component;  

component seven_segment_cntrl is
    port (                                                  --port declaration
        input: in unsigned(3 downto 0);             --data input
        hex: out std_logic_vector(6 downto 0)       --seven segment output
        );  
end component;

begin

--Reset Mode
    process (MAX10_CLK1_50,KEY(0),temp_reset_n)
        begin
            if (KEY(1) = '1') then
                temp_reset_n <= KEY(1);             --assign key0 to left turn mode
                reset_n <= temp_reset_n;
            elsif rising_edge(MAX10_CLK1_50) then
                temp_reset_n <= '0';
                reset_n  <= temp_reset_n;
            end if;
    end process;

--Night mode 
    process (MAX10_CLK1_50)
        begin
            if rising_edge(MAX10_CLK1_50) then
                temp_night <= SW(1);                    --assign sw1 to left turn mode
                night <= temp_night;
            end if;
    end process; 

-- Left turn mode
    process (MAX10_CLK1_50)
        begin
            if rising_edge(MAX10_CLK1_50) then
                temp_ltmode <= SW(0);               --assign sw0 to left turn mode
                ltmode <= temp_ltmode;
            end if; 
    end process;

----------COUNTERS----------
--counter for 1 second
one_second : gen_counter
generic map (
        wide => sim_wide,--28 bits get 50Mhz down to 1 second
        max => sim_max   --count to 50Million
        )
port map (
        clk => MAX10_CLK1_50,data => (others => '0'),load => '0',enable => '1',reset_n => reset_n,count => open,term => enable_pulse_every_one_second
        );

--counter for 2 seconds         
two_second : gen_counter 
generic map (
        wide => 4,--4 bit counter
        max => 1    --1*2=2
    )
port map (
        clk => MAX10_CLK1_50,enable => enable_pulse_every_one_second,count => two_second_count_value,term => enable_pulse_every_two_second
        );

--counter for 4 seconds
four_second : gen_counter 
generic map (
        wide => 4,--4 bit counter
        max => 3    --1*4=4 
        )
port map (
        clk => MAX10_CLK1_50,count => four_second_count_value,term => enable_pulse_every_four_second
        );

--counter for 6 seconds
six_second : gen_counter 
generic map (
        wide => 4,--4 bit counter
        max => 5    --1*6=6
        )
port map (
        clk => MAX10_CLK1_50,count => six_second_count_value,term => enable_pulse_every_six_second
        );

--North/South Reset 
    process (MAX10_CLK1_50,reset_n)
    begin
        if reset_n = '1' then
            ncurrent_state <= north_start;
        elsif rising_edge (MAX10_CLK1_50) then
            ncurrent_state <= nnext_state;
        end if;
    end process;

--East/West Reset
    process (MAX10_CLK1_50,reset_n)
    begin
        if reset_n = '1' then
            ecurrent_state <= east_red;
        elsif rising_edge (MAX10_CLK1_50) then
            ecurrent_state <= enext_state;
        end if;
    end process;

--combinational process and case statement for north/south
process(ncurrent_state,nnext_state,nstart,enable_pulse_every_one_second,enable_pulse_every_two_second,enable_pulse_every_four_second,enable_pulse_every_six_second)
    begin
            case ncurrent_state is
                when north_start =>
                    if nstart = '1' then
                        nnext_state <= north_green;
                    end if;

                when north_green =>
                    if enable_pulse_every_four_second = '1' then
                        nnext_state <= north_yellow;
                    else
                        nnext_state <= north_green;
                    end if;

                when north_yellow =>
                    if enable_pulse_every_two_second = '1' then
                        nnext_state <= nwait;
                    else
                        nnext_state <= north_yellow;
                    end if; 

                when north_red =>
                    if nstart = '1' then
                        if ltmode = '1' and night = '0' then    
                            nnext_state <= north_ltgn;
                        elsif night = '1' then
                            nnext_state <= north_night0;
                        elsif night = '0' and ltmode = '0' then
                            if enable_pulse_every_six_second = '1' then
                                nnext_state <= north_green;
                            else
                                nnext_state <= north_red;
                            end if;
                        end if;
                    else 
                        nnext_state <= north_red;
                    end if; 

                when north_ltgn =>
                    if enable_pulse_every_four_second = '1' then
                        nnext_state <= north_ltyw;
                    else
                        nnext_state <= north_ltgn;
                    end if;

                when north_ltyw =>
                    if enable_pulse_every_two_second = '1' then
                        nnext_state <= north_green;
                    else
                        nnext_state <= north_ltyw;
                    end if;

                when north_night0 =>
                    if night = '1' then
                        if enable_pulse_every_one_second = '1' then
                            nnext_state <= north_night1;
                        else 
                            nnext_state <= north_night0;
                        end if;
                    else
                        nnext_state <= north_red;
                    end if;

                when north_night1 =>
                    if enable_pulse_every_one_second = '1' then
                        nnext_state <= north_night0;
                    else 
                        nnext_state <= north_night1;
                    end if;

                when nwait =>
                    if nstart = '0' then
                        nnext_state <= north_red;
                    elsif night = '1' then
                        nnext_state <= north_night1;
                    else
                        nnext_state <= nwait;
                    end if;
            end case;
    end process;

--combinatorial process and case statement for east/west lights
process(ecurrent_state,enext_state,estart,enable_pulse_every_six_second)
    begin
            case ecurrent_state is
                when ewait =>
                    if estart = '0' then
                        enext_state <= east_red;
                    elsif night = '1' then
                        enext_state <= east_night1;
                    else
                        enext_state <= ewait;
                    end if; 

                when east_green =>
                    if enable_pulse_every_four_second = '1' then
                        enext_state <= east_yellow;
                    else
                        enext_state <= east_green;
                    end if;

                when east_yellow =>
                    if enable_pulse_every_two_second = '1' then
                        enext_state <= ewait;
                    else
                        enext_state <= east_yellow;
                    end if;

                when east_red =>
                    if estart = '1' then
                        if ltmode = '1' and night = '0' then    
                            enext_state <= east_ltgn;
                        elsif night = '1' then
                            enext_state <= east_night1;
                        elsif night = '0' and ltmode = '0' then
                            if enable_pulse_every_six_second = '1' then
                                enext_state <= east_green;
                            else
                                enext_state <= east_red;
                            end if;
                        end if;
                    else 
                        enext_state <= east_red;
                    end if;     

                when east_ltgn =>
                    if enable_pulse_every_four_second = '1' then
                        enext_state <= east_ltyw;
                    else
                        enext_state <= east_ltgn;
                    end if;

                when east_ltyw =>
                    if enable_pulse_every_two_second = '1' then
                        enext_state <= east_green;
                    else
                        enext_state <= east_ltyw;
                    end if;     

                when east_night0 =>
                    if night = '1' then
                        if enable_pulse_every_one_second = '1' then
                            enext_state <= east_night1;
                        else 
                            enext_state <= east_night0;
                        end if;
                    else
                        enext_state <= ewait;
                    end if;

                when east_night1 =>
                    if enable_pulse_every_one_second = '1' then
                        enext_state <= east_night0;
                    else 
                        enext_state <= east_night1;
                    end if;
            end case;
    end process;

    out1: process (ncurrent_state)
    begin
    estart <= '0';
        case ncurrent_state is
            when north_start =>
                estart <= '0';
                nout0 <= "0000";            --green light

            when north_green =>
                estart <= '0';
                nout0 <= "0000";            --green light

            when north_yellow => 
                estart <= '0';
                nout0 <= "0001";            --yellow light

            when north_red =>
                estart <= '1';
                nout0 <= "0010";            --red light

            when north_ltgn =>
                estart <= '0';
                nout0 <= "0011";            --left turn green and red light

            when north_ltyw =>
                estart <= '0';
                nout0 <= "0100";            --left turn yellow and red light

            when north_night0 =>
                estart <= '0';
                nout0 <= "0101";            --blank

            when north_night1 =>
                estart <= '1';
                nout0 <= "0001";            --yellow light

            when nwait =>
                estart <= '1';
                nout0 <= "0010";            --red light     
        end case;
    end process out1;

    out2: process (ecurrent_state)
    begin
    nstart <= '1';
        case ecurrent_state is          

            when east_green => 
                nstart <= '0';
                eout5 <= "0000";        --green light

            when east_yellow =>
                nstart <= '0';
                eout5 <= "0001";        --yellow light

            when east_red =>
                nstart <= '1';
                eout5 <= "0010";        --red light

            when east_ltgn =>
                nstart <= '0';
                eout5 <= "0011";        --left turn green and red light

            when east_ltyw =>
                nstart <= '0';
                eout5 <= "0100";        --left turn yellow and red light

            when east_night0 =>
                nstart <= '0';
                eout5 <= "0101";        --blank

            when east_night1 =>
                nstart <= '0';
                eout5 <= "0010";        --red light

            when ewait =>
                nstart <= '1';
                eout5 <= "0010";        --red light 
        end case;
    end process out2;

hex1 <= (others => '1');
hex2 <= (others => '1');
hex3 <= (others => '1');
hex4 <= (others => '1');

        hex5_driver: seven_segment_cntrl
          port map(
             input => unsigned(eout5),hex   => HEX5
             );  
        hex0_driver: seven_segment_cntrl
          port map(
             input => unsigned(nout0),hex   => HEX0
             ); 
end architecture;

这是正在使用的seven_seg_cntrl:

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

ENTITY seven_segment_cntrl IS
    PORT (
        input : IN UNSIGNED(3 DOWNTO 0);
        hex : OUT STD_LOGIC_VECTOR(6 downto 0)
    );  
END ENTITY seven_segment_cntrl;

ARCHITECTURE logic OF seven_segment_cntrl IS
signal seven_seg : std_logic_vector (6 downto 0);  -- upper bit is seg_a,lower bit is seg_g
BEGIN
    hex(6 downto 0) <= not seven_seg(0) & not seven_seg(1) & not seven_seg(2)&
                        not seven_seg(3) & not seven_seg(4) & not seven_seg(5)& 
                              not seven_seg(6);

    PROCESS (input)
    BEGIN
        CASE input IS
            WHEN  "0000" =>  -- 7-segment display green light when input equals "0000"
              seven_seg <= "0001000"; 
            WHEN  "0001" =>  -- 7-segment display yellow light when input equals "0001"
              seven_seg <= "0000001"; 
            WHEN  "0010" =>  -- 7-segment display red light when input equals "0010"
              seven_seg <= "1000000"; 
            WHEN  "0011" =>  -- 7-segment display red w/ LT green when input equals "0011"
              seven_seg <= "1000010";  
            WHEN  "0100" =>  -- 7-segment display red w/ LT yellow when input equals "0100"
              seven_seg <= "1000100"; 
            WHEN  "0101" =>  -- 7-segment display "_" when input equals "0100"
              seven_seg <= "0000000";
            WHEN OTHERS =>   -- 7-segment display 'E' for error
              seven_seg <= "1001111";  
        END CASE;
    END PROCESS;
END ARCHITECTURE logic;

我的板子仅在7段显示“ north_green”,而从那儿看不到任何地方,这使我认为这是一个时钟问题。 Modelsim也没有显示任何内容。我不确定term信号是否是用于计数器的正确信号,因此在如何在代码中使用此通用时钟以获得所需的正确脉冲方面,我需要帮助。另外,我想指出,我的代码可以按原样编译而没有错误。预先谢谢你

编辑:这是我的测试台(显然不起作用)。 -- add more vectors to test everythingend process;之间的区域显然是我们唯一可以编辑的部分。

libraRY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;

entity lite_tb is
end entity;

architecture behav of lite_tb is

component base is
port (
    --clocks

    MAX10_CLK1_50           :   in      std_logic;

    --seven seg
    HEX0,HEX5        :   out std_logic_vector(6 downto 0);
    --general human interface
    KEY                     :   in      std_logic_vector(1 downto 0);
    SW                          :   in      std_logic_vector(9 downto 0);
    LEDR                        :   out std_logic_vector(9 downto 0)

);
end component;

constant CLK_PER:time := 20 ns;
constant clk_cycle:time := 2*clk_per;

signal aclr_n : std_logic;
signal clk    : std_logic;
signal sw     : std_logic_vector(9 downto 0);
signal key    : std_logic_vector(1 downto 0);
signal ledr   : std_logic_vector(9 downto 0);
signal hex0   : std_logic_vector(6 downto 0); -- right most
signal hex1   : std_logic_vector(6 downto 0);   
signal hex2   : std_logic_vector(6 downto 0);   
signal hex3   : std_logic_vector(6 downto 0);   
signal hex4   : std_logic_vector(6 downto 0);   
signal hex5   : std_logic_vector(6 downto 0); -- left most

begin


    clock:process begin  -- this process just continues to run as the simulation time continues
         clk <= '0';
         wait for CLK_PER;
         clk <= '1';
         wait for CLK_PER;
         end process;



    vectors:process begin -- put you test vectors here,remember to advance the simulation in modelsim

        aclr_n <= '0';      -- assert the asynchronous reset signal
        sw     <= "0000000000"; -- drive all the switch inputs to a 0
        wait for 5 ns;          -- wait for a fraction of the clock so stimulus is not occuring on clock edges
        aclr_n <= '1';          -- release the reset signal

        wait for 2*clk_cycle; --  wait for a number of clock cycles


        -- add more vectors to test everything
        sw     <= "0000000001"; 
        wait for 2*clk_cycle; 
        wait for 2000 ns; 
        sw     <= "0000000000";

        wait for 2*clk_cycle;   

        sw     <= "0000000010"; 
        wait for 2*clk_cycle;
        wait for 2000 ns;           

        aclr_n <= '0';      
        sw     <= "0000000000"; 
        wait for 5 ns;          
        aclr_n <= '1';          

        end process;

key(1) <= aclr_n;
key(0) <= clk;


-- instantiate the device under test (dut)
dut :base
port map (
    --clocks

    MAX10_CLK1_50   => clk,--seven seg
    HEX0        => hex0,HEX1        => hex1,HEX2        => hex2,HEX3        => hex3,HEX4        => hex4,HEX5        => hex5,--general human interface
    KEY         => key,SW          => sw,LEDR        => ledr     

);
end architecture;

使用Modelsim,无论代码或TB发生什么变化,我都无法显示this以外的信号。

soei4366 回答:如何使用VHDL通用计数器我已在我的代码中给出了如何创建正常的测试平台

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3094373.html

大家都在问