一种用verilog生成任意位二进制转BCD码的方法

//
//filename: bin2bcd.v
//author: lyq
//Date: 2016.3.12 11:36
//
// 二进制转BCD算法(左移加3)
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   00-│b16│b15│b14│b13│b12│b11│b10│b9 │b8 │b7 │b6 │b5 │b4 │b3 │b2 │b1 │b0 │a12│a11│a10│a9 │a8 │a7 │a6 │a5 │a4 │a3 │a2 │a1 │a0 │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   d1-│   │   │   │   │   │   │   │   │   │   │   │   │   │ 0 │a12│a11│a10│   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                                           └─────d00─────┘                    
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   c1-│   │   │   │   │   │   │   │   │   │   │   │   │   │c00│c00│c00│c00│   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                                           └──c00=d00+3──┘                    
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   d2-│   │   │   │   │   │   │   │   │   │   │   │   │c00│c00│c00│c00│a9 │   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                                           └─────d01─────┘                    
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   c2-│   │   │   │   │   │   │   │   │   │   │   │   │c00│c01│c01│c01│c01│   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                                          └────c01=d01+3────┘                    
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   d3-│   │   │   │   │   │   │   │   │   │   │   │c00│c01│c01│c01│c01│a8 │   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                                          └──────d02──────┘                    
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//   c3-│   │   │   │   │   │   │   │   │   │   │   │c00│c01│c02│c02│c02│c02│   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                                          └────c02=d02+3───┘                    
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//d6-d4-│   │   │   │   │   │   │   │   │   │0  │c00│c01│c02│c02│c02│c02│a7 │   │   │   │   │   │   │   │   │   │   │   │   │   │
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                           └─────d13─────┘ └─────d03─────┘                     
//      ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
//c6-c4-│   │   │   │   │   │   │   │   │   │c13│c13│c13│c13│c03│c03│c03│c03│   │   │   │   │   │   │   │   │   │   │   │   │   │ 
//      └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
//                                           └───c13=d13+3───┘ └───c03=d03+3──┘                     
//


//BIN_BITS: >=4
//BCD_BITS: 
module bin2bcd
(
bin, 
bcd
);


parameter BIN_BITS = 32;
parameter BCD_BITS = 40;


input  wire [BIN_BITS - 1 : 0] bin;
output wire [BCD_BITS - 1 : 0] bcd;


//实际BCD码的有效位数(二进位)
localparam BCD_REAL_BITS = ((BIN_BITS-4)/3+1)*4 + (BIN_BITS-1)%3 + 1;


//这是算法需要的线变量
wire [BCD_REAL_BITS - 1 : 0] bcd_i;


//算法中间变量
wire [3:0] d[0 : (BCD_BITS - 1) / 4][0 : BIN_BITS - 4];
wire [3:0] c[0 : (BCD_BITS - 1) / 4][0 : BIN_BITS - 4];
 
genvar i, j;


//对算法和实际的BCD位数进行匹配,因为算法需要的位数可能会大于实际需要的位数
generate    
begin
if (BCD_BITS < BCD_REAL_BITS)
begin  //传入的BCD位少于算法需要的位数
assign bcd[BCD_BITS-1 : 0] = bcd_i[BCD_BITS - 1 : 0];
end
else  
begin
assign bcd[BCD_REAL_BITS - 1 : 0] = bcd_i[BCD_REAL_BITS - 1 : 0];
if (BCD_BITS > BCD_REAL_BITS)
assign bcd[(BCD_BITS - 1)- : BCD_BITS - BCD_REAL_BITS] = 0;
end  
end
endgenerate


//d的生成逻辑
generate 
begin
//生成d,c逻辑
for (i = 0; i < (BIN_BITS - 4) / 3 + 1; i = i + 1) 
begin
for (j = i * 3; j < BIN_BITS - 3; j = j + 1) 
begin
if (i == 0) //第一列d
begin
if (j == 0) //生成第一个d
assign d[0][j] = {1'b0, bin[(BIN_BITS - 1)-:3]};
else //移位生成第一列d
assign d[0][j] = {c[0][j-1][2:0], bin[BIN_BITS-3-j]};
end
else if (j == i * 3) //形成新d列
assign d[i][j] = {1'b0, c[i-1][j-3][3], c[i-1][j-2][3], c[i-1][j-1][3]};
else //移位生成新d
assign d[i][j] = {c[i][j-1][2:0], c[i-1][j-1][3]};

//生成c逻辑(加3)逻辑
assign c[i][j] = add3_fun(d[i][j]);
end

//联接bcd码
if (i == 0) //第一个BCD位
assign bcd_i[((i+1)*4-1)-:4] = {c[i][BIN_BITS-4][2:0], bin[0]};
else
assign bcd_i[((i+1)*4-1)-:4] = {c[i][BIN_BITS-4][2:0], c[i-1][BIN_BITS-4][3]};
end  

//联接最高位bcd码
for(j = BCD_REAL_BITS % 4; j != 0; j = j - 1)
assign bcd_i[(BCD_REAL_BITS/4)*4+(j-1)] = c[BCD_REAL_BITS/4-1][BIN_BITS-4-(j-1)][3];
end 
endgenerate


function automatic [3:0] add3_fun;
input [3:0] in;
begin
case (in)
4'b0000: add3_fun = 4'b0000;
4'b0001: add3_fun = 4'b0001;
4'b0010: add3_fun = 4'b0010;
4'b0011: add3_fun = 4'b0011;
4'b0100: add3_fun = 4'b0100;
4'b0101: add3_fun = 4'b1000;
4'b0110: add3_fun = 4'b1001;
4'b0111: add3_fun = 4'b1010;
4'b1000: add3_fun = 4'b1011;
4'b1001: add3_fun = 4'b1100;
default: add3_fun = 4'b0000;
endcase
end
endfunction


endmodule

你可能感兴趣的:(FPGA学习)