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!
-
\$\begingroup\$ Hint: dividing by 10 is expensive. Dividing by 16 is cheap. \$\endgroup\$The Photon– The Photon2018年10月15日 15:39:34 +00:00Commented Oct 15, 2018 at 15:39
-
\$\begingroup\$ Also, for loops in Verilog don't cause sequential calculations; they cause multiple circuits to be generated. \$\endgroup\$The Photon– The Photon2018年10月15日 15:40:33 +00:00Commented Oct 15, 2018 at 15:40
-
\$\begingroup\$ 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. \$\endgroup\$Tom Carpenter– Tom Carpenter2018年10月15日 15:43:30 +00:00Commented Oct 15, 2018 at 15:43
-
\$\begingroup\$ 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. \$\endgroup\$The Photon– The Photon2018年10月15日 16:11:52 +00:00Commented Oct 15, 2018 at 16:11
-
\$\begingroup\$ 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. \$\endgroup\$Oldfart– Oldfart2018年10月15日 16:19:22 +00:00Commented Oct 15, 2018 at 16:19
1 Answer 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!