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/bin2bcd.sv | 76 ++++++++++++++++++++++++++++ hdl/fibseq.sv | 32 ++++++++++++ hdl/jtag_uart.sv | 84 ++++++++++++++++++++++++++++++ hdl/ntoa.sv | 90 ++++++++++++++++++++++++++++++++ hdl/top.sv | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hdl/utils.svh | 5 ++ 6 files changed, 439 insertions(+) create mode 100644 hdl/bin2bcd.sv create mode 100644 hdl/fibseq.sv create mode 100644 hdl/jtag_uart.sv create mode 100644 hdl/ntoa.sv create mode 100644 hdl/top.sv create mode 100644 hdl/utils.svh (limited to 'hdl') diff --git a/hdl/bin2bcd.sv b/hdl/bin2bcd.sv new file mode 100644 index 0000000..9b1609b --- /dev/null +++ b/hdl/bin2bcd.sv @@ -0,0 +1,76 @@ +`include "utils.svh" + +module bin2bcd + #( 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 :-( + , MAX_SKIP = BITS + ) + ( input bit clk + , input bit reset + + , output bit bin_ready + , input bit bin_valid `define bin_valid `past(bin_valid) + , input bit [BITS-1:0] bin_data `define bin_data `past(bin_data) + + , input bit bcd_ready `define bcd_ready `past(bcd_ready) + , output bit bcd_valid + , output bit [DIGITS-1:0][BASE_BITS-1:0] bcd_data + ); + +bit bin_b_valid; +bit [BITS-1:0] bin_b_data; + +bit [DIGITS-1:0][BASE_BITS-1:0] bcd; + +bit [$clog2(BITS):0] work; + +always_ff @(posedge clk) begin + if (reset) begin + bin_ready = 0; + bcd_valid = 0; + bin_b_valid = 0; + end else begin + if (bin_ready && `bin_valid) begin + bin_b_valid = 1; + bin_b_data = `bin_data; + bcd = 0; + work = BITS; + for (int i = 0; i < BITS && i < MAX_SKIP; ++i) begin + if (bin_b_data[BITS-1]) break; + bin_b_data = { bin_b_data[BITS-2:0], 1'b0 }; + work = work - 1; + end + end + + if (bin_b_valid && work != 0) begin + automatic bit carry = bin_b_data[BITS-1]; + for (int i = 0; i < DIGITS; ++i) begin + {carry, bcd[i]} = {bcd[i], carry}; + if ({carry, bcd[i]} >= BASE) begin + // verilator lint_off WIDTH + bcd[i] = {carry, bcd[i]} - BASE; + // verilator lint_on WIDTH + carry = 1; + end + end + assert(!carry); + + bin_b_data = bin_b_data << 1; + + work = work - 1; + end + + if (`bcd_ready) bcd_valid = 0; + if (!bcd_valid && bin_b_valid && work == 0) begin + bcd_valid = 1; + bcd_data = bcd; + bin_b_valid = 0; + end + + bin_ready = !bin_b_valid; + end +end + +endmodule diff --git a/hdl/fibseq.sv b/hdl/fibseq.sv new file mode 100644 index 0000000..752c0b6 --- /dev/null +++ b/hdl/fibseq.sv @@ -0,0 +1,32 @@ +`include "utils.svh" + +module fibseq + #( BITS = 8 + ) + ( input bit clk + , input bit reset + + , input bit ready `define ready `past(ready) + , output bit valid + , output bit [BITS-1:0] data + ); + +bit [BITS-1:0] a; +bit [BITS-1:0] b; + +always_ff @(posedge clk) begin + if (reset) begin + valid = 0; + a = 0; + b = 1; + end else begin + if (`ready) valid = 0; + if (!valid) begin + valid = 1; + data = a; + {a, b} = {b, a + b}; + end + end +end + +endmodule diff --git a/hdl/jtag_uart.sv b/hdl/jtag_uart.sv new file mode 100644 index 0000000..eb0bc11 --- /dev/null +++ b/hdl/jtag_uart.sv @@ -0,0 +1,84 @@ +`include "utils.svh" + +module jtag_uart + #( INSTANCE = 0 + + , RX_FIFO_BITS = 6 + , TX_FIFO_BITS = 6 + ) + ( input bit clk + , input bit reset + + , input bit rx_ready `define rx_ready `past(rx_ready) + , output bit rx_valid + , output bit [7:0] rx_data + + , output bit tx_ready + , input bit tx_valid `define tx_valid `past(tx_valid) + , input bit [7:0] tx_data `define tx_data `past(tx_data) + ); + +`ifdef SYNTHESIS + +alt_jtag_atlantic + #( .INSTANCE_ID(INSTANCE) + , .LOG2_RXFIFO_DEPTH(RX_FIFO_BITS) + , .LOG2_TXFIFO_DEPTH(TX_FIFO_BITS) + , .SLD_AUTO_INSTANCE_INDEX("NO") + ) real_jtag + ( .clk(clk) + , .rst_n(!reset) + , .r_dat(tx_data) + , .r_val(tx_valid) + , .r_ena(tx_ready) + , .t_dat(rx_data) + , .t_dav(rx_ready) + , .t_ena(rx_valid) + ); + +`else + +bit [7:0] sim_rx_rom [0:(1<<16)-1]; +initial $readmemh("mem/jtag_uart.hex", sim_rx_rom); + +bit [15:0] sim_rx_addr; + +bit tx_b_valid; +bit [7:0] tx_b_data; + +always_ff @(posedge clk) begin + if (reset) begin + rx_valid = 0; + tx_ready = 0; + sim_rx_addr = 0; + tx_b_valid = 0; + end else begin + automatic bit [7:0] sim_rx_data = sim_rx_rom[sim_rx_addr]; + + // RX logic + if (`rx_ready) rx_valid = 0; + if (!rx_valid && (sim_rx_data != 0)) begin +`ifdef JTAG_UART_LOCAL_ECHO + $write("%s", sim_rx_data); +`endif + rx_valid = 1; + rx_data = sim_rx_data; + sim_rx_addr = sim_rx_addr + 1; + end + + // TX logic + if (tx_ready && `tx_valid) begin + tx_b_valid = 1; + tx_b_data = `tx_data; + end + if (tx_b_valid) begin + $write("%s", tx_b_data); + tx_b_valid = 0; + end + tx_ready = !tx_b_valid; + end +end + +`endif + +endmodule 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 diff --git a/hdl/top.sv b/hdl/top.sv new file mode 100644 index 0000000..33c1fc5 --- /dev/null +++ b/hdl/top.sv @@ -0,0 +1,152 @@ +`include "utils.svh" + +module top + #( FIB_BITS = 16 + , FIB_BASE = 10 + , FIB_DIGITS = 5 + + , ROM_BITS = 8 + ) + ( input bit clk // verilator public + , input bit reset_n // verilator public + ); + +bit reset; +assign reset = !reset_n; + +bit [7:0] rom [0:(1<