mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-22 21:09:15 -04:00
minor udpate
This commit is contained in:
parent
874e3e138e
commit
b347fbe6c4
39 changed files with 20 additions and 4507 deletions
|
@ -13,6 +13,26 @@
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`ifdef SYNTHESIS
|
||||
`define TRACING_ON
|
||||
`define TRACING_OFF
|
||||
`ifndef NDEBUG
|
||||
`define DEBUG_BLOCK(x) x
|
||||
`else
|
||||
`define DEBUG_BLOCK(x)
|
||||
`endif
|
||||
`define IGNORE_UNOPTFLAT_BEGIN
|
||||
`define IGNORE_UNOPTFLAT_END
|
||||
`define IGNORE_UNUSED_BEGIN
|
||||
`define IGNORE_UNUSED_END
|
||||
`define IGNORE_WARNINGS_BEGIN
|
||||
`define IGNORE_WARNINGS_END
|
||||
`define UNUSED_PARAM(x)
|
||||
`define UNUSED_SPARAM(x)
|
||||
`define UNUSED_VAR(x)
|
||||
`define UNUSED_PIN(x) . x ()
|
||||
`define TRACE(level, args) $write args
|
||||
`else
|
||||
`ifdef VERILATOR
|
||||
`define TRACING_ON /* verilator tracing_on */
|
||||
`define TRACING_OFF /* verilator tracing_off */
|
||||
|
@ -66,25 +86,7 @@
|
|||
. x () \
|
||||
/* verilator lint_on PINCONNECTEMPTY */
|
||||
`define TRACE(level, args) dpi_trace(level, $sformatf args)
|
||||
`else
|
||||
`define TRACING_ON
|
||||
`define TRACING_OFF
|
||||
`ifndef NDEBUG
|
||||
`define DEBUG_BLOCK(x) x
|
||||
`else
|
||||
`define DEBUG_BLOCK(x)
|
||||
`endif
|
||||
`define IGNORE_UNOPTFLAT_BEGIN
|
||||
`define IGNORE_UNOPTFLAT_END
|
||||
`define IGNORE_UNUSED_BEGIN
|
||||
`define IGNORE_UNUSED_END
|
||||
`define IGNORE_WARNINGS_BEGIN
|
||||
`define IGNORE_WARNINGS_END
|
||||
`define UNUSED_PARAM(x)
|
||||
`define UNUSED_SPARAM(x)
|
||||
`define UNUSED_VAR(x)
|
||||
`define UNUSED_PIN(x) . x ()
|
||||
`define TRACE(level, args) $write args
|
||||
`endif
|
||||
|
||||
`define STATIC_ASSERT(cond, msg) \
|
||||
|
|
3
hw/syn/xilinx/test2/.gitignore
vendored
3
hw/syn/xilinx/test2/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
/build*/*
|
||||
/.run/*
|
||||
/.Xil/*
|
|
@ -1,128 +0,0 @@
|
|||
ifneq ($(findstring Makefile, $(MAKEFILE_LIST)), Makefile)
|
||||
help:
|
||||
$(ECHO) "Makefile Usage:"
|
||||
$(ECHO) " make all TARGET=<sw_emu/hw_emu/hw> PLATFORM=<FPGA platform>"
|
||||
$(ECHO) " Command to generate the design for specified Target and Device."
|
||||
$(ECHO) ""
|
||||
$(ECHO) " make clean"
|
||||
$(ECHO) " Command to remove the generated non-hardware files."
|
||||
$(ECHO) ""
|
||||
endif
|
||||
|
||||
TARGET ?= hw
|
||||
PLATFORM ?=
|
||||
|
||||
PREFIX ?= build
|
||||
|
||||
RTL_DIR = ../hdl
|
||||
|
||||
BUILD_DIR = $(PREFIX)_$(PLATFORM)_$(TARGET)
|
||||
BIN_DIR = $(BUILD_DIR)/bin
|
||||
|
||||
RTL_INCLUDE += -I$(RTL_DIR)
|
||||
|
||||
CONFIGS += -DSYNTHESIS -DVIVADO
|
||||
|
||||
VIVADO = $(XILINX_VIVADO)/bin/vivado
|
||||
|
||||
VPP = $(XILINX_VITIS)/bin/v++
|
||||
|
||||
CP = cp -rf
|
||||
RMDIR = rm -rf
|
||||
|
||||
ECHO = @echo
|
||||
|
||||
XO_CONTAINER = $(BIN_DIR)/krnl_vadd_rtl.xo
|
||||
|
||||
XCLBIN_CONTAINER = $(BIN_DIR)/krnl_vadd_rtl.xclbin
|
||||
|
||||
EMCONFIG = $(BIN_DIR)/emconfig.json
|
||||
|
||||
NCPUS := $(shell grep -c ^processor /proc/cpuinfo)
|
||||
JOBS := $(shell expr $(NCPUS) - 1)
|
||||
|
||||
# Kernel compiler global settings
|
||||
VPP_FLAGS += --link --target $(TARGET) --platform $(PLATFORM) --save-temps --no_ip_cache
|
||||
VPP_FLAGS += --vivado.synth.jobs $(JOBS) --vivado.impl.jobs $(JOBS)
|
||||
VPP_FLAGS += --connectivity.sp krnl_vadd_rtl_1.m_axi_mem:HBM[0:15]
|
||||
VPP_FLAGS += --report estimate
|
||||
VPP_FLAGS += --config ../vitis.ini
|
||||
|
||||
# Enable perf counters
|
||||
ifdef PERF
|
||||
CONFIGS += -DPERF_ENABLE
|
||||
endif
|
||||
|
||||
# Generates profile summary report
|
||||
ifdef PROFILE
|
||||
VPP_FLAGS += --profile_kernel data:all:all:all
|
||||
VPP_FLAGS += --profile_kernel stall:all:all:all
|
||||
endif
|
||||
|
||||
# Debugigng
|
||||
ifdef DEBUG
|
||||
VPP_FLAGS += -g --optimize 0 --debug.protocol all
|
||||
ifeq ($(TARGET), hw)
|
||||
VPP_FLAGS += --debug.chipscope krnl_vadd_rtl_1
|
||||
CONFIGS += -DCHIPSCOPE
|
||||
else
|
||||
CONFIGS += -DSIMULATION $(DBG_FLAGS)
|
||||
VPP_FLAGS += --vivado.prop fileset.sim_1.xsim.elaborate.debug_level=all
|
||||
endif
|
||||
else
|
||||
CONFIGS += -DNDEBUG
|
||||
VPP_FLAGS += --optimize 3
|
||||
endif
|
||||
|
||||
# Host
|
||||
EXECUTABLE = ./test
|
||||
CMD_ARGS = -x $(XCLBIN_CONTAINER)
|
||||
CXXFLAGS += -std=c++14 -g -O0 -fmessage-length=0 -I$(XILINX_XRT)/include -I$(XILINX_VIVADO)/include -Wall -I../src
|
||||
LDFLAGS += -L$(XILINX_XRT)/lib -pthread -luuid -lxrt_coreutil
|
||||
HOST_SRCS += ./src/host.cpp ./src/cmdlineparser.cpp ./src/logger.cpp
|
||||
|
||||
# RTL Kernel only supports Hardware and Hardware Emulation.
|
||||
ifneq ($(TARGET),$(findstring $(TARGET), hw hw_emu))
|
||||
$(warning WARNING:Application supports only hw hw_emu TARGET. Please use the target for running the application)
|
||||
endif
|
||||
|
||||
.PHONY: all run host clean gen-sources emconfig check-devices
|
||||
|
||||
all: check-devices $(XCLBIN_CONTAINER) emconfig host
|
||||
|
||||
gen-sources: $(BUILD_DIR)/sources.txt
|
||||
$(BUILD_DIR)/sources.txt:
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); ../scripts/gen_sources.sh $(RTL_INCLUDE) $(CONFIGS) > sources.txt
|
||||
|
||||
$(XO_CONTAINER): $(BUILD_DIR)/sources.txt ./kernel.xml
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); $(VIVADO) -mode batch -source ../scripts/gen_xo.tcl -tclargs ../$(XO_CONTAINER) krnl_vadd_rtl sources.txt ../kernel.xml ../$(BUILD_DIR)
|
||||
|
||||
$(XCLBIN_CONTAINER): $(XO_CONTAINER)
|
||||
mkdir -p $(BIN_DIR); cd $(BUILD_DIR); $(VPP) $(VPP_FLAGS) -o ../$(XCLBIN_CONTAINER) ../$(XO_CONTAINER)
|
||||
|
||||
emconfig: $(EMCONFIG)
|
||||
$(EMCONFIG):
|
||||
mkdir -p $(BIN_DIR); cd $(BUILD_DIR); emconfigutil --platform $(PLATFORM) --od ../$(BIN_DIR)
|
||||
|
||||
host: $(EXECUTABLE)
|
||||
$(EXECUTABLE): $(HOST_SRCS)
|
||||
g++ $^ $(CXXFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
run: $(EXECUTABLE) $(EMCONFIG)
|
||||
ifeq ($(TARGET),$(filter $(TARGET),sw_emu hw_emu))
|
||||
EMCONFIG_PATH=$(BIN_DIR) XCL_EMULATION_MODE=$(TARGET) $(EXECUTABLE) $(CMD_ARGS)
|
||||
else
|
||||
EMCONFIG_PATH=$(BIN_DIR) $(EXECUTABLE) $(CMD_ARGS)
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(RMDIR) $(BUILD_DIR) $(EXECUTABLE)
|
||||
|
||||
# Check the devices avaiable
|
||||
check-devices:
|
||||
ifndef PLATFORM
|
||||
$(error PLATFORM not set. Please set the PLATFORM properly and rerun. Run "make help" for more details.)
|
||||
endif
|
||||
ifndef XILINX_VITIS
|
||||
$(error XILINX_VITIS variable is not set, please set correctly and rerun)
|
||||
endif
|
|
@ -1,178 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Description: This is a wrapper of module "krnl_vadd_rtl_int"
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// default_nettype of none prevents implicit wire declaration.
|
||||
`default_nettype none
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
`ifndef NOGLOBALS
|
||||
`include "globals.vh"
|
||||
`endif
|
||||
|
||||
module krnl_vadd_rtl #(
|
||||
parameter integer C_S_AXI_CTRL_DATA_WIDTH = 32,
|
||||
parameter integer C_S_AXI_CTRL_ADDR_WIDTH = 6,
|
||||
parameter integer C_M_AXI_MEM_ID_WIDTH = 1,
|
||||
parameter integer C_M_AXI_MEM_ADDR_WIDTH = 32,
|
||||
parameter integer C_M_AXI_MEM_DATA_WIDTH = 32
|
||||
)
|
||||
(
|
||||
// System signals
|
||||
input wire ap_clk,
|
||||
input wire ap_rst_n,
|
||||
|
||||
// AXI4 master interface
|
||||
output wire m_axi_mem_awvalid,
|
||||
input wire m_axi_mem_awready,
|
||||
output wire [C_M_AXI_MEM_ADDR_WIDTH-1:0] m_axi_mem_awaddr,
|
||||
output wire [C_M_AXI_MEM_ID_WIDTH - 1:0] m_axi_mem_awid,
|
||||
output wire [7:0] m_axi_mem_awlen,
|
||||
output wire [2:0] m_axi_mem_awsize,
|
||||
output wire [1:0] m_axi_mem_awburst,
|
||||
output wire [1:0] m_axi_mem_awlock,
|
||||
output wire [3:0] m_axi_mem_awcache,
|
||||
output wire [2:0] m_axi_mem_awprot,
|
||||
output wire [3:0] m_axi_mem_awqos,
|
||||
output wire [3:0] m_axi_mem_awregion,
|
||||
|
||||
output wire m_axi_mem_wvalid,
|
||||
input wire m_axi_mem_wready,
|
||||
output wire [C_M_AXI_MEM_DATA_WIDTH-1:0] m_axi_mem_wdata,
|
||||
output wire [C_M_AXI_MEM_DATA_WIDTH/8-1:0] m_axi_mem_wstrb,
|
||||
output wire m_axi_mem_wlast,
|
||||
|
||||
input wire m_axi_mem_bvalid,
|
||||
output wire m_axi_mem_bready,
|
||||
input wire [C_M_AXI_MEM_ID_WIDTH - 1:0] m_axi_mem_bid,
|
||||
input wire [1:0] m_axi_mem_bresp,
|
||||
|
||||
output wire m_axi_mem_arvalid,
|
||||
input wire m_axi_mem_arready,
|
||||
output wire [C_M_AXI_MEM_ADDR_WIDTH-1:0] m_axi_mem_araddr,
|
||||
output wire [C_M_AXI_MEM_ID_WIDTH-1:0] m_axi_mem_arid,
|
||||
output wire [7:0] m_axi_mem_arlen,
|
||||
output wire [2:0] m_axi_mem_arsize,
|
||||
output wire [1:0] m_axi_mem_arburst,
|
||||
output wire [1:0] m_axi_mem_arlock,
|
||||
output wire [3:0] m_axi_mem_arcache,
|
||||
output wire [2:0] m_axi_mem_arprot,
|
||||
output wire [3:0] m_axi_mem_arqos,
|
||||
output wire [3:0] m_axi_mem_arregion,
|
||||
|
||||
input wire m_axi_mem_rvalid,
|
||||
output wire m_axi_mem_rready,
|
||||
input wire [C_M_AXI_MEM_DATA_WIDTH - 1:0] m_axi_mem_rdata,
|
||||
input wire m_axi_mem_rlast,
|
||||
input wire [C_M_AXI_MEM_ID_WIDTH - 1:0] m_axi_mem_rid,
|
||||
input wire [1:0] m_axi_mem_rresp,
|
||||
|
||||
// AXI4-Lite slave interface
|
||||
input wire s_axi_ctrl_awvalid,
|
||||
output wire s_axi_ctrl_awready,
|
||||
input wire [C_S_AXI_CTRL_ADDR_WIDTH-1:0] s_axi_ctrl_awaddr,
|
||||
input wire s_axi_ctrl_wvalid,
|
||||
output wire s_axi_ctrl_wready,
|
||||
input wire [C_S_AXI_CTRL_DATA_WIDTH-1:0] s_axi_ctrl_wdata,
|
||||
input wire [C_S_AXI_CTRL_DATA_WIDTH/8-1:0] s_axi_ctrl_wstrb,
|
||||
input wire s_axi_ctrl_arvalid,
|
||||
output wire s_axi_ctrl_arready,
|
||||
input wire [C_S_AXI_CTRL_ADDR_WIDTH-1:0] s_axi_ctrl_araddr,
|
||||
output wire s_axi_ctrl_rvalid,
|
||||
input wire s_axi_ctrl_rready,
|
||||
output wire [C_S_AXI_CTRL_DATA_WIDTH-1:0] s_axi_ctrl_rdata,
|
||||
output wire [1:0] s_axi_ctrl_rresp,
|
||||
output wire s_axi_ctrl_bvalid,
|
||||
input wire s_axi_ctrl_bready,
|
||||
output wire [1:0] s_axi_ctrl_bresp,
|
||||
|
||||
output wire interrupt
|
||||
);
|
||||
|
||||
krnl_vadd_rtl_int #(
|
||||
.C_S_AXI_CTRL_DATA_WIDTH ( C_S_AXI_CTRL_DATA_WIDTH ),
|
||||
.C_S_AXI_CTRL_ADDR_WIDTH ( C_S_AXI_CTRL_ADDR_WIDTH ),
|
||||
.C_M_AXI_MEM_ID_WIDTH ( C_M_AXI_MEM_ID_WIDTH ),
|
||||
.C_M_AXI_MEM_ADDR_WIDTH ( C_M_AXI_MEM_ADDR_WIDTH ),
|
||||
.C_M_AXI_MEM_DATA_WIDTH ( C_M_AXI_MEM_DATA_WIDTH )
|
||||
)
|
||||
inst_krnl_vadd_rtl_int (
|
||||
.ap_clk ( ap_clk ),
|
||||
.ap_rst_n ( ap_rst_n ),
|
||||
.m_axi_mem_awvalid ( m_axi_mem_awvalid ),
|
||||
.m_axi_mem_awready ( m_axi_mem_awready ),
|
||||
.m_axi_mem_awaddr ( m_axi_mem_awaddr ),
|
||||
.m_axi_mem_awid ( m_axi_mem_awid ),
|
||||
.m_axi_mem_awlen ( m_axi_mem_awlen ),
|
||||
.m_axi_mem_awsize ( m_axi_mem_awsize ),
|
||||
.m_axi_mem_awburst ( m_axi_mem_awburst ),
|
||||
.m_axi_mem_awlock ( m_axi_mem_awlock ),
|
||||
.m_axi_mem_awcache ( m_axi_mem_awcache ),
|
||||
.m_axi_mem_awprot ( m_axi_mem_awprot ),
|
||||
.m_axi_mem_awqos ( m_axi_mem_awqos ),
|
||||
.m_axi_mem_awregion ( m_axi_mem_awregion ),
|
||||
.m_axi_mem_wvalid ( m_axi_mem_wvalid ),
|
||||
.m_axi_mem_wready ( m_axi_mem_wready ),
|
||||
.m_axi_mem_wdata ( m_axi_mem_wdata ),
|
||||
.m_axi_mem_wstrb ( m_axi_mem_wstrb ),
|
||||
.m_axi_mem_wlast ( m_axi_mem_wlast ),
|
||||
.m_axi_mem_arvalid ( m_axi_mem_arvalid ),
|
||||
.m_axi_mem_arready ( m_axi_mem_arready ),
|
||||
.m_axi_mem_araddr ( m_axi_mem_araddr ),
|
||||
.m_axi_mem_arid ( m_axi_mem_arid ),
|
||||
.m_axi_mem_arlen ( m_axi_mem_arlen ),
|
||||
.m_axi_mem_arsize ( m_axi_mem_arsize ),
|
||||
.m_axi_mem_arburst ( m_axi_mem_arburst ),
|
||||
.m_axi_mem_arlock ( m_axi_mem_arlock ),
|
||||
.m_axi_mem_arcache ( m_axi_mem_arcache ),
|
||||
.m_axi_mem_arprot ( m_axi_mem_arprot ),
|
||||
.m_axi_mem_arqos ( m_axi_mem_arqos ),
|
||||
.m_axi_mem_arregion ( m_axi_mem_arregion ),
|
||||
.m_axi_mem_rvalid ( m_axi_mem_rvalid ),
|
||||
.m_axi_mem_rready ( m_axi_mem_rready ),
|
||||
.m_axi_mem_rdata ( m_axi_mem_rdata ),
|
||||
.m_axi_mem_rlast ( m_axi_mem_rlast ),
|
||||
.m_axi_mem_rid ( m_axi_mem_rid ),
|
||||
.m_axi_mem_rresp ( m_axi_mem_rresp ),
|
||||
.m_axi_mem_bvalid ( m_axi_mem_bvalid ),
|
||||
.m_axi_mem_bready ( m_axi_mem_bready ),
|
||||
.m_axi_mem_bresp ( m_axi_mem_bresp ),
|
||||
.m_axi_mem_bid ( m_axi_mem_bid ),
|
||||
.s_axi_ctrl_awvalid ( s_axi_ctrl_awvalid ),
|
||||
.s_axi_ctrl_awready ( s_axi_ctrl_awready ),
|
||||
.s_axi_ctrl_awaddr ( s_axi_ctrl_awaddr ),
|
||||
.s_axi_ctrl_wvalid ( s_axi_ctrl_wvalid ),
|
||||
.s_axi_ctrl_wready ( s_axi_ctrl_wready ),
|
||||
.s_axi_ctrl_wdata ( s_axi_ctrl_wdata ),
|
||||
.s_axi_ctrl_wstrb ( s_axi_ctrl_wstrb ),
|
||||
.s_axi_ctrl_arvalid ( s_axi_ctrl_arvalid ),
|
||||
.s_axi_ctrl_arready ( s_axi_ctrl_arready ),
|
||||
.s_axi_ctrl_araddr ( s_axi_ctrl_araddr ),
|
||||
.s_axi_ctrl_rvalid ( s_axi_ctrl_rvalid ),
|
||||
.s_axi_ctrl_rready ( s_axi_ctrl_rready ),
|
||||
.s_axi_ctrl_rdata ( s_axi_ctrl_rdata ),
|
||||
.s_axi_ctrl_rresp ( s_axi_ctrl_rresp ),
|
||||
.s_axi_ctrl_bvalid ( s_axi_ctrl_bvalid ),
|
||||
.s_axi_ctrl_bready ( s_axi_ctrl_bready ),
|
||||
.s_axi_ctrl_bresp ( s_axi_ctrl_bresp ),
|
||||
.interrupt ( interrupt )
|
||||
);
|
||||
endmodule : krnl_vadd_rtl
|
||||
|
||||
`default_nettype wire
|
|
@ -1,68 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Description: Basic Adder, no overflow. Unsigned. Combinatorial.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module krnl_vadd_rtl_adder #(
|
||||
parameter integer C_DATA_WIDTH = 32, // Data width of both input and output data
|
||||
parameter integer C_NUM_CHANNELS = 2 // Number of input channels. Only a value of 2 implemented.
|
||||
)
|
||||
(
|
||||
input wire aclk,
|
||||
input wire areset,
|
||||
|
||||
input wire [C_NUM_CHANNELS-1:0] s_tvalid,
|
||||
input wire [C_NUM_CHANNELS-1:0][C_DATA_WIDTH-1:0] s_tdata,
|
||||
output wire [C_NUM_CHANNELS-1:0] s_tready,
|
||||
|
||||
output wire m_tvalid,
|
||||
output wire [C_DATA_WIDTH-1:0] m_tdata,
|
||||
input wire m_tready
|
||||
|
||||
);
|
||||
|
||||
timeunit 1ps;
|
||||
timeprecision 1ps;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
logic [C_DATA_WIDTH-1:0] acc;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Logic
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always_comb begin
|
||||
acc = s_tdata[0];
|
||||
for (int i = 1; i < C_NUM_CHANNELS; i++) begin
|
||||
acc = acc + s_tdata[i];
|
||||
end
|
||||
end
|
||||
|
||||
assign m_tvalid = &s_tvalid;
|
||||
assign m_tdata = acc;
|
||||
|
||||
// Only assert s_tready when transfer has been accepted. tready asserted on all channels simultaneously
|
||||
assign s_tready = m_tready & m_tvalid ? {C_NUM_CHANNELS{1'b1}} : {C_NUM_CHANNELS{1'b0}};
|
||||
|
||||
endmodule : krnl_vadd_rtl_adder
|
||||
|
||||
`default_nettype wire
|
|
@ -1,274 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Description: This is a multi-threaded AXI4 read master. Each channel will
|
||||
// issue commands on a different IDs. As a result data may arrive out of
|
||||
// order. The amount of data requested is equal to the ctrl_length variable.
|
||||
// Prog full is set and sampled such that the FIFO will never overflow. Thus
|
||||
// rready can be always asserted for better timing.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module krnl_vadd_rtl_axi_read_master #(
|
||||
parameter integer C_ID_WIDTH = 1, // Must be >= $clog2(C_NUM_CHANNELS)
|
||||
parameter integer C_ADDR_WIDTH = 64,
|
||||
parameter integer C_DATA_WIDTH = 32,
|
||||
parameter integer C_NUM_CHANNELS = 2, // Only 2 tested.
|
||||
parameter integer C_LENGTH_WIDTH = 32,
|
||||
parameter integer C_BURST_LEN = 256, // Max AXI burst length for read commands
|
||||
parameter integer C_LOG_BURST_LEN = 8,
|
||||
parameter integer C_MAX_OUTSTANDING = 3
|
||||
)
|
||||
(
|
||||
// System signals
|
||||
input wire aclk,
|
||||
input wire areset,
|
||||
// Control signals
|
||||
input wire ctrl_start,
|
||||
output wire ctrl_done,
|
||||
input wire [C_NUM_CHANNELS-1:0][C_ADDR_WIDTH-1:0] ctrl_offset,
|
||||
input wire [C_LENGTH_WIDTH-1:0] ctrl_length,
|
||||
input wire [C_NUM_CHANNELS-1:0] ctrl_prog_full,
|
||||
// AXI4 master interface
|
||||
output wire arvalid,
|
||||
input wire arready,
|
||||
output wire [C_ADDR_WIDTH-1:0] araddr,
|
||||
output wire [C_ID_WIDTH-1:0] arid,
|
||||
output wire [7:0] arlen,
|
||||
output wire [2:0] arsize,
|
||||
input wire rvalid,
|
||||
output wire rready,
|
||||
input wire [C_DATA_WIDTH - 1:0] rdata,
|
||||
input wire rlast,
|
||||
input wire [C_ID_WIDTH - 1:0] rid,
|
||||
input wire [1:0] rresp,
|
||||
// AXI4-Stream master interface, 1 interface per channel.
|
||||
output wire [C_NUM_CHANNELS-1:0] m_tvalid,
|
||||
input wire [C_NUM_CHANNELS-1:0] m_tready,
|
||||
output wire [C_NUM_CHANNELS-1:0][C_DATA_WIDTH-1:0] m_tdata
|
||||
);
|
||||
|
||||
timeunit 1ps;
|
||||
timeprecision 1ps;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Local Parameters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
localparam integer LP_MAX_OUTSTANDING_CNTR_WIDTH = $clog2(C_MAX_OUTSTANDING+1);
|
||||
localparam integer LP_TRANSACTION_CNTR_WIDTH = C_LENGTH_WIDTH-C_LOG_BURST_LEN;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Control logic
|
||||
logic [C_NUM_CHANNELS-1:0] done = '0;
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] num_full_bursts;
|
||||
logic num_partial_bursts;
|
||||
logic start = 1'b0;
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] num_transactions;
|
||||
logic has_partial_burst;
|
||||
logic [C_LOG_BURST_LEN-1:0] final_burst_len;
|
||||
logic single_transaction;
|
||||
logic ar_idle = 1'b1;
|
||||
logic ar_done;
|
||||
// AXI Read Address Channel
|
||||
logic fifo_stall;
|
||||
logic arxfer;
|
||||
logic arvalid_r = 1'b0;
|
||||
logic [C_NUM_CHANNELS-1:0][C_ADDR_WIDTH-1:0] addr;
|
||||
logic [C_ID_WIDTH-1:0] id = {C_ID_WIDTH{1'b1}};
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] ar_transactions_to_go;
|
||||
logic ar_final_transaction;
|
||||
logic [C_NUM_CHANNELS-1:0] incr_ar_to_r_cnt;
|
||||
logic [C_NUM_CHANNELS-1:0] decr_ar_to_r_cnt;
|
||||
logic [C_NUM_CHANNELS-1:0] stall_ar;
|
||||
logic [C_NUM_CHANNELS-1:0][LP_MAX_OUTSTANDING_CNTR_WIDTH-1:0] outstanding_vacancy_count;
|
||||
// AXI Data Channel
|
||||
logic [C_NUM_CHANNELS-1:0] tvalid;
|
||||
logic [C_NUM_CHANNELS-1:0][C_DATA_WIDTH-1:0] tdata;
|
||||
logic rxfer;
|
||||
logic [C_NUM_CHANNELS-1:0] decr_r_transaction_cntr;
|
||||
logic [C_NUM_CHANNELS-1:0][LP_TRANSACTION_CNTR_WIDTH-1:0] r_transactions_to_go;
|
||||
logic [C_NUM_CHANNELS-1:0] r_final_transaction;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Control Logic
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
always @(posedge aclk) begin
|
||||
for (int i = 0; i < C_NUM_CHANNELS; i++) begin
|
||||
done[i] <= rxfer & rlast & (rid == i) & r_final_transaction[i] ? 1'b1 :
|
||||
ctrl_done ? 1'b0 : done[i];
|
||||
end
|
||||
end
|
||||
assign ctrl_done = &done;
|
||||
|
||||
// Determine how many full burst to issue and if there are any partial bursts.
|
||||
assign num_full_bursts = ctrl_length[C_LOG_BURST_LEN+:C_LENGTH_WIDTH-C_LOG_BURST_LEN];
|
||||
assign num_partial_bursts = ctrl_length[0+:C_LOG_BURST_LEN] ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
start <= ctrl_start;
|
||||
num_transactions <= (num_partial_bursts == 1'b0) ? num_full_bursts - 1'b1 : num_full_bursts;
|
||||
has_partial_burst <= num_partial_bursts;
|
||||
final_burst_len <= ctrl_length[0+:C_LOG_BURST_LEN] - 1'b1;
|
||||
end
|
||||
|
||||
// Special case if there is only 1 AXI transaction.
|
||||
assign single_transaction = (num_transactions == {LP_TRANSACTION_CNTR_WIDTH{1'b0}}) ? 1'b1 : 1'b0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// AXI Read Address Channel
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
assign arvalid = arvalid_r;
|
||||
assign araddr = addr[id];
|
||||
assign arlen = ar_final_transaction || (start & single_transaction) ? final_burst_len : C_BURST_LEN - 1;
|
||||
assign arsize = $clog2((C_DATA_WIDTH/8));
|
||||
assign arid = id;
|
||||
|
||||
assign arxfer = arvalid & arready;
|
||||
assign fifo_stall = ctrl_prog_full[id];
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (areset) begin
|
||||
arvalid_r <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
arvalid_r <= ~ar_idle & ~stall_ar[id] & ~arvalid_r & ~fifo_stall ? 1'b1 :
|
||||
arready ? 1'b0 : arvalid_r;
|
||||
end
|
||||
end
|
||||
|
||||
// When ar_idle, there are no transactions to issue.
|
||||
always @(posedge aclk) begin
|
||||
if (areset) begin
|
||||
ar_idle <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
ar_idle <= start ? 1'b0 :
|
||||
ar_done ? 1'b1 :
|
||||
ar_idle;
|
||||
end
|
||||
end
|
||||
|
||||
// each channel is assigned a different id. The transactions are interleaved.
|
||||
always @(posedge aclk) begin
|
||||
if (start) begin
|
||||
id <= {C_ID_WIDTH{1'b1}};
|
||||
end
|
||||
else begin
|
||||
id <= arxfer ? id - 1'b1 : id;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Increment to next address after each transaction is issued.
|
||||
always @(posedge aclk) begin
|
||||
for (int i = 0; i < C_NUM_CHANNELS; i++) begin
|
||||
addr[i] <= ctrl_start ? ctrl_offset[i] :
|
||||
arxfer && (id == i) ? addr[i] + C_BURST_LEN*C_DATA_WIDTH/8 :
|
||||
addr[i];
|
||||
end
|
||||
end
|
||||
|
||||
// Counts down the number of transactions to send.
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( LP_TRANSACTION_CNTR_WIDTH ) ,
|
||||
.C_INIT ( {LP_TRANSACTION_CNTR_WIDTH{1'b0}} )
|
||||
)
|
||||
inst_ar_transaction_cntr (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( start ) ,
|
||||
.incr ( 1'b0 ) ,
|
||||
.decr ( arxfer && id == '0 ) ,
|
||||
.load_value ( num_transactions ) ,
|
||||
.count ( ar_transactions_to_go ) ,
|
||||
.is_zero ( ar_final_transaction )
|
||||
);
|
||||
|
||||
assign ar_done = ar_final_transaction && arxfer && id == 1'b0;
|
||||
|
||||
always_comb begin
|
||||
for (int i = 0; i < C_NUM_CHANNELS; i++) begin
|
||||
incr_ar_to_r_cnt[i] = rxfer & rlast & (rid == i);
|
||||
decr_ar_to_r_cnt[i] = arxfer & (arid == i);
|
||||
end
|
||||
end
|
||||
|
||||
// Keeps track of the number of outstanding transactions. Stalls
|
||||
// when the value is reached so that the FIFO won't overflow.
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( LP_MAX_OUTSTANDING_CNTR_WIDTH ) ,
|
||||
.C_INIT ( C_MAX_OUTSTANDING[0+:LP_MAX_OUTSTANDING_CNTR_WIDTH] )
|
||||
)
|
||||
inst_ar_to_r_transaction_cntr[C_NUM_CHANNELS-1:0] (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( 1'b0 ) ,
|
||||
.incr ( incr_ar_to_r_cnt ) ,
|
||||
.decr ( decr_ar_to_r_cnt ) ,
|
||||
.load_value ( {LP_MAX_OUTSTANDING_CNTR_WIDTH{1'b0}} ) ,
|
||||
.count ( outstanding_vacancy_count ) ,
|
||||
.is_zero ( stall_ar )
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// AXI Read Channel
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
assign m_tvalid = tvalid;
|
||||
assign m_tdata = tdata;
|
||||
|
||||
always_comb begin
|
||||
for (int i = 0; i < C_NUM_CHANNELS; i++) begin
|
||||
tvalid[i] = rvalid && (rid == i);
|
||||
tdata[i] = rdata;
|
||||
end
|
||||
end
|
||||
|
||||
// rready can remain high for optimal timing because ar transactions are not issued
|
||||
// unless there is enough space in the FIFO.
|
||||
assign rready = 1'b1;
|
||||
assign rxfer = rready & rvalid;
|
||||
|
||||
always_comb begin
|
||||
for (int i = 0; i < C_NUM_CHANNELS; i++) begin
|
||||
decr_r_transaction_cntr[i] = rxfer & rlast & (rid == i);
|
||||
end
|
||||
end
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( LP_TRANSACTION_CNTR_WIDTH ) ,
|
||||
.C_INIT ( {LP_TRANSACTION_CNTR_WIDTH{1'b0}} )
|
||||
)
|
||||
inst_r_transaction_cntr[C_NUM_CHANNELS-1:0] (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( start ) ,
|
||||
.incr ( 1'b0 ) ,
|
||||
.decr ( decr_r_transaction_cntr ) ,
|
||||
.load_value ( num_transactions ) ,
|
||||
.count ( r_transactions_to_go ) ,
|
||||
.is_zero ( r_final_transaction )
|
||||
);
|
||||
|
||||
|
||||
endmodule : krnl_vadd_rtl_axi_read_master
|
||||
|
||||
`default_nettype wire
|
|
@ -1,276 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Description: AXI4 Write Master. Takes a stream of data in,
|
||||
// appends address information and sends it out.
|
||||
`default_nettype none
|
||||
|
||||
module krnl_vadd_rtl_axi_write_master #(
|
||||
parameter integer C_ADDR_WIDTH = 64,
|
||||
parameter integer C_DATA_WIDTH = 32,
|
||||
parameter integer C_MAX_LENGTH_WIDTH = 32,
|
||||
parameter integer C_BURST_LEN = 256,
|
||||
parameter integer C_LOG_BURST_LEN = 8
|
||||
)
|
||||
(
|
||||
// Control interface
|
||||
input wire ctrl_start,
|
||||
input wire [C_ADDR_WIDTH-1:0] ctrl_offset,
|
||||
input wire [C_MAX_LENGTH_WIDTH-1:0] ctrl_length,
|
||||
output wire ctrl_done,
|
||||
|
||||
// AXI4-Stream interface
|
||||
input wire s_tvalid,
|
||||
input wire [C_DATA_WIDTH-1:0] s_tdata,
|
||||
output wire s_tready,
|
||||
|
||||
// AXI Interface
|
||||
input wire aclk,
|
||||
input wire areset,
|
||||
|
||||
output wire [C_ADDR_WIDTH-1:0] awaddr,
|
||||
output wire [7:0] awlen,
|
||||
output wire [2:0] awsize,
|
||||
output wire awvalid,
|
||||
input wire awready,
|
||||
|
||||
output wire [C_DATA_WIDTH-1:0] wdata,
|
||||
output wire [C_DATA_WIDTH/8-1:0] wstrb,
|
||||
output wire wlast,
|
||||
output wire wvalid,
|
||||
input wire wready,
|
||||
|
||||
input wire [1:0] bresp,
|
||||
input wire bvalid,
|
||||
output wire bready
|
||||
);
|
||||
|
||||
timeunit 1ps;
|
||||
timeprecision 1ps;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Local Parameters
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
localparam integer LP_LOG_MAX_W_TO_AW = 8; // Allow up to 256 outstanding w to aw transactions
|
||||
localparam integer LP_TRANSACTION_CNTR_WIDTH = C_MAX_LENGTH_WIDTH-C_LOG_BURST_LEN;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] num_full_bursts;
|
||||
logic num_partial_bursts;
|
||||
logic start = 1'b0;
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] num_transactions;
|
||||
logic has_partial_burst;
|
||||
logic [C_LOG_BURST_LEN-1:0] final_burst_len;
|
||||
logic single_transaction;
|
||||
|
||||
logic wxfer; // Unregistered write data transfer
|
||||
logic wfirst = 1'b1;
|
||||
logic load_burst_cntr;
|
||||
logic [C_LOG_BURST_LEN-1:0] wxfers_to_go; // Used for simulation debug
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] w_transactions_to_go;
|
||||
logic w_final_transaction;
|
||||
logic w_almost_final_transaction = 1'b0;
|
||||
|
||||
logic awxfer;
|
||||
logic awvalid_r = 1'b0;
|
||||
logic [C_ADDR_WIDTH-1:0] addr;
|
||||
logic wfirst_d1 = 1'b0;
|
||||
logic wfirst_pulse = 1'b0;
|
||||
logic [LP_LOG_MAX_W_TO_AW-1:0] dbg_w_to_aw_outstanding;
|
||||
logic idle_aw;
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] aw_transactions_to_go;
|
||||
logic aw_final_transaction;
|
||||
|
||||
wire bxfer;
|
||||
logic [LP_TRANSACTION_CNTR_WIDTH-1:0] b_transactions_to_go;
|
||||
logic b_final_transaction;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Control logic
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Count the number of transfers and assert done when the last bvalid is received.
|
||||
assign num_full_bursts = ctrl_length[C_LOG_BURST_LEN+:C_MAX_LENGTH_WIDTH-C_LOG_BURST_LEN];
|
||||
assign num_partial_bursts = ctrl_length[0+:C_LOG_BURST_LEN] ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
start <= ctrl_start;
|
||||
num_transactions <= (num_partial_bursts == 1'b0) ? num_full_bursts - 1'b1 : num_full_bursts;
|
||||
has_partial_burst <= num_partial_bursts;
|
||||
final_burst_len <= ctrl_length[0+:C_LOG_BURST_LEN] - 1'b1;
|
||||
end
|
||||
|
||||
assign ctrl_done = bxfer & b_final_transaction;
|
||||
assign single_transaction = (num_transactions == {LP_TRANSACTION_CNTR_WIDTH{1'b0}}) ? 1'b1 : 1'b0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AXI Write Data Channel
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
assign wvalid = s_tvalid;
|
||||
assign wdata = s_tdata;
|
||||
assign wstrb = {(C_DATA_WIDTH/8){1'b1}};
|
||||
assign s_tready = wready;
|
||||
|
||||
assign wxfer = wvalid & wready;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (areset) begin
|
||||
wfirst <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
wfirst <= wxfer ? wlast : wfirst;
|
||||
end
|
||||
end
|
||||
|
||||
// Load burst counter with partial burst if on final transaction or if there is only 1 transaction
|
||||
assign load_burst_cntr = (wxfer & wlast & w_almost_final_transaction) || (start & single_transaction);
|
||||
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( C_LOG_BURST_LEN ) ,
|
||||
.C_INIT ( {C_LOG_BURST_LEN{1'b1}} )
|
||||
)
|
||||
inst_burst_cntr (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( load_burst_cntr ) ,
|
||||
.incr ( 1'b0 ) ,
|
||||
.decr ( wxfer ) ,
|
||||
.load_value ( final_burst_len ) ,
|
||||
.count ( wxfers_to_go ) ,
|
||||
.is_zero ( wlast )
|
||||
);
|
||||
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( LP_TRANSACTION_CNTR_WIDTH ) ,
|
||||
.C_INIT ( {LP_TRANSACTION_CNTR_WIDTH{1'b0}} )
|
||||
)
|
||||
inst_w_transaction_cntr (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( start ) ,
|
||||
.incr ( 1'b0 ) ,
|
||||
.decr ( wxfer & wlast ) ,
|
||||
.load_value ( num_transactions ) ,
|
||||
.count ( w_transactions_to_go ) ,
|
||||
.is_zero ( w_final_transaction )
|
||||
);
|
||||
|
||||
always @(posedge aclk) begin
|
||||
w_almost_final_transaction <= (w_transactions_to_go == 1) ? 1'b1 : 1'b0;
|
||||
end
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AXI Write Address Channel
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The address channel samples the data channel and send out transactions when
|
||||
// first beat of wdata is asserted. This ensures that address requests are not
|
||||
// sent without data on the way.
|
||||
|
||||
assign awvalid = awvalid_r;
|
||||
assign awxfer = awvalid & awready;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
if (areset) begin
|
||||
awvalid_r <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
awvalid_r <= ~idle_aw & ~awvalid_r ? 1'b1 :
|
||||
awready ? 1'b0 :
|
||||
awvalid_r;
|
||||
end
|
||||
end
|
||||
|
||||
assign awaddr = addr;
|
||||
|
||||
always @(posedge aclk) begin
|
||||
addr <= ctrl_start ? ctrl_offset :
|
||||
awxfer ? addr + C_BURST_LEN*C_DATA_WIDTH/8 :
|
||||
addr;
|
||||
end
|
||||
|
||||
assign awlen = aw_final_transaction || (start & single_transaction) ? final_burst_len : C_BURST_LEN - 1;
|
||||
assign awsize = $clog2((C_DATA_WIDTH/8));
|
||||
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH (LP_LOG_MAX_W_TO_AW),
|
||||
.C_INIT ({LP_LOG_MAX_W_TO_AW{1'b0}})
|
||||
)
|
||||
inst_w_to_aw_cntr (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( 1'b0 ) ,
|
||||
.incr ( wfirst_pulse ) ,
|
||||
.decr ( awxfer ) ,
|
||||
.load_value ( ) ,
|
||||
.count ( dbg_w_to_aw_outstanding ) ,
|
||||
.is_zero ( idle_aw )
|
||||
);
|
||||
|
||||
always @(posedge aclk) begin
|
||||
wfirst_d1 <= wvalid & wfirst;
|
||||
end
|
||||
|
||||
always @(posedge aclk) begin
|
||||
wfirst_pulse <= wvalid & wfirst & ~wfirst_d1;
|
||||
end
|
||||
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( LP_TRANSACTION_CNTR_WIDTH ) ,
|
||||
.C_INIT ( {LP_TRANSACTION_CNTR_WIDTH{1'b0}} )
|
||||
)
|
||||
inst_aw_transaction_cntr (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( start ) ,
|
||||
.incr ( 1'b0 ) ,
|
||||
.decr ( awxfer ) ,
|
||||
.load_value ( num_transactions ) ,
|
||||
.count ( aw_transactions_to_go ) ,
|
||||
.is_zero ( aw_final_transaction )
|
||||
);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AXI Write Response Channel
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign bready = 1'b1;
|
||||
assign bxfer = bready & bvalid;
|
||||
|
||||
krnl_vadd_rtl_counter #(
|
||||
.C_WIDTH ( LP_TRANSACTION_CNTR_WIDTH ) ,
|
||||
.C_INIT ( {LP_TRANSACTION_CNTR_WIDTH{1'b0}} )
|
||||
)
|
||||
inst_b_transaction_cntr (
|
||||
.clk ( aclk ) ,
|
||||
.clken ( 1'b1 ) ,
|
||||
.rst ( areset ) ,
|
||||
.load ( start ) ,
|
||||
.incr ( 1'b0 ) ,
|
||||
.decr ( bxfer ) ,
|
||||
.load_value ( num_transactions ) ,
|
||||
.count ( b_transactions_to_go ) ,
|
||||
.is_zero ( b_final_transaction )
|
||||
);
|
||||
|
||||
endmodule : krnl_vadd_rtl_axi_write_master
|
||||
|
||||
`default_nettype wire
|
|
@ -1,437 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
`timescale 1ns/1ps
|
||||
module krnl_vadd_rtl_control_s_axi
|
||||
#(parameter
|
||||
C_S_AXI_ADDR_WIDTH = 6,
|
||||
C_S_AXI_DATA_WIDTH = 32
|
||||
)(
|
||||
// axi4 lite slave signals
|
||||
input wire ACLK,
|
||||
input wire ARESET,
|
||||
input wire ACLK_EN,
|
||||
input wire [C_S_AXI_ADDR_WIDTH-1:0] AWADDR,
|
||||
input wire AWVALID,
|
||||
output wire AWREADY,
|
||||
input wire [C_S_AXI_DATA_WIDTH-1:0] WDATA,
|
||||
input wire [C_S_AXI_DATA_WIDTH/8-1:0] WSTRB,
|
||||
input wire WVALID,
|
||||
output wire WREADY,
|
||||
output wire [1:0] BRESP,
|
||||
output wire BVALID,
|
||||
input wire BREADY,
|
||||
input wire [C_S_AXI_ADDR_WIDTH-1:0] ARADDR,
|
||||
input wire ARVALID,
|
||||
output wire ARREADY,
|
||||
output wire [C_S_AXI_DATA_WIDTH-1:0] RDATA,
|
||||
output wire [1:0] RRESP,
|
||||
output wire RVALID,
|
||||
input wire RREADY,
|
||||
output wire interrupt,
|
||||
// user signals
|
||||
output wire ap_start,
|
||||
input wire ap_done,
|
||||
input wire ap_ready,
|
||||
input wire ap_idle,
|
||||
output wire [63:0] a,
|
||||
output wire [63:0] b,
|
||||
output wire [63:0] c,
|
||||
output wire [31:0] length_r
|
||||
);
|
||||
//------------------------Address Info-------------------
|
||||
// 0x00 : Control signals
|
||||
// bit 0 - ap_start (Read/Write/COH)
|
||||
// bit 1 - ap_done (Read/COR)
|
||||
// bit 2 - ap_idle (Read)
|
||||
// bit 3 - ap_ready (Read)
|
||||
// bit 7 - auto_restart (Read/Write)
|
||||
// others - reserved
|
||||
// 0x04 : Global Interrupt Enable Register
|
||||
// bit 0 - Global Interrupt Enable (Read/Write)
|
||||
// others - reserved
|
||||
// 0x08 : IP Interrupt Enable Register (Read/Write)
|
||||
// bit 0 - Channel 0 (ap_done)
|
||||
// bit 1 - Channel 1 (ap_ready)
|
||||
// others - reserved
|
||||
// 0x0c : IP Interrupt Status Register (Read/TOW)
|
||||
// bit 0 - Channel 0 (ap_done)
|
||||
// bit 1 - Channel 1 (ap_ready)
|
||||
// others - reserved
|
||||
// 0x10 : Data signal of a
|
||||
// bit 31~0 - a[31:0] (Read/Write)
|
||||
// 0x14 : Data signal of a
|
||||
// bit 31~0 - a[63:32] (Read/Write)
|
||||
// 0x18 : reserved
|
||||
// 0x1c : Data signal of b
|
||||
// bit 31~0 - b[31:0] (Read/Write)
|
||||
// 0x20 : Data signal of b
|
||||
// bit 31~0 - b[63:32] (Read/Write)
|
||||
// 0x24 : reserved
|
||||
// 0x28 : Data signal of c
|
||||
// bit 31~0 - c[31:0] (Read/Write)
|
||||
// 0x2c : Data signal of c
|
||||
// bit 31~0 - c[63:32] (Read/Write)
|
||||
// 0x30 : reserved
|
||||
// 0x34 : Data signal of length_r
|
||||
// bit 31~0 - length_r[31:0] (Read/Write)
|
||||
// 0x38 : reserved
|
||||
// (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)
|
||||
|
||||
//------------------------Parameter----------------------
|
||||
localparam
|
||||
ADDR_AP_CTRL = 6'h00,
|
||||
ADDR_GIE = 6'h04,
|
||||
ADDR_IER = 6'h08,
|
||||
ADDR_ISR = 6'h0c,
|
||||
ADDR_A_DATA_0 = 6'h10,
|
||||
ADDR_A_DATA_1 = 6'h14,
|
||||
ADDR_A_CTRL = 6'h18,
|
||||
ADDR_B_DATA_0 = 6'h1c,
|
||||
ADDR_B_DATA_1 = 6'h20,
|
||||
ADDR_B_CTRL = 6'h24,
|
||||
ADDR_C_DATA_0 = 6'h28,
|
||||
ADDR_C_DATA_1 = 6'h2c,
|
||||
ADDR_C_CTRL = 6'h30,
|
||||
ADDR_LENGTH_R_DATA_0 = 6'h34,
|
||||
ADDR_LENGTH_R_CTRL = 6'h38,
|
||||
WRIDLE = 2'd0,
|
||||
WRDATA = 2'd1,
|
||||
WRRESP = 2'd2,
|
||||
RDIDLE = 2'd0,
|
||||
RDDATA = 2'd1,
|
||||
ADDR_BITS = 6;
|
||||
|
||||
//------------------------Local signal-------------------
|
||||
reg [1:0] wstate = WRIDLE;
|
||||
reg [1:0] wnext;
|
||||
reg [ADDR_BITS-1:0] waddr;
|
||||
wire [31:0] wmask;
|
||||
wire aw_hs;
|
||||
wire w_hs;
|
||||
reg [1:0] rstate = RDIDLE;
|
||||
reg [1:0] rnext;
|
||||
reg [31:0] rdata;
|
||||
wire ar_hs;
|
||||
wire [ADDR_BITS-1:0] raddr;
|
||||
// internal registers
|
||||
wire int_ap_idle;
|
||||
wire int_ap_ready;
|
||||
reg int_ap_done = 1'b0;
|
||||
reg int_ap_start = 1'b0;
|
||||
reg int_auto_restart = 1'b0;
|
||||
reg int_gie = 2'b0;
|
||||
reg [1:0] int_ier = 2'b0;
|
||||
reg [1:0] int_isr = 2'b0;
|
||||
reg [63:0] int_a = 64'b0;
|
||||
reg [63:0] int_b = 64'b0;
|
||||
reg [63:0] int_c = 64'b0;
|
||||
reg [31:0] int_length_r = 32'b0;
|
||||
|
||||
//------------------------Instantiation------------------
|
||||
|
||||
//------------------------AXI write fsm------------------
|
||||
assign AWREADY = (~ARESET) & (wstate == WRIDLE);
|
||||
assign WREADY = (wstate == WRDATA);
|
||||
assign BRESP = 2'b00; // OKAY
|
||||
assign BVALID = (wstate == WRRESP);
|
||||
assign wmask = { {8{WSTRB[3]}}, {8{WSTRB[2]}}, {8{WSTRB[1]}}, {8{WSTRB[0]}} };
|
||||
assign aw_hs = AWVALID & AWREADY;
|
||||
assign w_hs = WVALID & WREADY;
|
||||
|
||||
// wstate
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
wstate <= WRIDLE;
|
||||
else if (ACLK_EN)
|
||||
wstate <= wnext;
|
||||
end
|
||||
|
||||
// wnext
|
||||
always @(*) begin
|
||||
case (wstate)
|
||||
WRIDLE:
|
||||
if (AWVALID)
|
||||
wnext = WRDATA;
|
||||
else
|
||||
wnext = WRIDLE;
|
||||
WRDATA:
|
||||
if (WVALID)
|
||||
wnext = WRRESP;
|
||||
else
|
||||
wnext = WRDATA;
|
||||
WRRESP:
|
||||
if (BREADY)
|
||||
wnext = WRIDLE;
|
||||
else
|
||||
wnext = WRRESP;
|
||||
default:
|
||||
wnext = WRIDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// waddr
|
||||
always @(posedge ACLK) begin
|
||||
if (ACLK_EN) begin
|
||||
if (aw_hs)
|
||||
waddr <= AWADDR[ADDR_BITS-1:0];
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------AXI read fsm-------------------
|
||||
assign ARREADY = (~ARESET) && (rstate == RDIDLE);
|
||||
assign RDATA = rdata;
|
||||
assign RRESP = 2'b00; // OKAY
|
||||
assign RVALID = (rstate == RDDATA);
|
||||
assign ar_hs = ARVALID & ARREADY;
|
||||
assign raddr = ARADDR[ADDR_BITS-1:0];
|
||||
|
||||
// rstate
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
rstate <= RDIDLE;
|
||||
else if (ACLK_EN)
|
||||
rstate <= rnext;
|
||||
end
|
||||
|
||||
// rnext
|
||||
always @(*) begin
|
||||
case (rstate)
|
||||
RDIDLE:
|
||||
if (ARVALID)
|
||||
rnext = RDDATA;
|
||||
else
|
||||
rnext = RDIDLE;
|
||||
RDDATA:
|
||||
if (RREADY & RVALID)
|
||||
rnext = RDIDLE;
|
||||
else
|
||||
rnext = RDDATA;
|
||||
default:
|
||||
rnext = RDIDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// rdata
|
||||
always @(posedge ACLK) begin
|
||||
if (ACLK_EN) begin
|
||||
if (ar_hs) begin
|
||||
rdata <= 1'b0;
|
||||
case (raddr)
|
||||
ADDR_AP_CTRL: begin
|
||||
rdata[0] <= int_ap_start;
|
||||
rdata[1] <= int_ap_done;
|
||||
rdata[2] <= int_ap_idle;
|
||||
rdata[3] <= int_ap_ready;
|
||||
rdata[7] <= int_auto_restart;
|
||||
end
|
||||
ADDR_GIE: begin
|
||||
rdata <= int_gie;
|
||||
end
|
||||
ADDR_IER: begin
|
||||
rdata <= int_ier;
|
||||
end
|
||||
ADDR_ISR: begin
|
||||
rdata <= int_isr;
|
||||
end
|
||||
ADDR_A_DATA_0: begin
|
||||
rdata <= int_a[31:0];
|
||||
end
|
||||
ADDR_A_DATA_1: begin
|
||||
rdata <= int_a[63:32];
|
||||
end
|
||||
ADDR_B_DATA_0: begin
|
||||
rdata <= int_b[31:0];
|
||||
end
|
||||
ADDR_B_DATA_1: begin
|
||||
rdata <= int_b[63:32];
|
||||
end
|
||||
ADDR_C_DATA_0: begin
|
||||
rdata <= int_c[31:0];
|
||||
end
|
||||
ADDR_C_DATA_1: begin
|
||||
rdata <= int_c[63:32];
|
||||
end
|
||||
ADDR_LENGTH_R_DATA_0: begin
|
||||
rdata <= int_length_r[31:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//------------------------Register logic-----------------
|
||||
assign interrupt = int_gie & (|int_isr);
|
||||
assign ap_start = int_ap_start;
|
||||
assign int_ap_idle = ap_idle;
|
||||
assign int_ap_ready = ap_ready;
|
||||
assign a = int_a;
|
||||
assign b = int_b;
|
||||
assign c = int_c;
|
||||
assign length_r = int_length_r;
|
||||
// int_ap_start
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_ap_start <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_AP_CTRL && WSTRB[0] && WDATA[0])
|
||||
int_ap_start <= 1'b1;
|
||||
else if (int_ap_ready)
|
||||
int_ap_start <= int_auto_restart; // clear on handshake/auto restart
|
||||
end
|
||||
end
|
||||
|
||||
// int_ap_done
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_ap_done <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (ap_done)
|
||||
int_ap_done <= 1'b1;
|
||||
else if (ar_hs && raddr == ADDR_AP_CTRL)
|
||||
int_ap_done <= 1'b0; // clear on read
|
||||
end
|
||||
end
|
||||
|
||||
// int_auto_restart
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_auto_restart <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_AP_CTRL && WSTRB[0])
|
||||
int_auto_restart <= WDATA[7];
|
||||
end
|
||||
end
|
||||
|
||||
// int_gie
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_gie <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_GIE && WSTRB[0])
|
||||
int_gie <= WDATA[0];
|
||||
end
|
||||
end
|
||||
|
||||
// int_ier
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_ier <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_IER && WSTRB[0])
|
||||
int_ier <= WDATA[1:0];
|
||||
end
|
||||
end
|
||||
|
||||
// int_isr[0]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_isr[0] <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (int_ier[0] & ap_done)
|
||||
int_isr[0] <= 1'b1;
|
||||
else if (w_hs && waddr == ADDR_ISR && WSTRB[0])
|
||||
int_isr[0] <= int_isr[0] ^ WDATA[0]; // toggle on write
|
||||
end
|
||||
end
|
||||
|
||||
// int_isr[1]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_isr[1] <= 1'b0;
|
||||
else if (ACLK_EN) begin
|
||||
if (int_ier[1] & ap_ready)
|
||||
int_isr[1] <= 1'b1;
|
||||
else if (w_hs && waddr == ADDR_ISR && WSTRB[0])
|
||||
int_isr[1] <= int_isr[1] ^ WDATA[1]; // toggle on write
|
||||
end
|
||||
end
|
||||
|
||||
// int_a[31:0]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_a[31:0] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_A_DATA_0)
|
||||
int_a[31:0] <= (WDATA[31:0] & wmask) | (int_a[31:0] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
// int_a[63:32]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_a[63:32] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_A_DATA_1)
|
||||
int_a[63:32] <= (WDATA[31:0] & wmask) | (int_a[63:32] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
// int_b[31:0]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_b[31:0] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_B_DATA_0)
|
||||
int_b[31:0] <= (WDATA[31:0] & wmask) | (int_b[31:0] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
// int_b[63:32]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_b[63:32] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_B_DATA_1)
|
||||
int_b[63:32] <= (WDATA[31:0] & wmask) | (int_b[63:32] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
// int_c[31:0]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_c[31:0] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_C_DATA_0)
|
||||
int_c[31:0] <= (WDATA[31:0] & wmask) | (int_c[31:0] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
// int_c[63:32]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_c[63:32] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_C_DATA_1)
|
||||
int_c[63:32] <= (WDATA[31:0] & wmask) | (int_c[63:32] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
// int_length_r[31:0]
|
||||
always @(posedge ACLK) begin
|
||||
if (ARESET)
|
||||
int_length_r[31:0] <= 0;
|
||||
else if (ACLK_EN) begin
|
||||
if (w_hs && waddr == ADDR_LENGTH_R_DATA_0)
|
||||
int_length_r[31:0] <= (WDATA[31:0] & wmask) | (int_length_r[31:0] & ~wmask);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//------------------------Memory logic-------------------
|
||||
|
||||
endmodule
|
|
@ -1,87 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Simple up/down counter with reset.
|
||||
//-----------------------------------------------------------------------------
|
||||
`default_nettype none
|
||||
`timescale 1ps/1ps
|
||||
module krnl_vadd_rtl_counter #(
|
||||
parameter integer C_WIDTH = 4,
|
||||
parameter [C_WIDTH-1:0] C_INIT = {C_WIDTH{1'b0}}
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
input wire clken,
|
||||
input wire rst,
|
||||
input wire load,
|
||||
input wire incr,
|
||||
input wire decr,
|
||||
input wire [C_WIDTH-1:0] load_value,
|
||||
output wire [C_WIDTH-1:0] count,
|
||||
output wire is_zero
|
||||
);
|
||||
|
||||
localparam [C_WIDTH-1:0] LP_ZERO = {C_WIDTH{1'b0}};
|
||||
localparam [C_WIDTH-1:0] LP_ONE = {{C_WIDTH-1{1'b0}},1'b1};
|
||||
localparam [C_WIDTH-1:0] LP_MAX = {C_WIDTH{1'b1}};
|
||||
|
||||
reg [C_WIDTH-1:0] count_r = C_INIT;
|
||||
reg is_zero_r = (C_INIT == LP_ZERO);
|
||||
|
||||
assign count = count_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
count_r <= C_INIT;
|
||||
end
|
||||
else if (clken) begin
|
||||
if (load) begin
|
||||
count_r <= load_value;
|
||||
end
|
||||
else if (incr & ~decr) begin
|
||||
count_r <= count_r + 1'b1;
|
||||
end
|
||||
else if (~incr & decr) begin
|
||||
count_r <= count_r - 1'b1;
|
||||
end
|
||||
else
|
||||
count_r <= count_r;
|
||||
end
|
||||
end
|
||||
|
||||
assign is_zero = is_zero_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
is_zero_r <= (C_INIT == LP_ZERO);
|
||||
end
|
||||
else if (clken) begin
|
||||
if (load) begin
|
||||
is_zero_r <= (load_value == LP_ZERO);
|
||||
end
|
||||
else begin
|
||||
is_zero_r <= incr ^ decr ? (decr && (count_r == LP_ONE)) || (incr && (count_r == LP_MAX)) : is_zero_r;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
is_zero_r <= is_zero_r;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule : krnl_vadd_rtl_counter
|
||||
`default_nettype wire
|
|
@ -1,418 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Description: This is a example of how to create an RTL Kernel. The function
|
||||
// of this module is to add two 32-bit values and produce a result. The values
|
||||
// are read from one AXI4 memory mapped master, processed and then written out.
|
||||
//
|
||||
// Data flow: axi_read_master->fifo[2]->adder->fifo->axi_write_master
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// default_nettype of none prevents implicit wire declaration.
|
||||
`default_nettype none
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module krnl_vadd_rtl_int #(
|
||||
parameter integer C_S_AXI_CTRL_DATA_WIDTH = 32,
|
||||
parameter integer C_S_AXI_CTRL_ADDR_WIDTH = 6,
|
||||
parameter integer C_M_AXI_MEM_ID_WIDTH = 1,
|
||||
parameter integer C_M_AXI_MEM_ADDR_WIDTH = 32,
|
||||
parameter integer C_M_AXI_MEM_DATA_WIDTH = 32
|
||||
)
|
||||
(
|
||||
// System signals
|
||||
input wire ap_clk,
|
||||
input wire ap_rst_n,
|
||||
|
||||
// AXI4 master interface
|
||||
output wire m_axi_mem_awvalid,
|
||||
input wire m_axi_mem_awready,
|
||||
output wire [C_M_AXI_MEM_ADDR_WIDTH-1:0] m_axi_mem_awaddr,
|
||||
output wire [C_M_AXI_MEM_ID_WIDTH - 1:0] m_axi_mem_awid,
|
||||
output wire [7:0] m_axi_mem_awlen,
|
||||
output wire [2:0] m_axi_mem_awsize,
|
||||
output wire [1:0] m_axi_mem_awburst,
|
||||
output wire [1:0] m_axi_mem_awlock,
|
||||
output wire [3:0] m_axi_mem_awcache,
|
||||
output wire [2:0] m_axi_mem_awprot,
|
||||
output wire [3:0] m_axi_mem_awqos,
|
||||
output wire [3:0] m_axi_mem_awregion,
|
||||
|
||||
output wire m_axi_mem_wvalid,
|
||||
input wire m_axi_mem_wready,
|
||||
output wire [C_M_AXI_MEM_DATA_WIDTH-1:0] m_axi_mem_wdata,
|
||||
output wire [C_M_AXI_MEM_DATA_WIDTH/8-1:0] m_axi_mem_wstrb,
|
||||
output wire m_axi_mem_wlast,
|
||||
|
||||
input wire m_axi_mem_bvalid,
|
||||
output wire m_axi_mem_bready,
|
||||
input wire [1:0] m_axi_mem_bresp,
|
||||
input wire [C_M_AXI_MEM_ID_WIDTH - 1:0] m_axi_mem_bid,
|
||||
|
||||
output wire m_axi_mem_arvalid,
|
||||
input wire m_axi_mem_arready,
|
||||
output wire [C_M_AXI_MEM_ADDR_WIDTH-1:0] m_axi_mem_araddr,
|
||||
output wire [C_M_AXI_MEM_ID_WIDTH-1:0] m_axi_mem_arid,
|
||||
output wire [7:0] m_axi_mem_arlen,
|
||||
output wire [2:0] m_axi_mem_arsize,
|
||||
output wire [1:0] m_axi_mem_arburst,
|
||||
output wire [1:0] m_axi_mem_arlock,
|
||||
output wire [3:0] m_axi_mem_arcache,
|
||||
output wire [2:0] m_axi_mem_arprot,
|
||||
output wire [3:0] m_axi_mem_arqos,
|
||||
output wire [3:0] m_axi_mem_arregion,
|
||||
|
||||
input wire m_axi_mem_rvalid,
|
||||
output wire m_axi_mem_rready,
|
||||
input wire [C_M_AXI_MEM_DATA_WIDTH - 1:0] m_axi_mem_rdata,
|
||||
input wire m_axi_mem_rlast,
|
||||
input wire [C_M_AXI_MEM_ID_WIDTH - 1:0] m_axi_mem_rid,
|
||||
input wire [1:0] m_axi_mem_rresp,
|
||||
|
||||
// AXI4-Lite slave interface
|
||||
input wire s_axi_ctrl_awvalid,
|
||||
output wire s_axi_ctrl_awready,
|
||||
input wire [C_S_AXI_CTRL_ADDR_WIDTH-1:0] s_axi_ctrl_awaddr,
|
||||
input wire s_axi_ctrl_wvalid,
|
||||
output wire s_axi_ctrl_wready,
|
||||
input wire [C_S_AXI_CTRL_DATA_WIDTH-1:0] s_axi_ctrl_wdata,
|
||||
input wire [C_S_AXI_CTRL_DATA_WIDTH/8-1:0] s_axi_ctrl_wstrb,
|
||||
input wire s_axi_ctrl_arvalid,
|
||||
output wire s_axi_ctrl_arready,
|
||||
input wire [C_S_AXI_CTRL_ADDR_WIDTH-1:0] s_axi_ctrl_araddr,
|
||||
output wire s_axi_ctrl_rvalid,
|
||||
input wire s_axi_ctrl_rready,
|
||||
output wire [C_S_AXI_CTRL_DATA_WIDTH-1:0] s_axi_ctrl_rdata,
|
||||
output wire [1:0] s_axi_ctrl_rresp,
|
||||
output wire s_axi_ctrl_bvalid,
|
||||
input wire s_axi_ctrl_bready,
|
||||
output wire [1:0] s_axi_ctrl_bresp,
|
||||
output wire interrupt
|
||||
);
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Local Parameters (constants)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
localparam integer LP_NUM_READ_CHANNELS = 2;
|
||||
localparam integer LP_LENGTH_WIDTH = 32;
|
||||
localparam integer LP_DW_BYTES = C_M_AXI_MEM_DATA_WIDTH/8;
|
||||
localparam integer LP_AXI_BURST_LEN = 4096/LP_DW_BYTES < 256 ? 4096/LP_DW_BYTES : 256;
|
||||
localparam integer LP_LOG_BURST_LEN = $clog2(LP_AXI_BURST_LEN);
|
||||
localparam integer LP_RD_MAX_OUTSTANDING = 3;
|
||||
localparam integer LP_RD_FIFO_DEPTH = LP_AXI_BURST_LEN*(LP_RD_MAX_OUTSTANDING + 1);
|
||||
localparam integer LP_WR_FIFO_DEPTH = LP_AXI_BURST_LEN;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
logic areset = 1'b0;
|
||||
logic ap_start;
|
||||
logic ap_start_pulse;
|
||||
logic ap_start_r;
|
||||
logic ap_ready;
|
||||
logic ap_done;
|
||||
logic ap_idle = 1'b1;
|
||||
logic [C_M_AXI_MEM_ADDR_WIDTH-1:0] a;
|
||||
logic [C_M_AXI_MEM_ADDR_WIDTH-1:0] b;
|
||||
logic [C_M_AXI_MEM_ADDR_WIDTH-1:0] c;
|
||||
logic [LP_LENGTH_WIDTH-1:0] length_r;
|
||||
|
||||
logic read_done;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] rd_tvalid;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] rd_tready_n;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] [C_M_AXI_MEM_DATA_WIDTH-1:0] rd_tdata;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] ctrl_rd_fifo_prog_full;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] rd_fifo_tvalid_n;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] rd_fifo_tready;
|
||||
logic [LP_NUM_READ_CHANNELS-1:0] [C_M_AXI_MEM_DATA_WIDTH-1:0] rd_fifo_tdata;
|
||||
|
||||
logic adder_tvalid;
|
||||
logic adder_tready_n;
|
||||
logic [C_M_AXI_MEM_DATA_WIDTH-1:0] adder_tdata;
|
||||
logic wr_fifo_tvalid_n;
|
||||
logic wr_fifo_tready;
|
||||
logic [C_M_AXI_MEM_DATA_WIDTH-1:0] wr_fifo_tdata;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RTL Logic
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Tie-off unused AXI protocol features
|
||||
assign m_axi_mem_awid = {C_M_AXI_MEM_ID_WIDTH{1'b0}};
|
||||
assign m_axi_mem_awburst = 2'b01;
|
||||
assign m_axi_mem_awlock = 2'b00;
|
||||
assign m_axi_mem_awcache = 4'b0000;
|
||||
assign m_axi_mem_awprot = 3'b000;
|
||||
assign m_axi_mem_awqos = 4'b0000;
|
||||
assign m_axi_mem_awregion = 4'b0000;
|
||||
assign m_axi_mem_arburst = 2'b01;
|
||||
assign m_axi_mem_arlock = 2'b00;
|
||||
assign m_axi_mem_arcache = 4'b0000;
|
||||
assign m_axi_mem_arprot = 3'b000;
|
||||
assign m_axi_mem_arqos = 4'b0000;
|
||||
assign m_axi_mem_arregion = 4'b0000;
|
||||
|
||||
// Register and invert reset signal for better timing.
|
||||
always @(posedge ap_clk) begin
|
||||
areset <= ~ap_rst_n;
|
||||
end
|
||||
|
||||
// create pulse when ap_start transitions to 1
|
||||
always @(posedge ap_clk) begin
|
||||
begin
|
||||
ap_start_r <= ap_start;
|
||||
end
|
||||
end
|
||||
|
||||
assign ap_start_pulse = ap_start & ~ap_start_r;
|
||||
|
||||
// ap_idle is asserted when done is asserted, it is de-asserted when ap_start_pulse
|
||||
// is asserted
|
||||
always @(posedge ap_clk) begin
|
||||
if (areset) begin
|
||||
ap_idle <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
ap_idle <= ap_done ? 1'b1 :
|
||||
ap_start_pulse ? 1'b0 :
|
||||
ap_idle;
|
||||
end
|
||||
end
|
||||
|
||||
assign ap_ready = ap_done;
|
||||
|
||||
// AXI4-Lite slave
|
||||
krnl_vadd_rtl_control_s_axi #(
|
||||
.C_S_AXI_ADDR_WIDTH( C_S_AXI_CTRL_ADDR_WIDTH ),
|
||||
.C_S_AXI_DATA_WIDTH( C_S_AXI_CTRL_DATA_WIDTH )
|
||||
)
|
||||
inst_krnl_vadd_control_s_axi (
|
||||
.AWVALID ( s_axi_ctrl_awvalid ) ,
|
||||
.AWREADY ( s_axi_ctrl_awready ) ,
|
||||
.AWADDR ( s_axi_ctrl_awaddr ) ,
|
||||
.WVALID ( s_axi_ctrl_wvalid ) ,
|
||||
.WREADY ( s_axi_ctrl_wready ) ,
|
||||
.WDATA ( s_axi_ctrl_wdata ) ,
|
||||
.WSTRB ( s_axi_ctrl_wstrb ) ,
|
||||
.ARVALID ( s_axi_ctrl_arvalid ) ,
|
||||
.ARREADY ( s_axi_ctrl_arready ) ,
|
||||
.ARADDR ( s_axi_ctrl_araddr ) ,
|
||||
.RVALID ( s_axi_ctrl_rvalid ) ,
|
||||
.RREADY ( s_axi_ctrl_rready ) ,
|
||||
.RDATA ( s_axi_ctrl_rdata ) ,
|
||||
.RRESP ( s_axi_ctrl_rresp ) ,
|
||||
.BVALID ( s_axi_ctrl_bvalid ) ,
|
||||
.BREADY ( s_axi_ctrl_bready ) ,
|
||||
.BRESP ( s_axi_ctrl_bresp ) ,
|
||||
.ACLK ( ap_clk ) ,
|
||||
.ARESET ( areset ) ,
|
||||
.ACLK_EN ( 1'b1 ) ,
|
||||
.ap_start ( ap_start ) ,
|
||||
.interrupt ( interrupt ) ,
|
||||
.ap_ready ( ap_ready ) ,
|
||||
.ap_done ( ap_done ) ,
|
||||
.ap_idle ( ap_idle ) ,
|
||||
.a ( a[0+:C_M_AXI_MEM_ADDR_WIDTH] ) ,
|
||||
.b ( b[0+:C_M_AXI_MEM_ADDR_WIDTH] ) ,
|
||||
.c ( c[0+:C_M_AXI_MEM_ADDR_WIDTH] ) ,
|
||||
.length_r ( length_r[0+:LP_LENGTH_WIDTH] )
|
||||
);
|
||||
|
||||
// AXI4 Read Master
|
||||
krnl_vadd_rtl_axi_read_master #(
|
||||
.C_ADDR_WIDTH ( C_M_AXI_MEM_ADDR_WIDTH ) ,
|
||||
.C_DATA_WIDTH ( C_M_AXI_MEM_DATA_WIDTH ) ,
|
||||
.C_ID_WIDTH ( C_M_AXI_MEM_ID_WIDTH ) ,
|
||||
.C_NUM_CHANNELS ( LP_NUM_READ_CHANNELS ) ,
|
||||
.C_LENGTH_WIDTH ( LP_LENGTH_WIDTH ) ,
|
||||
.C_BURST_LEN ( LP_AXI_BURST_LEN ) ,
|
||||
.C_LOG_BURST_LEN ( LP_LOG_BURST_LEN ) ,
|
||||
.C_MAX_OUTSTANDING ( LP_RD_MAX_OUTSTANDING )
|
||||
)
|
||||
inst_axi_read_master (
|
||||
.aclk ( ap_clk ) ,
|
||||
.areset ( areset ) ,
|
||||
|
||||
.ctrl_start ( ap_start_pulse ) ,
|
||||
.ctrl_done ( read_done ) ,
|
||||
.ctrl_offset ( {b,a} ) ,
|
||||
.ctrl_length ( length_r ) ,
|
||||
.ctrl_prog_full ( ctrl_rd_fifo_prog_full ) ,
|
||||
|
||||
.arvalid ( m_axi_mem_arvalid ) ,
|
||||
.arready ( m_axi_mem_arready ) ,
|
||||
.araddr ( m_axi_mem_araddr ) ,
|
||||
.arid ( m_axi_mem_arid ) ,
|
||||
.arlen ( m_axi_mem_arlen ) ,
|
||||
.arsize ( m_axi_mem_arsize ) ,
|
||||
.rvalid ( m_axi_mem_rvalid ) ,
|
||||
.rready ( m_axi_mem_rready ) ,
|
||||
.rdata ( m_axi_mem_rdata ) ,
|
||||
.rlast ( m_axi_mem_rlast ) ,
|
||||
.rid ( m_axi_mem_rid ) ,
|
||||
.rresp ( m_axi_mem_rresp ) ,
|
||||
|
||||
.m_tvalid ( rd_tvalid ) ,
|
||||
.m_tready ( ~rd_tready_n ) ,
|
||||
.m_tdata ( rd_tdata )
|
||||
);
|
||||
|
||||
// xpm_fifo_sync: Synchronous FIFO
|
||||
// Xilinx Parameterized Macro, Version 2016.4
|
||||
xpm_fifo_sync # (
|
||||
.FIFO_MEMORY_TYPE ("auto"), //string; "auto", "block", "distributed", or "ultra";
|
||||
.ECC_MODE ("no_ecc"), //string; "no_ecc" or "en_ecc";
|
||||
.FIFO_WRITE_DEPTH (LP_RD_FIFO_DEPTH), //positive integer
|
||||
.WRITE_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH), //positive integer
|
||||
.WR_DATA_COUNT_WIDTH ($clog2(LP_RD_FIFO_DEPTH)+1), //positive integer, Not used
|
||||
.PROG_FULL_THRESH (LP_AXI_BURST_LEN-2), //positive integer
|
||||
.FULL_RESET_VALUE (1), //positive integer; 0 or 1
|
||||
.READ_MODE ("fwft"), //string; "std" or "fwft";
|
||||
.FIFO_READ_LATENCY (1), //positive integer;
|
||||
.READ_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH), //positive integer
|
||||
.RD_DATA_COUNT_WIDTH ($clog2(LP_RD_FIFO_DEPTH)+1), //positive integer, not used
|
||||
.PROG_EMPTY_THRESH (10), //positive integer, not used
|
||||
.DOUT_RESET_VALUE ("0"), //string, don't care
|
||||
.WAKEUP_TIME (0) //positive integer; 0 or 2;
|
||||
|
||||
) inst_rd_xpm_fifo_sync[LP_NUM_READ_CHANNELS-1:0] (
|
||||
.sleep ( 1'b0 ) ,
|
||||
.rst ( areset ) ,
|
||||
.wr_clk ( ap_clk ) ,
|
||||
.wr_en ( rd_tvalid ) ,
|
||||
.din ( rd_tdata ) ,
|
||||
.full ( rd_tready_n ) ,
|
||||
.prog_full ( ctrl_rd_fifo_prog_full) ,
|
||||
.wr_data_count ( ) ,
|
||||
.overflow ( ) ,
|
||||
.wr_rst_busy ( ) ,
|
||||
.rd_en ( rd_fifo_tready ) ,
|
||||
.dout ( rd_fifo_tdata ) ,
|
||||
.empty ( rd_fifo_tvalid_n ) ,
|
||||
.prog_empty ( ) ,
|
||||
.rd_data_count ( ) ,
|
||||
.underflow ( ) ,
|
||||
.rd_rst_busy ( ) ,
|
||||
.injectsbiterr ( 1'b0 ) ,
|
||||
.injectdbiterr ( 1'b0 ) ,
|
||||
.sbiterr ( ) ,
|
||||
.dbiterr ( )
|
||||
|
||||
);
|
||||
|
||||
// Combinatorial Adder
|
||||
krnl_vadd_rtl_adder #(
|
||||
.C_DATA_WIDTH ( C_M_AXI_MEM_DATA_WIDTH ) ,
|
||||
.C_NUM_CHANNELS ( LP_NUM_READ_CHANNELS )
|
||||
)
|
||||
inst_adder (
|
||||
.aclk ( ap_clk ) ,
|
||||
.areset ( areset ) ,
|
||||
|
||||
.s_tvalid ( ~rd_fifo_tvalid_n ) ,
|
||||
.s_tready ( rd_fifo_tready ) ,
|
||||
.s_tdata ( rd_fifo_tdata ) ,
|
||||
|
||||
.m_tvalid ( adder_tvalid ) ,
|
||||
.m_tready ( ~adder_tready_n ) ,
|
||||
.m_tdata ( adder_tdata )
|
||||
);
|
||||
|
||||
// xpm_fifo_sync: Synchronous FIFO
|
||||
// Xilinx Parameterized Macro, Version 2016.4
|
||||
xpm_fifo_sync # (
|
||||
.FIFO_MEMORY_TYPE ("auto"), //string; "auto", "block", "distributed", or "ultra";
|
||||
.ECC_MODE ("no_ecc"), //string; "no_ecc" or "en_ecc";
|
||||
.FIFO_WRITE_DEPTH (LP_WR_FIFO_DEPTH), //positive integer
|
||||
.WRITE_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH), //positive integer
|
||||
.WR_DATA_COUNT_WIDTH ($clog2(LP_WR_FIFO_DEPTH)), //positive integer, Not used
|
||||
.PROG_FULL_THRESH (10), //positive integer, Not used
|
||||
.FULL_RESET_VALUE (1), //positive integer; 0 or 1
|
||||
.READ_MODE ("fwft"), //string; "std" or "fwft";
|
||||
.FIFO_READ_LATENCY (1), //positive integer;
|
||||
.READ_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH), //positive integer
|
||||
.RD_DATA_COUNT_WIDTH ($clog2(LP_WR_FIFO_DEPTH)), //positive integer, not used
|
||||
.PROG_EMPTY_THRESH (10), //positive integer, not used
|
||||
.DOUT_RESET_VALUE ("0"), //string, don't care
|
||||
.WAKEUP_TIME (0) //positive integer; 0 or 2;
|
||||
|
||||
) inst_wr_xpm_fifo_sync (
|
||||
.sleep ( 1'b0 ) ,
|
||||
.rst ( areset ) ,
|
||||
.wr_clk ( ap_clk ) ,
|
||||
.wr_en ( adder_tvalid ) ,
|
||||
.din ( adder_tdata ) ,
|
||||
.full ( adder_tready_n ) ,
|
||||
.prog_full ( ) ,
|
||||
.wr_data_count ( ) ,
|
||||
.overflow ( ) ,
|
||||
.wr_rst_busy ( ) ,
|
||||
.rd_en ( wr_fifo_tready ) ,
|
||||
.dout ( wr_fifo_tdata ) ,
|
||||
.empty ( wr_fifo_tvalid_n ) ,
|
||||
.prog_empty ( ) ,
|
||||
.rd_data_count ( ) ,
|
||||
.underflow ( ) ,
|
||||
.rd_rst_busy ( ) ,
|
||||
.injectsbiterr ( 1'b0 ) ,
|
||||
.injectdbiterr ( 1'b0 ) ,
|
||||
.sbiterr ( ) ,
|
||||
.dbiterr ( )
|
||||
|
||||
);
|
||||
|
||||
|
||||
// AXI4 Write Master
|
||||
krnl_vadd_rtl_axi_write_master #(
|
||||
.C_ADDR_WIDTH ( C_M_AXI_MEM_ADDR_WIDTH ) ,
|
||||
.C_DATA_WIDTH ( C_M_AXI_MEM_DATA_WIDTH ) ,
|
||||
.C_MAX_LENGTH_WIDTH ( LP_LENGTH_WIDTH ) ,
|
||||
.C_BURST_LEN ( LP_AXI_BURST_LEN ) ,
|
||||
.C_LOG_BURST_LEN ( LP_LOG_BURST_LEN )
|
||||
)
|
||||
inst_axi_write_master (
|
||||
.aclk ( ap_clk ) ,
|
||||
.areset ( areset ) ,
|
||||
|
||||
.ctrl_start ( ap_start_pulse ) ,
|
||||
.ctrl_offset ( c ) ,
|
||||
.ctrl_length ( length_r ) ,
|
||||
.ctrl_done ( ap_done ) ,
|
||||
|
||||
.awvalid ( m_axi_mem_awvalid ) ,
|
||||
.awready ( m_axi_mem_awready ) ,
|
||||
.awaddr ( m_axi_mem_awaddr ) ,
|
||||
.awlen ( m_axi_mem_awlen ) ,
|
||||
.awsize ( m_axi_mem_awsize ) ,
|
||||
|
||||
.s_tvalid ( ~wr_fifo_tvalid_n ) ,
|
||||
.s_tready ( wr_fifo_tready ) ,
|
||||
.s_tdata ( wr_fifo_tdata ) ,
|
||||
|
||||
.wvalid ( m_axi_mem_wvalid ) ,
|
||||
.wready ( m_axi_mem_wready ) ,
|
||||
.wdata ( m_axi_mem_wdata ) ,
|
||||
.wstrb ( m_axi_mem_wstrb ) ,
|
||||
.wlast ( m_axi_mem_wlast ) ,
|
||||
|
||||
.bvalid ( m_axi_mem_bvalid ) ,
|
||||
.bready ( m_axi_mem_bready ) ,
|
||||
.bresp ( m_axi_mem_bresp )
|
||||
);
|
||||
|
||||
endmodule : krnl_vadd_rtl_int
|
||||
|
||||
`default_nettype wire
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root versionMajor="1" versionMinor="6">
|
||||
<kernel name="krnl_vadd_rtl" language="ip_c" vlnv="xilinx.com:RTLKernel:krnl_vadd_rtl:1.0" attributes="" preferredWorkGroupSizeMultiple="0" workGroupSize="1" interrupt="true" hwControlProtocol="user_managed">
|
||||
<ports>
|
||||
<port name="s_axi_ctrl" mode="slave" range="0x1000" dataWidth="32" portType="addressable" base="0x0"/>
|
||||
<port name="m_axi_mem" mode="master" range="0xFFFFFFFF" dataWidth="32" portType="addressable" base="0x0"/>
|
||||
</ports>
|
||||
<args>
|
||||
<arg id="0" name="a" addressQualifier="1" port="m_axi_mem" size="0x8" offset="0x010" type="void*" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="1" name="b" addressQualifier="1" port="m_axi_mem" size="0x8" offset="0x01C" type="void*" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="2" name="c" addressQualifier="1" port="m_axi_mem" size="0x8" offset="0x028" type="void*" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="3" name="l" addressQualifier="0" port="s_axi_ctrl" size="0x4" offset="0x034" type="uint" hostOffset="0x0" hostSize="0x4"/>
|
||||
</args>
|
||||
</kernel>
|
||||
</root>
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
exclude_list="VX_fpu_fpnew.sv"
|
||||
macros=()
|
||||
includes=()
|
||||
|
||||
# parse command arguments
|
||||
while getopts D:I:h flag
|
||||
do
|
||||
case "${flag}" in
|
||||
D) macros+=( ${OPTARG} );;
|
||||
I) includes+=( ${OPTARG} );;
|
||||
h) echo "Usage: [-D macro] [-I include] [-h help]"
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# dump macros
|
||||
for value in ${macros[@]}; do
|
||||
echo "+define+$value"
|
||||
done
|
||||
|
||||
# dump include directories
|
||||
for dir in ${includes[@]}; do
|
||||
echo "+incdir+$dir"
|
||||
done
|
||||
|
||||
# dump source files
|
||||
for dir in ${includes[@]}; do
|
||||
for file in $(find $dir -maxdepth 1 -name '*.v' -o -name '*.sv' -type f); do
|
||||
exclude=0
|
||||
for fe in $exclude_list; do
|
||||
if [[ $file =~ $fe ]]; then
|
||||
exclude=1
|
||||
fi
|
||||
done
|
||||
if [[ $exclude == 0 ]]; then
|
||||
echo $file
|
||||
fi
|
||||
done
|
||||
done
|
|
@ -1,23 +0,0 @@
|
|||
if { $::argc != 5 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 5 arguments!\n"
|
||||
puts "Usage: $::argv0 <xoname> <krnl_name> <vcs_file> <kernel_xml> <build_dir>\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set xoname [lindex $::argv 0]
|
||||
set krnl_name [lindex $::argv 1]
|
||||
set vcs_file [lindex $::argv 2]
|
||||
set krnl_xml [lindex $::argv 3]
|
||||
set build_dir [lindex $::argv 4]
|
||||
|
||||
set script_path [ file dirname [ file normalize [ info script ] ] ]
|
||||
|
||||
if {[file exists "${xoname}"]} {
|
||||
file delete -force "${xoname}"
|
||||
}
|
||||
|
||||
set argv [list ${krnl_name} ${build_dir}]
|
||||
set argc 2
|
||||
source ${script_path}/package_kernel.tcl
|
||||
|
||||
package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory "${build_dir}/xo/packaged_kernel" -kernel_xml ${krnl_xml}
|
|
@ -1,125 +0,0 @@
|
|||
if { $::argc != 2 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 2 arguments!\n"
|
||||
puts "Usage: $::argv0 <krnl_name> <build_dir>\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set krnl_name [lindex $::argv 0]
|
||||
set build_dir [lindex $::argv 1]
|
||||
|
||||
set script_path [ file dirname [ file normalize [ info script ] ] ]
|
||||
|
||||
set path_to_packaged "${build_dir}/xo/packaged_kernel"
|
||||
set path_to_tmp_project "${build_dir}/xo/project"
|
||||
|
||||
source "${script_path}/parse_vcs_list.tcl"
|
||||
set vlist [parse_vcs_list "${vcs_file}"]
|
||||
|
||||
set vsources_list [lindex $vlist 0]
|
||||
set vincludes_list [lindex $vlist 1]
|
||||
set vdefines_list [lindex $vlist 2]
|
||||
|
||||
#puts ${vsources_list}
|
||||
#puts ${vdefines_list}
|
||||
|
||||
# dump defines into globals.vh
|
||||
set chipscope 0
|
||||
set fh [open "${build_dir}/globals.vh" w]
|
||||
foreach def $vdefines_list {
|
||||
set fields [split $def "="]
|
||||
set len [llength $fields]
|
||||
set name [lindex $fields 0]
|
||||
puts -nonewline $fh "`define "
|
||||
if {$len > 1} {
|
||||
set value [lindex $fields 1]
|
||||
puts -nonewline $fh $name
|
||||
puts -nonewline $fh " "
|
||||
puts $fh $value
|
||||
} else {
|
||||
puts $fh $name
|
||||
if { $name == "CHIPSCOPE" } {
|
||||
set chipscope 1
|
||||
}
|
||||
}
|
||||
}
|
||||
close $fh
|
||||
|
||||
create_project -force kernel_pack $path_to_tmp_project
|
||||
|
||||
add_files -norecurse ${vsources_list}
|
||||
|
||||
set obj [get_filesets sources_1]
|
||||
set files [list \
|
||||
[file normalize "${build_dir}/globals.vh"] \
|
||||
]
|
||||
add_files -verbose -norecurse -fileset $obj $files
|
||||
|
||||
set_property include_dirs ${vincludes_list} [current_fileset]
|
||||
#set_property verilog_define ${vdefines_list} [current_fileset]
|
||||
|
||||
set obj [get_filesets sources_1]
|
||||
set_property -verbose -name "top" -value ${krnl_name} -objects $obj
|
||||
|
||||
if { $chipscope == 1 } {
|
||||
# hw debugging
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_afu
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_NUM_OF_PROBES {3} \
|
||||
CONFIG.C_DATA_DEPTH {8192} \
|
||||
CONFIG.C_PROBE0_WIDTH {584} \
|
||||
CONFIG.C_PROBE1_WIDTH {16} \
|
||||
CONFIG.C_PROBE2_WIDTH {64} \
|
||||
] [get_ips ila_afu]
|
||||
generate_target {instantiation_template} [get_files ila_afu.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_afu.xci]
|
||||
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_fetch
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_NUM_OF_PROBES {5} \
|
||||
CONFIG.C_DATA_DEPTH {8192} \
|
||||
CONFIG.C_PROBE0_WIDTH {128} \
|
||||
CONFIG.C_PROBE1_WIDTH {128} \
|
||||
CONFIG.C_PROBE2_WIDTH {128} \
|
||||
CONFIG.C_PROBE3_WIDTH {544} \
|
||||
CONFIG.C_PROBE4_WIDTH {128} \
|
||||
] [get_ips ila_fetch]
|
||||
generate_target {instantiation_template} [get_files ila_fetch.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_fetch.xci]
|
||||
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_issue
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_NUM_OF_PROBES {2} \
|
||||
CONFIG.C_DATA_DEPTH {8192} \
|
||||
CONFIG.C_PROBE0_WIDTH {128} \
|
||||
CONFIG.C_PROBE1_WIDTH {128} \
|
||||
] [get_ips ila_issue]
|
||||
generate_target {instantiation_template} [get_files ila_issue.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_issue.xci]
|
||||
}
|
||||
|
||||
update_compile_order -fileset sources_1
|
||||
update_compile_order -fileset sim_1
|
||||
ipx::package_project -root_dir $path_to_packaged -vendor xilinx.com -library RTLKernel -taxonomy /KernelIP -import_files -set_current false
|
||||
ipx::unload_core $path_to_packaged/component.xml
|
||||
ipx::edit_ip_in_project -upgrade true -name tmp_edit_project -directory $path_to_packaged $path_to_packaged/component.xml
|
||||
|
||||
set core [ipx::current_core]
|
||||
|
||||
set_property core_revision 2 $core
|
||||
foreach up [ipx::get_user_parameters] {
|
||||
ipx::remove_user_parameter [get_property NAME $up] $core
|
||||
}
|
||||
|
||||
ipx::associate_bus_interfaces -busif s_axi_ctrl -clock ap_clk $core
|
||||
ipx::associate_bus_interfaces -busif m_axi_mem -clock ap_clk $core
|
||||
|
||||
set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} $core
|
||||
set_property sdx_kernel true $core
|
||||
set_property sdx_kernel_type rtl $core
|
||||
set_property supported_families { } $core
|
||||
set_property auto_family_support_level level_2 $core
|
||||
ipx::create_xgui_files $core
|
||||
ipx::update_checksums $core
|
||||
ipx::check_integrity -kernel $core
|
||||
ipx::save_core $core
|
||||
close_project -delete
|
|
@ -1,33 +0,0 @@
|
|||
proc parse_vcs_list {flist_path} {
|
||||
set f [split [string trim [read [open $flist_path r]]] "\n"]
|
||||
set flist [list ]
|
||||
set dir_list [list ]
|
||||
set def_list [list ]
|
||||
foreach x $f {
|
||||
if {![string match "" $x]} {
|
||||
# If the item starts with +incdir+, directory files need to be added
|
||||
if {[string match "#*" $x]} {
|
||||
# get rid of comment line
|
||||
} elseif {[string match "+incdir+*" $x]} {
|
||||
set trimchars "+incdir+"
|
||||
set temp [string trimleft $x $trimchars]
|
||||
set expanded [subst $temp]
|
||||
lappend dir_list $expanded
|
||||
} elseif {[string match "+define+*" $x]} {
|
||||
set trimchars "+define+"
|
||||
set temp [string trimleft $x $trimchars]
|
||||
set expanded [subst $temp]
|
||||
lappend def_list $expanded
|
||||
} else {
|
||||
set expanded [subst $x]
|
||||
lappend flist $expanded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#puts $flist
|
||||
#puts $dir_list
|
||||
#puts $def_list
|
||||
|
||||
return [list $flist $dir_list $def_list]
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#
|
||||
# Copyright 2021 Xilinx, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
log_wave -r *
|
||||
run all
|
||||
exit
|
|
@ -1,348 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "cmdlineparser.h"
|
||||
#include "logger.h"
|
||||
#include <assert.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace sda {
|
||||
namespace utils {
|
||||
|
||||
bool is_file(const std::string& name) {
|
||||
ifstream f(name.c_str());
|
||||
if (f.good()) {
|
||||
f.close();
|
||||
return true;
|
||||
} else {
|
||||
f.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_number(const std::string& s) {
|
||||
std::string::const_iterator it = s.begin();
|
||||
while (it != s.end() && std::isdigit(*it)) ++it;
|
||||
return !s.empty() && it == s.end();
|
||||
}
|
||||
|
||||
bool starts_with(const string& src, const string& sub) {
|
||||
return (src.find(sub) == 0);
|
||||
}
|
||||
|
||||
CmdLineParser::CmdLineParser() {
|
||||
// TODO Auto-generated constructor stub
|
||||
m_strDefaultKey = "";
|
||||
m_appname = "application.exe";
|
||||
addSwitch("--help", "-h", "prints this help list", "", true);
|
||||
}
|
||||
|
||||
/*
|
||||
CmdLineParser::CmdLineParser(int argc, char* argv[]) {
|
||||
// TODO Auto-generated constructor stub
|
||||
assert(parse(argc, argv) > 0);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
CmdLineParser::~CmdLineParser() {
|
||||
// TODO Auto-generated destructor stub
|
||||
for (size_t i = 0; i < m_vSwitches.size(); i++) {
|
||||
delete m_vSwitches[i];
|
||||
m_vSwitches[i] = nullptr;
|
||||
}
|
||||
|
||||
m_vSwitches.resize(0);
|
||||
}
|
||||
|
||||
bool CmdLineParser::addSwitch(const CmdSwitch& s) {
|
||||
CmdSwitch cmd = s;
|
||||
|
||||
if (cmd.desc.length() == 0) {
|
||||
LogError("No description provided!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check input
|
||||
if (cmd.key.find("--") != 0 || cmd.key.length() < 3) {
|
||||
LogError(
|
||||
"The input key is invalid. Please start with -- and keep a "
|
||||
"length >= 3");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_mapKeySwitch.find(cmd.key) != m_mapKeySwitch.end()) {
|
||||
LogError("This key %s is taken already!", cmd.key.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmd.shortcut.length() == 0) {
|
||||
string temp = "-" + cmd.key[2];
|
||||
|
||||
int i = 3;
|
||||
while (m_mapShortcutKeys.find(temp) != m_mapShortcutKeys.end() && (size_t)i < cmd.key.length()) {
|
||||
temp = "-" + s.key[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
cmd.shortcut = temp;
|
||||
LogInfo("Automatic shortcut assigned %s to %s", temp.c_str(), cmd.key.c_str());
|
||||
}
|
||||
|
||||
if (s.istoggle) {
|
||||
cmd.default_value = string("false");
|
||||
cmd.value = cmd.default_value;
|
||||
cmd.isvalid = true;
|
||||
} else {
|
||||
cmd.value = cmd.default_value;
|
||||
cmd.isvalid = false;
|
||||
}
|
||||
|
||||
// add
|
||||
CmdSwitch* pcmd = new CmdSwitch(cmd);
|
||||
m_vSwitches.push_back(pcmd);
|
||||
m_mapShortcutKeys[s.shortcut] = cmd.key;
|
||||
m_mapKeySwitch[s.key] = pcmd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CmdLineParser::addSwitch(
|
||||
const string& name, const string& shortcut, const string& desc, const string& default_value, bool istoggle) {
|
||||
CmdSwitch s;
|
||||
s.key = name;
|
||||
s.shortcut = shortcut;
|
||||
s.desc = desc;
|
||||
s.default_value = default_value;
|
||||
s.istoggle = istoggle;
|
||||
|
||||
return addSwitch(s);
|
||||
}
|
||||
|
||||
bool CmdLineParser::setDefaultKey(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end()) {
|
||||
CmdSwitch* pcmd = m_mapKeySwitch[m_strDefaultKey];
|
||||
if (pcmd != nullptr) {
|
||||
if (pcmd->istoggle) {
|
||||
LogError(
|
||||
"Boolean command line options can not be used as "
|
||||
"default keys");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set default key
|
||||
m_strDefaultKey = strKey;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
int CmdLineParser::parse(int argc, char* argv[]) {
|
||||
int i = 0;
|
||||
int ctOptions = 0;
|
||||
while (i < argc) {
|
||||
string key, val;
|
||||
bool iskey = false;
|
||||
string token = string(argv[i]);
|
||||
|
||||
bool isNextTokenKey = false;
|
||||
if (i + 1 < argc) {
|
||||
string peeknext = string(argv[i + 1]);
|
||||
if (starts_with(peeknext, "-") || starts_with(peeknext, "--")) {
|
||||
string fullkey;
|
||||
isNextTokenKey = token_to_fullkeyname(peeknext, fullkey);
|
||||
}
|
||||
}
|
||||
|
||||
// full-key
|
||||
if (starts_with(token, string("--"))) {
|
||||
if (m_mapKeySwitch.find(token) == m_mapKeySwitch.end()) {
|
||||
LogError("Unrecognized key passed %s", token.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = token;
|
||||
iskey = true;
|
||||
}
|
||||
// shortcut
|
||||
else if (starts_with(token, "-")) {
|
||||
if (m_mapShortcutKeys.find(token) == m_mapShortcutKeys.end()) {
|
||||
LogError("Unrecognized shortcut key passed %s", token.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = m_mapShortcutKeys[token];
|
||||
iskey = true;
|
||||
}
|
||||
// default key, the value for default key is the last argument
|
||||
else if (isNextTokenKey == false && m_strDefaultKey.length() > 0 && i == argc - 2) {
|
||||
if (m_mapKeySwitch.find(m_strDefaultKey) == m_mapKeySwitch.end()) {
|
||||
LogError("Unrecognized default key %s", m_strDefaultKey.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogInfo("Using default key: %s", m_strDefaultKey.c_str());
|
||||
key = m_strDefaultKey;
|
||||
iskey = true;
|
||||
}
|
||||
|
||||
// if iskey and needs param then read it
|
||||
if (iskey) {
|
||||
ctOptions++;
|
||||
|
||||
if (key == "--help") {
|
||||
printHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// fetch value
|
||||
CmdSwitch* pcmd = m_mapKeySwitch[key];
|
||||
|
||||
// read next
|
||||
if (pcmd->istoggle) {
|
||||
pcmd->value = string("true");
|
||||
pcmd->isvalid = true;
|
||||
} else {
|
||||
i++;
|
||||
pcmd->value = string(argv[i]);
|
||||
pcmd->isvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
// next token
|
||||
i++;
|
||||
}
|
||||
|
||||
// capture real app name
|
||||
if (argc > 0) {
|
||||
m_appname = string(argv[0]);
|
||||
}
|
||||
|
||||
return ctOptions;
|
||||
}
|
||||
|
||||
bool CmdLineParser::token_to_fullkeyname(const string& token, string& fullkey) {
|
||||
fullkey = "";
|
||||
int ctDashes = 0;
|
||||
if (starts_with(token, string("--")))
|
||||
ctDashes = 2;
|
||||
else if (starts_with(token, string("-")))
|
||||
ctDashes = 1;
|
||||
|
||||
if (ctDashes == 0) return false;
|
||||
|
||||
if (ctDashes == 2) {
|
||||
if (m_mapKeySwitch.find(token) == m_mapKeySwitch.end()) {
|
||||
LogError("Unrecognized key passed %s", token.c_str());
|
||||
return false;
|
||||
}
|
||||
fullkey = token;
|
||||
} else if (ctDashes == 1) {
|
||||
if (m_mapShortcutKeys.find(token) == m_mapShortcutKeys.end()) {
|
||||
LogError("Unrecognized shortcut key passed %s", token.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fullkey = m_mapShortcutKeys[token];
|
||||
}
|
||||
|
||||
return (fullkey.length() > 0);
|
||||
}
|
||||
|
||||
string CmdLineParser::value(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end())
|
||||
return m_mapKeySwitch[strKey]->value;
|
||||
else {
|
||||
LogWarn("The input key %s is not recognized!", strKey.c_str());
|
||||
return string("");
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdLineParser::value_to_bool(const char* key) {
|
||||
string strVal = value(key);
|
||||
if (strVal == "true") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int CmdLineParser::value_to_int(const char* key) {
|
||||
string strVal = value(key);
|
||||
if (strVal.length() == 0 || !is_number(strVal)) return -1;
|
||||
return atoi(strVal.c_str());
|
||||
}
|
||||
|
||||
double CmdLineParser::value_to_double(const char* key) {
|
||||
string strVal = value(key);
|
||||
if (strVal.length() == 0) return -1;
|
||||
return atof(strVal.c_str());
|
||||
}
|
||||
|
||||
bool CmdLineParser::isValid(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end())
|
||||
return m_mapKeySwitch[strKey]->isvalid;
|
||||
else {
|
||||
LogWarn("The input key %s is not recognized!", strKey.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CmdLineParser::printHelp() {
|
||||
printf("===========================================================\n");
|
||||
string strAllShortcuts = "";
|
||||
for (size_t i = 0; i < m_vSwitches.size(); i++) {
|
||||
CmdSwitch* pcmd = m_vSwitches[i];
|
||||
if (pcmd && pcmd->shortcut.length() > 0) strAllShortcuts = strAllShortcuts + pcmd->shortcut;
|
||||
}
|
||||
// example
|
||||
printf("Usage: %s -[%s]\n\n", m_appname.c_str(), strAllShortcuts.c_str());
|
||||
|
||||
// row by row
|
||||
for (size_t i = 0; i < m_vSwitches.size(); i++) {
|
||||
CmdSwitch* pcmd = m_vSwitches[i];
|
||||
|
||||
if (pcmd->default_value.length() > 0)
|
||||
printf("\t%s, %s\t\t%s\t Default: [%s]\n", pcmd->key.c_str(), pcmd->shortcut.c_str(), pcmd->desc.c_str(),
|
||||
pcmd->default_value.c_str());
|
||||
else
|
||||
printf("\t%s, %s\t\t%s\n", pcmd->key.c_str(), pcmd->shortcut.c_str(), pcmd->desc.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
CmdLineParser::CmdSwitch* CmdLineParser::getCmdSwitch(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end())
|
||||
return m_mapKeySwitch[strKey];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace sda
|
|
@ -1,110 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef CMDLINEPARSER_H_
|
||||
#define CMDLINEPARSER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sda {
|
||||
namespace utils {
|
||||
|
||||
bool is_file(const std::string& name);
|
||||
|
||||
/*!
|
||||
* Synopsis:
|
||||
* 1.Parses the command line passed in from the user and stores all enabled
|
||||
* system options.
|
||||
* 2.Prints help for the user if an option is not valid.
|
||||
* 3.Stores options and provides a mechanism to read those options
|
||||
*/
|
||||
class CmdLineParser {
|
||||
public:
|
||||
class CmdSwitch {
|
||||
public:
|
||||
std::string key;
|
||||
std::string shortcut;
|
||||
std::string default_value;
|
||||
std::string value;
|
||||
std::string desc;
|
||||
bool istoggle;
|
||||
bool isvalid;
|
||||
};
|
||||
|
||||
public:
|
||||
CmdLineParser();
|
||||
// CmdLineParser(int argc, char* argv[]);
|
||||
virtual ~CmdLineParser();
|
||||
|
||||
bool addSwitch(const CmdSwitch& s);
|
||||
bool addSwitch(const std::string& name,
|
||||
const std::string& shortcut,
|
||||
const std::string& desc,
|
||||
const std::string& default_value = "",
|
||||
bool istoggle = false);
|
||||
|
||||
/*!
|
||||
* sets default key to be able to read a 2 argumented call
|
||||
*/
|
||||
bool setDefaultKey(const char* key);
|
||||
|
||||
/*!
|
||||
* parse and store command line
|
||||
*/
|
||||
int parse(int argc, char* argv[]);
|
||||
|
||||
/*!
|
||||
* retrieve value using a key
|
||||
*/
|
||||
std::string value(const char* key);
|
||||
|
||||
bool value_to_bool(const char* key);
|
||||
|
||||
int value_to_int(const char* key);
|
||||
|
||||
double value_to_double(const char* key);
|
||||
|
||||
/*!
|
||||
* Returns true if a valid value is supplied by user
|
||||
*/
|
||||
bool isValid(const char* key);
|
||||
|
||||
/*!
|
||||
* prints the help menu in case the options are not correct.
|
||||
*/
|
||||
virtual void printHelp();
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Retrieve command switch
|
||||
*/
|
||||
CmdSwitch* getCmdSwitch(const char* key);
|
||||
|
||||
bool token_to_fullkeyname(const std::string& token, std::string& fullkey);
|
||||
|
||||
private:
|
||||
std::map<std::string, CmdSwitch*> m_mapKeySwitch;
|
||||
std::map<std::string, std::string> m_mapShortcutKeys;
|
||||
std::vector<CmdSwitch*> m_vSwitches;
|
||||
std::string m_strDefaultKey;
|
||||
std::string m_appname;
|
||||
};
|
||||
|
||||
// bool starts_with(const string& src, const string& sub);
|
||||
}
|
||||
}
|
||||
#endif /* CMDLINEPARSER_H_ */
|
|
@ -1,191 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "cmdlineparser.h"
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
|
||||
// XRT includes
|
||||
#include "experimental/xrt_bo.h"
|
||||
#include "experimental/xrt_ip.h"
|
||||
#include "experimental/xrt_device.h"
|
||||
#include "experimental/xrt_kernel.h"
|
||||
#include "experimental/xrt_xclbin.h"
|
||||
|
||||
#define CSR_CTL 0x0
|
||||
#define CSR_A 0x10
|
||||
#define CSR_B 0x1C
|
||||
#define CSR_C 0x28
|
||||
#define CSR_L 0x34
|
||||
|
||||
#define IP_START 0x1
|
||||
#define IP_IDLE 0x4
|
||||
|
||||
#define NUM_ITEMS 1
|
||||
|
||||
#define BANK_SIZE 0x10000000
|
||||
#define NUM_BANKS 16
|
||||
|
||||
uint64_t ba_addr = 0x10;
|
||||
uint64_t bb_addr = 0x20;
|
||||
uint64_t bc_addr = 0x00;
|
||||
|
||||
static int get_bank_info(uint64_t dev_addr, uint32_t* pIdx, uint32_t* pOff) {
|
||||
uint32_t index = dev_addr / BANK_SIZE;
|
||||
uint32_t offset = dev_addr % BANK_SIZE;
|
||||
if (index > NUM_BANKS) {
|
||||
fprintf(stderr, "[VXDRV] Error: address out of range: 0x%lx\n", dev_addr);
|
||||
return -1;
|
||||
}
|
||||
*pIdx = index;
|
||||
*pOff = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
class ResourceManager {
|
||||
public:
|
||||
xrt::bo get_buffer(xrt::device& device, uint32_t bank_id) {
|
||||
auto it = xrtBuffers_.find(bank_id);
|
||||
if (it != xrtBuffers_.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
xrt::bo xrtBuffer(device, BANK_SIZE, xrt::bo::flags::normal, bank_id);
|
||||
xrtBuffers_.insert({bank_id, xrtBuffer});
|
||||
return xrtBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct buf_cnt_t {
|
||||
xrt::bo xrtBuffer;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
std::unordered_map<uint32_t, xrt::bo> xrtBuffers_;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Command Line Parser
|
||||
sda::utils::CmdLineParser parser;
|
||||
|
||||
// Switches
|
||||
//**************//"<Full Arg>", "<Short Arg>", "<Description>", "<Default>"
|
||||
parser.addSwitch("--xclbin_file", "-x", "input binary file string", "");
|
||||
parser.addSwitch("--device_id", "-d", "device index", "0");
|
||||
parser.parse(argc, argv);
|
||||
|
||||
// Read settings
|
||||
std::string binaryFile = parser.value("xclbin_file");
|
||||
int device_index = stoi(parser.value("device_id"));
|
||||
|
||||
if (argc < 3) {
|
||||
parser.printHelp();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ResourceManager res_mgr;
|
||||
|
||||
std::cout << "Open the device" << device_index << std::endl;
|
||||
auto device = xrt::device(device_index);
|
||||
|
||||
std::cout << "Load the xclbin " << binaryFile << std::endl;
|
||||
auto uuid = device.load_xclbin(binaryFile);
|
||||
|
||||
std::cout << "Load the kernel ip" << std::endl;
|
||||
auto ip = xrt::ip(device, uuid, "krnl_vadd_rtl");
|
||||
|
||||
size_t vector_size_bytes = sizeof(int) * NUM_ITEMS;
|
||||
|
||||
uint32_t ba_idx, bb_idx, bc_idx;
|
||||
uint32_t ba_offset, bb_offset, bc_offset;
|
||||
|
||||
get_bank_info(ba_addr, &ba_idx, &ba_offset);
|
||||
get_bank_info(bb_addr, &bb_idx, &bb_offset);
|
||||
get_bank_info(bc_addr, &bc_idx, &bc_offset);
|
||||
|
||||
auto ba = res_mgr.get_buffer(device, ba_idx);
|
||||
auto bb = res_mgr.get_buffer(device, bb_idx);
|
||||
auto bc = res_mgr.get_buffer(device, bc_idx);
|
||||
|
||||
// upload source buffers
|
||||
std::cout << "Writing the input data..." << std::endl;
|
||||
|
||||
std::vector<int> src_buf(NUM_ITEMS), dst_buf(NUM_ITEMS), ref_buf(NUM_ITEMS);
|
||||
for (int i = 0; i < NUM_ITEMS; ++i) {
|
||||
src_buf[i] = i;
|
||||
dst_buf[i] = 0xdeadbeef;
|
||||
ref_buf[i] = i + i;
|
||||
}
|
||||
|
||||
ba.write(src_buf.data(), vector_size_bytes, ba_offset);
|
||||
ba.sync(XCL_BO_SYNC_BO_TO_DEVICE, vector_size_bytes, ba_offset);
|
||||
|
||||
bb.write(src_buf.data(), vector_size_bytes, bb_offset);
|
||||
bb.sync(XCL_BO_SYNC_BO_TO_DEVICE, vector_size_bytes, bb_offset);
|
||||
|
||||
bc.write(dst_buf.data(), vector_size_bytes, bc_offset);
|
||||
bc.sync(XCL_BO_SYNC_BO_TO_DEVICE, vector_size_bytes, bc_offset);
|
||||
|
||||
std::cout << "Setting IP registers..." << std::endl;
|
||||
ip.write_register(CSR_A, ba_addr);
|
||||
ip.write_register(CSR_A + 4, ba_addr >> 32);
|
||||
ip.write_register(CSR_B, bb_addr);
|
||||
ip.write_register(CSR_B + 4, bb_addr >> 32);
|
||||
ip.write_register(CSR_C, bc_addr);
|
||||
ip.write_register(CSR_C + 4, bc_addr >> 32);
|
||||
ip.write_register(CSR_L, NUM_ITEMS);
|
||||
|
||||
// Start execution
|
||||
|
||||
std::cout << "IP Start..." << std::endl;
|
||||
ip.write_register(CSR_CTL, IP_START);
|
||||
|
||||
// Wait until the IP is DONE
|
||||
|
||||
uint32_t axi_ctrl = 0;
|
||||
while ((axi_ctrl & IP_IDLE) != IP_IDLE) {
|
||||
axi_ctrl = ip.read_register(CSR_CTL);
|
||||
}
|
||||
|
||||
std::cout << "IP Done!" << std::endl;
|
||||
|
||||
// Get the output
|
||||
|
||||
std::cout << "Reading output data..." << std::endl;
|
||||
|
||||
bc.sync(XCL_BO_SYNC_BO_FROM_DEVICE, vector_size_bytes, bc_offset);
|
||||
bc.read(dst_buf.data(), vector_size_bytes, bc_offset);
|
||||
|
||||
// Validate our results
|
||||
std::cout << "Validating results..." << std::endl;
|
||||
int errors = 0;
|
||||
for (int i = 0; i < NUM_ITEMS; ++i) {
|
||||
if (dst_buf[i] != ref_buf[i]) {
|
||||
std::cout << "*** missmatch: (" << i << ") actual=" << dst_buf[i] << ", expected=" << ref_buf[i] << std::endl;
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors != 0) {
|
||||
std::cout << "TEST FAILED!\n";
|
||||
return errors;
|
||||
}
|
||||
|
||||
std::cout << "TEST PASSED!\n";
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "logger.h"
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#ifdef WINDOWS
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace sda {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
string GetApplicationPath() {
|
||||
#ifdef WINDOWS
|
||||
#define GetCurrentDir _getcwd
|
||||
#else
|
||||
#define GetCurrentDir getcwd
|
||||
#endif
|
||||
|
||||
char strCurrentPath[FILENAME_MAX];
|
||||
|
||||
if (!GetCurrentDir(strCurrentPath, sizeof(strCurrentPath))) {
|
||||
return string("");
|
||||
}
|
||||
|
||||
/* not really required */
|
||||
strCurrentPath[sizeof(strCurrentPath) - 1] = '\0';
|
||||
return string(strCurrentPath);
|
||||
}
|
||||
|
||||
string ToLower(const string& s) {
|
||||
string result = s;
|
||||
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||
return result;
|
||||
}
|
||||
|
||||
string ToUpper(const string& s) {
|
||||
string result = s;
|
||||
std::transform(result.begin(), result.end(), result.begin(), ::toupper);
|
||||
return result;
|
||||
}
|
||||
|
||||
string GetTimeStamp() {
|
||||
return "";
|
||||
}
|
||||
|
||||
// trim from start
|
||||
string& ltrim(std::string& s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
return s;
|
||||
}
|
||||
|
||||
// trim from end
|
||||
string& rtrim(std::string& s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
// trim from both ends
|
||||
string& trim(std::string& s) {
|
||||
return ltrim(rtrim(s));
|
||||
}
|
||||
|
||||
string GetFileExt(const string& s) {
|
||||
string strext = s.substr(s.find_last_of(".") + 1);
|
||||
return strext;
|
||||
}
|
||||
|
||||
string GetFileTitleOnly(const string& s) {
|
||||
string temp = s;
|
||||
string::size_type d = temp.find_last_of("//");
|
||||
if (d == string::npos) d = temp.find_last_of("\\");
|
||||
if (d != string::npos) temp = temp.substr(d + 1);
|
||||
|
||||
d = temp.find_last_of(".");
|
||||
if (d != string::npos) temp = temp.substr(0, d);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void LogWrapper(int etype, const char* file, int line, const char* desc, ...) {
|
||||
// crop file name from full path
|
||||
string strFileLoc(file);
|
||||
strFileLoc = strFileLoc.substr(strFileLoc.find_last_of("\\/") + 1);
|
||||
|
||||
string strHeader = "";
|
||||
{
|
||||
char header[512];
|
||||
// source
|
||||
switch (etype) {
|
||||
case (sda::etError): {
|
||||
snprintf(header, sizeof(header), "ERROR: [%s:%d]", strFileLoc.c_str(), line);
|
||||
break;
|
||||
}
|
||||
case (sda::etInfo): {
|
||||
snprintf(header, sizeof(header), "INFO: [%s:%d]", strFileLoc.c_str(), line);
|
||||
break;
|
||||
}
|
||||
case (sda::etWarning): {
|
||||
snprintf(header, sizeof(header), "WARN: [%s:%d]", strFileLoc.c_str(), line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
strHeader = string(header);
|
||||
}
|
||||
|
||||
// time
|
||||
string strTime = "";
|
||||
#ifdef ENABLE_LOG_TIME
|
||||
{
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
#ifdef ENABLE_SECURE_API
|
||||
char buffer[64];
|
||||
struct tm timeinfo;
|
||||
localtime_s(&timeinfo, &rawtime);
|
||||
asctime_s(timeinfo, buffer, sizeof(buffer)) snprintf(buffer, sizeof(buffer), "TIME: [%s]", asctime(timeinfo));
|
||||
strTime = string(buffer);
|
||||
#else
|
||||
char buffer[64];
|
||||
struct tm* timeinfo = localtime(&rawtime);
|
||||
string temp = string(asctime(timeinfo));
|
||||
temp = trim(temp);
|
||||
|
||||
// strftime(buffer, sizeof(buffer), "TIME: []")
|
||||
snprintf(buffer, sizeof(buffer), "TIME: [%s]", temp.c_str());
|
||||
strTime = string(buffer);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// format the message itself
|
||||
string strMsg = "";
|
||||
{
|
||||
char msg[512];
|
||||
va_list args;
|
||||
va_start(args, desc);
|
||||
vsnprintf(msg, sizeof(msg), desc, args);
|
||||
va_end(args);
|
||||
strMsg = string(msg);
|
||||
}
|
||||
|
||||
// combine
|
||||
string strOut = strHeader + string(" ") + strTime + string(" ") + strMsg + string("\n");
|
||||
|
||||
// display
|
||||
cout << strOut;
|
||||
|
||||
// store
|
||||
#ifdef ENABLE_LOG_TOFILE
|
||||
std::ofstream outfile;
|
||||
outfile.open("benchapp.log", std::ios_base::app);
|
||||
outfile << strOut;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace sda
|
|
@ -1,70 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef LOGGER_H_
|
||||
#define LOGGER_H_
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define ENABLE_LOG_TOFILE 1
|
||||
#define ENABLE_LOG_TIME 1
|
||||
|
||||
// global logging
|
||||
#define LogInfo(desc, ...) sda::LogWrapper(0, __FILE__, __LINE__, desc, ##__VA_ARGS__)
|
||||
#define LogWarn(desc, ...) sda::LogWrapper(1, __FILE__, __LINE__, desc, ##__VA_ARGS__)
|
||||
#define LogError(desc, ...) sda::LogWrapper(2, __FILE__, __LINE__, desc, ##__VA_ARGS__)
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace sda {
|
||||
|
||||
enum LOGTYPE { etInfo, etWarning, etError };
|
||||
|
||||
// string
|
||||
string& ltrim(string& s);
|
||||
string& rtrim(string& s);
|
||||
string& trim(string& s);
|
||||
string GetFileExt(const string& s);
|
||||
string GetFileTitleOnly(const string& s);
|
||||
|
||||
string ToLower(const string& s);
|
||||
string ToUpper(const string& s);
|
||||
|
||||
// time
|
||||
string GetTimeStamp();
|
||||
|
||||
// paths
|
||||
string GetApplicationPath();
|
||||
|
||||
// debug
|
||||
template <typename T>
|
||||
void PrintPOD(const vector<T>& pod, size_t display_count = 0, const int precision = 4) {
|
||||
size_t count = pod.size();
|
||||
if (display_count > 0) count = std::min<size_t>(pod.size(), display_count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
cout << std::setprecision(precision) << pod[i] << ", ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// logging
|
||||
void LogWrapper(int etype, const char* file, int line, const char* desc, ...);
|
||||
}
|
||||
|
||||
#endif /* LOGGER_H_ */
|
|
@ -1,9 +0,0 @@
|
|||
[connectivity]
|
||||
#nk=krnl_vadd_rtl:1
|
||||
#sp=krnl_vadd_rtl_1.m_axi_mem:HBM[0:15]
|
||||
|
||||
[vivado]
|
||||
#prop=fileset.sim_1.xsim.elaborate.debug_level=all
|
||||
|
||||
[advanced]
|
||||
#param=compiler.userPostDebugProfileOverlayTcl=../scripts/post_dbg_profile_overlay.tcl
|
|
@ -1,11 +0,0 @@
|
|||
[Runtime]
|
||||
runtime_log=console
|
||||
|
||||
[Emulation]
|
||||
#debug_mode=gui
|
||||
#user_pre_sim_script=xsim.tcl
|
||||
|
||||
[Debug]
|
||||
profile=true
|
||||
timeline_trace=true
|
||||
data_transfer_trace=fine
|
3
hw/syn/xilinx/test3/.gitignore
vendored
3
hw/syn/xilinx/test3/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
/build*/*
|
||||
/.run/*
|
||||
/.Xil/*
|
|
@ -1,157 +0,0 @@
|
|||
ifneq ($(findstring Makefile, $(MAKEFILE_LIST)), Makefile)
|
||||
help:
|
||||
$(ECHO) "Makefile Usage:"
|
||||
$(ECHO) " make all TARGET=<sw_emu/hw_emu/hw> PLATFORM=<FPGA platform>"
|
||||
$(ECHO) " Command to generate the design for specified Target and Device."
|
||||
$(ECHO) ""
|
||||
$(ECHO) " make clean"
|
||||
$(ECHO) " Command to remove the generated non-hardware files."
|
||||
$(ECHO) ""
|
||||
endif
|
||||
|
||||
TARGET ?= hw
|
||||
PLATFORM ?=
|
||||
|
||||
PREFIX ?= build
|
||||
|
||||
RTL_DIR = ../../../../rtl
|
||||
AFU_DIR = ../../../../afu/xrt
|
||||
|
||||
BUILD_DIR = $(PREFIX)_$(PLATFORM)_$(TARGET)
|
||||
BIN_DIR = $(BUILD_DIR)/bin
|
||||
|
||||
# Control RTL debug tracing states
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CORE_PIPELINE
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CORE_ICACHE
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CORE_DCACHE
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CORE_MEM
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CACHE_BANK
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CACHE_MSHR
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CACHE_TAG
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_CACHE_DATA
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_AFU
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_TEX
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_RASTER
|
||||
DBG_TRACE_FLAGS += -DDBG_TRACE_ROP
|
||||
|
||||
DBG_FLAGS += $(DBG_TRACE_FLAGS)
|
||||
|
||||
FPU_INCLUDE = -I$(RTL_DIR)/fpu_unit
|
||||
TEX_INCLUDE = -I$(RTL_DIR)/tex_unit
|
||||
RASTER_INCLUDE = -I$(RTL_DIR)/raster_unit
|
||||
ROP_INCLUDE = -I$(RTL_DIR)/rop_unit
|
||||
RTL_INCLUDE = -I$(RTL_DIR) -I$(RTL_DIR)/libs -I$(RTL_DIR)/interfaces -I$(RTL_DIR)/core -I$(RTL_DIR)/cache -I$(AFU_DIR)
|
||||
RTL_INCLUDE += $(FPU_INCLUDE) $(TEX_INCLUDE) $(RASTER_INCLUDE) $(ROP_INCLUDE)
|
||||
|
||||
#CONFIGS += -DEXT_GFX_ENABLE
|
||||
CONFIGS += -DNUM_WARPS=2 -DNUM_THREADS=2 -DEXT_F_DISABLE
|
||||
|
||||
CONFIGS += -DSYNTHESIS -DVIVADO
|
||||
|
||||
VIVADO = $(XILINX_VIVADO)/bin/vivado
|
||||
|
||||
VPP = $(XILINX_VITIS)/bin/v++
|
||||
|
||||
CP = cp -rf
|
||||
RMDIR = rm -rf
|
||||
|
||||
ECHO = @echo
|
||||
|
||||
XO_CONTAINER = $(BIN_DIR)/vortex_afu.xo
|
||||
|
||||
XCLBIN_CONTAINER = $(BIN_DIR)/vortex_afu.xclbin
|
||||
|
||||
EMCONFIG = $(BIN_DIR)/emconfig.json
|
||||
|
||||
NCPUS := $(shell grep -c ^processor /proc/cpuinfo)
|
||||
JOBS := $(shell expr $(NCPUS) - 1)
|
||||
|
||||
# Kernel compiler global settings
|
||||
VPP_FLAGS += --link --target $(TARGET) --platform $(PLATFORM) --save-temps --no_ip_cache
|
||||
VPP_FLAGS += --vivado.synth.jobs $(JOBS) --vivado.impl.jobs $(JOBS)
|
||||
VPP_FLAGS += --connectivity.sp vortex_afu_1.m_axi_mem:HBM[0:15]
|
||||
VPP_FLAGS += --report 2
|
||||
VPP_FLAGS += --config ../vitis.ini
|
||||
|
||||
# Enable perf counters
|
||||
ifdef PERF
|
||||
CONFIGS += -DPERF_ENABLE
|
||||
endif
|
||||
|
||||
# Generates profile summary report
|
||||
ifdef PROFILE
|
||||
VPP_FLAGS += --profile_kernel data:all:all:all
|
||||
VPP_FLAGS += --profile_kernel stall:all:all:all
|
||||
endif
|
||||
|
||||
# Debugigng
|
||||
ifdef DEBUG
|
||||
VPP_FLAGS += -g --optimize 0 --debug.protocol all
|
||||
ifeq ($(TARGET), hw)
|
||||
VPP_FLAGS += --debug.chipscope vortex_afu_1
|
||||
CONFIGS += -DCHIPSCOPE
|
||||
else
|
||||
CONFIGS += -DSIMULATION $(DBG_FLAGS)
|
||||
VPP_FLAGS += --vivado.prop fileset.sim_1.xsim.elaborate.debug_level=all
|
||||
endif
|
||||
else
|
||||
CONFIGS += -DNDEBUG
|
||||
VPP_FLAGS += --optimize 3
|
||||
endif
|
||||
|
||||
# Host
|
||||
EXECUTABLE = ./test
|
||||
CMD_ARGS = -x $(XCLBIN_CONTAINER)
|
||||
CXXFLAGS += -std=c++14 -g -O0 -fmessage-length=0 -I$(XILINX_XRT)/include -I$(XILINX_VIVADO)/include -Wall -I../src
|
||||
LDFLAGS += -L$(XILINX_XRT)/lib -pthread -luuid -lxrt_coreutil
|
||||
HOST_SRCS += ./src/host.cpp ./src/cmdlineparser.cpp ./src/logger.cpp
|
||||
|
||||
# RTL Kernel only supports Hardware and Hardware Emulation.
|
||||
ifneq ($(TARGET),$(findstring $(TARGET), hw hw_emu))
|
||||
$(warning WARNING:Application supports only hw hw_emu TARGET. Please use the target for running the application)
|
||||
endif
|
||||
|
||||
.PHONY: all run host clean gen-sources emconfig check-devices
|
||||
|
||||
all: check-devices $(XCLBIN_CONTAINER) emconfig host
|
||||
|
||||
gen-sources: $(BUILD_DIR)/sources.txt
|
||||
$(BUILD_DIR)/sources.txt:
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); ../scripts/gen_sources.sh $(RTL_INCLUDE) $(CONFIGS) > sources.txt
|
||||
|
||||
$(XO_CONTAINER): $(BUILD_DIR)/sources.txt ./kernel.xml
|
||||
mkdir -p $(BUILD_DIR); cd $(BUILD_DIR); $(VIVADO) -mode batch -source ../scripts/gen_xo.tcl -tclargs ../$(XO_CONTAINER) vortex_afu sources.txt ../kernel.xml ../$(BUILD_DIR)
|
||||
|
||||
$(XCLBIN_CONTAINER): $(XO_CONTAINER)
|
||||
mkdir -p $(BIN_DIR); cd $(BUILD_DIR); $(VPP) $(VPP_FLAGS) -o ../$(XCLBIN_CONTAINER) ../$(XO_CONTAINER)
|
||||
|
||||
emconfig: $(EMCONFIG)
|
||||
$(EMCONFIG):
|
||||
mkdir -p $(BIN_DIR); cd $(BUILD_DIR); emconfigutil --platform $(PLATFORM) --od ../$(BIN_DIR)
|
||||
|
||||
host: $(EXECUTABLE)
|
||||
$(EXECUTABLE): $(HOST_SRCS)
|
||||
g++ $^ $(CXXFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
run: $(EXECUTABLE)
|
||||
ifeq ($(TARGET),$(filter $(TARGET),sw_emu hw_emu))
|
||||
EMCONFIG_PATH=$(BIN_DIR) XCL_EMULATION_MODE=$(TARGET) $(EXECUTABLE) $(CMD_ARGS)
|
||||
else
|
||||
EMCONFIG_PATH=$(BIN_DIR) $(EXECUTABLE) $(CMD_ARGS)
|
||||
endif
|
||||
|
||||
chipscope:
|
||||
debug_hw --xvc_pcie /dev/xfpga/xvc_pub.u2305.0 --hw_server &
|
||||
debug_hw --vivado --host localhost --ltx_file $(BUILD_DIR)/_x/link/vivado/vpl/prj/prj.runs/impl_1/debug_nets.ltx &
|
||||
|
||||
clean:
|
||||
$(RMDIR) $(BUILD_DIR) $(EXECUTABLE)
|
||||
|
||||
# Check the devices avaiable
|
||||
check-devices:
|
||||
ifndef PLATFORM
|
||||
$(error PLATFORM not set. Please set the PLATFORM properly and rerun. Run "make help" for more details.)
|
||||
endif
|
||||
ifndef XILINX_VITIS
|
||||
$(error XILINX_VITIS variable is not set, please set correctly and rerun)
|
||||
endif
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root versionMajor="1" versionMinor="9">
|
||||
<kernel name="vortex_afu" language="ip" vlnv="xilinx.com:RTLKernel:vortex_afu:1.0" attributes="" preferredWorkGroupSizeMultiple="0" workGroupSize="1" hwControlProtocol="ap_ctrl_hs">
|
||||
<ports>
|
||||
<port name="s_axi_ctrl" mode="slave" range="0x1000" dataWidth="32" portType="addressable" base="0x0"/>
|
||||
<port name="m_axi_mem" mode="master" range="0xFFFFFFFF" dataWidth="512" portType="addressable" base="0x0"/>
|
||||
</ports>
|
||||
<args>
|
||||
<arg id="0" name="DEV" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x010" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="1" name="ISA" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x01C" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="2" name="DCR" addressQualifier="0" port="s_axi_ctrl" size="0x8" offset="0x028" type="uint" hostOffset="0x0" hostSize="0x8"/>
|
||||
<arg id="3" name="MEM" addressQualifier="1" port="m_axi_mem" size="0x8" offset="0x034" type="void*" hostOffset="0x0" hostSize="0x8"/>
|
||||
</args>
|
||||
</kernel>
|
||||
</root>
|
|
@ -1,27 +0,0 @@
|
|||
if { $::argc != 1 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 1 arguments!\n"
|
||||
puts "Usage: $::argv0 <ip_dir>\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set ip_dir [lindex $::argv 0]
|
||||
|
||||
# IP folder does not exist. Create IP folder
|
||||
file mkdir ${ip_dir}
|
||||
|
||||
# create_ip requires that a project is open in memory.
|
||||
# Create project but don't do anything with it
|
||||
create_project -in_memory
|
||||
|
||||
create_ip -name floating_point -vendor xilinx.com -library ip -version 7.1 -module_name xil_fdiv -dir ${ip_dir}
|
||||
set_property -dict [list CONFIG.Component_Name {xil_fdiv} CONFIG.Operation_Type {Divide} CONFIG.Flow_Control {NonBlocking} CONFIG.Has_ACLKEN {true} CONFIG.C_Has_UNDERFLOW {true} CONFIG.C_Has_OVERFLOW {true} CONFIG.C_Has_INVALID_OP {true} CONFIG.C_Has_DIVIDE_BY_ZERO {true} CONFIG.A_Precision_Type {Single} CONFIG.C_A_Exponent_Width {8} CONFIG.C_A_Fraction_Width {24} CONFIG.Result_Precision_Type {Single} CONFIG.C_Result_Exponent_Width {8} CONFIG.C_Result_Fraction_Width {24} CONFIG.C_Mult_Usage {No_Usage} CONFIG.Has_RESULT_TREADY {false} CONFIG.C_Latency {28} CONFIG.C_Rate {1}] [get_ips xil_fdiv]
|
||||
|
||||
create_ip -name floating_point -vendor xilinx.com -library ip -version 7.1 -module_name xil_fsqrt -dir ${ip_dir}
|
||||
set_property -dict [list CONFIG.Component_Name {xil_fsqrt} CONFIG.Operation_Type {Square_root} CONFIG.Flow_Control {NonBlocking} CONFIG.Has_ACLKEN {true} CONFIG.C_Has_INVALID_OP {true} CONFIG.A_Precision_Type {Single} CONFIG.C_A_Exponent_Width {8} CONFIG.C_A_Fraction_Width {24} CONFIG.Result_Precision_Type {Single} CONFIG.C_Result_Exponent_Width {8} CONFIG.C_Result_Fraction_Width {24} CONFIG.C_Mult_Usage {No_Usage} CONFIG.Has_RESULT_TREADY {false} CONFIG.C_Latency {28} CONFIG.C_Rate {1}] [get_ips xil_fsqrt]
|
||||
|
||||
create_ip -name floating_point -vendor xilinx.com -library ip -version 7.1 -module_name xil_fma -dir ${ip_dir}
|
||||
set_property -dict [list CONFIG.Component_Name {xil_fma} CONFIG.Operation_Type {FMA} CONFIG.Add_Sub_Value {Add} CONFIG.Flow_Control {NonBlocking} CONFIG.Has_ACLKEN {true} CONFIG.C_Has_UNDERFLOW {true} CONFIG.C_Has_OVERFLOW {true} CONFIG.C_Has_INVALID_OP {true} CONFIG.Has_A_TUSER {false} CONFIG.A_Precision_Type {Single} CONFIG.C_A_Exponent_Width {8} CONFIG.C_A_Fraction_Width {24} CONFIG.Result_Precision_Type {Single} CONFIG.C_Result_Exponent_Width {8} CONFIG.C_Result_Fraction_Width {24} CONFIG.C_Mult_Usage {Medium_Usage} CONFIG.Has_RESULT_TREADY {false} CONFIG.C_Latency {16} CONFIG.C_Rate {1} CONFIG.A_TUSER_Width {1}] [get_ips xil_fma]
|
||||
|
||||
generate_target all [get_ips]
|
||||
|
||||
close_project -delete
|
|
@ -1,46 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
exclude_list="VX_fpu_fpnew.sv"
|
||||
macros=()
|
||||
includes=()
|
||||
|
||||
# parse command arguments
|
||||
while getopts D:I:h flag
|
||||
do
|
||||
case "${flag}" in
|
||||
D) macros+=( ${OPTARG} );;
|
||||
I) includes+=( ${OPTARG} );;
|
||||
h) echo "Usage: [-D macro] [-I include] [-h help]"
|
||||
exit 0
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# dump macros
|
||||
for value in ${macros[@]}; do
|
||||
echo "+define+$value"
|
||||
done
|
||||
|
||||
# dump include directories
|
||||
for dir in ${includes[@]}; do
|
||||
echo "+incdir+$dir"
|
||||
done
|
||||
|
||||
# dump source files
|
||||
for dir in ${includes[@]}; do
|
||||
for file in $(find $dir -maxdepth 1 -name '*.v' -o -name '*.sv' -type f); do
|
||||
exclude=0
|
||||
for fe in $exclude_list; do
|
||||
if [[ $file =~ $fe ]]; then
|
||||
exclude=1
|
||||
fi
|
||||
done
|
||||
if [[ $exclude == 0 ]]; then
|
||||
echo $file
|
||||
fi
|
||||
done
|
||||
done
|
|
@ -1,27 +0,0 @@
|
|||
if { $::argc != 5 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 5 arguments!\n"
|
||||
puts "Usage: $::argv0 <xoname> <krnl_name> <vcs_file> <kernel_xml> <build_dir>\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set xoname [lindex $::argv 0]
|
||||
set krnl_name [lindex $::argv 1]
|
||||
set vcs_file [lindex $::argv 2]
|
||||
set krnl_xml [lindex $::argv 3]
|
||||
set build_dir [lindex $::argv 4]
|
||||
|
||||
set script_path [ file dirname [ file normalize [ info script ] ] ]
|
||||
|
||||
if {[file exists "${xoname}"]} {
|
||||
file delete -force "${xoname}"
|
||||
}
|
||||
|
||||
set argv [list ${build_dir}/ip]
|
||||
set argc 1
|
||||
source ${script_path}/gen_ip.tcl
|
||||
|
||||
set argv [list ${krnl_name} ${build_dir}]
|
||||
set argc 2
|
||||
source ${script_path}/package_kernel.tcl
|
||||
|
||||
package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory "${build_dir}/xo/packaged_kernel" -kernel_xml ${krnl_xml}
|
|
@ -1,141 +0,0 @@
|
|||
if { $::argc != 2 } {
|
||||
puts "ERROR: Program \"$::argv0\" requires 2 arguments!\n"
|
||||
puts "Usage: $::argv0 <krnl_name> <build_dir>\n"
|
||||
exit
|
||||
}
|
||||
|
||||
set krnl_name [lindex $::argv 0]
|
||||
set build_dir [lindex $::argv 1]
|
||||
|
||||
set script_path [ file dirname [ file normalize [ info script ] ] ]
|
||||
|
||||
set path_to_packaged "${build_dir}/xo/packaged_kernel"
|
||||
set path_to_tmp_project "${build_dir}/xo/project"
|
||||
|
||||
source "${script_path}/parse_vcs_list.tcl"
|
||||
set vlist [parse_vcs_list "${vcs_file}"]
|
||||
|
||||
set vsources_list [lindex $vlist 0]
|
||||
set vincludes_list [lindex $vlist 1]
|
||||
set vdefines_list [lindex $vlist 2]
|
||||
|
||||
#puts ${vsources_list}
|
||||
#puts ${vdefines_list}
|
||||
|
||||
# dump defines into globals.vh
|
||||
set chipscope 0
|
||||
set fh [open "${build_dir}/globals.vh" w]
|
||||
foreach def $vdefines_list {
|
||||
set fields [split $def "="]
|
||||
set len [llength $fields]
|
||||
set name [lindex $fields 0]
|
||||
puts -nonewline $fh "`define "
|
||||
if {$len > 1} {
|
||||
set value [lindex $fields 1]
|
||||
puts -nonewline $fh $name
|
||||
puts -nonewline $fh " "
|
||||
puts $fh $value
|
||||
} else {
|
||||
puts $fh $name
|
||||
if { $name == "CHIPSCOPE" } {
|
||||
set chipscope 1
|
||||
}
|
||||
}
|
||||
}
|
||||
close $fh
|
||||
|
||||
create_project -force kernel_pack $path_to_tmp_project
|
||||
|
||||
set obj [get_filesets sources_1]
|
||||
|
||||
add_files -verbose -norecurse -fileset $obj ${vsources_list}
|
||||
|
||||
set files [list \
|
||||
[file normalize "${build_dir}/globals.vh"] \
|
||||
[file normalize "${build_dir}/ip/xil_fdiv/xil_fdiv.xci"] \
|
||||
[file normalize "${build_dir}/ip/xil_fma/xil_fma.xci"] \
|
||||
[file normalize "${build_dir}/ip/xil_fsqrt/xil_fsqrt.xci"] \
|
||||
]
|
||||
add_files -verbose -norecurse -fileset $obj $files
|
||||
|
||||
set_property include_dirs ${vincludes_list} [current_fileset]
|
||||
#set_property verilog_define ${vdefines_list} [current_fileset]
|
||||
|
||||
set_property -verbose -name "top" -value ${krnl_name} -objects $obj
|
||||
|
||||
if { $chipscope == 1 } {
|
||||
# hw debugging
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_afu
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_EN_STRG_QUAL {1} \
|
||||
CONFIG.C_DATA_DEPTH {4096} \
|
||||
CONFIG.C_NUM_OF_PROBES {2} \
|
||||
CONFIG.C_PROBE0_WIDTH {8} \
|
||||
CONFIG.C_PROBE1_WIDTH {24} \
|
||||
] [get_ips ila_afu]
|
||||
generate_target {instantiation_template} [get_files ila_afu.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_afu.xci]
|
||||
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_fetch
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_EN_STRG_QUAL {1} \
|
||||
CONFIG.C_DATA_DEPTH {4096} \
|
||||
CONFIG.C_NUM_OF_PROBES {5} \
|
||||
CONFIG.C_PROBE0_WIDTH {128} \
|
||||
CONFIG.C_PROBE1_WIDTH {128} \
|
||||
CONFIG.C_PROBE2_WIDTH {128} \
|
||||
CONFIG.C_PROBE3_WIDTH {128} \
|
||||
CONFIG.C_PROBE4_WIDTH {128} \
|
||||
] [get_ips ila_fetch]
|
||||
generate_target {instantiation_template} [get_files ila_fetch.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_fetch.xci]
|
||||
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_issue
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_EN_STRG_QUAL {1} \
|
||||
CONFIG.C_DATA_DEPTH {4096} \
|
||||
CONFIG.C_NUM_OF_PROBES {2} \
|
||||
CONFIG.C_PROBE0_WIDTH {128} \
|
||||
CONFIG.C_PROBE1_WIDTH {128} \
|
||||
] [get_ips ila_issue]
|
||||
generate_target {instantiation_template} [get_files ila_issue.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_issue.xci]
|
||||
|
||||
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_lsu
|
||||
set_property -dict [list CONFIG.C_ADV_TRIGGER {true} \
|
||||
CONFIG.C_EN_STRG_QUAL {1} \
|
||||
CONFIG.C_DATA_DEPTH {4096} \
|
||||
CONFIG.C_NUM_OF_PROBES {2} \
|
||||
CONFIG.C_PROBE0_WIDTH {128} \
|
||||
CONFIG.C_PROBE1_WIDTH {128} \
|
||||
] [get_ips ila_lsu]
|
||||
generate_target {instantiation_template} [get_files ila_lsu.xci]
|
||||
set_property generate_synth_checkpoint false [get_files ila_lsu.xci]
|
||||
}
|
||||
|
||||
update_compile_order -fileset sources_1
|
||||
update_compile_order -fileset sim_1
|
||||
ipx::package_project -root_dir $path_to_packaged -vendor xilinx.com -library RTLKernel -taxonomy /KernelIP -import_files -set_current false
|
||||
ipx::unload_core $path_to_packaged/component.xml
|
||||
ipx::edit_ip_in_project -upgrade true -name tmp_edit_project -directory $path_to_packaged $path_to_packaged/component.xml
|
||||
|
||||
set core [ipx::current_core]
|
||||
|
||||
set_property core_revision 2 $core
|
||||
foreach up [ipx::get_user_parameters] {
|
||||
ipx::remove_user_parameter [get_property NAME $up] $core
|
||||
}
|
||||
|
||||
ipx::associate_bus_interfaces -busif s_axi_ctrl -clock ap_clk $core
|
||||
ipx::associate_bus_interfaces -busif m_axi_mem -clock ap_clk $core
|
||||
|
||||
set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} $core
|
||||
set_property sdx_kernel true $core
|
||||
set_property sdx_kernel_type rtl $core
|
||||
set_property supported_families { } $core
|
||||
set_property auto_family_support_level level_2 $core
|
||||
ipx::create_xgui_files $core
|
||||
ipx::update_checksums $core
|
||||
ipx::check_integrity -kernel $core
|
||||
ipx::save_core $core
|
||||
close_project -delete
|
|
@ -1,33 +0,0 @@
|
|||
proc parse_vcs_list {flist_path} {
|
||||
set f [split [string trim [read [open $flist_path r]]] "\n"]
|
||||
set flist [list ]
|
||||
set dir_list [list ]
|
||||
set def_list [list ]
|
||||
foreach x $f {
|
||||
if {![string match "" $x]} {
|
||||
# If the item starts with +incdir+, directory files need to be added
|
||||
if {[string match "#*" $x]} {
|
||||
# get rid of comment line
|
||||
} elseif {[string match "+incdir+*" $x]} {
|
||||
set trimchars "+incdir+"
|
||||
set temp [string trimleft $x $trimchars]
|
||||
set expanded [subst $temp]
|
||||
lappend dir_list $expanded
|
||||
} elseif {[string match "+define+*" $x]} {
|
||||
set trimchars "+define+"
|
||||
set temp [string trimleft $x $trimchars]
|
||||
set expanded [subst $temp]
|
||||
lappend def_list $expanded
|
||||
} else {
|
||||
set expanded [subst $x]
|
||||
lappend flist $expanded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#puts $flist
|
||||
#puts $dir_list
|
||||
#puts $def_list
|
||||
|
||||
return [list $flist $dir_list $def_list]
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#
|
||||
# Copyright 2021 Xilinx, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
log_wave -r *
|
||||
run all
|
||||
exit
|
|
@ -1,348 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "cmdlineparser.h"
|
||||
#include "logger.h"
|
||||
#include <assert.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace sda {
|
||||
namespace utils {
|
||||
|
||||
bool is_file(const std::string& name) {
|
||||
ifstream f(name.c_str());
|
||||
if (f.good()) {
|
||||
f.close();
|
||||
return true;
|
||||
} else {
|
||||
f.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_number(const std::string& s) {
|
||||
std::string::const_iterator it = s.begin();
|
||||
while (it != s.end() && std::isdigit(*it)) ++it;
|
||||
return !s.empty() && it == s.end();
|
||||
}
|
||||
|
||||
bool starts_with(const string& src, const string& sub) {
|
||||
return (src.find(sub) == 0);
|
||||
}
|
||||
|
||||
CmdLineParser::CmdLineParser() {
|
||||
// TODO Auto-generated constructor stub
|
||||
m_strDefaultKey = "";
|
||||
m_appname = "application.exe";
|
||||
addSwitch("--help", "-h", "prints this help list", "", true);
|
||||
}
|
||||
|
||||
/*
|
||||
CmdLineParser::CmdLineParser(int argc, char* argv[]) {
|
||||
// TODO Auto-generated constructor stub
|
||||
assert(parse(argc, argv) > 0);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
CmdLineParser::~CmdLineParser() {
|
||||
// TODO Auto-generated destructor stub
|
||||
for (size_t i = 0; i < m_vSwitches.size(); i++) {
|
||||
delete m_vSwitches[i];
|
||||
m_vSwitches[i] = nullptr;
|
||||
}
|
||||
|
||||
m_vSwitches.resize(0);
|
||||
}
|
||||
|
||||
bool CmdLineParser::addSwitch(const CmdSwitch& s) {
|
||||
CmdSwitch cmd = s;
|
||||
|
||||
if (cmd.desc.length() == 0) {
|
||||
LogError("No description provided!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check input
|
||||
if (cmd.key.find("--") != 0 || cmd.key.length() < 3) {
|
||||
LogError(
|
||||
"The input key is invalid. Please start with -- and keep a "
|
||||
"length >= 3");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_mapKeySwitch.find(cmd.key) != m_mapKeySwitch.end()) {
|
||||
LogError("This key %s is taken already!", cmd.key.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmd.shortcut.length() == 0) {
|
||||
string temp = "-" + cmd.key[2];
|
||||
|
||||
int i = 3;
|
||||
while (m_mapShortcutKeys.find(temp) != m_mapShortcutKeys.end() && (size_t)i < cmd.key.length()) {
|
||||
temp = "-" + s.key[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
cmd.shortcut = temp;
|
||||
LogInfo("Automatic shortcut assigned %s to %s", temp.c_str(), cmd.key.c_str());
|
||||
}
|
||||
|
||||
if (s.istoggle) {
|
||||
cmd.default_value = string("false");
|
||||
cmd.value = cmd.default_value;
|
||||
cmd.isvalid = true;
|
||||
} else {
|
||||
cmd.value = cmd.default_value;
|
||||
cmd.isvalid = false;
|
||||
}
|
||||
|
||||
// add
|
||||
CmdSwitch* pcmd = new CmdSwitch(cmd);
|
||||
m_vSwitches.push_back(pcmd);
|
||||
m_mapShortcutKeys[s.shortcut] = cmd.key;
|
||||
m_mapKeySwitch[s.key] = pcmd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CmdLineParser::addSwitch(
|
||||
const string& name, const string& shortcut, const string& desc, const string& default_value, bool istoggle) {
|
||||
CmdSwitch s;
|
||||
s.key = name;
|
||||
s.shortcut = shortcut;
|
||||
s.desc = desc;
|
||||
s.default_value = default_value;
|
||||
s.istoggle = istoggle;
|
||||
|
||||
return addSwitch(s);
|
||||
}
|
||||
|
||||
bool CmdLineParser::setDefaultKey(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end()) {
|
||||
CmdSwitch* pcmd = m_mapKeySwitch[m_strDefaultKey];
|
||||
if (pcmd != nullptr) {
|
||||
if (pcmd->istoggle) {
|
||||
LogError(
|
||||
"Boolean command line options can not be used as "
|
||||
"default keys");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set default key
|
||||
m_strDefaultKey = strKey;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
int CmdLineParser::parse(int argc, char* argv[]) {
|
||||
int i = 0;
|
||||
int ctOptions = 0;
|
||||
while (i < argc) {
|
||||
string key, val;
|
||||
bool iskey = false;
|
||||
string token = string(argv[i]);
|
||||
|
||||
bool isNextTokenKey = false;
|
||||
if (i + 1 < argc) {
|
||||
string peeknext = string(argv[i + 1]);
|
||||
if (starts_with(peeknext, "-") || starts_with(peeknext, "--")) {
|
||||
string fullkey;
|
||||
isNextTokenKey = token_to_fullkeyname(peeknext, fullkey);
|
||||
}
|
||||
}
|
||||
|
||||
// full-key
|
||||
if (starts_with(token, string("--"))) {
|
||||
if (m_mapKeySwitch.find(token) == m_mapKeySwitch.end()) {
|
||||
LogError("Unrecognized key passed %s", token.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = token;
|
||||
iskey = true;
|
||||
}
|
||||
// shortcut
|
||||
else if (starts_with(token, "-")) {
|
||||
if (m_mapShortcutKeys.find(token) == m_mapShortcutKeys.end()) {
|
||||
LogError("Unrecognized shortcut key passed %s", token.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = m_mapShortcutKeys[token];
|
||||
iskey = true;
|
||||
}
|
||||
// default key, the value for default key is the last argument
|
||||
else if (isNextTokenKey == false && m_strDefaultKey.length() > 0 && i == argc - 2) {
|
||||
if (m_mapKeySwitch.find(m_strDefaultKey) == m_mapKeySwitch.end()) {
|
||||
LogError("Unrecognized default key %s", m_strDefaultKey.c_str());
|
||||
printHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogInfo("Using default key: %s", m_strDefaultKey.c_str());
|
||||
key = m_strDefaultKey;
|
||||
iskey = true;
|
||||
}
|
||||
|
||||
// if iskey and needs param then read it
|
||||
if (iskey) {
|
||||
ctOptions++;
|
||||
|
||||
if (key == "--help") {
|
||||
printHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// fetch value
|
||||
CmdSwitch* pcmd = m_mapKeySwitch[key];
|
||||
|
||||
// read next
|
||||
if (pcmd->istoggle) {
|
||||
pcmd->value = string("true");
|
||||
pcmd->isvalid = true;
|
||||
} else {
|
||||
i++;
|
||||
pcmd->value = string(argv[i]);
|
||||
pcmd->isvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
// next token
|
||||
i++;
|
||||
}
|
||||
|
||||
// capture real app name
|
||||
if (argc > 0) {
|
||||
m_appname = string(argv[0]);
|
||||
}
|
||||
|
||||
return ctOptions;
|
||||
}
|
||||
|
||||
bool CmdLineParser::token_to_fullkeyname(const string& token, string& fullkey) {
|
||||
fullkey = "";
|
||||
int ctDashes = 0;
|
||||
if (starts_with(token, string("--")))
|
||||
ctDashes = 2;
|
||||
else if (starts_with(token, string("-")))
|
||||
ctDashes = 1;
|
||||
|
||||
if (ctDashes == 0) return false;
|
||||
|
||||
if (ctDashes == 2) {
|
||||
if (m_mapKeySwitch.find(token) == m_mapKeySwitch.end()) {
|
||||
LogError("Unrecognized key passed %s", token.c_str());
|
||||
return false;
|
||||
}
|
||||
fullkey = token;
|
||||
} else if (ctDashes == 1) {
|
||||
if (m_mapShortcutKeys.find(token) == m_mapShortcutKeys.end()) {
|
||||
LogError("Unrecognized shortcut key passed %s", token.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fullkey = m_mapShortcutKeys[token];
|
||||
}
|
||||
|
||||
return (fullkey.length() > 0);
|
||||
}
|
||||
|
||||
string CmdLineParser::value(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end())
|
||||
return m_mapKeySwitch[strKey]->value;
|
||||
else {
|
||||
LogWarn("The input key %s is not recognized!", strKey.c_str());
|
||||
return string("");
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdLineParser::value_to_bool(const char* key) {
|
||||
string strVal = value(key);
|
||||
if (strVal == "true") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int CmdLineParser::value_to_int(const char* key) {
|
||||
string strVal = value(key);
|
||||
if (strVal.length() == 0 || !is_number(strVal)) return -1;
|
||||
return atoi(strVal.c_str());
|
||||
}
|
||||
|
||||
double CmdLineParser::value_to_double(const char* key) {
|
||||
string strVal = value(key);
|
||||
if (strVal.length() == 0) return -1;
|
||||
return atof(strVal.c_str());
|
||||
}
|
||||
|
||||
bool CmdLineParser::isValid(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end())
|
||||
return m_mapKeySwitch[strKey]->isvalid;
|
||||
else {
|
||||
LogWarn("The input key %s is not recognized!", strKey.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CmdLineParser::printHelp() {
|
||||
printf("===========================================================\n");
|
||||
string strAllShortcuts = "";
|
||||
for (size_t i = 0; i < m_vSwitches.size(); i++) {
|
||||
CmdSwitch* pcmd = m_vSwitches[i];
|
||||
if (pcmd && pcmd->shortcut.length() > 0) strAllShortcuts = strAllShortcuts + pcmd->shortcut;
|
||||
}
|
||||
// example
|
||||
printf("Usage: %s -[%s]\n\n", m_appname.c_str(), strAllShortcuts.c_str());
|
||||
|
||||
// row by row
|
||||
for (size_t i = 0; i < m_vSwitches.size(); i++) {
|
||||
CmdSwitch* pcmd = m_vSwitches[i];
|
||||
|
||||
if (pcmd->default_value.length() > 0)
|
||||
printf("\t%s, %s\t\t%s\t Default: [%s]\n", pcmd->key.c_str(), pcmd->shortcut.c_str(), pcmd->desc.c_str(),
|
||||
pcmd->default_value.c_str());
|
||||
else
|
||||
printf("\t%s, %s\t\t%s\n", pcmd->key.c_str(), pcmd->shortcut.c_str(), pcmd->desc.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
CmdLineParser::CmdSwitch* CmdLineParser::getCmdSwitch(const char* key) {
|
||||
string strKey(key);
|
||||
if (!starts_with(strKey, "--")) strKey = "--" + strKey;
|
||||
|
||||
if (m_mapKeySwitch.find(strKey) != m_mapKeySwitch.end())
|
||||
return m_mapKeySwitch[strKey];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace sda
|
|
@ -1,110 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef CMDLINEPARSER_H_
|
||||
#define CMDLINEPARSER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sda {
|
||||
namespace utils {
|
||||
|
||||
bool is_file(const std::string& name);
|
||||
|
||||
/*!
|
||||
* Synopsis:
|
||||
* 1.Parses the command line passed in from the user and stores all enabled
|
||||
* system options.
|
||||
* 2.Prints help for the user if an option is not valid.
|
||||
* 3.Stores options and provides a mechanism to read those options
|
||||
*/
|
||||
class CmdLineParser {
|
||||
public:
|
||||
class CmdSwitch {
|
||||
public:
|
||||
std::string key;
|
||||
std::string shortcut;
|
||||
std::string default_value;
|
||||
std::string value;
|
||||
std::string desc;
|
||||
bool istoggle;
|
||||
bool isvalid;
|
||||
};
|
||||
|
||||
public:
|
||||
CmdLineParser();
|
||||
// CmdLineParser(int argc, char* argv[]);
|
||||
virtual ~CmdLineParser();
|
||||
|
||||
bool addSwitch(const CmdSwitch& s);
|
||||
bool addSwitch(const std::string& name,
|
||||
const std::string& shortcut,
|
||||
const std::string& desc,
|
||||
const std::string& default_value = "",
|
||||
bool istoggle = false);
|
||||
|
||||
/*!
|
||||
* sets default key to be able to read a 2 argumented call
|
||||
*/
|
||||
bool setDefaultKey(const char* key);
|
||||
|
||||
/*!
|
||||
* parse and store command line
|
||||
*/
|
||||
int parse(int argc, char* argv[]);
|
||||
|
||||
/*!
|
||||
* retrieve value using a key
|
||||
*/
|
||||
std::string value(const char* key);
|
||||
|
||||
bool value_to_bool(const char* key);
|
||||
|
||||
int value_to_int(const char* key);
|
||||
|
||||
double value_to_double(const char* key);
|
||||
|
||||
/*!
|
||||
* Returns true if a valid value is supplied by user
|
||||
*/
|
||||
bool isValid(const char* key);
|
||||
|
||||
/*!
|
||||
* prints the help menu in case the options are not correct.
|
||||
*/
|
||||
virtual void printHelp();
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Retrieve command switch
|
||||
*/
|
||||
CmdSwitch* getCmdSwitch(const char* key);
|
||||
|
||||
bool token_to_fullkeyname(const std::string& token, std::string& fullkey);
|
||||
|
||||
private:
|
||||
std::map<std::string, CmdSwitch*> m_mapKeySwitch;
|
||||
std::map<std::string, std::string> m_mapShortcutKeys;
|
||||
std::vector<CmdSwitch*> m_vSwitches;
|
||||
std::string m_strDefaultKey;
|
||||
std::string m_appname;
|
||||
};
|
||||
|
||||
// bool starts_with(const string& src, const string& sub);
|
||||
}
|
||||
}
|
||||
#endif /* CMDLINEPARSER_H_ */
|
|
@ -1,245 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#include "cmdlineparser.h"
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
|
||||
// XRT includes
|
||||
#include "experimental/xrt_bo.h"
|
||||
#include "experimental/xrt_ip.h"
|
||||
#include "experimental/xrt_device.h"
|
||||
#include "experimental/xrt_kernel.h"
|
||||
#include "experimental/xrt_xclbin.h"
|
||||
|
||||
#define MMIO_CTL_ADDR 0x00
|
||||
#define MMIO_DEV_ADDR 0x10
|
||||
#define MMIO_ISA_ADDR 0x1C
|
||||
#define MMIO_DCR_ADDR 0x28
|
||||
|
||||
#define CTL_AP_START (1<<0)
|
||||
#define CTL_AP_DONE (1<<1)
|
||||
#define CTL_AP_IDLE (1<<2)
|
||||
#define CTL_AP_READY (1<<3)
|
||||
#define CTL_AP_RESET (1<<4)
|
||||
#define CTL_AP_RESTART (1<<7)
|
||||
|
||||
#define DCR_BASE_STARTUP_ADDR 1
|
||||
|
||||
#define BANK_SIZE 0x10000000
|
||||
#define NUM_BANKS 16
|
||||
|
||||
uint32_t count = 16;
|
||||
uint32_t args_addr = 0x7ffff000;
|
||||
uint32_t kernel_addr = 0x80000000;
|
||||
uint32_t src_addr = 0x20000000;
|
||||
uint32_t dst_addr = 0x10000000;
|
||||
|
||||
uint32_t kernel_bin [] = {
|
||||
0x008000ef, // jal ra,80000008 <main>
|
||||
0x0000000b, // 0xb
|
||||
0x7ffff7b7, // lui a5,0x7ffff
|
||||
0x0007a703, // lw a4,0(a5) # 7ffff000 <reg_t6+0x7fffefe1>
|
||||
0x0047a683, // lw a3,4(a5)
|
||||
0x0087a583, // lw a1,8(a5)
|
||||
0xcc5027f3, // csrr a5,0xcc5
|
||||
0x02e787b3, // mul a5,a5,a4
|
||||
0x02070863, // beqz a4,80000050 <main+0x48>
|
||||
0x00f70733, // add a4,a4,a5
|
||||
0x00271713, // slli a4,a4,0x2
|
||||
0x00279793, // slli a5,a5,0x2
|
||||
0x00d787b3, // add a5,a5,a3
|
||||
0x00d70733, // add a4,a4,a3
|
||||
0x40d585b3, // sub a1,a1,a3
|
||||
0x0007a603, // lw a2,0(a5)
|
||||
0x00f586b3, // add a3,a1,a5
|
||||
0x00478793, // addi a5,a5,4
|
||||
0x00c6a023, // sw a2,0(a3)
|
||||
0xfef718e3, // bne a4,a5,8000003c <main+0x34>
|
||||
0x00008067 // ret
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t count;
|
||||
uint32_t src_addr;
|
||||
uint32_t dst_addr;
|
||||
} kernel_args_t;
|
||||
|
||||
static int get_bank_info(uint64_t dev_addr, uint32_t* pIdx, uint32_t* pOff) {
|
||||
uint32_t index = dev_addr / BANK_SIZE;
|
||||
uint32_t offset = dev_addr % BANK_SIZE;
|
||||
if (index > NUM_BANKS) {
|
||||
fprintf(stderr, "[VXDRV] 0xaddress // out of range: 0x%lx\n", dev_addr);
|
||||
return -1;
|
||||
}
|
||||
*pIdx = index;
|
||||
*pOff = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
class ResourceManager {
|
||||
public:
|
||||
xrt::bo get_buffer(xrt::device& device, uint32_t bank_id) {
|
||||
auto it = xrtBuffers_.find(bank_id);
|
||||
if (it != xrtBuffers_.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
xrt::bo xrtBuffer(device, BANK_SIZE, xrt::bo::flags::normal, bank_id);
|
||||
xrtBuffers_.insert({bank_id, xrtBuffer});
|
||||
return xrtBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct buf_cnt_t {
|
||||
xrt::bo xrtBuffer;
|
||||
uint32_t count;
|
||||
};
|
||||
|
||||
std::unordered_map<uint32_t, xrt::bo> xrtBuffers_;
|
||||
};
|
||||
|
||||
void wait_for_enter(const std::string &msg) {
|
||||
std::cout << msg << std::endl;
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// Command Line Parser
|
||||
sda::utils::CmdLineParser parser;
|
||||
|
||||
// Switches
|
||||
//**************//"<Full Arg>", "<Short Arg>", "<Description>", "<Default>"
|
||||
parser.addSwitch("--xclbin_file", "-x", "input binary file string", "");
|
||||
parser.addSwitch("--device_id", "-d", "device index", "0");
|
||||
parser.parse(argc, argv);
|
||||
|
||||
// Read settings
|
||||
std::string binaryFile = parser.value("xclbin_file");
|
||||
int device_index = stoi(parser.value("device_id"));
|
||||
|
||||
if (argc < 3) {
|
||||
parser.printHelp();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ResourceManager res_mgr;
|
||||
|
||||
std::cout << "Open the device" << device_index << std::endl;
|
||||
auto device = xrt::device(device_index);
|
||||
|
||||
std::cout << "Load the xclbin " << binaryFile << std::endl;
|
||||
auto uuid = device.load_xclbin(binaryFile);
|
||||
|
||||
std::cout << "Load the kernel ip" << std::endl;
|
||||
auto ip = xrt::ip(device, uuid, "vortex_afu");
|
||||
|
||||
std::cout << "Reset device..." << std::endl;
|
||||
ip.write_register(MMIO_CTL_ADDR, CTL_AP_RESET);
|
||||
|
||||
// Update DCRs
|
||||
ip.write_register(MMIO_DCR_ADDR, DCR_BASE_STARTUP_ADDR);
|
||||
ip.write_register(MMIO_DCR_ADDR + 4, kernel_addr);
|
||||
|
||||
uint32_t kernel_idx;
|
||||
uint32_t kernel_offset;
|
||||
get_bank_info(kernel_addr, &kernel_idx, &kernel_offset);
|
||||
auto kernel_bo = res_mgr.get_buffer(device, kernel_idx);
|
||||
|
||||
uint32_t args_idx;
|
||||
uint32_t args_offset;
|
||||
get_bank_info(args_addr, &args_idx, &args_offset);
|
||||
auto args_bo = res_mgr.get_buffer(device, args_idx);
|
||||
|
||||
uint32_t src_idx;
|
||||
uint32_t src_offset;
|
||||
get_bank_info(src_addr, &src_idx, &src_offset);
|
||||
auto src_bo = res_mgr.get_buffer(device, src_idx);
|
||||
|
||||
uint32_t dst_idx;
|
||||
uint32_t dst_offset;
|
||||
get_bank_info(dst_addr, &dst_idx, &dst_offset);
|
||||
auto dst_bo = res_mgr.get_buffer(device, dst_idx);
|
||||
|
||||
std::cout << "Upload kernel (bank=" << kernel_idx << ", offset=" << kernel_offset << ")..." << std::endl;
|
||||
uint32_t kernel_size = sizeof(kernel_bin);
|
||||
kernel_bo.write(kernel_bin, kernel_size, kernel_offset);
|
||||
kernel_bo.sync(XCL_BO_SYNC_BO_TO_DEVICE, kernel_size, kernel_offset);
|
||||
|
||||
std::cout << "Upload kernel arguments (bank=" << args_idx << ", offset=" << args_offset << ")..." << std::endl;
|
||||
kernel_args_t kernel_args{count, src_addr, dst_addr};
|
||||
uint32_t args_size = sizeof(kernel_args);
|
||||
args_bo.write(&kernel_args, args_size, args_offset);
|
||||
args_bo.sync(XCL_BO_SYNC_BO_TO_DEVICE, args_size, args_offset);
|
||||
|
||||
std::cout << "Upload source buffer (bank=" << src_idx << ", offset=" << src_offset << ")..." << std::endl;
|
||||
uint32_t src_size = count * sizeof(uint32_t);
|
||||
{
|
||||
auto src_map = reinterpret_cast<uint32_t*>(src_bo.map<uint8_t*>() + src_offset);
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
src_map[i] = i;
|
||||
}
|
||||
src_bo.sync(XCL_BO_SYNC_BO_TO_DEVICE, src_size, src_offset);
|
||||
|
||||
auto dst_size = count * sizeof(uint32_t);
|
||||
std::cout << "Clear destination buffer (bank=" << dst_idx << ", offset=" << dst_offset << ")..." << std::endl;
|
||||
{
|
||||
auto dst_map = reinterpret_cast<uint32_t*>(dst_bo.map<uint8_t*>() + dst_offset);
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
dst_map[i] = 0xdeadbeef;
|
||||
}
|
||||
dst_bo.sync(XCL_BO_SYNC_BO_TO_DEVICE, dst_size, dst_offset);
|
||||
|
||||
// Start execution
|
||||
|
||||
//wait_for_enter("\nPress ENTER to continue after setting up ILA trigger...");
|
||||
|
||||
std::cout << "IP Start..." << std::endl;
|
||||
ip.write_register(MMIO_CTL_ADDR, CTL_AP_START);
|
||||
|
||||
// Wait until the IP is DONE
|
||||
|
||||
uint32_t axi_ctrl = 0;
|
||||
while ((axi_ctrl & CTL_AP_DONE) != CTL_AP_DONE) {
|
||||
axi_ctrl = ip.read_register(MMIO_CTL_ADDR);
|
||||
}
|
||||
|
||||
std::cout << "IP Done!" << std::endl;
|
||||
|
||||
// check output
|
||||
uint32_t errors = 0;
|
||||
std::cout << "Download destination buffer (bank=" << dst_idx << ", offset=" << dst_offset << ")..." << std::endl;
|
||||
dst_bo.sync(XCL_BO_SYNC_BO_FROM_DEVICE, dst_size, dst_offset);
|
||||
{
|
||||
auto dst_map = reinterpret_cast<uint32_t*>(dst_bo.map<uint8_t*>() + dst_offset);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
uint32_t ref = i;
|
||||
if (dst_map[i] != ref) {
|
||||
std::cout << "Error (" << i << "): actual=" << dst_map[i] << ", expected=" << ref << std::endl;
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors != 0) {
|
||||
std::cout << "FAILED!" << std::endl;
|
||||
return errors;
|
||||
}
|
||||
|
||||
std::cout << "PASSED!" << std::endl;
|
||||
return 0;
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#include "logger.h"
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#ifdef WINDOWS
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace sda {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
string GetApplicationPath() {
|
||||
#ifdef WINDOWS
|
||||
#define GetCurrentDir _getcwd
|
||||
#else
|
||||
#define GetCurrentDir getcwd
|
||||
#endif
|
||||
|
||||
char strCurrentPath[FILENAME_MAX];
|
||||
|
||||
if (!GetCurrentDir(strCurrentPath, sizeof(strCurrentPath))) {
|
||||
return string("");
|
||||
}
|
||||
|
||||
/* not really required */
|
||||
strCurrentPath[sizeof(strCurrentPath) - 1] = '\0';
|
||||
return string(strCurrentPath);
|
||||
}
|
||||
|
||||
string ToLower(const string& s) {
|
||||
string result = s;
|
||||
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||
return result;
|
||||
}
|
||||
|
||||
string ToUpper(const string& s) {
|
||||
string result = s;
|
||||
std::transform(result.begin(), result.end(), result.begin(), ::toupper);
|
||||
return result;
|
||||
}
|
||||
|
||||
string GetTimeStamp() {
|
||||
return "";
|
||||
}
|
||||
|
||||
// trim from start
|
||||
string& ltrim(std::string& s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
return s;
|
||||
}
|
||||
|
||||
// trim from end
|
||||
string& rtrim(std::string& s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
// trim from both ends
|
||||
string& trim(std::string& s) {
|
||||
return ltrim(rtrim(s));
|
||||
}
|
||||
|
||||
string GetFileExt(const string& s) {
|
||||
string strext = s.substr(s.find_last_of(".") + 1);
|
||||
return strext;
|
||||
}
|
||||
|
||||
string GetFileTitleOnly(const string& s) {
|
||||
string temp = s;
|
||||
string::size_type d = temp.find_last_of("//");
|
||||
if (d == string::npos) d = temp.find_last_of("\\");
|
||||
if (d != string::npos) temp = temp.substr(d + 1);
|
||||
|
||||
d = temp.find_last_of(".");
|
||||
if (d != string::npos) temp = temp.substr(0, d);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
void LogWrapper(int etype, const char* file, int line, const char* desc, ...) {
|
||||
// crop file name from full path
|
||||
string strFileLoc(file);
|
||||
strFileLoc = strFileLoc.substr(strFileLoc.find_last_of("\\/") + 1);
|
||||
|
||||
string strHeader = "";
|
||||
{
|
||||
char header[512];
|
||||
// source
|
||||
switch (etype) {
|
||||
case (sda::etError): {
|
||||
snprintf(header, sizeof(header), "ERROR: [%s:%d]", strFileLoc.c_str(), line);
|
||||
break;
|
||||
}
|
||||
case (sda::etInfo): {
|
||||
snprintf(header, sizeof(header), "INFO: [%s:%d]", strFileLoc.c_str(), line);
|
||||
break;
|
||||
}
|
||||
case (sda::etWarning): {
|
||||
snprintf(header, sizeof(header), "WARN: [%s:%d]", strFileLoc.c_str(), line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
strHeader = string(header);
|
||||
}
|
||||
|
||||
// time
|
||||
string strTime = "";
|
||||
#ifdef ENABLE_LOG_TIME
|
||||
{
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
#ifdef ENABLE_SECURE_API
|
||||
char buffer[64];
|
||||
struct tm timeinfo;
|
||||
localtime_s(&timeinfo, &rawtime);
|
||||
asctime_s(timeinfo, buffer, sizeof(buffer)) snprintf(buffer, sizeof(buffer), "TIME: [%s]", asctime(timeinfo));
|
||||
strTime = string(buffer);
|
||||
#else
|
||||
char buffer[64];
|
||||
struct tm* timeinfo = localtime(&rawtime);
|
||||
string temp = string(asctime(timeinfo));
|
||||
temp = trim(temp);
|
||||
|
||||
// strftime(buffer, sizeof(buffer), "TIME: []")
|
||||
snprintf(buffer, sizeof(buffer), "TIME: [%s]", temp.c_str());
|
||||
strTime = string(buffer);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// format the message itself
|
||||
string strMsg = "";
|
||||
{
|
||||
char msg[512];
|
||||
va_list args;
|
||||
va_start(args, desc);
|
||||
vsnprintf(msg, sizeof(msg), desc, args);
|
||||
va_end(args);
|
||||
strMsg = string(msg);
|
||||
}
|
||||
|
||||
// combine
|
||||
string strOut = strHeader + string(" ") + strTime + string(" ") + strMsg + string("\n");
|
||||
|
||||
// display
|
||||
cout << strOut;
|
||||
|
||||
// store
|
||||
#ifdef ENABLE_LOG_TOFILE
|
||||
std::ofstream outfile;
|
||||
outfile.open("benchapp.log", std::ios_base::app);
|
||||
outfile << strOut;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace sda
|
|
@ -1,70 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2019-2021 Xilinx, Inc
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"). You may
|
||||
* not use this file except in compliance with the License. A copy of the
|
||||
* License is located at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
#ifndef LOGGER_H_
|
||||
#define LOGGER_H_
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define ENABLE_LOG_TOFILE 1
|
||||
#define ENABLE_LOG_TIME 1
|
||||
|
||||
// global logging
|
||||
#define LogInfo(desc, ...) sda::LogWrapper(0, __FILE__, __LINE__, desc, ##__VA_ARGS__)
|
||||
#define LogWarn(desc, ...) sda::LogWrapper(1, __FILE__, __LINE__, desc, ##__VA_ARGS__)
|
||||
#define LogError(desc, ...) sda::LogWrapper(2, __FILE__, __LINE__, desc, ##__VA_ARGS__)
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace sda {
|
||||
|
||||
enum LOGTYPE { etInfo, etWarning, etError };
|
||||
|
||||
// string
|
||||
string& ltrim(string& s);
|
||||
string& rtrim(string& s);
|
||||
string& trim(string& s);
|
||||
string GetFileExt(const string& s);
|
||||
string GetFileTitleOnly(const string& s);
|
||||
|
||||
string ToLower(const string& s);
|
||||
string ToUpper(const string& s);
|
||||
|
||||
// time
|
||||
string GetTimeStamp();
|
||||
|
||||
// paths
|
||||
string GetApplicationPath();
|
||||
|
||||
// debug
|
||||
template <typename T>
|
||||
void PrintPOD(const vector<T>& pod, size_t display_count = 0, const int precision = 4) {
|
||||
size_t count = pod.size();
|
||||
if (display_count > 0) count = std::min<size_t>(pod.size(), display_count);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
cout << std::setprecision(precision) << pod[i] << ", ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// logging
|
||||
void LogWrapper(int etype, const char* file, int line, const char* desc, ...);
|
||||
}
|
||||
|
||||
#endif /* LOGGER_H_ */
|
|
@ -1,9 +0,0 @@
|
|||
[connectivity]
|
||||
#nk=vortex_afu:1
|
||||
#sp=vortex_afu_1.m_axi_mem:HBM[0:15]
|
||||
|
||||
[vivado]
|
||||
#prop=fileset.sim_1.xsim.elaborate.debug_level=all
|
||||
|
||||
[advanced]
|
||||
#param=compiler.userPostDebugProfileOverlayTcl=../scripts/post_dbg_profile_overlay.tcl
|
|
@ -1,11 +0,0 @@
|
|||
[Runtime]
|
||||
runtime_log=console
|
||||
|
||||
[Emulation]
|
||||
#debug_mode=gui
|
||||
#user_pre_sim_script=xsim.tcl
|
||||
|
||||
[Debug]
|
||||
profile=true
|
||||
timeline_trace=true
|
||||
data_transfer_trace=fine
|
Loading…
Add table
Add a link
Reference in a new issue