2

I'm trying to convert Hex number into Decimal ASCII representation in Verilog, I've done the next code that converts successfully but this it cost a lot of timing for my design, could anyone help me with any suggestions for optimizing this code?

module Hex_To_ASCII 
#
(
    parameter NumberOfDigits = 14,
              InputSize      = 47
)
(
    input clk,

    input go,

    input [InputSize -1:0] Value,

    output reg [NumberOfDigits * 8 -1:0] ASCII
);

integer i;
integer j;

reg [7:0] ASCII_Integer [0:NumberOfDigits-1]; 
reg [InputSize - 1:0] hexInteger_tmp;
reg [NumberOfDigits*8 -1:0] full_ASCII_tmp;

reg start;
reg stop;

always @ (posedge clk) begin
    if (go) begin start <= 1; stop <= 0; end
    if (!go) begin start <= 0; stop <= 1; end
end


always @ (posedge clk) begin


  if (start) begin

      hexInteger_tmp = Value;      

      for(i = 0; i <= NumberOfDigits-1; i = i +1) begin       
          ASCII_Integer[i] = ( hexInteger_tmp % 10 ) + 8'h30;
          hexInteger_tmp = hexInteger_tmp / 10;          
      end

      full_ASCII_tmp = ASCII_Integer[NumberOfDigits -1];
      for(j = NumberOfDigits -2; j >= 0; j = j -1) begin
          full_ASCII_tmp = {full_ASCII_tmp, ASCII_Integer[j]};
      end

      ASCII = full_ASCII_tmp; 

  end

  if (stop) begin
      for(i = 0; i <= NumberOfDigits-1; i = i +1) begin       
          ASCII_Integer[i] = 0;             
      end

      hexInteger_tmp = 0; 
      full_ASCII_tmp = 0;  
      ASCII          = 0;   
  end



end

endmodule 

Thanks Guys!

  • Hint: dividing by 10 is expensive. Dividing by 16 is cheap. – The Photon Oct 15 '18 at 15:39
  • Also, for loops in Verilog don't cause sequential calculations; they cause multiple circuits to be generated. – The Photon Oct 15 '18 at 15:40
  • Might I suggest that you read about the "Double Dabble" algorithm - it's a great way of avoiding having to do any very expensive division. – Tom Carpenter Oct 15 '18 at 15:43
  • Your text says you want to "convert Hex number into **Hex** ASCII representation in Verilog". But your code seems to be trying to convert to a decimal ASCII representation. Please **edit** you question to make clear which one you want to do. – The Photon Oct 15 '18 at 16:11
  • +1 for editing rather than replying in comments. – The Photon Oct 15 '18 at 16:14
  • Note that algorithms like the "Double Dabble" can be sped up by merging multiple steps into one. Thus you can, with the right code, convert 2, 3 or more bits per clock cycle at the cost of more logic. However the process is always to start with one bit and then work from there. – Oldfart Oct 15 '18 at 16:19
  • @TomCarpenter Thanks, did not know about the double-dabble. Got it working (just for fun) in Verilog for 1, 2 and 4 bits per clock cycle. Alexis: there is VHDL code in wikipedia. – Oldfart Oct 15 '18 at 21:18

1 Answers1

1

Regarding the Tom Carpenter answer, I've found an algorithm for Double Dabble in google, finally, I've added 'h30 to every 4 bits of the result and is done

if someone needs it here is the code:

////////////////////////////////////////////////////////////////////////////////////
//                                 18-bit Example                                 //
//                                                                                //
//                     B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B       //
//                     I  I  I  I  I  I  I  I  I  I  I  I  I  I  I  I  I  I       //
//                     N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N       //
//                     1  1  1  1  1  1  1  1  9  8  7  6  5  4  3  2  1  0       //
//     '0 '0 '0 '0 '0  7  6  5  4  3  2  1  0  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  V__V__V__V  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  | /IF>4THEN+3\ |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  | \__________/ |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  V__V__V__V  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  | /IF>4THEN+3\ |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  | \__________/ |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  V__V__V__V  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  | /IF>4THEN+3\ |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  | \__________/ |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  V__V__V__V  V__V__V__V  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  | /IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  | \__________/\__________/ |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  V__V__V__V  V__V__V__V  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  | /IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  | \__________/\__________/ |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  V__V__V__V  V__V__V__V  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  | /IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  | \__________/\__________/ |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |  |  |  |  |  |  |       //
//      |  | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |  |  |  |       //
//      |  | \__________/\__________/\__________/ |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |  |  |  |  |  |       //
//      |  |  | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |  |  |       //
//      |  |  | \__________/\__________/\__________/ |  |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  |  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |  |  |  |  |       //
//      |  |  |  | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |  |       //
//      |  |  |  | \__________/\__________/\__________/ |  |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |  |  |  |       //
//      | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |  |       //
//      | \__________/\__________/\__________/\__________/ |  |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |  |  |       //
//      |  | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |  |  |       //
//      |  | \__________/\__________/\__________/\__________/ |  |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  |  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |  |       //
//      |  |  | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |  |       //
//      |  |  | \__________/\__________/\__________/\__________/ |  |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  |  |  |       //
//     /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |  |       //
//     \__________/\__________/\__________/\__________/\__________/ |  |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  |  |       //
//      | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |  |       //
//      | \__________/\__________/\__________/\__________/\__________/ |  |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      |  |  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  V__V__V__V  |       //
//      |  | /IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\/IF>4THEN+3\ |       //
//      |  | \__________/\__________/\__________/\__________/\__________/ |       //
//      |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |       //
//      B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B  B       //
//      C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C  C       //
//      D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D       //
//      2  2  2  1  1  1  1  1  1  1  1  1  1  9  8  7  6  5  4  3  2  1  0       //
//      2  1  0  9  8  7  6  5  4  3  2  1  0                                     //
//     \_______/\__________/\__________/\__________/\__________/\__________/      //
//     100,000's  10,000's     1000's      100's        10's         1's          //
//                                                                                //
////////////////////////////////////////////////////////////////////////////////////

module bin2bcd
 #( parameter                W = 64)  // input width
  ( input      [W-1      :0] bin   ,  // binary
    output reg [W+(W-4)/3:0] bcd   ); // bcd {...,thousands,hundreds,tens,ones}

  integer i,j;

  always @(bin) begin


    for(i = 0; i <= W+(W-4)/3; i = i+1) bcd[i] = 0;     // initialize with zeros
    bcd[W-1:0] = bin;                                   // initialize with input vector
    for(i = 0; i <= W-4; i = i+1)                       // iterate on structure depth
      for(j = 0; j <= i/3; j = j+1)                     // iterate on structure width
        if (bcd[W-i+4*j -: 4] > 4)                      // if > 4
          bcd[W-i+4*j -: 4] = bcd[W-i+4*j -: 4] + 4'd3; // add 3     
  end

endmodule

Many thanks for your help!