VHDL交通灯控制器设计

要求:
1. 控制对象为单个十字路口的南北向交通灯,具体包含一个左转箭头灯(可以显示红色,绿色)和一个圆形指示灯(可以显示红色,绿色,以及黄色)
2. 圆形指示灯:当接收到东西向左转箭头灯的左转完成信号(外界输入)后,经过3次黄灯闪烁(一秒闪烁一次)后由原本的红灯跳转为绿灯,绿灯维持24秒,经过3次黄灯闪烁跳转回红灯,并输出一个左转允许信号;
3. 左转箭头灯:当接收到圆形指示灯的左转允许信号后,由红色跳转为绿色,维持15秒后跳转回红色,并输出一个左转完成信号;
4. 设置一个交通管制按钮,该按钮按下后,所有信号灯亮起红色;
5. 需要分别完成以下两个模块的VHDL设计并分别进行仿真测试:圆灯控制器和箭头灯控制器;
6. 按照合理逻辑将上述两个模块进行连接,必要时适当添加周边电路,完成整体的VHDL设计,再进行仿真测试

上课听了 但还是不会 有没有好人解答一下😭😭

来自NewBing和LP的编写:

以下是一个VHDL交通灯控制器的设计示例,包括圆灯控制器、箭头灯控制器以及整体的控制器。

  1. 圆灯控制器设计:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity RoundLightController is
    port (
        clk: in std_logic;                          -- 时钟信号
        reset: in std_logic;                        -- 复位信号
        leftTurnComplete: in std_logic;             -- 左转完成信号
        roundLight: out std_logic_vector(2 downto 0);-- 圆灯输出信号(0:红色,1:绿色,2:黄色)
        leftTurnAllow: out std_logic                 -- 左转允许信号
    );
end entity RoundLightController;

architecture rtl of RoundLightController is
    constant clk_freq: integer := 1_000_000;    -- 时钟频率(1MHz)
    constant delay_1s: integer := clk_freq;      -- 1秒延迟
    constant delay_1s_div_2: integer := clk_freq / 2;  -- 0.5秒延迟
    
    signal roundState: std_logic_vector(1 downto 0);  -- 圆灯状态(00:红灯,01:绿灯,10:黄灯)
    signal roundCounter: unsigned(7 downto 0);        -- 圆灯计数器
    signal roundYellowCounter: unsigned(7 downto 0);  -- 圆灯黄灯计数器
    
begin
    process (clk, reset)
    begin
        if reset = '1' then
            roundState <= "00";                  -- 复位时初始状态为红灯
            roundCounter <= (others => '0');     -- 复位时计数器清零
            roundYellowCounter <= (others => '0');-- 复位时黄灯计数器清零
            roundLight <= "000";                  -- 复位时圆灯输出为红色
            leftTurnAllow <= '0';                 -- 复位时左转允许信号为禁止
        elsif rising_edge(clk) then
            if roundCounter >= delay_1s then
                roundCounter <= (others => '0');         -- 计数器重新清零
                case roundState is
                    when "00" =>                           -- 红灯状态
                        roundLight <= "001";                -- 输出黄色
                        roundYellowCounter <= (others => '0');  -- 黄灯计数器清零
                        if leftTurnComplete = '1' then
                            roundState <= "10";            -- 如果收到左转完成信号,进入黄灯状态
                        end if;
                    when "10" =>                           -- 黄灯状态
                        if roundYellowCounter >= delay_1s_div_2 then
                            roundYellowCounter <= (others => '0');  -- 计数器重新清零
                            roundState <= "01";            -- 进入绿灯状态
                        else
                            roundYellowCounter <= roundYellowCounter + 1;  -- 计数器递增
                        end if;
                    when "01" =>                           -- 绿灯状态
                        roundLight <= "010";                -- 输出绿色
                        roundState <= "01";                -- 绿灯状态维持
                        roundCounter <= roundCounter + 1;   -- 计数器递增
                        if roundCounter >= 24 * delay_1s then
                            roundCounter <= (others => '0');     -- 计数器重新清零
                            roundState <= "10";            -- 进入黄灯状态
                            leftTurnAllow <= '1';         -- 输出左转允许信号
                        end if;
                end case;
            else
                roundCounter <= roundCounter + 1;         -- 计数器递增
            end if;
        end if;
    end process;
