过去两天这一次令人难以置信,所以我来到互联网寻求帮助。
首先背景信息...... 我正在使用Altera DE0板为uni工作的交通灯项目。关于VHDL,我完成了n00b,这个第一个任务或多或少是"这里有一个有限状态机的例子和一个LPM计数器的例子,去做一些流量灯&#34 ;.我认为这个想法只是为了感受使用VHDL并弄乱代码来使某些东西发挥作用。
我们从FSM上的教科书(Free Range VHDL p93 iirc)中得到了一个例子,然后展示了如何使用Quartus中的Megawizard插件管理器创建一个LPM计数器,基本上只需合并/扩展它们。这是我使用VHDL做的第一件事。
交通信号灯应该是主要道路和小路的交叉路口。默认状态将是主要道路绿色和次要道路红色。它应该保持这种状态,直到它检测到按钮(即小路上的汽车)然后变为琥珀色然后变为红色,然后小路将从红色变为绿色并保持绿色10秒。它将保持在彼此状态1秒钟。 我已经使用了9个状态(A-I)和一个LPM计数器,而我只想在" q"的第26位和第29位寻找1。计数器的输出(?)为1秒和10秒延迟。
我的问题是我不知道在哪里设置和重置计时器。从技术上讲,它应该在移动到每个状态后重置,然后在移动到下一个状态时设置(即允许计数)。
我将粘贴下面的代码,目前timer_rst位被注释掉了。我已经尝试将它们放在代码中的所有不同行中,但最接近它的工作是设置和重置定时器,其中注释了设置和重置部分。当我一次一个地取消评论它们并且每次从状态A转到B然后转C时运行它,但之后它会跳到E然后它快速地通过状态移动到所有状态LED发光,似乎随机跳过不同的状态。显然这不是应该怎么做的!
那么有人可以帮助我吗?
我希望我在这里得到了足够好的解释。我会粘贴指向运行我的代码的电路板视频的链接,您也可以查看下面的代码。
感谢您提供的任何帮助!
--Finite state machine using DE0 board implementing a set
--of traffic tights at a major road/minor road junction.
--Major road is green until car present at minor road
--then goes to red while minor road goes to green.
--8 states, A-H. A is 'default' state
--1 sec delay: state B,C,D,F,G,H, 10 sec delay: state E,I.
--Maj Rd lights: LEDG(5 downto 3) Red/Amber/Green.
--Min Rd lights: LEDG(2 downto 0) Red/Amber/Green.
--State vector printed on LEDG(9 downto 6) in binary
--library declarations
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY lpm; --allows use of Altera LPM functions
USE lpm.all;
--entity
entity TRAFFICLIGHTS is
port(
KEY : in std_logic_vector(1 downto 0); --minor rd car present KEY(1) & reset KEY(0)-ACTIVE LOW!
CLOCK_50 : in std_logic;
LEDG : out std_logic_vector(9 downto 0); --6 lights 2 * (red/amber/green) & state vector
HEX0 : out std_LOGIC_VECTOR(7 downto 0) --display current state
);
end TRAFFICLIGHTS;
-- architecture
architecture TRAFFICLIGHTS_arch of TRAFFICLIGHTS is
type state_type is (A,B,C,D,E,F,G,H,I);
signal PS, NS : state_type;
signal timer_rst : std_logic; --wiring to delay components , one_sec, ten_sec
signal timer_q : std_logic_vector(29 downto 0); --output from timer
--LPM counter
component timer
PORT
(
aclr : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (29 DOWNTO 0) --uses bit 29 for 10 secs, bit 26 for 1 sec
);
end component;
begin
--wiring up LPM counter to signals
U1 : timer
PORT MAP (
aclr => timer_rst,
clock => clock_50,
q => timer_q
);
--detects change in clock, next state or reset key press
sync_proc: process (clock_50, NS, KEY(0))
begin
if (KEY(0)='0') then --if reset pressed, return to state A
PS <= A;
elsif (rising_edge(clock_50)) then --else put present state in next state
PS <= NS;
end if;
end process sync_proc;
--detect change in present state or KEY(1) i.e. minor road car present
comb_proc: process (PS, KEY(1))
begin
case PS is
when A => --when in A: MajRd green, MinRd red, no delay
--show state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0001";
HEX0(7 downto 0) <= "10001000"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (KEY(1) = '0') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= B; --if car present @MinRd, next state is B
else NS <= A;
end if;
when B => --when in B: MajRd amber, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0010";
HEX0(7 downto 0) <= "10000011"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '1'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= C;
else NS <= B;
end if;
when C => --when in C: MajRd red, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0011";
HEX0(7 downto 0) <= "11000110"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= D;
else NS <= C;
end if;
when D => --when in D: MajRd red, MinRd red/amber, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0100";
HEX0(7 downto 0) <= "10100001"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '1'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= E;
else NS <= D;
end if;
when E => --when in E: MajRd red, MinRd green, 10 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0101";
HEX0(7 downto 0) <= "10000110"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '0'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '1'; --MinGreen
if (timer_q(29) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= F;
else NS <= E;
end if;
when F => --when in F: MajRd red, MinRd amber, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0110";
HEX0(7 downto 0) <= "10001110"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '0'; --MinRed
LEDG(1) <= '1'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= G;
else NS <= F;
end if;
when G => --when in G: MajRd red, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0111";
HEX0(7 downto 0) <= "10010000"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= H;
else NS <= G;
end if;
when H => --when in H: MajRd red/amber, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "1000";
HEX0(7 downto 0) <= "10001001"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= I;
else NS <= H;
end if;
--new state allows MajRd to stay green (10 sec) if car at MinRd or not
when I => --when in I: MajRd green, MinRd red, 10 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "1001";
HEX0(7 downto 0) <= "11111001"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(29) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= C;
else NS <= A;
end if;
when others => -- the catch-all condition
PS <= A; -- if anything else, return to state A
end case;
end process comb_proc;
end TRAFFICLIGHTS_arch;
视频: https://www.dropbox.com/s/70tkr67zdjj8pyk/File%2018-03-2015%2017%2057%2054.mov?dl=0
尝试添加中间状态,这里是以下前几个的case语句中的代码。它刚刚开始并直接跳到B状态,而不是去任何地方。
case PS is
when A => --when in A: MajRd green, MinRd red, no delay
--show state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0001";
HEX0(7 downto 0) <= "10001000"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (KEY(1) = '0') then
timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= B; --if car present @MinRd, next state is B
else NS <= A_1;
end if;
when A_1 =>
--LEDs and 7 seg same as A
LEDG(9 downto 0) <= "0001001100";
HEX0(7 downto 0) <= "10001000"; --display state on 7 seg
timer_rst <= '0'; -- allow timer to count
NS <= B;
when B => --when in B: MajRd amber, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0010";
HEX0(7 downto 0) <= "10000011"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '1'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= B_1;
else NS <= B;
end if;
when B_1 =>
--LEDs and 7 seg same as B
LEDG(9 downto 0) <= "0010010100";
HEX0(7 downto 0) <= "10000011"; --display state on 7 seg
timer_rst <= '0'; -- allow timer to count
NS <= C;
答案 0 :(得分:0)
克里斯,检查&#34;硬件中的有限状态机......&#34;,V。A. Pedroni,麻省理工学院出版社,第166页。