小梅哥-参数化设计及模块重用设计不同频率的流水灯

文章描述了一个使用Verilog设计的方案,通过例化8个不同的led_flash_1_run模块,每个模块配置不同的计数器参数来实现从0.1ms到0.8ms的周期性闪烁。在led_flash_8模块中,每个Led的闪烁频率通过MCNT参数进行配置,避免了数据溢出问题。激励文件用于测试和仿真Led灯的闪烁行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目

8个Led灯分别以不同频率循环闪烁,led[0]0.1ms亮一次;led[1]0.2ms亮一次;led[2]0.3ms亮一次依次类推

二、思路

每个灯的亮的时间不同,但是都在原来的基础上加了0.1ms. 先在文件led_diff_1中设计一个灯,再Add sources创建一个新的设计文件led_diff_8,在这个新的设计文件中依次例化8个led模块

三、设计文件

设计文件共两个,先设计一个led灯的功能led_flash_1_run;在另外一个设计文件led_flash_8中例化8次led_flash_1_run模块

`timescale 1ns / 1ns
module led_flash_1_run(clk,reset_n,led
    );
    input clk;
    input reset_n;
    output reg led;
    reg [31:0] counter;//注意led的闪烁频率设置的较慢,要防止数据溢出,导致程序出错;
    //led灯最长时间0.8ms一次,计数器计数40000000次,d40000000=b1 0111 1101 0111 1000 0100 0000 0000;需要宽度29位;此处32位,可以正常使用
    parameter MCNT = 8'd24999999;//parameter 参数,此处参数任意,例化可以修改该参数
  
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter <=0;
    else if(counter == MCNT)    
        counter <=0;
    else 
        counter <=counter +1'b1;
        
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        led <=0;
    else if(counter == MCNT)
        led <=!led; //在always里赋值,则必须为reg型
endmodule                                                                                                                       
`timescale 1ns / 1ns
module led_flash_8(clk,reset_n,led);
    input clk;
    input reset_n;
    output [7:0]led;
    
    led_flash_1_run led_flash_8_inst0(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[0])
    );
    defparam led_flash_8_inst0.MCNT = 5000000-1;//led灯亮0.1ms一次,0.1ms=100000000ns,100000000ns/20ns= 5000000
    
     led_flash_1_run led_flash_8_inst1(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[1])
    );
     defparam led_flash_8_inst1.MCNT = 10000000-1;//led灯亮0.2ms一次,0.2ms=200000000ns,200000000ns/20ns= 10000000
     
     led_flash_1_run led_flash_8_inst2(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[2])
    );
    defparam led_flash_8_inst2.MCNT = 15000000-1;//led灯亮0.3ms一次,0.3ms=300000000ns,300000000ns/20ns= 15000000
    
     led_flash_1_run led_flash_8_inst3(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[3])
    );
    defparam led_flash_8_inst3.MCNT = 20000000-1;//led灯亮0.4ms一次,0.4ms=400000000ns,400000000ns/20ns= 20000000
    
     led_flash_1_run led_flash_8_inst4(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[4])
    );
    defparam led_flash_8_inst4.MCNT = 25000000-1;//led灯亮0.5ms一次,0.5ms=500000000ns,500000000ns/20ns= 25000000
    
     led_flash_1_run led_flash_8_inst5(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[5])
    );
    defparam led_flash_8_inst5.MCNT = 30000000-1;//led灯亮0.6ms一次,0.6ms=600000000ns,600000000ns/20ns= 30000000
    
     led_flash_1_run led_flash_8_inst6(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[6])
    );
    defparam led_flash_8_inst6.MCNT = 35000000-1;//led灯亮0.7ms一次,0.7ms=700000000ns,700000000ns/20ns= 35000000
    
    led_flash_1_run led_flash_8_inst7(
    .clk(clk),
    .reset_n(reset_n),
    .led(led[7])
    );
    defparam led_flash_8_inst7.MCNT = 40000000-1;//led灯亮0.8ms一次,0.8ms=800000000ns,800000000ns/20ns= 40000000
    
endmodule

四、激励文件

`timescale 1ns / 1ns
module led_flash_8_tb(

    );  
    reg clk;
    reg reset_n;
    wire [7:0]led;
    
    led_flash_8 led_flash_8_inst(
    .clk(clk),
    .reset_n(reset_n),
    .led(led)
    ); 
    initial clk=1;
    always #10 clk=~clk;
    
    initial begin
    reset_n=0;
    #201;
    reset_n=1;
//    #4000000000;
//    $stop;
    end
endmodule

五、仿真图

横坐标一个大刻度200ms,led[0]灯100ms亮一次;led[1]灯200ms亮一次;led[2]灯300ms亮一次;led[3]灯400ms亮一次;led[4]灯500ms亮一次;led[5]灯600ms亮一次;led[6]灯700ms亮一次;led[7]灯800ms亮一次

注意:是每隔100us led[0]都会亮 (并不是说在100us处亮了200us处该led[1]亮 led[0]就不亮了)

六、总结

1、在主模块led_flash_8中,通过调用子模块单个led闪烁功能,利用led_flash_8_inst1.MCNT 对8个led分别进行闪烁频率配置;并且要注意每一次调用子模块的函数名应当不同,要有唯一性

2、由于在主模块将led的闪烁频率设置的较慢,counter对于原来的25位数据溢出,导致程序出错,因此需要注意参数的数据位数。这里设置为32位防止溢出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值