推荐答案
测试一下
题目
请用Verilog RTL描述如下图设计:以clk为基准,设计一个秒计数器,在指定的计数值产生中断,实时输出当前的秒数计数值。
参考答案与知识点
参考答案
本设计需要将32.768KHz时钟分频得到1Hz的秒时钟,再根据秒时钟进行计数。采用异步复位(低有效)和同步启动信号。设计包含以下模块:分频计数器(div_cnt)产生秒时钟使能(sec_en),秒计数器(sec_cnt)在sec_en有效时递增,状态机控制启动、计数和停止。关键代码片段如下:
// 分频器:32768分频
reg [14:0] div_cnt;
wire sec_en = (div_cnt == 32767);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) div_cnt <= 0;
else if (state == COUNT && sec_en) div_cnt <= 0;
else if (state == COUNT) div_cnt <= div_cnt + 1;
else div_cnt <= 0;
end
// 状态机:IDLE, COUNT, DONE
always @(posedge clk or negedge rst_n) begin
if (!rst_n) state <= IDLE;
else case (state)
IDLE: if (start) state <= COUNT;
COUNT: if (sec_en && sec_cnt == alarm) state <= DONE;
DONE: state <= IDLE;
default: state <= IDLE;
endcase
end
// 秒计数器
always @(posedge clk or negedge rst_n) begin
if (!rst_n) sec_cnt <= 0;
else if (state == COUNT && sec_en) begin
if (sec_cnt == alarm) sec_cnt <= 0;
else sec_cnt <= sec_cnt + 1;
end
else if (state == IDLE && start) sec_cnt <= 0;
end
// 中断脉冲
assign int = (state == COUNT && sec_en && sec_cnt == alarm) ? 1 : 0;
注意:分频器在非COUNT状态下清零以节省功耗,秒计数器在到达alarm后清零并停止。start信号仅在IDLE状态有效,忽略COUNT期间的start。int脉冲宽度为一个clk周期。复位时所有寄存器清零。
涉及知识点
- 异步复位设计
- 时钟分频器实现
- 有限状态机控制
- 秒计数器溢出及中断
- 同步信号处理