end architecture;
  1. 箭头灯控制器设计:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity LeftTurnLightController is
    port (
        clk: in std_logic;                          -- 时钟信号
        reset: in std_logic;                        -- 复位信号
        roundLeftTurnAllow: in std_logic;            -- 圆灯左转允许信号
        leftTurnLight: out std_logic_vector(1 downto 0); -- 箭头灯输出信号(0:红色,1:绿色)
        leftTurnComplete: out std_logic              -- 左转完成信号
    );
end entity LeftTurnLightController;

architecture rtl of LeftTurnLightController is
    constant clk_freq: integer := 1_000_000;    -- 时钟频率(1MHz)
    constant delay_1s: integer := clk_freq;      -- 1秒延迟
    
    signal leftTurnState: std_logic;            -- 箭头灯状态(0:红灯,1:绿灯)
    signal leftTurnCounter: unsigned(7 downto 0);-- 箭头灯计数器
    
begin
    process (clk, reset)
    begin
        if reset = '1' then
            leftTurnState <= '0';                    -- 复位时初始状态为红灯
            leftTurnCounter <= (others => '0');      -- 复位时计数器清零
            leftTurnLight <= "00";                    -- 复位时箭头灯输出为红色
            leftTurnComplete <= '0';                  -- 复位时左转完成信号为禁止
        elsif rising_edge(clk) then
            if roundLeftTurnAllow = '1' then
                if leftTurnCounter >= delay_1s then
                    leftTurnCounter <= (others => '0');       -- 计数器重新清零
                    case leftTurnState is
                        when '0' =>                           -- 红灯状态
                            leftTurnLight <= "01";             -- 输出绿色
                            leftTurnState <= '1';             -- 进入绿灯状态
                            leftTurnComplete <= '1';          -- 输出左转完成信号
                        when '1' =>                           -- 绿灯状态
                            leftTurnLight <= "00";             -- 输出红色
                            leftTurnState <= '0';             -- 进入红灯状态
                            leftTurnComplete <= '0';          -- 左转完成信号禁止
                    end case;
                else
                    leftTurnCounter <= leftTurnCounter + 1;     -- 计数器递增
                end if;
            else
                leftTurnCounter <= (others => '0');     -- 圆灯左转允许信号禁止时,计数器清零
                leftTurnLight <= "00";                   -- 箭头灯输出为红色
                leftTurnState <= '0';                    -- 进入红灯状态
                leftTurnComplete <= '0';                 -- 左转完成信号禁止
            end if;
        end if;
    end process;
end architecture;
  1. 整体控制器设计:
library ieee;
use ieee.std_logic_1164.all;

entity TrafficLightController is
    port (
        clk: in std_logic;                          -- 时钟信号
        reset: in std_logic;                        -- 复位信号
        roundLeftTurnAllow: out std_logic;           -- 圆灯左转允许信号
        roundLight: out std_logic_vector(2 downto 0);-- 圆灯输出信号(0:红色,1:绿色,2:黄色)
        leftTurnLight: out std_logic_vector(1 downto 0); -- 箭头灯输出信号(0:红色,1:绿色)
        leftTurnComplete: in std_logic;              -- 左转完成信号
        trafficControlButton: in std_logic           -- 交通管制按钮
    );
end entity TrafficLightController;

