add fpga test
diff --git a/verilog/rtl/fpga/Makefile b/verilog/rtl/fpga/Makefile new file mode 100644 index 0000000..555204e --- /dev/null +++ b/verilog/rtl/fpga/Makefile
@@ -0,0 +1,66 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Usage: +# make clean all +# make prog + +NAME = fpga_top +DEPS = \ +../usb_cdc/usb_cdc/phy_tx.v \ +../usb_cdc/usb_cdc/phy_rx.v \ +../usb_cdc/usb_cdc/sie.v \ +../usb_cdc/usb_cdc/ctrl_endp.v \ +../usb_cdc/usb_cdc/in_fifo.v \ +../usb_cdc/usb_cdc/out_fifo.v \ +../usb_cdc/usb_cdc/bulk_endp.v \ +../usb_cdc/usb_cdc/usb_cdc.v \ +../usb_cdc/examples/common/hdl/prescaler.v \ +../usb_cdc/examples/common/hdl/fifo_if.v \ +../usb_cdc/examples/TinyFPGA-BX/hdl/soc/app.v +PIN_DEF = fpga_pins.pcf + +# TinyFPGA-BX +FPGA_SIZE = 8k +FPGA_TYPE = hx +FPGA_PACK = cm81 + +all: sint + +sim: $(NAME)_tb.vcd + gtkwave $< $(<:.vcd=.gtkw) & + +$(NAME)_tb.vcd: $(NAME).v $(DEPS) $(NAME)_tb.v + +sint: $(NAME).bin + +$(NAME).json: $(NAME).v $(DEPS) + +$(NAME).asc: $(NAME).json $(PIN_DEF) + +prog: $(NAME).bin + tinyprog -p $< + +time: $(NAME).rpt + +.SUFFIXES: .asc .bin .json .v .vcd .rpt + +.asc.rpt: + icetime -d $(FPGA_TYPE)$(FPGA_SIZE) -P $(FPGA_PACK) -mtr $@ $^ + +.v.vcd: + iverilog $^ -o $(@:.vcd=.out) + ./$(@:.vcd=.out) + +.v.json: + yosys -p "synth_ice40 -json $@" $^ + +.json.asc: + nextpnr-ice40 --$(FPGA_TYPE)$(FPGA_SIZE) --package $(FPGA_PACK) --pcf-allow-unconstrained --pcf $(PIN_DEF) --json $< --asc $@ + +.asc.bin: + icepack $< $@ + +clean: + rm -f *.bin *.asc *.json *.out *.vcd *.rpt + +.PHONY: all sim sint prog clean time
diff --git a/verilog/rtl/fpga/README.md b/verilog/rtl/fpga/README.md new file mode 100644 index 0000000..a3bb582 --- /dev/null +++ b/verilog/rtl/fpga/README.md
@@ -0,0 +1,14 @@ +# FPGA tests + +Use TinyFPGA to test. + +## USB + +```sh +cd ../usb_cdc/examples/TinyFPGA-BX/OSS_CAD_Suite/ +tinyprog -l +make all PROJ=soc +make prog PROJ=soc +minicom -D /dev/ttyACM0 +``` +
diff --git a/verilog/rtl/fpga/fpga_pins.pcf b/verilog/rtl/fpga/fpga_pins.pcf new file mode 100644 index 0000000..3674bae --- /dev/null +++ b/verilog/rtl/fpga/fpga_pins.pcf
@@ -0,0 +1,9 @@ +# ############################################################################## +# TinyFPGA BX +# ############################################################################## + +set_io usb_pu A3 +set_io usb_n A4 +set_io usb_p B4 +set_io led B3 +set_io clk B2
diff --git a/verilog/rtl/fpga/fpga_top.v b/verilog/rtl/fpga/fpga_top.v new file mode 100644 index 0000000..67da9e0 --- /dev/null +++ b/verilog/rtl/fpga/fpga_top.v
@@ -0,0 +1,176 @@ + +module soc + ( + input clk, // 16MHz Clock + output led, // User LED ON=1, OFF=0 + inout usb_p, // USB+ + inout usb_n, // USB- + output usb_pu // USB 1.5kOhm Pullup EN + ); + + localparam BIT_SAMPLES = 'd4; + localparam [6:0] DIVF = 12*BIT_SAMPLES-1; + + wire clk_pll; + wire clk_1mhz; + wire clk_2mhz; + wire clk_4mhz; + wire clk_8mhz; + wire lock; + wire dp_pu; + wire dp_rx; + wire dn_rx; + wire dp_tx; + wire dn_tx; + wire tx_en; + wire [7:0] out_data; + wire out_valid; + wire in_ready; + wire [7:0] in_data; + wire in_valid; + wire out_ready; + + // if FEEDBACK_PATH = SIMPLE: + // clk_freq = (ref_freq * (DIVF + 1)) / (2**DIVQ * (DIVR + 1)); + SB_PLL40_CORE #(.DIVR(4'd0), + .DIVF(DIVF), + .DIVQ(3'd4), + .FILTER_RANGE(3'b001), + .FEEDBACK_PATH("SIMPLE"), + .DELAY_ADJUSTMENT_MODE_FEEDBACK("FIXED"), + .FDA_FEEDBACK(4'b0000), + .DELAY_ADJUSTMENT_MODE_RELATIVE("FIXED"), + .FDA_RELATIVE(4'b0000), + .SHIFTREG_DIV_MODE(2'b00), + .PLLOUT_SELECT("GENCLK"), + .ENABLE_ICEGATE(1'b0)) + u_pll (.REFERENCECLK(clk), // 16MHz + .PLLOUTCORE(), + .PLLOUTGLOBAL(clk_pll), // 48MHz + .EXTFEEDBACK(1'b0), + .DYNAMICDELAY(8'd0), + .LOCK(lock), + .BYPASS(1'b0), + .RESETB(1'b1), + .SDI(1'b0), + .SDO(), + .SCLK(1'b0), + .LATCHINPUTVALUE(1'b1)); + + prescaler u_prescaler (.clk_i(clk), + .rstn_i(lock), + .clk_div16_o(clk_1mhz), + .clk_div8_o(clk_2mhz), + .clk_div4_o(clk_4mhz), + .clk_div2_o(clk_8mhz)); + + reg [1:0] rstn_sync; + + wire rstn; + + assign rstn = rstn_sync[0]; + + always @(posedge clk_1mhz or negedge lock) begin + if (~lock) begin + rstn_sync <= 2'd0; + end else begin + rstn_sync <= {1'b1, rstn_sync[1]}; + end + end + + reg [20:0] up_cnt; + reg [1:0] sleep_sq; + + wire sleep; + + always @(posedge clk_1mhz or negedge rstn) begin + if (~rstn) begin + up_cnt <= 'd0; + sleep_sq <= 2'b00; + end else begin + sleep_sq <= {sleep, sleep_sq[1]}; + if (up_cnt[20] == 1'b0) + up_cnt <= up_cnt + 1; + else if (~sleep_sq[0]) + up_cnt <= 21'hE0000; + end + end + + assign led = ~dp_pu | ~up_cnt[20]; + + app u_app (.clk_i(clk_2mhz), + .rstn_i(rstn), + .sleep_o(sleep), + .out_data_i(out_data), + .out_valid_i(out_valid), + .in_ready_i(in_ready), + .out_ready_o(out_ready), + .in_data_o(in_data), + .in_valid_o(in_valid)); + + usb_cdc #(.VENDORID(16'h1D50), + .PRODUCTID(16'h6130), + .IN_BULK_MAXPACKETSIZE('d8), + .OUT_BULK_MAXPACKETSIZE('d8), + .BIT_SAMPLES(BIT_SAMPLES), + .USE_APP_CLK(1), + .APP_CLK_RATIO(BIT_SAMPLES*12/2)) // BIT_SAMPLES * 12MHz / 2MHz + u_usb_cdc (.frame_o(), + .configured_o(), + .app_clk_i(clk_2mhz), + .clk_i(clk_pll), + .rstn_i(rstn), + .out_ready_i(out_ready), + .in_data_i(in_data), + .in_valid_i(in_valid), + .dp_rx_i(dp_rx), + .dn_rx_i(dn_rx), + .out_data_o(out_data), + .out_valid_o(out_valid), + .in_ready_o(in_ready), + .dp_pu_o(dp_pu), + .tx_en_o(tx_en), + .dp_tx_o(dp_tx), + .dn_tx_o(dn_tx)); + + SB_IO #(.PIN_TYPE(6'b101001), + .PULLUP(1'b0)) + u_usb_p (.PACKAGE_PIN(usb_p), + .OUTPUT_ENABLE(tx_en), + .D_OUT_0(dp_tx), + .D_IN_0(dp_rx), + .D_OUT_1(1'b0), + .D_IN_1(), + .CLOCK_ENABLE(1'b0), + .LATCH_INPUT_VALUE(1'b0), + .INPUT_CLK(1'b0), + .OUTPUT_CLK(1'b0)); + + SB_IO #(.PIN_TYPE(6'b101001), + .PULLUP(1'b0)) + u_usb_n (.PACKAGE_PIN(usb_n), + .OUTPUT_ENABLE(tx_en), + .D_OUT_0(dn_tx), + .D_IN_0(dn_rx), + .D_OUT_1(1'b0), + .D_IN_1(), + .CLOCK_ENABLE(1'b0), + .LATCH_INPUT_VALUE(1'b0), + .INPUT_CLK(1'b0), + .OUTPUT_CLK(1'b0)); + + // drive usb_pu to 3.3V or to high impedance + SB_IO #(.PIN_TYPE(6'b101001), + .PULLUP(1'b0)) + u_usb_pu (.PACKAGE_PIN(usb_pu), + .OUTPUT_ENABLE(dp_pu), + .D_OUT_0(1'b1), + .D_IN_0(), + .D_OUT_1(1'b0), + .D_IN_1(), + .CLOCK_ENABLE(1'b0), + .LATCH_INPUT_VALUE(1'b0), + .INPUT_CLK(1'b0), + .OUTPUT_CLK(1'b0)); + +endmodule