列表

详情


VL57. 交通灯

描述

要求实现一个交通红绿灯,具有红黄绿三个小指示灯和一个行人按钮,正常情况下,机动车道指示灯按照60时钟周期绿灯,5个时钟周期黄灯,10个时钟周期红灯循环。当行人按钮按下,如果剩余绿灯时间大于10个时钟,则缩短为10个时钟,小于10个时钟则保持不变。

注:机动车道的指示灯和人行道指示灯应该是配对的,当机动车道的灯为绿或者黄时,人行道的灯为红;当机动车道的灯为红时,人行道的灯为绿,为简便起见,只考虑机动车道的指示灯。

模块的信号接口图如下:

      

请使用VerilogHDL语言实现,并编写testbench验证功能。

输入描述

clk:系统时钟信号
rst_n:复位信号,低电平有效
pass_request:行人按钮信号,当该信号为1,表示按钮按下,如果剩余绿灯时间大于10个时钟,则缩短为10个时钟,小于10个时钟则保持不变。

输出描述

clock:交通灯倒计时读数
red:该信号为1,表示红灯亮,为0表示红灯不亮
yellow:该信号为1,表示黄灯亮,为0表示黄灯不亮
green:该信号为1,表示黄灯亮,为0表示黄灯不亮

原站题解

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

上一题