原理,将二进制码转换为BCD码,对于8位二进制码,最大为255,需要个位、十位、百位三个BCD码。
移位加三的原理是用20位的寄存器,高12位置零,低八位为原二进制码。然后开始移位,移位8次,每次移位后判断个位、十位、百位是否大于等于5,如果大于等于5再移位那么就会大于10,就会溢出,因此需要加三后移位,(这样移位后相当于+6),即将满16进位变成了满10进位。
代码如下。
`timescale 1ns/1ps
module bin_bcd(Clk,Rst_n,data_bin,data_b,data_s,data_g);
input Clk,Rst_n;
input [7:0] data_bin;
//input s;
output reg [3:0] data_b,data_s,data_g;
reg [19:0] data_buff;
reg [3:0] cnt ;
always@(posedge Clk,negedge Rst_n ) begin
if(~Rst_n)
cnt <= 0;
else if (cnt ==4'd8)
cnt <= 0;
else
cnt <= cnt + 4'b1;
end
always@(posedge Clk,negedge Rst_n) begin
if(~Rst_n)
data_buff <= {12'd0,data_bin};
else if(~|cnt)
data_buff <= {12'd0,data_bin};
else begin
if(data_buff[11:8] >= 4'd5 )
data_buff[11:8] = data_buff[11:8] + 'd3 ;
if(data_buff[15:12] >= 4'd5 )
data_buff[15:12] = data_buff[15:12] + 'd3 ;
if(data_buff[19:16] >= 4'd5)
data_buff[19:16] = data_buff[19:16] + 'd3 ;
data_buff <= data_buff << 1 ;
end
end
always@(posedge Clk,negedge Rst_n ) begin
if(~Rst_n) begin
{data_b,data_s,data_g} <= 0;
end
else if (cnt==4'd0)
{data_b,data_s,data_g} <= data_buff[19:8];
end
endmodule
这其中容易出现的问题。
(1)关于多个if语句的并列使用,对于同一个操作数,在最后的if是具有最高优先级的。但是这里三个if语句针对的位数不同,对应的寄存器不同,所以是并列的。
要注意的是移位应该发生加三之后,先加三,再移位。(begin end块内是有先后顺序的)
每个时钟周期更新一次数据