architecture rtl of TrafficLightController is
    component RoundLightController is
        port (
            clk: in std_logic;                          -- 时钟信号
            reset: in std_logic;                        -- 复位信号
            leftTurnComplete: in std_logic;             -- 左转完成信号
            roundLight: out std_logic_vector(2 downto 0);-- 圆灯输出信号(0:红色,1:绿色,2:黄色)
            leftTurnAllow: out std_logic                 -- 左转允许信号
        );
    end component;

    component LeftTurnLightController is
        port (
            clk: in std_logic;                          -- 时钟信号
            reset: in std_logic;                        -- 复位信号
            roundLeftTurnAllow: in std_logic;            -- 圆灯左转允许信号
            leftTurnLight: out std_logic_vector(1 downto 0); -- 箭头灯输出信号(0:红色,1:绿色)
            leftTurnComplete: out std_logic              -- 左转完成信号
        );
    end component;

    signal roundLeftTurnAllow_internal: std_logic;      -- 内部信号,用于连接两个控制器
    signal roundLight_internal: std_logic_vector(2 downto 0);-- 内部信号,用于连接两个控制器
    signal leftTurnLight_internal: std_logic_vector(1 downto 0); -- 内部信号,用于连接两个控制器

begin
    RoundLightControl: RoundLightController
        port map (
            clk => clk,                               -- 时钟信号
            reset => reset,                           -- 复位信号
            leftTurnComplete => leftTurnComplete,     -- 左转完成信号
            roundLight => roundLight_internal,        -- 圆灯输出信号
            leftTurnAllow => roundLeftTurnAllow_internal -- 圆灯左转允许信号
        );

    LeftTurnLightControl: LeftTurnLightController
        port map (
            clk => clk,                               -- 时钟信号
            reset => reset,                           -- 复位信号
            roundLeftTurnAllow => roundLeftTurnAllow_internal, -- 圆灯左转允许信号
            leftTurnLight => leftTurnLight_internal,  -- 箭头灯输出信号
            leftTurnComplete => leftTurnComplete      -- 左转完成信号
        );

    process (clk, reset, trafficControlButton)
    begin
        if reset = '1' then
            roundLeftTurnAllow_internal <= '0';      -- 复位时圆灯左转允许信号禁止
            roundLight_internal <= "000";            -- 复位时圆灯输出为红色
            leftTurnLight_internal <= "00";          -- 复位时箭头灯输出为红色
        elsif rising_edge(clk) then
            if trafficControlButton = '1' then
                roundLeftTurnAllow_internal <= '0';  -- 交通管制按钮按下时圆灯左转允许信号禁止
                roundLight_internal <= "000";        -- 交通管制按钮按下时圆灯输出为红色
                leftTurnLight_internal <= "00";      -- 交通管制按钮按下时箭头灯输出为红色
            else
                roundLeftTurnAllow_internal <= roundLeftTurnAllow_internal;  -- 圆灯左转允许信号保持不变
                roundLight_internal <= roundLight_internal;                  -- 圆灯输出保持不变
                leftTurnLight_internal <= leftTurnLight_internal;            -- 箭头灯输出保持不变
            end if;
        end if;
    end process;

    roundLeftTurnAllow <= roundLeftTurnAllow_internal;    -- 输出圆灯左转允许信号
    roundLight <= roundLight_internal;                    -- 输出圆灯输出信号
    leftTurnLight <= leftTurnLight_internal;              -- 输出箭头灯输出信号

end architecture;

这个整体控制器将圆灯控制器和箭头灯控制器连接在一起,并添加了一个交通管制按钮的逻辑。交通管制按钮按下时,所有信号灯都会亮起红色,即圆灯输出为红色,箭头灯输出为红色。其他情况下,两个控制器根据逻辑进行状态转换和信号输出。

引用ChatGPT部分内容参考:
首先,我们需要定义一些常量和信号:

constant CLK_FREQ : integer := 50_000_000; -- 时钟频率为50MHz
constant GREEN_TIME : integer := 24 * CLK_FREQ; -- 绿灯持续时间为24秒
constant YELLOW_TIME : integer := 1 * CLK_FREQ; -- 黄灯闪烁时间为1秒
constant LEFT_TIME : integer := 15 * CLK_FREQ; -- 左转箭头灯持续时间为15秒

