summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineering.com>2019-04-28 18:55:21 -0500
committerTimothy Pearson <tpearson@raptorengineering.com>2019-04-28 18:55:21 -0500
commite1a4f6f17e99d4e8f9bd45743f449a84ae02bb0a (patch)
tree9292db2b1e5d45476a5075ffbb12dfa99e84ce0c
parente1e7c9e49df6b95a09a05c9256faf55d62f36985 (diff)
downloadulab-e1a4f6f17e99d4e8f9bd45743f449a84ae02bb0a.tar.gz
ulab-e1a4f6f17e99d4e8f9bd45743f449a84ae02bb0a.zip
Add intial version of Lattice remote FPGA interface
Minor tweaks to core remote FPGA file to eliminate Yosys warnings and reduce design size
-rw-r--r--fpga/serial/common/remote_access.v31
-rw-r--r--fpga/serial/lattice/eb85/Makefile123
-rw-r--r--fpga/serial/lattice/eb85/control_fpga.pcf66
-rw-r--r--fpga/serial/lattice/eb85/main.v98
l---------fpga/serial/lattice/eb85/remote_access.v1
-rw-r--r--fpga/serial/lattice/eb85/remote_access_defines.v8
-rw-r--r--fpga/serial/xilinx/digilent/spartan_3/remote_access_defines.v8
-rw-r--r--fpga/serial/xilinx/digilent/spartan_3e/remote_access_defines.v8
-rw-r--r--fpga/serial/xilinx/digilent/spartan_6/remote_access_defines.v8
9 files changed, 350 insertions, 1 deletions
diff --git a/fpga/serial/common/remote_access.v b/fpga/serial/common/remote_access.v
index 3a52885..e30006f 100644
--- a/fpga/serial/common/remote_access.v
+++ b/fpga/serial/common/remote_access.v
@@ -18,6 +18,9 @@
// sales@raptorengineering.com
//
//////////////////////////////////////////////////////////////////////////////////
+
+`include "remote_access_defines.v"
+
module remote_access(
input main_fifty_clock, // 50MHz clock in
input [3:0] remote_access_4_bit_output, // 4 bit output from the user program to remote access client
@@ -38,13 +41,17 @@ module remote_access(
input [5:0] lcd_data_in_address,
input [7:0] lcd_data_in_data,
input lcd_data_in_enable,
+`ifdef SYSTEM_HAS_SRAM
input sram_wren_in,
input sram_clock_in,
input [7:0] sram_data_in,
input [(RAM_ADDR_BITS-1):0] sram_address_in,
output [7:0] sram_data_out,
+`endif
output sram_available,
+`ifdef SYSTEM_HAS_SRAM
input sram_processing_done,
+`endif
input [7:0] led_segment_bus,
input [3:0] led_digit_select,
@@ -55,6 +62,10 @@ module remote_access(
output remote_access_lcd_enable_out);
parameter RAM_ADDR_BITS = 14;
+
+`ifndef SYSTEM_HAS_SRAM
+ reg sram_processing_done = 1'b1;
+`endif
reg [7:0] remote_access_4_bit_input_reg;
reg [7:0] remote_access_8_bit_input_reg;
@@ -184,7 +195,7 @@ module remote_access(
led_display_bytes[3] = 255;
end
end
-
+
//-----------------------------------------------------------------------------------
//
// Instantiate the data storage RAM for signal processing
@@ -202,6 +213,7 @@ module remote_access(
reg [(RAM_ADDR_BITS-1):0] data_storage_addra_reg;
reg data_storage_write_enable_reg;
+`ifdef SYSTEM_HAS_SRAM
data_storage #(RAM_ADDR_BITS) data_storage(.clka(data_storage_clka), .dina(data_storage_dina), .addra(data_storage_addra),
.wea(data_storage_write_enable), .douta(data_storage_data_out));
@@ -211,6 +223,7 @@ module remote_access(
assign data_storage_write_enable = (data_storage_remote_enable) ? data_storage_write_enable_reg : sram_wren_in;
assign sram_data_out = data_storage_data_out;
+`endif
// -----------------------------------------------------------------------------------------------
//
@@ -396,11 +409,17 @@ module remote_access(
if ((transmit_dsp_status == 1) && (transmit_dsp_rx_complete == 0) && (transmit_dsp_status_done == 0)) begin
if (transmit_dsp_status_holdoff == 0) begin
transmit_dsp_status_holdoff = 1;
+`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0;
data_storage_addra_reg = 0; // Initial data value
+`endif
end else begin
+`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0;
TxD_data = data_storage_data_out;
+`else
+ TxD_data = 0;
+`endif
TxD_start = 1;
tx_toggle = 1;
@@ -409,8 +428,10 @@ module remote_access(
data_storage_addra_reg = transmit_dsp_status_counter[(RAM_ADDR_BITS-1):0];
if (transmit_dsp_status_counter >= (2**RAM_ADDR_BITS)) begin
transmit_dsp_status_done = 1;
+`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 1'bz;
data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}};
+`endif
end
end
end
@@ -581,7 +602,9 @@ module remote_access(
data_write_timer = data_write_timer - 1;
end else begin
if (data_write_timer == 1) begin
+`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0;
+`endif
data_write_timer = 0;
end
end
@@ -607,9 +630,11 @@ module remote_access(
// DSP input data
if (dsp_update_counter < (2**RAM_ADDR_BITS)) begin
data_storage_remote_enable = 1;
+`ifdef SYSTEM_HAS_SRAM
data_storage_addra_reg = dsp_update_counter[(RAM_ADDR_BITS-1):0];
data_storage_dina_reg = serial_rx_data_reg;
data_storage_write_enable_reg = 1;
+`endif
data_write_timer = 3;
dsp_update_counter = dsp_update_counter + 1;
@@ -620,11 +645,15 @@ module remote_access(
if (dsp_update_counter >= (2**RAM_ADDR_BITS)) begin
next_byte_is_command = 0;
+`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0;
+`endif
data_storage_remote_enable = 0;
sram_available_reg = 1;
+`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 1'bz;
data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}};
+`endif
waiting_on_dsp_processing = 1;
transmit_dsp_rx_complete = 1;
next_byte_is_command_prev_command = 0;
diff --git a/fpga/serial/lattice/eb85/Makefile b/fpga/serial/lattice/eb85/Makefile
new file mode 100644
index 0000000..d00e5a5
--- /dev/null
+++ b/fpga/serial/lattice/eb85/Makefile
@@ -0,0 +1,123 @@
+# This file is part of the Universal Laboratory (uLab)
+#
+# © 2017 - 2019 Raptor Engineering, LLC
+# All Rights Reserved
+#
+# Licensed under the terms of the AGPL v3
+
+MAX_FPGA_ROUTE_PASSES = 100
+
+SOURCE_FILES = main.v remote_access.v
+
+# Default seed
+#ARACHNE_PNR_SEED = 1
+
+# Selected seed from fastest placement search
+# NOTE: Must be updated every time the Verilog source is modified, no matter how trivially!
+# Does not need to be updated if firmware program (C) sources are modified
+# 0 automatically uses the best placement result
+ARACHNE_PNR_SEED = 0
+#ARACHNE_PNR_SEED = 1
+
+YOSYS_ICE40_SIM_LIB = $(shell yosys-config --datdir/ice40/cells_sim.v)
+
+.PRECIOUS: control_fpga_%.int
+
+control_fpga_%.tmg: control_fpga_%.int control_fpga.pcf
+ echo "Total path delay: inf ns (0.0 MHz)" > $@
+ -icetime -tmd hx8k -p control_fpga.pcf -P ct256 $< > $@ 2>&1
+
+control_fpga_%.int: control_fpga.blif control_fpga.pcf
+ echo "" > $@
+ -arachne-pnr -s $* -d 8k -P ct256 -m $(MAX_FPGA_ROUTE_PASSES) -p control_fpga.pcf $< -o $@
+
+control_fpga.int: control_fpga_1.tmg control_fpga_2.tmg control_fpga_3.tmg control_fpga_4.tmg control_fpga_5.tmg control_fpga_6.tmg control_fpga_7.tmg control_fpga_8.tmg control_fpga_9.tmg \
+ control_fpga_10.tmg control_fpga_11.tmg control_fpga_12.tmg control_fpga_13.tmg control_fpga_14.tmg control_fpga_15.tmg control_fpga_16.tmg control_fpga_17.tmg control_fpga_18.tmg control_fpga_19.tmg \
+ control_fpga_20.tmg control_fpga_21.tmg control_fpga_22.tmg control_fpga_23.tmg control_fpga_24.tmg control_fpga_25.tmg control_fpga_26.tmg control_fpga_27.tmg control_fpga_28.tmg control_fpga_29.tmg \
+ control_fpga_30.tmg control_fpga_31.tmg control_fpga_32.tmg control_fpga_33.tmg control_fpga_34.tmg control_fpga_35.tmg control_fpga_36.tmg control_fpga_37.tmg control_fpga_38.tmg control_fpga_39.tmg \
+ control_fpga_40.tmg control_fpga_41.tmg control_fpga_42.tmg control_fpga_43.tmg control_fpga_44.tmg control_fpga_45.tmg control_fpga_46.tmg control_fpga_47.tmg control_fpga_48.tmg control_fpga_49.tmg \
+ control_fpga_50.tmg control_fpga_51.tmg control_fpga_52.tmg control_fpga_53.tmg control_fpga_54.tmg control_fpga_55.tmg control_fpga_56.tmg control_fpga_57.tmg control_fpga_58.tmg control_fpga_59.tmg \
+ control_fpga_60.tmg control_fpga_61.tmg control_fpga_62.tmg control_fpga_63.tmg control_fpga_64.tmg
+ BEST_TRIAL=0; \
+ BEST_TRIAL_RESULT=0; \
+ for trial in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64; do \
+ CURRENT_TRIAL_RESULT=$$(cat control_fpga_$${trial}.tmg | grep "Total path delay" | awk '{print $$6}' | sed 's/(//g'); \
+ if [ "$$CURRENT_TRIAL_RESULT" != "" ]; then \
+ echo "control_fpga_$${trial}.tmg : $$CURRENT_TRIAL_RESULT"; \
+ COMPARISON_RESULT=$$(echo "$$CURRENT_TRIAL_RESULT > $$BEST_TRIAL_RESULT" | bc -l); \
+ if [ $$COMPARISON_RESULT -eq 1 ]; then \
+ BEST_TRIAL=control_fpga_$${trial}.tmg; \
+ BEST_TRIAL_RESULT=$$CURRENT_TRIAL_RESULT; \
+ fi; \
+ fi; \
+ done; \
+ if [ "$$BEST_TRIAL_RESULT" -eq "0" ]; then \
+ echo "Unable to determine fastest result. Selecting first run...."; \
+ BEST_TRIAL=control_fpga_1.tmg; \
+ BEST_TRIAL_RESULT=0; \
+ fi; \
+ echo "Fastest result: $$BEST_TRIAL : $$BEST_TRIAL_RESULT"; \
+ cp `echo $$BEST_TRIAL | sed 's/\.tmg/\.int/g'` control_fpga.int; \
+ cp $$BEST_TRIAL control_fpga.tmg
+ifneq ($(ARACHNE_PNR_SEED),0)
+ cp control_fpga_$(ARACHNE_PNR_SEED).int control_fpga.int
+ cp control_fpga_$(ARACHNE_PNR_SEED).tmg control_fpga.tmg
+endif
+ cat control_fpga.tmg
+
+control_fpga.ex: control_fpga.int
+ icebox_explain control_fpga.int > control_fpga.ex
+
+control_fpga.blif: $(SOURCE_FILES)
+ yosys -l yosys.log -q -p "synth_ice40 -top control_fpga_top -blif control_fpga.blif" $(SOURCE_FILES)
+
+control_fpga.bin: control_fpga.int
+ icepack control_fpga.int control_fpga.bin
+
+blank.rom:
+ dd if=/dev/zero ibs=1k count=256 | tr "\000" "\377" > blank.rom
+
+control_fpga.rom: blank.rom control_fpga.bin
+ cp blank.rom control_fpga.rom
+ dd if=control_fpga.bin of=control_fpga.rom conv=notrunc
+
+control_fpga_test.vcd: $(SOURCE_FILES) testbench.v
+ rm -f control_fpga_sim
+ rm -f control_fpga.vcd
+ /usr/bin/iverilog -DSIMULATION -o control_fpga_sim $(SOURCE_FILES) testbench.v
+ ./control_fpga_sim
+
+simulate: control_fpga_test.vcd
+
+simulate_view: control_fpga_test.vcd
+ gtkwave control_fpga_test.vcd
+
+all: control_fpga.rom
+
+dump_toolchain_info:
+ -@echo "================================================================================"
+ -@echo "Base system:\t"
+ -@echo -n "Architecture:\t"
+ -@uname -m 2>/dev/null
+ -@echo -n "gcc:\t\t"
+ -@gcc -dumpversion 2>/dev/null
+ -@echo -n "clang:\t\t"
+ -@clang --version 2>/dev/null | head -n 1
+ -@echo "\nFPGA toolchain:"
+ -@echo -n "Icarus verilog:\t"
+ -@iverilog -V 2>/dev/null | head -n 1
+ -@echo -n "Yosys:\t\t"
+ -@yosys -V 2>/dev/null
+ -@echo -n "arachne-pnr:\t"
+ -@arachne-pnr -v 2>/dev/null
+ -@echo "================================================================================"
+
+test: control_fpga.bin
+ iceprog -S control_fpga.bin
+
+flash: control_fpga.bin
+ iceprog control_fpga.bin
+
+clean:
+ rm -f control_fpga.blif control_fpga.ex control_fpga.int control_fpga.tmg control_fpga_*.int control_fpga_*.tmg control_fpga.bin yosys.log
+
diff --git a/fpga/serial/lattice/eb85/control_fpga.pcf b/fpga/serial/lattice/eb85/control_fpga.pcf
new file mode 100644
index 0000000..ddcaaa2
--- /dev/null
+++ b/fpga/serial/lattice/eb85/control_fpga.pcf
@@ -0,0 +1,66 @@
+# This file is part of the Universal Laboratory (uLab)
+#
+# © 2017 - 2019 Raptor Engineering, LLC
+# All Rights Reserved
+#
+# Licensed under the terms of the AGPL v3
+
+# Main system clock
+set_io main_12_mhz_clock J3
+
+# Debug / GPIO connections
+set_io led_bank[7] C3
+set_io led_bank[6] B3
+set_io led_bank[5] C4
+set_io led_bank[4] C5
+set_io led_bank[3] A1
+set_io led_bank[2] A2
+set_io led_bank[1] B4
+set_io led_bank[0] B5
+
+# Guest FPGA interface
+set_io four_bit_output[3] C16
+set_io four_bit_output[2] D16
+set_io four_bit_output[1] E16
+set_io four_bit_output[0] F16
+
+set_io four_bit_input[3] B16
+set_io four_bit_input[2] D14
+set_io four_bit_input[1] D15
+set_io four_bit_input[0] E14
+
+set_io eight_bit_output[7] G16
+set_io eight_bit_output[6] H16
+set_io eight_bit_output[5] J15
+set_io eight_bit_output[4] G14
+set_io eight_bit_output[3] K14
+set_io eight_bit_output[2] K15
+set_io eight_bit_output[1] M16
+set_io eight_bit_output[0] N16
+
+set_io eight_bit_input[7] F15
+set_io eight_bit_input[6] G15
+set_io eight_bit_input[5] H14
+set_io eight_bit_input[4] F14
+set_io eight_bit_input[3] J14
+set_io eight_bit_input[2] K16
+set_io eight_bit_input[1] L16
+set_io eight_bit_input[0] M15
+
+set_io led_segment_bus[7] T1
+set_io led_segment_bus[6] R2
+set_io led_segment_bus[5] R3
+set_io led_segment_bus[4] T5
+set_io led_segment_bus[3] T6
+set_io led_segment_bus[2] T7
+set_io led_segment_bus[1] P8
+set_io led_segment_bus[0] T10
+
+set_io led_digit_select[3] T2
+set_io led_digit_select[2] T3
+set_io led_digit_select[1] R4
+set_io led_digit_select[0] R5
+
+# Serial interface
+set_io serial_input B10
+set_io serial_output B12
diff --git a/fpga/serial/lattice/eb85/main.v b/fpga/serial/lattice/eb85/main.v
new file mode 100644
index 0000000..e736781
--- /dev/null
+++ b/fpga/serial/lattice/eb85/main.v
@@ -0,0 +1,98 @@
+// This file is part of the Universal Laboratory (uLab)
+//
+// © 2017 - 2019 Raptor Engineering, LLC
+// All Rights Reserved
+//
+// Licensed under the terms of the AGPL v3
+
+module control_fpga_top
+ (
+ // Input clock
+ input wire main_12_mhz_clock,
+
+ // Guest FPGA interface
+ input wire [3:0] four_bit_output, // Output from the user program to the remote access module
+ output wire [3:0] four_bit_input, // Input to the user program from the remote access module
+ input wire [7:0] eight_bit_output, // Output from the user program to the remote access module
+ output wire [7:0] eight_bit_input, // Input to the user program from the remote access module
+
+ input wire [7:0] led_segment_bus,
+ input wire [3:0] led_digit_select,
+
+ // Serial interface
+ input wire serial_input,
+ output wire serial_output,
+
+ // On-board diagnostic LEDs
+ output wire [7:0] led_bank
+ );
+
+ parameter RAM_ADDR_BITS = 0;
+
+ // Synthesize 50MHz clock from 12MHz clock
+ wire main_50_mhz_clock;
+ wire pll_locked;
+
+ SB_PLL40_CORE #(
+ .FEEDBACK_PATH("SIMPLE"),
+ .DIVR(4'b0000), // DIVR = 0
+ .DIVF(7'b1000010), // DIVF = 66
+ .DIVQ(3'b100), // DIVQ = 4
+ .FILTER_RANGE(3'b001) // FILTER_RANGE = 1
+ ) system_pll (
+ .LOCK(pll_locked),
+ .RESETB(1'b1),
+ .BYPASS(1'b0),
+ .REFERENCECLK(main_12_mhz_clock),
+ .PLLOUTCORE(main_50_mhz_clock)
+ );
+
+ reg [7:0] diagnostic_led_data = 8'b0;
+
+ wire [15:0] sixteen_bit_output; // Output from the user program to the remote access module
+ wire [15:0] sixteen_bit_input; // Input to the user program from the remote access module
+
+ wire [5:0] lcd_data_in_address;
+ wire [7:0] lcd_data_in_data;
+ wire lcd_data_in_enable;
+
+ assign sixteen_bit_output = 16'b0; // Diable 16 bit input for now
+ //assign led_bank = eight_bit_input; // Mirror input to the LEDs
+ assign led_bank = diagnostic_led_data; // Show diagnostic data on LEDs
+
+ reg [22:0] slow_clock_divider = 23'b0;
+ wire slow_clock;
+ reg [1:0] kr_state = 2'b0;
+ always @(posedge main_12_mhz_clock) begin
+ slow_clock_divider <= slow_clock_divider + 1;
+ end
+ assign slow_clock = slow_clock_divider[22];
+
+ always @(posedge slow_clock) begin
+ kr_state <= kr_state + 1;
+ if (pll_locked) begin
+ case (kr_state)
+ 0: diagnostic_led_data <= 8'b00011000;
+ 1: diagnostic_led_data <= 8'b00100100;
+ 2: diagnostic_led_data <= 8'b01000010;
+ 3: diagnostic_led_data <= 8'b10000001;
+ endcase
+ end else begin
+ diagnostic_led_data <= 8'b0;
+ end
+ end
+
+ assign lcd_data_in_enable = 1'b0; // Disable LCD I/O for now
+ assign lcd_data_in_address = 6'b0; // Disable LCD I/O for now
+ assign lcd_data_in_data = 8'b0; // Disable LCD I/O for now
+
+ // Instantiate main remote access module
+ remote_access #(RAM_ADDR_BITS) remote_access(.main_fifty_clock(main_50_mhz_clock), .remote_access_4_bit_output(four_bit_output),
+ .remote_access_4_bit_input(four_bit_input), .remote_access_8_bit_output(eight_bit_output),
+ .remote_access_8_bit_input(eight_bit_input), .remote_access_16_bit_output(sixteen_bit_output),
+ .remote_access_16_bit_input(sixteen_bit_input),
+ .serial_port_receiver(serial_input), .serial_port_transmitter(serial_output), .remote_access_input_enable(1'b0),
+ .local_input(8'b0), .seize_serial_tx(1'b0), .serial_tx_data(8'b0), .serial_tx_strobe(1'b0),
+ .lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable),
+ .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select));
+endmodule
diff --git a/fpga/serial/lattice/eb85/remote_access.v b/fpga/serial/lattice/eb85/remote_access.v
new file mode 120000
index 0000000..2d26470
--- /dev/null
+++ b/fpga/serial/lattice/eb85/remote_access.v
@@ -0,0 +1 @@
+../../common/remote_access.v \ No newline at end of file
diff --git a/fpga/serial/lattice/eb85/remote_access_defines.v b/fpga/serial/lattice/eb85/remote_access_defines.v
new file mode 100644
index 0000000..a9948fd
--- /dev/null
+++ b/fpga/serial/lattice/eb85/remote_access_defines.v
@@ -0,0 +1,8 @@
+// This file is part of the Universal Laboratory (uLab)
+//
+// © 2017 - 2019 Raptor Engineering, LLC
+// All Rights Reserved
+//
+// Licensed under the terms of the AGPL v3
+
+// `define SYSTEM_HAS_SRAM 1
diff --git a/fpga/serial/xilinx/digilent/spartan_3/remote_access_defines.v b/fpga/serial/xilinx/digilent/spartan_3/remote_access_defines.v
new file mode 100644
index 0000000..63792f0
--- /dev/null
+++ b/fpga/serial/xilinx/digilent/spartan_3/remote_access_defines.v
@@ -0,0 +1,8 @@
+// This file is part of the Universal Laboratory (uLab)
+//
+// © 2017 - 2019 Raptor Engineering, LLC
+// All Rights Reserved
+//
+// Licensed under the terms of the AGPL v3
+
+`define SYSTEM_HAS_SRAM 1
diff --git a/fpga/serial/xilinx/digilent/spartan_3e/remote_access_defines.v b/fpga/serial/xilinx/digilent/spartan_3e/remote_access_defines.v
new file mode 100644
index 0000000..63792f0
--- /dev/null
+++ b/fpga/serial/xilinx/digilent/spartan_3e/remote_access_defines.v
@@ -0,0 +1,8 @@
+// This file is part of the Universal Laboratory (uLab)
+//
+// © 2017 - 2019 Raptor Engineering, LLC
+// All Rights Reserved
+//
+// Licensed under the terms of the AGPL v3
+
+`define SYSTEM_HAS_SRAM 1
diff --git a/fpga/serial/xilinx/digilent/spartan_6/remote_access_defines.v b/fpga/serial/xilinx/digilent/spartan_6/remote_access_defines.v
new file mode 100644
index 0000000..63792f0
--- /dev/null
+++ b/fpga/serial/xilinx/digilent/spartan_6/remote_access_defines.v
@@ -0,0 +1,8 @@
+// This file is part of the Universal Laboratory (uLab)
+//
+// © 2017 - 2019 Raptor Engineering, LLC
+// All Rights Reserved
+//
+// Licensed under the terms of the AGPL v3
+
+`define SYSTEM_HAS_SRAM 1