應用:
用fpga實現對數碼管顯示,以前通常的方法是進行整除和取余進行運算,但是fpga並不擅長乘法除法運算,所以可以用BCD碼來轉換。
BCD碼:通俗的可以理解為用四位二進制數表示一位十進制數字。例如,256就可以用bcd碼表示為:0010_1001_0110
因此在數碼管顯示中,也就是把256各位分出來,就可以用bcd碼來表示,下面說一種二進制轉換bcd碼的方法。
加3移位法:
bcd碼中只有0~9十進制數,但是在四位二進制中是16進制進1,因此在移位過程中要對二進制進行判斷,當在移位之后的狀態Qn+1大於9,要對Qn加6才可以。例如1000移位大於9加6為0001_0110,對應bcd碼中的16。
我們也可以在移位之前進行判斷,如果移位之前的Qn數據大於4,說明Qn+1會溢出,所以可以+3再進行移位,例如1000大於4,加3為1011然后再進行移位0001_0110,16和剛才結果是一樣的。
簡單的說,判斷的目的是防止下一次移位,發生數據溢出的情況
思路:
代碼可以總結為三個部分:移位,加二進制數,判斷(最后一次不需要判斷)
例如15 --- 1111
(1)移位 0000_0000 加 0000_0001 判斷 0000_0001
(2)移位 0000_0010 加 0000_0011 判斷 0000_0011
(3)移位 0000_0110 加 0000_0111 判斷 0000_1010
(4)移位 0001_0100 加 0001_0101
/********************************* 功能:實現對6位十進制數以內的bcd碼轉換 time: 2017/4/29 vision:1.0 *********************************/ `define data_in_num 19 `define data_bcd_num 23 module pro_bcd( clk, rst_n, data_in, data_bcd ); input clk; input rst_n; input [`data_in_num :0] data_in; output [`data_bcd_num:0] data_bcd; reg [`data_bcd_num:0] data_bcd_r; reg [1:0] state; reg [5:0] shift_cnt; always @(posedge clk or negedge rst_n) if(!rst_n)begin data_bcd_r <= 0; state <= 0; shift_cnt <= 0; end else case(state) 2'd0:begin shift_cnt <= 0; data_bcd_r <= 0; state <= state + 1; end 2'd1:begin //移位 if(shift_cnt < `data_in_num + 1)begin data_bcd_r <= data_bcd_r<<1; shift_cnt <= shift_cnt + 1; state <= state + 1; end else state <= 0; end 2'd2:begin //相加 data_bcd_r <= data_bcd_r + data_in[`data_in_num + 1 - shift_cnt]; state <= state + 1; end 2'd3:begin //判斷 if(data_bcd_r[3:0] > 4 ) //1 data_bcd_r <= data_bcd_r + 3; if(data_bcd_r[7:4]>4) //2 data_bcd_r[7:4] <= data_bcd_r[7:4] + 3; if(data_bcd_r[11:8]>4) //3 data_bcd_r[11:8] <= data_bcd_r[11:8] + 3; if(data_bcd_r[15:12]>4) //4 data_bcd_r[15:12] <= data_bcd_r[15:12] + 3; if(data_bcd_r[19:16]>4) //5 data_bcd_r[19:16] <= data_bcd_r[19:16] + 3; if(data_bcd_r[`data_bcd_num:20]>4) //6 data_bcd_r[`data_bcd_num:20] <= data_bcd_r[`data_bcd_num:20] + 3; state <= 1; end default:state <= 0; endcase assign data_bcd = (state == 3)&&(shift_cnt == `data_in_num + 1) ? data_bcd_r : data_bcd; endmodule