signal clk : std_logic := '0'; -- 时钟信号
signal reset : std_logic := '0'; -- 复位信号
signal east_left_done : std_logic := '0'; -- 东西向左转完成信号
signal north_green : std_logic := '0'; -- 南北向绿灯信号
signal north_yellow : std_logic := '0'; -- 南北向黄灯信号
signal north_red : std_logic := '1'; -- 南北向红灯信号
signal north_left : std_logic := '0'; -- 南北向左转箭头灯信号
signal north_left_done : std_logic := '0'; -- 南北向左转完成信号
signal control : std_logic := '0'; -- 交通管制按钮信号

接下来,我们可以编写圆灯控制器的代码。该控制器需要实现圆形指示灯的状态转换和左转允许信号的输出。我们可以使用一个状态机来实现这个功能:

process (clk, reset)
    type state_t is (RED, YELLOW1, YELLOW2, GREEN);
    variable state : state_t := RED;
    variable counter : integer := 0;
begin
    if reset = '1' then
        state := RED;
        counter := 0;
        north_green <= '0';
        north_yellow <= '0';
        north_red <= '1';
        north_left_done <= '0';
    elsif rising_edge(clk) then
        case state is
            when RED =>
                north_green <= '0';
                north_yellow <= '0';
                north_red <= '1';
                if east_left_done = '1' then
                    counter := 0;
                    state := YELLOW1;
                end if;
            when YELLOW1 =>
                north_green <= '0';
                north_yellow <= '1';
                north_red <= '0';
                if counter = YELLOW_TIME then
                    counter := 0;
                    state := YELLOW2;
                else
                    counter := counter + 1;
                end if;
            when YELLOW2 =>
                north_green <= '0';
                north_yellow <= '0';
                north_red <= '1';
                if counter = YELLOW_TIME then
                    counter := 0;
                    state := GREEN;
                else
                    counter := counter + 1;
                end if;
            when GREEN =>
                north_green <= '1';
                north_yellow <= '0';
                north_red <= '0';
                if counter = GREEN_TIME then
                    counter := 0;
                    state := YELLOW1;
                    north_left_done <= '1';
                else
                    counter := counter + 1;
                end if;
        end case;
    end if;
end process;

在上面的代码中,我们定义了一个状态机,包含了红灯、黄灯1、黄灯2和绿灯四个状态。在每个状态下,我们根据需要设置南北向三个信号的值,并根据计数器的值进行状态转换。当接收到东西向左转完成信号时,我们将状态转换为黄灯1,并重置计数器。当绿灯持续时间达到设定值时,我们将状态转换为黄灯1,并输出左转允许信号。

接下来,我们可以编写箭头灯控制器的代码。该控制器需要实现左转箭头灯的状态转换和左转完成信号的输出。我们可以使用一个简单的状态机来实现这个功能:

process (clk, reset)
    type state_t is (RED, GREEN);
    variable state : state_t := RED;
    variable counter : integer := 0;
begin
    if reset = '1' then
        state := RED;
        counter := 0;
        north_left <= '0';
        north_left_done <= '0';
    elsif rising_edge(clk) then
        case state is
            when RED =>
                north_left <= '0';
                if north_left_done = '1' then
                    counter := 0;
                    state := GREEN;
                end if;
            when GREEN =>
                north_left <= '1';
                if counter = LEFT_TIME then
                    counter := 0;
                    state := RED;
                    north_left_done <= '0';
                else
                    counter := counter + 1;
                end if;
        end case;
    end if;
end process;

在上面的代码中,我们定义了一个状态机,包含了红灯和绿灯两个状态。在每个状态下,我们根据需要设置南北向左转箭头灯的值,并根据计数器的值进行状态转换。当接收到圆形指示灯的左转允许信号时,我们将状态转换为绿灯,并重置计数器。当左转箭头灯持续时间达到设定值时,我们将状态转换为红灯,并输出左转完成信号。

