使用Veriog - HDL语言,DE0 FPGA开发板在 DE0 开发板的最右侧的 HEX LED 数码管上,进行计数并用十进制数进行显示。计数器特征如下:
该计数器在电路复位后会循环的从0值递增计数到最大值,计数最大值是一个循环变化的过程,计数器复位之后,第一次计数最大值是6,然后是7、8、9,然后计数最大值又变成6,如此往复循环, 计数数值变化的时间间隔是1秒 ,计数过程如下所示:
0 1 … 6 | 0 1 … 7 | 0 1 … 8 | 0 1 …9 | 0 1 … 6 |
---|
其中,max表示计数最大值;CNTVAL表示计数值,计数最大值要依次加一,加到9时再变为6。max[3..0]和CNTVAL[3..0]构成D触发器。CLK为1s周期。
顶层RTL:
cnt_sync为第一级计数器,其OV输出端用于产生1s的时钟信号;
cnt_0to9为第二级计数器,用于产生显示的计数值;
tubedec_4to16为数码管译码电路。
cnt_0to9底层RTL:
Verilog HDL代码:
module cnt_sync(
RESET ,
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK,RESET;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 50_000_000; //50MHz下为1s
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK)
begin
if (!RESET)
begin
CNTVAL <= 0;
end
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 // module cnt_sync
////////////////////////////////////////////////////////
module cnt_en_0to9(
EN ,
RESET ,
CLK , // clock
CNTVAL); // counter value
// OV ); // overflow
input CLK,RESET,EN;
output [4-1:0] CNTVAL;
//output OV;
reg [4-1:0] CNTVAL;
//reg OV;
reg [4-1:0] max=6;
always @ (posedge CLK or negedge RESET)
begin
if(!RESET) //when rst, set max=6
begin
max <= 6;
CNTVAL <= 0;
end
else if(EN)
begin
if(CNTVAL >= max) //when OV, max++, if max=9,then max=6
begin
CNTVAL <= 0;
max <= max + 1'b1;
if (max >= 9)
max <= 6;
end
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL;
end
// always @ (CNTVAL)
// begin
// if(CNTVAL == max)
// begin
// OV = 1'b1;
// end
// else
// OV = 1'b0;
// end
endmodule // module cnt_en_0to9
///////////////////////////////////////////////////////
module tubedec_4to16(IN,OUT);
input[3:0] IN;
output reg[7:0] OUT;
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;
4'hA: OUT=8'h88;
4'hB: OUT=8'h83;
4'hC: OUT=8'hc6;
4'hD: OUT=8'ha1;
4'hE: OUT=8'h86;
4'hF: OUT=8'h8e;
default: OUT=8'hff;
endcase
end
endmodule
在 DE0 开发板的 从左到右 的 4个HEX LED 数码管上,进行计数并用十进制数进行显示。计数器特征如下:
顶层RTL:
顶层RTL涉及:
cnt_sync为第一级计数器,其OV输出端用于产生1s的时钟信号;
cnt_0to9为第二级计数器,用于产生显示的计数值及数码管选择器的CLK信号;
dec_CLKto4为数码管选择器,用于产生数码管译码器使能信号,控制数码管何时点亮;
tubedec_en_4to16为数码管译码器,带有使能控制端,输出为共阳极数码管段选信号。
module cnt_sync(
RESET ,
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK,RESET;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 50_000_000; //50MHz下为1s
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK)
begin
if (!RESET)
begin
CNTVAL <= 0;
end
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 // module cnt_sync
///////////////////////////////////////////////////////
module cnt_en_0to9(
EN ,
RESET ,
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK,RESET,EN;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
reg [4-1:0] max=6;
always @ (posedge CLK or negedge RESET)
begin
if(!RESET) //when rst, set max=6
begin
max <= 6;
CNTVAL <= 0;
end
else if(EN)
begin //when OV, max++, if max=9,then max=6
if(CNTVAL >= max)
begin
CNTVAL <= 0;
max <= max + 1'b1;
if (max >= 9)
max <= 6;
end
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL;
end
always @ (CNTVAL)
begin
if(CNTVAL == max)
begin
OV = 1'b1;
end
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
//////////////////////////////////////////////////////
module dec_ento4(
EN,
RESET,
OUT);
input RESET,EN;
output [4-1:0] OUT ;
reg [4-1:0] OUT ;
reg [3:0] CNT;
always @(negedge EN or negedge RESET)
begin
if (!RESET)
CNT <= 0;
else
begin
if (CNT >= 3)
CNT <= 0;
else
CNT <= CNT + 1'b1;
end
end
always @ (CNT) begin
case(CNT)
2'b00: OUT = 4'b 0001;
2'b01: OUT = 4'b 0010;
2'b10: OUT = 4'b 0100;
2'b11: OUT = 4'b 1000;
endcase
end
endmodule // module dec_ento4;
///////////////////////////////////////////////////////
module tubedec_en_4to16(IN,OUT,EN);
input EN;
input[3:0] IN;
output reg[7:0] OUT;
always @(IN)
begin
if(EN)
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;
4'hA: OUT=8'h88;
4'hB: OUT=8'h83;
4'hC: OUT=8'hc6;
4'hD: OUT=8'ha1;
4'hE: OUT=8'h86;
4'hF: OUT=8'h8e;
endcase
end
else
begin
OUT=8'hff;
end
end
endmodule