summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile4
-rw-r--r--bin2bcd.sv52
-rw-r--r--ntoa.sv9
-rw-r--r--top.sv6
4 files changed, 26 insertions, 45 deletions
diff --git a/Makefile b/Makefile
index d270ffb..9eff3ef 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,8 @@ HEADERS := $(wildcard **.svh)
3CPPSRCS := $(wildcard **.cpp) 3CPPSRCS := $(wildcard **.cpp)
4COLLATERAL := $(wildcard **.hex) 4COLLATERAL := $(wildcard **.hex)
5 5
6OPTS ?=
7
6QUARTUS ?= /opt/quartus-lite/20.1.1.720/ 8QUARTUS ?= /opt/quartus-lite/20.1.1.720/
7 9
8QUARTUS_SH := $(QUARTUS)/quartus/bin/quartus_sh 10QUARTUS_SH := $(QUARTUS)/quartus/bin/quartus_sh
@@ -23,7 +25,7 @@ pof: build/toycpu.pof
23 25
24build/Vtop: $(VERILOG) $(HEADERS) $(CPPSRCS) $(COLLATERAL) 26build/Vtop: $(VERILOG) $(HEADERS) $(CPPSRCS) $(COLLATERAL)
25 @mkdir -p build 27 @mkdir -p build
26 verilator +1800-2017ext+sv -Wall -Wno-BLKSEQ -O3 --Mdir build --trace --cc --build --exe --top-module top $(VERILOG) $(CPPSRCS) 28 verilator +1800-2017ext+sv -Wall -Wno-BLKSEQ -O3 $(OPTS) --Mdir build --trace --cc --build --exe --top-module top $(VERILOG) $(CPPSRCS)
27 29
28build/toycpu.pof: build/toycpu.qpf $(VERILOG) $(COLLATERAL) 30build/toycpu.pof: build/toycpu.qpf $(VERILOG) $(COLLATERAL)
29 cd build; $(QUARTUS_SH) --flow compile toycpu 31 cd build; $(QUARTUS_SH) --flow compile toycpu
diff --git a/bin2bcd.sv b/bin2bcd.sv
index 266860c..8e618c6 100644
--- a/bin2bcd.sv
+++ b/bin2bcd.sv
@@ -15,37 +15,8 @@ module bin2bcd
15 , output bit [DIGITS-1:0][BASE_BITS-1:0] bcd_data 15 , output bit [DIGITS-1:0][BASE_BITS-1:0] bcd_data
16 ); 16 );
17 17
18// FIXME I don't think this works for odd bases
19
20localparam BASE_BITS = $clog2(BASE); 18localparam BASE_BITS = $clog2(BASE);
21localparam SLACK = (1 << BASE_BITS) - BASE;
22localparam DIGITS = $rtoi($ceil($ln(1 << BITS) / $ln(BASE))); 19localparam DIGITS = $rtoi($ceil($ln(1 << BITS) / $ln(BASE)));
23localparam CARRY_TEST = $rtoi($ceil($itor(BASE) / 2));
24localparam CARRY_ADD = $rtoi($ceil($itor(SLACK) / 2));
25
26`ifdef DEBUG_BIN2BCD
27
28initial $display("%d BITS", BITS);
29initial $display("%d BASE", BASE);
30initial $display("%d BASE_BITS", BASE_BITS);
31initial $display("%d SLACK", SLACK);
32initial $display("%d DIGITS", DIGITS);
33initial $display("%d CARRY_TEST", CARRY_TEST);
34initial $display("%d CARRY_ADD", CARRY_ADD);
35
36initial for(int i = 0; i < BASE; i = i + 1) begin
37 // verilator lint_off WIDTH
38 automatic bit [BASE_BITS-1:0] n = i;
39 automatic bit [BASE_BITS-1:0] a = n >= CARRY_TEST ? CARRY_ADD : 0;
40 automatic bit [BASE_BITS-1:0] s = n + a;
41 // verilator lint_on WIDTH
42 automatic bit c;
43 automatic bit [BASE_BITS-1:0] d;
44 {c, d} = {s, 1'b0};
45 $display("\t\t(%x + %x => %x) * 2 => %x:%x", n, a, s, c, d);
46end
47
48`endif
49 20
50bit bin_b_valid; 21bit bin_b_valid;
51bit [BITS-1:0] bin_b_data; 22bit [BITS-1:0] bin_b_data;
@@ -65,7 +36,7 @@ always_ff @(posedge clk) begin
65 bin_b_data = `bin_data; 36 bin_b_data = `bin_data;
66 bcd = 0; 37 bcd = 0;
67 work = BITS; 38 work = BITS;
68 for (int i = 0; i < BITS && i < MAX_SKIP; i = i + 1) begin 39 for (int i = 0; i < BITS && i < MAX_SKIP; ++i) begin
69 if (bin_b_data[BITS-1]) break; 40 if (bin_b_data[BITS-1]) break;
70 bin_b_data = { bin_b_data[BITS-2:0], 1'b0 }; 41 bin_b_data = { bin_b_data[BITS-2:0], 1'b0 };
71 work = work - 1; 42 work = work - 1;
@@ -73,14 +44,19 @@ always_ff @(posedge clk) begin
73 end 44 end
74 45
75 if (bin_b_valid && work != 0) begin 46 if (bin_b_valid && work != 0) begin
76 for (int i = 0; i < DIGITS; i = i + 1) 47 automatic bit carry = bin_b_data[BITS-1];
77 // verilator lint_off WIDTH 48 for (int i = 0; i < DIGITS; ++i) begin
78 if (bcd[i] >= CARRY_TEST) bcd[i] = bcd[i] + CARRY_ADD; 49 {carry, bcd[i]} = {bcd[i], carry};
79 // verilator lint_on WIDTH 50 if ({carry, bcd[i]} >= BASE) begin
80 for (int i = DIGITS - 1; i > 0; i = i - 1) 51 // verilator lint_off WIDTH
81 bcd[i] = { bcd[i][BASE_BITS-2:0], bcd[i-1][BASE_BITS-1] }; 52 bcd[i] = {carry, bcd[i]} - BASE;
82 bcd[0] = { bcd[0][BASE_BITS-2:0], bin_b_data[BITS-1] }; 53 // verilator lint_on WIDTH
83 bin_b_data = { bin_b_data[BITS-2:0], 1'b0 }; 54 carry = 1;
55 end
56 end
57 assert(!carry);
58
59 bin_b_data = bin_b_data << 1;
84 60
85 work = work - 1; 61 work = work - 1;
86 end 62 end
diff --git a/ntoa.sv b/ntoa.sv
index 2a5c1ef..f8e9f43 100644
--- a/ntoa.sv
+++ b/ntoa.sv
@@ -1,5 +1,6 @@
1module ntoa 1module ntoa
2 #( BITS = 8 2 #( BITS = 8
3 , BASE = 10
3 ) 4 )
4 ( input bit clk 5 ( input bit clk
5 , input bit reset 6 , input bit reset
@@ -19,7 +20,7 @@ bit [b2b.DIGITS-1:0][b2b.BASE_BITS-1:0] bcd_data;
19 20
20bin2bcd 21bin2bcd
21 #( .BITS(BITS) 22 #( .BITS(BITS)
22 , .BASE(10) 23 , .BASE(BASE)
23 ) b2b 24 ) b2b
24 ( .clk(clk) 25 ( .clk(clk)
25 , .reset(reset) 26 , .reset(reset)
@@ -50,10 +51,10 @@ always_ff @(posedge clk) begin
50 // verilator lint_off WIDTH 51 // verilator lint_off WIDTH
51 work = b2b.DIGITS; 52 work = b2b.DIGITS;
52 // verilator lint_on WIDTH 53 // verilator lint_on WIDTH
53 for (int i = 0; i < b2b.DIGITS - 1; i = i + 1) begin 54 for (int i = 0; i < b2b.DIGITS - 1; ++i) begin
54 if (bcd_b_data[b2b.DIGITS-1] != 0) break; 55 if (bcd_b_data[b2b.DIGITS-1] != 0) break;
55 bcd_b_data = { bcd_b_data[b2b.DIGITS-2:0], {b2b.BASE_BITS{1'b0}} }; 56 bcd_b_data = { bcd_b_data[b2b.DIGITS-2:0], {b2b.BASE_BITS{1'b0}} };
56 work = work - 1; 57 --work;
57 end 58 end
58 end 59 end
59 60
@@ -68,7 +69,7 @@ always_ff @(posedge clk) begin
68 a_data = "a" + bcd_b_data[b2b.DIGITS-1] - 10; 69 a_data = "a" + bcd_b_data[b2b.DIGITS-1] - 10;
69 // verilator lint_off WIDTH 70 // verilator lint_off WIDTH
70 bcd_b_data = { bcd_b_data[b2b.DIGITS-2:0], {b2b.BASE_BITS{1'b0}} }; 71 bcd_b_data = { bcd_b_data[b2b.DIGITS-2:0], {b2b.BASE_BITS{1'b0}} };
71 work = work - 1; 72 --work;
72 end else begin 73 end else begin
73 a_valid = 1; 74 a_valid = 1;
74 a_data = ","; 75 a_data = ",";
diff --git a/top.sv b/top.sv
index 4acfdeb..cbb5b55 100644
--- a/top.sv
+++ b/top.sv
@@ -1,5 +1,6 @@
1module top 1module top
2 #( FIB_BITS = 16 2 #( FIB_BITS = 16
3 , FIB_BASE = 10
3 , ROM_BITS = 8 4 , ROM_BITS = 8
4 ) 5 )
5 ( input bit clk // verilator public 6 ( input bit clk // verilator public
@@ -58,6 +59,7 @@ bit [7:0] fib_a_data;
58 59
59ntoa 60ntoa
60 #( .BITS(FIB_BITS) 61 #( .BITS(FIB_BITS)
62 , .BASE(FIB_BASE)
61 ) fib_ntoa 63 ) fib_ntoa
62 ( .clk(clk) 64 ( .clk(clk)
63 , .reset(reset) 65 , .reset(reset)
@@ -97,9 +99,9 @@ always_ff @(posedge clk) begin
97 if (!tx_valid && (data != 0)) begin 99 if (!tx_valid && (data != 0)) begin
98 tx_valid = 1; 100 tx_valid = 1;
99 tx_data = data; 101 tx_data = data;
100 addr = addr + 1; 102 ++addr;
101 end else if (data == 0) begin 103 end else if (data == 0) begin
102 addr = addr + 1; 104 ++addr;
103 state = state.next; 105 state = state.next;
104 end 106 end
105 end 107 end