【FPGA】Verilog实现交通信号灯
更新:
其余各部分代码已公布。
-------------------------------------------------------------------------------------------------------
大二数字电路的课程设计中,有一份日常作业使用Xilinx FPGA实现简易交通信号灯,但很可惜当时时间有限,没能最终完成。正好在这一学期选修SOPC设计课程,同样采用了Xilinx FPGA,故打算重新完成交通信号灯的相关内容。
本项目采用Digilent公司生产的BASYS3开发板,基于Xilinx FPGA,该板子目前可以在马云家买到,不过价格偏贵,在校学生可在digilent官网申请以更低价格买入。
大致的框架如下,只是个构思,还很不完善,后续会进行修改。比如现在我目前并没有把计时功能完全从State模块中摘出来,只是用Timer实例化了一个1s计时器在里面,并且用count计数。
TOP代码
module BASYS_BIGPROJECT_Top ( input clk, output wire[5:0]Trans_light, output wire[3:0]Num_choose, output wire[7:0]Num_data ); wire [1:0]state_connect; wire [2:0]count_connect; //wire [6:0]Num_data_connect; BASYS_BIGPROJECT_State state( .clk(clk), .state(state_connect), .count(count_connect) ); BASYS_BIGPROJECT_Display display( .clk(clk), .count(count_connect), .state(state_connect), .Trans_light(Trans_light), .Num_choose(Num_choose), .Num_data(Num_data) ); endmodule
State代码
module BASYS_BIGPROJECT_State( input clk, output [1:0]state, output [2:0]count ); reg [1:0]reg_state = 0; reg [2:0]reg_count = 0; wire cnt_connect; Freq_divider clk_1s( .clk(clk), .rst(0), .count(cnt_connect) ); //states for lights parameter MR_BG = 2'b00; parameter MR_BY = 2'b01; parameter MG_BR = 2'b11; parameter MY_BR = 2'b10; //green led for 4s, yellow led for 2s always@(posedge cnt_connect) begin case(reg_state) MR_BG:begin //main red, branch green if(reg_count<4) begin reg_state <= MR_BG; reg_count <= reg_count + 1; end else begin reg_state <= MR_BY; reg_count <= 3'b000; end end MR_BY:begin //main red, branch yellow if(reg_count<2) begin reg_state <= MR_BY; reg_count <= reg_count + 1; end else begin reg_state <= MG_BR; reg_count <= 3'b000; end end MG_BR:begin //main green, branch red if(reg_count<4) begin reg_state <= MG_BR; reg_count <= reg_count + 1; end else begin reg_state <= MY_BR; reg_count <= 3'b000; end end MY_BR:begin //main yellow, branch red if(reg_count<2) begin reg_state <= MY_BR; reg_count <= reg_count + 1; end else begin reg_state <= MR_BG; reg_count <= 3'b000; end end endcase end assign state = reg_state; assign count = reg_count; endmodule
Display代码
module BASYS_BIGPROJECT_Display ( input clk, input [1:0]state, input [2:0]count, output [5:0]Trans_light, output [3:0]Num_choose, output [7:0]Num_data ); reg [5:0]reg_light = 0; reg [3:0]reg_Num_digit = 0; reg [3:0]reg_Num_choose = 4'b1110; wire [7:0]Num_data_connect; wire refresh; reg [3:0]Data_Main = 0; reg [3:0]Data_Branch = 0; //divider for refresh Freq_divider #(13)play( .clk(clk), .rst(1'b0), .count(refresh) ); //Decode the digit Digital_decode decoder( .clk(clk), .data(reg_Num_digit), .Trans_num(Num_data_connect) ); //switch the light always @(posedge clk) begin case(state) 2'b00:begin reg_light <= 6'b100001; Data_Main <= 6 - count; Data_Branch <= 4 - count; end 2'b01:begin reg_light <= 6'b100010; Data_Main <= 2 - count; Data_Branch <= 2 - count; end 2'b11:begin reg_light <= 6'b001100; Data_Main <= 4 - count; Data_Branch <= 6 - count; end 2'b10:begin reg_light <= 6'b010100; Data_Main <= 2 - count; Data_Branch <= 2 - count; end endcase end //Scanned display for digit always @(posedge refresh) begin if(reg_Num_choose == 4'b1110) begin reg_Num_choose <= 4'b1011; reg_Num_digit <= Data_Main; end else begin reg_Num_choose <= 4'b1110; reg_Num_digit <= Data_Branch; end end assign Trans_light = reg_light; assign Num_choose = reg_Num_choose; assign Num_data = Num_data_connect; endmodule
Tools代码
module Freq_divider #(parameter N = 27) ( input clk, input rst, output [N-1:0]freq_div, output count ); reg [N-1:0]regN = 0; always@(posedge clk) begin if(rst) regN <= 0; else regN <= regN+1; end assign freq_div = regN; assign count = (regN == 2**N-1)?1'b1:1'b0; endmodule module Digital_decode ( input clk, input [3:0]data, output [7:0]Trans_num ); reg [7:0]reg_Trans_num = 0; always@(posedge clk) begin case(data) 4'd0: reg_Trans_num <= 8'b0000_0011; 4'd1: reg_Trans_num <= 8'b1001_1111; 4'd2: reg_Trans_num <= 8'b0010_0101; 4'd3: reg_Trans_num <= 8'b0000_1101; 4'd4: reg_Trans_num <= 8'b1001_1001; 4'd5: reg_Trans_num <= 8'b0100_1001; 4'd6: reg_Trans_num <= 8'b0100_0001; 4'd7: reg_Trans_num <= 8'b0001_1111; 4'd8: reg_Trans_num <= 8'b0000_0001; 4'd9: reg_Trans_num <= 8'b0000_1001; default: reg_Trans_num <= 8'b0001_0001; endcase end assign Trans_num = reg_Trans_num; endmodule
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话