dyj6pdehen 2024-03-21 16:36 采纳率: 78.9%
浏览 27

verilog流水灯代码求检查

任务要求流水灯:驱动板上LED1 ~LED8按如下2个模式循环闪烁:
① 每个灯亮1s灭1s,从右至左依次闪烁,共8次
② 每个灯亮1s灭0.5s,从左至右间隔闪烁,共4次
求朋友们检查一下下面代码还有没有什么大的缺陷

`timescale 1ns / 1ns

module ledflow(
    input               sys_clk  ,  //系统时钟
    input               sys_rst_n,  //系统复位,低电平有效
    output  reg  [7:0]  led         //8个LED灯
    );

//reg define
reg [31:0] counter1, counter2;
reg [31:0] cnt;
reg led_control;
reg [7:0] led1,led2;
//*****************************************************
//**                    main code
//***************************************************** 
                                                                                                                                                                                                                         
//计数器counter1对系统时钟计数,计时2秒,对应状态1,1s左移1s灭
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        counter1 <= 32'd0;
    else if(!led_control)//led_control==0为状态1
            if (counter1 < 32'd200_000_000)//系统时钟100M,计数器计200M次即2s
                counter1 <= counter1 + 1'b1;
            else
                counter1 <= 32'd0;
        else
            counter1 <= 32'd0; //状态2时,counter1置零不计数
end
//计数器counter2计数1.5秒,对应状态2,1s右移0.5s灭
always @ (posedge sys_clk or negedge sys_rst_n) begin
// begin your code here
    if (!sys_rst_n)
        counter2 <= 32'd0;
    else if(led_control) begin // led_control==1为状态2
            if (counter2 < 32'd150_000_000) // 系统时钟100M,计数器计150M次即1.5s
                counter2 <= counter2 + 1'b1;
            else
                counter2 <= 32'd0;
        end
        else
            counter2 <= 32'd0; // 状态1时,counter2置零不计数
// end your code here
end 

//一轮用时:状态1每个灯用时2s,亮一轮8个灯即16s+状态2每个灯用时1.5s,间隔亮两轮4个灯即6s=22秒
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        cnt<=32'd0;
    else if(cnt<32'd2200_000_000)
        cnt<=cnt+1;
    else
        cnt<=0;
end 

always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        led_control <= 0;
    // begin your code here
    else begin
        if (cnt >= 16 * 110_000_000) // 1-16s为状态1,即led_control=0
            led_control <= 1; // 16s后进入状态2
        if (cnt >= 22 * 110_000_000) // 17-22s为状态2,即led_control=1
            led_control <= 0; // 22s后重新进入状态1
    end
    // end your code here

end

//移位寄存器led1,2s左移1次
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)
        led1<=8'b00000001;
    else if (!led_control) begin
            if (counter1 == 32'd200_000_000) 
                led1 <= {led1[6:0], 1'b0};  //左移1位
            else 
                led1 <= led1;
        end
        else led1 <= {led2[7], led2[7:1]};//状态2时led1就在led2基础上左移,状态转换时即可无缝衔接
end

//移位寄存器led2,1.5s右移2位
always @(posedge sys_clk or negedge sys_rst_n) begin
// begin your code here
   if(!sys_rst_n)
        led2 <= 8'b10000000;
    else if (led_control) begin // 状态2时向右移动
        if (counter2 == 32'd150_000_000)
            led2 <= led2 >> 2; // 右移2位
        else
            led2 <= led2;
    end
    else
        led2 <= led2; // 状态1时led2保持不变
// end your code here
end
        
//根据led_control给输出LED赋值
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n)
        led <= 8'b00000001;
    else case (led_control)
             0   : begin // 进入状态1时
                    if (cnt >= 32'd0 && cnt < 16 * 110_000_000) // 1-16s为状态1,每个灯用时2s
                        led <= led1;
                    else if (cnt >= 16 * 110_000_000 && cnt < 22 * 110_000_000) // 17-22s为状态2,每个灯用时1.5s
                        led <= led2;
                end
            1   : begin // 进入状态2时
                    if (cnt >= 16 * 110_000_000 && cnt < 22 * 110_000_000) // 17-22s为状态2,每个灯用时1.5s
                        led <= led2;
                    else if (cnt >= 22 * 110_000_000 && cnt < 38 * 110_000_000) // 间隔亮两轮4个灯即6s
                        led <= led1;
                end
            default  : led <= led;
        endcase
end

endmodule


  • 写回答

1条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-03-21 16:37
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    1. 代码中的缺陷:
    • 在 always@posedge sys_clk or negedge sys_rst_n 部分,未对 rst_n 取反
    • 在 always@posedge sys_clk or negedge sys_rst_n 部分,应采用异步复位而不是同步复位,即使用 if (sys_rst_n == 1'b0) 而不是 if (!sys_rst_n)
    • 代码案例:
    `timescale 1ns / 1ns
    module ledflow(
      input               sys_clk,      // 系统时钟
      input               sys_rst_n,   // 系统复位,低电平有效
      output reg  [7:0]   led          // 8个LED灯
    );
    // 计数器
    reg [31:0] counter1, counter2;
    reg [31:0] cnt;
    reg led_control;
    reg [7:0] led1, led2;
    // 计时器1,对应状态1,每个灯亮1s灭1s,从右至左依次闪烁,共8次
    always @(posedge sys_clk or negedge sys_rst_n) begin
      if (!sys_rst_n) begin
        counter1 <= 32'd0;
      end else if (!led_control) begin
        if (counter1 < 32'd200_000_000) begin // 系统时钟100M,计数器计200M次即2s
          counter1 <= counter1 + 1'b1;
        end else begin
          counter1 <= 32'd0;
        end
      end else begin
        counter1 <= 32'd0; // 状态2时,计数器counter1置零不计数
      end
    end
    // 计时器2,对应状态2,每个灯亮1s灭0.5s,从左至右间隔闪烁,共4次
    always @(posedge sys_clk or negedge sys_rst_n) begin
      if (!sys_rst_n) begin
        counter2 <= 32'd0;
      end else if (led_control) begin
        if (counter2 < 32'd150_000_000) begin // 系统时钟100M,计数器计150M次即1.5s
          counter2 <= counter2 + 1'b1;
        end else begin
          counter2 <= 32'd0;
        end
      end else begin
        counter2 <= 32'd0; // 状态1时,计数器counter2置零不计数
      end
    end
    // 状态控制器
    always @(posedge sys_clk or negedge sys_rst_n) begin
      if (!sys_rst_n) begin
        led_control <= 1'b0;
      end else begin
        if (cnt >= 16 * 110_000_000 && cnt < 22 * 110_000_000) begin
          led_control <= 1'b1; // 16s后进入状态2
        end else if (cnt >= 22 * 110_000_000) begin
          led_control <= 1'b0; // 22s后重新进入状态1
        end
      end
    end
    // LED闪烁
    always @(posedge sys_clk or negedge sys_rst_n) begin
      if(!sys_rst_n) begin
        cnt <= 32'd0;
      end else begin
        if (cnt >= 22 * 110_000_000) begin
          cnt <= 32'd0;
        end else begin
          cnt <= cnt + 1;
        end
      end
      if (!sys_rst_n) begin
        led <= 8'b00000000;
      end else begin
        if (!led_control) begin // 状态1:每个灯亮1s灭1s,从右至左依次闪烁,共8次
          case(counter1)
            32'd0:   led <= 8'b10000000; // 第1次亮灯
            32'd50_000_000: led <= 8'b01000000; // 第2次亮灯
            32'd100_000_000: led <= 8'b00100000; // 第3次亮灯
            32'd150_000_000: led <= 8'b00010000; // 第4次亮灯
            32'd200_000_000: led <= 8'b00001000; // 第5次亮灯
            32'd250_000_000: led <= 8'b00000100; // 第6次亮灯
            32'd300_000_000: led <= 8'b00000010; // 第7次亮灯
            32'd350_000_000: led <= 8'b00000001; // 第8次亮灯
            default: led <= led;
          endcase
        end else begin // 状态2:每个灯亮1s灭0.5s,从左至右间隔闪烁,共4次
          led1 = {led2[7], led2[7:1]};
          led2 = {1'b0, led1[7:2]};
          led = led2;
        end
      end
    end
    endmodule
    
    评论

报告相同问题?

问题事件

  • 创建了问题 3月21日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见