FPGA自学教程 11 双向红绿灯

双非硕士 研一下学期视觉转FPGA

长路漫漫,但希望前途光明

设计思路:使用fpga模拟双向红绿灯,也就是模拟实际路上红绿灯每个灯的亮灭程度:比如第一个红灯亮时,第二个灯的绿灯就亮,然后接着第二个灯的绿灯转为黄灯并闪烁时,第一个红灯转为绿灯,第二个灯转为红灯,依此类推。。。。。

设计思路图如下:

 如上图所示,在0到1s时为空闲状态,在1s到4s时,是下方的绿灯和上方的红灯同时亮,在4s到5s时,下方的绿灯改为黄灯,并控制黄灯闪烁(可以更为真实的模拟红绿灯的状态),同时上方的红灯继续亮,在第5s到第8s时,上方的红灯改为绿灯,下方的黄灯改为红灯,在第8s到第9s时,上方的绿灯改为黄灯并控制黄灯闪烁,而下方的红灯保持不变。

伪代码如下:

parameter	DELAY_CNT_MAX	=	225000000 - 1;                //9秒
parameter one_times = 25000000 - 1;                         //1秒
parameter four_times = 75000000 - 1 + 25000000;            //4秒
parameter five_times = 75000000 + 25000000 + 25000000 - 1;              //5秒
parameter seven_times = 75000000 + 2500000 + 25000000 + 25000000 + 25000000 - 1;           //7秒
parameter eigtht_times = 75000000 + 25000000 + 75000000  + 25000000 - 1;           //8秒
parameter nine_times = DELAY_CNT_MAX;            //9秒
reg one_times_flag     ;
reg four_times_flag     ;
reg five_times_flag     ;
reg seven_times_flag    ;
reg eigtht_times_flag   ;
reg nine_times_flag     ;
reg [31:0]times_cnt;
always@(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        begin
            times_cnt <= 0;
        end
    else if(times_cnt == DELAY_CNT_MAX)
        times_cnt <= 0;
    else
        times_cnt <= times_cnt + 1'b1;
parameter S0 = 8'b0000_0001;
parameter S1 = 8'b0000_0010;
parameter S2 = 8'b0000_0100;
parameter S3 = 8'b0000_1000;
parameter S4 = 8'b0001_0000;
reg [7:0]state;
always@(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        begin
        one_times_flag  <= 0;
        four_times_flag  <= 0;
        five_times_flag <= 0;
        seven_times_flag <= 0;
        eigtht_times_flag <= 0; 
        nine_times_flag <= 0; 
        state <= S0;
        end
    else
    begin
        case(state)
        S0:
            begin
            one_times_flag <= 1'b1;
            if(times_cnt == one_times)
                state <= S1;
            end
        S1:
            begin
            if(times_cnt == four_times)
                begin
                    one_times_flag <= 0;
                    four_times_flag <= 1'b1;
                    state <= S2;
                end    
            end
        S2:
            begin
            if(times_cnt == five_times)
                begin
                    four_times_flag <= 0;
                    five_times_flag <= 1'b1;
                    state <= S3;
                end    
            end
        S3:
            begin
            if(times_cnt == eigtht_times)
                begin
                    five_times_flag <= 0;
                    eigtht_times_flag <= 1'b1;
                    state <= S4;
                end    
            end
        S4:
            begin
            if(times_cnt == nine_times)
                begin
                    eigtht_times_flag <= 0;
                    nine_times_flag <= 1'b1;
                    state <= S0;
                end    
            end
        default:
            begin
                one_times_flag      <=    one_times_flag   ;
                four_times_flag     <=    four_times_flag  ;
                five_times_flag     <=    five_times_flag  ;
                seven_times_flag     <=   seven_times_flag ;
                eigtht_times_flag   <=    eigtht_times_flag;
                nine_times_flag     <=    nine_times_flag  ;
            end
        endcase
reg	[2:0]	led_left;	// 3个LED的亮灭状态
reg	[2:0]	led_right;	// 3个LED的亮灭状态

always@(posedge i_clk or negedge i_rst_n)
begin
    if(!i_rst_n)
    begin
        led_left <= 0;
        led_right <= 0;
    end
    else
    begin
        if(one_times_flag)
            begin
                led_left <= 3'b100;
                led_right <= 3'b100;
            end
        else if(four_times_flag)
            begin
                led_left <= 3'b100;
                led_right <= 3'b010;
            end
        else if(five_times_flag)
            begin
                led_left <= 3'b010;
                led_right <= 3'b001;
            end
        else if(eigtht_times_flag)
            begin
                led_left <= 3'b001;
                led_right <= 3'b001;
            end
    end 
end
reg [23:0]cnt;
reg flag1;
reg flag2;
always @(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        cnt <= 0;
    else if(cnt == one_times / 6)
        cnt <= 0;
    else 
        cnt <= cnt + 1'b1;

always @(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        flag1 <= 0;
    else if(led_left[0] == 1'b1)
        begin
            if(cnt == one_times / 6)
                flag1 <= 1'b1;
            else 
                flag1 <= 0;
        end
always @(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        flag2 <= 0;
    else if(led_right[1] == 1'b1)
        begin
            if(cnt == one_times / 6)
                flag2 <= 1'b1;
            else 
                flag2 <= 0;
        end
reg led_3_temp;
always @(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        led_3_temp <= 0;
    else if(led_right[1] == 1'b1)
        begin
            if(flag2 == 1'b1)
                led_3_temp <= ~led_3_temp;
            else 
                led_3_temp <= led_3_temp ;
        end
always @(posedge i_clk )
begin
    if(led_3_temp == 1'b1)
        led1_rgb <= 48'hFFFF_8FFF_0000;
    else
        led1_rgb <= 48'b0;
end
reg led_1_temp;
always @(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n)
        led_1_temp <= 0;
    else if(led_left[0] == 1'b1)
    begin
        if(flag1 == 1'b1)
            led_1_temp <= ~led_1_temp;
        else if(flag1 == 0)
            led_1_temp <= led_1_temp;
    end
always @(posedge i_clk)
begin
    if(led_1_temp == 1'b1)
        led3_rgb <= 48'hFFFF_8FFF_0000;
    else
        led3_rgb <= 48'b0;
end      
//根据led对应位的高低电平,指定LED灯的颜色输出
assign	led0_rgb	 = (led_right[0] == 1'b1) ? 48'hFFFF_0000_0000 : 48'b0; // 输出RED颜色给LED0
//assign	led1_rgb	 = (led_right[1] == 1'b1) ? 48'hFFFF_FFFF_0000 : 48'b0; // 输出YELLOW颜色给LED1      !!!
assign	led2_rgb	 = (led_right[2] == 1'b1) ? 48'h0000_FFFF_0000 : 48'b0; // 输出GREEN颜色给LED2
//assign	led3_rgb	 = (led_left[0] == 1'b1) ? 48'hFFFF_FFFF_0000 : 48'b0; // 输出YELLOW颜色给LED3       !!!
assign	led4_rgb	 = (led_left[1] == 1'b1) ? 48'h0000_FFFF_0000 : 48'b0; // 输出GREEN颜色给LED4
assign	led5_rgb	 = (led_left[2] == 1'b1) ? 48'hFFFF_0000_0000 : 48'b0; // 输出RED颜色给LED5

显示效果如下,由于灯是会实时变化的,下面的图片是黄灯和红灯同时亮

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值