前言
当cnt为49_999_999位时,转换为二进制26位宽。
当cnt为29_999_999位时,转换为二进制25位宽,后续都采用第二种。
一、代码
1.rtl代码
代码如下(示例):
module counter
#(
parameter CNT_MAX =25'd24_999_999//不仅可以写在模块内部,还可以写在模块名称之后
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg led_out
);
/* parameter CNT_MAX =25'd24_999_999;//不仅可以写在模块内部,还可以写在模块名称之后
localparam CNT_MAX =25'd24_999_999;//只能写在模块内部 */
reg [24:0] cnt;
//用always赋值,故用reg型
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
1.测试代码
代码如下(示例):
`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
二、RTL Viewer
RTL Viewer与rtl代码保持一致。