以秒为单位的计数器

 学习的文章:https://mp.weixin.qq.com/s/hfrnaK4QJRN7JE_Eieuu7Q

仅作个人学习记录,侵权即删。

原理:

具体要求:以clk为基准,设计一个秒计数器,在指定的计数值产生中断,实时输出当前的秒数计数值。已知clk的频率32.768kHz,rst_n低电平有效,收到start后,秒计数器sec_cnt从零开始以秒为单位来计数,计数到alarm[7:0]指定的数值后,产生一个脉冲int,然后秒数计数器回零并停止。

解决:意思是通过clk分频一个周期为1s的时钟,拿这个时钟来检测alarm的数值,比如alarm是3,那么就是有3秒。

clk=32768Hz=215Hz,那么1s就需要计数(1/(1/clk))=215次。

还有一个这里的计数到32768,就意味着从0计数到32767,那么就是15'b111_1111_1111_1111,如果计数到这个值就会占用很多资源,所以改成了&cnt_1s==1'b1。


 代码:

综合代码:

module sec_cnt
#(
parameter cnt_1s_width=4'd14
)
(
input clk,
input rst_n,
input start,
input [7:0]alarm,
output reg int,
output reg [31:0]sec_cnt   //计数计算到第sec_cnt个1s
);
reg cnt_en;               //将start寄存到一个寄存器,这样可以控制它的状态
reg [cnt_1s_0]cnt_1s;    //计数到1s所用的时间

always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt_en<=1'b0;
else if(start)
cnt_en<=1'b1;
else if(sec_cnt==alarm && &cnt_1s==1'b1)
cnt_en<=1'b0;

always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt_1s<=15'd0;
else if(cnt_en)
cnt_1s<=cnt_1s+1'b1;
else
cnt_1s<=15'd0;

always @(posedge clk or negedge rst_n)
if(!rst_n)
sec_cnt<=32'd0;
else if(sec_cnt==alarm && &cnt_1s==1'b1)   //这两个不能换过来
sec_cnt<=32'd0;
else if(&cnt_1s==1'b1 && cnt_en==1'b1)     //这两个不能换过来
sec_cnt<=sec_cnt+1'b1;

always @(posedge clk or negedge rst_n)
if(!rst_n)
int<=1'b0;
else if(sec_cnt==alarm && &cnt_1s==1'b1)
int<=1'b1;
else
int<=1'b0;
endmodule 

仿真代码:仿真这里按照着原理,把宽度parameter从14换成2,省略了很多计数,只是数值计算就变成了7,所以&cnt_1s==1'b1就是cnt_1s==3'b111。

`timescale 1ns/1ns
module sec_cnt_tb;
reg clk;
reg rst_n;
reg start;
reg [7:0]alarm;
wire int;
wire [31:0]sec_cnt;
initial begin
clk<=1'b1;
rst_n<=1'b0;
start<=1'b0;
alarm<=8'd0;
#10 rst_n<=1'b1;
end
always #10 clk<=~clk;

initial begin
#40
start<=1'b1;
alarm<=8'd3;
#20 
start<=1'b0;
#1000
start<=1'b1;
alarm<=8'd4;
#20
start<=1'b0;
end

sec_cnt 
#(
.cnt_1s_width(4'd2)  //这里就是把宽度parameter值由15变成2,所以计数&cnt_1s==1'b1就是3'b111
)
u_sec_cnt(
.clk (clk),
.rst_n (rst_n),
.start (start),
.alarm (alarm),
.int (int),
.sec_cnt (sec_cnt)
);
endmodule

仿真效果:

部分放大一点:

原文地址:https://www.cnblogs.com/FPGAer/p/13828325.html