最后,我们需要将两个控制器连接起来,并添加交通管制按钮的功能。我们可以使用一个简单的if语句来实现这个功能:

process (clk, reset)
begin
    if reset = '1' then
        control <= '0';
    elsif rising_edge(clk) then
        if control = '1' then
            north_green <= '0';
            north_yellow <= '0';
            north_red <= '1';
            north_left <= '0';
            north_left_done <= '0';
        else
            -- 圆灯控制器
            -- 箭头灯控制器
        end if;
    end if;
end process;

在上面的代码中,我们根据交通管制按钮的状态来控制南北向四个信号的值。当按钮按下时,所有信号灯亮起红色。否则,我们分别调用圆灯控制器和箭头灯控制器的代码来控制南北向四个信号的值。

最后,我们需要编写一个顶层模块,将时钟、复位和控制信号连接起来,并将南北向四个信号输出到FPGA的引脚上。这个模块的代码可能如下所示:

entity top is
    port (
        clk : in std_logic;
        reset : in std_logic;
        control : in std_logic;
        north_green : out std_logic;
        north_yellow : out std_logic;
        north_red : out std_logic;
        north_left : out std_logic;
        north_left_done : out std_logic;
        east_left_done : in std_logic
    );
end entity;

architecture rtl of top is
begin
    -- 圆灯控制器
    process (clk, reset, east_left_done)
        -- 圆灯控制器的代码
    end process;

    -- 箭头灯控制器
    process (clk, reset, north_left_done)
        -- 箭头灯控制器的代码
    end process;

    -- 交通管制按钮
    process (clk, reset, control)
        -- 交通管制按钮的代码
    end process;

    -- 输出信号
    north_green <= north_green;
    north_yellow <= north_yellow;
    north_red <= north_red;
    north_left <= north_left;
    north_left_done <= north_left_done;
end architecture;

在上面的代码中,我们定义了一个顶层模块,将时钟、复位和控制信号连接起来,并将南北向四个信号输出到FPGA的引脚上。我们分别调用圆灯控制器、箭头灯控制器和交通管制按钮的代码,并将南北向四个信号的值输出到FPGA的引脚上。

最后,我们需要进行仿真测试,以确保整个设计的正确性。我们可以使用Vivado或ModelSim等仿真工具来进行仿真测试。在仿真测试中,我们需要模拟输入信号,包括时钟、复位、交通管制按钮和东西向左转完成信号,并观察输出信号的变化,以确保整个设计的正确性。

首先,我们可以将整个系统分成三个模块:圆形指示灯控制器、左转箭头灯控制器和交通管制按钮控制器。其中,前两个模块就是您所要求的圆形指示灯和左转箭头灯控制器,第三个模块用于控制整个系统的开关。

圆形指示灯控制器:

1、使用一个计数器,每次计数器达到24秒时,将圆形指示灯从绿色跳转回红色,同时输出一个左转允许信号。在此之前,需要先对圆形指示灯进行3次黄灯闪烁,以提示行驶人员。
2、为了实现3次黄灯闪烁功能,我们需要使用一个计数器和一个状态机。当计数器达到1秒时,状态机将圆形指示灯由红色跳转为黄色,当计数器达到2秒时,状态机将灯颜色跳转为红色,同时开始进行下一次闪烁,直到完成3次。
左转箭头灯控制器:

1、当接收到圆形指示灯的左转允许信号时,将左转箭头灯从红色跳转为绿色并维持15秒,在15秒结束后跳转回红色并输出一个左转完成信号。
交通管制按钮控制器:

1、当该按钮按下时,所有信号灯亮起红色。
在连接两个模块时,我们需要使用一个信号进行通讯,以实现圆形指示灯控制器向左转箭头灯控制器发送左转允许信号的功能。具体实现方法可以是:当圆形指示灯控制器计数器达到24秒时,向一个信号发出高电平,表示左转允许信号已经输出;左转箭头灯控制器通过检测该信号状态,判断是否需要进行左转动作。

