题解 | #交通灯#不看答案不知道系列(idle->red)
交通灯
https://www.nowcoder.com/practice/b5ae79ff08804b61ad61f749eaf157ba?tpId=302&tqId=5000636&ru=/exam/oj&qru=/ta/verilog-advanced/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DVerilog%25E7%25AF%2587%26topicId%3D302
`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
parameter idle = 6'b000001,s_green = 6'b000010,s_yellow = 6'b000100,s_red = 6'b001000,s0 = 6'b010000,s1=6'b100000;
reg [5:0] state_c,state_n;
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
state_c <= idle;
end
else begin
state_c <= state_n;
end
end
reg [7:0] clock_temp;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
clock_temp <= 8'd10;
end
else if(state_c == s_red && clock_temp > 8'd1)begin
clock_temp <= clock_temp - 1'b1;
end
else if(state_c == s_red && clock_temp == 8'd1)begin
clock_temp <= 8'd5;
end
else if(state_c == s_yellow && clock_temp > 8'd1)begin
clock_temp <= clock_temp - 1'b1;
end
else if(state_c == s_yellow && clock_temp == 8'd1)begin
clock_temp <= 8'd60;
end
else if(state_c == s_green && pass_request && clock_temp > 8'd10)begin
clock_temp <= 8'd10;
end
else if(state_c == s_green && clock_temp > 8'd1)begin
clock_temp <= clock_temp - 1'b1;
end
else if(state_c == s_green && clock_temp == 8'd1)begin
clock_temp <= 8'd10;
end
else begin
clock_temp <= clock_temp;
end
end
// 看答案 idle ->red 中间还要打两拍,不知道为什么
//2
always@(*)begin
case(state_c)
idle:begin
state_n = s0;
end
s0:begin
state_n = s1;
end
s1:begin
state_n = s_red;
end
s_green:begin
if(clock_temp == 8'd1)begin
state_n = s_red;
end
else begin
state_n = s_green;
end
end
s_yellow:begin
if(clock_temp == 8'd1)begin
state_n = s_green;
end
else begin
state_n = s_yellow;
end
end
s_red:begin
if(clock_temp == 8'd1)begin
state_n = s_yellow;
end
else begin
state_n = s_red;
end
end
default:state_n = idle;
endcase
end
//3
assign clock = state_c == s0?8'd9:(state_c == s1?8'd8:clock_temp);
always@(*)begin
if(state_c == s_green) green = 1'b1;else green = 1'b0;
if(state_c == s_yellow) yellow = 1'b1;else yellow = 1'b0;
if(state_c == s_red) red = 1'b1;else red = 1'b0;
end
endmodule

