**
实验内容(一)
**
1.手工绘制的RTL结构图:
2.Quartus生成的RTL
实验原理:
整个计数器一共有3个模块组成:
(1)第一模块为生成基准信号的cnt_sync模块,为使计数数值变化的时间间隔是1秒 ,所以定义一个常数MAX_VAL为50000000,当计数器的计数值等于这个常数时,OV溢出1,从而产生1s的时间间隔;
(2)第二模块为cnt_en_0to9带使能的计数器模块,当使能信号EN有效时,此模块开启,计数器开始从
0 1 … 6 0 1… 7 0 1 … 8 0 1 … 9 0 1 … 6 …… 开始循环计数;
(3)第三模块为dec_4to9的译码器模块,让译码器的输入端连接上一级计数器的输出端,根据8段数码管的编码原理进行编码,从而点亮LED数码管。
以下分别为不同RTL的展开图:
(1)cnt_sync生成基准信号模块
(2)cnt_en_0to9带使能的计数模块
(3)dec_4to9模块
3.SignalTap截图
4.代码片模块
/ //生成基准信号模块 module cnt_sync( CLK,//时钟,上升沿有效 RST,//异步复位,低电平有效 CNTVAL,//输出的计数值信号 OV);//计数溢出信号,计数值为最大值时该信号为1
//电路编译参数,最大计数值 parameter MAX_VAL=50_000_000;
input CLK; input RST; output [32-1:0] CNTVAL; output OV;
reg [32-1:0] CNTVAL; reg OV;
always @ (posedge CLK or negedge RST) begin if(!RST) CNTVAL <= 0; else begin if(CNTVAL >= MAX_VAL) CNTVAL <= 0; else CNTVAL <= CNTVAL +1’b1; end
end always @ (CNTVAL) begin if(CNTVAL == MAX_VAL) OV = 1’b1; else OV = 1’b0; end
endmodule
// //cnt_rst带有使能的计数器模块 module cnt_en_0to9( CLK,//时钟,上升沿有效 EN,//输入的计数使能,高有效 CNTVAL);//输出的计数值信号
input CLK; input EN; output [3:0] CNTVAL;
reg [3:0] CNTVAL; reg [3:0] MAX_CNT=6;
always @ (posedge CLK) begin if(EN) begin//使能信号开启,执行计数功能 if(CNTVAL < MAX_CNT) CNTVAL <= CNTVAL +1’b1; else begin CNTVAL <= 0;//计数到最大值,下一计数值清零 MAX_CNT <= MAX_CNT + 1’b1; if(MAX_CNT >= 9) MAX_CNT <= 6; end end else begin CNTVAL <= CNTVAL ;//当使能信号无效时,计数值保持不变 end
end endmodule
/// //译码器模块 module dec_4to9( //数码管的输出最大为0-9 IN,//译码器的输入 OUT);//译码器的输出
input [3:0] IN; output [7:0] OUT;
reg [7:0] OUT;//有8段数码管
always @ (IN) begin case(IN) 4’h0: OUT= 8’hc0; 4’h1: OUT= 8’hf9; 4’h2: OUT= 8’ha4; 4’h3: OUT= 8’hb0; 4’h4: OUT= 8’h99; 4’h5: OUT= 8’h92; 4’h6: OUT= 8’h82; 4’h7: OUT= 8’hf8; 4’h8: OUT= 8’h80; 4’h9: OUT= 8’h90; endcase
end endmodule `
**
实验内容(二)
**
1.手工绘制的RTL结构图:
2.Quartus生成的RTL
实验原理:
整个计数器一共有4个大模块组成:
(1)第一模块为生成基准信号的cnt_sync模块,为使计数数值变化的时间间隔是1秒 ,所以定义一个常数MAX_VAL为50000000,当计数器的计数值等于这个常数时,OV溢出1,从而产生1s的时间间隔;
(2)第二模块为cnt_ov带使能的计数器模块,当使能信号EN有效时,此模块开启,在此模块中定义了一个reg变量MAX,MAX的取值分别可以为6,7,8,9,当计数器的计数值CNT分别等于MAX时,OV信号分别溢出1,否则溢出0,也就是OV信号分别每隔6s、7s、8s分别溢出。
(3)第三模块为dec_4to9的译码器模块,由于在这一模块中在一个EN使能信号中会出现多个时钟脉冲,为了保证译码器在多个时钟脉冲下只使能一次,因此我加了一个首先用于锁存EN信号的D触发器,从而让它延迟一个时钟周期,然后对D触发器的输出端信号取反再与EN取与作为整个译码器的使能信号,然后让译码器的输出端作为分别开启下一级译码器的使能端,对下一级译码器起到选通使能的作用。
(4)第四大模块由4个普通的译码器组成,根据不同的使能信号有效,4个译码器分别被开启,然后根据8段数码管的编码原理进行编码,从而点亮LED数码管。
以下分别为不同RTL的展开图:
(1)cnt_sync生成基准信号模块
(2)cnt_ov带使能的计数模块
(3)dec_2to4带使能的译码器模块
(4)dec_0to9带使能的译码器模块
3.SignalTap截图
4.代码片
module cnt_sync(
CLK,//时钟,上升沿有效
CNTVAL,//输出的计数值信号
OV);//计数溢出信号,计数值为最大值时该信号为
1
//电路编译参数,最大计数值
parameter MAX_VAL=
50_000_000;
input CLK;
output [
32-
1:
0] CNTVAL;
output OV;
reg [
32-
1:
0] CNTVAL;
reg OV;
always @ (posedge CLK )//在CLK时钟的上升沿执行always模块里的操作
begin
if(CNTVAL >= MAX_VAL)
CNTVAL <=
0;
else
CNTVAL <= CNTVAL +
1'b1;
end
always @ (CNTVAL)
begin
if(CNTVAL == MAX_VAL)//当计数值等于最大计数值时,OV溢出,从而达到计数数值变化的时间间隔是
1秒
OV =
1'b1;
else
OV =
1'b0;
end
endmodule
//
//cnt_ov计数器模块,在此模块中实现循环计数
module cnt_ov(
CLK,//时钟,上升沿有效
EN,//使能信号,高有效
RST,//异步复位,低电平有效
CNT,//输出的计数值信号
OV); //计数溢出信号,计数值为最大值时该信号为
1
input CLK;
input EN;
input RST;
output [
4-
1:
0] CNT;
output OV;
reg [
4-
1:
0] CNT;
reg OV;
reg [
4-
1:
0] MAX=
6;
always @ (posedge CLK
or posedge RST) //在CLK时钟的上升沿或RST的下降沿执行always模块里的操作
begin
if(RST)
begin
CNT <=
0;
end
else begin
if(EN)
begin
if(CNT < MAX)
CNT <= CNT +
1'b1;
else begin
CNT <=
0;
if (MAX <
9)
MAX <= MAX +
1'b1;
else
MAX <=
6;
end
end
else
CNT <= CNT;
end
end
always @ (CNT
or RST)
begin
if(RST)
OV =
0;//当复位时,OV不溢出,即后面的模块不能正常工作
else begin
if(CNT ==
0)//当CNT=
0时OV溢出,即刚开始dec_2to4得EN使能信号就有效,此时开启第二个译码器,即从第二个数码管开始亮
OV =
1'b1;
else
OV =
1'b0;
end
end
endmodule
//
//dec_2to4选通使能端译码器,用于选通下一级的译码器
module dec_2to4(
CLK,//时钟,上升沿有效
EN,//使能信号,高有效
RST,
OUT);//译码器输出值
input CLK;
input EN;
input RST;
output [
3:
0]
OUT ;
reg [
3:
0]
OUT ;
reg [
3:
0] CNTVAL;
reg OUT_R;//定义一个D触发器
always @(posedge CLK
or posedge RST)//在CLK时钟的上升沿或RST的下降沿执行always模块里的操作
begin
if(RST)
CNTVAL <=
0;
else begin
OUT_R <= EN;//将EN使能信号锁存到D触发器中,实现一个CLK时钟的延迟
if(EN&~OUT_R)
begin //将EN信号与D锁存器输出端取反的信号相与,实现单周期使能
if (CNTVAL <
3)
CNTVAL <= CNTVAL +
1'b1;
else
CNTVAL <=
0;
end
else
CNTVAL <= CNTVAL;
end
end
always @ (CNTVAL
or RST)
begin
if(RST)
OUT =
4'b 0000;//当复位时,后面的译码器中的EN使能信号无效,数码管都不会亮
else begin
case(CNTVAL)
2'b00:
OUT =
4'b 1000;
2'b01:
OUT =
4'b 0001;//因为刚开始OV会直接溢出,导致译码器计数值为
1即
01,故本来会开启第二个数码管,但为了让其从第一个亮,所以接输出
0001,让第一个数码管亮
2'b10:
OUT =
4'b 0010;
2'b11:
OUT =
4'b 0100;
endcase
end
end
endmodule
//dec_0to9显示输出数据译码器模块
module dec_0to9( //数码管从
0到
15依次输出
IN,//译码器的输入信号
RST,
EN,//使能信号,高有效
OUT);//译码器输出值
input EN;
input RST;
input [
3:
0]
IN;
output [
7:
0]
OUT;
reg [
7:
0]
OUT;//有
8段数码管
always @ (RST
or IN)
begin
if(EN)
begin
case(
IN)//当使能信号有效时,数码管显示
4'h0:
OUT=
8'hc0;//
4bit才能保证从
0-
16
4'h1:
OUT=
8'hf9;
4'h2:
OUT=
8'ha4;
4'h3:
OUT=
8'hb0;
4'h4:
OUT=
8'h99;
4'h5:
OUT=
8'h92;
4'h6:
OUT=
8'h82;
4'h7:
OUT=
8'hf8;
4'h8:
OUT=
8'h80;
4'h9:
OUT=
8'h90;
endcase
end
else
OUT=
8'hff;//当使能信号无效时,数码管熄灭
end
endmodule
转载请注明原文地址: https://ju.6miu.com/read-971190.html