module ntoa #( BITS = 8 , BASE = 10 ) ( input bit clk , input bit reset , output bit n_ready , input bit n_valid `define n_valid $past(n_valid) , input bit [BITS-1:0] n_data `define n_data $past(n_data) , input bit a_ready `define a_ready $past(a_ready) , output bit a_valid , output bit [7:0] a_data ); bit bcd_ready; bit bcd_valid; bit [b2b.DIGITS-1:0][b2b.BASE_BITS-1:0] bcd_data; bin2bcd #( .BITS(BITS) , .BASE(BASE) ) b2b ( .clk(clk) , .reset(reset) , .bin_ready(n_ready) , .bin_valid(n_valid) , .bin_data(n_data) , .bcd_ready(bcd_ready) , .bcd_valid(bcd_valid) `define bcd_valid $past(bcd_valid) , .bcd_data(bcd_data) `define bcd_data $past(bcd_data) ); bit bcd_b_valid; bit [b2b.DIGITS-1:0][b2b.BASE_BITS-1:0] bcd_b_data; bit [$clog2(b2b.DIGITS):0] work; always_ff @(posedge clk) begin if (reset) begin a_valid = 0; bcd_ready = 0; bcd_b_valid = 0; end else begin if (bcd_ready && `bcd_valid) begin bcd_b_valid = 1; bcd_b_data = `bcd_data; // verilator lint_off WIDTH work = b2b.DIGITS; // verilator lint_on WIDTH for (int i = 0; i < b2b.DIGITS - 1; ++i) begin if (bcd_b_data[b2b.DIGITS-1] != 0) break; bcd_b_data = { bcd_b_data[b2b.DIGITS-2:0], {b2b.BASE_BITS{1'b0}} }; --work; end end if (`a_ready) a_valid = 0; if (!a_valid && bcd_b_valid) begin if (work != 0) begin a_valid = 1; // verilator lint_off WIDTH if (bcd_b_data[b2b.DIGITS-1] < 10) a_data = "0" + bcd_b_data[b2b.DIGITS-1]; else a_data = "a" + bcd_b_data[b2b.DIGITS-1] - 10; // verilator lint_off WIDTH bcd_b_data = { bcd_b_data[b2b.DIGITS-2:0], {b2b.BASE_BITS{1'b0}} }; --work; end else begin a_valid = 1; a_data = ","; bcd_b_valid = 0; end end bcd_ready = !bcd_b_valid; end end endmodule