2.计数器-点亮数码管

    xiaoxiao2021-12-14  21

    **

    实验内容(一)

    **

    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会直接溢出,导致译码器计数值为101,故本来会开启第二个数码管,但为了让其从第一个亮,所以接输出0001,让第一个数码管亮 2'b10: OUT = 4'b 0010; 2'b11: OUT = 4'b 0100; endcase end end endmodule //dec_0to9显示输出数据译码器模块 module dec_0to9( //数码管从015依次输出 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

    最新回复(0)