VHDL交通灯控制器

时间:2015-01-05 16:19:40

标签: vhdl state-machine

以下是红绿灯控制器的简单代码。它根据计数器值循环通过状态。但是我希望它在第一个状态下再保持10秒,当按下任何想法时我会怎么做。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity TLC is
    Port (
              Trafficlights: out  STD_LOGIC_Vector (5 downto 0);
              Clck : in  STD_LOGIC;
              Reset : in  STD_LOGIC;
              P_B : in STD_LOGIC);
 end TLC;

architecture Behavioral of TLC is
  type state_type is (st0_R1_G2, st1_R1_A1_A2, st2_G1_R2, st3_A1_R2_A2); 

  signal state: state_type; 
  signal count : std_logic_vector (3 downto 0);

  constant sec10 : std_logic_vector ( 3 downto 0) := "1010";
  constant sec2 : std_logic_vector (3 downto 0 ) := "0010";
  constant sec16: std_logic_vector (3 downto 0 ) := "1111";
begin
  process (Clck,Reset)
  begin
    if Reset='1' then
      state <= st0_R1_G2;         --reset to initial state
      count <= X"0";             -- reset counter
    elsif Clck' event and Clck = '1' then --rising edge
       case (state) is              ---state transitions
         when st0_R1_G2 =>
           if count < sec10 then
             state <= st0_R1_G2;
             count <= count + 1;                
           else  
             state <= st1_R1_A1_A2;
             count <= X"0";
           end if;

         when st1_R1_A1_A2 =>
           if count < sec2 then
             state <=  st1_R1_A1_A2;
             count <= count + 1;
           else
             state <= st2_G1_R2;
             count <= X"0";
           end if;

         when st2_G1_R2 =>
           if count < sec10 then
             state <= st2_G1_R2;
             count <= count + 1;
           else
             state <= st3_A1_R2_A2;
             count <= X"0";
           end if;

         when st3_A1_R2_A2 =>   
           if count < sec2 then
             state <=  st3_A1_R2_A2;
             count <= count + 1;
           else
             state <=st0_R1_G2;
             count <= X"0";
           end if; 

         when others =>
           state <= st0_R1_G2;
       end case;      
     end if;
   end process;

   OUTPUT_DECODE: process (state)
   begin
     case state is 
       when st0_R1_G2 =>    Trafficlights <= "100001";  -- Traffic Red 1, Pedestrian Green 1 
       when st1_R1_A1_A2 => Trafficlights <= "110010";
       when st2_G1_R2 =>    Trafficlights <= "001100";
       when st3_A1_R2_A2 => Trafficlights <= "010110";
       when others =>       Trafficlights <= "100001";
     end case; 
   end process;
 end Behavioral;

1 个答案:

答案 0 :(得分:0)

我还没有模拟过这个。

这个想法是将count计数器延长一点,包含额外的10秒。输入p_b用于异步设置按钮事件锁存器,用于启动扩展计数,可能允许人行横道流量在前10秒内遍历。

由JK触发器(crosstime)控制。这里值得注意的特征应该是仅在延长的20秒周期的前10秒启用交叉步行。你没有得到许可,无法跨越。

所有这一切都假定您的按钮是按需行人过路处请求,您不能解释您的州名和灯光。

我猜你想要用crosstime给行人绿灯做准备。

(如果这不起作用或者不是你想要的,你就得到了你付出的代价。)

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

entity tlc is
    port (
        trafficlights:  out std_logic_vector (5 downto 0);
        clck:           in  std_logic;
        reset:          in  std_logic;
        p_b:            in std_logic
    );
 end entity tlc;

architecture behavioral of tlc is
    type state_type is (st0_r1_g2, st1_r1_a1_a2, st2_g1_r2, st3_a1_r2_a2); 

    signal state: state_type; 
    signal count: std_logic_vector  (4 downto 0) ; -- (3 downto 0);
    signal pb_event:    std_logic;
    signal crosstime: std_logic;  -- JK FF

    constant sec10 : std_logic_vector (4 downto 0) := "01010"; -- ( 3 downto 0) := "1010";
    constant sec2 : std_logic_vector (4 downto 0) := "00010"; -- (3 downto 0 ) := "0010";
    -- constant sec16: std_logic_vector (4 downto 0) := "01111"; -- (3 downto 0 ) := "1111";
    constant sec20: std_logic_vector (4 downto 0) := "10100"; -- new
begin

    process (clck, reset, p_b)  -- added push button
    begin
        if p_b = '1' and reset = '0' then  -- asynch set for push button
            pb_event <= '1';
        end if;
        if reset = '1' then
            state <= st0_r1_g2;         -- reset to initial state
            count <= (others => '0');   -- reset counter
            pb_event <= '0';
            crosstime  <= '0';
        elsif clck' event and clck = '1' then -- rising edge
            if pb_event = '1' and count = "00000" then  -- J input
                crosstime <= '1';
            end if;
            case (state) is              -- state transitions
                when st0_r1_g2 =>
                    if (crosstime = '0' and count < 20) or 
                       (crosstime = '1' and count < sec10) then
                        state <= st0_r1_g2;
                        count <= count + 1;
                    else  
                        state <= st1_r1_a1_a2;
                        count <= "00000"; -- x"0";
                        if crosstime = '1' then   -- K input
                            crosstime <= '0';
                            pb_event <= '0';
                        end if;
                    end if;
                when st1_r1_a1_a2 =>
                    if count < sec2 then
                        state <=  st1_r1_a1_a2;
                        count <= count + 1;
                    else
                        state <= st2_g1_r2;
                        count <= (others => '0');
                    end if;
                when st2_g1_r2 =>
                    if count < sec10 then
                        state <= st2_g1_r2;
                        count <= count + 1;
                    else
                        state <= st3_a1_r2_a2;
                        count <= (others => '0');
                    end if;
                when st3_a1_r2_a2 =>   
                    if count < sec2 then
                        state <=  st3_a1_r2_a2;
                        count <= count + 1;
                    else
                        state <=st0_r1_g2;
                        count <= (others => '0');
                    end if; 
                when others =>
                    state <= st0_r1_g2;
            end case;
        end if;
    end process;

