add sim tests
diff --git a/verilog/rtl/0001-fix-make-targets.patch b/verilog/rtl/0001-fix-make-targets.patch new file mode 100644 index 0000000..95cd1b8 --- /dev/null +++ b/verilog/rtl/0001-fix-make-targets.patch
@@ -0,0 +1,162 @@ +From f9f5d6804186bab5b9f44c65bd7986cec5c77840 Mon Sep 17 00:00:00 2001 +From: roman3017 <rbacik@hotmail.com> +Date: Tue, 20 Dec 2022 20:19:40 -0800 +Subject: [PATCH] fix make targets + +make PROJ=soc lint +make PROJ=soc sim +make PROJ=soc wave +make PROJ=soc clean all +make PROJ=soc prog +--- + examples/TinyFPGA-BX/OSS_CAD_Suite/Makefile | 6 +++--- + examples/common/hdl/sim_tasks.v | 2 +- + examples/common/hdl/usb_rx_tasks.v | 8 +++++--- + examples/common/hdl/usb_tasks.v | 2 +- + usb_cdc/sie.v | 4 ++-- + 5 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/examples/TinyFPGA-BX/OSS_CAD_Suite/Makefile b/examples/TinyFPGA-BX/OSS_CAD_Suite/Makefile +index 057b70c..1a31220 100644 +--- a/examples/TinyFPGA-BX/OSS_CAD_Suite/Makefile ++++ b/examples/TinyFPGA-BX/OSS_CAD_Suite/Makefile +@@ -1,6 +1,6 @@ + + # override the default with: make all PROJ=loopback +-PROJ = demo ++PROJ ?= demo + + PIN_DEF = pins.pcf + DEVICE = lp8k +@@ -42,7 +42,7 @@ prog: $(OUT_DIR)/$(PROJ).bin + tinyprog -p $< + + lint: $(HDL_FILES) +- verilator --lint-only --default-language 1364-2001 -Wall -Wno-UNUSED -Wno-UNDRIVEN -Wno-TIMESCALEMOD -DBLACKBOX -DNO_ICE40_DEFAULT_ASSIGNMENTS --top $(PROJ) $(INC_DIRS) -v $(ICE40_LIB) $^ ++ verilator --lint-only --default-language 1364-2001 -Wall -Wno-UNUSED -Wno-UNDRIVEN -Wno-TIMESCALEMOD -DBLACKBOX -DNO_ICE40_DEFAULT_ASSIGNMENTS $(INC_DIRS) -v $(ICE40_LIB) $^ + + $(OUT_DIR)/cells_sim.v: + patch $(ICE40_LIB) -o $(OUT_DIR)/cells_sim.v < ../../common/hdl/ice40/cells_sim.v.patch +@@ -56,7 +56,7 @@ $(OUT_DIR)/%.fst: $(OUT_DIR)/%.vvp + sim: $(OUT_DIR)/$(PROJ).fst + + $(OUT_DIR)/%.xml: $(HDL_FILES) $(TB_HDL_FILES) | $(OUT_DIR) $(OUT_DIR)/cells_sim.v +- verilator -xml-only --bbox-unsup --bbox-sys -Wno-lint -Wno-TIMESCALEMOD -Wno-STMTDLY -Wno-INFINITELOOP -DBLACKBOX -DNO_ICE40_DEFAULT_ASSIGNMENTS --top tb_$(PROJ) $(INC_DIRS) -v $(OUT_DIR)/cells_sim.v $^ --xml-output $@ ++ verilator -xml-only --bbox-unsup --bbox-sys -Wno-lint -Wno-TIMESCALEMOD -Wno-STMTDLY -Wno-INFINITELOOP -DBLACKBOX -DNO_ICE40_DEFAULT_ASSIGNMENTS $(INC_DIRS) -v $(OUT_DIR)/cells_sim.v $^ --xml-output $@ + + $(OUT_DIR)/%.stems: $(OUT_DIR)/%.xml + xml2stems $< $@ +diff --git a/examples/common/hdl/sim_tasks.v b/examples/common/hdl/sim_tasks.v +index 6fbcd61..8df33cc 100644 +--- a/examples/common/hdl/sim_tasks.v ++++ b/examples/common/hdl/sim_tasks.v +@@ -52,6 +52,6 @@ + if (end_ms > 0) \ + $write(" (%3d%%)", 100*time_ms/end_ms); \ + $write("\015"); \ +- $fflush(32'h8000_0001); // flush STDOUT \ ++ $fflush(32'h8000_0001); \ + end \ + end +diff --git a/examples/common/hdl/usb_rx_tasks.v b/examples/common/hdl/usb_rx_tasks.v +index f3f6db5..ade5c4b 100644 +--- a/examples/common/hdl/usb_rx_tasks.v ++++ b/examples/common/hdl/usb_rx_tasks.v +@@ -10,6 +10,7 @@ localparam [3:0] PID_OUT = 4'b0001, + PID_NAK = 4'b1010, + PID_STALL = 4'b1110; + ++localparam [4:0] POLY5 = 5'b00101; + function automatic [4:0] crc5; + input [MAX_BITS-1:0] data; + input integer bits; +@@ -26,6 +27,7 @@ function automatic [4:0] crc5; + end + endfunction + ++localparam [15:0] POLY16 = 16'h8005; + function automatic [15:0] crc16; + input [8*MAX_BYTES-1:0] data; + input integer bytes; +@@ -44,12 +46,12 @@ function automatic [15:0] crc16; + end + endfunction + ++localparam real STABLE_RATIO = 0.5; // stable time / bit_time + task automatic wait_bit + ( + input time bit_time, + input integer timeout // number of bit_time periods + ); +- localparam real STABLE_RATIO = 0.5; // stable time / bit_time + time start_time; + time wait_time; + reg exit; +@@ -210,6 +212,8 @@ task automatic raw_packet_rx + end + endtask + ++localparam [4:0] POLY5_RESIDUAL = 5'b01100; ++localparam [15:0] POLY16_RESIDUAL = 16'b1000000000001101; + task automatic packet_rx + ( + output [3:0] pid, +@@ -221,8 +225,6 @@ task automatic packet_rx + input time bit_time, + input integer timeout // number of bit_time periods + ); +- localparam [4:0] POLY5_RESIDUAL = 5'b01100; +- localparam [15:0] POLY16_RESIDUAL = 16'b1000000000001101; + reg [8*MAX_BYTES-1:0] raw_data; + integer raw_bytes; + integer i; +diff --git a/examples/common/hdl/usb_tasks.v b/examples/common/hdl/usb_tasks.v +index 9f35ffc..8488af7 100644 +--- a/examples/common/hdl/usb_tasks.v ++++ b/examples/common/hdl/usb_tasks.v +@@ -358,6 +358,7 @@ task automatic test_sof_crc_error + end + endtask + ++localparam PACKET_TIMEOUT = 6; // TRSPIPD1 (USB2.0 Tab.7-14 pag.188) + task automatic test_data_out + ( + input [6:0] address, +@@ -370,7 +371,6 @@ task automatic test_data_out + input time wait_time, + inout [15:0] dataout_toggle + ); +- localparam PACKET_TIMEOUT = 6; // TRSPIPD1 (USB2.0 Tab.7-14 pag.188) + reg zlp; + reg [3:0] packet_pid; + time start_timeout; +diff --git a/usb_cdc/sie.v b/usb_cdc/sie.v +index 58390c6..c808882 100644 +--- a/usb_cdc/sie.v ++++ b/usb_cdc/sie.v +@@ -122,9 +122,9 @@ module sie + end + endfunction + ++ localparam [4:0] POLY5 = 5'b00101; + function [4:0] crc5; + input [10:0] data; +- localparam [4:0] POLY5 = 5'b00101; + reg [3:0] i; + begin + crc5 = 5'b11111; +@@ -147,10 +147,10 @@ module sie + end + endfunction + ++ localparam [15:0] POLY16 = 16'h8005; + function [15:0] crc16; + input [7:0] data; + input [15:0] crc; +- localparam [15:0] POLY16 = 16'h8005; + reg [3:0] i; + begin + crc16 = crc; +-- +2.34.1 +
diff --git a/verilog/rtl/fpga/Makefile b/verilog/rtl/fpga/Makefile index e241c45..d71710d 100644 --- a/verilog/rtl/fpga/Makefile +++ b/verilog/rtl/fpga/Makefile
@@ -27,8 +27,13 @@ FPGA_TYPE = lp FPGA_PACK = cm81 +CLK_MHZ = 48 + all: sint time +pll.v: + icepll -i 16 -o $(CLK_MHZ) -m -f $@ + sim: $(NAME)_tb.vcd gtkwave $< $(<:.vcd=.gtkw) & @@ -58,7 +63,7 @@ yosys -p "$(foreach file,$^,read_verilog $(file);)" -p "synth_ice40 -json $@" $^ .json.asc: - nextpnr-ice40 --$(FPGA_TYPE)$(FPGA_SIZE) --package $(FPGA_PACK) --pcf-allow-unconstrained --pcf $(PIN_DEF) --json $< --asc $@ + nextpnr-ice40 --$(FPGA_TYPE)$(FPGA_SIZE) --freq $(CLK_MHZ) --package $(FPGA_PACK) --pcf-allow-unconstrained --pcf $(PIN_DEF) --json $< --asc $@ .asc.bin: icepack $< $@
diff --git a/verilog/rtl/fpga/README.md b/verilog/rtl/fpga/README.md index 3fc86c5..32fd384 100644 --- a/verilog/rtl/fpga/README.md +++ b/verilog/rtl/fpga/README.md
@@ -1,6 +1,29 @@ +# Similation tests + +## UART + +```sh +cd verilog/rtl/ +iverilog test_uart.v verilog-uart/rtl/uart.v verilog-uart/rtl/uart_rx.v verilog-uart/rtl/uart_tx.v -o test_uart.out + +./test_uart.out +gtkwave test_uart.vcd +``` + +## USB + +```sh +cd verilog/rtl/usb_cdc/ +git apply ../0001-fix-make-targets.patch + +cd examples/TinyFPGA-BX/OSS_CAD_Suite/ +make PROJ=soc clean sim +make PROJ=soc wave +``` + # FPGA tests -Use TinyFPGA to test. +Use TinyFPGA_BX to test. ## USB @@ -16,9 +39,9 @@ minicom -D /dev/ttyACM0 ``` -## USB2TTL +## USB2UART -Attach another USB2TTL to pins 4,5 and see characters being passed between. +Attach another USB2UART to the first three pins on TinyFPGA_BX: GND, 1(RX), and 2(TX). One should see characters being passed between. ```sh tinyprog -l
diff --git a/verilog/rtl/test_uart.v b/verilog/rtl/test_uart.v new file mode 100644 index 0000000..1b54548 --- /dev/null +++ b/verilog/rtl/test_uart.v
@@ -0,0 +1,161 @@ +/* + * Usage: + * iverilog test_uart.v ../rtl/uart.v ../rtl/uart_rx.v ../rtl/uart_tx.v -o test_uart.out + * ./test_uart.out + * gtkwave test_uart.vcd [test_uart.gtkw] + */ + +`timescale 1 ns / 1 ps + +module test_uart; + +// Testbench uses a 48 MHz clock +// Want to interface to 115200 baud UART +// 10000000 / 115200 = 87 Clocks Per Bit. +parameter c_CLOCK_MHZ = 48; +parameter c_UART_SPEED = 115200; + +parameter c_CLOCK_PERIOD_NS = 1000/c_CLOCK_MHZ; +parameter c_CLKS_PER_BIT = c_CLOCK_MHZ*1000000/c_UART_SPEED; +parameter c_CLKS_PER_BYTE = (c_CLKS_PER_BIT+7)/8; +parameter c_BIT_PERIOD = c_CLKS_PER_BIT*c_CLOCK_PERIOD_NS; + +integer i; +integer j; + +reg [15:0] prescale = c_CLKS_PER_BYTE; +reg clk = 0; +reg rst = 0; + +// Inputs +reg m_axis_tready = 0; +reg rxd = 1; +// Outputs +wire [7:0] m_axis_tdata; +wire m_axis_tvalid; +wire rx_busy; +wire rx_overrun_error; +wire rx_frame_error; + +// Inputs +reg [7:0] s_axis_tdata = 8'd0; +reg s_axis_tvalid = 1'b0; +reg [9:0] r_Tx_Data = 0; +// Outputs +wire s_axis_tready; +wire txd; +wire tx_busy; + +// Write a byte to RX pin +task UART_WRITE_RX_AND_RCV; + input [7:0] i_Data; + integer ii; +begin + m_axis_tready <= 1; + + // Write Start Bit + #(c_BIT_PERIOD) rxd <= 1'b0; + + // Write Data + for (ii=0; ii<8; ii=ii+1) + begin + #(c_BIT_PERIOD) rxd <= i_Data[ii]; + end + + // Write Stop Bit + #(c_BIT_PERIOD) rxd <= 1'b1; + + @(posedge m_axis_tvalid); +end +endtask + +// Send a byte and read back data from TX pin +task UART_SEND_AND_READ_TX; + output [9:0] o_Data; + integer ii; +begin + // Send byte + @(posedge clk); + s_axis_tvalid <= 1'b1; + @(posedge clk); + s_axis_tvalid <= 1'b0; + + @(posedge tx_busy); + + // Read Data + for (ii=0; ii<10; ii=ii+1) + begin + #(c_BIT_PERIOD) o_Data[ii] <= txd; + end + + @(posedge s_axis_tready); +end +endtask + +always +#(c_CLOCK_PERIOD_NS/2) clk <= !clk; + +initial begin + $dumpfile("test_uart.vcd"); + $dumpvars(0, test_uart); + + // Exercise Rx + j=0; + for (i=0; i<256; i=i+1) + begin + UART_WRITE_RX_AND_RCV(i); + if (m_axis_tdata == i) + j=j+1; + else + $display("RX Test Failed - Incorrect Byte Received"); + end + if (j == 256) + $display("RX Test Passed - Correct Bytes Received"); + + // Exercise Tx + j=0; + for (i=0; i<256; i=i+1) + begin + s_axis_tdata <= i; + UART_SEND_AND_READ_TX(r_Tx_Data); + // Check that the correct byte was sent + if (r_Tx_Data[8:1] == i) + j=j+1; + else + $display("TX Test Failed - Incorrect Byte Sent"); + end + if (j == 256) + $display("TX Test Passed - Correct Bytes Sent"); + + $finish; +end + +uart #( + .DATA_WIDTH(8) +) +UUT ( + .clk(clk), + .rst(rst), + // axi output + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + // input + .rxd(rxd), + // status + .rx_busy(rx_busy), + .rx_overrun_error(rx_overrun_error), + .rx_frame_error(rx_frame_error), + // axi input + .s_axis_tdata(s_axis_tdata), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + // output + .txd(txd), + // status + .tx_busy(tx_busy), + // configuration + .prescale(prescale) +); + +endmodule