Add intial version of Lattice remote FPGA interface

Minor tweaks to core remote FPGA file to eliminate Yosys warnings and reduce design size
master
Timothy Pearson 6 years ago
parent e1e7c9e49d
commit e1a4f6f17e

@ -18,6 +18,9 @@
// sales@raptorengineering.com // sales@raptorengineering.com
// //
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
`include "remote_access_defines.v"
module remote_access( module remote_access(
input main_fifty_clock, // 50MHz clock in 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 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 [5:0] lcd_data_in_address,
input [7:0] lcd_data_in_data, input [7:0] lcd_data_in_data,
input lcd_data_in_enable, input lcd_data_in_enable,
`ifdef SYSTEM_HAS_SRAM
input sram_wren_in, input sram_wren_in,
input sram_clock_in, input sram_clock_in,
input [7:0] sram_data_in, input [7:0] sram_data_in,
input [(RAM_ADDR_BITS-1):0] sram_address_in, input [(RAM_ADDR_BITS-1):0] sram_address_in,
output [7:0] sram_data_out, output [7:0] sram_data_out,
`endif
output sram_available, output sram_available,
`ifdef SYSTEM_HAS_SRAM
input sram_processing_done, input sram_processing_done,
`endif
input [7:0] led_segment_bus, input [7:0] led_segment_bus,
input [3:0] led_digit_select, input [3:0] led_digit_select,
@ -56,6 +63,10 @@ module remote_access(
parameter RAM_ADDR_BITS = 14; 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_4_bit_input_reg;
reg [7:0] remote_access_8_bit_input_reg; reg [7:0] remote_access_8_bit_input_reg;
reg [15:0] remote_access_16_bit_input_reg; reg [15:0] remote_access_16_bit_input_reg;
@ -202,6 +213,7 @@ module remote_access(
reg [(RAM_ADDR_BITS-1):0] data_storage_addra_reg; reg [(RAM_ADDR_BITS-1):0] data_storage_addra_reg;
reg data_storage_write_enable_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), 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)); .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 data_storage_write_enable = (data_storage_remote_enable) ? data_storage_write_enable_reg : sram_wren_in;
assign sram_data_out = data_storage_data_out; 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 == 1) && (transmit_dsp_rx_complete == 0) && (transmit_dsp_status_done == 0)) begin
if (transmit_dsp_status_holdoff == 0) begin if (transmit_dsp_status_holdoff == 0) begin
transmit_dsp_status_holdoff = 1; transmit_dsp_status_holdoff = 1;
`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0; data_storage_write_enable_reg = 0;
data_storage_addra_reg = 0; // Initial data value data_storage_addra_reg = 0; // Initial data value
`endif
end else begin end else begin
`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0; data_storage_write_enable_reg = 0;
TxD_data = data_storage_data_out; TxD_data = data_storage_data_out;
`else
TxD_data = 0;
`endif
TxD_start = 1; TxD_start = 1;
tx_toggle = 1; tx_toggle = 1;
@ -409,8 +428,10 @@ module remote_access(
data_storage_addra_reg = transmit_dsp_status_counter[(RAM_ADDR_BITS-1):0]; data_storage_addra_reg = transmit_dsp_status_counter[(RAM_ADDR_BITS-1):0];
if (transmit_dsp_status_counter >= (2**RAM_ADDR_BITS)) begin if (transmit_dsp_status_counter >= (2**RAM_ADDR_BITS)) begin
transmit_dsp_status_done = 1; transmit_dsp_status_done = 1;
`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 1'bz; data_storage_write_enable_reg = 1'bz;
data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}}; data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}};
`endif
end end
end end
end end
@ -581,7 +602,9 @@ module remote_access(
data_write_timer = data_write_timer - 1; data_write_timer = data_write_timer - 1;
end else begin end else begin
if (data_write_timer == 1) begin if (data_write_timer == 1) begin
`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0; data_storage_write_enable_reg = 0;
`endif
data_write_timer = 0; data_write_timer = 0;
end end
end end
@ -607,9 +630,11 @@ module remote_access(
// DSP input data // DSP input data
if (dsp_update_counter < (2**RAM_ADDR_BITS)) begin if (dsp_update_counter < (2**RAM_ADDR_BITS)) begin
data_storage_remote_enable = 1; data_storage_remote_enable = 1;
`ifdef SYSTEM_HAS_SRAM
data_storage_addra_reg = dsp_update_counter[(RAM_ADDR_BITS-1):0]; data_storage_addra_reg = dsp_update_counter[(RAM_ADDR_BITS-1):0];
data_storage_dina_reg = serial_rx_data_reg; data_storage_dina_reg = serial_rx_data_reg;
data_storage_write_enable_reg = 1; data_storage_write_enable_reg = 1;
`endif
data_write_timer = 3; data_write_timer = 3;
dsp_update_counter = dsp_update_counter + 1; dsp_update_counter = dsp_update_counter + 1;
@ -620,11 +645,15 @@ module remote_access(
if (dsp_update_counter >= (2**RAM_ADDR_BITS)) begin if (dsp_update_counter >= (2**RAM_ADDR_BITS)) begin
next_byte_is_command = 0; next_byte_is_command = 0;
`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 0; data_storage_write_enable_reg = 0;
`endif
data_storage_remote_enable = 0; data_storage_remote_enable = 0;
sram_available_reg = 1; sram_available_reg = 1;
`ifdef SYSTEM_HAS_SRAM
data_storage_write_enable_reg = 1'bz; data_storage_write_enable_reg = 1'bz;
data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}}; data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}};
`endif
waiting_on_dsp_processing = 1; waiting_on_dsp_processing = 1;
transmit_dsp_rx_complete = 1; transmit_dsp_rx_complete = 1;
next_byte_is_command_prev_command = 0; next_byte_is_command_prev_command = 0;

@ -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

@ -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

@ -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

@ -0,0 +1 @@
../../common/remote_access.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

@ -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

@ -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

@ -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
Loading…
Cancel
Save