summaryrefslogtreecommitdiff
path: root/hdl/ntoa.sv
diff options
context:
space:
mode:
Diffstat (limited to 'hdl/ntoa.sv')
-rw-r--r--hdl/ntoa.sv90
1 files changed, 90 insertions, 0 deletions
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 @@
1`include "utils.svh"
2
3module ntoa
4 #( BITS = 8
5 , BASE = 10
6 , BASE_BITS = $clog2(BASE)
7 , DIGITS = 3 // should be ceil[log(2**BITS) base BASE] which is hard to do in Verilog :-(
8 )
9 ( input bit clk
10 , input bit reset
11
12 , output bit n_ready
13 , input bit n_valid `define n_valid `past(n_valid)
14 , input bit [BITS-1:0] n_data `define n_data `past(n_data)
15
16 , input bit a_ready `define a_ready `past(a_ready)
17 , output bit a_valid
18 , output bit [7:0] a_data
19 );
20
21bit bcd_ready;
22bit bcd_valid;
23bit [DIGITS-1:0][BASE_BITS-1:0] bcd_data;
24
25bin2bcd
26 #( .BITS(BITS)
27 , .BASE(BASE)
28 , .BASE_BITS(BASE_BITS)
29 , .DIGITS(DIGITS)
30 ) b2b
31 ( .clk(clk)
32 , .reset(reset)
33
34 , .bin_ready(n_ready)
35 , .bin_valid(n_valid)
36 , .bin_data(n_data)
37
38 , .bcd_ready(bcd_ready)
39 , .bcd_valid(bcd_valid) `define bcd_valid `past(bcd_valid)
40 , .bcd_data(bcd_data) `define bcd_data `past(bcd_data)
41 );
42
43bit bcd_b_valid;
44bit [DIGITS-1:0][BASE_BITS-1:0] bcd_b_data;
45
46bit [$clog2(DIGITS):0] work;
47
48always_ff @(posedge clk) begin
49 if (reset) begin
50 a_valid = 0;
51 bcd_ready = 0;
52 bcd_b_valid = 0;
53 end else begin
54 if (bcd_ready && `bcd_valid) begin
55 bcd_b_valid = 1;
56 bcd_b_data = `bcd_data;
57 // verilator lint_off WIDTH
58 work = DIGITS;
59 // verilator lint_on WIDTH
60 for (int i = 0; i < DIGITS - 1; ++i) begin
61 if (bcd_b_data[DIGITS-1] != 0) break;
62 bcd_b_data = { bcd_b_data[DIGITS-2:0], {BASE_BITS{1'b0}} };
63 --work;
64 end
65 end
66
67 if (`a_ready) a_valid = 0;
68 if (!a_valid && bcd_b_valid) begin
69 if (work != 0) begin
70 a_valid = 1;
71 // verilator lint_off WIDTH
72 if (bcd_b_data[DIGITS-1] < 10)
73 a_data = "0" + bcd_b_data[DIGITS-1];
74 else
75 a_data = "a" + bcd_b_data[DIGITS-1] - 10;
76 // verilator lint_off WIDTH
77 bcd_b_data = { bcd_b_data[DIGITS-2:0], {BASE_BITS{1'b0}} };
78 --work;
79 end else begin
80 a_valid = 1;
81 a_data = ",";
82 bcd_b_valid = 0;
83 end
84 end
85
86 bcd_ready = !bcd_b_valid;
87 end
88end
89
90endmodule