1.原理
这个十六进制是右边的dp为高位。
数码管的动态显示,在第一个计数周期显示个位,在第二个周期显示十位,在第三个周期显示百位由于人眼的视觉和数码管的特性,感觉就是显示了234,每个数码管的显示需要从输入的数据里提取出个十百位,所以需要BCD码。
8,原来输入的数据有多少位宽就要移位多少次。
增加一个BCD转码模块。
修改系统框图
2.代码
2.1 bcd_8421.v
module bcd_8421(
input wire sys_clk ,
input wire sys_rst_n ,
input wire[19:0] data ,
output reg[3:0] unit ,
output reg[3:0] ten ,
output reg[3:0] hun ,
output reg[3:0] tho ,
output reg[3:0] t_tho ,
output reg[3:0] h_hun
);
reg [4:0]cnt_shift; //输入是20位,第0次补0,要计数到20,就是0-20,第21次进行输出的赋值
reg [43:0]data_shift;//20位的data输入,和4*6=24位的8421BCD
reg shift_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
cnt_shift<=5'd0;
else if((cnt_shift==5'd21)&&(shift_flag==1'b1))
cnt_shift<=5'd0;
else if(shift_flag==1'b1)
cnt_shift<=cnt_shift+1'b1;
else
cnt_shift<=cnt_shift;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
shift_flag<=1'b0;
else
shift_flag<=~shift_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
data_shift<=44'd0;
else if(cnt_shift==5'd0)
data_shift<={24'b0,data};
else if((cnt_shift<21)&&(shift_flag==1'b0))
begin
data_shift[23:20]<=(data_shift[23:20]>4) ? (data_shift[23:20]+2'd3) : (data_shift[23:20]);
data_shift[27:24]<=(data_shift[27:24]>4) ? (data_shift[27:24]+2'd3) : (data_shift[27:24]);
data_shift[31:28]<=(data_shift[31:28]>4) ? (data_shift[31:28]+2'd3) : (data_shift[31:28]);
data_shift[35:32]<=(data_shift[35:32]>4) ? (data_shift[35:32]+2'd3) : (data_shift[35:32]);
data_shift[39:36]<=(data_shift[39:36]>4) ? (data_shift[39:36]+2'd3) : (data_shift[39:36]);
data_shift[43:40]<=(data_shift[43:40]>4) ? (data_shift[43:40]+2'd3) : (data_shift[43:40]);
end
else if((cnt_shift<5'd21)&&(shift_flag==1'b1))
data_shift<=data_shift<<1;
else
data_shift<=data_shift;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
begin
unit <=4'b0;
ten <=4'b0;
hun <=4'b0;
tho <=4'b0;
t_tho <=4'b0;
h_hun <=4'b0;
end
else if(cnt_shift==5'd21)
begin
unit <=data_shift[23:20];
ten <=data_shift[27:24];
hun <=data_shift[31:28];
tho <=data_shift[35:32];
t_tho <=data_shift[39:36];
h_hun <=data_shift[43:40];
end
endmodule
2.2 tb_bcd_8421.v
`timescale 1ns/1ns
module tb_bcd_8421();
reg sys_clk ;
reg sys_rst_n;
reg [19:0] data;
wire [3:0]unit ;
wire [3:0]ten ;
wire [3:0]hun ;
wire [3:0]tho ;
wire [3:0]t_tho ;
wire [3:0]h_hun ;
initial
begin
sys_clk=1'b1;
sys_rst_n<=1'b0;
data<=20'd0;
#30
sys_rst_n<=1'b1;
data<=20'd123_456;
#3000
data<=20'd654_321;
#3000
data<=20'd987_654;
#3000
data<=20'd999_999;
end
always #10 sys_clk=~sys_clk;
bcd_8421 tb_bcd_8421(
.sys_clk (sys_clk) ,
.sys_rst_n (sys_rst_n) ,
.data (data) ,
.unit (unit) ,
.ten (ten) ,
.hun (hun) ,
.tho (tho) ,
.t_tho (t_tho) ,
.h_hun (h_hun)
);
endmodule
shift_reg高电平时,cnt_shift开始计数
(最后一位999_999显示有误,不知道怎么改)