实验内容1
内容1视频:计数器单数码管显示
人工RTL图
顶层设计
- 时间基准模块的OV产生以1s为周期的脉冲信号;
- 带使能的多周期计数器进行循环计数,并以时间基准模块的OV作为使能端;
- 4-7译码器用于译码使在数码管上显示对应字符。
时间基准模块
- 在CLK的上升沿,判断计数值CNTVAL是否小于计数循环最大值MAX_VAL,若是,则输出CNTVAL+1,否则输出循环初值0。
- 当计数到最大值时,OV溢出为1,代表一个周期。
带使能的多周期计数器
- 同步高电平复位,在CLK上升沿,且RST高电平复位,给输出CNT、循环最大值CNT_VAL分别赋初值0、6。
- RST低电平且使能有效时,判断输出CNT是否小于循环最大值CNT_VAL,若是,则输出CNT+1,否则输出CNT为0,并判断循环最大值CNT_VAL是否小于9,若是,则CNT_VAL++,否则CNT_VAL赋6。
- 使能为0时,保持输出值CNT。
数码管4-8译码器_无小数点
- 数码管为共阳极,即输出为低电压时,相应字码段点亮,反之熄灭。根据下图可得到译码字段即可,RTL根据译码字段通过或门可以画出来,略过。
Quartus生成的RTL图
- 顶层设计
- 时间基准模块
- 带使能的多周期计数器
- 数码管4-8译码器_无小数点
SignalTap分析
- 计数器的计数值的SignalTap截图,使用Segment 模式,捕获一个完整的计数循环过程中所有的计数值。
- 以时间基准模块的OV为触发信号,2k的采样深度,设置segmented为64段32点进行采样,结果如下:
代码片
- 时间基准模块
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
parameter CNTVAL_WL = 32;
parameter MAX_VAL = 50_000_000;//周期:50_000_000*0.02us=1s
input CLK;
output [CNTVAL_WL-1:0] CNTVAL;
output OV;
reg [CNTVAL_WL-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL < MAX_VAL)
CNTVAL <= CNTVAL + 1'b1;
else
CNTVAL <= 0;
end
always @ (CNTVAL) begin //计数到最大值时,OV溢出
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_sync
- 带使能的多周期计数模块
module cnt_en_circle_0tomax6_9(
CLK , // clock
EN , //enable
RST , //reset
CNT , //output
OV );
input CLK , RST , EN ;
output OV ;
output [4-1:0] CNT;//output counter value
parameter CNT_VAL_MIN=6; //counter cycle min value
parameter CNT_VAL_MAX=9; //counter cycle max value
reg [4-1:0] CNT;
reg [4-1:0] CNT_VAL=CNT_VAL_MIN;
reg OV;
//同步高电平复位
always @ (posedge CLK) begin
if(RST)begin //reset
CNT <= 0;
CNT_VAL <= CNT_VAL_MIN;
end
else begin
if(EN)begin //enable
if(CNT < CNT_VAL)
CNT <= CNT + 1'b1;
else begin
CNT <= 0;
if(CNT_VAL < CNT_VAL_MAX) //判断计数值是否到达最大的循环值
CNT_VAL <= CNT_VAL + 1'b1;
else
CNT_VAL <= CNT_VAL_MIN;
end
end
else CNT <= CNT ;