差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
binary_to_bcd [2021/01/28 15:46]
gongyusu 创建
binary_to_bcd [2021/01/28 16:41] (当前版本)
gongyusu
行 4: 行 4:
 Binary coded decimal uses four bits per digit to represent a decimal number. For example the number 159 in decimal takes 12 bits to represent. This is useful for applications that interface to 7-Segment LEDs, among other things. The reason for this is that each 7-Segment display is treated individually (each gets 4 bits of the 12 bit number in the example above). The FPGA designer needs to know how to drive each digit, and uses BCD to do this. The table for BCD is below. Binary coded decimal uses four bits per digit to represent a decimal number. For example the number 159 in decimal takes 12 bits to represent. This is useful for applications that interface to 7-Segment LEDs, among other things. The reason for this is that each 7-Segment display is treated individually (each gets 4 bits of the 12 bit number in the example above). The FPGA designer needs to know how to drive each digit, and uses BCD to do this. The table for BCD is below.
  
-BCD and Decimal Numbers +BCD和十进制数值 | 
-BCD Decimal +|BCD|十进制| 
-0000 0 +|0000|0| 
-0001 1 +|0001|1| 
-0010 2 +|0010| 
-0011 3 +|0011| 
-0100 4 +|0100| 
-0101 5 +|0101| 
-0110 6 +|0110| 
-0111 7 +|0111| 
-1000 8 +|1000| 
-1001 9 +|1001
-others undefined+|其它|未定义| 
 Let's look at 159. The hundreds digit 1 is represented in binary by 0001. The tens digit 5 is represented in binary by 0101. The ones digit 9 is represented in binary by 1001. The entire number 159 in BCD is therefore: 000101011001. However 159 in binary is represented by 10011111. Again we need a way to convert this binary number 10011111 to its BCD equivalent 000101011001. To do this, we will use the Double Dabble algorithm. Let's look at 159. The hundreds digit 1 is represented in binary by 0001. The tens digit 5 is represented in binary by 0101. The ones digit 9 is represented in binary by 1001. The entire number 159 in BCD is therefore: 000101011001. However 159 in binary is represented by 10011111. Again we need a way to convert this binary number 10011111 to its BCD equivalent 000101011001. To do this, we will use the Double Dabble algorithm.
  