另外,在实际硬件设计中,我们还需要考虑到信号灯的互锁问题,防止多个信号灯同时亮起,导致交通事故等问题。因此,我们需要对两个控制器进行互锁保护,以确保只有一个信号灯处于绿灯状态。

最后,我们可以基于上述设计方案进行VHDL代码编写并进行仿真测试,以验证设计的正确性和可靠性。需要注意的是,由于实际硬件设计中存在时序相关的问题,因此在进行仿真测试时需要考虑各个信号的传输延迟等因素。
以下是各个模块的详细代码:

圆形指示灯控制器:


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

entity circular_lamp_controller is
  port (
    signal from_left_arrow : in std_logic; -- 来自左转箭头灯控制器的信号
    signal reset : in std_logic; -- 重置信号
    signal start : in std_logic; -- 开始信号
    signal stop : out std_logic; -- 停止信号,用于互锁保护
    signal circular_red : out std_logic; -- 圆形指示灯红色信号
    signal circular_yellow : out std_logic; -- 圆形指示灯黄色信号
    signal circular_green : out std_logic; -- 圆形指示灯绿色信号
    signal allow_left : out std_logic -- 左转允许信号
  );
end entity;

architecture rtl of circular_lamp_controller is
  -- 定义状态机状态
  type state_type is (red, yellow, green);
  signal state : state_type;
  
  -- 定义计数器,用于实现3次黄灯闪烁
  signal counter : unsigned(5 downto 0);
  
  -- 定义时钟计数器,用于计时
  signal clk_counter : unsigned(23 downto 0);
  
begin
  -- 计数器递增
  process(clk_counter)
  begin
    if rising_edge(clk_counter) then
      if start = '1' then
        counter <= counter + 1;
      end if;
    end if;
  end process;
  
  -- 状态机逻辑
  process(state, from_left_arrow, counter)
  begin
    case state is
      when red =>
        if from_left_arrow = '1' then
          if counter >= 18 and counter <= 21 then
            circular_yellow <= '1';
            circular_red <= '0';
            circular_green <= '0';
            allow_left <= '0';
          elsif counter = 22 then
            circular_yellow <= '0';
            circular_red <= '0';
            circular_green <= '1';
            allow_left <= '0';
            state <= green;
          else
            circular_red <= '1';
            circular_yellow <= '0';
            circular_green <= '0';
            allow_left <= '0';
          end if;
        else
          circular_red <= '1';
          circular_yellow <= '0';
          circular_green <= '0';
          allow_left <= '0';
        end if;
      when yellow =>
        if counter = 24 then
          circular_red <= '1';
          circular_yellow <= '0';
          circular_green <= '0';
          allow_left <= '1';
          state <= red;
          counter <= (others => '0'); -- 重置计数器
        elsif counter >= 20 and counter <= 23 then
          circular_yellow <= '1';
          circular_red <= '0';
          circular_green <= '0';
          allow_left <= '0';
        else
          circular_yellow <= '0';
          circular_red <= '0';
          circular_green <= '0';
          allow_left <= '0';
        end if;
      when green =>
        if from_left_arrow = '1' then
          if counter >= 0 and counter <= 2 then
            circular_yellow <= '1';
            circular_red <= '0';
            circular_green <= '1';
            allow_left <= '0';
          elsif counter >= 3 and counter <= 26 then
            circular_yellow <= '0';
            circular_red <= '0';
            circular_green <= '1';
            allow_left <= '0';
          elsif counter >= 27 and counter <= 29 then
            circular_yellow <= '1';
            circular_red <= '0';
            circular_green <= '0';
            allow_left <= '0';
          elsif counter = 30 then
            circular_yellow <= '0';
            circular_red <= '1';
            circular_green <= '0';
            allow_left <= '0';
            state <= yellow;
            counter <= (others => '0'); -- 重置计数器
          end if;
        else
          if counter >= 0 and counter <= 22 then
            circular_yellow <= '0';
            circular_red <= '0';
            circular_green <= '1';
            allow_left <= '0';
          elsif counter >= 23 and counter <= 25 then
            circular_yellow <= '1';
            circular_red <= '0';
            circular_green <= '0';
            allow_left <= '0';
          elsif counter = 26 then
            circular_yellow <= '0';
            circular_red <= '1';
            circular_green <= '0';
            allow_left <= '0';
            state <= yellow;
            counter <= (others => '0'); -- 重置计数器
          end if;
        end if;
    end case;
  end process;
  
  -- 时钟计数器递增
  process(clk)
  begin
    if rising_edge(clk) then
      if reset = '1' then
        clk_counter <= (others => '0');
      elsif start = '1' then
        clk_counter <= clk_counter + 1;
      end if;
    end if;
  end process;
  
  -- 互锁保护逻辑
  stop <= circular_yellow or circular_green or allow_left;
  
