目录
一、设计原理:时序状态机与时间控制
1. 状态定义
2. 核心模块
二、Multisim 电路设计
1. 时钟分频电路
2. 状态控制电路
3. 灯组驱动电路
4. 完整电路框图
三、Vivado Verilog 仿真代码
1. 完整代码
2. 测试代码(Testbench)
3. 仿真结果说明
四、总结
本文针对 “四方向交通信号灯时序控制” 课设需求,从设计原理、Multisim 电路搭建、Vivado Verilog 仿真三个维度展开,完整实现题目要求的灯组时序逻辑。
题目要求:以4个红色指示灯、4个绿色指示灯和4个黄色指示灯模拟路口的东、南、西、北4个方向的红、绿、黄交通灯。控制这些指示灯,使它们按下列规律亮和灭——
- 初始状态为4个方向的红灯全亮,时间1S
- 东、西方向绿灯亮,南、北方向红灯亮。东、西方向通车,时间5S
- 东、西方向黄灯闪烁,南、北方向红灯亮,时间2S
- 东、西方向红灯亮,南、北方向绿灯亮,南、北方向通车,时间5S
- 东、西方向红灯亮,南、北方向黄闪烁,时间2S
- 返回2),继续运行
注:黄灯闪烁通过连续亮0.2S和灭0.2S实现,利用开发板中1KHZ作为设计中的初始时钟,通过分频得到0.2S、1S和5S等时钟信号。
一、设计原理:时序状态机与时间控制
题目要求的交通灯时序是典型的有限状态机(FSM),共 6 个状态,需通过 “时钟分频 + 计数器 + 状态译码” 实现:
1. 状态定义
| 状态编号 | 状态描述 | 持续时间 | 灯组状态(东 / 西 - 南 / 北) |
|---|---|---|---|
| S0 | 初始状态 | 1s | 全红灯 |
| S1 | 东西通行 | 5s | 东 / 西绿灯,南 / 北红灯 |
| S2 | 东西黄灯闪烁 | 2s | 东 / 西黄灯闪烁,南 / 北红灯 |
| S3 | 南北通行 | 5s | 东 / 西红灯,南 / 北绿灯 |
| S4 | 南北黄灯闪烁 | 2s | 东 / 西红灯,南 / 北黄灯闪烁 |
| S5 | 状态跳转 | 0s | 返回 S1 循环 |
2. 核心模块
- 时钟分频模块:将 1kHz 输入时钟分频为 0.2s(5Hz)、1s(1Hz)、5s(0.2Hz)时钟,用于时间控制和黄灯闪烁;
- 计数器模块:对分频后的时钟计数,达到对应状态时间后触发状态跳转;
- 状态译码模块:将状态信号转换为灯组控制信号(红 / 绿 / 黄灯的亮灭);
- 黄灯闪烁模块:通过 0.2s 时钟控制黄灯的 “亮 0.2s - 灭 0.2s” 交替。
二、Multisim 电路设计
使用中规模集成芯片搭建电路,核心器件包括:555 定时器(时钟源)、74LS161(计数器)、74LS138(译码器)、LED 灯组。
1. 时钟分频电路
以 555 定时器生成 1kHz 初始时钟,再通过 74LS161 分频得到目标时钟:
- 1kHz → 1Hz(1s):74LS161 级联成 1000 分频(1000=2^10-24,预置数 0x03E8);
- 1kHz → 5Hz(0.2s):200 分频(预置数 0x00C8)。
电路连接:
- 555 定时器外接 R=1kΩ、C=0.1μF,生成 1kHz 方波;
- 74LS161 的 CLK 接 555 输出,LOAD 端接预置数,RCO 端作为分频后时钟输出。
2. 状态控制电路
用 2 片 74LS161 级联成模 6 计数器(状态 S0-S5),配合 74LS138 译码输出状态信号:
- 74LS161 的 CLK 接 1Hz 时钟,计数范围 0-5(预置数 0x0005);
- 74LS138 的 A/B/C 端接 74LS161 的 Q0-Q2,译码输出 S0-S5 的状态信号。
3. 灯组驱动电路
- 红灯 / 绿灯:直接由 74LS138 的译码信号驱动(高电平亮);
- 黄灯:将译码信号与 5Hz 时钟(0.2s)通过与门连接,实现 “亮 0.2s - 灭 0.2s” 闪烁。
4. 电路框图
[555定时器] → [1kHz时钟] → [74LS161分频] → [1Hz/5Hz时钟] ↓ [74LS161模6计数器] → [74LS138译码] → [灯组控制信号] → [LED灯组] ↓ [与门(黄灯闪烁)]三、Vivado Verilog 仿真代码
通过 Verilog 实现时序状态机,包含分频模块、状态机模块、灯组控制模块,可直接在 Vivado 中仿真验证。
1. 完整代码
`timescale 1ns / 1ps module traffic_light_controller( input clk_1kHz, // 输入1kHz时钟 input rst_n, // 复位信号(低有效) // 灯组输出:east_west[2:0] = {红,黄,绿}, south_north[2:0] = {红,黄,绿} output reg [2:0] east_west, output reg [2:0] south_north ); // 1. 时钟分频:1kHz → 1Hz(1s)、5Hz(0.2s) reg [9:0] cnt_div_1Hz; // 1kHz→1Hz:1000分频 reg [7:0] cnt_div_5Hz; // 1kHz→5Hz:200分频 reg clk_1Hz, clk_5Hz; always @(posedge clk_1kHz or negedge rst_n) begin if(!rst_n) begin cnt_div_1Hz <= 10'd0; clk_1Hz <= 1'b0; end else if(cnt_div_1Hz == 10'd999) begin cnt_div_1Hz <= 10'd0; clk_1Hz <= ~clk_1Hz; end else begin cnt_div_1Hz <= cnt_div_1Hz + 1'd1; end end always @(posedge clk_1kHz or negedge rst_n) begin if(!rst_n) begin cnt_div_5Hz <= 8'd0; clk_5Hz <= 1'b0; end else if(cnt_div_5Hz == 8'd199) begin cnt_div_5Hz <= 8'd0; clk_5Hz <= ~clk_5Hz; end else begin cnt_div_5Hz <= cnt_div_5Hz + 1'd1; end end // 2. 状态机:状态定义+时间计数 typedef enum {S0, S1, S2, S3, S4, S5} state_t; reg [2:0] current_state, next_state; reg [3:0] state_cnt; // 状态持续时间计数器 // 状态跳转(时序逻辑) always @(posedge clk_1Hz or negedge rst_n) begin if(!rst_n) begin current_state <= S0; state_cnt <= 4'd0; end else begin current_state <= next_state; // 状态持续时间计数 if(current_state == S0 && state_cnt == 4'd1) begin // S0:1s state_cnt <= 4'd0; end else if(current_state == S1 && state_cnt == 4'd5) begin // S1:5s state_cnt <= 4'd0; end else if(current_state == S2 && state_cnt == 4'd2) begin // S2:2s state_cnt <= 4'd0; end else if(current_state == S3 && state_cnt == 4'd5) begin // S3:5s state_cnt <= 4'd0; end else if(current_state == S4 && state_cnt == 4'd2) begin // S4:2s state_cnt <= 4'd0; end else begin state_cnt <= state_cnt + 1'd1; end end end // 状态转移逻辑(组合逻辑) always @(*) begin case(current_state) S0: next_state = (state_cnt == 4'd1) ? S1 : S0; S1: next_state = (state_cnt == 4'd5) ? S2 : S1; S2: next_state = (state_cnt == 4'd2) ? S3 : S2; S3: next_state = (state_cnt == 4'd5) ? S4 : S3; S4: next_state = (state_cnt == 4'd2) ? S5 : S4; S5: next_state = S1; // 循环 default: next_state = S0; endcase end // 3. 灯组控制 always @(*) begin case(current_state) S0: begin // 全红灯 east_west = 3'b100; // 红黄绿:100=红灯亮 south_north = 3'b100; end S1: begin // 东西绿灯,南北红灯 east_west = 3'b001; // 001=绿灯亮 south_north = 3'b100; end S2: begin // 东西黄灯闪烁,南北红灯 east_west = clk_5Hz ? 3'b010 : 3'b000; // 5Hz闪烁 south_north = 3'b100; end S3: begin // 南北绿灯,东西红灯 east_west = 3'b100; south_north = 3'b001; end S4: begin // 南北黄灯闪烁,东西红灯 east_west = 3'b100; south_north = clk_5Hz ? 3'b010 : 3'b000; end S5: begin // 跳转状态 east_west = 3'b100; south_north = 3'b100; end default: begin east_west = 3'b100; south_north = 3'b100; end endcase end endmodule2. 测试代码(Testbench)
`timescale 1ns / 1ps module tb_traffic_light; reg clk_1kHz; reg rst_n; wire [2:0] east_west; wire [2:0] south_north; // 实例化被测模块 traffic_light_controller uut( .clk_1kHz(clk_1kHz), .rst_n(rst_n), .east_west(east_west), .south_north(south_north) ); // 生成1kHz时钟 initial begin clk_1kHz = 1'b0; forever #500 clk_1kHz = ~clk_1kHz; // 1kHz=1ms周期 end // 复位与仿真控制 initial begin rst_n = 1'b0; #1000; rst_n = 1'b1; #20000; // 仿真20s,覆盖2个完整周期 $finish; end endmodule3. 仿真结果说明
在 Vivado 中运行仿真后,可观察到:
- 状态跳转:S0 (1s)→S1 (5s)→S2 (2s)→S3 (5s)→S4 (2s)→S1 循环;
- 灯组状态:各状态下东 / 西、南 / 北的红 / 绿 / 黄灯亮灭符合题目要求;
- 黄灯闪烁:S2/S4 状态下,黄灯随 5Hz 时钟交替亮灭。
四、总结
本设计通过Multisim 硬件电路和Vivado Verilog 代码两种方式实现了交通灯时序控制:
- Multisim 电路基于中规模芯片,体现数电 “硬件逻辑” 设计思路;
- Vivado 代码基于状态机,更贴近现代数字系统的 “软件化” 设计方法。
两种方案均满足题目要求的时序逻辑,可直接用于课设仿真验证。