当前位置:   article > 正文

小梅哥Xilinx FPGA学习笔记6——参数化设计及模块重用设计流水灯(跑马灯)_设计快速重用及参数化设计

设计快速重用及参数化设计

〇、功能介绍

1.功能描述

8个Led灯以0.5s的的速率循环闪烁,参数化设计并且调用三八译码器模块完成该设计。
三八译码器模块见https://blog.csdn.net/weixin_42454243/article/details/122039239 《小梅哥Xilinx FPGA学习笔记2——三八译码器》

一、代码编写

1.设计文件

设计文件共两个,一个pipeline_led.v文件;一个decoder_3_8.v文件

module pipeline_led(clk,reset_n,led

    );
    input clk;
    input reset_n;
    output  [7:0] led;
   reg [24:0] counter;
   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;
        
   reg [2:0] counter2;//用3种状态控制8个led灯
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter2 <=0;
    else if(counter == MCNT)
        counter2 <=counter2 +1'b1;  //当counter2 ==7 时,自动溢出变成0

//调用其他的子模块
    decoder_3_8 decoder_3_8_inst0(
    .a(counter2[2]),//是因为decoder_3_8子模块中的位拼接,a是高位,c是最低位
    .b(counter2[1]),
    .c(counter2[0]),
    .out(led)//使用调用模块的功能,对于在该设计文件输出则不需要定义reg型,是因为在子模块中已经对out进行了reg定义,out在此模块中是隐藏的wire。
    );                                                                                                                
                                                                                                    
endmodule                                                                                                                                                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
   module decoder_3_8(a,b,c,out);
    input a;
    input b;
    input c;
    output [7:0] out;
    reg [7:0] out;
    //output reg [7:0] out

//以always块描述的信号 赋值,被赋值的对象必须要定义成reg类型
always@(a,b,c)begin //相当于always@(*)
        case({a,b,c})//位拼接,{a,b,c}三位信号
            3'b000:out = 8'b0000_0001;
            3'b001:out = 8'b0000_0010;
            3'b010:out = 8'b0000_0100;
            3'b011:out = 8'b0000_1000;
            3'b100:out = 8'b0001_0000;
            3'b101:out = 8'b0010_0000;//3'd5 :out = 8'b0010_0000
            3'b110:out = 8'b0100_0000;
            3'b111:out = 8'b1000_0000;           
        endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.激励文件

下面两个激励文件二选一

`timescale 1ns / 1ns

module pipeline_led_tb(    );
    reg clk;
    reg reset_n;
    wire [7:0]led;
    
    pipeline_led pipeline_led(
    .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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
module pipeline_led_tb(    );
    reg clk;
    reg reset_n;
    wire [7:0]led;
    defparam pipeline_led_inst0.MCNT=2499;//与设计文件中的参数无关parameter MCNT = 8'd24999999;,这里仿真的值为MCNT=2499;
    pipeline_led pipeline_led_inst0(
    .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   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3.仿真图

1.仿真图counter的参数设计是24999,横坐标一个大刻度20us,led灯0.5ms亮一次

   parameter MCNT = 8'd24999;//parameter 参数,仿真文件选择第一个文件
  • 1

在这里插入图片描述

2.在testbench中使用defparam,仿真图counter的参数设计是2499,横坐标一个大刻度100us,led灯50us亮一次
在这里插入图片描述
3…在testbench中使用defparam,仿真图counter的参数设计是249,横坐标一个大刻度20us,led灯5us亮一次
在这里插入图片描述

二、总结

1.对于在验证功能的时候,缩短时间要对所有包含的语句均进行改写,采用参数化设计,定义一个MCNT参数,可以将其用在程序的所有位置,只需要对一处就行修改,程序所有对应位置值都能得到修改;

//为缩短时间,将下面第一条语句改为第二条语句,模块中的counter==8'd24999999均需要改为counter==8'd24999
//    else if(counter==25000000-1)                                                                                                                           
    else if(counter==8'd24999)    //缩小仿真时间,验证功能 
  • 1
  • 2
  • 3
   parameter MCNT = 8'd24999;//parameter 参数
  • 1

2.对于缩短仿真时间,可以不改变设计文件,在testbench中使用defparam;或者用#例化参数MCNT。

 defparam pipeline_led_inst0.MCNT=2499;//注意例化的标签名要有唯一性
    pipeline_led pipeline_led_inst0(
    .clk(clk),
    .reset_n(reset_n),
    .led(led)
    );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  //    defparam pipeline_led_inst0.MCNT=24999;
    pipeline_led
    #(
    .MCNT(249)
    )
    pipeline_led_inst0(
    .clk(clk),
    .reset_n(reset_n),
    .led(led)
    );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.上诉第2条,defparam和#例化参数也可以用在设计文件引用其他子模块中。

//对于decoder_3_8模块进行参数化设计
module decoder_3_8(a,b,c,out);
    input a;
    input b;
    input c;
    parameter WIDTH = 15//parameter 参数,该处参数可以任意设计,因为调用的时候,我们可以修改
    output [WIDTH:0] out;
    reg [WIDTH:0] out;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
//在pipeline_led模块中调用decoder_3_8模块,方法一:
 	defparam decoder_3_8_inst0.WIDTH=7;//注意例化的标签名要有唯一性
    decoder_3_8 decoder_3_8_inst0(
    .a(counter2[2]),
    .b(counter2[1]),
    .c(counter2[0]),
    .out(led)
    );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
//在pipeline_led模块中调用decoder_3_8模块,方法二:
// 	defparam decoder_3_8_inst0.WIDTH=7;//注意例化的标签名要有唯一性
    decoder_3_8 
    #(
    .WIDTH(7)
    )
    decoder_3_8_inst0(
    .a(counter2[2]),
    .b(counter2[1]),
    .c(counter2[0]),
    .out(led)
    );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

后记:把未知当做好奇,而非恐惧。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/699713
推荐阅读
相关标签
  

闽ICP备14008679号