From 5c1df6d27f5dac143efc9ce84689b863dbee45bd Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Wed, 24 Mar 2021 08:35:07 -0700 Subject: Reorganize repo layout to make it a little easier to work within. --- hdl/ntoa.sv | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 hdl/ntoa.sv (limited to 'hdl/ntoa.sv') diff --git a/hdl/ntoa.sv b/hdl/ntoa.sv new file mode 100644 index 0000000..6da1baf --- /dev/null +++ b/hdl/ntoa.sv @@ -0,0 +1,90 @@ +`include "utils.svh" + +module ntoa + #( BITS = 8 + , BASE = 10 + , BASE_BITS = $clog2(BASE) + , DIGITS = 3 // should be ceil[log(2**BITS) base BASE] which is hard to do in Verilog :-( + ) + ( 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 [DIGITS-1:0][BASE_BITS-1:0] bcd_data; + +bin2bcd + #( .BITS(BITS) + , .BASE(BASE) + , .BASE_BITS(BASE_BITS) + , .DIGITS(DIGITS) + ) 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 [DIGITS-1:0][BASE_BITS-1:0] bcd_b_data; + +bit [$clog2(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 = DIGITS; + // verilator lint_on WIDTH + for (int i = 0; i < DIGITS - 1; ++i) begin + if (bcd_b_data[DIGITS-1] != 0) break; + bcd_b_data = { bcd_b_data[DIGITS-2:0], {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[DIGITS-1] < 10) + a_data = "0" + bcd_b_data[DIGITS-1]; + else + a_data = "a" + bcd_b_data[DIGITS-1] - 10; + // verilator lint_off WIDTH + bcd_b_data = { bcd_b_data[DIGITS-2:0], {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 -- cgit v1.2.3