我正在学习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,因此我将wide
和max
的初始设置值用于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 everything
和end 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以外的信号。