题解主体

    首先设置一个倒计时的计数器,每个时钟计数器输出减一,当计数器计数到0时,切换切换显示灯颜色,同时重置计数器为相应颜色的持续时间。
每个颜色的指示灯都会持续一段时间,可以取指示灯信号变化的上升沿作为状态转移的触发条件。上升沿的获取可以通过缓存一个时刻的数值,当当前时刻为1,前一时刻为0时,表示上升沿出现。
    reg p_red,p_yellow,p_green;        //用于缓存信号灯的前一时刻的数值,判断上升沿
always @(posedge clk, negedge rst_n) 
    begin
        if(!rst_n)
            begin
                p_yellow <= 1'd0;
                p_red <= 1'd0;
                p_green <= 1'd0;
            end
        else 
            begin
                p_yellow <= yellow;
                p_red <= red;
                p_green <= green;
            end    
按照上文提到的倒计时的取值逻辑,首先判断当前是否是绿灯,绿灯倒计时是否大于10,行人按钮是否被按下,如果这三个条件同时满足,则把倒计时置为10。
然后根据指示灯的颜色确定倒计时的数值:当红灯上升沿到达时,说明切换到红灯状态,倒计时置为10,当绿灯上升沿到达时,倒计时置为60,当黄灯上升沿到达时,倒计时置为3。
其余情况下,倒计时每个时钟减一。
always @(posedge clk, negedge rst_n) 
    begin
        if(!rst_n)
        begin
            cnt <= 7'd0;
        end
        else if (pass_request&&green&&(cnt>10))
            cnt <= 7'd10;
        else if (!green&&p_red)
            cnt <= 7'd60;
        else if (!yellow&&p_yellow)
            cnt <= 7'd3;
        else if (!red&&p_red)
            cnt <= 7'd10;    
        else cnt <= cnt -1;
 assign clock = cnt;
三个颜色的指示灯之间的转化可以使用一个简单的状态机实现。在红灯状态下,红灯亮,其余两个灯灭。而且当cnt==0,即倒计时结束时切换到黄灯,否则停留在红灯状态。在黄灯灯状态下,黄灯亮,其余两个灯灭。而且当cnt==0,即倒计时结束时切换到绿灯,否则停留在黄灯状态。在绿灯状态下,绿灯亮,其余两个灯灭。而且当cnt==0,即倒计时结束时切换到红灯,否则停留在绿灯状态。
有一点需要特别注意:考虑取信号上升沿和重置计数器数值所需要的时间,倒计时和信号灯颜色有3个时钟的错位。使用在cnt==3时,而不是cnt==0时,完成状态切换。同时将指示灯延迟一个时钟输出可以实现信号灯颜色和倒计时的对应。
    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

参考答案

`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