VL57. 交通灯
描述
要求实现一个交通红绿灯,具有红黄绿三个小指示灯和一个行人按钮,正常情况下,机动车道指示灯按照60时钟周期绿灯,5个时钟周期黄灯,10个时钟周期红灯循环。当行人按钮按下,如果剩余绿灯时间大于10个时钟,则缩短为10个时钟,小于10个时钟则保持不变。
注:机动车道的指示灯和人行道指示灯应该是配对的,当机动车道的灯为绿或者黄时,人行道的灯为红;当机动车道的灯为红时,人行道的灯为绿,为简便起见,只考虑机动车道的指示灯。
模块的信号接口图如下:
输入描述
输出描述
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`timescale 1ns/1ns module triffic_light ( input rst_n, //异位复位信号,低电平有效 input clk, //时钟信号 input pass_request, output wire[7:0]clock, output reg red, output reg yellow, output reg green ); parameter rst = 3'd0, R = 3'd1, Y = 3'd2, G = 3'd3; reg [7:0] cnt; reg [1:0] state, n_state; always@(posedge clk or negedge rst_n)begin if(~rst_n)begin state <= rst; end else begin state <= n_state; end end always@(*)begin case(state) rst: n_state = (cnt == 8'd8) ? R : rst; R: n_state = (cnt == 8'd1) ? Y : R; Y: n_state = (cnt == 8'd1) ? G : Y; G: n_state = (cnt == 8'd1) ? R : G; default: n_state = rst; endcase end always@(posedge clk or negedge rst_n)begin if(~rst_n)begin cnt <= 8'd10; end else begin if(cnt == 8'd1)begin case(state) G, rst : cnt <= 8'd10; Y : cnt <= 8'd60; R : cnt <= 8'd5; default : cnt <= 8'd10; endcase end else if(cnt==8'd8&&state==rst)begin cnt <= 8'd10; end else if((pass_request) & (cnt > 8'd10) & (state == G))begin cnt <= 8'd10; end else begin cnt <= cnt - 1'd1; end end end always@(posedge clk or negedge rst_n)begin if(~rst_n)begin red <= 1'd0; yellow <= 1'd0; green <= 1'd0; end else begin case(n_state) rst: begin red <= 1'd0; yellow <= 1'd0; green <= 1'd0; end R: begin red <= 1'd1; yellow <= 1'd0; green <= 1'd0; end Y: begin red <= 1'd0; yellow <= 1'd1; green <= 1'd0; end G: begin red <= 1'd0; yellow <= 1'd0; green <= 1'd1; end endcase end end assign clock = cnt; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`timescale 1ns/1ns module triffic_light ( input rst_n, //异位复位信号,低电平有效 input clk, //时钟信号 input pass_request, output wire[7:0]clock, output reg red, output reg yellow, output reg green ); parameter idle = 2'd0, s1_red = 2'd1, s2_yellow = 2'd2, s3_green = 2'd3; reg [7:0] cnt; reg [1:0] state; reg p_red,p_yellow,p_green; //用于缓存信号灯的前一时刻的数值,判断上升沿 always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= idle; p_red <= 1'b0; p_green <= 1'b0; p_yellow <= 1'b0; end else case(state) idle: begin p_red <= 1'b0; p_green <= 1'b0; p_yellow <= 1'b0; state <= s1_red; end s1_red: begin p_red <= 1'b1; p_green <= 1'b0; p_yellow <= 1'b0; if (cnt == 3) state <= s2_yellow; else state <= s1_red; end s2_yellow: begin p_red <= 1'b0; p_green <= 1'b0; p_yellow <= 1'b1; if (cnt == 3) state <= s3_green; else state <= s2_yellow; end s3_green: begin p_red <= 1'b0; p_green <= 1'b1; p_yellow <= 1'b0; if (cnt == 3) state <= s1_red; else state <= s3_green; end endcase end always @(posedge clk or negedge rst_n) if(!rst_n) cnt <= 7'd10; else if (pass_request&&green&&(cnt>10)) cnt <= 7'd10; else if (!green&&p_green) cnt <= 7'd60; else if (!yellow&&p_yellow) cnt <= 7'd5; else if (!red&&p_red) cnt <= 7'd10; else cnt <= cnt -1; assign clock = cnt; always @(posedge clk or negedge rst_n) if(!rst_n) begin yellow <= 1'd0; red <= 1'd0; green <= 1'd0; end else begin yellow <= p_yellow; red <= p_red; green <= p_green; end endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`timescale 1ns/1ns module triffic_light ( input rst_n, //异位复位信号,低电平有效 input clk, //时钟信号 input pass_request, output wire[7:0]clock, output reg red, output reg yellow, output reg green ); reg [6:0] cnt; reg flag; reg [3:0]flag_cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin flag<=1'b0; cnt <= 7'd0; end else if (flag == 1'b0) begin if (cnt == 7'd2) begin flag <= 1'b1; cnt <= 7'b0; end else cnt <= cnt +1'b1; end else if (pass_request) begin if (cnt <= 7'd65) cnt <= 7'd65; else cnt <= cnt+1'b1; end else begin if (cnt == 7'd74) cnt <= 7'd0; else cnt <= cnt + 1'b1; end end always @(posedge clk or negedge rst_n) begin if (!rst_n) begin red <= 1'b0; yellow <= 1'b0; green <= 1'b0; end else begin green <= (cnt<74 &&cnt >= 7'd14)? 1'b1:1'b0; yellow <= (cnt < 7'd14 && cnt >=7'd9)? 1'b1:1'b0; red <= (cnt == 7'd74||cnt < 7'd9)? ((flag == 1'b0 && cnt != 7'd2)? 1'b0:1'b1):1'b0; end end assign clock = green? (8'd75 - cnt): yellow? (8'd15 - cnt): red? (8'd10-cnt):8'd10-cnt; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`timescale 1ns/1ns module triffic_light ( input rst_n, //异位复位信号,低电平有效 input clk, //时钟信号 input pass_request, output wire[7:0]clock, output reg red, output reg yellow, output reg green ); //1.使用3个计数器,分别计数红,黄,绿 //2.使用1个计数器,根据计数值的范围分别表示红,黄,绿 //0-9 : 红色 10 //10-14: 黄色 5 //15-74 : 绿色 60 reg [6:0] count75; reg flag; always @(posedge clk or negedge rst_n) begin if(!rst_n)begin count75 <= 7'b0; flag <= 1'b0; end else begin if(pass_request)begin if(count75 <= 7'd65) count75 <= 7'd65; else count75 <= count75 + 7'b1; end else begin if(flag == 1'b0)begin if(count75 == 7'd2)begin flag <= 1'b1; count75 <= 7'b0; end else begin count75 <= count75 + 7'b1; end end else begin if(count75 == 7'd74) count75 <= 7'b0; else count75 <= count75 + 7'b1; end end end end //红黄绿 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin red <= 1'b0; yellow <= 1'b0; green <= 1'b0; end else begin if(count75>=0 && count75 < 9 || count75 == 7'd74)begin if(flag == 1'b0 && count75 != 7'd2) red <= 1'b0; else red <= 1'b1; yellow <= 1'b0; green <= 1'b0; end else if(count75 >= 9 && count75 < 14)begin red <= 1'b0; yellow <= 1'b1; green <= 1'b0; end else if(count75 >= 14 && count75 < 74)begin red <= 1'b0; yellow <= 1'b0; green <= 1'b1; end else begin red <= red; yellow <= yellow; green <= green; end end end //倒计时 reg [7:0] clock_t; always@(rst_n, pass_request, count75, flag)begin if(!rst_n)begin clock_t = 8'd10; end else begin if(count75 >= 0 && count75 <= 9)begin clock_t = 8'd10 - count75; end else if(count75 >= 10 && count75 <= 14)begin clock_t = 8'd15 - count75; end else if(count75 >= 15 && count75 <= 74)begin clock_t = 8'd75 - count75; end else begin clock_t = clock_t; end end end assign clock = clock_t; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-05
`timescale 1ns/1ns module triffic_light ( input rst_n, //异位复位信号,低电平有效 input clk, //时钟信号 input pass_request, output wire[7:0]clock, output reg red, output reg yellow, output reg green ); parameter RST=0,GREEN=1,YELLOW=2,RED=3; reg [1:0] state,nexts; reg [7:0] clockr; assign clock = clockr; always@(posedge clk or negedge rst_n) begin if(!rst_n) state <= RST; else state <= nexts; end always@(*) begin if(!rst_n) nexts = RST; else case(state) RST: nexts = (clockr==8'd8)?RED:RST; GREEN: nexts = (clockr==8'd1)?RED:GREEN; YELLOW: nexts = (clockr==8'd1)?GREEN:YELLOW; RED: nexts = (clockr==8'd1)?YELLOW:RED; default: nexts = RST; endcase end always@(posedge clk or negedge rst_n) begin if(!rst_n) clockr <= 8'd10; else if(pass_request&&state==GREEN&&clockr>8'd10) clockr <= 8'd10; else case(state) RST: clockr <= (clockr==8'd8)?8'd10:clockr-8'd1; GREEN: clockr <= (clockr==8'd1)?8'd10:clockr-8'd1; YELLOW: clockr = (clockr==8'd1)?8'd60:clockr-8'd1; RED: clockr = (clockr==8'd1)?8'd5:clockr-8'd1; default: clockr <= 8'd10; endcase end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin green <= 0; yellow <= 0; red <= 0; end else case(nexts) RST: begin green <= 0; yellow <= 0; red <= 0; end GREEN: begin green <= 1; yellow <= 0; red <= 0; end YELLOW: begin green <= 0; yellow <= 1; red <= 0; end RED: begin green <= 0; yellow <= 0; red <= 1; end default:begin green <= 0; yellow <= 0; red <= 0; end endcase end endmodule