end architecture;

左转箭头灯控制器:


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

entity left_arrow_lamp_controller is
  port (
    signal from_circular_lamp : in std_logic; -- 来自圆形指示灯控制器的信号,用于接收左转允许信号
    signal reset : in std_logic; -- 重置信号
    signal start : in std_logic; -- 开始信号
    signal stop : out std_logic; -- 停止信号,用于互锁保护
    signal left_arrow_red : out std_logic; -- 左转箭头灯红色信号
    signal left_arrow_green : out std_logic; -- 左转箭头灯绿色信号
    signal left_finished : out std_logic -- 左转完成信号
  );
end entity;

architecture rtl of left_arrow_lamp_controller is
  -- 定义计数器,用于计时
  signal counter : unsigned(23 downto 0);
  
  -- 定义状态机状态
  type state_type is (red, green);
  signal state : state_type;
  
begin
  -- 计数器递增
  process(counter)
  begin
    if rising_edge(counter) then
      if start = '1' then
        counter <= counter + 1;
      end if;
    end if;
  end process;
  
  -- 状态机逻辑
  process(state, from_circular_lamp, counter)
  begin
    case state is
      when red =>
        if from_circular_lamp = '1' then
          left_arrow_red <= '0';
          left_arrow_green <= '1';
          left_finished <= '0';
          state <= green;
          counter <= (others => '0'); -- 重置计数器
        else
          left_arrow_red <= '1';
          left_arrow_green <= '0';
          left_finished <= '0';
        end if;
      when green =>
        if counter = 15 then
          left_arrow_red <= '1';
          left_arrow_green <= '0';
          left_finished <= '1';
          state <= red;
          counter <= (others => '0'); -- 重置计数器
        else
          left_arrow_red <= '0';
          left_arrow_green <= '1';
          left_finished <= '0';
        end if;
    end case;
  end process;
  
  -- 互锁保护逻辑
  stop <= left_arrow_green or left_finished;
  
end architecture;

交通管制按钮控制器:


library ieee;
use ieee.std_logic_1164.all;

entity traffic_control_button_controller is
  port (
    signal button : in std_logic; -- 交通管制按钮信号
    signal reset : in std_logic; -- 重置信号
    signal start : in std_logic; -- 开始信号
    signal circular_red : out std_logic; -- 圆形指示灯红色信号
    signal circular_yellow : out std_logic; -- 圆形指示灯黄色信号
    signal circular_green : out std_logic; -- 圆形指示灯绿色信号
    signal left_arrow_red : out std_logic; -- 左转箭头灯红色信号
    signal left_arrow_green : out std_logic; -- 左转箭头灯绿色信号
    signal allow_left : out std_logic; -- 左转允许信号
    signal left_finished : out std_logic -- 左转完成信号
  );
end entity;

architecture rtl of traffic_control_button_controller is