行 24: 行 25:
 Double Dabble Finite State Machine Double Dabble Finite State Machine
  
 +Verilog Implementation
 +Binary_To_BCD.v:​
 +<code verilog>
 +///////////////////////////////////////////////////////////////////////////////​
 +// File Downloaded from http://​www.nandland.com
 +///////////////////////////////////////////////////////////////////////////////​
 +module Binary_to_BCD
 +  #(parameter INPUT_WIDTH,​
 +    parameter DECIMAL_DIGITS)
 +  (
 +   ​input ​                        ​i_Clock,​
 +   input [INPUT_WIDTH-1:​0] ​      ​i_Binary,​
 +   ​input ​                        ​i_Start,​
 +   //
 +   ​output [DECIMAL_DIGITS*4-1:​0] o_BCD,
 +   ​output ​                       o_DV
 +   );
 +   
 +  parameter s_IDLE ​             = 3'​b000;​
 +  parameter s_SHIFT ​            = 3'​b001;​
 +  parameter s_CHECK_SHIFT_INDEX = 3'​b010;​
 +  parameter s_ADD               = 3'​b011;​
 +  parameter s_CHECK_DIGIT_INDEX = 3'​b100;​
 +  parameter s_BCD_DONE ​         = 3'​b101;​
 +   
 +  reg [2:0] r_SM_Main = s_IDLE;
 +   
 +  // The vector that contains the output BCD
 +  reg [DECIMAL_DIGITS*4-1:​0] r_BCD = 0;
 +    ​
 +  // The vector that contains the input binary value being shifted.
 +  reg [INPUT_WIDTH-1:​0] ​     r_Binary = 0;
 +      ​
 +  // Keeps track of which Decimal Digit we are indexing
 +  reg [DECIMAL_DIGITS-1:​0] ​  ​r_Digit_Index = 0;
 +    ​
 +  // Keeps track of which loop iteration we are on.
 +  // Number of loops performed = INPUT_WIDTH
 +  reg [7:0]                  r_Loop_Count = 0;
 + 
 +  wire [3:0]                 ​w_BCD_Digit;​
 +  reg                        r_DV = 1'​b0; ​                      
 +    ​
 +  always @(posedge i_Clock)
 +    begin
 + 
 +      case (r_SM_Main) ​
 +  ​
 +        // Stay in this state until i_Start comes along
 +        s_IDLE :
 +          begin
 +            r_DV <= 1'b0;
 +             
 +            if (i_Start == 1'b1)
 +              begin
 +                r_Binary ​ <= i_Binary;
 +                r_SM_Main <= s_SHIFT;
 +                r_BCD     <= 0;
 +              end
 +            else
 +              r_SM_Main <= s_IDLE;
 +          end
 +                 
 +  ​
 +        // Always shift the BCD Vector until we have shifted all bits through
 +        // Shift the most significant bit of r_Binary into r_BCD lowest bit.
 +        s_SHIFT :
 +          begin
 +            r_BCD     <= r_BCD << 1;
 +            r_BCD[0] ​ <= r_Binary[INPUT_WIDTH-1];​
 +            r_Binary ​ <= r_Binary << 1;
 +            r_SM_Main <= s_CHECK_SHIFT_INDEX;​
 +          end          ​
 +         
 +  ​
 +        // Check if we are done with shifting in r_Binary vector
 +        s_CHECK_SHIFT_INDEX :
 +          begin
 +            if (r_Loop_Count == INPUT_WIDTH-1)
 +              begin
 +                r_Loop_Count <= 0;
 +                r_SM_Main ​   <= s_BCD_DONE;
 +              end
 +            else
 +              begin
 +                r_Loop_Count <= r_Loop_Count + 1;
 +                r_SM_Main ​   <= s_ADD;
 +              end
 +          end
 +                 
 +  ​
 +        // Break down each BCD Digit individually. ​ Check them one-by-one to
 +        // see if they are greater than 4.  If they are, increment by 3.
 +        // Put the result back into r_BCD Vector.  ​
 +        s_ADD :
 +          begin
 +            if (w_BCD_Digit > 4)
 +              begin                                     
 +                r_BCD[(r_Digit_Index*4)+:​4] <= w_BCD_Digit + 3;  ​
 +              end
 +             
 +            r_SM_Main <= s_CHECK_DIGIT_INDEX; ​
 +          end       
 +         
 +         
 +        // Check if we are done incrementing all of the BCD Digits
 +        s_CHECK_DIGIT_INDEX :
 +          begin
 +            if (r_Digit_Index == DECIMAL_DIGITS-1)
 +              begin
 +                r_Digit_Index <= 0;
 +                r_SM_Main ​    <= s_SHIFT;
 +              end
 +            else
 +              begin
 +                r_Digit_Index <= r_Digit_Index + 1;
 +                r_SM_Main ​    <= s_ADD;
 +              end
 +          end
 +         
 +  ​
 +  ​
 +        s_BCD_DONE :
 +          begin
 +            r_DV      <= 1'b1;
 +            r_SM_Main <= s_IDLE;
 +          end
 +         
 +         
 +        default :
 +          r_SM_Main <= s_IDLE;
 +            ​
 +      endcase
 +    end // always @ (posedge i_Clock)  ​
 + 
 +   
 +  assign w_BCD_Digit = r_BCD[r_Digit_Index*4 +: 4];
 +       
 +  assign o_BCD = r_BCD;
 +  assign o_DV  = r_DV;
 +      ​
 +endmodule // Binary_to_BCD
 +</​code>​