From 46bd4302de262872185d87ba8a7cec5c36b197b4 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 8 Dec 2022 18:49:21 -0800 Subject: [PATCH 1/9] Update async FIFO timing constraints to handle clocks from OOC IP that are not constrained during synthesis Signed-off-by: Alex Forencich --- syn/vivado/axis_async_fifo.tcl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/syn/vivado/axis_async_fifo.tcl b/syn/vivado/axis_async_fifo.tcl index 5f173b3ca..086515a34 100644 --- a/syn/vivado/axis_async_fifo.tcl +++ b/syn/vivado/axis_async_fifo.tcl @@ -24,13 +24,13 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || puts "Inserting timing constraints for axis_async_fifo instance $fifo_inst" # get clock periods - set read_clk [get_clocks -of_objects [get_pins -quiet "$fifo_inst/rd_ptr_reg_reg[*]/C $fifo_inst/rd_ptr_gray_reg_reg[*]/C $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]/C"]] - set write_clk [get_clocks -of_objects [get_pins -quiet "$fifo_inst/wr_ptr_reg_reg[*]/C $fifo_inst/wr_ptr_gray_reg_reg[*]/C $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]/C"]] + set write_clk [get_clocks -of_objects [get_cells -quiet "$fifo_inst/wr_ptr_reg_reg[*] $fifo_inst/wr_ptr_gray_reg_reg[*] $fifo_inst/rd_ptr_gray_sync1_reg_reg[*]"]] + set read_clk [get_clocks -of_objects [get_cells -quiet "$fifo_inst/rd_ptr_reg_reg[*] $fifo_inst/rd_ptr_gray_reg_reg[*] $fifo_inst/wr_ptr_gray_sync1_reg_reg[*]"]] - set read_clk_period [get_property -min PERIOD $read_clk] - set write_clk_period [get_property -min PERIOD $write_clk] + set write_clk_period [if {[llength $write_clk]} {get_property -min PERIOD $write_clk} {expr 1.0}] + set read_clk_period [if {[llength $read_clk]} {get_property -min PERIOD $read_clk} {expr 1.0}] - set min_clk_period [expr $read_clk_period < $write_clk_period ? $read_clk_period : $write_clk_period] + set min_clk_period [expr min($write_clk_period, $read_clk_period)] # reset synchronization set reset_ffs [get_cells -quiet -hier -regexp ".*/s_rst_sync\[23\]_reg_reg" -filter "PARENT == $fifo_inst"] From a1abc97e2a1f22da6597418141b89a660030e631 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 27 Dec 2022 18:26:47 -0800 Subject: [PATCH 2/9] ISE does not support clog2 in localparam Signed-off-by: Alex Forencich --- rtl/axis_baser_tx_64.v | 4 ++-- rtl/axis_gmii_tx.v | 2 +- rtl/axis_xgmii_tx_32.v | 4 ++-- rtl/axis_xgmii_tx_64.v | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rtl/axis_baser_tx_64.v b/rtl/axis_baser_tx_64.v index e0283a3d7..d79bfe8f3 100644 --- a/rtl/axis_baser_tx_64.v +++ b/rtl/axis_baser_tx_64.v @@ -87,8 +87,8 @@ module axis_baser_tx_64 # output wire error_underflow ); -localparam EMPTY_WIDTH = $clog2(KEEP_WIDTH); -localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-KEEP_WIDTH+1); +parameter EMPTY_WIDTH = $clog2(KEEP_WIDTH); +parameter MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-KEEP_WIDTH+1); // bus width assertions initial begin diff --git a/rtl/axis_gmii_tx.v b/rtl/axis_gmii_tx.v index de86e8e99..b731ebd90 100644 --- a/rtl/axis_gmii_tx.v +++ b/rtl/axis_gmii_tx.v @@ -88,7 +88,7 @@ module axis_gmii_tx # output wire error_underflow ); -localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-1+1); +parameter MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-1+1); // bus width assertions initial begin diff --git a/rtl/axis_xgmii_tx_32.v b/rtl/axis_xgmii_tx_32.v index 000885042..1f87cef24 100644 --- a/rtl/axis_xgmii_tx_32.v +++ b/rtl/axis_xgmii_tx_32.v @@ -85,8 +85,8 @@ module axis_xgmii_tx_32 # output wire error_underflow ); -localparam EMPTY_WIDTH = $clog2(KEEP_WIDTH); -localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-CTRL_WIDTH+1); +parameter EMPTY_WIDTH = $clog2(KEEP_WIDTH); +parameter MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-CTRL_WIDTH+1); // bus width assertions initial begin diff --git a/rtl/axis_xgmii_tx_64.v b/rtl/axis_xgmii_tx_64.v index 5e257e01c..4372c75c8 100644 --- a/rtl/axis_xgmii_tx_64.v +++ b/rtl/axis_xgmii_tx_64.v @@ -87,8 +87,8 @@ module axis_xgmii_tx_64 # output wire error_underflow ); -localparam EMPTY_WIDTH = $clog2(KEEP_WIDTH); -localparam MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-CTRL_WIDTH+1); +parameter EMPTY_WIDTH = $clog2(KEEP_WIDTH); +parameter MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-CTRL_WIDTH+1); // bus width assertions initial begin From 8c3df76b978765d3771f50305c439b4f503ce773 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Tue, 27 Dec 2022 18:26:58 -0800 Subject: [PATCH 3/9] Fix signal name Signed-off-by: Alex Forencich --- example/HXT100G/fpga/rtl/fpga.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/HXT100G/fpga/rtl/fpga.v b/example/HXT100G/fpga/rtl/fpga.v index c735fdb6e..9bf299ef9 100644 --- a/example/HXT100G/fpga/rtl/fpga.v +++ b/example/HXT100G/fpga/rtl/fpga.v @@ -225,7 +225,7 @@ wire [3:0] led_int; /* * Silicon Labs CP2102 USB UART */ -wire uart_sys_rst; +wire uart_rst_int; wire uart_suspend_int; wire uart_ri_int; wire uart_dcd_int; From 786e971f40295ca2f6f2e49df1f3c05bb00eb223 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Thu, 29 Dec 2022 23:54:17 -0800 Subject: [PATCH 4/9] Remove separate memory read register (it causes ISE to crash, and is not necessary for URAM inference) Signed-off-by: Alex Forencich --- rtl/axis_async_fifo.v | 7 +++---- rtl/axis_fifo.v | 7 +++---- syn/vivado/axis_async_fifo.tcl | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/rtl/axis_async_fifo.v b/rtl/axis_async_fifo.v index ebe756f15..fbe9c891e 100644 --- a/rtl/axis_async_fifo.v +++ b/rtl/axis_async_fifo.v @@ -209,7 +209,6 @@ reg m_rst_sync3_reg = 1'b1; (* ramstyle = "no_rw_check" *) reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0; (* shreg_extract = "no" *) @@ -268,7 +267,7 @@ generate if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -wire [WIDTH-1:0] m_axis = RAM_PIPELINE ? m_axis_pipe_reg[RAM_PIPELINE+1-1] : mem_read_data_reg; +wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1]; wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1]; @@ -551,7 +550,7 @@ always @(posedge m_clk) begin if (OUTPUT_FIFO_ENABLE || m_axis_tready || ((~m_axis_tvalid_pipe_reg) >> j)) begin // output ready or bubble in pipeline; transfer down pipeline m_axis_tvalid_pipe_reg[j] <= m_axis_tvalid_pipe_reg[j-1]; - m_axis_pipe_reg[j] <= j == 1 ? mem_read_data_reg : m_axis_pipe_reg[j-1]; + m_axis_pipe_reg[j] <= m_axis_pipe_reg[j-1]; m_axis_tvalid_pipe_reg[j-1] <= 1'b0; end end @@ -559,7 +558,7 @@ always @(posedge m_clk) begin if (OUTPUT_FIFO_ENABLE || m_axis_tready || ~m_axis_tvalid_pipe_reg) begin // output ready or bubble in pipeline; read new data from FIFO m_axis_tvalid_pipe_reg[0] <= 1'b0; - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; if (!empty && !m_rst_sync3_reg && !m_drop_frame_reg && pipe_ready) begin // not empty, increment pointer m_axis_tvalid_pipe_reg[0] <= 1'b1; diff --git a/rtl/axis_fifo.v b/rtl/axis_fifo.v index fb2aa81f7..b6bd49a6c 100644 --- a/rtl/axis_fifo.v +++ b/rtl/axis_fifo.v @@ -163,7 +163,6 @@ reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}; (* ramstyle = "no_rw_check" *) reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg [WIDTH-1:0] mem_read_data_reg; reg mem_read_data_valid_reg = 1'b0; (* shreg_extract = "no" *) @@ -197,7 +196,7 @@ generate if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = s_axis_tuser; endgenerate -wire [WIDTH-1:0] m_axis = RAM_PIPELINE ? m_axis_pipe_reg[RAM_PIPELINE+1-1] : mem_read_data_reg; +wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1]; wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1]; @@ -286,7 +285,7 @@ always @(posedge clk) begin if (OUTPUT_FIFO_ENABLE || m_axis_tready || ((~m_axis_tvalid_pipe_reg) >> j)) begin // output ready or bubble in pipeline; transfer down pipeline m_axis_tvalid_pipe_reg[j] <= m_axis_tvalid_pipe_reg[j-1]; - m_axis_pipe_reg[j] <= j == 1 ? mem_read_data_reg : m_axis_pipe_reg[j-1]; + m_axis_pipe_reg[j] <= m_axis_pipe_reg[j-1]; m_axis_tvalid_pipe_reg[j-1] <= 1'b0; end end @@ -294,7 +293,7 @@ always @(posedge clk) begin if (OUTPUT_FIFO_ENABLE || m_axis_tready || ~m_axis_tvalid_pipe_reg) begin // output ready or bubble in pipeline; read new data from FIFO m_axis_tvalid_pipe_reg[0] <= 1'b0; - mem_read_data_reg <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; if (!empty && pipe_ready) begin // not empty, increment pointer m_axis_tvalid_pipe_reg[0] <= 1'b1; diff --git a/syn/vivado/axis_async_fifo.tcl b/syn/vivado/axis_async_fifo.tcl index 086515a34..817ac33bb 100644 --- a/syn/vivado/axis_async_fifo.tcl +++ b/syn/vivado/axis_async_fifo.tcl @@ -83,7 +83,7 @@ foreach fifo_inst [get_cells -hier -filter {(ORIG_REF_NAME == axis_async_fifo || } # output register (needed for distributed RAM sync write/async read) - set output_reg_ffs [get_cells -quiet "$fifo_inst/mem_read_data_reg_reg[*]"] + set output_reg_ffs [get_cells -quiet "$fifo_inst/m_axis_pipe_reg_reg[0][*]"] if {[llength $output_reg_ffs]} { set_false_path -from $write_clk -to $output_reg_ffs From 713b138ecefd28466fd16b96370f65640b4081e7 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 1 Jan 2023 21:44:15 -0800 Subject: [PATCH 5/9] Fix timing of IDDR2 on Spartan 6 Signed-off-by: Alex Forencich --- rtl/iddr.v | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rtl/iddr.v b/rtl/iddr.v index d11f51601..bf4de3422 100644 --- a/rtl/iddr.v +++ b/rtl/iddr.v @@ -86,11 +86,14 @@ if (TARGET == "XILINX") begin .S(1'b0) ); end else if (IODDR_STYLE == "IODDR2") begin + wire q1_int; + reg q1_delay; + IDDR2 #( .DDR_ALIGNMENT("C0") ) iddr_inst ( - .Q0(q1[n]), + .Q0(q1_int), .Q1(q2[n]), .C0(clk), .C1(~clk), @@ -99,6 +102,12 @@ if (TARGET == "XILINX") begin .R(1'b0), .S(1'b0) ); + + always @(posedge clk) begin + q1_delay <= q1_int; + end + + assign q1[n] = q1_delay; end end end else if (TARGET == "ALTERA") begin From f3d5e7452703a25cb394e124bbba648e0c4cf69a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 1 Jan 2023 22:03:14 -0800 Subject: [PATCH 6/9] Add RV901T example design Signed-off-by: Alex Forencich --- example/RV901T/fpga/README.md | 31 + example/RV901T/fpga/clock.ucf | 6 + example/RV901T/fpga/common/xilinx.mk | 191 ++++++ example/RV901T/fpga/fpga.ucf | 48 ++ example/RV901T/fpga/fpga/Makefile | 70 +++ example/RV901T/fpga/lib/eth | 1 + example/RV901T/fpga/rtl/fpga.v | 292 +++++++++ example/RV901T/fpga/rtl/fpga_core.v | 579 ++++++++++++++++++ example/RV901T/fpga/tb/fpga_core/Makefile | 100 +++ .../fpga/tb/fpga_core/test_fpga_core.py | 223 +++++++ 10 files changed, 1541 insertions(+) create mode 100644 example/RV901T/fpga/README.md create mode 100644 example/RV901T/fpga/clock.ucf create mode 100644 example/RV901T/fpga/common/xilinx.mk create mode 100644 example/RV901T/fpga/fpga.ucf create mode 100644 example/RV901T/fpga/fpga/Makefile create mode 120000 example/RV901T/fpga/lib/eth create mode 100644 example/RV901T/fpga/rtl/fpga.v create mode 100644 example/RV901T/fpga/rtl/fpga_core.v create mode 100644 example/RV901T/fpga/tb/fpga_core/Makefile create mode 100644 example/RV901T/fpga/tb/fpga_core/test_fpga_core.py diff --git a/example/RV901T/fpga/README.md b/example/RV901T/fpga/README.md new file mode 100644 index 000000000..854fc03a4 --- /dev/null +++ b/example/RV901T/fpga/README.md @@ -0,0 +1,31 @@ +# Verilog Ethernet RV901T Example Design + +## Introduction + +This example design targets the Linsn RV901T FPGA board. + +The design by default listens to UDP port 1234 at IP address 192.168.1.128 and +will echo back any packets received. The design will also respond correctly +to ARP requests. + +* FPGA: XC6SLX16T-2FT256 +* PHY: Broadcom B50612 + +## How to build + +Run make to build. Ensure that the Xilinx ISE toolchain components are +in PATH. + +## How to test + +Run make program to program the RV901T board with the Xilinx Impact software. +Then run + + netcat -u 192.168.1.128 1234 + +to open a UDP connection to port 1234. Any text entered into netcat will be +echoed back after pressing enter. + +It is also possible to use hping to test the design by running + + hping 192.168.1.128 -2 -p 1234 -d 1024 diff --git a/example/RV901T/fpga/clock.ucf b/example/RV901T/fpga/clock.ucf new file mode 100644 index 000000000..e048a42f1 --- /dev/null +++ b/example/RV901T/fpga/clock.ucf @@ -0,0 +1,6 @@ +# UCF file for clock module domain crossing constraints + +NET "clk_125mhz_int" TNM = "ffs_clk_125mhz_int"; +NET "core_inst/eth_mac_inst/rx_clk" TNM = "ffs_gmii_rx_clk"; +TIMESPEC "TS_clk_125mhz_int_to_gmii_rx_clk" = FROM "ffs_clk_125mhz_int" TO "ffs_gmii_rx_clk" 10 ns; +TIMESPEC "TS_gmii_rx_clk_to_clk_125mhz_int" = FROM "ffs_gmii_rx_clk" TO "ffs_clk_125mhz_int" 10 ns; diff --git a/example/RV901T/fpga/common/xilinx.mk b/example/RV901T/fpga/common/xilinx.mk new file mode 100644 index 000000000..f10a45f8e --- /dev/null +++ b/example/RV901T/fpga/common/xilinx.mk @@ -0,0 +1,191 @@ +############################################################################# +# Author: Lane Brooks/Keith Fife +# Date: 04/28/2006 +# License: GPL +# Desc: This is a Makefile intended to take a verilog rtl design +# through the Xilinx ISE tools to generate configuration files for +# Xilinx FPGAs. This file is generic and just a template. As such +# all design specific options such as synthesis files, fpga part type, +# prom part type, etc should be set in the top Makefile prior to +# including this file. Alternatively, all parameters can be passed +# in from the command line as well. +# +############################################################################## +# +# Parameter: +# SYN_FILES - Space seperated list of files to be synthesized +# PART - FPGA part (see Xilinx documentation) +# PROM - PROM part +# NGC_PATHS - Space seperated list of any dirs with pre-compiled ngc files. +# UCF_FILES - Space seperated list of user constraint files. Defaults to xilinx/$(FPGA_TOP).ucf +# +# +# Example Calling Makefile: +# +# SYN_FILES = fpga.v fifo.v clks.v +# PART = xc3s1000 +# FPGA_TOP = fpga +# PROM = xc18v04 +# NGC_PATH = ipLib1 ipLib2 +# FPGA_ARCH = spartan6 +# SPI_PROM_SIZE = (in bytes) +# include xilinx.mk +############################################################################# +# +# Command Line Example: +# make -f xilinx.mk PART=xc3s1000-4fg320 SYN_FILES="fpga.v test.v" FPGA_TOP=fpga +# +############################################################################## +# +# Required Setup: +# +# %.ucf - user constraint file. Needed by ngdbuild +# +# Optional Files: +# %.xcf - user constraint file. Needed by xst. +# %.ut - File for pin states needed by bitgen + + +.PHONY: clean bit prom fpga spi + + +# Mark the intermediate files as PRECIOUS to prevent make from +# deleting them (see make manual section 10.4). +.PRECIOUS: %.ngc %.ngd %_map.ncd %.ncd %.twr %.bit %_timesim.v + +# include the local Makefile for project for any project specific targets +CONFIG ?= config.mk +-include ../$(CONFIG) + +SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) +INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) +INC_PATHS_REL = $(patsubst %, ../%, $(INC_PATHS)) +NGC_PATHS_REL = $(patsubst %, ../%, $(NGC_PATHS)) + +ifdef UCF_FILES + UCF_FILES_REL = $(patsubst %, ../%, $(UCF_FILES)) +else + UCF_FILES_REL = $(FPGA_TOP).ucf +endif + + + +fpga: $(FPGA_TOP).bit + +mcs: $(FPGA_TOP).mcs + +prom: $(FPGA_TOP).spi + +spi: $(FPGA_TOP).spi + +fpgasim: $(FPGA_TOP)_sim.v + + +########################### XST TEMPLATES ############################ +# There are 2 files that XST uses for synthesis that we auto generate. +# The first is a project file which is just a list of all the verilog +# files. The second is the src file which passes XST all the options. +# See XST user manual for XST options. +%.ngc: $(SYN_FILES_REL) $(INC_FILES_REL) + rm -rf xst $*.prj $*.xst defines.v + touch defines.v + mkdir -p xst/tmp + for x in $(DEFS); do echo '`define' $$x >> defines.v; done + echo verilog work defines.v > $*.prj + for x in $(SYN_FILES_REL); do echo verilog work $$x >> $*.prj; done + @echo "set -tmpdir ./xst/tmp" >> $*.xst + @echo "set -xsthdpdir ./xst" >> $*.xst + @echo "run" >> $*.xst + @echo "-ifn $*.prj" >> $*.xst + @echo "-ifmt mixed" >> $*.xst + @echo "-top $*" >> $*.xst + @echo "-ofn $*" >> $*.xst + @echo "-ofmt NGC" >> $*.xst + @echo "-opt_mode Speed" >> $*.xst + @echo "-opt_level 1" >> $*.xst + # @echo "-verilog2001 YES" >> $*.xst + @echo "-keep_hierarchy NO" >> $*.xst + @echo "-p $(FPGA_PART)" >> $*.xst + xst -ifn $*.xst -ofn $*.log + + +########################### ISE TRANSLATE ############################ +# ngdbuild will automatically use a ucf called %.ucf if one is found. +# We setup the dependancy such that %.ucf file is required. If any +# pre-compiled ncd files are needed, set the NGC_PATH variable as a space +# seperated list of directories that include the pre-compiled ngc files. +%.ngd: %.ngc $(UCF_FILES_REL) + ngdbuild -dd ngdbuild $(patsubst %,-sd %, $(NGC_PATHS_REL)) $(patsubst %,-uc %, $(UCF_FILES_REL)) -p $(FPGA_PART) $< $@ + + +########################### ISE MAP ################################### +ifeq ($(FPGA_ARCH),spartan6) + MAP_OPTS= -register_duplication on -timing -xe n +else + MAP_OPTS= -cm speed -register_duplication on -timing -xe n -pr b +endif + +%_map.ncd: %.ngd + map -p $(FPGA_PART) $(MAP_OPTS) -w -o $@ $< $*.pcf + +# map -p $(FPGA_PART) -cm area -pr b -k 4 -c 100 -o $@ $< $*.pcf + + +########################### ISE PnR ################################### +%.ncd: %_map.ncd + par -w -ol high $< $@ $*.pcf + +# par -w -ol std -t 1 $< $@ $*.pcf + + +##################### ISE Static Timing Analysis ##################### +%.twr: %.ncd + -trce -e 3 -l 3 -u -xml $* $< -o $@ $*.pcf + +%_sim.v: %.ncd + netgen -s 4 -pcf $*.pcf -sdf_anno true -ism -sdf_path netgen -w -dir . -ofmt verilog -sim $< $@ + +# netgen -ise "/home/lane/Second/xilinx/Second/Second" -intstyle ise -s 4 -pcf Second.pcf -sdf_anno true -sdf_path netgen/par -w -dir netgen/par -ofmt verilog -sim Second.ncd Second_timesim.v + + +########################### ISE Bitgen ############################# +%.bit: %.twr + bitgen $(BITGEN_OPTIONS) -w $*.ncd $*.bit + mkdir -p rev + EXT=bit; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +########################### ISE Promgen ############################# +%.mcs: %.bit + promgen -spi -w -p mcs -s $(SPI_PROM_SIZE) -o $@ -u 0 $< + # promgen -w -p mcs -c FF -o $@ -u 0 $< -x $(PROM) + mkdir -p rev + EXT=mcs; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + echo "Output: rev/$*_rev$$COUNT.$$EXT"; + + +%.spi: %.mcs + objcopy -I ihex -O binary $< $@ + EXT=spi; COUNT=100; \ + while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + do let COUNT=COUNT+1; done; \ + cp $@ rev/$*_rev$$COUNT.$$EXT; \ + + +tmpclean: + -rm -rf xst ngdbuild *_map.* *.ncd *.ngc *.log *.xst *.prj *.lso *~ *.pcf *.bld *.ngd *.xpi *_pad.* *.unroutes *.twx *.par *.twr *.pad *.drc *.bgn *.prm *.sig netgen *.v *.nlf *.xml + +clean: tmpclean + -rm -rf *.bit *.mcs + +# clean everything +distclean: clean + -rm -rf rev + diff --git a/example/RV901T/fpga/fpga.ucf b/example/RV901T/fpga/fpga.ucf new file mode 100644 index 000000000..8570c6a7f --- /dev/null +++ b/example/RV901T/fpga/fpga.ucf @@ -0,0 +1,48 @@ +# User Constraints File for the Linsn RV901T board + +CONFIG PART = xc6slx16-2ftg256; + +# 25 MHz clock +NET "clk_25mhz" LOC = "M9" | IOSTANDARD=LVCMOS33 | TNM_NET = "clk_25mhz"; +TIMESPEC "TS_clk_25mhz" = PERIOD "clk_25mhz" 25000 kHz; + +# Light Emitting Diodes +NET "led" LOC = "F7" | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO | DRIVE=2; + +# Broadcom B50612D Tri-Mode Ethernet PHY (1000BASE-T) (U200) +# RGMII Transmit +NET "phy_0_tx_clk" LOC = "D1" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_0_txd<0>" LOC = "E3" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_0_txd<1>" LOC = "E2" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_0_txd<2>" LOC = "E1" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_0_txd<3>" LOC = "F3" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_0_tx_ctl" LOC = "E4" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +# RGMII Receive +NET "phy_0_rx_clk" LOC = "F1" | IOSTANDARD=LVCMOS33 | TNM_NET = "phy_0_rx_clk"; +NET "phy_0_rxd<0>" LOC = "F2" | IOSTANDARD=LVCMOS33; +NET "phy_0_rxd<1>" LOC = "F4" | IOSTANDARD=LVCMOS33; +NET "phy_0_rxd<2>" LOC = "G1" | IOSTANDARD=LVCMOS33; +NET "phy_0_rxd<3>" LOC = "G3" | IOSTANDARD=LVCMOS33; +NET "phy_0_rx_ctl" LOC = "H1" | IOSTANDARD=LVCMOS33; + +# Timing constraints for Ethernet PHY +TIMESPEC "TS_phy_0_rx_clk" = PERIOD "phy_0_rx_clk" 8000 ps HIGH 50 %; + +# Broadcom B50612D Tri-Mode Ethernet PHY (1000BASE-T) (U201) +# RGMII Transmit +NET "phy_1_tx_clk" LOC = "J1" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_1_txd<0>" LOC = "J3" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_1_txd<1>" LOC = "K1" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_1_txd<2>" LOC = "K2" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_1_txd<3>" LOC = "H3" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +NET "phy_1_tx_ctl" LOC = "H2" | IOSTANDARD=LVCMOS33 | SLEW = FAST; +# RGMII Receive +NET "phy_1_rx_clk" LOC = "K3" | IOSTANDARD=LVCMOS33 | TNM_NET = "phy_1_rx_clk"; +NET "phy_1_rxd<0>" LOC = "L1" | IOSTANDARD=LVCMOS33; +NET "phy_1_rxd<1>" LOC = "L3" | IOSTANDARD=LVCMOS33; +NET "phy_1_rxd<2>" LOC = "M1" | IOSTANDARD=LVCMOS33; +NET "phy_1_rxd<3>" LOC = "M2" | IOSTANDARD=LVCMOS33; +NET "phy_1_rx_ctl" LOC = "M3" | IOSTANDARD=LVCMOS33; + +# Timing constraints for Ethernet PHY +TIMESPEC "TS_phy_1_rx_clk" = PERIOD "phy_1_rx_clk" 8000 ps HIGH 50 %; diff --git a/example/RV901T/fpga/fpga/Makefile b/example/RV901T/fpga/fpga/Makefile new file mode 100644 index 000000000..5aa825f8f --- /dev/null +++ b/example/RV901T/fpga/fpga/Makefile @@ -0,0 +1,70 @@ + +# FPGA settings +FPGA_PART = xc6slx16-2ftg256 +FPGA_TOP = fpga +FPGA_ARCH = spartan6 + +# PROM settings +#PROM = xc18v04 +#SPI_PROM_SIZE = (in bytes) + +# Files for synthesis +SYN_FILES = rtl/fpga.v +SYN_FILES += rtl/fpga_core.v +SYN_FILES += lib/eth/rtl/iddr.v +SYN_FILES += lib/eth/rtl/oddr.v +SYN_FILES += lib/eth/rtl/ssio_ddr_in.v +SYN_FILES += lib/eth/rtl/ssio_ddr_out.v +SYN_FILES += lib/eth/rtl/rgmii_phy_if.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii_fifo.v +SYN_FILES += lib/eth/rtl/eth_mac_1g_rgmii.v +SYN_FILES += lib/eth/rtl/eth_mac_1g.v +SYN_FILES += lib/eth/rtl/axis_gmii_rx.v +SYN_FILES += lib/eth/rtl/axis_gmii_tx.v +SYN_FILES += lib/eth/rtl/lfsr.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v +SYN_FILES += lib/eth/rtl/udp_complete.v +SYN_FILES += lib/eth/rtl/udp_checksum_gen.v +SYN_FILES += lib/eth/rtl/udp.v +SYN_FILES += lib/eth/rtl/udp_ip_rx.v +SYN_FILES += lib/eth/rtl/udp_ip_tx.v +SYN_FILES += lib/eth/rtl/ip_complete.v +SYN_FILES += lib/eth/rtl/ip.v +SYN_FILES += lib/eth/rtl/ip_eth_rx.v +SYN_FILES += lib/eth/rtl/ip_eth_tx.v +SYN_FILES += lib/eth/rtl/ip_arb_mux.v +SYN_FILES += lib/eth/rtl/arp.v +SYN_FILES += lib/eth/rtl/arp_cache.v +SYN_FILES += lib/eth/rtl/arp_eth_rx.v +SYN_FILES += lib/eth/rtl/arp_eth_tx.v +SYN_FILES += lib/eth/rtl/eth_arb_mux.v +SYN_FILES += lib/eth/lib/axis/rtl/arbiter.v +SYN_FILES += lib/eth/lib/axis/rtl/priority_encoder.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo.v +SYN_FILES += lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v +SYN_FILES += lib/eth/lib/axis/rtl/sync_reset.v +#SYN_FILES += coregen/dcm_i100_o125/dcm_i100_o125.v + +# UCF files +UCF_FILES = fpga.ucf +UCF_FILES += clock.ucf + +# NGC paths for ngdbuild +#NGC_PATHS = coregen/dcm_i100_o125 + +# Bitgen options +BITGEN_OPTIONS = -g StartupClk:Cclk -g ConfigRate:26 + +include ../common/xilinx.mk + +program: $(FPGA_TOP).bit + echo "setmode -bscan" > program.cmd + echo "setcable -p auto" >> program.cmd + echo "identify" >> program.cmd + echo "assignfile -p 1 -file $(FPGA_TOP).bit" >> program.cmd + echo "program -p 1" >> program.cmd + echo "quit" >> program.cmd + impact -batch program.cmd + diff --git a/example/RV901T/fpga/lib/eth b/example/RV901T/fpga/lib/eth new file mode 120000 index 000000000..11a54ed36 --- /dev/null +++ b/example/RV901T/fpga/lib/eth @@ -0,0 +1 @@ +../../../../ \ No newline at end of file diff --git a/example/RV901T/fpga/rtl/fpga.v b/example/RV901T/fpga/rtl/fpga.v new file mode 100644 index 000000000..827e12be0 --- /dev/null +++ b/example/RV901T/fpga/rtl/fpga.v @@ -0,0 +1,292 @@ +/* + +Copyright (c) 2014-2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA top-level module + */ +module fpga ( + /* + * Clock: 25 MHz + */ + input wire clk_25mhz, + /* + * GPIO + */ + output wire led, + /* + * Ethernet: 1000BASE-T RGMII + */ + input wire phy_0_rx_clk, + input wire [3:0] phy_0_rxd, + input wire phy_0_rx_ctl, + output wire phy_0_tx_clk, + output wire [3:0] phy_0_txd, + output wire phy_0_tx_ctl, + + input wire phy_1_rx_clk, + input wire [3:0] phy_1_rxd, + input wire phy_1_rx_ctl, + output wire phy_1_tx_clk, + output wire [3:0] phy_1_txd, + output wire phy_1_tx_ctl +); + +// Clock and reset + +// Internal 125 MHz clock +wire clk_125mhz_pll_out; +wire clk_125mhz_int; +wire clk90_125mhz_pll_out; +wire clk90_125mhz_int; +wire rst_125mhz_int; + +wire pll_rst = 0; +wire pll_locked; +wire pll_clkfb; + +// PLL instance +// 25 MHz in, 125 MHz out +// PFD range: 19 MHz to 400 MHz +// VCO range: 400 MHz to 1000 MHz +// M = 40, D = 1 sets Fvco = 1000 +// Divide by 8 to get output frequency of 125 MHz +PLL_BASE #( + .COMPENSATION(), + .BANDWIDTH("OPTIMIZED"), + .CLKOUT0_DIVIDE(8), + .CLKOUT0_DUTY_CYCLE(0.50), + .CLKOUT0_PHASE(0.0), + .CLKOUT1_DIVIDE(8), + .CLKOUT1_DUTY_CYCLE(0.50), + .CLKOUT1_PHASE(90.0), + .CLKOUT2_DIVIDE(1), + .CLKOUT2_DUTY_CYCLE(0.50), + .CLKOUT2_PHASE(0.0), + .CLKOUT3_DIVIDE(1), + .CLKOUT3_DUTY_CYCLE(0.50), + .CLKOUT3_PHASE(0.0), + .CLKOUT4_DIVIDE(1), + .CLKOUT4_DUTY_CYCLE(0.50), + .CLKOUT4_PHASE(0.0), + .CLKOUT5_DIVIDE(1), + .CLKOUT5_DUTY_CYCLE(0.50), + .CLKOUT5_PHASE(0.0), + .CLKFBOUT_MULT(40), + .CLKFBOUT_PHASE(0.0), + .DIVCLK_DIVIDE(1), + .REF_JITTER(0.100), + .CLKIN_PERIOD(25.0), + .CLK_FEEDBACK("CLKFBOUT"), + .RESET_ON_LOSS_OF_LOCK("FALSE") +) +clk_pll_inst ( + .CLKIN(clk_25mhz), + .CLKFBIN(pll_clkfb), + .RST(pll_rst), + .CLKOUT0(clk_125mhz_pll_out), + .CLKOUT1(clk90_125mhz_pll_out), + .CLKOUT2(), + .CLKOUT3(), + .CLKOUT4(), + .CLKOUT5(), + .CLKFBOUT(pll_clkfb), + .LOCKED(pll_locked) +); + +BUFG +clk_125mhz_bufg_inst ( + .I(clk_125mhz_pll_out), + .O(clk_125mhz_int) +); + +BUFG +clk90_125mhz_bufg_inst ( + .I(clk90_125mhz_pll_out), + .O(clk90_125mhz_int) +); + +sync_reset #( + .N(4) +) +sync_reset_125mhz_inst ( + .clk(clk_125mhz_int), + .rst(~pll_locked), + .out(rst_125mhz_int) +); + +// GPIO +wire led_int; + +assign led = led_int; + +// IODELAY elements for RGMII interface to PHY +generate + +genvar n; + +// 2 ns delay (40 taps at about 50 ps/tap) +localparam PHY_0_RX_DELAY_TAPS = 40; + +wire [3:0] phy_0_rxd_delay; +wire phy_0_rx_ctl_delay; + +IODELAY2 #( + .IDELAY_TYPE("FIXED"), + .IDELAY_VALUE(PHY_0_RX_DELAY_TAPS), + .ODELAY_VALUE(PHY_0_RX_DELAY_TAPS), + .DELAY_SRC("IDATAIN") +) +phy_0_rx_ctl_idelay_inst ( + .DATAOUT(phy_0_rx_ctl_delay), + .CAL(0), + .CE(0), + .CLK(0), + .IDATAIN(phy_0_rx_ctl), + .INC(0), + .IOCLK0(0), + .IOCLK1(0), + .ODATAIN(0), + .RST(0), + .T(1) +); + +for (n = 0; n < 4; n = n + 1) begin : phy_0_rxd_delay_ch + + IODELAY2 #( + .IDELAY_TYPE("FIXED"), + .IDELAY_VALUE(PHY_0_RX_DELAY_TAPS), + .ODELAY_VALUE(PHY_0_RX_DELAY_TAPS), + .DELAY_SRC("IDATAIN") + ) + phy_0_rxd_idelay_inst ( + .DATAOUT(phy_0_rxd_delay[n]), + .CAL(0), + .CE(0), + .CLK(0), + .IDATAIN(phy_0_rxd[n]), + .INC(0), + .IOCLK0(0), + .IOCLK1(0), + .ODATAIN(0), + .RST(0), + .T(1) + ); + +end + +// 2 ns delay (40 taps at about 50 ps/tap) +localparam PHY_1_RX_DELAY_TAPS = 40; + +wire [3:0] phy_1_rxd_delay; +wire phy_1_rx_ctl_delay; + +IODELAY2 #( + .IDELAY_TYPE("FIXED"), + .IDELAY_VALUE(PHY_1_RX_DELAY_TAPS), + .ODELAY_VALUE(PHY_1_RX_DELAY_TAPS), + .DELAY_SRC("IDATAIN") +) +phy_1_rx_ctl_idelay_inst ( + .DATAOUT(phy_1_rx_ctl_delay), + .CAL(0), + .CE(0), + .CLK(0), + .IDATAIN(phy_1_rx_ctl), + .INC(0), + .IOCLK0(0), + .IOCLK1(0), + .ODATAIN(0), + .RST(0), + .T(1) +); + +for (n = 0; n < 4; n = n + 1) begin : phy_1_rxd_delay_ch + + IODELAY2 #( + .IDELAY_TYPE("FIXED"), + .IDELAY_VALUE(PHY_1_RX_DELAY_TAPS), + .ODELAY_VALUE(PHY_1_RX_DELAY_TAPS), + .DELAY_SRC("IDATAIN") + ) + phy_1_rxd_idelay_inst ( + .DATAOUT(phy_1_rxd_delay[n]), + .CAL(0), + .CE(0), + .CLK(0), + .IDATAIN(phy_1_rxd[n]), + .INC(0), + .IOCLK0(0), + .IOCLK1(0), + .ODATAIN(0), + .RST(0), + .T(1) + ); + +end + +endgenerate + +fpga_core #( + .TARGET("XILINX"), + .USE_CLK90("FALSE") +) +core_inst ( + /* + * Clock: 125MHz + * Synchronous reset + */ + .clk_125mhz(clk_125mhz_int), + .clk90_125mhz(clk90_125mhz_int), + .rst_125mhz(rst_125mhz_int), + /* + * GPIO + */ + .led(led_int), + /* + * Ethernet: 1000BASE-T RGMII + */ + .phy_0_rx_clk(phy_0_rx_clk), + .phy_0_rxd(phy_0_rxd_delay), + .phy_0_rx_ctl(phy_0_rx_ctl_delay), + .phy_0_tx_clk(phy_0_tx_clk), + .phy_0_txd(phy_0_txd), + .phy_0_tx_ctl(phy_0_tx_ctl), + + .phy_1_rx_clk(phy_1_rx_clk), + .phy_1_rxd(phy_1_rxd_delay), + .phy_1_rx_ctl(phy_1_rx_ctl_delay), + .phy_1_tx_clk(phy_1_tx_clk), + .phy_1_txd(phy_1_txd), + .phy_1_tx_ctl(phy_1_tx_ctl) +); + +endmodule + +`resetall diff --git a/example/RV901T/fpga/rtl/fpga_core.v b/example/RV901T/fpga/rtl/fpga_core.v new file mode 100644 index 000000000..2cac60e2c --- /dev/null +++ b/example/RV901T/fpga/rtl/fpga_core.v @@ -0,0 +1,579 @@ +/* + +Copyright (c) 2014-2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * FPGA core logic + */ +module fpga_core # +( + parameter TARGET = "GENERIC", + parameter USE_CLK90 = "TRUE" +) +( + /* + * Clock: 125MHz + * Synchronous reset + */ + input wire clk_125mhz, + input wire clk90_125mhz, + input wire rst_125mhz, + + /* + * GPIO + */ + output wire led, + + /* + * Ethernet: 1000BASE-T RGMII + */ + input wire phy_0_rx_clk, + input wire [3:0] phy_0_rxd, + input wire phy_0_rx_ctl, + output wire phy_0_tx_clk, + output wire [3:0] phy_0_txd, + output wire phy_0_tx_ctl, + + input wire phy_1_rx_clk, + input wire [3:0] phy_1_rxd, + input wire phy_1_rx_ctl, + output wire phy_1_tx_clk, + output wire [3:0] phy_1_txd, + output wire phy_1_tx_ctl +); + +// AXI between MAC and Ethernet modules +wire [7:0] rx_axis_tdata; +wire rx_axis_tvalid; +wire rx_axis_tready; +wire rx_axis_tlast; +wire rx_axis_tuser; + +wire [7:0] tx_axis_tdata; +wire tx_axis_tvalid; +wire tx_axis_tready; +wire tx_axis_tlast; +wire tx_axis_tuser; + +// Ethernet frame between Ethernet modules and UDP stack +wire rx_eth_hdr_ready; +wire rx_eth_hdr_valid; +wire [47:0] rx_eth_dest_mac; +wire [47:0] rx_eth_src_mac; +wire [15:0] rx_eth_type; +wire [7:0] rx_eth_payload_axis_tdata; +wire rx_eth_payload_axis_tvalid; +wire rx_eth_payload_axis_tready; +wire rx_eth_payload_axis_tlast; +wire rx_eth_payload_axis_tuser; + +wire tx_eth_hdr_ready; +wire tx_eth_hdr_valid; +wire [47:0] tx_eth_dest_mac; +wire [47:0] tx_eth_src_mac; +wire [15:0] tx_eth_type; +wire [7:0] tx_eth_payload_axis_tdata; +wire tx_eth_payload_axis_tvalid; +wire tx_eth_payload_axis_tready; +wire tx_eth_payload_axis_tlast; +wire tx_eth_payload_axis_tuser; + +// IP frame connections +wire rx_ip_hdr_valid; +wire rx_ip_hdr_ready; +wire [47:0] rx_ip_eth_dest_mac; +wire [47:0] rx_ip_eth_src_mac; +wire [15:0] rx_ip_eth_type; +wire [3:0] rx_ip_version; +wire [3:0] rx_ip_ihl; +wire [5:0] rx_ip_dscp; +wire [1:0] rx_ip_ecn; +wire [15:0] rx_ip_length; +wire [15:0] rx_ip_identification; +wire [2:0] rx_ip_flags; +wire [12:0] rx_ip_fragment_offset; +wire [7:0] rx_ip_ttl; +wire [7:0] rx_ip_protocol; +wire [15:0] rx_ip_header_checksum; +wire [31:0] rx_ip_source_ip; +wire [31:0] rx_ip_dest_ip; +wire [7:0] rx_ip_payload_axis_tdata; +wire rx_ip_payload_axis_tvalid; +wire rx_ip_payload_axis_tready; +wire rx_ip_payload_axis_tlast; +wire rx_ip_payload_axis_tuser; + +wire tx_ip_hdr_valid; +wire tx_ip_hdr_ready; +wire [5:0] tx_ip_dscp; +wire [1:0] tx_ip_ecn; +wire [15:0] tx_ip_length; +wire [7:0] tx_ip_ttl; +wire [7:0] tx_ip_protocol; +wire [31:0] tx_ip_source_ip; +wire [31:0] tx_ip_dest_ip; +wire [7:0] tx_ip_payload_axis_tdata; +wire tx_ip_payload_axis_tvalid; +wire tx_ip_payload_axis_tready; +wire tx_ip_payload_axis_tlast; +wire tx_ip_payload_axis_tuser; + +// UDP frame connections +wire rx_udp_hdr_valid; +wire rx_udp_hdr_ready; +wire [47:0] rx_udp_eth_dest_mac; +wire [47:0] rx_udp_eth_src_mac; +wire [15:0] rx_udp_eth_type; +wire [3:0] rx_udp_ip_version; +wire [3:0] rx_udp_ip_ihl; +wire [5:0] rx_udp_ip_dscp; +wire [1:0] rx_udp_ip_ecn; +wire [15:0] rx_udp_ip_length; +wire [15:0] rx_udp_ip_identification; +wire [2:0] rx_udp_ip_flags; +wire [12:0] rx_udp_ip_fragment_offset; +wire [7:0] rx_udp_ip_ttl; +wire [7:0] rx_udp_ip_protocol; +wire [15:0] rx_udp_ip_header_checksum; +wire [31:0] rx_udp_ip_source_ip; +wire [31:0] rx_udp_ip_dest_ip; +wire [15:0] rx_udp_source_port; +wire [15:0] rx_udp_dest_port; +wire [15:0] rx_udp_length; +wire [15:0] rx_udp_checksum; +wire [7:0] rx_udp_payload_axis_tdata; +wire rx_udp_payload_axis_tvalid; +wire rx_udp_payload_axis_tready; +wire rx_udp_payload_axis_tlast; +wire rx_udp_payload_axis_tuser; + +wire tx_udp_hdr_valid; +wire tx_udp_hdr_ready; +wire [5:0] tx_udp_ip_dscp; +wire [1:0] tx_udp_ip_ecn; +wire [7:0] tx_udp_ip_ttl; +wire [31:0] tx_udp_ip_source_ip; +wire [31:0] tx_udp_ip_dest_ip; +wire [15:0] tx_udp_source_port; +wire [15:0] tx_udp_dest_port; +wire [15:0] tx_udp_length; +wire [15:0] tx_udp_checksum; +wire [7:0] tx_udp_payload_axis_tdata; +wire tx_udp_payload_axis_tvalid; +wire tx_udp_payload_axis_tready; +wire tx_udp_payload_axis_tlast; +wire tx_udp_payload_axis_tuser; + +wire [7:0] rx_fifo_udp_payload_axis_tdata; +wire rx_fifo_udp_payload_axis_tvalid; +wire rx_fifo_udp_payload_axis_tready; +wire rx_fifo_udp_payload_axis_tlast; +wire rx_fifo_udp_payload_axis_tuser; + +wire [7:0] tx_fifo_udp_payload_axis_tdata; +wire tx_fifo_udp_payload_axis_tvalid; +wire tx_fifo_udp_payload_axis_tready; +wire tx_fifo_udp_payload_axis_tlast; +wire tx_fifo_udp_payload_axis_tuser; + +// Configuration +wire [47:0] local_mac = 48'h02_00_00_00_00_00; +wire [31:0] local_ip = {8'd192, 8'd168, 8'd1, 8'd128}; +wire [31:0] gateway_ip = {8'd192, 8'd168, 8'd1, 8'd1}; +wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0}; + +// IP ports not used +assign rx_ip_hdr_ready = 1; +assign rx_ip_payload_axis_tready = 1; + +assign tx_ip_hdr_valid = 0; +assign tx_ip_dscp = 0; +assign tx_ip_ecn = 0; +assign tx_ip_length = 0; +assign tx_ip_ttl = 0; +assign tx_ip_protocol = 0; +assign tx_ip_source_ip = 0; +assign tx_ip_dest_ip = 0; +assign tx_ip_payload_axis_tdata = 0; +assign tx_ip_payload_axis_tvalid = 0; +assign tx_ip_payload_axis_tlast = 0; +assign tx_ip_payload_axis_tuser = 0; + +// Loop back UDP +wire match_cond = rx_udp_dest_port == 1234; +wire no_match = !match_cond; + +reg match_cond_reg = 0; +reg no_match_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + match_cond_reg <= 0; + no_match_reg <= 0; + end else begin + if (rx_udp_payload_axis_tvalid) begin + if ((!match_cond_reg && !no_match_reg) || + (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin + match_cond_reg <= match_cond; + no_match_reg <= no_match; + end + end else begin + match_cond_reg <= 0; + no_match_reg <= 0; + end + end +end + +assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond; +assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match; +assign tx_udp_ip_dscp = 0; +assign tx_udp_ip_ecn = 0; +assign tx_udp_ip_ttl = 64; +assign tx_udp_ip_source_ip = local_ip; +assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip; +assign tx_udp_source_port = rx_udp_dest_port; +assign tx_udp_dest_port = rx_udp_source_port; +assign tx_udp_length = rx_udp_length; +assign tx_udp_checksum = 0; + +assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata; +assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid; +assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready; +assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast; +assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser; + +assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata; +assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg; +assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg; +assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast; +assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser; + +// Place first payload byte onto LEDs +reg valid_last = 0; +reg led_reg = 0; + +always @(posedge clk_125mhz) begin + if (rst_125mhz) begin + led_reg <= 0; + end else begin + if (tx_udp_payload_axis_tvalid) begin + if (!valid_last) begin + led_reg <= tx_udp_payload_axis_tdata; + valid_last <= 1'b1; + end + if (tx_udp_payload_axis_tlast) begin + valid_last <= 1'b0; + end + end + end +end + +assign led = led_reg; + +eth_mac_1g_rgmii_fifo #( + .TARGET(TARGET), + .IODDR_STYLE("IODDR2"), + .CLOCK_INPUT_STYLE("BUFG"), + .USE_CLK90(USE_CLK90), + .ENABLE_PADDING(1), + .MIN_FRAME_LENGTH(64), + .TX_FIFO_DEPTH(4096), + .TX_FRAME_FIFO(1), + .RX_FIFO_DEPTH(4096), + .RX_FRAME_FIFO(1) +) +eth_mac_inst ( + .gtx_clk(clk_125mhz), + .gtx_clk90(clk90_125mhz), + .gtx_rst(rst_125mhz), + .logic_clk(clk_125mhz), + .logic_rst(rst_125mhz), + + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tready(rx_axis_tready), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + + .rgmii_rx_clk(phy_0_rx_clk), + .rgmii_rxd(phy_0_rxd), + .rgmii_rx_ctl(phy_0_rx_ctl), + .rgmii_tx_clk(phy_0_tx_clk), + .rgmii_txd(phy_0_txd), + .rgmii_tx_ctl(phy_0_tx_ctl), + + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + .speed(), + + .ifg_delay(12) +); + +assign phy_1_tx_clk = 1'b0; +assign phy_1_txd = 4'd0; +assign phy_1_tx_ctl = 1'b0; + +eth_axis_rx +eth_axis_rx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // AXI input + .s_axis_tdata(rx_axis_tdata), + .s_axis_tvalid(rx_axis_tvalid), + .s_axis_tready(rx_axis_tready), + .s_axis_tlast(rx_axis_tlast), + .s_axis_tuser(rx_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(rx_eth_hdr_valid), + .m_eth_hdr_ready(rx_eth_hdr_ready), + .m_eth_dest_mac(rx_eth_dest_mac), + .m_eth_src_mac(rx_eth_src_mac), + .m_eth_type(rx_eth_type), + .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Status signals + .busy(), + .error_header_early_termination() +); + +eth_axis_tx +eth_axis_tx_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .s_eth_hdr_valid(tx_eth_hdr_valid), + .s_eth_hdr_ready(tx_eth_hdr_ready), + .s_eth_dest_mac(tx_eth_dest_mac), + .s_eth_src_mac(tx_eth_src_mac), + .s_eth_type(tx_eth_type), + .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // AXI output + .m_axis_tdata(tx_axis_tdata), + .m_axis_tvalid(tx_axis_tvalid), + .m_axis_tready(tx_axis_tready), + .m_axis_tlast(tx_axis_tlast), + .m_axis_tuser(tx_axis_tuser), + // Status signals + .busy() +); + +udp_complete +udp_complete_inst ( + .clk(clk_125mhz), + .rst(rst_125mhz), + // Ethernet frame input + .s_eth_hdr_valid(rx_eth_hdr_valid), + .s_eth_hdr_ready(rx_eth_hdr_ready), + .s_eth_dest_mac(rx_eth_dest_mac), + .s_eth_src_mac(rx_eth_src_mac), + .s_eth_type(rx_eth_type), + .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata), + .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid), + .s_eth_payload_axis_tready(rx_eth_payload_axis_tready), + .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast), + .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser), + // Ethernet frame output + .m_eth_hdr_valid(tx_eth_hdr_valid), + .m_eth_hdr_ready(tx_eth_hdr_ready), + .m_eth_dest_mac(tx_eth_dest_mac), + .m_eth_src_mac(tx_eth_src_mac), + .m_eth_type(tx_eth_type), + .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata), + .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid), + .m_eth_payload_axis_tready(tx_eth_payload_axis_tready), + .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast), + .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser), + // IP frame input + .s_ip_hdr_valid(tx_ip_hdr_valid), + .s_ip_hdr_ready(tx_ip_hdr_ready), + .s_ip_dscp(tx_ip_dscp), + .s_ip_ecn(tx_ip_ecn), + .s_ip_length(tx_ip_length), + .s_ip_ttl(tx_ip_ttl), + .s_ip_protocol(tx_ip_protocol), + .s_ip_source_ip(tx_ip_source_ip), + .s_ip_dest_ip(tx_ip_dest_ip), + .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata), + .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid), + .s_ip_payload_axis_tready(tx_ip_payload_axis_tready), + .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast), + .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser), + // IP frame output + .m_ip_hdr_valid(rx_ip_hdr_valid), + .m_ip_hdr_ready(rx_ip_hdr_ready), + .m_ip_eth_dest_mac(rx_ip_eth_dest_mac), + .m_ip_eth_src_mac(rx_ip_eth_src_mac), + .m_ip_eth_type(rx_ip_eth_type), + .m_ip_version(rx_ip_version), + .m_ip_ihl(rx_ip_ihl), + .m_ip_dscp(rx_ip_dscp), + .m_ip_ecn(rx_ip_ecn), + .m_ip_length(rx_ip_length), + .m_ip_identification(rx_ip_identification), + .m_ip_flags(rx_ip_flags), + .m_ip_fragment_offset(rx_ip_fragment_offset), + .m_ip_ttl(rx_ip_ttl), + .m_ip_protocol(rx_ip_protocol), + .m_ip_header_checksum(rx_ip_header_checksum), + .m_ip_source_ip(rx_ip_source_ip), + .m_ip_dest_ip(rx_ip_dest_ip), + .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata), + .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid), + .m_ip_payload_axis_tready(rx_ip_payload_axis_tready), + .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast), + .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser), + // UDP frame input + .s_udp_hdr_valid(tx_udp_hdr_valid), + .s_udp_hdr_ready(tx_udp_hdr_ready), + .s_udp_ip_dscp(tx_udp_ip_dscp), + .s_udp_ip_ecn(tx_udp_ip_ecn), + .s_udp_ip_ttl(tx_udp_ip_ttl), + .s_udp_ip_source_ip(tx_udp_ip_source_ip), + .s_udp_ip_dest_ip(tx_udp_ip_dest_ip), + .s_udp_source_port(tx_udp_source_port), + .s_udp_dest_port(tx_udp_dest_port), + .s_udp_length(tx_udp_length), + .s_udp_checksum(tx_udp_checksum), + .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata), + .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid), + .s_udp_payload_axis_tready(tx_udp_payload_axis_tready), + .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast), + .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser), + // UDP frame output + .m_udp_hdr_valid(rx_udp_hdr_valid), + .m_udp_hdr_ready(rx_udp_hdr_ready), + .m_udp_eth_dest_mac(rx_udp_eth_dest_mac), + .m_udp_eth_src_mac(rx_udp_eth_src_mac), + .m_udp_eth_type(rx_udp_eth_type), + .m_udp_ip_version(rx_udp_ip_version), + .m_udp_ip_ihl(rx_udp_ip_ihl), + .m_udp_ip_dscp(rx_udp_ip_dscp), + .m_udp_ip_ecn(rx_udp_ip_ecn), + .m_udp_ip_length(rx_udp_ip_length), + .m_udp_ip_identification(rx_udp_ip_identification), + .m_udp_ip_flags(rx_udp_ip_flags), + .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset), + .m_udp_ip_ttl(rx_udp_ip_ttl), + .m_udp_ip_protocol(rx_udp_ip_protocol), + .m_udp_ip_header_checksum(rx_udp_ip_header_checksum), + .m_udp_ip_source_ip(rx_udp_ip_source_ip), + .m_udp_ip_dest_ip(rx_udp_ip_dest_ip), + .m_udp_source_port(rx_udp_source_port), + .m_udp_dest_port(rx_udp_dest_port), + .m_udp_length(rx_udp_length), + .m_udp_checksum(rx_udp_checksum), + .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata), + .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid), + .m_udp_payload_axis_tready(rx_udp_payload_axis_tready), + .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast), + .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser), + // Status signals + .ip_rx_busy(), + .ip_tx_busy(), + .udp_rx_busy(), + .udp_tx_busy(), + .ip_rx_error_header_early_termination(), + .ip_rx_error_payload_early_termination(), + .ip_rx_error_invalid_header(), + .ip_rx_error_invalid_checksum(), + .ip_tx_error_payload_early_termination(), + .ip_tx_error_arp_failed(), + .udp_rx_error_header_early_termination(), + .udp_rx_error_payload_early_termination(), + .udp_tx_error_payload_early_termination(), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(0) +); + +axis_fifo #( + .DEPTH(8192), + .DATA_WIDTH(8), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .FRAME_FIFO(0) +) +udp_payload_fifo ( + .clk(clk_125mhz), + .rst(rst_125mhz), + + // AXI input + .s_axis_tdata(rx_fifo_udp_payload_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid), + .s_axis_tready(rx_fifo_udp_payload_axis_tready), + .s_axis_tlast(rx_fifo_udp_payload_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_udp_payload_axis_tuser), + + // AXI output + .m_axis_tdata(tx_fifo_udp_payload_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid), + .m_axis_tready(tx_fifo_udp_payload_axis_tready), + .m_axis_tlast(tx_fifo_udp_payload_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_udp_payload_axis_tuser), + + // Status + .status_overflow(), + .status_bad_frame(), + .status_good_frame() +); + +endmodule + +`resetall diff --git a/example/RV901T/fpga/tb/fpga_core/Makefile b/example/RV901T/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..c6328a449 --- /dev/null +++ b/example/RV901T/fpga/tb/fpga_core/Makefile @@ -0,0 +1,100 @@ +# Copyright (c) 2020 Alex Forencich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g_rgmii_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g_rgmii.v +VERILOG_SOURCES += ../../lib/eth/rtl/iddr.v +VERILOG_SOURCES += ../../lib/eth/rtl/oddr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ssio_ddr_in.v +VERILOG_SOURCES += ../../lib/eth/rtl/rgmii_phy_if.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_gmii_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_gmii_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete.v +VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen.v +VERILOG_SOURCES += ../../lib/eth/rtl/udp.v +VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete.v +VERILOG_SOURCES += ../../lib/eth/rtl/ip.v +VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v +VERILOG_SOURCES += ../../lib/eth/rtl/arp.v +VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v +VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v +VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v +VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v + +# module parameters +#export PARAM_A ?= value + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + +# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + +# COMPILE_ARGS += -GA=$(PARAM_A) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +include $(shell cocotb-config --makefiles)/Makefile.sim + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst diff --git a/example/RV901T/fpga/tb/fpga_core/test_fpga_core.py b/example/RV901T/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..974a6e66c --- /dev/null +++ b/example/RV901T/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,223 @@ +""" + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +import logging +import os + +from scapy.layers.l2 import Ether, ARP +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.triggers import RisingEdge, Timer + +from cocotbext.eth import GmiiFrame, RgmiiPhy + + +class TB: + def __init__(self, dut, speed=1000e6): + self.dut = dut + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + self.rgmii_phy_0 = RgmiiPhy(dut.phy_0_txd, dut.phy_0_tx_ctl, dut.phy_0_tx_clk, + dut.phy_0_rxd, dut.phy_0_rx_ctl, dut.phy_0_rx_clk, speed=speed) + + self.rgmii_phy_1 = RgmiiPhy(dut.phy_1_txd, dut.phy_1_tx_ctl, dut.phy_1_tx_clk, + dut.phy_1_rxd, dut.phy_1_rx_ctl, dut.phy_1_rx_clk, speed=speed) + + dut.clk_125mhz.setimmediatevalue(0) + dut.clk90_125mhz.setimmediatevalue(0) + + cocotb.start_soon(self._run_clk_125mhz()) + + async def init(self): + + self.dut.rst_125mhz.setimmediatevalue(0) + + for k in range(10): + await RisingEdge(self.dut.clk_125mhz) + + self.dut.rst_125mhz.value = 1 + + for k in range(10): + await RisingEdge(self.dut.clk_125mhz) + + self.dut.rst_125mhz.value = 0 + + async def _run_clk_125mhz(self): + t = Timer(2, 'ns') + while True: + self.dut.clk_125mhz.value = 1 + await t + self.dut.clk90_125mhz.value = 1 + await t + self.dut.clk_125mhz.value = 0 + await t + self.dut.clk90_125mhz.value = 0 + await t + + +@cocotb.test() +async def run_test(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("test UDP RX packet") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00') + ip = IP(src='192.168.1.100', dst='192.168.1.128') + udp = UDP(sport=5678, dport=1234) + test_pkt = eth / ip / udp / payload + + test_frame = GmiiFrame.from_payload(test_pkt.build()) + + await tb.rgmii_phy_0.rx.send(test_frame) + + tb.log.info("receive ARP request") + + rx_frame = await tb.rgmii_phy_0.tx.recv() + + rx_pkt = Ether(bytes(rx_frame.get_payload())) + + tb.log.info("RX packet: %s", repr(rx_pkt)) + + assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff' + assert rx_pkt.src == test_pkt.dst + assert rx_pkt[ARP].hwtype == 1 + assert rx_pkt[ARP].ptype == 0x0800 + assert rx_pkt[ARP].hwlen == 6 + assert rx_pkt[ARP].plen == 4 + assert rx_pkt[ARP].op == 1 + assert rx_pkt[ARP].hwsrc == test_pkt.dst + assert rx_pkt[ARP].psrc == test_pkt[IP].dst + assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00' + assert rx_pkt[ARP].pdst == test_pkt[IP].src + + tb.log.info("send ARP response") + + eth = Ether(src=test_pkt.src, dst=test_pkt.dst) + arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2, + hwsrc=test_pkt.src, psrc=test_pkt[IP].src, + hwdst=test_pkt.dst, pdst=test_pkt[IP].dst) + resp_pkt = eth / arp + + resp_frame = GmiiFrame.from_payload(resp_pkt.build()) + + await tb.rgmii_phy_0.rx.send(resp_frame) + + tb.log.info("receive UDP packet") + + rx_frame = await tb.rgmii_phy_0.tx.recv() + + rx_pkt = Ether(bytes(rx_frame.get_payload())) + + tb.log.info("RX packet: %s", repr(rx_pkt)) + + assert rx_pkt.dst == test_pkt.src + assert rx_pkt.src == test_pkt.dst + assert rx_pkt[IP].dst == test_pkt[IP].src + assert rx_pkt[IP].src == test_pkt[IP].dst + assert rx_pkt[UDP].dport == test_pkt[UDP].sport + assert rx_pkt[UDP].sport == test_pkt[UDP].dport + assert rx_pkt[UDP].payload == test_pkt[UDP].payload + + await RisingEdge(dut.clk_125mhz) + await RisingEdge(dut.clk_125mhz) + + +# cocotb-test + +tests_dir = os.path.abspath(os.path.dirname(__file__)) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(eth_rtl_dir, "eth_mac_1g_rgmii_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_1g_rgmii.v"), + os.path.join(eth_rtl_dir, "iddr.v"), + os.path.join(eth_rtl_dir, "oddr.v"), + os.path.join(eth_rtl_dir, "ssio_ddr_in.v"), + os.path.join(eth_rtl_dir, "rgmii_phy_if.v"), + os.path.join(eth_rtl_dir, "eth_mac_1g.v"), + os.path.join(eth_rtl_dir, "axis_gmii_rx.v"), + os.path.join(eth_rtl_dir, "axis_gmii_tx.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "eth_axis_rx.v"), + os.path.join(eth_rtl_dir, "eth_axis_tx.v"), + os.path.join(eth_rtl_dir, "udp_complete.v"), + os.path.join(eth_rtl_dir, "udp_checksum_gen.v"), + os.path.join(eth_rtl_dir, "udp.v"), + os.path.join(eth_rtl_dir, "udp_ip_rx.v"), + os.path.join(eth_rtl_dir, "udp_ip_tx.v"), + os.path.join(eth_rtl_dir, "ip_complete.v"), + os.path.join(eth_rtl_dir, "ip.v"), + os.path.join(eth_rtl_dir, "ip_eth_rx.v"), + os.path.join(eth_rtl_dir, "ip_eth_tx.v"), + os.path.join(eth_rtl_dir, "ip_arb_mux.v"), + os.path.join(eth_rtl_dir, "arp.v"), + os.path.join(eth_rtl_dir, "arp_cache.v"), + os.path.join(eth_rtl_dir, "arp_eth_rx.v"), + os.path.join(eth_rtl_dir, "arp_eth_tx.v"), + os.path.join(eth_rtl_dir, "eth_arb_mux.v"), + os.path.join(axis_rtl_dir, "arbiter.v"), + os.path.join(axis_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + ] + + parameters = {} + + # parameters['A'] = val + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, "sim_build", + request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) From 7a0e88ffeaa93ec64c58bf0d1e940eeb28eb3538 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 13 Jan 2023 14:57:46 -0800 Subject: [PATCH 7/9] Update vivado.mk Signed-off-by: Alex Forencich --- .../ADM_PCIE_9V3/fpga_10g/common/vivado.mk | 56 +++++++++++-------- .../ADM_PCIE_9V3/fpga_25g/common/vivado.mk | 56 +++++++++++-------- example/AU200/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/AU250/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/AU280/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/AU50/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/Arty/fpga/common/vivado.mk | 56 +++++++++++-------- example/ExaNIC_X10/fpga/common/vivado.mk | 56 +++++++++++-------- example/ExaNIC_X25/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/HTG9200/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/KC705/fpga_gmii/common/vivado.mk | 56 +++++++++++-------- example/KC705/fpga_rgmii/common/vivado.mk | 56 +++++++++++-------- example/KC705/fpga_sgmii/common/vivado.mk | 56 +++++++++++-------- example/NetFPGA_SUME/fpga/common/vivado.mk | 56 +++++++++++-------- example/NexysVideo/fpga/common/vivado.mk | 56 +++++++++++-------- example/VCU108/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/VCU108/fpga_1g/common/vivado.mk | 56 +++++++++++-------- example/VCU118/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/VCU118/fpga_1g/common/vivado.mk | 56 +++++++++++-------- example/VCU118/fpga_25g/common/vivado.mk | 56 +++++++++++-------- example/VCU1525/fpga_10g/common/vivado.mk | 56 +++++++++++-------- example/ZCU102/fpga/common/vivado.mk | 56 +++++++++++-------- example/ZCU106/fpga/common/vivado.mk | 56 +++++++++++-------- example/fb2CG/fpga_10g/common/vivado.mk | 56 +++++++++++-------- 24 files changed, 768 insertions(+), 576 deletions(-) diff --git a/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk b/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk +++ b/example/ADM_PCIE_9V3/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk b/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk +++ b/example/ADM_PCIE_9V3/fpga_25g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/AU200/fpga_10g/common/vivado.mk b/example/AU200/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/AU200/fpga_10g/common/vivado.mk +++ b/example/AU200/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/AU250/fpga_10g/common/vivado.mk b/example/AU250/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/AU250/fpga_10g/common/vivado.mk +++ b/example/AU250/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/AU280/fpga_10g/common/vivado.mk b/example/AU280/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/AU280/fpga_10g/common/vivado.mk +++ b/example/AU280/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/AU50/fpga_10g/common/vivado.mk b/example/AU50/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/AU50/fpga_10g/common/vivado.mk +++ b/example/AU50/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/Arty/fpga/common/vivado.mk b/example/Arty/fpga/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/Arty/fpga/common/vivado.mk +++ b/example/Arty/fpga/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/ExaNIC_X10/fpga/common/vivado.mk b/example/ExaNIC_X10/fpga/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/ExaNIC_X10/fpga/common/vivado.mk +++ b/example/ExaNIC_X10/fpga/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/ExaNIC_X25/fpga_10g/common/vivado.mk b/example/ExaNIC_X25/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/ExaNIC_X25/fpga_10g/common/vivado.mk +++ b/example/ExaNIC_X25/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/HTG9200/fpga_10g/common/vivado.mk b/example/HTG9200/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/HTG9200/fpga_10g/common/vivado.mk +++ b/example/HTG9200/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/KC705/fpga_gmii/common/vivado.mk b/example/KC705/fpga_gmii/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/KC705/fpga_gmii/common/vivado.mk +++ b/example/KC705/fpga_gmii/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/KC705/fpga_rgmii/common/vivado.mk b/example/KC705/fpga_rgmii/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/KC705/fpga_rgmii/common/vivado.mk +++ b/example/KC705/fpga_rgmii/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/KC705/fpga_sgmii/common/vivado.mk b/example/KC705/fpga_sgmii/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/KC705/fpga_sgmii/common/vivado.mk +++ b/example/KC705/fpga_sgmii/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/NetFPGA_SUME/fpga/common/vivado.mk b/example/NetFPGA_SUME/fpga/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/NetFPGA_SUME/fpga/common/vivado.mk +++ b/example/NetFPGA_SUME/fpga/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/NexysVideo/fpga/common/vivado.mk b/example/NexysVideo/fpga/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/NexysVideo/fpga/common/vivado.mk +++ b/example/NexysVideo/fpga/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/VCU108/fpga_10g/common/vivado.mk b/example/VCU108/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/VCU108/fpga_10g/common/vivado.mk +++ b/example/VCU108/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/VCU108/fpga_1g/common/vivado.mk b/example/VCU108/fpga_1g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/VCU108/fpga_1g/common/vivado.mk +++ b/example/VCU108/fpga_1g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/VCU118/fpga_10g/common/vivado.mk b/example/VCU118/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/VCU118/fpga_10g/common/vivado.mk +++ b/example/VCU118/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/VCU118/fpga_1g/common/vivado.mk b/example/VCU118/fpga_1g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/VCU118/fpga_1g/common/vivado.mk +++ b/example/VCU118/fpga_1g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/VCU118/fpga_25g/common/vivado.mk b/example/VCU118/fpga_25g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/VCU118/fpga_25g/common/vivado.mk +++ b/example/VCU118/fpga_25g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/VCU1525/fpga_10g/common/vivado.mk b/example/VCU1525/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/VCU1525/fpga_10g/common/vivado.mk +++ b/example/VCU1525/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/ZCU102/fpga/common/vivado.mk b/example/ZCU102/fpga/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/ZCU102/fpga/common/vivado.mk +++ b/example/ZCU102/fpga/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/ZCU106/fpga/common/vivado.mk b/example/ZCU106/fpga/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/ZCU106/fpga/common/vivado.mk +++ b/example/ZCU106/fpga/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi diff --git a/example/fb2CG/fpga_10g/common/vivado.mk b/example/fb2CG/fpga_10g/common/vivado.mk index 83bcb8d90..21e6a5fed 100644 --- a/example/fb2CG/fpga_10g/common/vivado.mk +++ b/example/fb2CG/fpga_10g/common/vivado.mk @@ -37,6 +37,9 @@ CONFIG ?= config.mk -include ../$(CONFIG) +FPGA_TOP ?= fpga +PROJECT ?= $(FPGA_TOP) + SYN_FILES_REL = $(patsubst %, ../%, $(SYN_FILES)) INC_FILES_REL = $(patsubst %, ../%, $(INC_FILES)) XCI_FILES_REL = $(patsubst %, ../%, $(XCI_FILES)) @@ -67,7 +70,8 @@ tmpclean: -rm -rf create_project.tcl run_synth.tcl run_impl.tcl generate_bit.tcl clean: tmpclean - -rm -rf *.bit program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *.bit *.ltx program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl + -rm -rf *_utilization.rpt *_utilization_hierarchical.rpt distclean: clean -rm -rf rev @@ -77,47 +81,51 @@ distclean: clean ################################################################### # Vivado project file -%.xpr: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) +create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL) rm -rf defines.v touch defines.v for x in $(DEFS); do echo '`define' $$x >> defines.v; done - echo "create_project -force -part $(FPGA_PART) $*" > create_project.tcl - echo "add_files -fileset sources_1 defines.v" >> create_project.tcl - for x in $(SYN_FILES_REL); do echo "add_files -fileset sources_1 $$x" >> create_project.tcl; done - for x in $(XDC_FILES_REL); do echo "add_files -fileset constrs_1 $$x" >> create_project.tcl; done - for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> create_project.tcl; done - for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> create_project.tcl; done - echo "exit" >> create_project.tcl - vivado -nojournal -nolog -mode batch -source create_project.tcl + echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@ + echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@ + echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@ + echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@ + for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done + for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done + +$(PROJECT).xpr: create_project.tcl + vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x) # synthesis run -%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) - echo "open_project $*.xpr" > run_synth.tcl +$(PROJECT).runs/synth_1/$(PROJECT).dcp: $(PROJECT).xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) + echo "open_project $(PROJECT).xpr" > run_synth.tcl echo "reset_run synth_1" >> run_synth.tcl echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl echo "wait_on_run synth_1" >> run_synth.tcl - echo "exit" >> run_synth.tcl vivado -nojournal -nolog -mode batch -source run_synth.tcl # implementation run -%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp - echo "open_project $*.xpr" > run_impl.tcl +$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp + echo "open_project $(PROJECT).xpr" > run_impl.tcl echo "reset_run impl_1" >> run_impl.tcl echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl echo "wait_on_run impl_1" >> run_impl.tcl - echo "exit" >> run_impl.tcl + echo "open_run impl_1" >> run_impl.tcl + echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl + echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl vivado -nojournal -nolog -mode batch -source run_impl.tcl # bit file -%.bit: %.runs/impl_1/%_routed.dcp - echo "open_project $*.xpr" > generate_bit.tcl +$(PROJECT).bit $(PROJECT).ltx: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp + echo "open_project $(PROJECT).xpr" > generate_bit.tcl echo "open_run impl_1" >> generate_bit.tcl - echo "write_bitstream -force $*.bit" >> generate_bit.tcl - echo "exit" >> generate_bit.tcl + echo "write_bitstream -force $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl + echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl vivado -nojournal -nolog -mode batch -source generate_bit.tcl + ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit . + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi mkdir -p rev - EXT=bit; COUNT=100; \ - while [ -e rev/$*_rev$$COUNT.$$EXT ]; \ + COUNT=100; \ + while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \ do COUNT=$$((COUNT+1)); done; \ - cp $@ rev/$*_rev$$COUNT.$$EXT; \ - echo "Output: rev/$*_rev$$COUNT.$$EXT"; + cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \ + if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi From cb1dc8fb153e6fc38bef51787a697d86124503f8 Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Fri, 13 Jan 2023 15:47:30 -0800 Subject: [PATCH 8/9] Optimize FCS verification in 10G/25G MAC modules Signed-off-by: Alex Forencich --- rtl/axis_baser_rx_64.v | 135 +++++++++++++++--------------------- rtl/axis_xgmii_rx_32.v | 103 +++++++++++++++------------- rtl/axis_xgmii_rx_64.v | 152 ++++++++++++++++++----------------------- 3 files changed, 175 insertions(+), 215 deletions(-) diff --git a/rtl/axis_baser_rx_64.v b/rtl/axis_baser_rx_64.v index 639325904..e22b9986f 100644 --- a/rtl/axis_baser_rx_64.v +++ b/rtl/axis_baser_rx_64.v @@ -163,7 +163,6 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; -reg update_crc_last; reg lanes_swapped = 1'b0; reg [31:0] swap_data = 32'd0; @@ -171,9 +170,10 @@ reg [31:0] swap_data = 32'd0; reg delay_type_valid = 1'b0; reg [3:0] delay_type = INPUT_TYPE_IDLE; +reg [DATA_WIDTH-1:0] encoded_rx_data_masked = {DATA_WIDTH{1'b0}}; + reg [DATA_WIDTH-1:0] input_data_d0 = {DATA_WIDTH{1'b0}}; reg [DATA_WIDTH-1:0] input_data_d1 = {DATA_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] input_data_crc = {DATA_WIDTH{1'b0}}; reg [3:0] input_type_d0 = INPUT_TYPE_IDLE; reg [3:0] input_type_d1 = INPUT_TYPE_IDLE; @@ -194,17 +194,20 @@ reg [PTP_TS_WIDTH-1:0] ptp_ts_adj_reg = 0; reg ptp_ts_borrow_reg = 0; reg [31:0] crc_state = 32'hFFFFFFFF; -reg [31:0] crc_state3 = 32'hFFFFFFFF; -wire [31:0] crc_next[7:0]; +wire [31:0] crc_next; -wire crc_valid0 = crc_next[0] == ~32'h2144df1c; -wire crc_valid1 = crc_next[1] == ~32'h2144df1c; -wire crc_valid2 = crc_next[2] == ~32'h2144df1c; -wire crc_valid3 = crc_next[3] == ~32'h2144df1c; -wire crc_valid7 = crc_next[7] == ~32'h2144df1c; +wire [7:0] crc_valid; +reg [7:0] crc_valid_save; -reg crc_valid7_save = 1'b0; +assign crc_valid[7] = crc_next == ~32'h2144df1c; +assign crc_valid[6] = crc_next == ~32'hc622f71d; +assign crc_valid[5] = crc_next == ~32'hb1c2a1a3; +assign crc_valid[4] = crc_next == ~32'h9d6cdf7e; +assign crc_valid[3] = crc_next == ~32'h6522df69; +assign crc_valid[2] = crc_next == ~32'he60914ae; +assign crc_valid[1] = crc_next == ~32'he38a6876; +assign crc_valid[0] = crc_next == ~32'h6b87b1ec; assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; @@ -217,29 +220,6 @@ assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; assign rx_bad_block = rx_bad_block_reg; -generate - genvar n; - - for (n = 0; n < 4; n = n + 1) begin : crc - lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8*(n+1)), - .STYLE("AUTO") - ) - eth_crc ( - .data_in(input_data_crc[0 +: 8*(n+1)]), - .state_in(crc_state3), - .data_out(), - .state_out(crc_next[n]) - ); - end - -endgenerate - lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -249,18 +229,42 @@ lfsr #( .DATA_WIDTH(64), .STYLE("AUTO") ) -eth_crc_64 ( +eth_crc ( .data_in(input_data_d0), .state_in(crc_state), .data_out(), - .state_out(crc_next[7]) + .state_out(crc_next) ); +// Mask input data +integer j; + +always @* begin + // minimal checks of control info to simplify datapath logic, full checks performed later + if (encoded_rx_hdr[0] == 0) begin + encoded_rx_data_masked = encoded_rx_data; + end else if (encoded_rx_data[7]) begin + // terminate + case (encoded_rx_data[6:4]) + 3'd0: encoded_rx_data_masked = 64'd0; + 3'd1: encoded_rx_data_masked = {56'd0, encoded_rx_data[15:8]}; + 3'd2: encoded_rx_data_masked = {48'd0, encoded_rx_data[23:8]}; + 3'd3: encoded_rx_data_masked = {40'd0, encoded_rx_data[31:8]}; + 3'd4: encoded_rx_data_masked = {32'd0, encoded_rx_data[39:8]}; + 3'd5: encoded_rx_data_masked = {24'd0, encoded_rx_data[47:8]}; + 3'd6: encoded_rx_data_masked = {16'd0, encoded_rx_data[55:8]}; + 3'd7: encoded_rx_data_masked = {8'd0, encoded_rx_data[63:8]}; + endcase + end else begin + // start, OS, etc. + encoded_rx_data_masked = {encoded_rx_data[63:8], 8'd0}; + end +end + always @* begin state_next = STATE_IDLE; reset_crc = 1'b0; - update_crc_last = 1'b0; m_axis_tdata_next = input_data_d1; m_axis_tkeep_next = 8'd0; @@ -300,7 +304,6 @@ always @* begin if (input_type_d0[3]) begin // INPUT_TYPE_TERM_* reset_crc = 1'b1; - update_crc_last = 1'b1; end if (input_type_d0 == INPUT_TYPE_DATA) begin @@ -317,11 +320,11 @@ always @* begin INPUT_TYPE_TERM_4: m_axis_tkeep_next = 8'b11111111; endcase m_axis_tlast_next = 1'b1; - if ((input_type_d0 == INPUT_TYPE_TERM_0 && crc_valid7_save) || - (input_type_d0 == INPUT_TYPE_TERM_1 && crc_valid0) || - (input_type_d0 == INPUT_TYPE_TERM_2 && crc_valid1) || - (input_type_d0 == INPUT_TYPE_TERM_3 && crc_valid2) || - (input_type_d0 == INPUT_TYPE_TERM_4 && crc_valid3)) begin + if ((input_type_d0 == INPUT_TYPE_TERM_0 && crc_valid_save[7]) || + (input_type_d0 == INPUT_TYPE_TERM_1 && crc_valid[0]) || + (input_type_d0 == INPUT_TYPE_TERM_2 && crc_valid[1]) || + (input_type_d0 == INPUT_TYPE_TERM_3 && crc_valid[2]) || + (input_type_d0 == INPUT_TYPE_TERM_4 && crc_valid[3])) begin // CRC valid end else begin m_axis_tuser_next[0] = 1'b1; @@ -358,9 +361,9 @@ always @* begin INPUT_TYPE_TERM_7: m_axis_tkeep_next = 8'b00000111; endcase - if ((input_type_d1 == INPUT_TYPE_TERM_5 && crc_valid0) || - (input_type_d1 == INPUT_TYPE_TERM_6 && crc_valid1) || - (input_type_d1 == INPUT_TYPE_TERM_7 && crc_valid2)) begin + if ((input_type_d1 == INPUT_TYPE_TERM_5 && crc_valid_save[4]) || + (input_type_d1 == INPUT_TYPE_TERM_6 && crc_valid_save[5]) || + (input_type_d1 == INPUT_TYPE_TERM_7 && crc_valid_save[6])) begin // CRC valid end else begin m_axis_tuser_next[0] = 1'b1; @@ -389,11 +392,7 @@ always @(posedge clk) begin delay_type_valid <= 1'b0; - if (encoded_rx_hdr == SYNC_DATA) begin - swap_data <= encoded_rx_data[63:32]; - end else begin - swap_data <= {8'd0, encoded_rx_data[63:40]}; - end + swap_data <= encoded_rx_data_masked[63:32]; if (PTP_TS_ENABLE && PTP_TS_WIDTH == 96) begin // ns field rollover @@ -407,8 +406,7 @@ always @(posedge clk) begin lanes_swapped <= 1'b0; start_packet_reg <= 2'b01; input_type_d0 <= INPUT_TYPE_START_0; - input_data_d0 <= encoded_rx_data; - input_data_crc <= encoded_rx_data; + input_data_d0 <= encoded_rx_data_masked; if (PTP_TS_WIDTH == 96) begin ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); @@ -426,8 +424,7 @@ always @(posedge clk) begin end else begin input_type_d0 <= INPUT_TYPE_IDLE; end - input_data_d0 <= {encoded_rx_data[31:0], swap_data}; - input_data_crc <= {encoded_rx_data[31:0], swap_data}; + input_data_d0 <= {encoded_rx_data_masked[31:0], swap_data}; if (PTP_TS_WIDTH == 96) begin ptp_ts_reg[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); @@ -471,13 +468,7 @@ always @(posedge clk) begin rx_bad_block_reg <= 1'b1; input_type_d0 <= INPUT_TYPE_ERROR; end - if (encoded_rx_hdr == SYNC_DATA) begin - input_data_d0 <= {encoded_rx_data[31:0], swap_data}; - input_data_crc <= {encoded_rx_data[31:0], swap_data}; - end else begin - input_data_d0 <= {encoded_rx_data[39:8], swap_data}; - input_data_crc <= {encoded_rx_data[39:8], swap_data}; - end + input_data_d0 <= {encoded_rx_data_masked[31:0], swap_data}; end else begin if (encoded_rx_hdr == SYNC_DATA) begin input_type_d0 <= INPUT_TYPE_DATA; @@ -500,13 +491,7 @@ always @(posedge clk) begin rx_bad_block_reg <= 1'b1; input_type_d0 <= INPUT_TYPE_ERROR; end - if (encoded_rx_hdr == SYNC_DATA) begin - input_data_d0 <= encoded_rx_data; - input_data_crc <= encoded_rx_data; - end else begin - input_data_d0 <= {8'd0, encoded_rx_data[63:8]}; - input_data_crc <= {8'd0, encoded_rx_data[63:8]}; - end + input_data_d0 <= encoded_rx_data_masked; end if (encoded_rx_hdr == SYNC_DATA) begin @@ -534,20 +519,10 @@ always @(posedge clk) begin if (reset_crc) begin crc_state <= 32'hFFFFFFFF; end else begin - crc_state <= crc_next[7]; + crc_state <= crc_next; end - if (update_crc_last) begin - crc_state3 <= crc_next[3]; - end else begin - crc_state3 <= crc_next[7]; - end - - crc_valid7_save <= crc_valid7; - - if (state_next == STATE_LAST) begin - input_data_crc[31:0] <= input_data_crc[63:32]; - end + crc_valid_save <= crc_valid; if (rst) begin state_reg <= STATE_IDLE; diff --git a/rtl/axis_xgmii_rx_32.v b/rtl/axis_xgmii_rx_32.v index bf10c4dec..6a5aa92f5 100644 --- a/rtl/axis_xgmii_rx_32.v +++ b/rtl/axis_xgmii_rx_32.v @@ -108,13 +108,18 @@ reg reset_crc; reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next; +reg [DATA_WIDTH-1:0] xgmii_rxd_masked = {DATA_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_term = {CTRL_WIDTH{1'b0}}; + reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}}; reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}}; reg [DATA_WIDTH-1:0] xgmii_rxd_d2 = {DATA_WIDTH{1'b0}}; reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}}; -reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}}; -reg [CTRL_WIDTH-1:0] xgmii_rxc_d2 = {CTRL_WIDTH{1'b0}}; + +reg xgmii_start_d0 = 1'b0; +reg xgmii_start_d1 = 1'b0; +reg xgmii_start_d2 = 1'b0; reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; @@ -128,17 +133,15 @@ reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg [31:0] crc_state = 32'hFFFFFFFF; -wire [31:0] crc_next[3:0]; +wire [31:0] crc_next; -wire crc_valid0 = crc_next[0] == ~32'h2144df1c; -wire crc_valid1 = crc_next[1] == ~32'h2144df1c; -wire crc_valid2 = crc_next[2] == ~32'h2144df1c; -wire crc_valid3 = crc_next[3] == ~32'h2144df1c; +wire [3:0] crc_valid; +reg [3:0] crc_valid_save; -reg crc_valid0_save = 1'b0; -reg crc_valid1_save = 1'b0; -reg crc_valid2_save = 1'b0; -reg crc_valid3_save = 1'b0; +assign crc_valid[3] = crc_next == ~32'h2144df1c; +assign crc_valid[2] = crc_next == ~32'hc622f71d; +assign crc_valid[1] = crc_next == ~32'hb1c2a1a3; +assign crc_valid[0] = crc_next == ~32'h9d6cdf7e; assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; @@ -152,28 +155,31 @@ assign error_bad_fcs = error_bad_fcs_reg; wire last_cycle = state_reg == STATE_LAST; -generate - genvar n; +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(32), + .STYLE("AUTO") +) +eth_crc ( + .data_in(xgmii_rxd_d0), + .state_in(crc_state), + .data_out(), + .state_out(crc_next) +); - for (n = 0; n < 4; n = n + 1) begin : crc - lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8*(n+1)), - .STYLE("AUTO") - ) - eth_crc ( - .data_in(xgmii_rxd_d0[0 +: 8*(n+1)]), - .state_in(crc_state), - .data_out(), - .state_out(crc_next[n]) - ); +// Mask input data +integer j; + +always @* begin + for (j = 0; j < 4; j = j + 1) begin + xgmii_rxd_masked[j*8 +: 8] = xgmii_rxc[j] ? 8'd0 : xgmii_rxd[j*8 +: 8]; + xgmii_term[j] = xgmii_rxc[j] && (xgmii_rxd[j*8 +: 8] == XGMII_TERM); end - -endgenerate +end // detect control characters reg [3:0] detect_term = 4'd0; @@ -238,7 +244,7 @@ always @* begin // idle state - wait for packet reset_crc = 1'b1; - if (xgmii_rxc_d2[0] && xgmii_rxd_d2[7:0] == XGMII_START) begin + if (xgmii_start_d2) begin // start condition if (control_masked) begin // control or error characters in first data word @@ -291,7 +297,7 @@ always @* begin // end this cycle m_axis_tkeep_next = 4'b1111; m_axis_tlast_next = 1'b1; - if (detect_term[0] && crc_valid3_save) begin + if (detect_term[0] && crc_valid_save[3]) begin // CRC valid end else begin m_axis_tuser_next[0] = 1'b1; @@ -317,9 +323,9 @@ always @* begin reset_crc = 1'b1; - if ((detect_term_save[1] && crc_valid0_save) || - (detect_term_save[2] && crc_valid1_save) || - (detect_term_save[3] && crc_valid2_save)) begin + if ((detect_term_save[1] && crc_valid_save[0]) || + (detect_term_save[2] && crc_valid_save[1]) || + (detect_term_save[3] && crc_valid_save[2])) begin // CRC valid end else begin m_axis_tuser_next[0] = 1'b1; @@ -347,30 +353,26 @@ always @(posedge clk) begin last_cycle_tkeep_reg <= last_cycle_tkeep_next; - for (i = 0; i < 4; i = i + 1) begin - detect_term[i] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); - end - + detect_term <= xgmii_term; detect_term_save <= detect_term; if (reset_crc) begin crc_state <= 32'hFFFFFFFF; end else begin - crc_state <= crc_next[3]; + crc_state <= crc_next; end - crc_valid0_save <= crc_valid0; - crc_valid1_save <= crc_valid1; - crc_valid2_save <= crc_valid2; - crc_valid3_save <= crc_valid3; + crc_valid_save <= crc_valid; - xgmii_rxd_d0 <= xgmii_rxd; + xgmii_rxd_d0 <= xgmii_rxd_masked; xgmii_rxc_d0 <= xgmii_rxc; xgmii_rxd_d1 <= xgmii_rxd_d0; - xgmii_rxc_d1 <= xgmii_rxc_d0; - xgmii_rxc_d2 <= xgmii_rxc_d1; xgmii_rxd_d2 <= xgmii_rxd_d1; + xgmii_start_d0 <= xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START; + xgmii_start_d1 <= xgmii_start_d0; + xgmii_start_d2 <= xgmii_start_d1; + if (rst) begin state_reg <= STATE_IDLE; @@ -381,7 +383,10 @@ always @(posedge clk) begin error_bad_fcs_reg <= 1'b0; xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; - xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; + + xgmii_start_d0 <= 1'b0; + xgmii_start_d1 <= 1'b0; + xgmii_start_d2 <= 1'b0; end end diff --git a/rtl/axis_xgmii_rx_64.v b/rtl/axis_xgmii_rx_64.v index 02a24044b..8d3f8b9db 100644 --- a/rtl/axis_xgmii_rx_64.v +++ b/rtl/axis_xgmii_rx_64.v @@ -106,20 +106,25 @@ reg [1:0] state_reg = STATE_IDLE, state_next; // datapath control signals reg reset_crc; -reg update_crc_last; reg [7:0] last_cycle_tkeep_reg = 8'd0, last_cycle_tkeep_next; reg lanes_swapped = 1'b0; reg [31:0] swap_rxd = 32'd0; reg [3:0] swap_rxc = 4'd0; +reg [3:0] swap_rxc_term = 4'd0; + +reg [DATA_WIDTH-1:0] xgmii_rxd_masked = {DATA_WIDTH{1'b0}}; +reg [CTRL_WIDTH-1:0] xgmii_term = {CTRL_WIDTH{1'b0}}; reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}}; reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] xgmii_rxd_crc = {DATA_WIDTH{1'b0}}; reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}}; -reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}}; + +reg xgmii_start_swap = 1'b0; +reg xgmii_start_d0 = 1'b0; +reg xgmii_start_d1 = 1'b0; reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next; @@ -136,17 +141,20 @@ reg [PTP_TS_WIDTH-1:0] ptp_ts_adj_reg = 0; reg ptp_ts_borrow_reg = 0; reg [31:0] crc_state = 32'hFFFFFFFF; -reg [31:0] crc_state3 = 32'hFFFFFFFF; -wire [31:0] crc_next[7:0]; +wire [31:0] crc_next; -wire crc_valid0 = crc_next[0] == ~32'h2144df1c; -wire crc_valid1 = crc_next[1] == ~32'h2144df1c; -wire crc_valid2 = crc_next[2] == ~32'h2144df1c; -wire crc_valid3 = crc_next[3] == ~32'h2144df1c; -wire crc_valid7 = crc_next[7] == ~32'h2144df1c; +wire [7:0] crc_valid; +reg [7:0] crc_valid_save; -reg crc_valid7_save = 1'b0; +assign crc_valid[7] = crc_next == ~32'h2144df1c; +assign crc_valid[6] = crc_next == ~32'hc622f71d; +assign crc_valid[5] = crc_next == ~32'hb1c2a1a3; +assign crc_valid[4] = crc_next == ~32'h9d6cdf7e; +assign crc_valid[3] = crc_next == ~32'h6522df69; +assign crc_valid[2] = crc_next == ~32'he60914ae; +assign crc_valid[1] = crc_next == ~32'he38a6876; +assign crc_valid[0] = crc_next == ~32'h6b87b1ec; assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tkeep = m_axis_tkeep_reg; @@ -158,29 +166,6 @@ assign start_packet = start_packet_reg; assign error_bad_frame = error_bad_frame_reg; assign error_bad_fcs = error_bad_fcs_reg; -generate - genvar n; - - for (n = 0; n < 4; n = n + 1) begin : crc - lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8*(n+1)), - .STYLE("AUTO") - ) - eth_crc ( - .data_in(xgmii_rxd_crc[0 +: 8*(n+1)]), - .state_in(crc_state3), - .data_out(), - .state_out(crc_next[n]) - ); - end - -endgenerate - lfsr #( .LFSR_WIDTH(32), .LFSR_POLY(32'h4c11db7), @@ -190,13 +175,23 @@ lfsr #( .DATA_WIDTH(64), .STYLE("AUTO") ) -eth_crc_64 ( - .data_in(xgmii_rxd_crc), +eth_crc ( + .data_in(xgmii_rxd_d0), .state_in(crc_state), .data_out(), - .state_out(crc_next[7]) + .state_out(crc_next) ); +// Mask input data +integer j; + +always @* begin + for (j = 0; j < 8; j = j + 1) begin + xgmii_rxd_masked[j*8 +: 8] = xgmii_rxc[j] ? 8'd0 : xgmii_rxd[j*8 +: 8]; + xgmii_term[j] = xgmii_rxc[j] && (xgmii_rxd[j*8 +: 8] == XGMII_TERM); + end +end + // detect control characters reg [7:0] detect_term = 8'd0; @@ -257,7 +252,6 @@ always @* begin state_next = STATE_IDLE; reset_crc = 1'b0; - update_crc_last = 1'b0; last_cycle_tkeep_next = last_cycle_tkeep_reg; @@ -276,7 +270,7 @@ always @* begin // idle state - wait for packet reset_crc = 1'b1; - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin + if (xgmii_start_d1) begin // start condition if (PTP_TS_ENABLE) begin @@ -312,7 +306,6 @@ always @* begin if (detect_term) begin reset_crc = 1'b1; - update_crc_last = 1'b1; end if (control_masked) begin @@ -327,11 +320,11 @@ always @* begin // end this cycle m_axis_tkeep_next = {tkeep_mask[3:0], 4'b1111}; m_axis_tlast_next = 1'b1; - if ((detect_term[0] && crc_valid7_save) || - (detect_term[1] && crc_valid0) || - (detect_term[2] && crc_valid1) || - (detect_term[3] && crc_valid2) || - (detect_term[4] && crc_valid3)) begin + if ((detect_term[0] && crc_valid_save[7]) || + (detect_term[1] && crc_valid[0]) || + (detect_term[2] && crc_valid[1]) || + (detect_term[3] && crc_valid[2]) || + (detect_term[4] && crc_valid[3])) begin // CRC valid end else begin m_axis_tuser_next[0] = 1'b1; @@ -357,9 +350,9 @@ always @* begin reset_crc = 1'b1; - if ((detect_term_save[5] && crc_valid0) || - (detect_term_save[6] && crc_valid1) || - (detect_term_save[7] && crc_valid2)) begin + if ((detect_term_save[5] && crc_valid_save[4]) || + (detect_term_save[6] && crc_valid_save[5]) || + (detect_term_save[7] && crc_valid_save[6])) begin // CRC valid end else begin m_axis_tuser_next[0] = 1'b1; @@ -367,7 +360,7 @@ always @* begin error_bad_fcs_next = 1'b1; end - if (xgmii_rxc_d1[0] && xgmii_rxd_d1[7:0] == XGMII_START) begin + if (xgmii_start_d1) begin // start condition if (control_masked) begin // control or error characters in first data word @@ -406,8 +399,12 @@ always @(posedge clk) begin detect_term_save <= detect_term; - swap_rxd <= xgmii_rxd[63:32]; + swap_rxd <= xgmii_rxd_masked[63:32]; swap_rxc <= xgmii_rxc[7:4]; + swap_rxc_term <= xgmii_term[7:4]; + + xgmii_start_swap <= 1'b0; + xgmii_start_d0 <= xgmii_start_swap; if (PTP_TS_ENABLE && PTP_TS_WIDTH == 96) begin // ns field rollover @@ -420,13 +417,12 @@ always @(posedge clk) begin if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin lanes_swapped <= 1'b0; start_packet_reg <= 2'b01; - xgmii_rxd_d0 <= xgmii_rxd; - xgmii_rxd_crc <= xgmii_rxd; + xgmii_rxd_d0 <= xgmii_rxd_masked; xgmii_rxc_d0 <= xgmii_rxc; + + xgmii_start_d0 <= 1'b1; - for (i = 0; i < 8; i = i + 1) begin - detect_term[i] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); - end + detect_term <= xgmii_term; if (PTP_TS_WIDTH == 96) begin ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS); @@ -437,14 +433,12 @@ always @(posedge clk) begin end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin lanes_swapped <= 1'b1; start_packet_reg <= 2'b10; - xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; - xgmii_rxd_crc <= {xgmii_rxd[31:0], swap_rxd}; + xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd}; xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; - for (i = 0; i < 4; i = i + 1) begin - detect_term[i] <= swap_rxc[i] && (swap_rxd[i*8 +: 8] == XGMII_TERM); - detect_term[i+4] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); - end + xgmii_start_swap <= 1'b1; + + detect_term <= {xgmii_term[3:0], swap_rxc_term}; if (PTP_TS_WIDTH == 96) begin ptp_ts_reg[45:0] <= ptp_ts[45:0] + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); @@ -453,44 +447,27 @@ always @(posedge clk) begin ptp_ts_reg <= ptp_ts + (((PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 3) >> 1); end end else if (lanes_swapped) begin - xgmii_rxd_d0 <= {xgmii_rxd[31:0], swap_rxd}; - xgmii_rxd_crc <= {xgmii_rxd[31:0], swap_rxd}; + xgmii_rxd_d0 <= {xgmii_rxd_masked[31:0], swap_rxd}; xgmii_rxc_d0 <= {xgmii_rxc[3:0], swap_rxc}; - for (i = 0; i < 4; i = i + 1) begin - detect_term[i] <= swap_rxc[i] && (swap_rxd[i*8 +: 8] == XGMII_TERM); - detect_term[i+4] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); - end + detect_term <= {xgmii_term[3:0], swap_rxc_term}; end else begin - xgmii_rxd_d0 <= xgmii_rxd; - xgmii_rxd_crc <= xgmii_rxd; + xgmii_rxd_d0 <= xgmii_rxd_masked; xgmii_rxc_d0 <= xgmii_rxc; - for (i = 0; i < 8; i = i + 1) begin - detect_term[i] <= xgmii_rxc[i] && (xgmii_rxd[i*8 +: 8] == XGMII_TERM); - end + detect_term <= xgmii_term; end if (reset_crc) begin crc_state <= 32'hFFFFFFFF; end else begin - crc_state <= crc_next[7]; + crc_state <= crc_next; end - if (update_crc_last) begin - crc_state3 <= crc_next[3]; - end else begin - crc_state3 <= crc_next[7]; - end - - crc_valid7_save <= crc_valid7; - - if (state_next == STATE_LAST) begin - xgmii_rxd_crc[31:0] <= xgmii_rxd_crc[63:32]; - end + crc_valid_save <= crc_valid; xgmii_rxd_d1 <= xgmii_rxd_d0; - xgmii_rxc_d1 <= xgmii_rxc_d0; + xgmii_start_d1 <= xgmii_start_d0; if (rst) begin state_reg <= STATE_IDLE; @@ -502,7 +479,10 @@ always @(posedge clk) begin error_bad_fcs_reg <= 1'b0; xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}}; - xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}}; + + xgmii_start_swap <= 1'b0; + xgmii_start_d0 <= 1'b0; + xgmii_start_d1 <= 1'b0; lanes_swapped <= 1'b0; end From 450765187efd97c83b0a5336cf8ea50ea4f3ac1a Mon Sep 17 00:00:00 2001 From: Alex Forencich Date: Sun, 15 Jan 2023 12:36:03 -0800 Subject: [PATCH 9/9] Update lfsr.v Signed-off-by: Alex Forencich --- rtl/lfsr.v | 343 +++++++++++++++++++++++++++-------------------------- 1 file changed, 172 insertions(+), 171 deletions(-) diff --git a/rtl/lfsr.v b/rtl/lfsr.v index 024724475..e3a472e3f 100644 --- a/rtl/lfsr.v +++ b/rtl/lfsr.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2016-2018 Alex Forencich +Copyright (c) 2016-2023 Alex Forencich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -184,6 +184,7 @@ Name Configuration Length Polynomial Initial value Note CRC16-IBM Galois, bit-reverse 16 16'h8005 16'hffff CRC16-CCITT Galois 16 16'h1021 16'h1d0f CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output +CRC32C Galois, bit-reverse 32 32'h1edc6f41 32'hffffffff iSCSI, Intel CRC32 instruction; invert final output PRBS6 Fibonacci 6 6'h21 any PRBS7 Fibonacci 7 7'h41 any PRBS9 Fibonacci 9 9'h021 any ITU V.52 @@ -200,161 +201,147 @@ PRBS31 Fibonacci, inverted 31 31'h10000001 any */ -reg [LFSR_WIDTH-1:0] lfsr_mask_state[LFSR_WIDTH-1:0]; -reg [DATA_WIDTH-1:0] lfsr_mask_data[LFSR_WIDTH-1:0]; -reg [LFSR_WIDTH-1:0] output_mask_state[DATA_WIDTH-1:0]; -reg [DATA_WIDTH-1:0] output_mask_data[DATA_WIDTH-1:0]; +function [LFSR_WIDTH+DATA_WIDTH-1:0] lfsr_mask(input [31:0] index); + reg [LFSR_WIDTH-1:0] lfsr_mask_state[LFSR_WIDTH-1:0]; + reg [DATA_WIDTH-1:0] lfsr_mask_data[LFSR_WIDTH-1:0]; + reg [LFSR_WIDTH-1:0] output_mask_state[DATA_WIDTH-1:0]; + reg [DATA_WIDTH-1:0] output_mask_data[DATA_WIDTH-1:0]; -reg [LFSR_WIDTH-1:0] state_val = 0; -reg [DATA_WIDTH-1:0] data_val = 0; + reg [LFSR_WIDTH-1:0] state_val; + reg [DATA_WIDTH-1:0] data_val; -integer i, j, k; + reg [DATA_WIDTH-1:0] data_mask; -initial begin - // init bit masks - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - lfsr_mask_state[i] = {LFSR_WIDTH{1'b0}}; - lfsr_mask_state[i][i] = 1'b1; - lfsr_mask_data[i] = {DATA_WIDTH{1'b0}}; - end - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - output_mask_state[i] = {LFSR_WIDTH{1'b0}}; - if (i < LFSR_WIDTH) begin - output_mask_state[i][i] = 1'b1; - end - output_mask_data[i] = {DATA_WIDTH{1'b0}}; - end + integer i, j; - // simulate shift register - if (LFSR_CONFIG == "FIBONACCI") begin - // Fibonacci configuration - for (i = DATA_WIDTH-1; i >= 0; i = i - 1) begin - // determine shift in value - // current value in last FF, XOR with input data bit (MSB first) - state_val = lfsr_mask_state[LFSR_WIDTH-1]; - data_val = lfsr_mask_data[LFSR_WIDTH-1]; - data_val = data_val ^ (1 << i); - - // add XOR inputs from correct indicies - for (j = 1; j < LFSR_WIDTH; j = j + 1) begin - if (LFSR_POLY & (1 << j)) begin - state_val = lfsr_mask_state[j-1] ^ state_val; - data_val = lfsr_mask_data[j-1] ^ data_val; - end - end - - // shift - for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin - lfsr_mask_state[j] = lfsr_mask_state[j-1]; - lfsr_mask_data[j] = lfsr_mask_data[j-1]; - end - for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin - output_mask_state[j] = output_mask_state[j-1]; - output_mask_data[j] = output_mask_data[j-1]; - end - output_mask_state[0] = state_val; - output_mask_data[0] = data_val; - if (LFSR_FEED_FORWARD) begin - // only shift in new input data - state_val = {LFSR_WIDTH{1'b0}}; - data_val = 1 << i; - end - lfsr_mask_state[0] = state_val; - lfsr_mask_data[0] = data_val; - end - end else if (LFSR_CONFIG == "GALOIS") begin - // Galois configuration - for (i = DATA_WIDTH-1; i >= 0; i = i - 1) begin - // determine shift in value - // current value in last FF, XOR with input data bit (MSB first) - state_val = lfsr_mask_state[LFSR_WIDTH-1]; - data_val = lfsr_mask_data[LFSR_WIDTH-1]; - data_val = data_val ^ (1 << i); - - // shift - for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin - lfsr_mask_state[j] = lfsr_mask_state[j-1]; - lfsr_mask_data[j] = lfsr_mask_data[j-1]; - end - for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin - output_mask_state[j] = output_mask_state[j-1]; - output_mask_data[j] = output_mask_data[j-1]; - end - output_mask_state[0] = state_val; - output_mask_data[0] = data_val; - if (LFSR_FEED_FORWARD) begin - // only shift in new input data - state_val = {LFSR_WIDTH{1'b0}}; - data_val = 1 << i; - end - lfsr_mask_state[0] = state_val; - lfsr_mask_data[0] = data_val; - - // add XOR inputs at correct indicies - for (j = 1; j < LFSR_WIDTH; j = j + 1) begin - if (LFSR_POLY & (1 << j)) begin - lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val; - lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val; - end - end - end - end else begin - $error("Error: unknown configuration setting!"); - $finish; - end - - // reverse bits if selected - if (REVERSE) begin - // reverse order - for (i = 0; i < LFSR_WIDTH/2; i = i + 1) begin - state_val = lfsr_mask_state[i]; - data_val = lfsr_mask_data[i]; - lfsr_mask_state[i] = lfsr_mask_state[LFSR_WIDTH-i-1]; - lfsr_mask_data[i] = lfsr_mask_data[LFSR_WIDTH-i-1]; - lfsr_mask_state[LFSR_WIDTH-i-1] = state_val; - lfsr_mask_data[LFSR_WIDTH-i-1] = data_val; - end - for (i = 0; i < DATA_WIDTH/2; i = i + 1) begin - state_val = output_mask_state[i]; - data_val = output_mask_data[i]; - output_mask_state[i] = output_mask_state[DATA_WIDTH-i-1]; - output_mask_data[i] = output_mask_data[DATA_WIDTH-i-1]; - output_mask_state[DATA_WIDTH-i-1] = state_val; - output_mask_data[DATA_WIDTH-i-1] = data_val; - end - // reverse bits + begin + // init bit masks for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - state_val = 0; - for (j = 0; j < LFSR_WIDTH; j = j + 1) begin - state_val[j] = lfsr_mask_state[i][LFSR_WIDTH-j-1]; - end - lfsr_mask_state[i] = state_val; - - data_val = 0; - for (j = 0; j < DATA_WIDTH; j = j + 1) begin - data_val[j] = lfsr_mask_data[i][DATA_WIDTH-j-1]; - end - lfsr_mask_data[i] = data_val; + lfsr_mask_state[i] = 0; + lfsr_mask_state[i][i] = 1'b1; + lfsr_mask_data[i] = 0; end for (i = 0; i < DATA_WIDTH; i = i + 1) begin - state_val = 0; - for (j = 0; j < LFSR_WIDTH; j = j + 1) begin - state_val[j] = output_mask_state[i][LFSR_WIDTH-j-1]; + output_mask_state[i] = 0; + if (i < LFSR_WIDTH) begin + output_mask_state[i][i] = 1'b1; end - output_mask_state[i] = state_val; - - data_val = 0; - for (j = 0; j < DATA_WIDTH; j = j + 1) begin - data_val[j] = output_mask_data[i][DATA_WIDTH-j-1]; - end - output_mask_data[i] = data_val; + output_mask_data[i] = 0; end - end - // for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - // $display("%b %b", lfsr_mask_state[i], lfsr_mask_data[i]); - // end -end + // simulate shift register + if (LFSR_CONFIG == "FIBONACCI") begin + // Fibonacci configuration + for (data_mask = {1'b1, {DATA_WIDTH-1{1'b0}}}; data_mask != 0; data_mask = data_mask >> 1) begin + // determine shift in value + // current value in last FF, XOR with input data bit (MSB first) + state_val = lfsr_mask_state[LFSR_WIDTH-1]; + data_val = lfsr_mask_data[LFSR_WIDTH-1]; + data_val = data_val ^ data_mask; + + // add XOR inputs from correct indicies + for (j = 1; j < LFSR_WIDTH; j = j + 1) begin + if ((LFSR_POLY >> j) & 1) begin + state_val = lfsr_mask_state[j-1] ^ state_val; + data_val = lfsr_mask_data[j-1] ^ data_val; + end + end + + // shift + for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j-1]; + lfsr_mask_data[j] = lfsr_mask_data[j-1]; + end + for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin + output_mask_state[j] = output_mask_state[j-1]; + output_mask_data[j] = output_mask_data[j-1]; + end + output_mask_state[0] = state_val; + output_mask_data[0] = data_val; + if (LFSR_FEED_FORWARD) begin + // only shift in new input data + state_val = {LFSR_WIDTH{1'b0}}; + data_val = data_mask; + end + lfsr_mask_state[0] = state_val; + lfsr_mask_data[0] = data_val; + end + end else if (LFSR_CONFIG == "GALOIS") begin + // Galois configuration + for (data_mask = {1'b1, {DATA_WIDTH-1{1'b0}}}; data_mask != 0; data_mask = data_mask >> 1) begin + // determine shift in value + // current value in last FF, XOR with input data bit (MSB first) + state_val = lfsr_mask_state[LFSR_WIDTH-1]; + data_val = lfsr_mask_data[LFSR_WIDTH-1]; + data_val = data_val ^ data_mask; + + // shift + for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j-1]; + lfsr_mask_data[j] = lfsr_mask_data[j-1]; + end + for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin + output_mask_state[j] = output_mask_state[j-1]; + output_mask_data[j] = output_mask_data[j-1]; + end + output_mask_state[0] = state_val; + output_mask_data[0] = data_val; + if (LFSR_FEED_FORWARD) begin + // only shift in new input data + state_val = {LFSR_WIDTH{1'b0}}; + data_val = data_mask; + end + lfsr_mask_state[0] = state_val; + lfsr_mask_data[0] = data_val; + + // add XOR inputs at correct indicies + for (j = 1; j < LFSR_WIDTH; j = j + 1) begin + if ((LFSR_POLY >> j) & 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val; + lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val; + end + end + end + end else begin + $error("Error: unknown configuration setting!"); + $finish; + end + + // reverse bits if selected + if (REVERSE) begin + if (index < LFSR_WIDTH) begin + state_val = 0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + state_val[i] = lfsr_mask_state[LFSR_WIDTH-index-1][LFSR_WIDTH-i-1]; + end + + data_val = 0; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + data_val[i] = lfsr_mask_data[LFSR_WIDTH-index-1][DATA_WIDTH-i-1]; + end + end else begin + state_val = 0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + state_val[i] = output_mask_state[DATA_WIDTH-(index-LFSR_WIDTH)-1][LFSR_WIDTH-i-1]; + end + + data_val = 0; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + data_val[i] = output_mask_data[DATA_WIDTH-(index-LFSR_WIDTH)-1][DATA_WIDTH-i-1]; + end + end + end else begin + if (index < LFSR_WIDTH) begin + state_val = lfsr_mask_state[index]; + data_val = lfsr_mask_data[index]; + end else begin + state_val = output_mask_state[index-LFSR_WIDTH]; + data_val = output_mask_data[index-LFSR_WIDTH]; + end + end + lfsr_mask = {data_val, state_val}; + end +endfunction // synthesis translate_off `define SIMULATION @@ -380,11 +367,13 @@ if (STYLE_INT == "REDUCTION") begin // slightly smaller than generated code with Quartus // --> better for simulation - for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : loop1 - assign state_out[n] = ^{(state_in & lfsr_mask_state[n]), (data_in & lfsr_mask_data[n])}; + for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : lfsr_state + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n); + assign state_out[n] = ^({data_in, state_in} & mask); end - for (n = 0; n < DATA_WIDTH; n = n + 1) begin : loop2 - assign data_out[n] = ^{(state_in & output_mask_state[n]), (data_in & output_mask_data[n])}; + for (n = 0; n < DATA_WIDTH; n = n + 1) begin : lfsr_data + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n+LFSR_WIDTH); + assign data_out[n] = ^({data_in, state_in} & mask); end end else if (STYLE_INT == "LOOP") begin @@ -395,36 +384,48 @@ end else if (STYLE_INT == "LOOP") begin // same size as generated code with Quartus // --> better for synthesis - reg [LFSR_WIDTH-1:0] state_out_reg = 0; - reg [DATA_WIDTH-1:0] data_out_reg = 0; + for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : lfsr_state + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n); - assign state_out = state_out_reg; - assign data_out = data_out_reg; + reg state_reg; - always @* begin - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - state_out_reg[i] = 0; - for (j = 0; j < LFSR_WIDTH; j = j + 1) begin - if (lfsr_mask_state[i][j]) begin - state_out_reg[i] = state_out_reg[i] ^ state_in[j]; + assign state_out[n] = state_reg; + + integer i; + + always @* begin + state_reg = 1'b0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + if (mask[i]) begin + state_reg = state_reg ^ state_in[i]; end end - for (j = 0; j < DATA_WIDTH; j = j + 1) begin - if (lfsr_mask_data[i][j]) begin - state_out_reg[i] = state_out_reg[i] ^ data_in[j]; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + if (mask[i+LFSR_WIDTH]) begin + state_reg = state_reg ^ data_in[i]; end end end - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - data_out_reg[i] = 0; - for (j = 0; j < LFSR_WIDTH; j = j + 1) begin - if (output_mask_state[i][j]) begin - data_out_reg[i] = data_out_reg[i] ^ state_in[j]; + end + for (n = 0; n < DATA_WIDTH; n = n + 1) begin : lfsr_data + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n+LFSR_WIDTH); + + reg data_reg; + + assign data_out[n] = data_reg; + + integer i; + + always @* begin + data_reg = 1'b0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + if (mask[i]) begin + data_reg = data_reg ^ state_in[i]; end end - for (j = 0; j < DATA_WIDTH; j = j + 1) begin - if (output_mask_data[i][j]) begin - data_out_reg[i] = data_out_reg[i] ^ data_in[j]; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + if (mask[i+LFSR_WIDTH]) begin + data_reg = data_reg ^ data_in[i]; end end end