目录
[1. 状态定义](#1. 状态定义)
[2. 核心模块](#2. 核心模块)
[二、Multisim 电路设计](#二、Multisim 电路设计)
[1. 时钟分频电路](#1. 时钟分频电路)
[2. 状态控制电路](#2. 状态控制电路)
[3. 灯组驱动电路](#3. 灯组驱动电路)
[4. 完整电路框图](#4. 完整电路框图)
[三、Vivado Verilog 仿真代码](#三、Vivado Verilog 仿真代码)
[1. 完整代码](#1. 完整代码)
[2. 测试代码(Testbench)](#2. 测试代码(Testbench))
[3. 仿真结果说明](#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
endmodule
2. 测试代码(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
endmodule
3. 仿真结果说明
在 Vivado 中运行仿真后,可观察到:
- 状态跳转:S0 (1s)→S1 (5s)→S2 (2s)→S3 (5s)→S4 (2s)→S1 循环;
- 灯组状态:各状态下东 / 西、南 / 北的红 / 绿 / 黄灯亮灭符合题目要求;
- 黄灯闪烁:S2/S4 状态下,黄灯随 5Hz 时钟交替亮灭。
四、总结
本设计通过Multisim 硬件电路 和Vivado Verilog 代码两种方式实现了交通灯时序控制:
- Multisim 电路基于中规模芯片,体现数电 "硬件逻辑" 设计思路;
- Vivado 代码基于状态机,更贴近现代数字系统的 "软件化" 设计方法。
两种方案均满足题目要求的时序逻辑,可直接用于课设仿真验证。