FPGA学习日志——计数器counter

计数器counter

实验目标:每个时钟周期加一,在实验中采用50Mhz的时钟,即一秒钟计数50M-1个/或0.5s计数25M-1个。同时利用LED小灯在0.5s熄灭,后0.5s点亮。

实验框图与波形图:
FPGA学习日志——计数器counter_第1张图片

实验代码

module  counter
#(
    parameter   CNT_MAX=25'd24_999_999
)
(
    input   wire   sys_clk,
    input   wire   sys_rst_n,
    output  reg    led_out
);
reg     [24:0] cnt;
    
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt<=25'd0;
    else if(cnt==CNT_MAX)
            cnt<=25'd0;
        else 
            cnt<=cnt+25'd1;
            
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        led_out <= 1'b0;
    else    if(cnt==CNT_MAX)
            led_out <= ~led_out;
            else
            led_out <= led_out;
endmodule

参数设定的两种方式

将某些参数统一以提前声明的方式进行定义,即用parameter来定义一个标识符来代表一个常量,称为符号常量,即标识符形式的常量,采用标识符代表一个常量可以提高程序的可读性和可维护性。另一个很有用的用途就是可以利用defparam或者在模块实例化的时候进行参数传递(即重写)

//方法一
parameter   CNT_MAX=25'd24_999_999;
//方法二
#(
    parameter   CNT_MAX=25'd24_999_999,
)//这种写法可以在实例化中参数传递的一个接口 */

对应两种方法在实例化中的修改

//方法一
defparam    counter_inst.CNT_MAX = 25'd1000;
//方法二
counter 
 #(
     .CNT_MAX(1000)//在实例化中按照一个接口进行赋值   
)
counter_inst//同时这里实例化名称位置有所不同
(
   .sys_clk(sys_clk),
   .sys_rst_n(sys_rst_n),   
   . led_out( led_out)
);

同时值得注意是的,例如设定了1000,此处1000仅作为减少仿真时间,与设定的上板时间定义的24_999_999没关系,。

仿真代码

`timescale 1ns/1ns
module tb_counter();
reg     sys_clk;
reg     sys_rst_n;

wire    led_out;

initial
    begin
        sys_clk=1'b1;
        sys_rst_n <=1'b0;
        #20
        sys_rst_n<=1'b1;
    end
always #10  sys_clk=~sys_clk;
initial
    begin
    $timeformat(-9,0,"ns",6);
    $monitor("@time %t:led_out=%b",$time,led_out);
    end
counter 
 #(
    .CNT_MAX(25'd24)
)
counter_inst
(
   .sys_clk(sys_clk),
   .sys_rst_n(sys_rst_n),
   
   . led_out( led_out)
);
endmodule

timescale的使用

timescale是Verilog HDL 中的一种时间尺度预编译指令,它用来定义模块的仿真 时的时间单位和时间精度。格式如下:

`timescale 仿真时间单位/时间精度

注意:用于说明仿真时间单位和时间精度的 数字只能是1、10、100,不能为其它的数字。而且,时间精度不能比时间单位还要大。最多两则一样大。比如:下面定义都是对的:

`timescale 1ns/1ps

`timescale 100ns/100ns

下面的定义是错的:

`timescale 1ps/1ns
在verilog中是没有默认timescale的,一个没有指定timescale的verilog模块就有可能错误的继承了前面编译模块的无效timescale参数。

你可能感兴趣的:(FPGA学习日志,fpga开发,学习)