先写源文件counter.v
//////////////////////////////////////////////////////////////////////////////////
// Module Name: counter
// 板子晶振为50mhz,就是50106hz,周期为20*10(-9)s,s/ms/us/ns/ps,相邻两单位前者是后者的1000倍
//所以为20ns,
//////////////////////////////////////////////////////////////////////////////////
/
本题目要求满500ms时led状态翻转,那么就是满2510^6次翻转,可以明确输出是led,输入是时钟,复位键
计数器既不属于输出也不属于输入,所以不是外部端口,所以不需要在ports_list中,接着打开计算器程序员模式
看看2510^6转为二进制是多少位以此来设置counter的范围
之所以clk算是输入我的理解是他作为外部时钟信号(应该是吧)
在这个源文件中就是设置逻辑要考虑情况有
1.rst按下以后,counter要清零,led熄灭
2.counter满了之后,led转变状态
*/
module counter(
clk,
rst,
led
);
input clk;
input rst;
output led;
reg led;
reg [24:0]counter;
parameter CNT_max = 24_999_999;//他是从0开始计数,那么到24999999就有25000000个周期
//事件控制有rst的按下,所以是下降沿,时钟满一个周期后关注其上升沿,从而对counter计数
always@(posedge clk or negedge rst)
begin
if (!rst)
begin
counter <= 25'b0;
end
else if (counter == CNT_max)
counter <= 25'b0;
else
counter <= counter + 1'b1;
end
//事件控制有rst的按下,所以是下降沿,时钟满一个周期后关注其上升沿,从而对led进行控制
always@(posedge clk or negedge rst)
begin
if (!rst)
begin
led <= 0;
end
else if (counter == CNT_max)
led <= ~led;
else
led <= led;
end
endmodule
//////////////////////////////////////////////////////////////////
再来看仿真文件counter_tb.v
`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Module Name: counter_tb
//////////////////////////////////////////////////////////////////////////////////
//仿真只是给激励信号,所以这里面不需要涉及到计数器
module counter_tb(
);
reg clk;
reg rst;
wire led;
counter cnt(
.clk(clk),
.rst(rst),
.led(led)
);
initial clk = 1;
always #10 clk = ~clk;//这里不是事件控制,只是需要一个时间,一个周期是20ns,那么正负各一半
// counter = 0;这里面都没涉及到counter所以不需要给counter设置初始值
// 重点是设置时钟周期,还是分开写吧,刚刚阻塞赋值和非阻塞赋值放在一起了
initial begin
rst <= 0;
#201;//模拟按下rst201ns,之所以加一,是为了不和时钟翻转冲突
rst <= 1;
#20000000000;//模拟松开rst
$stop;
end
endmodule
标签:led,FPGA,clk,counter,注释,计数器,rst,reg From: https://www.cnblogs.com/cccofHIT/p/18034392