output_decode: 
    process (state)
    begin
        case state is 
            when st0_r1_g2 =>    trafficlights <= "100001";  -- traffic red 1, pedestrian green 1 
            when st1_r1_a1_a2 => trafficlights <= "110010";
            when st2_g1_r2 =>    trafficlights <= "001100";
            when st3_a1_r2_a2 => trafficlights <= "010110";
            when others =>       trafficlights <= "100001";
        end case; 
    end process;
end architecture behavioral;

<小时/> * ...香港专业教育学院试图合成这个,我得到并且错误说&#34;信号pb_event无法合成,错误的同步描述。当前软件版本不支持用于描述同步元素(寄存器,内存等)的描述样式。&#34;你有什么想法是因为它的异步并且与其他同步设计不兼容吗?*

在不知道供应商抱怨pb_even的情况下,它会牵扯我们的手。

似乎抱怨在pb_event上同时进行异步设置和异步重置。删除异步重置可能会解决问题(需要使用该集来告诉我们有人想要使用人行横道)。

让我们将pb_event触发器移出当前进程以使其可用。仅使用set输入的结果是重置将设置pb_event并导致第一次crosswalk事件。

注意我仍然不了解交通灯,并且我在状态st0_r1_g2中进行的修改预计在较长的20秒间隔的前10秒内启用人行横道灯。这不包括在内。

此外,您可以简单地将计数与最终计数进行比较,&#34; / =&#34;而不是&#34;&lt;&#34;这可能导致计数比较逻辑减少。这可能发生,因为count总是介于0和结束计数之间。平等比量级比较容易得多。我也没有进行这些更改(并且我很想为计数终端值设置单独的识别器)。

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

entity tlc is
    port (
        trafficlights:  out std_logic_vector (5 downto 0);
        clck:           in  std_logic;
        reset:          in  std_logic;
        p_b:            in std_logic
    );
 end entity tlc;

architecture behavioral of tlc is
    type state_type is (st0_r1_g2, st1_r1_a1_a2, st2_g1_r2, st3_a1_r2_a2); 

    signal state: state_type; 
    signal count: std_logic_vector  (4 downto 0) ;
    signal pb_event:    std_logic;
    signal crosstime: std_logic;  -- JK FF

    constant sec10 : std_logic_vector (4 downto 0) := "01010"; 
    constant sec2 : std_logic_vector (4 downto 0) := "00010";
    constant sec20: std_logic_vector (4 downto 0) := "10100";

begin

pbevent:
    process (clck, reset, p_b)
    begin
        if p_b = '1' or reset = '1' then -- async set for push button
            pb_event <= '1';             -- reset will give crosswalk event
        elsif clck'event and clck = '1' then
            if state = st0_r1_g2 and 
              (( crosstime = '1' and count = sec10) or count = sec20) then
                pb_event <= '0';
            end if;
        end if;
    end process;
unlabelled:
    process (clck, reset) 
    begin

        if reset = '1' then
            state <= st0_r1_g2;         -- reset to initial state
            count <= (others => '0');   -- reset counter
            crosstime  <= '0';
        elsif clck'event and clck = '1' then
            if pb_event = '1' and count = "00000" then  -- J input
                crosstime <= '1';
            end if;
            case (state) is
                when st0_r1_g2 =>
                    if (crosstime = '0' and count < sec20) or 
                       (crosstime = '1' and count < sec10) then
                        state <= st0_r1_g2;
                        count <= count + 1;
                    else  
                        state <= st1_r1_a1_a2;
                        count <= "00000";
                        if crosstime = '1' then   -- K input
                            crosstime <= '0';
                        end if;
                    end if;
                when st1_r1_a1_a2 =>
                    if count < sec2 then
                        state <=  st1_r1_a1_a2;
                        count <= count + 1;
                    else
                        state <= st2_g1_r2;
                        count <= (others => '0');
                    end if;
                when st2_g1_r2 =>
                    if count < sec10 then
                        state <= st2_g1_r2;
                        count <= count + 1;
                    else
                        state <= st3_a1_r2_a2;
                        count <= (others => '0');
                    end if;
                when st3_a1_r2_a2 =>   
                    if count < sec2 then
                        state <=  st3_a1_r2_a2;
                        count <= count + 1;
                    else
                        state <=st0_r1_g2;
                        count <= (others => '0');
                    end if; 
                when others =>
                    state <= st0_r1_g2;
            end case;
        end if;
    end process;
output_decode: 
    process (state)
    begin
        case state is 
            when st0_r1_g2 =>    trafficlights <= "100001";  -- traffic red 1, pedestrian green 1 
            when st1_r1_a1_a2 => trafficlights <= "110010";
            when st2_g1_r2 =>    trafficlights <= "001100";
            when st3_a1_r2_a2 => trafficlights <= "010110";
            when others =>       trafficlights <= "100001";
        end case; 
    end process;
end architecture behavioral;

状态st0_r1_g2中找到的条件已折叠为单独写入&#39; 0&#39;到了pb_event触发器。您可能会预计任何时间count = sec20应该清除触发器。