begin
  process(button, reset, start)
  begin
    if reset = '1' then
      -- 硬件复位
      circular_red <= '1';
      circular_yellow <= '0';
      circular_green <= '0';
      left_arrow_red <= '1';
      left_arrow_green <= '0';
      allow_left <= '0';
      left_finished <= '0';
    elsif button = '1' then
      -- 交通管制按钮被按下
      circular_red <= '1';
      circular_yellow <= '0';
      circular_green <= '0';
      left_arrow_red <= '1';
      left_arrow_green <= '0';
      allow_left <= '0';
      left_finished <= '0';
    else
      -- 正常工作状态
      circular_red <= '1';
      circular_yellow <= '0';
      circular_green <= '1';
      left_arrow_red <= '1';
      left_arrow_green <= '0';
      allow_left <= '0';
      left_finished <= '0';
    end if;
  end process;
  
end architecture;

顶层文件的代码,将三个模块串联起来:


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

entity top_level is
  port (
    signal button : in std_logic; -- 交通管制按钮信号
    signal reset : in std_logic; -- 重置信号
    signal start : in std_logic; -- 开始信号
    signal clk : in std_logic; -- 时钟信号
    signal circular_red : out std_logic; -- 圆形指示灯红色信号
    signal circular_yellow : out std_logic; -- 圆形指示灯黄色信号
    signal circular_green : out std_logic; -- 圆形指示灯绿色信号
    signal left_arrow_red : out std_logic; -- 左转箭头灯红色信号
    signal left_arrow_green : out std_logic; -- 左转箭头灯绿色信号
    signal allow_left : out std_logic; -- 左转允许信号
    signal left_finished : out std_logic -- 左转完成信号
  );
end entity;

architecture rtl of top_level is
  -- 实例化模块
  signal from_left_arrow : std_logic;
  signal stop_circular_lamp : std_logic;
  signal stop_left_arrow : std_logic;
  
  component traffic_control_button_controller
    port (
      button : in std_logic;
      reset : in std_logic;
      start : in std_logic;
      circular_red : out std_logic;
      circular_yellow : out std_logic;
      circular_green : out std_logic;
      left_arrow_red : out std_logic;
      left_arrow_green : out std_logic;
      allow_left : out std_logic;
      left_finished : out std_logic
    );
  end component;
  
  component circular_lamp_controller 
    port (
      from_left_arrow : in std_logic;
      reset : in std_logic;
      start : in std_logic;
      stop : out std_logic;
      circular_red : out std_logic;
      circular_yellow : out std_logic;
      circular_green : out std_logic;
      allow_left : out std_logic
    );
  end component;
  
  component left_arrow_lamp_controller 
    port (
      from_circular_lamp : in std_logic;
      reset : in std_logic;
      start : in std_logic;
      stop : out std_logic;
      left_arrow_red : out std_logic;
      left_arrow_green : out std_logic;
      left_finished : out std_logic
    );
  end component;

begin
  -- 实例化模块并连接信号
  traffic_control_button_inst : traffic_control_button_controller
  port map (
    button => button,
    reset => reset,
    start => start,
    circular_red => circular_red,
    circular_yellow => circular_yellow,
    circular_green => circular_green,
    left_arrow_red => left_arrow_red,
    left_arrow_green => left_arrow_green,
    allow_left => allow_left,
    left_finished => left_finished
  );
  
  circular_lamp_inst : circular_lamp_controller
  port map (
    from_left_arrow => from_left_arrow,
    reset => reset,
    start => start,
    stop => stop_circular_lamp,
    circular_red => circular_red,
    circular_yellow => circular_yellow,
    circular_green => circular_green,
    allow_left => allow_left
  );
  
  left_arrow_lamp_inst : left_arrow_lamp_controller
  port map (
    from_circular_lamp => allow_left,
    reset => reset,
    start => start,
    stop => stop_left_arrow,
    left_arrow_red => left_arrow_red,
    left_arrow_green => left_arrow_green,
    left_finished => left_finished
  );
  
  -- 连接信号,将左转箭头灯控制器的输出与圆形指示灯控制器的输入相连
  from_left_arrow <= left_arrow_green;
  
end architecture;