From 7717e646cd0d2adbd4947cfeaccffcb2edf55d72 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 6 Oct 2022 15:59:12 -0400 Subject: [PATCH 01/14] Update supported_boards.json --- hls4ml/templates/supported_boards.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hls4ml/templates/supported_boards.json b/hls4ml/templates/supported_boards.json index 8f45dbad2..6b49cbcdc 100644 --- a/hls4ml/templates/supported_boards.json +++ b/hls4ml/templates/supported_boards.json @@ -28,5 +28,13 @@ "tcl_scripts": {"axi_master": "axi_master_design.tcl"}, "python_drivers": {}, "c_drivers": { "axi_master": "axi_master_design.c"} + }, + + "vcu128": { + "part": "xcvu37p-fsvh2892-2L-e", + "tcl_scripts": {"axi_master": "axi_master_design.tcl"}, + "python_drivers": {}, + "c_drivers": { "axi_master": "axi_master_design.c"} } + } From d5c780bbd48ed2cea54ba5031e8cf20cb9c7b2a9 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 6 Oct 2022 15:59:32 -0400 Subject: [PATCH 02/14] Add files via upload --- .../vivado_accelerator/vcu128/Readme.md | 1 + .../vcu128/c_drivers/sdk/Makefile | 33 ++ .../vcu128/c_drivers/sdk/common/main.c | 351 ++++++++++++ .../vcu128/c_drivers/sdk/setup.tcl | 14 + .../vcu128/tcl_scripts/axi_master_design.tcl | 519 ++++++++++++++++++ .../verilog_wrappers/design_1_wrapper.v | 92 ++++ 6 files changed, 1010 insertions(+) create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/Readme.md create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v diff --git a/hls4ml/templates/vivado_accelerator/vcu128/Readme.md b/hls4ml/templates/vivado_accelerator/vcu128/Readme.md new file mode 100644 index 000000000..785d69b84 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/Readme.md @@ -0,0 +1 @@ +This is the test for adding VCU128 board to HLS4ML template. diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile new file mode 100644 index 000000000..03ab9b8de --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile @@ -0,0 +1,33 @@ +DESIGN := design_1 + +help: + @echo "INFO: make to show targets" +.PHONY: help + +--setup: + xsct ./setup.tcl $(DESIGN) +.PHONY: --setup + +sdk: --setup + rm -f $(DESIGN)_standalone/src/helloworld.c + cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c + cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h +.PHONY: sdk + +gui: + xsdk --workspace . & +.PHONY: gui + +clean: + rm -rf $(DESIGN)_platform + rm -rf $(DESIGN)_standalone + rm -rf $(DESIGN)_standalone_bsp + rm -rf RemoteSystemsTempFiles + rm -rf .Xil + rm -rf .metadata + rm -f *.log +.PHONY: clean + +ultraclean: clean + rm -rf hdf/*.hdf +.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c new file mode 100644 index 000000000..41f5dca28 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c @@ -0,0 +1,351 @@ +/** + * + * Set Heap Size in ldscript.ld to 0x1000000 (16MB) + * + */ + +#include "xmyproject_axi.h" /* TODO: design-dependent name */ +#include "stdio.h" /* PRINTF */ +#include "unistd.h" /* sleep */ +#include "stdlib.h" +#include "malloc.h" +#include "assert.h" +#include "xil_io.h" /* peripheral read/write wrappers */ +#include "platform.h" /* platform init/cleanup functions */ +#include "xil_cache.h" /* enable/disable caches etc */ +#include "xil_printf.h" /* UART debug print functions */ +#include "xparameters.h" /* peripherals base addresses */ +#include "xtmrctr.h" /* timer, Xilinx IP Timer Counter */ + +#include "data.h" + +#define EEMBC_POWER 1 + +#ifdef EEMBC_POWER +#include "xgpio.h" /* AXI GPIO drivers */ + +#define PIN 0x01 +#define GPIO_PMOD_PIN_DEVICE_ID XPAR_GPIO_0_DEVICE_ID + +#define set_pin_high(InstancePtr, Mask) \ + XGpio_DiscreteWrite(InstancePtr, 1, Mask) + +#define set_pin_low(InstancePtr, Mask) \ + XGpio_DiscreteClear(InstancePtr, 1, Mask) + +XGpio Gpio; +#endif + + +//#define __DEBUG__ + +#define MAX_PRINT_ELEMENTS (16) + +#define PRINTF printf + +const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; +const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; + +#if 1 +/* Accelerator verification */ +#define REFERENCE_OUTPUTS data_y_hls_outputs +#else +/* Accelerator validation */ +#define REFERENCE_OUTPUTS data_y_outputs +//#define REFERENCE_OUTPUTS data_y_keras_outputs +#endif + +unsigned get_max(float *data, unsigned n_elements) { + float max_value = 0.0; + unsigned max_index = 0; + for (unsigned i = 0; i < n_elements; i++) + if (data[i] >= max_value) { + max_index = i; + max_value = data[i]; + } + return max_index; +} + +float *inputs_mem = NULL; +float *outputs_mem = NULL; +float *reference_mem = NULL; + +/* Accelerator configuration */ +XMyproject_axi accelerator; /* TODO: design-dependent name */ +XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ + +/* Accelerator initialization routine */ +void init_accelerators() { + PRINTF("INFO: Initializing accelerator\r\n"); + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_DEVICE_ID); /* TODO: design-dependent name */ + if (accelerator_cfg) { + int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ + if (status != XST_SUCCESS) { + PRINTF("ERROR: Initializing accelerator\r\n"); + } + } +} + +/* Reference implementation of the accelerator in software */ +int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { +#ifdef __DEBUG__ + PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); +#endif + /* See data.h for inputs and outputs */ + for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { + sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; + } + return 0; +} + +/* Profiling utilities */ +static XTmrCtr TimerCounterInst; +#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID +#define TIMER_CNTR_0 0 +#define TIMER_CNTR_1 1 + +void start_64b_counter() { + XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_0); + XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_1); +} + +void stop_64b_counter() { + XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_0); + XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_1); +} + +u64 get_64b_counter_value() { + //printf("bytes %u\n\r", sizeof(u64)); + u64 lo_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_0); + u64 hi_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_1); + u64 counter = (hi_counter << 32) | lo_counter; + //printf("INFO: hi = %lu, lo = %lu, total = %lu\n\r", hi_counter, lo_counter, counter); + return counter; +} + +#if 0 +double get_elapsed_time(u64 clk_start, u64 clk_stop) { + return ((clk_stop-clk_start) * (1.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ)); +} +#endif + +float get_elapsed_time_ns(u64 clks) { + return clks * 1000000000.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ; +} + + +/* Dump data to the console */ +void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { + PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); + /* Print at most MAX_PRINT_ELEMENTS */ + for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { + PRINTF("INFO: [%u] ", i); + for (unsigned j = 0; j < feature_count; j++) { + unsigned index = i * feature_count + j; + PRINTF("%f ", data[index]); + } + PRINTF("\r\n"); + } +} + +/* The top of the hill :-) */ +int main(int argc, char** argv) { + + int status; + u64 calibration_time; + double __attribute__ ((unused)) sw_elapsed = 0; + u64 hw_elapsed = 0; + u64 cache_elapsed = 0; + unsigned hw_errors; + + char __attribute__ ((unused)) dummy; /* dummy input */ + + /* Initialize platform (uart and caches) */ + init_platform(); + + PRINTF("\r\n"); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ + PRINTF("INFO: ==================================================\r\n"); + + init_accelerators(); + + /* Timer Counter */ + status = XTmrCtr_Initialize(&TimerCounterInst, TMRCTR_DEVICE_ID); + if (status != XST_SUCCESS){ + print("ERROR: Timer counter initialization failed \r\n"); + return status; + } + + XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0, + XTC_AUTO_RELOAD_OPTION | + XTC_CASCADE_MODE_OPTION); + + print("INFO: Timer counter initialized\r\n"); + + inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); + outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + + /* Calibration */ + start_64b_counter(); + sleep(1); + stop_64b_counter(); + calibration_time = get_64b_counter_value(); + PRINTF("INFO: Time calibration for one second (%lf sec, %llu clk)\r\n", get_elapsed_time_ns(calibration_time), calibration_time); + + /* Initialize memory */ + PRINTF("INFO: Initialize memory\r\n"); + PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ + PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); + PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); + PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); + PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + + // Set Heap Size in ldscript.ld to 0x1000000 (16MB) + //malloc_stats(); + + for (int i = 0; i < INPUT_N_ELEMENTS; i++) { + inputs_mem[i] = data_X_inputs[i]; + } + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + outputs_mem[i] = 0x0; + } + + /* ****** SW REFERENCE ****** */ + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Start SW reference implementation\r\n"); + start_64b_counter(); + sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); + stop_64b_counter(); + sw_elapsed = get_64b_counter_value(); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + //PRINTF("INFO:"); + + /* ****** HW ACCELERATOR ****** */ + PRINTF("INFO: Start HW accelerator\r\n"); + start_64b_counter(); + Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + stop_64b_counter(); + cache_elapsed = get_64b_counter_value(); + + for (unsigned j = 0; j < N_SAMPLES; j++) { + float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; + float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; + + /* Configure the accelerator */ + start_64b_counter(); + XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ + XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ + + XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ + + /* Polling */ + while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ + + /* Get error status */ + //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ + stop_64b_counter(); + hw_elapsed += get_64b_counter_value(); + } + + start_64b_counter(); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + stop_64b_counter(); + cache_elapsed += get_64b_counter_value(); + + PRINTF("INFO: HW accelerator done!\r\n"); + + /* ****** VALIDATION ****** */ + PRINTF("INFO: ================== Verification ==================\r\n"); +#ifdef __DEBUG__ + PRINTF("INFO: Dump data\r\n"); + dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); + dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); + dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); +#endif + +#ifdef __DEBUG__ + PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); +#endif + PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); + PRINTF("INFO: - total %f sec\r\n", get_elapsed_time_ns(hw_elapsed)); + PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", get_elapsed_time_ns(hw_elapsed) / (N_SAMPLES), (get_elapsed_time_ns(hw_elapsed)*1000.0) / (N_SAMPLES)); + PRINTF("INFO: Cache flush time: %f sec\r\n", get_elapsed_time_ns(cache_elapsed)); +#ifdef __DEBUG__ + PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); +#endif + + hw_errors = 0; +#if 1 + /* Accelerator verification */ + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + if (outputs_mem[i] != reference_mem[i]) { + PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); + hw_errors++; + } + } + PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); + if (hw_errors > 0) + PRINTF("INFO: Verification: FAIL\r\n"); + else + PRINTF("INFO: Verification: PASS!\r\n"); +#else + /* Accelerator validation */ + for (unsigned s = 0; s < N_SAMPLES; s++) { + unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + if (hw_digit != ref_digit) { +#ifdef __DEBUG__ + PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); +#endif + hw_errors++; + } + } + float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; + float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); + PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); + PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); + PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); +#endif + + PRINTF("INFO: ==================================================\r\n"); + + +#ifdef EEMBC_POWER + /* Initialize the GPIO driver */ + status = XGpio_Initialize(&Gpio, GPIO_PMOD_PIN_DEVICE_ID); + if (status != XST_SUCCESS) { + xil_printf("GPIO Initialization Failed\r\n"); + return XST_FAILURE; + } + + set_pin_low(&Gpio, PIN); + + PRINTF("INFO: Connect logic analyzer to the pin 3 of Pmod D\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + + /* Loop forever */ + for (unsigned i; i < 100; i++) { + set_pin_high(&Gpio, PIN); + + sleep(1); + + set_pin_low(&Gpio, PIN); + + sleep(1); + } +#endif + + cleanup_platform(); + + return 0; +} + + diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl new file mode 100644 index 000000000..383bf39cf --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl @@ -0,0 +1,14 @@ +# See +# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html + +setws . +if { $::argc == 1 } { + set myproject [lindex $::argv 0] + createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf + createapp -name ${myproject}\_standalone -app {Hello World} -proc microblaze_mcu -hwproject ${myproject}\_platform -os standalone + configapp -app ${myproject}\_standalone build-config release + #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} + #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} + projects -build + #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} +} diff --git a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl new file mode 100644 index 000000000..6351502ec --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl @@ -0,0 +1,519 @@ + +################################################################ +# Author: Mohammad Mehdi Rahimifar +# 3IT-University of Sherbrooke +# August 2022 +# +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + + + +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source design_1_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + + + +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +#set acc_name "${myproject}_axi" +set part_name "xcvu37p-fsvh2892-2L-e" +set board_name "xilinx.com:vcu128:part0:1.0" + + + + + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 ${myproject}_vivado_accelerator -part xcvu37p-fsvh2892-2L-e + set_property BOARD_PART xilinx.com:vcu128:part0:1.0 [current_project] +} + + + + +# Setup IP repo +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +#set_property ip_repo_paths /home/subnugler/Desktop/MICROBLAZE_TEST/Microblaze/myproject_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + + + + + + +#CHANGED HERE!!!!!!!!!!! + +# CHANGE DESIGN NAME HERE +#variable design_name +#set design_name design_1 + + + + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:smartconnect:1.0\ +xilinx.com:ip:axi_timer:2.0\ +xilinx.com:ip:axi_uart16550:2.0\ +xilinx.com:ip:clk_wiz:6.0\ +xilinx.com:ip:ddr4:2.2\ +xilinx.com:ip:mdm:3.2\ +xilinx.com:ip:microblaze:11.0\ +xilinx.com:hls:myproject_axi:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:lmb_bram_if_cntlr:4.0\ +xilinx.com:ip:lmb_v10:3.0\ +xilinx.com:ip:blk_mem_gen:8.4\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + +# Hierarchical cell: microblaze_0_local_memory +proc create_hier_cell_microblaze_0_local_memory { parentCell nameHier } { + + variable script_folder + + if { $parentCell eq "" || $nameHier eq "" } { + catch {common::send_msg_id "BD_TCL-102" "ERROR" "create_hier_cell_microblaze_0_local_memory() - Empty argument(s)!"} + return + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + # Create cell and set as current instance + set hier_obj [create_bd_cell -type hier $nameHier] + current_bd_instance $hier_obj + + # Create interface pins + create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 DLMB + + create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 ILMB + + + # Create pins + create_bd_pin -dir I -type clk LMB_Clk + create_bd_pin -dir I -type rst SYS_Rst + + # Create instance: dlmb_bram_if_cntlr, and set properties + set dlmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 dlmb_bram_if_cntlr ] + set_property -dict [ list \ + CONFIG.C_ECC {0} \ + ] $dlmb_bram_if_cntlr + + # Create instance: dlmb_v10, and set properties + set dlmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 dlmb_v10 ] + + # Create instance: ilmb_bram_if_cntlr, and set properties + set ilmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 ilmb_bram_if_cntlr ] + set_property -dict [ list \ + CONFIG.C_ECC {0} \ + ] $ilmb_bram_if_cntlr + + # Create instance: ilmb_v10, and set properties + set ilmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 ilmb_v10 ] + + # Create instance: lmb_bram, and set properties + set lmb_bram [ create_bd_cell -type ip -vlnv xilinx.com:ip:blk_mem_gen:8.4 lmb_bram ] + set_property -dict [ list \ + CONFIG.Memory_Type {True_Dual_Port_RAM} \ + CONFIG.use_bram_block {BRAM_Controller} \ + ] $lmb_bram + + # Create interface connections + connect_bd_intf_net -intf_net microblaze_0_dlmb [get_bd_intf_pins DLMB] [get_bd_intf_pins dlmb_v10/LMB_M] + connect_bd_intf_net -intf_net microblaze_0_dlmb_bus [get_bd_intf_pins dlmb_bram_if_cntlr/SLMB] [get_bd_intf_pins dlmb_v10/LMB_Sl_0] + connect_bd_intf_net -intf_net microblaze_0_dlmb_cntlr [get_bd_intf_pins dlmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTA] + connect_bd_intf_net -intf_net microblaze_0_ilmb [get_bd_intf_pins ILMB] [get_bd_intf_pins ilmb_v10/LMB_M] + connect_bd_intf_net -intf_net microblaze_0_ilmb_bus [get_bd_intf_pins ilmb_bram_if_cntlr/SLMB] [get_bd_intf_pins ilmb_v10/LMB_Sl_0] + connect_bd_intf_net -intf_net microblaze_0_ilmb_cntlr [get_bd_intf_pins ilmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTB] + + # Create port connections + connect_bd_net -net SYS_Rst_1 [get_bd_pins SYS_Rst] [get_bd_pins dlmb_bram_if_cntlr/LMB_Rst] [get_bd_pins dlmb_v10/SYS_Rst] [get_bd_pins ilmb_bram_if_cntlr/LMB_Rst] [get_bd_pins ilmb_v10/SYS_Rst] + connect_bd_net -net microblaze_0_Clk [get_bd_pins LMB_Clk] [get_bd_pins dlmb_bram_if_cntlr/LMB_Clk] [get_bd_pins dlmb_v10/LMB_Clk] [get_bd_pins ilmb_bram_if_cntlr/LMB_Clk] [get_bd_pins ilmb_v10/LMB_Clk] + + # Restore current instance + current_bd_instance $oldCurInst +} + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set ddr4_sdram [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddr4_rtl:1.0 ddr4_sdram ] + + set default_100mhz_clk [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 default_100mhz_clk ] + set_property -dict [ list \ + CONFIG.FREQ_HZ {100000000} \ + ] $default_100mhz_clk + + set rs232_uart_0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:uart_rtl:1.0 rs232_uart_0 ] + + + # Create ports + set dummy_port_in [ create_bd_port -dir I -type rst dummy_port_in ] + set_property -dict [ list \ + CONFIG.POLARITY {ACTIVE_HIGH} \ + ] $dummy_port_in + + # Create instance: axi_smc, and set properties + set axi_smc [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_smc ] + set_property -dict [ list \ + CONFIG.NUM_CLKS {2} \ + CONFIG.NUM_SI {4} \ + ] $axi_smc + + # Create instance: axi_timer_0, and set properties + set axi_timer_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_timer:2.0 axi_timer_0 ] + + # Create instance: axi_uart16550_0, and set properties + set axi_uart16550_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uart16550:2.0 axi_uart16550_0 ] + set_property -dict [ list \ + CONFIG.UART_BOARD_INTERFACE {rs232_uart_0} \ + CONFIG.USE_BOARD_FLOW {true} \ + ] $axi_uart16550_0 + + # Create instance: clk_wiz_0, and set properties + set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ] + set_property -dict [ list \ + CONFIG.CLKOUT1_JITTER {166.057} \ + CONFIG.CLKOUT1_PHASE_ERROR {298.404} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {125.000} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {125.000} \ + CONFIG.RESET_BOARD_INTERFACE {Custom} \ + CONFIG.USE_BOARD_FLOW {true} \ + ] $clk_wiz_0 + + # Create instance: ddr4_0, and set properties + set ddr4_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:ddr4:2.2 ddr4_0 ] + set_property -dict [ list \ + CONFIG.C0_CLOCK_BOARD_INTERFACE {default_100mhz_clk} \ + CONFIG.C0_DDR4_BOARD_INTERFACE {ddr4_sdram} \ + CONFIG.RESET_BOARD_INTERFACE {dummy_port_in} \ + ] $ddr4_0 + + # Create instance: mdm_1, and set properties + set mdm_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mdm:3.2 mdm_1 ] + + # Create instance: microblaze_0, and set properties + set microblaze_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:11.0 microblaze_0 ] + set_property -dict [ list \ + CONFIG.C_ADDR_TAG_BITS {16} \ + CONFIG.C_CACHE_BYTE_SIZE {32768} \ + CONFIG.C_DCACHE_ADDR_TAG {16} \ + CONFIG.C_DCACHE_BYTE_SIZE {32768} \ + CONFIG.C_DCACHE_USE_WRITEBACK {1} \ + CONFIG.C_DEBUG_ENABLED {1} \ + CONFIG.C_DIV_ZERO_EXCEPTION {1} \ + CONFIG.C_D_AXI {1} \ + CONFIG.C_D_LMB {1} \ + CONFIG.C_FPU_EXCEPTION {1} \ + CONFIG.C_ICACHE_LINE_LEN {8} \ + CONFIG.C_ICACHE_STREAMS {1} \ + CONFIG.C_ICACHE_VICTIMS {8} \ + CONFIG.C_ILL_OPCODE_EXCEPTION {1} \ + CONFIG.C_I_LMB {1} \ + CONFIG.C_MMU_ZONES {2} \ + CONFIG.C_M_AXI_D_BUS_EXCEPTION {1} \ + CONFIG.C_M_AXI_I_BUS_EXCEPTION {1} \ + CONFIG.C_NUMBER_OF_PC_BRK {2} \ + CONFIG.C_NUMBER_OF_RD_ADDR_BRK {1} \ + CONFIG.C_NUMBER_OF_WR_ADDR_BRK {1} \ + CONFIG.C_OPCODE_0x0_ILLEGAL {1} \ + CONFIG.C_PVR {2} \ + CONFIG.C_UNALIGNED_EXCEPTIONS {1} \ + CONFIG.C_USE_BARREL {1} \ + CONFIG.C_USE_DCACHE {1} \ + CONFIG.C_USE_DIV {1} \ + CONFIG.C_USE_FPU {1} \ + CONFIG.C_USE_HW_MUL {2} \ + CONFIG.C_USE_ICACHE {1} \ + CONFIG.C_USE_MMU {3} \ + CONFIG.C_USE_MSR_INSTR {1} \ + CONFIG.C_USE_PCMP_INSTR {1} \ + CONFIG.G_TEMPLATE_LIST {10} \ + CONFIG.G_USE_EXCEPTIONS {1} \ + ] $microblaze_0 + + # Create instance: microblaze_0_axi_periph, and set properties + set microblaze_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 microblaze_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {4} \ + ] $microblaze_0_axi_periph + + # Create instance: microblaze_0_local_memory + create_hier_cell_microblaze_0_local_memory [current_bd_instance .] microblaze_0_local_memory + + # Create instance: myproject_axi_0, and set properties + set myproject_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 myproject_axi_0 ] + + # Create instance: rst_clk_wiz_0_100M, and set properties + set rst_clk_wiz_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_clk_wiz_0_100M ] + set_property -dict [ list \ + CONFIG.RESET_BOARD_INTERFACE {Custom} \ + CONFIG.USE_BOARD_FLOW {true} \ + ] $rst_clk_wiz_0_100M + + # Create instance: rst_ddr4_0_333M, and set properties + set rst_ddr4_0_333M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ddr4_0_333M ] + + # Create interface connections + connect_bd_intf_net -intf_net axi_smc_M00_AXI [get_bd_intf_pins axi_smc/M00_AXI] [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI] + connect_bd_intf_net -intf_net axi_uart16550_0_UART [get_bd_intf_ports rs232_uart_0] [get_bd_intf_pins axi_uart16550_0/UART] + connect_bd_intf_net -intf_net ddr4_0_C0_DDR4 [get_bd_intf_ports ddr4_sdram] [get_bd_intf_pins ddr4_0/C0_DDR4] + connect_bd_intf_net -intf_net default_100mhz_clk_1 [get_bd_intf_ports default_100mhz_clk] [get_bd_intf_pins ddr4_0/C0_SYS_CLK] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_DC [get_bd_intf_pins axi_smc/S00_AXI] [get_bd_intf_pins microblaze_0/M_AXI_DC] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_DP [get_bd_intf_pins microblaze_0/M_AXI_DP] [get_bd_intf_pins microblaze_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_IC [get_bd_intf_pins axi_smc/S01_AXI] [get_bd_intf_pins microblaze_0/M_AXI_IC] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M00_AXI [get_bd_intf_pins axi_timer_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M00_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M01_AXI [get_bd_intf_pins axi_uart16550_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M01_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M02_AXI [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI_CTRL] [get_bd_intf_pins microblaze_0_axi_periph/M02_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M03_AXI [get_bd_intf_pins microblaze_0_axi_periph/M03_AXI] [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] + connect_bd_intf_net -intf_net microblaze_0_debug [get_bd_intf_pins mdm_1/MBDEBUG_0] [get_bd_intf_pins microblaze_0/DEBUG] + connect_bd_intf_net -intf_net microblaze_0_dlmb_1 [get_bd_intf_pins microblaze_0/DLMB] [get_bd_intf_pins microblaze_0_local_memory/DLMB] + connect_bd_intf_net -intf_net microblaze_0_ilmb_1 [get_bd_intf_pins microblaze_0/ILMB] [get_bd_intf_pins microblaze_0_local_memory/ILMB] + connect_bd_intf_net -intf_net myproject_axi_0_m_axi_IN_BUS [get_bd_intf_pins axi_smc/S02_AXI] [get_bd_intf_pins myproject_axi_0/m_axi_IN_BUS] + connect_bd_intf_net -intf_net myproject_axi_0_m_axi_OUT_BUS [get_bd_intf_pins axi_smc/S03_AXI] [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] + + # Create port connections + connect_bd_net -net clk_wiz_0_locked [get_bd_pins clk_wiz_0/locked] [get_bd_pins rst_clk_wiz_0_100M/dcm_locked] + connect_bd_net -net ddr4_0_c0_ddr4_ui_clk [get_bd_pins axi_smc/aclk] [get_bd_pins clk_wiz_0/clk_in1] [get_bd_pins ddr4_0/c0_ddr4_ui_clk] [get_bd_pins microblaze_0_axi_periph/M02_ACLK] [get_bd_pins rst_ddr4_0_333M/slowest_sync_clk] + connect_bd_net -net ddr4_0_c0_ddr4_ui_clk_sync_rst [get_bd_pins clk_wiz_0/reset] [get_bd_pins ddr4_0/c0_ddr4_ui_clk_sync_rst] [get_bd_pins rst_clk_wiz_0_100M/ext_reset_in] [get_bd_pins rst_ddr4_0_333M/ext_reset_in] + connect_bd_net -net dummy_port_in_1 [get_bd_ports dummy_port_in] [get_bd_pins ddr4_0/sys_rst] + connect_bd_net -net mdm_1_debug_sys_rst [get_bd_pins mdm_1/Debug_SYS_Rst] [get_bd_pins rst_clk_wiz_0_100M/mb_debug_sys_rst] + connect_bd_net -net microblaze_0_Clk [get_bd_pins axi_smc/aclk1] [get_bd_pins axi_timer_0/s_axi_aclk] [get_bd_pins axi_uart16550_0/s_axi_aclk] [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins microblaze_0/Clk] [get_bd_pins microblaze_0_axi_periph/ACLK] [get_bd_pins microblaze_0_axi_periph/M00_ACLK] [get_bd_pins microblaze_0_axi_periph/M01_ACLK] [get_bd_pins microblaze_0_axi_periph/M03_ACLK] [get_bd_pins microblaze_0_axi_periph/S00_ACLK] [get_bd_pins microblaze_0_local_memory/LMB_Clk] [get_bd_pins myproject_axi_0/ap_clk] [get_bd_pins rst_clk_wiz_0_100M/slowest_sync_clk] + connect_bd_net -net rst_clk_wiz_0_100M_bus_struct_reset [get_bd_pins microblaze_0_local_memory/SYS_Rst] [get_bd_pins rst_clk_wiz_0_100M/bus_struct_reset] + connect_bd_net -net rst_clk_wiz_0_100M_mb_reset [get_bd_pins microblaze_0/Reset] [get_bd_pins rst_clk_wiz_0_100M/mb_reset] + connect_bd_net -net rst_clk_wiz_0_100M_peripheral_aresetn [get_bd_pins axi_smc/aresetn] [get_bd_pins axi_timer_0/s_axi_aresetn] [get_bd_pins axi_uart16550_0/s_axi_aresetn] [get_bd_pins microblaze_0_axi_periph/ARESETN] [get_bd_pins microblaze_0_axi_periph/M00_ARESETN] [get_bd_pins microblaze_0_axi_periph/M01_ARESETN] [get_bd_pins microblaze_0_axi_periph/M03_ARESETN] [get_bd_pins microblaze_0_axi_periph/S00_ARESETN] [get_bd_pins myproject_axi_0/ap_rst_n] [get_bd_pins rst_clk_wiz_0_100M/peripheral_aresetn] + connect_bd_net -net rst_ddr4_0_333M_peripheral_aresetn [get_bd_pins ddr4_0/c0_ddr4_aresetn] [get_bd_pins microblaze_0_axi_periph/M02_ARESETN] [get_bd_pins rst_ddr4_0_333M/peripheral_aresetn] + + # Create address segments + assign_bd_address -offset 0x41C00000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_timer_0/S_AXI/Reg] -force + assign_bd_address -offset 0x44A00000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_uart16550_0/S_AXI/Reg] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + assign_bd_address -offset 0x44B00000 -range 0x00100000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP_CTRL/C0_REG] -force + assign_bd_address -offset 0x00000000 -range 0x00002000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs microblaze_0_local_memory/dlmb_bram_if_cntlr/SLMB/Mem] -force + assign_bd_address -offset 0x00000000 -range 0x00002000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs microblaze_0_local_memory/ilmb_bram_if_cntlr/SLMB/Mem] -force + assign_bd_address -offset 0x44A10000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs myproject_axi_0/s_axi_CTRL_BUS/Reg] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces myproject_axi_0/Data_m_axi_IN_BUS] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces myproject_axi_0/Data_m_axi_OUT_BUS] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + + + # Restore current instance + current_bd_instance $oldCurInst + + validate_bd_design + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + +############################################################################################################# + +#WRAP THE MODEL + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top + +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +#open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages + + + + + + + + + + + + + + + + + diff --git a/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v b/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v new file mode 100644 index 000000000..aa944e12a --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v @@ -0,0 +1,92 @@ +//Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. +//-------------------------------------------------------------------------------- +//Tool Version: Vivado v.2019.2 (lin64) Build 2708876 Wed Nov 6 21:39:14 MST 2019 +//Date : Wed Oct 5 16:49:36 2022 +//Host : subnugler running 64-bit Ubuntu 22.04.1 LTS +//Command : generate_target design_1_wrapper.bd +//Design : design_1_wrapper +//Purpose : IP block netlist +//-------------------------------------------------------------------------------- +`timescale 1 ps / 1 ps + +module design_1_wrapper + (ddr4_sdram_act_n, + ddr4_sdram_adr, + ddr4_sdram_ba, + ddr4_sdram_bg, + ddr4_sdram_ck_c, + ddr4_sdram_ck_t, + ddr4_sdram_cke, + ddr4_sdram_cs_n, + ddr4_sdram_dm_n, + ddr4_sdram_dq, + ddr4_sdram_dqs_c, + ddr4_sdram_dqs_t, + ddr4_sdram_odt, + ddr4_sdram_reset_n, + default_100mhz_clk_clk_n, + default_100mhz_clk_clk_p, + dummy_port_in, + rs232_uart_0_rxd, + rs232_uart_0_txd); + output ddr4_sdram_act_n; + output [16:0]ddr4_sdram_adr; + output [1:0]ddr4_sdram_ba; + output ddr4_sdram_bg; + output ddr4_sdram_ck_c; + output ddr4_sdram_ck_t; + output ddr4_sdram_cke; + output [1:0]ddr4_sdram_cs_n; + inout [8:0]ddr4_sdram_dm_n; + inout [71:0]ddr4_sdram_dq; + inout [8:0]ddr4_sdram_dqs_c; + inout [8:0]ddr4_sdram_dqs_t; + output ddr4_sdram_odt; + output ddr4_sdram_reset_n; + input default_100mhz_clk_clk_n; + input default_100mhz_clk_clk_p; + input dummy_port_in; + input rs232_uart_0_rxd; + output rs232_uart_0_txd; + + wire ddr4_sdram_act_n; + wire [16:0]ddr4_sdram_adr; + wire [1:0]ddr4_sdram_ba; + wire ddr4_sdram_bg; + wire ddr4_sdram_ck_c; + wire ddr4_sdram_ck_t; + wire ddr4_sdram_cke; + wire [1:0]ddr4_sdram_cs_n; + wire [8:0]ddr4_sdram_dm_n; + wire [71:0]ddr4_sdram_dq; + wire [8:0]ddr4_sdram_dqs_c; + wire [8:0]ddr4_sdram_dqs_t; + wire ddr4_sdram_odt; + wire ddr4_sdram_reset_n; + wire default_100mhz_clk_clk_n; + wire default_100mhz_clk_clk_p; + wire dummy_port_in; + wire rs232_uart_0_rxd; + wire rs232_uart_0_txd; + + design_1 design_1_i + (.ddr4_sdram_act_n(ddr4_sdram_act_n), + .ddr4_sdram_adr(ddr4_sdram_adr), + .ddr4_sdram_ba(ddr4_sdram_ba), + .ddr4_sdram_bg(ddr4_sdram_bg), + .ddr4_sdram_ck_c(ddr4_sdram_ck_c), + .ddr4_sdram_ck_t(ddr4_sdram_ck_t), + .ddr4_sdram_cke(ddr4_sdram_cke), + .ddr4_sdram_cs_n(ddr4_sdram_cs_n), + .ddr4_sdram_dm_n(ddr4_sdram_dm_n), + .ddr4_sdram_dq(ddr4_sdram_dq), + .ddr4_sdram_dqs_c(ddr4_sdram_dqs_c), + .ddr4_sdram_dqs_t(ddr4_sdram_dqs_t), + .ddr4_sdram_odt(ddr4_sdram_odt), + .ddr4_sdram_reset_n(ddr4_sdram_reset_n), + .default_100mhz_clk_clk_n(default_100mhz_clk_clk_n), + .default_100mhz_clk_clk_p(default_100mhz_clk_clk_p), + .dummy_port_in(dummy_port_in), + .rs232_uart_0_rxd(rs232_uart_0_rxd), + .rs232_uart_0_txd(rs232_uart_0_txd)); +endmodule From 78c410214185c2da1e49ce55dce2339ee631fcbc Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Fri, 7 Oct 2022 11:42:26 -0400 Subject: [PATCH 03/14] Update axi_master_design.tcl --- .../vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl index 6351502ec..c3fa41ddd 100644 --- a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl +++ b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl @@ -51,7 +51,7 @@ set board_name "xilinx.com:vcu128:part0:1.0" set list_projs [get_projects -quiet] if { $list_projs eq "" } { - create_project project_1 ${myproject}_vivado_accelerator -part xcvu37p-fsvh2892-2L-e + create_project project_1 ${myproject}_vivado_accelerator -part xcvu37p-fsvh2892-2L-e -force set_property BOARD_PART xilinx.com:vcu128:part0:1.0 [current_project] } From bf75ffca757735415e1d8bcd9d5a7037c5f072d1 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Tue, 11 Oct 2022 11:18:10 -0400 Subject: [PATCH 04/14] Update main.c --- .../vcu128/c_drivers/sdk/common/main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c index 41f5dca28..84e3aa3d0 100644 --- a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c @@ -19,12 +19,12 @@ #include "data.h" -#define EEMBC_POWER 1 +/*#define EEMBC_POWER 1 #ifdef EEMBC_POWER #include "xgpio.h" /* AXI GPIO drivers */ -#define PIN 0x01 +/*#define PIN 0x01 #define GPIO_PMOD_PIN_DEVICE_ID XPAR_GPIO_0_DEVICE_ID #define set_pin_high(InstancePtr, Mask) \ @@ -35,7 +35,7 @@ XGpio Gpio; #endif - +*/ //#define __DEBUG__ @@ -77,7 +77,7 @@ XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ /* Accelerator initialization routine */ void init_accelerators() { PRINTF("INFO: Initializing accelerator\r\n"); - accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_DEVICE_ID); /* TODO: design-dependent name */ + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ if (accelerator_cfg) { int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ if (status != XST_SUCCESS) { @@ -130,7 +130,7 @@ double get_elapsed_time(u64 clk_start, u64 clk_stop) { #endif float get_elapsed_time_ns(u64 clks) { - return clks * 1000000000.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ; + return clks * 1000000000.0/XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ; } @@ -348,4 +348,3 @@ int main(int argc, char** argv) { return 0; } - From fecb76a3dcea04038a8cd5b98dd6b39c4c49d987 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Tue, 11 Oct 2022 15:54:21 -0400 Subject: [PATCH 05/14] Update axi_master_design.tcl --- .../vcu128/tcl_scripts/axi_master_design.tcl | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl index c3fa41ddd..a0540bcb5 100644 --- a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl +++ b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl @@ -1,9 +1,27 @@ ################################################################ -# Author: Mohammad Mehdi Rahimifar -# 3IT-University of Sherbrooke -# August 2022 -# +# +# MIT License +# +# Copyright (c) 2022 University of Sherbrooke +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# Author : Mehdi Rahimifar +# Last update : 2022-08-25 +# Description : This contains the tcl scripts to generate the right block design for VCU128 and the accelerator from hls4ml in Vivado ################################################################ namespace eval _tcl { From 3685e671af54de03b79d6e712bf59d10b011f2c7 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:25:52 -0500 Subject: [PATCH 06/14] Update supported_boards.json --- hls4ml/templates/supported_boards.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hls4ml/templates/supported_boards.json b/hls4ml/templates/supported_boards.json index 6b49cbcdc..8019a6ffc 100644 --- a/hls4ml/templates/supported_boards.json +++ b/hls4ml/templates/supported_boards.json @@ -35,6 +35,14 @@ "tcl_scripts": {"axi_master": "axi_master_design.tcl"}, "python_drivers": {}, "c_drivers": { "axi_master": "axi_master_design.c"} + }, + + "zcu104": { + "part": "xczu7ev-ffvc1156-2-e", + "tcl_scripts": {"axi_master": "axi_master_design.tcl"}, + "python_drivers": {"axi_stream": "axi_stream_driver.py"}, + "c_drivers": {} } + } From ad7b79d8ec940b772c9772259eefd604158d53b9 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:26:59 -0500 Subject: [PATCH 07/14] Delete hls4ml/templates/vivado_accelerator directory --- .../arty-a7-100t/c_drivers/sdk/Makefile | 33 -- .../arty-a7-100t/c_drivers/sdk/common/main.c | 351 ------------ .../arty-a7-100t/c_drivers/sdk/setup.tcl | 14 - .../tcl_scripts/axi_master_design.tcl | 193 ------- .../verilog_wrappers/design_1_wrapper.v | 209 ------- .../arty-a7-100t/xdc_constraints/pin_pmod.xdc | 4 - .../arty-a7-100t/xdc_constraints/qspi.xdc | 13 - .../xdc_constraints/uart_pmod.xdc | 8 - .../templates/vivado_accelerator/build_lib.sh | 18 - .../vivado_accelerator/myproject_axi.cpp | 20 - .../vivado_accelerator/myproject_axi.h | 13 - .../pynq-z1/c_drivers/sdk/Makefile | 33 -- .../pynq-z1/c_drivers/sdk/common/main.c | 262 --------- .../pynq-z1/c_drivers/sdk/setup.tcl | 14 - .../python_drivers/axi_stream_driver.py | 75 --- .../pynq-z1/tcl_scripts/axi_lite_design.tcl | 26 - .../pynq-z1/tcl_scripts/axi_master_design.tcl | 88 --- .../pynq-z1/tcl_scripts/axi_stream_design.tcl | 59 -- .../pynq-z2/c_drivers/sdk/Makefile | 33 -- .../pynq-z2/c_drivers/sdk/common/main.c | 262 --------- .../pynq-z2/c_drivers/sdk/setup.tcl | 14 - .../python_drivers/axi_stream_driver.py | 75 --- .../pynq-z2/tcl_scripts/axi_lite_design.tcl | 26 - .../pynq-z2/tcl_scripts/axi_master_design.tcl | 88 --- .../pynq-z2/tcl_scripts/axi_stream_design.tcl | 59 -- .../ultra96v2/c_drivers/axi_master_driver.c | 6 - .../ultra96v2/c_drivers/axi_master_driver.h | 6 - .../ultra96v2/c_drivers/sdk/Makefile | 33 -- .../ultra96v2/c_drivers/sdk/common/main.c | 262 --------- .../ultra96v2/c_drivers/sdk/setup.tcl | 18 - .../python_drivers/axi_stream_driver.py | 75 --- .../ultra96v2/tcl_scripts/axi_lite_design.tcl | 26 - .../tcl_scripts/axi_master_design.tcl | 91 --- .../tcl_scripts/axi_stream_design.tcl | 58 -- .../vivado_accelerator/vcu128/Readme.md | 1 - .../vcu128/c_drivers/sdk/Makefile | 33 -- .../vcu128/c_drivers/sdk/common/main.c | 350 ------------ .../vcu128/c_drivers/sdk/setup.tcl | 14 - .../vcu128/tcl_scripts/axi_master_design.tcl | 537 ------------------ .../verilog_wrappers/design_1_wrapper.v | 92 --- .../python_drivers/axi_stream_driver.py | 75 --- .../zcu102/tcl_scripts/axi_stream_design.tcl | 58 -- 42 files changed, 3725 deletions(-) delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc delete mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc delete mode 100644 hls4ml/templates/vivado_accelerator/build_lib.sh delete mode 100644 hls4ml/templates/vivado_accelerator/myproject_axi.cpp delete mode 100644 hls4ml/templates/vivado_accelerator/myproject_axi.h delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/vcu128/Readme.md delete mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile delete mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c delete mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl delete mode 100644 hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v delete mode 100644 hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py delete mode 100644 hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile deleted file mode 100644 index 03ab9b8de..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -DESIGN := design_1 - -help: - @echo "INFO: make to show targets" -.PHONY: help - ---setup: - xsct ./setup.tcl $(DESIGN) -.PHONY: --setup - -sdk: --setup - rm -f $(DESIGN)_standalone/src/helloworld.c - cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c - cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h -.PHONY: sdk - -gui: - xsdk --workspace . & -.PHONY: gui - -clean: - rm -rf $(DESIGN)_platform - rm -rf $(DESIGN)_standalone - rm -rf $(DESIGN)_standalone_bsp - rm -rf RemoteSystemsTempFiles - rm -rf .Xil - rm -rf .metadata - rm -f *.log -.PHONY: clean - -ultraclean: clean - rm -rf hdf/*.hdf -.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c deleted file mode 100644 index 41f5dca28..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c +++ /dev/null @@ -1,351 +0,0 @@ -/** - * - * Set Heap Size in ldscript.ld to 0x1000000 (16MB) - * - */ - -#include "xmyproject_axi.h" /* TODO: design-dependent name */ -#include "stdio.h" /* PRINTF */ -#include "unistd.h" /* sleep */ -#include "stdlib.h" -#include "malloc.h" -#include "assert.h" -#include "xil_io.h" /* peripheral read/write wrappers */ -#include "platform.h" /* platform init/cleanup functions */ -#include "xil_cache.h" /* enable/disable caches etc */ -#include "xil_printf.h" /* UART debug print functions */ -#include "xparameters.h" /* peripherals base addresses */ -#include "xtmrctr.h" /* timer, Xilinx IP Timer Counter */ - -#include "data.h" - -#define EEMBC_POWER 1 - -#ifdef EEMBC_POWER -#include "xgpio.h" /* AXI GPIO drivers */ - -#define PIN 0x01 -#define GPIO_PMOD_PIN_DEVICE_ID XPAR_GPIO_0_DEVICE_ID - -#define set_pin_high(InstancePtr, Mask) \ - XGpio_DiscreteWrite(InstancePtr, 1, Mask) - -#define set_pin_low(InstancePtr, Mask) \ - XGpio_DiscreteClear(InstancePtr, 1, Mask) - -XGpio Gpio; -#endif - - -//#define __DEBUG__ - -#define MAX_PRINT_ELEMENTS (16) - -#define PRINTF printf - -const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; -const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; - -#if 1 -/* Accelerator verification */ -#define REFERENCE_OUTPUTS data_y_hls_outputs -#else -/* Accelerator validation */ -#define REFERENCE_OUTPUTS data_y_outputs -//#define REFERENCE_OUTPUTS data_y_keras_outputs -#endif - -unsigned get_max(float *data, unsigned n_elements) { - float max_value = 0.0; - unsigned max_index = 0; - for (unsigned i = 0; i < n_elements; i++) - if (data[i] >= max_value) { - max_index = i; - max_value = data[i]; - } - return max_index; -} - -float *inputs_mem = NULL; -float *outputs_mem = NULL; -float *reference_mem = NULL; - -/* Accelerator configuration */ -XMyproject_axi accelerator; /* TODO: design-dependent name */ -XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ - -/* Accelerator initialization routine */ -void init_accelerators() { - PRINTF("INFO: Initializing accelerator\r\n"); - accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_DEVICE_ID); /* TODO: design-dependent name */ - if (accelerator_cfg) { - int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ - if (status != XST_SUCCESS) { - PRINTF("ERROR: Initializing accelerator\r\n"); - } - } -} - -/* Reference implementation of the accelerator in software */ -int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { -#ifdef __DEBUG__ - PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); -#endif - /* See data.h for inputs and outputs */ - for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { - sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; - } - return 0; -} - -/* Profiling utilities */ -static XTmrCtr TimerCounterInst; -#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID -#define TIMER_CNTR_0 0 -#define TIMER_CNTR_1 1 - -void start_64b_counter() { - XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_0); - XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_1); -} - -void stop_64b_counter() { - XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_0); - XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_1); -} - -u64 get_64b_counter_value() { - //printf("bytes %u\n\r", sizeof(u64)); - u64 lo_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_0); - u64 hi_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_1); - u64 counter = (hi_counter << 32) | lo_counter; - //printf("INFO: hi = %lu, lo = %lu, total = %lu\n\r", hi_counter, lo_counter, counter); - return counter; -} - -#if 0 -double get_elapsed_time(u64 clk_start, u64 clk_stop) { - return ((clk_stop-clk_start) * (1.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ)); -} -#endif - -float get_elapsed_time_ns(u64 clks) { - return clks * 1000000000.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ; -} - - -/* Dump data to the console */ -void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { - PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); - /* Print at most MAX_PRINT_ELEMENTS */ - for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { - PRINTF("INFO: [%u] ", i); - for (unsigned j = 0; j < feature_count; j++) { - unsigned index = i * feature_count + j; - PRINTF("%f ", data[index]); - } - PRINTF("\r\n"); - } -} - -/* The top of the hill :-) */ -int main(int argc, char** argv) { - - int status; - u64 calibration_time; - double __attribute__ ((unused)) sw_elapsed = 0; - u64 hw_elapsed = 0; - u64 cache_elapsed = 0; - unsigned hw_errors; - - char __attribute__ ((unused)) dummy; /* dummy input */ - - /* Initialize platform (uart and caches) */ - init_platform(); - - PRINTF("\r\n"); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ - PRINTF("INFO: ==================================================\r\n"); - - init_accelerators(); - - /* Timer Counter */ - status = XTmrCtr_Initialize(&TimerCounterInst, TMRCTR_DEVICE_ID); - if (status != XST_SUCCESS){ - print("ERROR: Timer counter initialization failed \r\n"); - return status; - } - - XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0, - XTC_AUTO_RELOAD_OPTION | - XTC_CASCADE_MODE_OPTION); - - print("INFO: Timer counter initialized\r\n"); - - inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); - outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - - /* Calibration */ - start_64b_counter(); - sleep(1); - stop_64b_counter(); - calibration_time = get_64b_counter_value(); - PRINTF("INFO: Time calibration for one second (%lf sec, %llu clk)\r\n", get_elapsed_time_ns(calibration_time), calibration_time); - - /* Initialize memory */ - PRINTF("INFO: Initialize memory\r\n"); - PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ - PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); - PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); - PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); - PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - - // Set Heap Size in ldscript.ld to 0x1000000 (16MB) - //malloc_stats(); - - for (int i = 0; i < INPUT_N_ELEMENTS; i++) { - inputs_mem[i] = data_X_inputs[i]; - } - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - outputs_mem[i] = 0x0; - } - - /* ****** SW REFERENCE ****** */ - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Start SW reference implementation\r\n"); - start_64b_counter(); - sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); - stop_64b_counter(); - sw_elapsed = get_64b_counter_value(); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - //PRINTF("INFO:"); - - /* ****** HW ACCELERATOR ****** */ - PRINTF("INFO: Start HW accelerator\r\n"); - start_64b_counter(); - Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - stop_64b_counter(); - cache_elapsed = get_64b_counter_value(); - - for (unsigned j = 0; j < N_SAMPLES; j++) { - float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; - float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; - - /* Configure the accelerator */ - start_64b_counter(); - XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ - XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ - - XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ - - /* Polling */ - while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ - - /* Get error status */ - //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ - stop_64b_counter(); - hw_elapsed += get_64b_counter_value(); - } - - start_64b_counter(); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - stop_64b_counter(); - cache_elapsed += get_64b_counter_value(); - - PRINTF("INFO: HW accelerator done!\r\n"); - - /* ****** VALIDATION ****** */ - PRINTF("INFO: ================== Verification ==================\r\n"); -#ifdef __DEBUG__ - PRINTF("INFO: Dump data\r\n"); - dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); - dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); - dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); -#endif - -#ifdef __DEBUG__ - PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); -#endif - PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); - PRINTF("INFO: - total %f sec\r\n", get_elapsed_time_ns(hw_elapsed)); - PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", get_elapsed_time_ns(hw_elapsed) / (N_SAMPLES), (get_elapsed_time_ns(hw_elapsed)*1000.0) / (N_SAMPLES)); - PRINTF("INFO: Cache flush time: %f sec\r\n", get_elapsed_time_ns(cache_elapsed)); -#ifdef __DEBUG__ - PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); -#endif - - hw_errors = 0; -#if 1 - /* Accelerator verification */ - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - if (outputs_mem[i] != reference_mem[i]) { - PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); - hw_errors++; - } - } - PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); - if (hw_errors > 0) - PRINTF("INFO: Verification: FAIL\r\n"); - else - PRINTF("INFO: Verification: PASS!\r\n"); -#else - /* Accelerator validation */ - for (unsigned s = 0; s < N_SAMPLES; s++) { - unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - if (hw_digit != ref_digit) { -#ifdef __DEBUG__ - PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); -#endif - hw_errors++; - } - } - float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; - float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); - PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); - PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); - PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); -#endif - - PRINTF("INFO: ==================================================\r\n"); - - -#ifdef EEMBC_POWER - /* Initialize the GPIO driver */ - status = XGpio_Initialize(&Gpio, GPIO_PMOD_PIN_DEVICE_ID); - if (status != XST_SUCCESS) { - xil_printf("GPIO Initialization Failed\r\n"); - return XST_FAILURE; - } - - set_pin_low(&Gpio, PIN); - - PRINTF("INFO: Connect logic analyzer to the pin 3 of Pmod D\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - - /* Loop forever */ - for (unsigned i; i < 100; i++) { - set_pin_high(&Gpio, PIN); - - sleep(1); - - set_pin_low(&Gpio, PIN); - - sleep(1); - } -#endif - - cleanup_platform(); - - return 0; -} - - diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl deleted file mode 100644 index 383bf39cf..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl +++ /dev/null @@ -1,14 +0,0 @@ -# See -# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html - -setws . -if { $::argc == 1 } { - set myproject [lindex $::argv 0] - createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf - createapp -name ${myproject}\_standalone -app {Hello World} -proc microblaze_mcu -hwproject ${myproject}\_platform -os standalone - configapp -app ${myproject}\_standalone build-config release - #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} - #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} - projects -build - #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} -} diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl deleted file mode 100644 index 67d667b06..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl +++ /dev/null @@ -1,193 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -# Project names -set project_name "project_1" -set design_name "design_1" -set hls_solution_name "solution1" -set acc_name "${myproject}_axi" -set part_name "xc7a100tcsg324-1" -set board_name "digilentinc.com:arty-a7-100:part0:1.0" - -# Set board and chip part names -create_project ${project_name} ${myproject}_vivado_accelerator -part ${part_name} -force -set_property board_part ${board_name} [current_project] - -# Create block design -create_bd_design ${design_name} - -# Setup IP repo -#set_property ip_repo_paths ${myproject}_prj [current_project] -set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] -update_ip_catalog - -# Create clock wizard -create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 -apply_board_connection -board_interface "sys_clock" -ip_intf "clk_wiz_0/clock_CLK_IN1" -diagram ${design_name} -set_property name clk_wizard [get_bd_cells clk_wiz_0] -set_property -dict [list CONFIG.CLKOUT2_USED {true} CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {166.667} CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {200.00} CONFIG.MMCM_CLKOUT0_DIVIDE_F {6.000} CONFIG.MMCM_CLKOUT1_DIVIDE {5} CONFIG.NUM_OUT_CLKS {2} CONFIG.CLKOUT1_JITTER {118.758} CONFIG.CLKOUT2_JITTER {114.829} CONFIG.CLKOUT2_PHASE_ERROR {98.575}] [get_bd_cells clk_wizard] -#set_property -dict [list CONFIG.RESET_TYPE {ACTIVE_LOW} CONFIG.RESET_PORT {resetn}] [get_bd_cells clk_wizard] - -# Create MIG -create_bd_cell -type ip -vlnv xilinx.com:ip:mig_7series:4.2 mig_7series_0 -apply_board_connection -board_interface "ddr3_sdram" -ip_intf "mig_7series_0/mig_ddr_interface" -diagram ${design_name} - -# Wire MIG and clock wizard -delete_bd_objs [get_bd_nets clk_ref_i_1] [get_bd_ports clk_ref_i] -delete_bd_objs [get_bd_nets sys_clk_i_1] [get_bd_ports sys_clk_i] -connect_bd_net [get_bd_pins clk_wizard/clk_out2] [get_bd_pins mig_7series_0/clk_ref_i] -connect_bd_net [get_bd_pins clk_wizard/clk_out1] [get_bd_pins mig_7series_0/sys_clk_i] - -# Setup reset -#set_property -dict [list CONFIG.RESET_BOARD_INTERFACE {reset}] [get_bd_cells clk_wizard] -apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {reset ( System Reset ) } Manual_Source {New External Port (ACTIVE_LOW)}} [get_bd_pins mig_7series_0/sys_rst] - -# Create instance of MicroBlaze -create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:11.0 microblaze_mcu -apply_bd_automation -rule xilinx.com:bd_rule:microblaze -config { \ - axi_intc {0} \ - axi_periph {Enabled} \ - cache {16KB} \ - clk {/mig_7series_0/ui_clk (83 MHz)} \ - debug_module {Debug Only} \ - ecc {None} \ - local_mem {32KB} \ - preset {None} } [get_bd_cells microblaze_mcu] - -# Resize data and instruction caches -set_property -dict [list CONFIG.C_ADDR_TAG_BITS {18} CONFIG.C_CACHE_BYTE_SIZE {1024} CONFIG.C_DCACHE_ADDR_TAG {18} CONFIG.C_DCACHE_BYTE_SIZE {1024}] [get_bd_cells microblaze_mcu] - -# Enable full FPU -set_property -dict [list CONFIG.C_USE_FPU {2}] [get_bd_cells microblaze_mcu] - -# Create UART interface -#create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uart16550:2.0 axi_uart -#apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {Auto} Master {/microblaze_mcu (Periph)} Slave {/axi_uart/S_AXI} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_uart/S_AXI] -#apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {usb_uart ( USB UART ) } Manual_Source {Auto}} [get_bd_intf_pins axi_uart/UART] - -# Create UART-lite interface -create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uartlite:2.0 axi_uart -if { ${eembc_power} } { - set_property -dict [list CONFIG.C_BAUDRATE {9600}] [get_bd_cells axi_uart] -} else { - apply_board_connection -board_interface "usb_uart" -ip_intf "axi_uart/UART" -diagram ${design_name} - set_property -dict [list CONFIG.C_BAUDRATE {115200}] [get_bd_cells axi_uart] -} -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master {/microblaze_mcu (Periph)} \ - Slave {/axi_uart/S_AXI} \ - intc_ip {New AXI Interconnect} \ - master_apm {0}} [get_bd_intf_pins axi_uart/S_AXI] - -# Forward UART interface to PMOD pins -if { ${eembc_power} } { - create_bd_port -dir O pmod_uart_txd - create_bd_port -dir I pmod_uart_rxd - connect_bd_net [get_bd_pins /axi_uart/tx] [get_bd_ports pmod_uart_txd] - connect_bd_net [get_bd_pins /axi_uart/rx] [get_bd_ports pmod_uart_rxd] - add_files -fileset constrs_1 -norecurse uart_pmod.xdc -} - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ - Clk_slave {/mig_7series_0/ui_clk (83 MHz)} \ - Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} \ - Master {/microblaze_mcu (Cached)} \ - Slave {/mig_7series_0/S_AXI} \ - intc_ip {Auto} master_apm {0} } [get_bd_intf_pins mig_7series_0/S_AXI] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master {/microblaze_mcu (Periph)} \ - Slave {/axi_uart/S_AXI} \ - intc_ip {New AXI Interconnect} \ - master_apm {0} } [get_bd_intf_pins axi_uart/S_AXI] - -# Add accelerator and connect s-axi interface -create_bd_cell -type ip -vlnv xilinx.com:hls:${acc_name}:1.0 ${acc_name} -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/microblaze_mcu (Periph)} Slave {/${acc_name}/s_axi_CTRL_BUS} intc_ip {/microblaze_mcu_axi_periph} master_apm {0}} [get_bd_intf_pins ${acc_name}/s_axi_CTRL_BUS] - -# Connect m-axi interfaces -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {/mig_7series_0/ui_clk (83 MHz)} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/${acc_name}/m_axi_IN_BUS} Slave {/mig_7series_0/S_AXI} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins ${acc_name}/m_axi_IN_BUS] -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {/mig_7series_0/ui_clk (83 MHz)} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/${acc_name}/m_axi_OUT_BUS} Slave {/mig_7series_0/S_AXI} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins ${acc_name}/m_axi_OUT_BUS] - -# Reset -apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {reset ( System Reset ) } Manual_Source {Auto}} [get_bd_pins clk_wizard/reset] - -# Add timer -create_bd_cell -type ip -vlnv xilinx.com:ip:axi_timer:2.0 axi_timer_mcu -set_property -dict [list CONFIG.enable_timer2 {1}] [get_bd_cells axi_timer_mcu] - -# Wire timer -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/microblaze_mcu (Periph)} Slave {/axi_timer_mcu/S_AXI} intc_ip {/microblaze_mcu_axi_periph} master_apm {0}} [get_bd_intf_pins axi_timer_mcu/S_AXI] - -# Add AXI GPIO controlled pin -if { ${eembc_power} } { - # Add AXI GPIO IP - create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 - # Wire it up to a single output pin (to a PMOD) - set_property -dict [list CONFIG.C_GPIO_WIDTH {1} CONFIG.C_ALL_OUTPUTS {1}] [get_bd_cells axi_gpio_0] - apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ - Clk_slave {Auto} \ - Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} \ - Master {/microblaze_mcu (Periph)} \ - Slave {/axi_gpio_0/S_AXI} \ - intc_ip {/microblaze_mcu_axi_periph} \ - master_apm {0}} [get_bd_intf_pins axi_gpio_0/S_AXI] - create_bd_port -dir O pmod_pin - connect_bd_net [get_bd_ports pmod_pin] [get_bd_pins axi_gpio_0/gpio_io_o] - - add_files -fileset constrs_1 -norecurse pin_pmod.xdc -} - -# Add Quad SPI for cold boot -if { ${eembc_power} } { - create_bd_cell -type ip -vlnv xilinx.com:ip:axi_quad_spi:3.2 axi_quad_spi_0 - set_property -dict [list CONFIG.C_SPI_MEMORY {3}] [get_bd_cells axi_quad_spi_0] - apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {qspi_flash ( Quad SPI Flash ) } Manual_Source {Auto}} [get_bd_intf_pins axi_quad_spi_0/SPI_0] - apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/microblaze_mcu (Periph)} Slave {/axi_quad_spi_0/AXI_LITE} intc_ip {/microblaze_mcu_axi_periph} master_apm {0}} [get_bd_intf_pins axi_quad_spi_0/AXI_LITE] - set_property -dict [list CONFIG.CLKOUT3_USED {true} CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {50} CONFIG.MMCM_CLKOUT2_DIVIDE {20} CONFIG.NUM_OUT_CLKS {3} CONFIG.CLKOUT3_JITTER {151.636} CONFIG.CLKOUT3_PHASE_ERROR {98.575}] [get_bd_cells clk_wizard] - connect_bd_net [get_bd_pins clk_wizard/clk_out3] [get_bd_pins axi_quad_spi_0/ext_spi_clk] - - # BUG FIX - delete_bd_objs [get_bd_nets clk_wizard_clk_out3] - connect_bd_net [get_bd_pins axi_quad_spi_0/ext_spi_clk] [get_bd_pins mig_7series_0/ui_clk] - - add_files -fileset constrs_1 -norecurse qspi.xdc -} - -# Validate the design block we created -validate_bd_design - -# Save design -save_bd_design - -# Top level wrapper -#make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top -#add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v -add_files -norecurse $design_name\_wrapper.v - -# In the Verilog wrapper, enable configuration for the EEMBC power setup -if { ${eembc_power} } { - set_property verilog_define EEMBC_POWER=1 [current_fileset] -} - -# Run synthesis and implementation -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -# Reporting -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages - -# Export HDF file for SDK flow -file mkdir ./hdf -file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v b/hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v deleted file mode 100644 index 3bbaf5f9b..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v +++ /dev/null @@ -1,209 +0,0 @@ -`timescale 1 ps / 1 ps - -module design_1_wrapper - (ddr3_sdram_addr, - ddr3_sdram_ba, - ddr3_sdram_cas_n, - ddr3_sdram_ck_n, - ddr3_sdram_ck_p, - ddr3_sdram_cke, - ddr3_sdram_cs_n, - ddr3_sdram_dm, - ddr3_sdram_dq, - ddr3_sdram_dqs_n, - ddr3_sdram_dqs_p, - ddr3_sdram_odt, - ddr3_sdram_ras_n, - ddr3_sdram_reset_n, - ddr3_sdram_we_n -`ifdef EEMBC_POWER - , - qspi_flash_io0_io, - qspi_flash_io1_io, - qspi_flash_io2_io, - qspi_flash_io3_io, - qspi_flash_sck_io, - qspi_flash_ss_io - `endif - , - reset, - sys_clock -`ifdef EEMBC_POWER - , - pmod_uart_rxd, - pmod_uart_txd, - pmod_pin -`else - , - usb_uart_rxd, - usb_uart_txd -`endif - ); - output [13:0]ddr3_sdram_addr; - output [2:0]ddr3_sdram_ba; - output ddr3_sdram_cas_n; - output [0:0]ddr3_sdram_ck_n; - output [0:0]ddr3_sdram_ck_p; - output [0:0]ddr3_sdram_cke; - output [0:0]ddr3_sdram_cs_n; - output [1:0]ddr3_sdram_dm; - inout [15:0]ddr3_sdram_dq; - inout [1:0]ddr3_sdram_dqs_n; - inout [1:0]ddr3_sdram_dqs_p; - output [0:0]ddr3_sdram_odt; - output ddr3_sdram_ras_n; - output ddr3_sdram_reset_n; - output ddr3_sdram_we_n; -`ifdef EEMBC_POWER - inout qspi_flash_io0_io; - inout qspi_flash_io1_io; - inout qspi_flash_io2_io; - inout qspi_flash_io3_io; - inout qspi_flash_sck_io; - inout qspi_flash_ss_io; - `endif - input reset; - input sys_clock; -`ifdef EEMBC_POWER - input pmod_uart_rxd; - output pmod_uart_txd; - output pmod_pin; -`else - input usb_uart_rxd; - output usb_uart_txd; -`endif - - - wire [13:0]ddr3_sdram_addr; - wire [2:0]ddr3_sdram_ba; - wire ddr3_sdram_cas_n; - wire [0:0]ddr3_sdram_ck_n; - wire [0:0]ddr3_sdram_ck_p; - wire [0:0]ddr3_sdram_cke; - wire [0:0]ddr3_sdram_cs_n; - wire [1:0]ddr3_sdram_dm; - wire [15:0]ddr3_sdram_dq; - wire [1:0]ddr3_sdram_dqs_n; - wire [1:0]ddr3_sdram_dqs_p; - wire [0:0]ddr3_sdram_odt; - wire ddr3_sdram_ras_n; - wire ddr3_sdram_reset_n; - wire ddr3_sdram_we_n; -`ifdef EEMBC_POWER - wire qspi_flash_io0_i; - wire qspi_flash_io0_io; - wire qspi_flash_io0_o; - wire qspi_flash_io0_t; - wire qspi_flash_io1_i; - wire qspi_flash_io1_io; - wire qspi_flash_io1_o; - wire qspi_flash_io1_t; - wire qspi_flash_io2_i; - wire qspi_flash_io2_io; - wire qspi_flash_io2_o; - wire qspi_flash_io2_t; - wire qspi_flash_io3_i; - wire qspi_flash_io3_io; - wire qspi_flash_io3_o; - wire qspi_flash_io3_t; - wire qspi_flash_sck_i; - wire qspi_flash_sck_io; - wire qspi_flash_sck_o; - wire qspi_flash_sck_t; - wire qspi_flash_ss_i; - wire qspi_flash_ss_io; - wire qspi_flash_ss_o; - wire qspi_flash_ss_t; -`else - wire usb_uart_rxd; - wire usb_uart_txd; -`endif - wire reset; - wire sys_clock; - -`ifdef EEMBC_POWER - IOBUF qspi_flash_io0_iobuf - (.I(qspi_flash_io0_o), - .IO(qspi_flash_io0_io), - .O(qspi_flash_io0_i), - .T(qspi_flash_io0_t)); - IOBUF qspi_flash_io1_iobuf - (.I(qspi_flash_io1_o), - .IO(qspi_flash_io1_io), - .O(qspi_flash_io1_i), - .T(qspi_flash_io1_t)); - IOBUF qspi_flash_io2_iobuf - (.I(qspi_flash_io2_o), - .IO(qspi_flash_io2_io), - .O(qspi_flash_io2_i), - .T(qspi_flash_io2_t)); - IOBUF qspi_flash_io3_iobuf - (.I(qspi_flash_io3_o), - .IO(qspi_flash_io3_io), - .O(qspi_flash_io3_i), - .T(qspi_flash_io3_t)); - IOBUF qspi_flash_sck_iobuf - (.I(qspi_flash_sck_o), - .IO(qspi_flash_sck_io), - .O(qspi_flash_sck_i), - .T(qspi_flash_sck_t)); - IOBUF qspi_flash_ss_iobuf - (.I(qspi_flash_ss_o), - .IO(qspi_flash_ss_io), - .O(qspi_flash_ss_i), - .T(qspi_flash_ss_t)); -`endif - - design_1 design_1_i - (.ddr3_sdram_addr(ddr3_sdram_addr), - .ddr3_sdram_ba(ddr3_sdram_ba), - .ddr3_sdram_cas_n(ddr3_sdram_cas_n), - .ddr3_sdram_ck_n(ddr3_sdram_ck_n), - .ddr3_sdram_ck_p(ddr3_sdram_ck_p), - .ddr3_sdram_cke(ddr3_sdram_cke), - .ddr3_sdram_cs_n(ddr3_sdram_cs_n), - .ddr3_sdram_dm(ddr3_sdram_dm), - .ddr3_sdram_dq(ddr3_sdram_dq), - .ddr3_sdram_dqs_n(ddr3_sdram_dqs_n), - .ddr3_sdram_dqs_p(ddr3_sdram_dqs_p), - .ddr3_sdram_odt(ddr3_sdram_odt), - .ddr3_sdram_ras_n(ddr3_sdram_ras_n), - .ddr3_sdram_reset_n(ddr3_sdram_reset_n), - .ddr3_sdram_we_n(ddr3_sdram_we_n) -`ifdef EEMBC_POWER - , - .qspi_flash_io0_i(qspi_flash_io0_i), - .qspi_flash_io0_o(qspi_flash_io0_o), - .qspi_flash_io0_t(qspi_flash_io0_t), - .qspi_flash_io1_i(qspi_flash_io1_i), - .qspi_flash_io1_o(qspi_flash_io1_o), - .qspi_flash_io1_t(qspi_flash_io1_t), - .qspi_flash_io2_i(qspi_flash_io2_i), - .qspi_flash_io2_o(qspi_flash_io2_o), - .qspi_flash_io2_t(qspi_flash_io2_t), - .qspi_flash_io3_i(qspi_flash_io3_i), - .qspi_flash_io3_o(qspi_flash_io3_o), - .qspi_flash_io3_t(qspi_flash_io3_t), - .qspi_flash_sck_i(qspi_flash_sck_i), - .qspi_flash_sck_o(qspi_flash_sck_o), - .qspi_flash_sck_t(qspi_flash_sck_t), - .qspi_flash_ss_i(qspi_flash_ss_i), - .qspi_flash_ss_o(qspi_flash_ss_o), - .qspi_flash_ss_t(qspi_flash_ss_t) - `endif - , - .reset(reset), - .sys_clock(sys_clock) -`ifdef EEMBC_POWER - , - .pmod_uart_rxd(pmod_uart_rxd), - .pmod_uart_txd(pmod_uart_txd), - .pmod_pin(pmod_pin) -`else - , - .usb_uart_rxd(usb_uart_rxd), - .usb_uart_txd(usb_uart_txd) -`endif - - ); -endmodule diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc deleted file mode 100644 index 321279b70..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc +++ /dev/null @@ -1,4 +0,0 @@ -# AXI GPIO controlled pin on Pmod Header JD - -# Output pin, PMOD D pin 3 (JD4), IO_L13N_T2_MRCC_35, F4, Blue cable -set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { pmod_pin }]; diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc deleted file mode 100644 index 6019da47b..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc +++ /dev/null @@ -1,13 +0,0 @@ -# -# See also -# https://github.com/Digilent/digilent-xdc/blob/master/Arty-A7-100-Master.xdc -# - -set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] - -# Quad SPI Flash -set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_ss_io }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs -set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io0_io }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] -set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io1_io }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] -set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io2_io }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] -set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io3_io }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc deleted file mode 100644 index 2cf181a20..000000000 --- a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc +++ /dev/null @@ -1,8 +0,0 @@ -# Expose UART Interface on Pmod Header JA -# You may need https://www.sparkfun.com/products/9873 - -# RX uart, PMOD A pin 2 (JA2), IO_L4P_T0_15, B11, BROWN cable -set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { pmod_uart_rxd }]; - -# TX uart, PMOD A pin 3 (JA3), IO_L4N_T0_15, A11, RED cable -set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { pmod_uart_txd }]; diff --git a/hls4ml/templates/vivado_accelerator/build_lib.sh b/hls4ml/templates/vivado_accelerator/build_lib.sh deleted file mode 100644 index 0d0bf156e..000000000 --- a/hls4ml/templates/vivado_accelerator/build_lib.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -CC=g++ -if [[ "$OSTYPE" == "linux-gnu" ]]; then - CFLAGS="-O3 -fPIC -std=c++11 -fno-gnu-unique" -elif [[ "$OSTYPE" == "darwin"* ]]; then - CFLAGS="-O3 -fPIC -std=c++11" -fi -INCFLAGS="-Ifirmware/ap_types/" -PROJECT=myproject -LIB_STAMP=mystamp - -${CC} ${CFLAGS} ${INCFLAGS} -c firmware/${PROJECT}.cpp -o ${PROJECT}.o -${CC} ${CFLAGS} ${INCFLAGS} -c firmware/${PROJECT}_axi.cpp -o ${PROJECT}_axi.o -${CC} ${CFLAGS} ${INCFLAGS} -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o -${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_axi.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so -rm -f *.o - diff --git a/hls4ml/templates/vivado_accelerator/myproject_axi.cpp b/hls4ml/templates/vivado_accelerator/myproject_axi.cpp deleted file mode 100644 index ab61fb4fd..000000000 --- a/hls4ml/templates/vivado_accelerator/myproject_axi.cpp +++ /dev/null @@ -1,20 +0,0 @@ -//hls-fpga-machine-learning insert include - -void myproject( - input_axi_t in[N_IN], - output_axi_t out[N_OUT] - ){ - - //hls-fpga-machine-learning insert interface - - unsigned short in_size = 0; - unsigned short out_size = 0; - - //hls-fpga-machine-learning insert local vars - - //hls-fpga-machine-learning insert enqueue - - //hls-fpga-machine-learning insert call - - //hls-fpga-machine-learning insert dequeue -} diff --git a/hls4ml/templates/vivado_accelerator/myproject_axi.h b/hls4ml/templates/vivado_accelerator/myproject_axi.h deleted file mode 100644 index fe3dbc5cd..000000000 --- a/hls4ml/templates/vivado_accelerator/myproject_axi.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MYPROJECT_AXI_H_ -#define MYPROJECT_AXI_H_ - -#include -//hls-fpga-machine-learning insert include - -//hls-fpga-machine-learning insert definitions - -void myproject( - input_axi_t in[N_IN], - output_axi_t out[N_OUT] - ); -#endif diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile deleted file mode 100644 index 03ab9b8de..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -DESIGN := design_1 - -help: - @echo "INFO: make to show targets" -.PHONY: help - ---setup: - xsct ./setup.tcl $(DESIGN) -.PHONY: --setup - -sdk: --setup - rm -f $(DESIGN)_standalone/src/helloworld.c - cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c - cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h -.PHONY: sdk - -gui: - xsdk --workspace . & -.PHONY: gui - -clean: - rm -rf $(DESIGN)_platform - rm -rf $(DESIGN)_standalone - rm -rf $(DESIGN)_standalone_bsp - rm -rf RemoteSystemsTempFiles - rm -rf .Xil - rm -rf .metadata - rm -f *.log -.PHONY: clean - -ultraclean: clean - rm -rf hdf/*.hdf -.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c deleted file mode 100644 index 7dd2be22a..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c +++ /dev/null @@ -1,262 +0,0 @@ -/** - * - * Set Heap Size in ldscript.ld to 0x1000000 (16MB) - * - */ - -#include "xmyproject_axi.h" /* TODO: design-dependent name */ -#include "stdio.h" /* PRINTF */ -#include "unistd.h" /* sleep */ -#include "stdlib.h" -#include "malloc.h" -#include "assert.h" -#include "xil_io.h" /* peripheral read/write wrappers */ -#include "xtime_l.h" /* to measure performance of the system */ -#include "platform.h" /* platform init/cleanup functions */ -#include "xil_cache.h" /* enable/disable caches etc */ -#include "xil_printf.h" /* UART debug print functions */ -#include "xparameters.h" /* peripherals base addresses */ - -#include "data.h" - -//#define __DEBUG__ - -#define MAX_PRINT_ELEMENTS (16) - -#define PRINTF printf - -const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; -const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; - -#if 1 -/* Accelerator verification */ -#define REFERENCE_OUTPUTS data_y_hls_outputs -#else -/* Accelerator validation */ -#define REFERENCE_OUTPUTS data_y_outputs -//#define REFERENCE_OUTPUTS data_y_keras_outputs -#endif - -unsigned get_max(float *data, unsigned n_elements) { - float max_value = 0.0; - unsigned max_index = 0; - for (unsigned i = 0; i < n_elements; i++) - if (data[i] >= max_value) { - max_index = i; - max_value = data[i]; - } - return max_index; -} - -float *inputs_mem = NULL; -float *outputs_mem = NULL; -float *reference_mem = NULL; - -/* Accelerator configuration */ -XMyproject_axi accelerator; /* TODO: design-dependent name */ -XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ - -/* Accelerator initialization routine */ -void init_accelerators() { - PRINTF("INFO: Initializing accelerator\r\n"); - accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ - if (accelerator_cfg) { - int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ - if (status != XST_SUCCESS) { - PRINTF("ERROR: Initializing accelerator\r\n"); - } - } -} - -/* Reference implementation of the accelerator in software */ -int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { -#ifdef __DEBUG__ - PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); -#endif - /* See data.h for inputs and outputs */ - for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { - sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; - } - return 0; -} - -/* Profiling function */ -double get_elapsed_time(XTime start, XTime stop) { - return 1.0 * (stop - start) / (COUNTS_PER_SECOND); -} - -/* Dump data to the console */ -void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { - PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); - /* Print at most MAX_PRINT_ELEMENTS */ - for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { - PRINTF("INFO: [%u] ", i); - for (unsigned j = 0; j < feature_count; j++) { - unsigned index = i * feature_count + j; - PRINTF("%f ", data[index]); - } - PRINTF("\r\n"); - } -} - -/* The top of the hill :-) */ -int main(int argc, char** argv) { - - XTime start, stop; - double calibration_time; - double sw_elapsed = 0; - double hw_elapsed = 0; - double cache_elapsed = 0; - unsigned hw_errors; - - char __attribute__ ((unused)) dummy; /* dummy input */ - - /* Initialize platform (uart and caches) */ - init_platform(); - - PRINTF("\r\n"); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ - PRINTF("INFO: ==================================================\r\n"); - - init_accelerators(); - - inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); - outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - - /* Calibration */ - XTime_GetTime(&start); - sleep(1); - XTime_GetTime(&stop); - calibration_time = get_elapsed_time(start, stop); - PRINTF("INFO: Time calibration for one second (%lf sec)\r\n", calibration_time); - - /* Initialize memory */ - PRINTF("INFO: Initialize memory\r\n"); - PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ - PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); - PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); - PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); - PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - - // Set Heap Size in ldscript.ld to 0x1000000 (16MB) - //malloc_stats(); - - for (int i = 0; i < INPUT_N_ELEMENTS; i++) { - inputs_mem[i] = data_X_inputs[i]; - } - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - outputs_mem[i] = 0x0; - } - - /* ****** SW REFERENCE ****** */ - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Start SW reference implementation\r\n"); - XTime_GetTime(&start); - sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); - XTime_GetTime(&stop); - sw_elapsed = get_elapsed_time(start, stop); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - //PRINTF("INFO:"); - - /* ****** HW ACCELERATOR ****** */ - PRINTF("INFO: Start HW accelerator\r\n"); - - XTime_GetTime(&start); - Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - XTime_GetTime(&stop); - cache_elapsed = get_elapsed_time(start, stop); - - for (unsigned j = 0; j < N_SAMPLES; j++) { - float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; - float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; - - /* Configure the accelerator */ - XTime_GetTime(&start); - XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ - XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ - - XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ - - /* Polling */ - while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ - - /* Get error status */ - //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ - XTime_GetTime(&stop); - hw_elapsed += get_elapsed_time(start, stop); - } - - XTime_GetTime(&start); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - XTime_GetTime(&stop); - cache_elapsed += get_elapsed_time(start, stop); - - PRINTF("INFO: HW accelerator done!\r\n"); - - /* ****** VALIDATION ****** */ - PRINTF("INFO: ================== Verification ==================\r\n"); -#ifdef __DEBUG__ - PRINTF("INFO: Dump data\r\n"); - dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); - dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); - dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); -#endif - -#ifdef __DEBUG__ - PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); -#endif - PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); - PRINTF("INFO: - total %f sec\r\n", hw_elapsed); - PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", hw_elapsed / (N_SAMPLES), (hw_elapsed*1000.0) / (N_SAMPLES)); - PRINTF("INFO: Cache flush time: %f sec\r\n", cache_elapsed); -#ifdef __DEBUG__ - PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); -#endif - - hw_errors = 0; -#if 1 - /* Accelerator verification */ - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - if (outputs_mem[i] != reference_mem[i]) { - PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); - hw_errors++; - } - } - PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); - if (hw_errors > 0) - PRINTF("INFO: Verification: FAIL\r\n"); - else - PRINTF("INFO: Verification: PASS!\r\n"); -#else - /* Accelerator validation */ - for (unsigned s = 0; s < N_SAMPLES; s++) { - unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - if (hw_digit != ref_digit) { -#ifdef __DEBUG__ - PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); -#endif - hw_errors++; - } - } - float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; - float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); - PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); - PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); - PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); -#endif - PRINTF("INFO: ==================================================\r\n"); - - cleanup_platform(); - - return 0; -} - - diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl deleted file mode 100644 index 5e9e92d50..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl +++ /dev/null @@ -1,14 +0,0 @@ -# See -# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html - -setws . -if { $::argc == 1 } { - set myproject [lindex $::argv 0] - createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf - createapp -name ${myproject}\_standalone -app {Hello World} -proc ps7_cortexa9_0 -hwproject ${myproject}\_platform -os standalone - configapp -app ${myproject}\_standalone build-config release - configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} - configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} - projects -build - #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} -} diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py deleted file mode 100644 index 4adb187ab..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py +++ /dev/null @@ -1,75 +0,0 @@ -from pynq import DefaultHierarchy, DefaultIP, allocate -from pynq import Overlay -from datetime import datetime -import pynq.lib.dma -import numpy as np - - -class NeuralNetworkOverlay(Overlay): - def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, - device=None): - super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) - self.sendchannel = self.hier_0.axi_dma_0.sendchannel - self.recvchannel = self.hier_0.axi_dma_0.recvchannel - self.input_buffer = allocate(shape=x_shape, dtype=dtype) - self.output_buffer = allocate(shape=y_shape, dtype=dtype) - - def _print_dt(self, timea, timeb, N): - dt = (timeb - timea) - dts = dt.seconds + dt.microseconds * 10 ** -6 - rate = N / dts - print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) - return dts, rate - - def predict(self, X, debug=False, profile=False, encode=None, decode=None): - """ - Obtain the predictions of the NN implemented in the FPGA. - Parameters: - - X : the input vector. Should be numpy ndarray. - - dtype : the data type of the elements of the input/output vectors. - Note: it should be set depending on the interface of the accelerator; if it uses 'float' - types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. - Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot - any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` - doc for more info). - In this case the encoding/decoding has to be computed by the PS. For example for - 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode - 'float' -> 'ap_fixed<16,6>': - ``` - def encode(xi): - return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) - def decode(yi): - return yi * 2**-10 - encode_v = np.vectorize(encode) # to apply them element-wise - decode_v = np.vectorize(decode) - ``` - - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. - - encode/decode: function pointers. See `dtype` section for more information. - - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to - the namesake parameter. - """ - if profile: - timea = datetime.now() - if encode is not None: - X = encode(X) - self.input_buffer[:] = X - self.sendchannel.transfer(self.input_buffer) - self.recvchannel.transfer(self.output_buffer) - if debug: - print("Transfer OK") - self.sendchannel.wait() - if debug: - print("Send OK") - self.recvchannel.wait() - if debug: - print("Receive OK") - # result = self.output_buffer.copy() - if decode is not None: - self.output_buffer = decode(self.output_buffer) - - if profile: - timeb = datetime.now() - dts, rate = self._print_dt(timea, timeb, len(X)) - return self.output_buffer, dts, rate - else: - return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl deleted file mode 100644 index 4f6847ae7..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl +++ /dev/null @@ -1,26 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force - -set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -# Create Block Designer design -create_bd_design "design_1" -create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 -apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/${myproject}_axi_0/s_axi_AXILiteS} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins ${myproject}_axi_0/s_axi_AXILiteS] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl deleted file mode 100644 index 6de05e15a..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl +++ /dev/null @@ -1,88 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -# Project names -set project_name "project_1" -set design_name "design_1" -set hls_solution_name "solution1" -set ps_name "processing_system7_0" -set acc_name "${myproject}_axi_0" -set part_name "xc7z020clg400-1" -set board_name "www.digilentinc.com:pynq-z1:part0:1.0" - -# Set board and chip part names -create_project ${project_name} ${myproject}_vivado_accelerator -part ${part_name} -force -set_property board_part ${board_name} [current_project] - -# Create block design -create_bd_design ${design_name} - -# Setup IP repo -#set_property ip_repo_paths ${myproject}_prj [current_project] -set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] -update_ip_catalog - -# Create and setup PS -create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 ${ps_name} -apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells ${ps_name}] -set_property -dict [list CONFIG.PCW_USE_S_AXI_GP0 {1} CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_IRQ_F2P_INTR {1}] [get_bd_cells ${ps_name}] - -# Create accelerator -create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 ${acc_name} - -# Wiring -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {Auto} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master {/myproject_axi_0/m_axi_IN_BUS} \ - Slave {/processing_system7_0/S_AXI_GP0} \ - intc_ip {Auto} \ - master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_GP0] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {Auto} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master {/processing_system7_0/M_AXI_GP0} \ - Slave {/myproject_axi_0/s_axi_CTRL_BUS} \ - intc_ip {New AXI Interconnect} \ - master_apm {0}} [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ - Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ - Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ - Master {/myproject_axi_0/m_axi_OUT_BUS} \ - Slave {/processing_system7_0/S_AXI_GP0} \ - intc_ip {/axi_smc} \ - master_apm {0}} [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] - -# Wiring interrupt signal -connect_bd_net [get_bd_pins myproject_axi_0/interrupt] [get_bd_pins processing_system7_0/IRQ_F2P] - -# Top level wrapper -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top -add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v - -# Memory mapping -delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_IOP] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] -delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_IOP] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] - -# Run synthesis and implementation -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -# Reporting -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages - -# Export HDF file for SDK flow -file mkdir ./hdf -file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl deleted file mode 100644 index f5901c7f3..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl +++ /dev/null @@ -1,59 +0,0 @@ -#@todo: try to remove startgroup and endgroup and see if it work -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force - -set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -create_bd_design "design_1" - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 -endgroup - -apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] - -startgroup -set_property -dict [list CONFIG.PCW_USE_S_AXI_HP0 {1}] [get_bd_cells processing_system7_0] -endgroup - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 -endgroup - -set_property -dict [list CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] -set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] - -startgroup -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_HP0] -endgroup - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {/axi_mem_intercon} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -endgroup - -connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] -connect_bd_intf_net [get_bd_intf_pins ${myproject}_axi_0/out_r] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] - -apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/processing_system7_0/FCLK_CLK0 (100 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] - -group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top - -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile deleted file mode 100644 index 03ab9b8de..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -DESIGN := design_1 - -help: - @echo "INFO: make to show targets" -.PHONY: help - ---setup: - xsct ./setup.tcl $(DESIGN) -.PHONY: --setup - -sdk: --setup - rm -f $(DESIGN)_standalone/src/helloworld.c - cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c - cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h -.PHONY: sdk - -gui: - xsdk --workspace . & -.PHONY: gui - -clean: - rm -rf $(DESIGN)_platform - rm -rf $(DESIGN)_standalone - rm -rf $(DESIGN)_standalone_bsp - rm -rf RemoteSystemsTempFiles - rm -rf .Xil - rm -rf .metadata - rm -f *.log -.PHONY: clean - -ultraclean: clean - rm -rf hdf/*.hdf -.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c deleted file mode 100644 index 7dd2be22a..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c +++ /dev/null @@ -1,262 +0,0 @@ -/** - * - * Set Heap Size in ldscript.ld to 0x1000000 (16MB) - * - */ - -#include "xmyproject_axi.h" /* TODO: design-dependent name */ -#include "stdio.h" /* PRINTF */ -#include "unistd.h" /* sleep */ -#include "stdlib.h" -#include "malloc.h" -#include "assert.h" -#include "xil_io.h" /* peripheral read/write wrappers */ -#include "xtime_l.h" /* to measure performance of the system */ -#include "platform.h" /* platform init/cleanup functions */ -#include "xil_cache.h" /* enable/disable caches etc */ -#include "xil_printf.h" /* UART debug print functions */ -#include "xparameters.h" /* peripherals base addresses */ - -#include "data.h" - -//#define __DEBUG__ - -#define MAX_PRINT_ELEMENTS (16) - -#define PRINTF printf - -const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; -const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; - -#if 1 -/* Accelerator verification */ -#define REFERENCE_OUTPUTS data_y_hls_outputs -#else -/* Accelerator validation */ -#define REFERENCE_OUTPUTS data_y_outputs -//#define REFERENCE_OUTPUTS data_y_keras_outputs -#endif - -unsigned get_max(float *data, unsigned n_elements) { - float max_value = 0.0; - unsigned max_index = 0; - for (unsigned i = 0; i < n_elements; i++) - if (data[i] >= max_value) { - max_index = i; - max_value = data[i]; - } - return max_index; -} - -float *inputs_mem = NULL; -float *outputs_mem = NULL; -float *reference_mem = NULL; - -/* Accelerator configuration */ -XMyproject_axi accelerator; /* TODO: design-dependent name */ -XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ - -/* Accelerator initialization routine */ -void init_accelerators() { - PRINTF("INFO: Initializing accelerator\r\n"); - accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ - if (accelerator_cfg) { - int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ - if (status != XST_SUCCESS) { - PRINTF("ERROR: Initializing accelerator\r\n"); - } - } -} - -/* Reference implementation of the accelerator in software */ -int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { -#ifdef __DEBUG__ - PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); -#endif - /* See data.h for inputs and outputs */ - for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { - sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; - } - return 0; -} - -/* Profiling function */ -double get_elapsed_time(XTime start, XTime stop) { - return 1.0 * (stop - start) / (COUNTS_PER_SECOND); -} - -/* Dump data to the console */ -void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { - PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); - /* Print at most MAX_PRINT_ELEMENTS */ - for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { - PRINTF("INFO: [%u] ", i); - for (unsigned j = 0; j < feature_count; j++) { - unsigned index = i * feature_count + j; - PRINTF("%f ", data[index]); - } - PRINTF("\r\n"); - } -} - -/* The top of the hill :-) */ -int main(int argc, char** argv) { - - XTime start, stop; - double calibration_time; - double sw_elapsed = 0; - double hw_elapsed = 0; - double cache_elapsed = 0; - unsigned hw_errors; - - char __attribute__ ((unused)) dummy; /* dummy input */ - - /* Initialize platform (uart and caches) */ - init_platform(); - - PRINTF("\r\n"); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ - PRINTF("INFO: ==================================================\r\n"); - - init_accelerators(); - - inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); - outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - - /* Calibration */ - XTime_GetTime(&start); - sleep(1); - XTime_GetTime(&stop); - calibration_time = get_elapsed_time(start, stop); - PRINTF("INFO: Time calibration for one second (%lf sec)\r\n", calibration_time); - - /* Initialize memory */ - PRINTF("INFO: Initialize memory\r\n"); - PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ - PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); - PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); - PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); - PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - - // Set Heap Size in ldscript.ld to 0x1000000 (16MB) - //malloc_stats(); - - for (int i = 0; i < INPUT_N_ELEMENTS; i++) { - inputs_mem[i] = data_X_inputs[i]; - } - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - outputs_mem[i] = 0x0; - } - - /* ****** SW REFERENCE ****** */ - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Start SW reference implementation\r\n"); - XTime_GetTime(&start); - sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); - XTime_GetTime(&stop); - sw_elapsed = get_elapsed_time(start, stop); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - //PRINTF("INFO:"); - - /* ****** HW ACCELERATOR ****** */ - PRINTF("INFO: Start HW accelerator\r\n"); - - XTime_GetTime(&start); - Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - XTime_GetTime(&stop); - cache_elapsed = get_elapsed_time(start, stop); - - for (unsigned j = 0; j < N_SAMPLES; j++) { - float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; - float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; - - /* Configure the accelerator */ - XTime_GetTime(&start); - XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ - XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ - - XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ - - /* Polling */ - while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ - - /* Get error status */ - //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ - XTime_GetTime(&stop); - hw_elapsed += get_elapsed_time(start, stop); - } - - XTime_GetTime(&start); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - XTime_GetTime(&stop); - cache_elapsed += get_elapsed_time(start, stop); - - PRINTF("INFO: HW accelerator done!\r\n"); - - /* ****** VALIDATION ****** */ - PRINTF("INFO: ================== Verification ==================\r\n"); -#ifdef __DEBUG__ - PRINTF("INFO: Dump data\r\n"); - dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); - dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); - dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); -#endif - -#ifdef __DEBUG__ - PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); -#endif - PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); - PRINTF("INFO: - total %f sec\r\n", hw_elapsed); - PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", hw_elapsed / (N_SAMPLES), (hw_elapsed*1000.0) / (N_SAMPLES)); - PRINTF("INFO: Cache flush time: %f sec\r\n", cache_elapsed); -#ifdef __DEBUG__ - PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); -#endif - - hw_errors = 0; -#if 1 - /* Accelerator verification */ - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - if (outputs_mem[i] != reference_mem[i]) { - PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); - hw_errors++; - } - } - PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); - if (hw_errors > 0) - PRINTF("INFO: Verification: FAIL\r\n"); - else - PRINTF("INFO: Verification: PASS!\r\n"); -#else - /* Accelerator validation */ - for (unsigned s = 0; s < N_SAMPLES; s++) { - unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - if (hw_digit != ref_digit) { -#ifdef __DEBUG__ - PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); -#endif - hw_errors++; - } - } - float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; - float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); - PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); - PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); - PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); -#endif - PRINTF("INFO: ==================================================\r\n"); - - cleanup_platform(); - - return 0; -} - - diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl deleted file mode 100644 index 5e9e92d50..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl +++ /dev/null @@ -1,14 +0,0 @@ -# See -# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html - -setws . -if { $::argc == 1 } { - set myproject [lindex $::argv 0] - createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf - createapp -name ${myproject}\_standalone -app {Hello World} -proc ps7_cortexa9_0 -hwproject ${myproject}\_platform -os standalone - configapp -app ${myproject}\_standalone build-config release - configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} - configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} - projects -build - #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} -} diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py deleted file mode 100644 index 4adb187ab..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py +++ /dev/null @@ -1,75 +0,0 @@ -from pynq import DefaultHierarchy, DefaultIP, allocate -from pynq import Overlay -from datetime import datetime -import pynq.lib.dma -import numpy as np - - -class NeuralNetworkOverlay(Overlay): - def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, - device=None): - super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) - self.sendchannel = self.hier_0.axi_dma_0.sendchannel - self.recvchannel = self.hier_0.axi_dma_0.recvchannel - self.input_buffer = allocate(shape=x_shape, dtype=dtype) - self.output_buffer = allocate(shape=y_shape, dtype=dtype) - - def _print_dt(self, timea, timeb, N): - dt = (timeb - timea) - dts = dt.seconds + dt.microseconds * 10 ** -6 - rate = N / dts - print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) - return dts, rate - - def predict(self, X, debug=False, profile=False, encode=None, decode=None): - """ - Obtain the predictions of the NN implemented in the FPGA. - Parameters: - - X : the input vector. Should be numpy ndarray. - - dtype : the data type of the elements of the input/output vectors. - Note: it should be set depending on the interface of the accelerator; if it uses 'float' - types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. - Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot - any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` - doc for more info). - In this case the encoding/decoding has to be computed by the PS. For example for - 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode - 'float' -> 'ap_fixed<16,6>': - ``` - def encode(xi): - return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) - def decode(yi): - return yi * 2**-10 - encode_v = np.vectorize(encode) # to apply them element-wise - decode_v = np.vectorize(decode) - ``` - - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. - - encode/decode: function pointers. See `dtype` section for more information. - - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to - the namesake parameter. - """ - if profile: - timea = datetime.now() - if encode is not None: - X = encode(X) - self.input_buffer[:] = X - self.sendchannel.transfer(self.input_buffer) - self.recvchannel.transfer(self.output_buffer) - if debug: - print("Transfer OK") - self.sendchannel.wait() - if debug: - print("Send OK") - self.recvchannel.wait() - if debug: - print("Receive OK") - # result = self.output_buffer.copy() - if decode is not None: - self.output_buffer = decode(self.output_buffer) - - if profile: - timeb = datetime.now() - dts, rate = self._print_dt(timea, timeb, len(X)) - return self.output_buffer, dts, rate - else: - return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl deleted file mode 100644 index 4f6847ae7..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl +++ /dev/null @@ -1,26 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force - -set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -# Create Block Designer design -create_bd_design "design_1" -create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 -apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/${myproject}_axi_0/s_axi_AXILiteS} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins ${myproject}_axi_0/s_axi_AXILiteS] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl deleted file mode 100644 index b3c3ba9c0..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl +++ /dev/null @@ -1,88 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -# Project names -set project_name "project_1" -set design_name "design_1" -set hls_solution_name "solution1" -set ps_name "processing_system7_0" -set acc_name "${myproject}_axi_0" -set part_name "xc7z020clg400-1" -set board_name "tul.com.tw:pynq-z2:part0:1.0" - -# Set board and chip part names -create_project ${project_name} ${myproject}_vivado_accelerator -part ${part_name} -force -set_property board_part ${board_name} [current_project] - -# Create block design -create_bd_design ${design_name} - -# Setup IP repo -#set_property ip_repo_paths ${myproject}_prj [current_project] -set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] -update_ip_catalog - -# Create and setup PS -create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 ${ps_name} -apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells ${ps_name}] -set_property -dict [list CONFIG.PCW_USE_S_AXI_GP0 {1} CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_IRQ_F2P_INTR {1}] [get_bd_cells ${ps_name}] - -# Create accelerator -create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 ${acc_name} - -# Wiring -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {Auto} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master {/myproject_axi_0/m_axi_IN_BUS} \ - Slave {/processing_system7_0/S_AXI_GP0} \ - intc_ip {Auto} \ - master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_GP0] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {Auto} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master {/processing_system7_0/M_AXI_GP0} \ - Slave {/myproject_axi_0/s_axi_CTRL_BUS} \ - intc_ip {New AXI Interconnect} \ - master_apm {0}} [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ - Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ - Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ - Master {/myproject_axi_0/m_axi_OUT_BUS} \ - Slave {/processing_system7_0/S_AXI_GP0} \ - intc_ip {/axi_smc} \ - master_apm {0}} [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] - -# Wiring interrupt signal -connect_bd_net [get_bd_pins myproject_axi_0/interrupt] [get_bd_pins processing_system7_0/IRQ_F2P] - -# Top level wrapper -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top -add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v - -# Memory mapping -delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_IOP] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] -delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_IOP] -delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] - -# Run synthesis and implementation -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -# Reporting -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages - -# Export HDF file for SDK flow -file mkdir ./hdf -file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl deleted file mode 100644 index f5901c7f3..000000000 --- a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl +++ /dev/null @@ -1,59 +0,0 @@ -#@todo: try to remove startgroup and endgroup and see if it work -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force - -set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -create_bd_design "design_1" - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 -endgroup - -apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] - -startgroup -set_property -dict [list CONFIG.PCW_USE_S_AXI_HP0 {1}] [get_bd_cells processing_system7_0] -endgroup - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 -endgroup - -set_property -dict [list CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] -set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] - -startgroup -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_HP0] -endgroup - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {/axi_mem_intercon} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -endgroup - -connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] -connect_bd_intf_net [get_bd_intf_pins ${myproject}_axi_0/out_r] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] - -apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/processing_system7_0/FCLK_CLK0 (100 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] - -group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top - -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c deleted file mode 100644 index 8a46df8bd..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "xil_printf.h" - -int main(void) { - xil_printf("Hello world!\r\n"); - return 0; -} diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h deleted file mode 100644 index 8a46df8bd..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "xil_printf.h" - -int main(void) { - xil_printf("Hello world!\r\n"); - return 0; -} diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile deleted file mode 100644 index 03ab9b8de..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -DESIGN := design_1 - -help: - @echo "INFO: make to show targets" -.PHONY: help - ---setup: - xsct ./setup.tcl $(DESIGN) -.PHONY: --setup - -sdk: --setup - rm -f $(DESIGN)_standalone/src/helloworld.c - cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c - cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h -.PHONY: sdk - -gui: - xsdk --workspace . & -.PHONY: gui - -clean: - rm -rf $(DESIGN)_platform - rm -rf $(DESIGN)_standalone - rm -rf $(DESIGN)_standalone_bsp - rm -rf RemoteSystemsTempFiles - rm -rf .Xil - rm -rf .metadata - rm -f *.log -.PHONY: clean - -ultraclean: clean - rm -rf hdf/*.hdf -.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c deleted file mode 100644 index 7dd2be22a..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c +++ /dev/null @@ -1,262 +0,0 @@ -/** - * - * Set Heap Size in ldscript.ld to 0x1000000 (16MB) - * - */ - -#include "xmyproject_axi.h" /* TODO: design-dependent name */ -#include "stdio.h" /* PRINTF */ -#include "unistd.h" /* sleep */ -#include "stdlib.h" -#include "malloc.h" -#include "assert.h" -#include "xil_io.h" /* peripheral read/write wrappers */ -#include "xtime_l.h" /* to measure performance of the system */ -#include "platform.h" /* platform init/cleanup functions */ -#include "xil_cache.h" /* enable/disable caches etc */ -#include "xil_printf.h" /* UART debug print functions */ -#include "xparameters.h" /* peripherals base addresses */ - -#include "data.h" - -//#define __DEBUG__ - -#define MAX_PRINT_ELEMENTS (16) - -#define PRINTF printf - -const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; -const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; - -#if 1 -/* Accelerator verification */ -#define REFERENCE_OUTPUTS data_y_hls_outputs -#else -/* Accelerator validation */ -#define REFERENCE_OUTPUTS data_y_outputs -//#define REFERENCE_OUTPUTS data_y_keras_outputs -#endif - -unsigned get_max(float *data, unsigned n_elements) { - float max_value = 0.0; - unsigned max_index = 0; - for (unsigned i = 0; i < n_elements; i++) - if (data[i] >= max_value) { - max_index = i; - max_value = data[i]; - } - return max_index; -} - -float *inputs_mem = NULL; -float *outputs_mem = NULL; -float *reference_mem = NULL; - -/* Accelerator configuration */ -XMyproject_axi accelerator; /* TODO: design-dependent name */ -XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ - -/* Accelerator initialization routine */ -void init_accelerators() { - PRINTF("INFO: Initializing accelerator\r\n"); - accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ - if (accelerator_cfg) { - int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ - if (status != XST_SUCCESS) { - PRINTF("ERROR: Initializing accelerator\r\n"); - } - } -} - -/* Reference implementation of the accelerator in software */ -int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { -#ifdef __DEBUG__ - PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); -#endif - /* See data.h for inputs and outputs */ - for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { - sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; - } - return 0; -} - -/* Profiling function */ -double get_elapsed_time(XTime start, XTime stop) { - return 1.0 * (stop - start) / (COUNTS_PER_SECOND); -} - -/* Dump data to the console */ -void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { - PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); - /* Print at most MAX_PRINT_ELEMENTS */ - for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { - PRINTF("INFO: [%u] ", i); - for (unsigned j = 0; j < feature_count; j++) { - unsigned index = i * feature_count + j; - PRINTF("%f ", data[index]); - } - PRINTF("\r\n"); - } -} - -/* The top of the hill :-) */ -int main(int argc, char** argv) { - - XTime start, stop; - double calibration_time; - double sw_elapsed = 0; - double hw_elapsed = 0; - double cache_elapsed = 0; - unsigned hw_errors; - - char __attribute__ ((unused)) dummy; /* dummy input */ - - /* Initialize platform (uart and caches) */ - init_platform(); - - PRINTF("\r\n"); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ - PRINTF("INFO: ==================================================\r\n"); - - init_accelerators(); - - inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); - outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - - /* Calibration */ - XTime_GetTime(&start); - sleep(1); - XTime_GetTime(&stop); - calibration_time = get_elapsed_time(start, stop); - PRINTF("INFO: Time calibration for one second (%lf sec)\r\n", calibration_time); - - /* Initialize memory */ - PRINTF("INFO: Initialize memory\r\n"); - PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ - PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); - PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); - PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); - PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - - // Set Heap Size in ldscript.ld to 0x1000000 (16MB) - //malloc_stats(); - - for (int i = 0; i < INPUT_N_ELEMENTS; i++) { - inputs_mem[i] = data_X_inputs[i]; - } - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - outputs_mem[i] = 0x0; - } - - /* ****** SW REFERENCE ****** */ - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Start SW reference implementation\r\n"); - XTime_GetTime(&start); - sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); - XTime_GetTime(&stop); - sw_elapsed = get_elapsed_time(start, stop); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - //PRINTF("INFO:"); - - /* ****** HW ACCELERATOR ****** */ - PRINTF("INFO: Start HW accelerator\r\n"); - - XTime_GetTime(&start); - Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - XTime_GetTime(&stop); - cache_elapsed = get_elapsed_time(start, stop); - - for (unsigned j = 0; j < N_SAMPLES; j++) { - float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; - float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; - - /* Configure the accelerator */ - XTime_GetTime(&start); - XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ - XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ - - XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ - - /* Polling */ - while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ - - /* Get error status */ - //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ - XTime_GetTime(&stop); - hw_elapsed += get_elapsed_time(start, stop); - } - - XTime_GetTime(&start); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - XTime_GetTime(&stop); - cache_elapsed += get_elapsed_time(start, stop); - - PRINTF("INFO: HW accelerator done!\r\n"); - - /* ****** VALIDATION ****** */ - PRINTF("INFO: ================== Verification ==================\r\n"); -#ifdef __DEBUG__ - PRINTF("INFO: Dump data\r\n"); - dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); - dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); - dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); -#endif - -#ifdef __DEBUG__ - PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); -#endif - PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); - PRINTF("INFO: - total %f sec\r\n", hw_elapsed); - PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", hw_elapsed / (N_SAMPLES), (hw_elapsed*1000.0) / (N_SAMPLES)); - PRINTF("INFO: Cache flush time: %f sec\r\n", cache_elapsed); -#ifdef __DEBUG__ - PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); -#endif - - hw_errors = 0; -#if 1 - /* Accelerator verification */ - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - if (outputs_mem[i] != reference_mem[i]) { - PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); - hw_errors++; - } - } - PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); - if (hw_errors > 0) - PRINTF("INFO: Verification: FAIL\r\n"); - else - PRINTF("INFO: Verification: PASS!\r\n"); -#else - /* Accelerator validation */ - for (unsigned s = 0; s < N_SAMPLES; s++) { - unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - if (hw_digit != ref_digit) { -#ifdef __DEBUG__ - PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); -#endif - hw_errors++; - } - } - float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; - float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); - PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); - PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); - PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); -#endif - PRINTF("INFO: ==================================================\r\n"); - - cleanup_platform(); - - return 0; -} - - diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl deleted file mode 100644 index ea386d428..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl +++ /dev/null @@ -1,18 +0,0 @@ -# See -# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html - -setws . -if { $::argc == 1 } { - set myproject [lindex $::argv 0] - createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf - createapp -name ${myproject}\_standalone -app {Hello World} -proc psu_cortexa53_0 -hwproject ${myproject}\_platform -os standalone -arch 64 - configbsp -bsp ${myproject}\_standalone_bsp stdin psu_uart_1 - configbsp -bsp ${myproject}\_standalone_bsp stdout psu_uart_1 - updatemss -mss ${myproject}\_standalone_bsp/system.mss - regenbsp -bsp ${myproject}\_standalone_bsp - configapp -app ${myproject}\_standalone build-config release - configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} - configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} - projects -build - #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} -} diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py deleted file mode 100644 index 4adb187ab..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py +++ /dev/null @@ -1,75 +0,0 @@ -from pynq import DefaultHierarchy, DefaultIP, allocate -from pynq import Overlay -from datetime import datetime -import pynq.lib.dma -import numpy as np - - -class NeuralNetworkOverlay(Overlay): - def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, - device=None): - super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) - self.sendchannel = self.hier_0.axi_dma_0.sendchannel - self.recvchannel = self.hier_0.axi_dma_0.recvchannel - self.input_buffer = allocate(shape=x_shape, dtype=dtype) - self.output_buffer = allocate(shape=y_shape, dtype=dtype) - - def _print_dt(self, timea, timeb, N): - dt = (timeb - timea) - dts = dt.seconds + dt.microseconds * 10 ** -6 - rate = N / dts - print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) - return dts, rate - - def predict(self, X, debug=False, profile=False, encode=None, decode=None): - """ - Obtain the predictions of the NN implemented in the FPGA. - Parameters: - - X : the input vector. Should be numpy ndarray. - - dtype : the data type of the elements of the input/output vectors. - Note: it should be set depending on the interface of the accelerator; if it uses 'float' - types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. - Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot - any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` - doc for more info). - In this case the encoding/decoding has to be computed by the PS. For example for - 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode - 'float' -> 'ap_fixed<16,6>': - ``` - def encode(xi): - return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) - def decode(yi): - return yi * 2**-10 - encode_v = np.vectorize(encode) # to apply them element-wise - decode_v = np.vectorize(decode) - ``` - - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. - - encode/decode: function pointers. See `dtype` section for more information. - - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to - the namesake parameter. - """ - if profile: - timea = datetime.now() - if encode is not None: - X = encode(X) - self.input_buffer[:] = X - self.sendchannel.transfer(self.input_buffer) - self.recvchannel.transfer(self.output_buffer) - if debug: - print("Transfer OK") - self.sendchannel.wait() - if debug: - print("Send OK") - self.recvchannel.wait() - if debug: - print("Receive OK") - # result = self.output_buffer.copy() - if decode is not None: - self.output_buffer = decode(self.output_buffer) - - if profile: - timeb = datetime.now() - dts, rate = self._print_dt(timea, timeb, len(X)) - return self.output_buffer, dts, rate - else: - return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl deleted file mode 100644 index 2df93afca..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl +++ /dev/null @@ -1,26 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xczu3eg-sbva484-1-e -force - -set_property board_part em.avnet.com:ultra96:part0:1.2 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -# Create Block Designer design -create_bd_design "design_1" -create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e -apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells zynq_ultra_ps_e] -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/${myproject}_axi_0/s_axi_AXILiteS} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins ${myproject}_axi_0/s_axi_AXILiteS] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl deleted file mode 100644 index bb91ba9ee..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl +++ /dev/null @@ -1,91 +0,0 @@ -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -# Project names -set project_name "project_1" -set design_name "design_1" -set hls_solution_name "solution1" -set ps_name "zynq_ultra_ps_e_0" -set acc_name "${myproject}_axi_0" - -# Board and chip part names -create_project ${project_name} ${myproject}_vivado_accelerator -part xczu9eg-ffvb1156-2-e -force -set_property board_part avnet.com:ultra96v2:part0:1.2 [current_project] - -# Create block design -create_bd_design ${design_name} - -# Setup IP repo -#set_property ip_repo_paths ${myproject}_prj [current_project] -set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] -update_ip_catalog - -# Create and setup PS -create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 ${ps_name} -apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } [get_bd_cells ${ps_name}] -set_property -dict [list CONFIG.PSU__USE__S_AXI_GP0 {1} CONFIG.PSU__SAXIGP0__DATA_WIDTH {32}] [get_bd_cells ${ps_name}] - -# Create accelerator -create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 ${acc_name} - -# Wiring -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {Auto} \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master "/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD" \ - Slave "/myproject_axi_0/s_axi_CTRL_BUS" \ - intc_ip {New AXI Interconnect} \ - master_apm {0}} [get_bd_intf_pins ${acc_name}/s_axi_CTRL_BUS] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master {Auto} \ - Clk_slave "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ - Clk_xbar "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ - Master "/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD" \ - Slave "/myproject_axi_0/s_axi_CTRL_BUS" \ - intc_ip {/ps8_0_axi_periph} \ - master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ - Clk_slave {Auto} \ - Clk_xbar {Auto} \ - Master "/myproject_axi_0/m_axi_IN_BUS" \ - Slave "/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD" \ - intc_ip {Auto} \ - master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] - -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ - Clk_master "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ - Clk_slave "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ - Clk_xbar "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ - Master "/myproject_axi_0/m_axi_OUT_BUS" \ - Slave "/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD" \ - intc_ip {/axi_smc} \ - master_apm {0}} [get_bd_intf_pins ${acc_name}/m_axi_OUT_BUS] - -# Wiring interrupt signal -connect_bd_net [get_bd_pins ${acc_name}/interrupt] [get_bd_pins ${ps_name}/pl_ps_irq0] - -# Top level wrapper -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top -add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v - -# Memory mapping -delete_bd_objs [get_bd_addr_segs -excluded ${acc_name}/Data_m_axi_IN_BUS/SEG_${ps_name}_HPC0_LPS_OCM] -delete_bd_objs [get_bd_addr_segs -excluded ${acc_name}/Data_m_axi_OUT_BUS/SEG_${ps_name}_HPC0_LPS_OCM] - -# Run synthesis and implementation -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -# Reporting -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages - -# Export HDF file for SDK flow -file mkdir ./hdf -file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl deleted file mode 100644 index 4721b5994..000000000 --- a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl +++ /dev/null @@ -1,58 +0,0 @@ -#@todo: try to remove startgroup and endgroup and see if it work -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xczu9eg-ffvb1156-2-e -force - -set_property board_part em.avnet.com:ultra96:part0:1.2 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -create_bd_design "design_1" -set_property ip_repo_paths ${myproject}_prj/solution1/impl/ip [current_project] -update_ip_catalog - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e_0 -endgroup - -apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } [get_bd_cells zynq_ultra_ps_e_0] - -set_property -dict [list CONFIG.PSU__USE__S_AXI_GP0 {1} CONFIG.PSU__SAXIGP0__DATA_WIDTH {32}] [get_bd_cells zynq_ultra_ps_e_0] - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 -endgroup -set_property -dict [list CONFIG.c_m_axi_s2mm_data_width.VALUE_SRC USER CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] -set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_m_axi_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] - -startgroup -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {New AXI SmartConnect} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] -endgroup - -startgroup -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {/ps8_0_axi_periph} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] -endgroup - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -endgroup -connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] -connect_bd_intf_net [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] [get_bd_intf_pins ${myproject}_axi_0/out_r] - -apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] -group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top - -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/vcu128/Readme.md b/hls4ml/templates/vivado_accelerator/vcu128/Readme.md deleted file mode 100644 index 785d69b84..000000000 --- a/hls4ml/templates/vivado_accelerator/vcu128/Readme.md +++ /dev/null @@ -1 +0,0 @@ -This is the test for adding VCU128 board to HLS4ML template. diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile deleted file mode 100644 index 03ab9b8de..000000000 --- a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -DESIGN := design_1 - -help: - @echo "INFO: make to show targets" -.PHONY: help - ---setup: - xsct ./setup.tcl $(DESIGN) -.PHONY: --setup - -sdk: --setup - rm -f $(DESIGN)_standalone/src/helloworld.c - cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c - cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h -.PHONY: sdk - -gui: - xsdk --workspace . & -.PHONY: gui - -clean: - rm -rf $(DESIGN)_platform - rm -rf $(DESIGN)_standalone - rm -rf $(DESIGN)_standalone_bsp - rm -rf RemoteSystemsTempFiles - rm -rf .Xil - rm -rf .metadata - rm -f *.log -.PHONY: clean - -ultraclean: clean - rm -rf hdf/*.hdf -.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c deleted file mode 100644 index 84e3aa3d0..000000000 --- a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c +++ /dev/null @@ -1,350 +0,0 @@ -/** - * - * Set Heap Size in ldscript.ld to 0x1000000 (16MB) - * - */ - -#include "xmyproject_axi.h" /* TODO: design-dependent name */ -#include "stdio.h" /* PRINTF */ -#include "unistd.h" /* sleep */ -#include "stdlib.h" -#include "malloc.h" -#include "assert.h" -#include "xil_io.h" /* peripheral read/write wrappers */ -#include "platform.h" /* platform init/cleanup functions */ -#include "xil_cache.h" /* enable/disable caches etc */ -#include "xil_printf.h" /* UART debug print functions */ -#include "xparameters.h" /* peripherals base addresses */ -#include "xtmrctr.h" /* timer, Xilinx IP Timer Counter */ - -#include "data.h" - -/*#define EEMBC_POWER 1 - -#ifdef EEMBC_POWER -#include "xgpio.h" /* AXI GPIO drivers */ - -/*#define PIN 0x01 -#define GPIO_PMOD_PIN_DEVICE_ID XPAR_GPIO_0_DEVICE_ID - -#define set_pin_high(InstancePtr, Mask) \ - XGpio_DiscreteWrite(InstancePtr, 1, Mask) - -#define set_pin_low(InstancePtr, Mask) \ - XGpio_DiscreteClear(InstancePtr, 1, Mask) - -XGpio Gpio; -#endif -*/ - -//#define __DEBUG__ - -#define MAX_PRINT_ELEMENTS (16) - -#define PRINTF printf - -const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; -const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; - -#if 1 -/* Accelerator verification */ -#define REFERENCE_OUTPUTS data_y_hls_outputs -#else -/* Accelerator validation */ -#define REFERENCE_OUTPUTS data_y_outputs -//#define REFERENCE_OUTPUTS data_y_keras_outputs -#endif - -unsigned get_max(float *data, unsigned n_elements) { - float max_value = 0.0; - unsigned max_index = 0; - for (unsigned i = 0; i < n_elements; i++) - if (data[i] >= max_value) { - max_index = i; - max_value = data[i]; - } - return max_index; -} - -float *inputs_mem = NULL; -float *outputs_mem = NULL; -float *reference_mem = NULL; - -/* Accelerator configuration */ -XMyproject_axi accelerator; /* TODO: design-dependent name */ -XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ - -/* Accelerator initialization routine */ -void init_accelerators() { - PRINTF("INFO: Initializing accelerator\r\n"); - accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ - if (accelerator_cfg) { - int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ - if (status != XST_SUCCESS) { - PRINTF("ERROR: Initializing accelerator\r\n"); - } - } -} - -/* Reference implementation of the accelerator in software */ -int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { -#ifdef __DEBUG__ - PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); -#endif - /* See data.h for inputs and outputs */ - for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { - sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; - } - return 0; -} - -/* Profiling utilities */ -static XTmrCtr TimerCounterInst; -#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID -#define TIMER_CNTR_0 0 -#define TIMER_CNTR_1 1 - -void start_64b_counter() { - XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_0); - XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_1); -} - -void stop_64b_counter() { - XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_0); - XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_1); -} - -u64 get_64b_counter_value() { - //printf("bytes %u\n\r", sizeof(u64)); - u64 lo_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_0); - u64 hi_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_1); - u64 counter = (hi_counter << 32) | lo_counter; - //printf("INFO: hi = %lu, lo = %lu, total = %lu\n\r", hi_counter, lo_counter, counter); - return counter; -} - -#if 0 -double get_elapsed_time(u64 clk_start, u64 clk_stop) { - return ((clk_stop-clk_start) * (1.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ)); -} -#endif - -float get_elapsed_time_ns(u64 clks) { - return clks * 1000000000.0/XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ; -} - - -/* Dump data to the console */ -void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { - PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); - /* Print at most MAX_PRINT_ELEMENTS */ - for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { - PRINTF("INFO: [%u] ", i); - for (unsigned j = 0; j < feature_count; j++) { - unsigned index = i * feature_count + j; - PRINTF("%f ", data[index]); - } - PRINTF("\r\n"); - } -} - -/* The top of the hill :-) */ -int main(int argc, char** argv) { - - int status; - u64 calibration_time; - double __attribute__ ((unused)) sw_elapsed = 0; - u64 hw_elapsed = 0; - u64 cache_elapsed = 0; - unsigned hw_errors; - - char __attribute__ ((unused)) dummy; /* dummy input */ - - /* Initialize platform (uart and caches) */ - init_platform(); - - PRINTF("\r\n"); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ - PRINTF("INFO: ==================================================\r\n"); - - init_accelerators(); - - /* Timer Counter */ - status = XTmrCtr_Initialize(&TimerCounterInst, TMRCTR_DEVICE_ID); - if (status != XST_SUCCESS){ - print("ERROR: Timer counter initialization failed \r\n"); - return status; - } - - XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0, - XTC_AUTO_RELOAD_OPTION | - XTC_CASCADE_MODE_OPTION); - - print("INFO: Timer counter initialized\r\n"); - - inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); - outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); - - /* Calibration */ - start_64b_counter(); - sleep(1); - stop_64b_counter(); - calibration_time = get_64b_counter_value(); - PRINTF("INFO: Time calibration for one second (%lf sec, %llu clk)\r\n", get_elapsed_time_ns(calibration_time), calibration_time); - - /* Initialize memory */ - PRINTF("INFO: Initialize memory\r\n"); - PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ - PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); - PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); - PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); - PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); - - // Set Heap Size in ldscript.ld to 0x1000000 (16MB) - //malloc_stats(); - - for (int i = 0; i < INPUT_N_ELEMENTS; i++) { - inputs_mem[i] = data_X_inputs[i]; - } - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - outputs_mem[i] = 0x0; - } - - /* ****** SW REFERENCE ****** */ - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Start SW reference implementation\r\n"); - start_64b_counter(); - sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); - stop_64b_counter(); - sw_elapsed = get_64b_counter_value(); - PRINTF("INFO: ==================================================\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - //PRINTF("INFO:"); - - /* ****** HW ACCELERATOR ****** */ - PRINTF("INFO: Start HW accelerator\r\n"); - start_64b_counter(); - Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - stop_64b_counter(); - cache_elapsed = get_64b_counter_value(); - - for (unsigned j = 0; j < N_SAMPLES; j++) { - float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; - float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; - - /* Configure the accelerator */ - start_64b_counter(); - XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ - XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ - - XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ - - /* Polling */ - while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ - - /* Get error status */ - //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ - stop_64b_counter(); - hw_elapsed += get_64b_counter_value(); - } - - start_64b_counter(); - Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); - stop_64b_counter(); - cache_elapsed += get_64b_counter_value(); - - PRINTF("INFO: HW accelerator done!\r\n"); - - /* ****** VALIDATION ****** */ - PRINTF("INFO: ================== Verification ==================\r\n"); -#ifdef __DEBUG__ - PRINTF("INFO: Dump data\r\n"); - dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); - dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); - dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); -#endif - -#ifdef __DEBUG__ - PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); -#endif - PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); - PRINTF("INFO: - total %f sec\r\n", get_elapsed_time_ns(hw_elapsed)); - PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", get_elapsed_time_ns(hw_elapsed) / (N_SAMPLES), (get_elapsed_time_ns(hw_elapsed)*1000.0) / (N_SAMPLES)); - PRINTF("INFO: Cache flush time: %f sec\r\n", get_elapsed_time_ns(cache_elapsed)); -#ifdef __DEBUG__ - PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); -#endif - - hw_errors = 0; -#if 1 - /* Accelerator verification */ - for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { - if (outputs_mem[i] != reference_mem[i]) { - PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); - hw_errors++; - } - } - PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); - if (hw_errors > 0) - PRINTF("INFO: Verification: FAIL\r\n"); - else - PRINTF("INFO: Verification: PASS!\r\n"); -#else - /* Accelerator validation */ - for (unsigned s = 0; s < N_SAMPLES; s++) { - unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); - if (hw_digit != ref_digit) { -#ifdef __DEBUG__ - PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); -#endif - hw_errors++; - } - } - float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; - float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); - PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); - PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); - PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); -#endif - - PRINTF("INFO: ==================================================\r\n"); - - -#ifdef EEMBC_POWER - /* Initialize the GPIO driver */ - status = XGpio_Initialize(&Gpio, GPIO_PMOD_PIN_DEVICE_ID); - if (status != XST_SUCCESS) { - xil_printf("GPIO Initialization Failed\r\n"); - return XST_FAILURE; - } - - set_pin_low(&Gpio, PIN); - - PRINTF("INFO: Connect logic analyzer to the pin 3 of Pmod D\r\n"); - PRINTF("INFO: Press any key to start:\r\n"); - dummy = inbyte(); - - /* Loop forever */ - for (unsigned i; i < 100; i++) { - set_pin_high(&Gpio, PIN); - - sleep(1); - - set_pin_low(&Gpio, PIN); - - sleep(1); - } -#endif - - cleanup_platform(); - - return 0; -} - diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl deleted file mode 100644 index 383bf39cf..000000000 --- a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl +++ /dev/null @@ -1,14 +0,0 @@ -# See -# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html - -setws . -if { $::argc == 1 } { - set myproject [lindex $::argv 0] - createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf - createapp -name ${myproject}\_standalone -app {Hello World} -proc microblaze_mcu -hwproject ${myproject}\_platform -os standalone - configapp -app ${myproject}\_standalone build-config release - #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} - #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} - projects -build - #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} -} diff --git a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl deleted file mode 100644 index a0540bcb5..000000000 --- a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl +++ /dev/null @@ -1,537 +0,0 @@ - -################################################################ -# -# MIT License -# -# Copyright (c) 2022 University of Sherbrooke -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# Author : Mehdi Rahimifar -# Last update : 2022-08-25 -# Description : This contains the tcl scripts to generate the right block design for VCU128 and the accelerator from hls4ml in Vivado -################################################################ - -namespace eval _tcl { -proc get_script_folder {} { - set script_path [file normalize [info script]] - set script_folder [file dirname $script_path] - return $script_folder -} -} -variable script_folder -set script_folder [_tcl::get_script_folder] - - - -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -################################################################ -# Check if script is running in correct Vivado version. -################################################################ - -################################################################ -# START -################################################################ - -# To test this script, run the following commands from Vivado Tcl console: -# source design_1_script.tcl - -# If there is no project opened, this script will create a -# project, but make sure you do not have an existing project -# <./myproj/project_1.xpr> in the current working folder. - - - -set project_name "project_1" -set design_name "design_1" -set hls_solution_name "solution1" -#set acc_name "${myproject}_axi" -set part_name "xcvu37p-fsvh2892-2L-e" -set board_name "xilinx.com:vcu128:part0:1.0" - - - - - -set list_projs [get_projects -quiet] -if { $list_projs eq "" } { - create_project project_1 ${myproject}_vivado_accelerator -part xcvu37p-fsvh2892-2L-e -force - set_property BOARD_PART xilinx.com:vcu128:part0:1.0 [current_project] -} - - - - -# Setup IP repo -set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] -#set_property ip_repo_paths /home/subnugler/Desktop/MICROBLAZE_TEST/Microblaze/myproject_prj/${hls_solution_name}/impl/ip [current_project] -update_ip_catalog - - - - - - -#CHANGED HERE!!!!!!!!!!! - -# CHANGE DESIGN NAME HERE -#variable design_name -#set design_name design_1 - - - - -# If you do not already have an existing IP Integrator design open, -# you can create a design using the following command: -# create_bd_design $design_name - -# Creating design if needed -set errMsg "" -set nRet 0 - -set cur_design [current_bd_design -quiet] -set list_cells [get_bd_cells -quiet] - -if { ${design_name} eq "" } { - # USE CASES: - # 1) Design_name not set - - set errMsg "Please set the variable to a non-empty value." - set nRet 1 - -} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { - # USE CASES: - # 2): Current design opened AND is empty AND names same. - # 3): Current design opened AND is empty AND names diff; design_name NOT in project. - # 4): Current design opened AND is empty AND names diff; design_name exists in project. - - if { $cur_design ne $design_name } { - common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." - set design_name [get_property NAME $cur_design] - } - common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." - -} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { - # USE CASES: - # 5) Current design opened AND has components AND same names. - - set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." - set nRet 1 -} elseif { [get_files -quiet ${design_name}.bd] ne "" } { - # USE CASES: - # 6) Current opened design, has components, but diff names, design_name exists in project. - # 7) No opened design, design_name exists in project. - - set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." - set nRet 2 - -} else { - # USE CASES: - # 8) No opened design, design_name not in project. - # 9) Current opened design, has components, but diff names, design_name not in project. - - common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." - - create_bd_design $design_name - - common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." - current_bd_design $design_name - -} - -common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." - -if { $nRet != 0 } { - catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} - return $nRet -} - -set bCheckIPsPassed 1 -################################################################## -# CHECK IPs -################################################################## -set bCheckIPs 1 -if { $bCheckIPs == 1 } { - set list_check_ips "\ -xilinx.com:ip:smartconnect:1.0\ -xilinx.com:ip:axi_timer:2.0\ -xilinx.com:ip:axi_uart16550:2.0\ -xilinx.com:ip:clk_wiz:6.0\ -xilinx.com:ip:ddr4:2.2\ -xilinx.com:ip:mdm:3.2\ -xilinx.com:ip:microblaze:11.0\ -xilinx.com:hls:myproject_axi:1.0\ -xilinx.com:ip:proc_sys_reset:5.0\ -xilinx.com:ip:lmb_bram_if_cntlr:4.0\ -xilinx.com:ip:lmb_v10:3.0\ -xilinx.com:ip:blk_mem_gen:8.4\ -" - - set list_ips_missing "" - common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." - - foreach ip_vlnv $list_check_ips { - set ip_obj [get_ipdefs -all $ip_vlnv] - if { $ip_obj eq "" } { - lappend list_ips_missing $ip_vlnv - } - } - - if { $list_ips_missing ne "" } { - catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } - set bCheckIPsPassed 0 - } - -} - -if { $bCheckIPsPassed != 1 } { - common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." - return 3 -} - -################################################################## -# DESIGN PROCs -################################################################## - - -# Hierarchical cell: microblaze_0_local_memory -proc create_hier_cell_microblaze_0_local_memory { parentCell nameHier } { - - variable script_folder - - if { $parentCell eq "" || $nameHier eq "" } { - catch {common::send_msg_id "BD_TCL-102" "ERROR" "create_hier_cell_microblaze_0_local_memory() - Empty argument(s)!"} - return - } - - # Get object for parentCell - set parentObj [get_bd_cells $parentCell] - if { $parentObj == "" } { - catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} - return - } - - # Make sure parentObj is hier blk - set parentType [get_property TYPE $parentObj] - if { $parentType ne "hier" } { - catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} - return - } - - # Save current instance; Restore later - set oldCurInst [current_bd_instance .] - - # Set parent object as current - current_bd_instance $parentObj - - # Create cell and set as current instance - set hier_obj [create_bd_cell -type hier $nameHier] - current_bd_instance $hier_obj - - # Create interface pins - create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 DLMB - - create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 ILMB - - - # Create pins - create_bd_pin -dir I -type clk LMB_Clk - create_bd_pin -dir I -type rst SYS_Rst - - # Create instance: dlmb_bram_if_cntlr, and set properties - set dlmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 dlmb_bram_if_cntlr ] - set_property -dict [ list \ - CONFIG.C_ECC {0} \ - ] $dlmb_bram_if_cntlr - - # Create instance: dlmb_v10, and set properties - set dlmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 dlmb_v10 ] - - # Create instance: ilmb_bram_if_cntlr, and set properties - set ilmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 ilmb_bram_if_cntlr ] - set_property -dict [ list \ - CONFIG.C_ECC {0} \ - ] $ilmb_bram_if_cntlr - - # Create instance: ilmb_v10, and set properties - set ilmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 ilmb_v10 ] - - # Create instance: lmb_bram, and set properties - set lmb_bram [ create_bd_cell -type ip -vlnv xilinx.com:ip:blk_mem_gen:8.4 lmb_bram ] - set_property -dict [ list \ - CONFIG.Memory_Type {True_Dual_Port_RAM} \ - CONFIG.use_bram_block {BRAM_Controller} \ - ] $lmb_bram - - # Create interface connections - connect_bd_intf_net -intf_net microblaze_0_dlmb [get_bd_intf_pins DLMB] [get_bd_intf_pins dlmb_v10/LMB_M] - connect_bd_intf_net -intf_net microblaze_0_dlmb_bus [get_bd_intf_pins dlmb_bram_if_cntlr/SLMB] [get_bd_intf_pins dlmb_v10/LMB_Sl_0] - connect_bd_intf_net -intf_net microblaze_0_dlmb_cntlr [get_bd_intf_pins dlmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTA] - connect_bd_intf_net -intf_net microblaze_0_ilmb [get_bd_intf_pins ILMB] [get_bd_intf_pins ilmb_v10/LMB_M] - connect_bd_intf_net -intf_net microblaze_0_ilmb_bus [get_bd_intf_pins ilmb_bram_if_cntlr/SLMB] [get_bd_intf_pins ilmb_v10/LMB_Sl_0] - connect_bd_intf_net -intf_net microblaze_0_ilmb_cntlr [get_bd_intf_pins ilmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTB] - - # Create port connections - connect_bd_net -net SYS_Rst_1 [get_bd_pins SYS_Rst] [get_bd_pins dlmb_bram_if_cntlr/LMB_Rst] [get_bd_pins dlmb_v10/SYS_Rst] [get_bd_pins ilmb_bram_if_cntlr/LMB_Rst] [get_bd_pins ilmb_v10/SYS_Rst] - connect_bd_net -net microblaze_0_Clk [get_bd_pins LMB_Clk] [get_bd_pins dlmb_bram_if_cntlr/LMB_Clk] [get_bd_pins dlmb_v10/LMB_Clk] [get_bd_pins ilmb_bram_if_cntlr/LMB_Clk] [get_bd_pins ilmb_v10/LMB_Clk] - - # Restore current instance - current_bd_instance $oldCurInst -} - - -# Procedure to create entire design; Provide argument to make -# procedure reusable. If parentCell is "", will use root. -proc create_root_design { parentCell } { - - variable script_folder - variable design_name - - if { $parentCell eq "" } { - set parentCell [get_bd_cells /] - } - - # Get object for parentCell - set parentObj [get_bd_cells $parentCell] - if { $parentObj == "" } { - catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} - return - } - - # Make sure parentObj is hier blk - set parentType [get_property TYPE $parentObj] - if { $parentType ne "hier" } { - catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} - return - } - - # Save current instance; Restore later - set oldCurInst [current_bd_instance .] - - # Set parent object as current - current_bd_instance $parentObj - - - # Create interface ports - set ddr4_sdram [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddr4_rtl:1.0 ddr4_sdram ] - - set default_100mhz_clk [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 default_100mhz_clk ] - set_property -dict [ list \ - CONFIG.FREQ_HZ {100000000} \ - ] $default_100mhz_clk - - set rs232_uart_0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:uart_rtl:1.0 rs232_uart_0 ] - - - # Create ports - set dummy_port_in [ create_bd_port -dir I -type rst dummy_port_in ] - set_property -dict [ list \ - CONFIG.POLARITY {ACTIVE_HIGH} \ - ] $dummy_port_in - - # Create instance: axi_smc, and set properties - set axi_smc [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_smc ] - set_property -dict [ list \ - CONFIG.NUM_CLKS {2} \ - CONFIG.NUM_SI {4} \ - ] $axi_smc - - # Create instance: axi_timer_0, and set properties - set axi_timer_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_timer:2.0 axi_timer_0 ] - - # Create instance: axi_uart16550_0, and set properties - set axi_uart16550_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uart16550:2.0 axi_uart16550_0 ] - set_property -dict [ list \ - CONFIG.UART_BOARD_INTERFACE {rs232_uart_0} \ - CONFIG.USE_BOARD_FLOW {true} \ - ] $axi_uart16550_0 - - # Create instance: clk_wiz_0, and set properties - set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ] - set_property -dict [ list \ - CONFIG.CLKOUT1_JITTER {166.057} \ - CONFIG.CLKOUT1_PHASE_ERROR {298.404} \ - CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {125.000} \ - CONFIG.MMCM_CLKFBOUT_MULT_F {125.000} \ - CONFIG.RESET_BOARD_INTERFACE {Custom} \ - CONFIG.USE_BOARD_FLOW {true} \ - ] $clk_wiz_0 - - # Create instance: ddr4_0, and set properties - set ddr4_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:ddr4:2.2 ddr4_0 ] - set_property -dict [ list \ - CONFIG.C0_CLOCK_BOARD_INTERFACE {default_100mhz_clk} \ - CONFIG.C0_DDR4_BOARD_INTERFACE {ddr4_sdram} \ - CONFIG.RESET_BOARD_INTERFACE {dummy_port_in} \ - ] $ddr4_0 - - # Create instance: mdm_1, and set properties - set mdm_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mdm:3.2 mdm_1 ] - - # Create instance: microblaze_0, and set properties - set microblaze_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:11.0 microblaze_0 ] - set_property -dict [ list \ - CONFIG.C_ADDR_TAG_BITS {16} \ - CONFIG.C_CACHE_BYTE_SIZE {32768} \ - CONFIG.C_DCACHE_ADDR_TAG {16} \ - CONFIG.C_DCACHE_BYTE_SIZE {32768} \ - CONFIG.C_DCACHE_USE_WRITEBACK {1} \ - CONFIG.C_DEBUG_ENABLED {1} \ - CONFIG.C_DIV_ZERO_EXCEPTION {1} \ - CONFIG.C_D_AXI {1} \ - CONFIG.C_D_LMB {1} \ - CONFIG.C_FPU_EXCEPTION {1} \ - CONFIG.C_ICACHE_LINE_LEN {8} \ - CONFIG.C_ICACHE_STREAMS {1} \ - CONFIG.C_ICACHE_VICTIMS {8} \ - CONFIG.C_ILL_OPCODE_EXCEPTION {1} \ - CONFIG.C_I_LMB {1} \ - CONFIG.C_MMU_ZONES {2} \ - CONFIG.C_M_AXI_D_BUS_EXCEPTION {1} \ - CONFIG.C_M_AXI_I_BUS_EXCEPTION {1} \ - CONFIG.C_NUMBER_OF_PC_BRK {2} \ - CONFIG.C_NUMBER_OF_RD_ADDR_BRK {1} \ - CONFIG.C_NUMBER_OF_WR_ADDR_BRK {1} \ - CONFIG.C_OPCODE_0x0_ILLEGAL {1} \ - CONFIG.C_PVR {2} \ - CONFIG.C_UNALIGNED_EXCEPTIONS {1} \ - CONFIG.C_USE_BARREL {1} \ - CONFIG.C_USE_DCACHE {1} \ - CONFIG.C_USE_DIV {1} \ - CONFIG.C_USE_FPU {1} \ - CONFIG.C_USE_HW_MUL {2} \ - CONFIG.C_USE_ICACHE {1} \ - CONFIG.C_USE_MMU {3} \ - CONFIG.C_USE_MSR_INSTR {1} \ - CONFIG.C_USE_PCMP_INSTR {1} \ - CONFIG.G_TEMPLATE_LIST {10} \ - CONFIG.G_USE_EXCEPTIONS {1} \ - ] $microblaze_0 - - # Create instance: microblaze_0_axi_periph, and set properties - set microblaze_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 microblaze_0_axi_periph ] - set_property -dict [ list \ - CONFIG.NUM_MI {4} \ - ] $microblaze_0_axi_periph - - # Create instance: microblaze_0_local_memory - create_hier_cell_microblaze_0_local_memory [current_bd_instance .] microblaze_0_local_memory - - # Create instance: myproject_axi_0, and set properties - set myproject_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 myproject_axi_0 ] - - # Create instance: rst_clk_wiz_0_100M, and set properties - set rst_clk_wiz_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_clk_wiz_0_100M ] - set_property -dict [ list \ - CONFIG.RESET_BOARD_INTERFACE {Custom} \ - CONFIG.USE_BOARD_FLOW {true} \ - ] $rst_clk_wiz_0_100M - - # Create instance: rst_ddr4_0_333M, and set properties - set rst_ddr4_0_333M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ddr4_0_333M ] - - # Create interface connections - connect_bd_intf_net -intf_net axi_smc_M00_AXI [get_bd_intf_pins axi_smc/M00_AXI] [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI] - connect_bd_intf_net -intf_net axi_uart16550_0_UART [get_bd_intf_ports rs232_uart_0] [get_bd_intf_pins axi_uart16550_0/UART] - connect_bd_intf_net -intf_net ddr4_0_C0_DDR4 [get_bd_intf_ports ddr4_sdram] [get_bd_intf_pins ddr4_0/C0_DDR4] - connect_bd_intf_net -intf_net default_100mhz_clk_1 [get_bd_intf_ports default_100mhz_clk] [get_bd_intf_pins ddr4_0/C0_SYS_CLK] - connect_bd_intf_net -intf_net microblaze_0_M_AXI_DC [get_bd_intf_pins axi_smc/S00_AXI] [get_bd_intf_pins microblaze_0/M_AXI_DC] - connect_bd_intf_net -intf_net microblaze_0_M_AXI_DP [get_bd_intf_pins microblaze_0/M_AXI_DP] [get_bd_intf_pins microblaze_0_axi_periph/S00_AXI] - connect_bd_intf_net -intf_net microblaze_0_M_AXI_IC [get_bd_intf_pins axi_smc/S01_AXI] [get_bd_intf_pins microblaze_0/M_AXI_IC] - connect_bd_intf_net -intf_net microblaze_0_axi_periph_M00_AXI [get_bd_intf_pins axi_timer_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M00_AXI] - connect_bd_intf_net -intf_net microblaze_0_axi_periph_M01_AXI [get_bd_intf_pins axi_uart16550_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M01_AXI] - connect_bd_intf_net -intf_net microblaze_0_axi_periph_M02_AXI [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI_CTRL] [get_bd_intf_pins microblaze_0_axi_periph/M02_AXI] - connect_bd_intf_net -intf_net microblaze_0_axi_periph_M03_AXI [get_bd_intf_pins microblaze_0_axi_periph/M03_AXI] [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] - connect_bd_intf_net -intf_net microblaze_0_debug [get_bd_intf_pins mdm_1/MBDEBUG_0] [get_bd_intf_pins microblaze_0/DEBUG] - connect_bd_intf_net -intf_net microblaze_0_dlmb_1 [get_bd_intf_pins microblaze_0/DLMB] [get_bd_intf_pins microblaze_0_local_memory/DLMB] - connect_bd_intf_net -intf_net microblaze_0_ilmb_1 [get_bd_intf_pins microblaze_0/ILMB] [get_bd_intf_pins microblaze_0_local_memory/ILMB] - connect_bd_intf_net -intf_net myproject_axi_0_m_axi_IN_BUS [get_bd_intf_pins axi_smc/S02_AXI] [get_bd_intf_pins myproject_axi_0/m_axi_IN_BUS] - connect_bd_intf_net -intf_net myproject_axi_0_m_axi_OUT_BUS [get_bd_intf_pins axi_smc/S03_AXI] [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] - - # Create port connections - connect_bd_net -net clk_wiz_0_locked [get_bd_pins clk_wiz_0/locked] [get_bd_pins rst_clk_wiz_0_100M/dcm_locked] - connect_bd_net -net ddr4_0_c0_ddr4_ui_clk [get_bd_pins axi_smc/aclk] [get_bd_pins clk_wiz_0/clk_in1] [get_bd_pins ddr4_0/c0_ddr4_ui_clk] [get_bd_pins microblaze_0_axi_periph/M02_ACLK] [get_bd_pins rst_ddr4_0_333M/slowest_sync_clk] - connect_bd_net -net ddr4_0_c0_ddr4_ui_clk_sync_rst [get_bd_pins clk_wiz_0/reset] [get_bd_pins ddr4_0/c0_ddr4_ui_clk_sync_rst] [get_bd_pins rst_clk_wiz_0_100M/ext_reset_in] [get_bd_pins rst_ddr4_0_333M/ext_reset_in] - connect_bd_net -net dummy_port_in_1 [get_bd_ports dummy_port_in] [get_bd_pins ddr4_0/sys_rst] - connect_bd_net -net mdm_1_debug_sys_rst [get_bd_pins mdm_1/Debug_SYS_Rst] [get_bd_pins rst_clk_wiz_0_100M/mb_debug_sys_rst] - connect_bd_net -net microblaze_0_Clk [get_bd_pins axi_smc/aclk1] [get_bd_pins axi_timer_0/s_axi_aclk] [get_bd_pins axi_uart16550_0/s_axi_aclk] [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins microblaze_0/Clk] [get_bd_pins microblaze_0_axi_periph/ACLK] [get_bd_pins microblaze_0_axi_periph/M00_ACLK] [get_bd_pins microblaze_0_axi_periph/M01_ACLK] [get_bd_pins microblaze_0_axi_periph/M03_ACLK] [get_bd_pins microblaze_0_axi_periph/S00_ACLK] [get_bd_pins microblaze_0_local_memory/LMB_Clk] [get_bd_pins myproject_axi_0/ap_clk] [get_bd_pins rst_clk_wiz_0_100M/slowest_sync_clk] - connect_bd_net -net rst_clk_wiz_0_100M_bus_struct_reset [get_bd_pins microblaze_0_local_memory/SYS_Rst] [get_bd_pins rst_clk_wiz_0_100M/bus_struct_reset] - connect_bd_net -net rst_clk_wiz_0_100M_mb_reset [get_bd_pins microblaze_0/Reset] [get_bd_pins rst_clk_wiz_0_100M/mb_reset] - connect_bd_net -net rst_clk_wiz_0_100M_peripheral_aresetn [get_bd_pins axi_smc/aresetn] [get_bd_pins axi_timer_0/s_axi_aresetn] [get_bd_pins axi_uart16550_0/s_axi_aresetn] [get_bd_pins microblaze_0_axi_periph/ARESETN] [get_bd_pins microblaze_0_axi_periph/M00_ARESETN] [get_bd_pins microblaze_0_axi_periph/M01_ARESETN] [get_bd_pins microblaze_0_axi_periph/M03_ARESETN] [get_bd_pins microblaze_0_axi_periph/S00_ARESETN] [get_bd_pins myproject_axi_0/ap_rst_n] [get_bd_pins rst_clk_wiz_0_100M/peripheral_aresetn] - connect_bd_net -net rst_ddr4_0_333M_peripheral_aresetn [get_bd_pins ddr4_0/c0_ddr4_aresetn] [get_bd_pins microblaze_0_axi_periph/M02_ARESETN] [get_bd_pins rst_ddr4_0_333M/peripheral_aresetn] - - # Create address segments - assign_bd_address -offset 0x41C00000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_timer_0/S_AXI/Reg] -force - assign_bd_address -offset 0x44A00000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_uart16550_0/S_AXI/Reg] -force - assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force - assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force - assign_bd_address -offset 0x44B00000 -range 0x00100000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP_CTRL/C0_REG] -force - assign_bd_address -offset 0x00000000 -range 0x00002000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs microblaze_0_local_memory/dlmb_bram_if_cntlr/SLMB/Mem] -force - assign_bd_address -offset 0x00000000 -range 0x00002000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs microblaze_0_local_memory/ilmb_bram_if_cntlr/SLMB/Mem] -force - assign_bd_address -offset 0x44A10000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs myproject_axi_0/s_axi_CTRL_BUS/Reg] -force - assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces myproject_axi_0/Data_m_axi_IN_BUS] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force - assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces myproject_axi_0/Data_m_axi_OUT_BUS] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force - - - # Restore current instance - current_bd_instance $oldCurInst - - validate_bd_design - save_bd_design -} -# End of create_root_design() - - -################################################################## -# MAIN FLOW -################################################################## - -create_root_design "" - - -############################################################################################################# - -#WRAP THE MODEL - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top - -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -#open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages - - - - - - - - - - - - - - - - - diff --git a/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v b/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v deleted file mode 100644 index aa944e12a..000000000 --- a/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v +++ /dev/null @@ -1,92 +0,0 @@ -//Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -//-------------------------------------------------------------------------------- -//Tool Version: Vivado v.2019.2 (lin64) Build 2708876 Wed Nov 6 21:39:14 MST 2019 -//Date : Wed Oct 5 16:49:36 2022 -//Host : subnugler running 64-bit Ubuntu 22.04.1 LTS -//Command : generate_target design_1_wrapper.bd -//Design : design_1_wrapper -//Purpose : IP block netlist -//-------------------------------------------------------------------------------- -`timescale 1 ps / 1 ps - -module design_1_wrapper - (ddr4_sdram_act_n, - ddr4_sdram_adr, - ddr4_sdram_ba, - ddr4_sdram_bg, - ddr4_sdram_ck_c, - ddr4_sdram_ck_t, - ddr4_sdram_cke, - ddr4_sdram_cs_n, - ddr4_sdram_dm_n, - ddr4_sdram_dq, - ddr4_sdram_dqs_c, - ddr4_sdram_dqs_t, - ddr4_sdram_odt, - ddr4_sdram_reset_n, - default_100mhz_clk_clk_n, - default_100mhz_clk_clk_p, - dummy_port_in, - rs232_uart_0_rxd, - rs232_uart_0_txd); - output ddr4_sdram_act_n; - output [16:0]ddr4_sdram_adr; - output [1:0]ddr4_sdram_ba; - output ddr4_sdram_bg; - output ddr4_sdram_ck_c; - output ddr4_sdram_ck_t; - output ddr4_sdram_cke; - output [1:0]ddr4_sdram_cs_n; - inout [8:0]ddr4_sdram_dm_n; - inout [71:0]ddr4_sdram_dq; - inout [8:0]ddr4_sdram_dqs_c; - inout [8:0]ddr4_sdram_dqs_t; - output ddr4_sdram_odt; - output ddr4_sdram_reset_n; - input default_100mhz_clk_clk_n; - input default_100mhz_clk_clk_p; - input dummy_port_in; - input rs232_uart_0_rxd; - output rs232_uart_0_txd; - - wire ddr4_sdram_act_n; - wire [16:0]ddr4_sdram_adr; - wire [1:0]ddr4_sdram_ba; - wire ddr4_sdram_bg; - wire ddr4_sdram_ck_c; - wire ddr4_sdram_ck_t; - wire ddr4_sdram_cke; - wire [1:0]ddr4_sdram_cs_n; - wire [8:0]ddr4_sdram_dm_n; - wire [71:0]ddr4_sdram_dq; - wire [8:0]ddr4_sdram_dqs_c; - wire [8:0]ddr4_sdram_dqs_t; - wire ddr4_sdram_odt; - wire ddr4_sdram_reset_n; - wire default_100mhz_clk_clk_n; - wire default_100mhz_clk_clk_p; - wire dummy_port_in; - wire rs232_uart_0_rxd; - wire rs232_uart_0_txd; - - design_1 design_1_i - (.ddr4_sdram_act_n(ddr4_sdram_act_n), - .ddr4_sdram_adr(ddr4_sdram_adr), - .ddr4_sdram_ba(ddr4_sdram_ba), - .ddr4_sdram_bg(ddr4_sdram_bg), - .ddr4_sdram_ck_c(ddr4_sdram_ck_c), - .ddr4_sdram_ck_t(ddr4_sdram_ck_t), - .ddr4_sdram_cke(ddr4_sdram_cke), - .ddr4_sdram_cs_n(ddr4_sdram_cs_n), - .ddr4_sdram_dm_n(ddr4_sdram_dm_n), - .ddr4_sdram_dq(ddr4_sdram_dq), - .ddr4_sdram_dqs_c(ddr4_sdram_dqs_c), - .ddr4_sdram_dqs_t(ddr4_sdram_dqs_t), - .ddr4_sdram_odt(ddr4_sdram_odt), - .ddr4_sdram_reset_n(ddr4_sdram_reset_n), - .default_100mhz_clk_clk_n(default_100mhz_clk_clk_n), - .default_100mhz_clk_clk_p(default_100mhz_clk_clk_p), - .dummy_port_in(dummy_port_in), - .rs232_uart_0_rxd(rs232_uart_0_rxd), - .rs232_uart_0_txd(rs232_uart_0_txd)); -endmodule diff --git a/hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py deleted file mode 100644 index 4adb187ab..000000000 --- a/hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py +++ /dev/null @@ -1,75 +0,0 @@ -from pynq import DefaultHierarchy, DefaultIP, allocate -from pynq import Overlay -from datetime import datetime -import pynq.lib.dma -import numpy as np - - -class NeuralNetworkOverlay(Overlay): - def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, - device=None): - super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) - self.sendchannel = self.hier_0.axi_dma_0.sendchannel - self.recvchannel = self.hier_0.axi_dma_0.recvchannel - self.input_buffer = allocate(shape=x_shape, dtype=dtype) - self.output_buffer = allocate(shape=y_shape, dtype=dtype) - - def _print_dt(self, timea, timeb, N): - dt = (timeb - timea) - dts = dt.seconds + dt.microseconds * 10 ** -6 - rate = N / dts - print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) - return dts, rate - - def predict(self, X, debug=False, profile=False, encode=None, decode=None): - """ - Obtain the predictions of the NN implemented in the FPGA. - Parameters: - - X : the input vector. Should be numpy ndarray. - - dtype : the data type of the elements of the input/output vectors. - Note: it should be set depending on the interface of the accelerator; if it uses 'float' - types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. - Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot - any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` - doc for more info). - In this case the encoding/decoding has to be computed by the PS. For example for - 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode - 'float' -> 'ap_fixed<16,6>': - ``` - def encode(xi): - return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) - def decode(yi): - return yi * 2**-10 - encode_v = np.vectorize(encode) # to apply them element-wise - decode_v = np.vectorize(decode) - ``` - - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. - - encode/decode: function pointers. See `dtype` section for more information. - - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to - the namesake parameter. - """ - if profile: - timea = datetime.now() - if encode is not None: - X = encode(X) - self.input_buffer[:] = X - self.sendchannel.transfer(self.input_buffer) - self.recvchannel.transfer(self.output_buffer) - if debug: - print("Transfer OK") - self.sendchannel.wait() - if debug: - print("Send OK") - self.recvchannel.wait() - if debug: - print("Receive OK") - # result = self.output_buffer.copy() - if decode is not None: - self.output_buffer = decode(self.output_buffer) - - if profile: - timeb = datetime.now() - dts, rate = self._print_dt(timea, timeb, len(X)) - return self.output_buffer, dts, rate - else: - return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl deleted file mode 100644 index fb79c8af8..000000000 --- a/hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl +++ /dev/null @@ -1,58 +0,0 @@ -#@todo: try to remove startgroup and endgroup and see if it work -set tcldir [file dirname [info script]] -source [file join $tcldir project.tcl] - -create_project project_1 ${myproject}_vivado_accelerator -part xczu9eg-ffvb1156-2-e -force - -set_property board_part xilinx.com:zcu102:part0:3.3 [current_project] -set_property ip_repo_paths ${myproject}_prj [current_project] -update_ip_catalog - -create_bd_design "design_1" -set_property ip_repo_paths ${myproject}_prj/solution1/impl/ip [current_project] -update_ip_catalog - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e_0 -endgroup - -apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } [get_bd_cells zynq_ultra_ps_e_0] - -set_property -dict [list CONFIG.PSU__USE__S_AXI_GP0 {1} CONFIG.PSU__SAXIGP0__DATA_WIDTH {32}] [get_bd_cells zynq_ultra_ps_e_0] - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 -endgroup -set_property -dict [list CONFIG.c_m_axi_s2mm_data_width.VALUE_SRC USER CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] -set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_m_axi_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] - -startgroup -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {New AXI SmartConnect} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] -endgroup - -startgroup -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] -apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {/ps8_0_axi_periph} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] -endgroup - -startgroup -create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 -endgroup -connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] -connect_bd_intf_net [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] [get_bd_intf_pins ${myproject}_axi_0/out_r] - -apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] -group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] - -make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top - -add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v - -reset_run impl_1 -reset_run synth_1 -launch_runs impl_1 -to_step write_bitstream -jobs 6 -wait_on_run -timeout 360 impl_1 - -open_run impl_1 -report_utilization -file util.rpt -hierarchical -hierarchical_percentages From 57a76c617aa4fb9b2c6843ef04e393e48ad52eee Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:28:27 -0500 Subject: [PATCH 08/14] Add files via upload --- .../arty-a7-100t/c_drivers/sdk/Makefile | 33 + .../arty-a7-100t/c_drivers/sdk/common/main.c | 351 +++ .../arty-a7-100t/c_drivers/sdk/setup.tcl | 14 + .../tcl_scripts/axi_master_design.tcl | 193 ++ .../verilog_wrappers/design_1_wrapper.v | 209 ++ .../arty-a7-100t/xdc_constraints/pin_pmod.xdc | 4 + .../arty-a7-100t/xdc_constraints/qspi.xdc | 13 + .../xdc_constraints/uart_pmod.xdc | 8 + .../templates/vivado_accelerator/build_lib.sh | 18 + .../vivado_accelerator/myproject_axi.cpp | 20 + .../vivado_accelerator/myproject_axi.h | 13 + .../pynq-z1/c_drivers/sdk/Makefile | 33 + .../pynq-z1/c_drivers/sdk/common/main.c | 262 +++ .../pynq-z1/c_drivers/sdk/setup.tcl | 14 + .../python_drivers/axi_stream_driver.py | 75 + .../pynq-z1/tcl_scripts/axi_lite_design.tcl | 26 + .../pynq-z1/tcl_scripts/axi_master_design.tcl | 88 + .../pynq-z1/tcl_scripts/axi_stream_design.tcl | 59 + .../pynq-z2/c_drivers/sdk/Makefile | 33 + .../pynq-z2/c_drivers/sdk/common/main.c | 262 +++ .../pynq-z2/c_drivers/sdk/setup.tcl | 14 + .../python_drivers/axi_stream_driver.py | 75 + .../pynq-z2/tcl_scripts/axi_lite_design.tcl | 26 + .../pynq-z2/tcl_scripts/axi_master_design.tcl | 88 + .../pynq-z2/tcl_scripts/axi_stream_design.tcl | 59 + .../ultra96v2/c_drivers/axi_master_driver.c | 6 + .../ultra96v2/c_drivers/axi_master_driver.h | 6 + .../ultra96v2/c_drivers/sdk/Makefile | 33 + .../ultra96v2/c_drivers/sdk/common/main.c | 262 +++ .../ultra96v2/c_drivers/sdk/setup.tcl | 18 + .../python_drivers/axi_stream_driver.py | 75 + .../ultra96v2/tcl_scripts/axi_lite_design.tcl | 26 + .../tcl_scripts/axi_master_design.tcl | 91 + .../tcl_scripts/axi_stream_design.tcl | 58 + .../vivado_accelerator/vcu128/Readme.md | 1 + .../vcu128/c_drivers/sdk/Makefile | 33 + .../vcu128/c_drivers/sdk/common/main.c | 350 +++ .../vcu128/c_drivers/sdk/setup.tcl | 14 + .../vcu128/tcl_scripts/axi_master_design.tcl | 537 +++++ .../verilog_wrappers/design_1_wrapper.v | 92 + .../python_drivers/axi_stream_driver.py | 75 + .../zcu102/tcl_scripts/axi_stream_design.tcl | 58 + .../python_drivers/axi_stream_driver.py | 75 + .../zcu104/tcl_scripts/axi_stream_design.tcl | 1888 +++++++++++++++++ 44 files changed, 5688 insertions(+) create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc create mode 100644 hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc create mode 100644 hls4ml/templates/vivado_accelerator/build_lib.sh create mode 100644 hls4ml/templates/vivado_accelerator/myproject_axi.cpp create mode 100644 hls4ml/templates/vivado_accelerator/myproject_axi.h create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/Readme.md create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v create mode 100644 hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py create mode 100644 hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl create mode 100644 hls4ml/templates/vivado_accelerator/zcu104/python_drivers/axi_stream_driver.py create mode 100644 hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile new file mode 100644 index 000000000..03ab9b8de --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/Makefile @@ -0,0 +1,33 @@ +DESIGN := design_1 + +help: + @echo "INFO: make to show targets" +.PHONY: help + +--setup: + xsct ./setup.tcl $(DESIGN) +.PHONY: --setup + +sdk: --setup + rm -f $(DESIGN)_standalone/src/helloworld.c + cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c + cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h +.PHONY: sdk + +gui: + xsdk --workspace . & +.PHONY: gui + +clean: + rm -rf $(DESIGN)_platform + rm -rf $(DESIGN)_standalone + rm -rf $(DESIGN)_standalone_bsp + rm -rf RemoteSystemsTempFiles + rm -rf .Xil + rm -rf .metadata + rm -f *.log +.PHONY: clean + +ultraclean: clean + rm -rf hdf/*.hdf +.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c new file mode 100644 index 000000000..41f5dca28 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/common/main.c @@ -0,0 +1,351 @@ +/** + * + * Set Heap Size in ldscript.ld to 0x1000000 (16MB) + * + */ + +#include "xmyproject_axi.h" /* TODO: design-dependent name */ +#include "stdio.h" /* PRINTF */ +#include "unistd.h" /* sleep */ +#include "stdlib.h" +#include "malloc.h" +#include "assert.h" +#include "xil_io.h" /* peripheral read/write wrappers */ +#include "platform.h" /* platform init/cleanup functions */ +#include "xil_cache.h" /* enable/disable caches etc */ +#include "xil_printf.h" /* UART debug print functions */ +#include "xparameters.h" /* peripherals base addresses */ +#include "xtmrctr.h" /* timer, Xilinx IP Timer Counter */ + +#include "data.h" + +#define EEMBC_POWER 1 + +#ifdef EEMBC_POWER +#include "xgpio.h" /* AXI GPIO drivers */ + +#define PIN 0x01 +#define GPIO_PMOD_PIN_DEVICE_ID XPAR_GPIO_0_DEVICE_ID + +#define set_pin_high(InstancePtr, Mask) \ + XGpio_DiscreteWrite(InstancePtr, 1, Mask) + +#define set_pin_low(InstancePtr, Mask) \ + XGpio_DiscreteClear(InstancePtr, 1, Mask) + +XGpio Gpio; +#endif + + +//#define __DEBUG__ + +#define MAX_PRINT_ELEMENTS (16) + +#define PRINTF printf + +const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; +const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; + +#if 1 +/* Accelerator verification */ +#define REFERENCE_OUTPUTS data_y_hls_outputs +#else +/* Accelerator validation */ +#define REFERENCE_OUTPUTS data_y_outputs +//#define REFERENCE_OUTPUTS data_y_keras_outputs +#endif + +unsigned get_max(float *data, unsigned n_elements) { + float max_value = 0.0; + unsigned max_index = 0; + for (unsigned i = 0; i < n_elements; i++) + if (data[i] >= max_value) { + max_index = i; + max_value = data[i]; + } + return max_index; +} + +float *inputs_mem = NULL; +float *outputs_mem = NULL; +float *reference_mem = NULL; + +/* Accelerator configuration */ +XMyproject_axi accelerator; /* TODO: design-dependent name */ +XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ + +/* Accelerator initialization routine */ +void init_accelerators() { + PRINTF("INFO: Initializing accelerator\r\n"); + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_DEVICE_ID); /* TODO: design-dependent name */ + if (accelerator_cfg) { + int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ + if (status != XST_SUCCESS) { + PRINTF("ERROR: Initializing accelerator\r\n"); + } + } +} + +/* Reference implementation of the accelerator in software */ +int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { +#ifdef __DEBUG__ + PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); +#endif + /* See data.h for inputs and outputs */ + for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { + sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; + } + return 0; +} + +/* Profiling utilities */ +static XTmrCtr TimerCounterInst; +#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID +#define TIMER_CNTR_0 0 +#define TIMER_CNTR_1 1 + +void start_64b_counter() { + XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_0); + XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_1); +} + +void stop_64b_counter() { + XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_0); + XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_1); +} + +u64 get_64b_counter_value() { + //printf("bytes %u\n\r", sizeof(u64)); + u64 lo_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_0); + u64 hi_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_1); + u64 counter = (hi_counter << 32) | lo_counter; + //printf("INFO: hi = %lu, lo = %lu, total = %lu\n\r", hi_counter, lo_counter, counter); + return counter; +} + +#if 0 +double get_elapsed_time(u64 clk_start, u64 clk_stop) { + return ((clk_stop-clk_start) * (1.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ)); +} +#endif + +float get_elapsed_time_ns(u64 clks) { + return clks * 1000000000.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ; +} + + +/* Dump data to the console */ +void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { + PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); + /* Print at most MAX_PRINT_ELEMENTS */ + for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { + PRINTF("INFO: [%u] ", i); + for (unsigned j = 0; j < feature_count; j++) { + unsigned index = i * feature_count + j; + PRINTF("%f ", data[index]); + } + PRINTF("\r\n"); + } +} + +/* The top of the hill :-) */ +int main(int argc, char** argv) { + + int status; + u64 calibration_time; + double __attribute__ ((unused)) sw_elapsed = 0; + u64 hw_elapsed = 0; + u64 cache_elapsed = 0; + unsigned hw_errors; + + char __attribute__ ((unused)) dummy; /* dummy input */ + + /* Initialize platform (uart and caches) */ + init_platform(); + + PRINTF("\r\n"); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ + PRINTF("INFO: ==================================================\r\n"); + + init_accelerators(); + + /* Timer Counter */ + status = XTmrCtr_Initialize(&TimerCounterInst, TMRCTR_DEVICE_ID); + if (status != XST_SUCCESS){ + print("ERROR: Timer counter initialization failed \r\n"); + return status; + } + + XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0, + XTC_AUTO_RELOAD_OPTION | + XTC_CASCADE_MODE_OPTION); + + print("INFO: Timer counter initialized\r\n"); + + inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); + outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + + /* Calibration */ + start_64b_counter(); + sleep(1); + stop_64b_counter(); + calibration_time = get_64b_counter_value(); + PRINTF("INFO: Time calibration for one second (%lf sec, %llu clk)\r\n", get_elapsed_time_ns(calibration_time), calibration_time); + + /* Initialize memory */ + PRINTF("INFO: Initialize memory\r\n"); + PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ + PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); + PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); + PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); + PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + + // Set Heap Size in ldscript.ld to 0x1000000 (16MB) + //malloc_stats(); + + for (int i = 0; i < INPUT_N_ELEMENTS; i++) { + inputs_mem[i] = data_X_inputs[i]; + } + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + outputs_mem[i] = 0x0; + } + + /* ****** SW REFERENCE ****** */ + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Start SW reference implementation\r\n"); + start_64b_counter(); + sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); + stop_64b_counter(); + sw_elapsed = get_64b_counter_value(); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + //PRINTF("INFO:"); + + /* ****** HW ACCELERATOR ****** */ + PRINTF("INFO: Start HW accelerator\r\n"); + start_64b_counter(); + Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + stop_64b_counter(); + cache_elapsed = get_64b_counter_value(); + + for (unsigned j = 0; j < N_SAMPLES; j++) { + float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; + float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; + + /* Configure the accelerator */ + start_64b_counter(); + XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ + XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ + + XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ + + /* Polling */ + while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ + + /* Get error status */ + //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ + stop_64b_counter(); + hw_elapsed += get_64b_counter_value(); + } + + start_64b_counter(); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + stop_64b_counter(); + cache_elapsed += get_64b_counter_value(); + + PRINTF("INFO: HW accelerator done!\r\n"); + + /* ****** VALIDATION ****** */ + PRINTF("INFO: ================== Verification ==================\r\n"); +#ifdef __DEBUG__ + PRINTF("INFO: Dump data\r\n"); + dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); + dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); + dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); +#endif + +#ifdef __DEBUG__ + PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); +#endif + PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); + PRINTF("INFO: - total %f sec\r\n", get_elapsed_time_ns(hw_elapsed)); + PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", get_elapsed_time_ns(hw_elapsed) / (N_SAMPLES), (get_elapsed_time_ns(hw_elapsed)*1000.0) / (N_SAMPLES)); + PRINTF("INFO: Cache flush time: %f sec\r\n", get_elapsed_time_ns(cache_elapsed)); +#ifdef __DEBUG__ + PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); +#endif + + hw_errors = 0; +#if 1 + /* Accelerator verification */ + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + if (outputs_mem[i] != reference_mem[i]) { + PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); + hw_errors++; + } + } + PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); + if (hw_errors > 0) + PRINTF("INFO: Verification: FAIL\r\n"); + else + PRINTF("INFO: Verification: PASS!\r\n"); +#else + /* Accelerator validation */ + for (unsigned s = 0; s < N_SAMPLES; s++) { + unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + if (hw_digit != ref_digit) { +#ifdef __DEBUG__ + PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); +#endif + hw_errors++; + } + } + float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; + float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); + PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); + PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); + PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); +#endif + + PRINTF("INFO: ==================================================\r\n"); + + +#ifdef EEMBC_POWER + /* Initialize the GPIO driver */ + status = XGpio_Initialize(&Gpio, GPIO_PMOD_PIN_DEVICE_ID); + if (status != XST_SUCCESS) { + xil_printf("GPIO Initialization Failed\r\n"); + return XST_FAILURE; + } + + set_pin_low(&Gpio, PIN); + + PRINTF("INFO: Connect logic analyzer to the pin 3 of Pmod D\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + + /* Loop forever */ + for (unsigned i; i < 100; i++) { + set_pin_high(&Gpio, PIN); + + sleep(1); + + set_pin_low(&Gpio, PIN); + + sleep(1); + } +#endif + + cleanup_platform(); + + return 0; +} + + diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl new file mode 100644 index 000000000..383bf39cf --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/c_drivers/sdk/setup.tcl @@ -0,0 +1,14 @@ +# See +# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html + +setws . +if { $::argc == 1 } { + set myproject [lindex $::argv 0] + createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf + createapp -name ${myproject}\_standalone -app {Hello World} -proc microblaze_mcu -hwproject ${myproject}\_platform -os standalone + configapp -app ${myproject}\_standalone build-config release + #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} + #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} + projects -build + #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} +} diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl new file mode 100644 index 000000000..67d667b06 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/tcl_scripts/axi_master_design.tcl @@ -0,0 +1,193 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +# Project names +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +set acc_name "${myproject}_axi" +set part_name "xc7a100tcsg324-1" +set board_name "digilentinc.com:arty-a7-100:part0:1.0" + +# Set board and chip part names +create_project ${project_name} ${myproject}_vivado_accelerator -part ${part_name} -force +set_property board_part ${board_name} [current_project] + +# Create block design +create_bd_design ${design_name} + +# Setup IP repo +#set_property ip_repo_paths ${myproject}_prj [current_project] +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + +# Create clock wizard +create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 +apply_board_connection -board_interface "sys_clock" -ip_intf "clk_wiz_0/clock_CLK_IN1" -diagram ${design_name} +set_property name clk_wizard [get_bd_cells clk_wiz_0] +set_property -dict [list CONFIG.CLKOUT2_USED {true} CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {166.667} CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {200.00} CONFIG.MMCM_CLKOUT0_DIVIDE_F {6.000} CONFIG.MMCM_CLKOUT1_DIVIDE {5} CONFIG.NUM_OUT_CLKS {2} CONFIG.CLKOUT1_JITTER {118.758} CONFIG.CLKOUT2_JITTER {114.829} CONFIG.CLKOUT2_PHASE_ERROR {98.575}] [get_bd_cells clk_wizard] +#set_property -dict [list CONFIG.RESET_TYPE {ACTIVE_LOW} CONFIG.RESET_PORT {resetn}] [get_bd_cells clk_wizard] + +# Create MIG +create_bd_cell -type ip -vlnv xilinx.com:ip:mig_7series:4.2 mig_7series_0 +apply_board_connection -board_interface "ddr3_sdram" -ip_intf "mig_7series_0/mig_ddr_interface" -diagram ${design_name} + +# Wire MIG and clock wizard +delete_bd_objs [get_bd_nets clk_ref_i_1] [get_bd_ports clk_ref_i] +delete_bd_objs [get_bd_nets sys_clk_i_1] [get_bd_ports sys_clk_i] +connect_bd_net [get_bd_pins clk_wizard/clk_out2] [get_bd_pins mig_7series_0/clk_ref_i] +connect_bd_net [get_bd_pins clk_wizard/clk_out1] [get_bd_pins mig_7series_0/sys_clk_i] + +# Setup reset +#set_property -dict [list CONFIG.RESET_BOARD_INTERFACE {reset}] [get_bd_cells clk_wizard] +apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {reset ( System Reset ) } Manual_Source {New External Port (ACTIVE_LOW)}} [get_bd_pins mig_7series_0/sys_rst] + +# Create instance of MicroBlaze +create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:11.0 microblaze_mcu +apply_bd_automation -rule xilinx.com:bd_rule:microblaze -config { \ + axi_intc {0} \ + axi_periph {Enabled} \ + cache {16KB} \ + clk {/mig_7series_0/ui_clk (83 MHz)} \ + debug_module {Debug Only} \ + ecc {None} \ + local_mem {32KB} \ + preset {None} } [get_bd_cells microblaze_mcu] + +# Resize data and instruction caches +set_property -dict [list CONFIG.C_ADDR_TAG_BITS {18} CONFIG.C_CACHE_BYTE_SIZE {1024} CONFIG.C_DCACHE_ADDR_TAG {18} CONFIG.C_DCACHE_BYTE_SIZE {1024}] [get_bd_cells microblaze_mcu] + +# Enable full FPU +set_property -dict [list CONFIG.C_USE_FPU {2}] [get_bd_cells microblaze_mcu] + +# Create UART interface +#create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uart16550:2.0 axi_uart +#apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {Auto} Master {/microblaze_mcu (Periph)} Slave {/axi_uart/S_AXI} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_uart/S_AXI] +#apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {usb_uart ( USB UART ) } Manual_Source {Auto}} [get_bd_intf_pins axi_uart/UART] + +# Create UART-lite interface +create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uartlite:2.0 axi_uart +if { ${eembc_power} } { + set_property -dict [list CONFIG.C_BAUDRATE {9600}] [get_bd_cells axi_uart] +} else { + apply_board_connection -board_interface "usb_uart" -ip_intf "axi_uart/UART" -diagram ${design_name} + set_property -dict [list CONFIG.C_BAUDRATE {115200}] [get_bd_cells axi_uart] +} +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master {/microblaze_mcu (Periph)} \ + Slave {/axi_uart/S_AXI} \ + intc_ip {New AXI Interconnect} \ + master_apm {0}} [get_bd_intf_pins axi_uart/S_AXI] + +# Forward UART interface to PMOD pins +if { ${eembc_power} } { + create_bd_port -dir O pmod_uart_txd + create_bd_port -dir I pmod_uart_rxd + connect_bd_net [get_bd_pins /axi_uart/tx] [get_bd_ports pmod_uart_txd] + connect_bd_net [get_bd_pins /axi_uart/rx] [get_bd_ports pmod_uart_rxd] + add_files -fileset constrs_1 -norecurse uart_pmod.xdc +} + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ + Clk_slave {/mig_7series_0/ui_clk (83 MHz)} \ + Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} \ + Master {/microblaze_mcu (Cached)} \ + Slave {/mig_7series_0/S_AXI} \ + intc_ip {Auto} master_apm {0} } [get_bd_intf_pins mig_7series_0/S_AXI] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master {/microblaze_mcu (Periph)} \ + Slave {/axi_uart/S_AXI} \ + intc_ip {New AXI Interconnect} \ + master_apm {0} } [get_bd_intf_pins axi_uart/S_AXI] + +# Add accelerator and connect s-axi interface +create_bd_cell -type ip -vlnv xilinx.com:hls:${acc_name}:1.0 ${acc_name} +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/microblaze_mcu (Periph)} Slave {/${acc_name}/s_axi_CTRL_BUS} intc_ip {/microblaze_mcu_axi_periph} master_apm {0}} [get_bd_intf_pins ${acc_name}/s_axi_CTRL_BUS] + +# Connect m-axi interfaces +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {/mig_7series_0/ui_clk (83 MHz)} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/${acc_name}/m_axi_IN_BUS} Slave {/mig_7series_0/S_AXI} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins ${acc_name}/m_axi_IN_BUS] +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {/mig_7series_0/ui_clk (83 MHz)} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/${acc_name}/m_axi_OUT_BUS} Slave {/mig_7series_0/S_AXI} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins ${acc_name}/m_axi_OUT_BUS] + +# Reset +apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {reset ( System Reset ) } Manual_Source {Auto}} [get_bd_pins clk_wizard/reset] + +# Add timer +create_bd_cell -type ip -vlnv xilinx.com:ip:axi_timer:2.0 axi_timer_mcu +set_property -dict [list CONFIG.enable_timer2 {1}] [get_bd_cells axi_timer_mcu] + +# Wire timer +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/microblaze_mcu (Periph)} Slave {/axi_timer_mcu/S_AXI} intc_ip {/microblaze_mcu_axi_periph} master_apm {0}} [get_bd_intf_pins axi_timer_mcu/S_AXI] + +# Add AXI GPIO controlled pin +if { ${eembc_power} } { + # Add AXI GPIO IP + create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 + # Wire it up to a single output pin (to a PMOD) + set_property -dict [list CONFIG.C_GPIO_WIDTH {1} CONFIG.C_ALL_OUTPUTS {1}] [get_bd_cells axi_gpio_0] + apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {/mig_7series_0/ui_clk (83 MHz)} \ + Clk_slave {Auto} \ + Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} \ + Master {/microblaze_mcu (Periph)} \ + Slave {/axi_gpio_0/S_AXI} \ + intc_ip {/microblaze_mcu_axi_periph} \ + master_apm {0}} [get_bd_intf_pins axi_gpio_0/S_AXI] + create_bd_port -dir O pmod_pin + connect_bd_net [get_bd_ports pmod_pin] [get_bd_pins axi_gpio_0/gpio_io_o] + + add_files -fileset constrs_1 -norecurse pin_pmod.xdc +} + +# Add Quad SPI for cold boot +if { ${eembc_power} } { + create_bd_cell -type ip -vlnv xilinx.com:ip:axi_quad_spi:3.2 axi_quad_spi_0 + set_property -dict [list CONFIG.C_SPI_MEMORY {3}] [get_bd_cells axi_quad_spi_0] + apply_bd_automation -rule xilinx.com:bd_rule:board -config { Board_Interface {qspi_flash ( Quad SPI Flash ) } Manual_Source {Auto}} [get_bd_intf_pins axi_quad_spi_0/SPI_0] + apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {/mig_7series_0/ui_clk (83 MHz)} Clk_slave {Auto} Clk_xbar {/mig_7series_0/ui_clk (83 MHz)} Master {/microblaze_mcu (Periph)} Slave {/axi_quad_spi_0/AXI_LITE} intc_ip {/microblaze_mcu_axi_periph} master_apm {0}} [get_bd_intf_pins axi_quad_spi_0/AXI_LITE] + set_property -dict [list CONFIG.CLKOUT3_USED {true} CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {50} CONFIG.MMCM_CLKOUT2_DIVIDE {20} CONFIG.NUM_OUT_CLKS {3} CONFIG.CLKOUT3_JITTER {151.636} CONFIG.CLKOUT3_PHASE_ERROR {98.575}] [get_bd_cells clk_wizard] + connect_bd_net [get_bd_pins clk_wizard/clk_out3] [get_bd_pins axi_quad_spi_0/ext_spi_clk] + + # BUG FIX + delete_bd_objs [get_bd_nets clk_wizard_clk_out3] + connect_bd_net [get_bd_pins axi_quad_spi_0/ext_spi_clk] [get_bd_pins mig_7series_0/ui_clk] + + add_files -fileset constrs_1 -norecurse qspi.xdc +} + +# Validate the design block we created +validate_bd_design + +# Save design +save_bd_design + +# Top level wrapper +#make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top +#add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v +add_files -norecurse $design_name\_wrapper.v + +# In the Verilog wrapper, enable configuration for the EEMBC power setup +if { ${eembc_power} } { + set_property verilog_define EEMBC_POWER=1 [current_fileset] +} + +# Run synthesis and implementation +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +# Reporting +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages + +# Export HDF file for SDK flow +file mkdir ./hdf +file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v b/hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v new file mode 100644 index 000000000..3bbaf5f9b --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/verilog_wrappers/design_1_wrapper.v @@ -0,0 +1,209 @@ +`timescale 1 ps / 1 ps + +module design_1_wrapper + (ddr3_sdram_addr, + ddr3_sdram_ba, + ddr3_sdram_cas_n, + ddr3_sdram_ck_n, + ddr3_sdram_ck_p, + ddr3_sdram_cke, + ddr3_sdram_cs_n, + ddr3_sdram_dm, + ddr3_sdram_dq, + ddr3_sdram_dqs_n, + ddr3_sdram_dqs_p, + ddr3_sdram_odt, + ddr3_sdram_ras_n, + ddr3_sdram_reset_n, + ddr3_sdram_we_n +`ifdef EEMBC_POWER + , + qspi_flash_io0_io, + qspi_flash_io1_io, + qspi_flash_io2_io, + qspi_flash_io3_io, + qspi_flash_sck_io, + qspi_flash_ss_io + `endif + , + reset, + sys_clock +`ifdef EEMBC_POWER + , + pmod_uart_rxd, + pmod_uart_txd, + pmod_pin +`else + , + usb_uart_rxd, + usb_uart_txd +`endif + ); + output [13:0]ddr3_sdram_addr; + output [2:0]ddr3_sdram_ba; + output ddr3_sdram_cas_n; + output [0:0]ddr3_sdram_ck_n; + output [0:0]ddr3_sdram_ck_p; + output [0:0]ddr3_sdram_cke; + output [0:0]ddr3_sdram_cs_n; + output [1:0]ddr3_sdram_dm; + inout [15:0]ddr3_sdram_dq; + inout [1:0]ddr3_sdram_dqs_n; + inout [1:0]ddr3_sdram_dqs_p; + output [0:0]ddr3_sdram_odt; + output ddr3_sdram_ras_n; + output ddr3_sdram_reset_n; + output ddr3_sdram_we_n; +`ifdef EEMBC_POWER + inout qspi_flash_io0_io; + inout qspi_flash_io1_io; + inout qspi_flash_io2_io; + inout qspi_flash_io3_io; + inout qspi_flash_sck_io; + inout qspi_flash_ss_io; + `endif + input reset; + input sys_clock; +`ifdef EEMBC_POWER + input pmod_uart_rxd; + output pmod_uart_txd; + output pmod_pin; +`else + input usb_uart_rxd; + output usb_uart_txd; +`endif + + + wire [13:0]ddr3_sdram_addr; + wire [2:0]ddr3_sdram_ba; + wire ddr3_sdram_cas_n; + wire [0:0]ddr3_sdram_ck_n; + wire [0:0]ddr3_sdram_ck_p; + wire [0:0]ddr3_sdram_cke; + wire [0:0]ddr3_sdram_cs_n; + wire [1:0]ddr3_sdram_dm; + wire [15:0]ddr3_sdram_dq; + wire [1:0]ddr3_sdram_dqs_n; + wire [1:0]ddr3_sdram_dqs_p; + wire [0:0]ddr3_sdram_odt; + wire ddr3_sdram_ras_n; + wire ddr3_sdram_reset_n; + wire ddr3_sdram_we_n; +`ifdef EEMBC_POWER + wire qspi_flash_io0_i; + wire qspi_flash_io0_io; + wire qspi_flash_io0_o; + wire qspi_flash_io0_t; + wire qspi_flash_io1_i; + wire qspi_flash_io1_io; + wire qspi_flash_io1_o; + wire qspi_flash_io1_t; + wire qspi_flash_io2_i; + wire qspi_flash_io2_io; + wire qspi_flash_io2_o; + wire qspi_flash_io2_t; + wire qspi_flash_io3_i; + wire qspi_flash_io3_io; + wire qspi_flash_io3_o; + wire qspi_flash_io3_t; + wire qspi_flash_sck_i; + wire qspi_flash_sck_io; + wire qspi_flash_sck_o; + wire qspi_flash_sck_t; + wire qspi_flash_ss_i; + wire qspi_flash_ss_io; + wire qspi_flash_ss_o; + wire qspi_flash_ss_t; +`else + wire usb_uart_rxd; + wire usb_uart_txd; +`endif + wire reset; + wire sys_clock; + +`ifdef EEMBC_POWER + IOBUF qspi_flash_io0_iobuf + (.I(qspi_flash_io0_o), + .IO(qspi_flash_io0_io), + .O(qspi_flash_io0_i), + .T(qspi_flash_io0_t)); + IOBUF qspi_flash_io1_iobuf + (.I(qspi_flash_io1_o), + .IO(qspi_flash_io1_io), + .O(qspi_flash_io1_i), + .T(qspi_flash_io1_t)); + IOBUF qspi_flash_io2_iobuf + (.I(qspi_flash_io2_o), + .IO(qspi_flash_io2_io), + .O(qspi_flash_io2_i), + .T(qspi_flash_io2_t)); + IOBUF qspi_flash_io3_iobuf + (.I(qspi_flash_io3_o), + .IO(qspi_flash_io3_io), + .O(qspi_flash_io3_i), + .T(qspi_flash_io3_t)); + IOBUF qspi_flash_sck_iobuf + (.I(qspi_flash_sck_o), + .IO(qspi_flash_sck_io), + .O(qspi_flash_sck_i), + .T(qspi_flash_sck_t)); + IOBUF qspi_flash_ss_iobuf + (.I(qspi_flash_ss_o), + .IO(qspi_flash_ss_io), + .O(qspi_flash_ss_i), + .T(qspi_flash_ss_t)); +`endif + + design_1 design_1_i + (.ddr3_sdram_addr(ddr3_sdram_addr), + .ddr3_sdram_ba(ddr3_sdram_ba), + .ddr3_sdram_cas_n(ddr3_sdram_cas_n), + .ddr3_sdram_ck_n(ddr3_sdram_ck_n), + .ddr3_sdram_ck_p(ddr3_sdram_ck_p), + .ddr3_sdram_cke(ddr3_sdram_cke), + .ddr3_sdram_cs_n(ddr3_sdram_cs_n), + .ddr3_sdram_dm(ddr3_sdram_dm), + .ddr3_sdram_dq(ddr3_sdram_dq), + .ddr3_sdram_dqs_n(ddr3_sdram_dqs_n), + .ddr3_sdram_dqs_p(ddr3_sdram_dqs_p), + .ddr3_sdram_odt(ddr3_sdram_odt), + .ddr3_sdram_ras_n(ddr3_sdram_ras_n), + .ddr3_sdram_reset_n(ddr3_sdram_reset_n), + .ddr3_sdram_we_n(ddr3_sdram_we_n) +`ifdef EEMBC_POWER + , + .qspi_flash_io0_i(qspi_flash_io0_i), + .qspi_flash_io0_o(qspi_flash_io0_o), + .qspi_flash_io0_t(qspi_flash_io0_t), + .qspi_flash_io1_i(qspi_flash_io1_i), + .qspi_flash_io1_o(qspi_flash_io1_o), + .qspi_flash_io1_t(qspi_flash_io1_t), + .qspi_flash_io2_i(qspi_flash_io2_i), + .qspi_flash_io2_o(qspi_flash_io2_o), + .qspi_flash_io2_t(qspi_flash_io2_t), + .qspi_flash_io3_i(qspi_flash_io3_i), + .qspi_flash_io3_o(qspi_flash_io3_o), + .qspi_flash_io3_t(qspi_flash_io3_t), + .qspi_flash_sck_i(qspi_flash_sck_i), + .qspi_flash_sck_o(qspi_flash_sck_o), + .qspi_flash_sck_t(qspi_flash_sck_t), + .qspi_flash_ss_i(qspi_flash_ss_i), + .qspi_flash_ss_o(qspi_flash_ss_o), + .qspi_flash_ss_t(qspi_flash_ss_t) + `endif + , + .reset(reset), + .sys_clock(sys_clock) +`ifdef EEMBC_POWER + , + .pmod_uart_rxd(pmod_uart_rxd), + .pmod_uart_txd(pmod_uart_txd), + .pmod_pin(pmod_pin) +`else + , + .usb_uart_rxd(usb_uart_rxd), + .usb_uart_txd(usb_uart_txd) +`endif + + ); +endmodule diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc new file mode 100644 index 000000000..321279b70 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/pin_pmod.xdc @@ -0,0 +1,4 @@ +# AXI GPIO controlled pin on Pmod Header JD + +# Output pin, PMOD D pin 3 (JD4), IO_L13N_T2_MRCC_35, F4, Blue cable +set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { pmod_pin }]; diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc new file mode 100644 index 000000000..6019da47b --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/qspi.xdc @@ -0,0 +1,13 @@ +# +# See also +# https://github.com/Digilent/digilent-xdc/blob/master/Arty-A7-100-Master.xdc +# + +set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] + +# Quad SPI Flash +set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_ss_io }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_cs +set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io0_io }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_dq[0] +set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io1_io }]; #IO_L1N_T0_D01_DIN_14 Sch=qspi_dq[1] +set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io2_io }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2] +set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { qspi_flash_io3_io }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3] diff --git a/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc new file mode 100644 index 000000000..2cf181a20 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/arty-a7-100t/xdc_constraints/uart_pmod.xdc @@ -0,0 +1,8 @@ +# Expose UART Interface on Pmod Header JA +# You may need https://www.sparkfun.com/products/9873 + +# RX uart, PMOD A pin 2 (JA2), IO_L4P_T0_15, B11, BROWN cable +set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { pmod_uart_rxd }]; + +# TX uart, PMOD A pin 3 (JA3), IO_L4N_T0_15, A11, RED cable +set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { pmod_uart_txd }]; diff --git a/hls4ml/templates/vivado_accelerator/build_lib.sh b/hls4ml/templates/vivado_accelerator/build_lib.sh new file mode 100644 index 000000000..0d0bf156e --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/build_lib.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +CC=g++ +if [[ "$OSTYPE" == "linux-gnu" ]]; then + CFLAGS="-O3 -fPIC -std=c++11 -fno-gnu-unique" +elif [[ "$OSTYPE" == "darwin"* ]]; then + CFLAGS="-O3 -fPIC -std=c++11" +fi +INCFLAGS="-Ifirmware/ap_types/" +PROJECT=myproject +LIB_STAMP=mystamp + +${CC} ${CFLAGS} ${INCFLAGS} -c firmware/${PROJECT}.cpp -o ${PROJECT}.o +${CC} ${CFLAGS} ${INCFLAGS} -c firmware/${PROJECT}_axi.cpp -o ${PROJECT}_axi.o +${CC} ${CFLAGS} ${INCFLAGS} -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o +${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_axi.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so +rm -f *.o + diff --git a/hls4ml/templates/vivado_accelerator/myproject_axi.cpp b/hls4ml/templates/vivado_accelerator/myproject_axi.cpp new file mode 100644 index 000000000..ab61fb4fd --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/myproject_axi.cpp @@ -0,0 +1,20 @@ +//hls-fpga-machine-learning insert include + +void myproject( + input_axi_t in[N_IN], + output_axi_t out[N_OUT] + ){ + + //hls-fpga-machine-learning insert interface + + unsigned short in_size = 0; + unsigned short out_size = 0; + + //hls-fpga-machine-learning insert local vars + + //hls-fpga-machine-learning insert enqueue + + //hls-fpga-machine-learning insert call + + //hls-fpga-machine-learning insert dequeue +} diff --git a/hls4ml/templates/vivado_accelerator/myproject_axi.h b/hls4ml/templates/vivado_accelerator/myproject_axi.h new file mode 100644 index 000000000..fe3dbc5cd --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/myproject_axi.h @@ -0,0 +1,13 @@ +#ifndef MYPROJECT_AXI_H_ +#define MYPROJECT_AXI_H_ + +#include +//hls-fpga-machine-learning insert include + +//hls-fpga-machine-learning insert definitions + +void myproject( + input_axi_t in[N_IN], + output_axi_t out[N_OUT] + ); +#endif diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile new file mode 100644 index 000000000..03ab9b8de --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/Makefile @@ -0,0 +1,33 @@ +DESIGN := design_1 + +help: + @echo "INFO: make to show targets" +.PHONY: help + +--setup: + xsct ./setup.tcl $(DESIGN) +.PHONY: --setup + +sdk: --setup + rm -f $(DESIGN)_standalone/src/helloworld.c + cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c + cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h +.PHONY: sdk + +gui: + xsdk --workspace . & +.PHONY: gui + +clean: + rm -rf $(DESIGN)_platform + rm -rf $(DESIGN)_standalone + rm -rf $(DESIGN)_standalone_bsp + rm -rf RemoteSystemsTempFiles + rm -rf .Xil + rm -rf .metadata + rm -f *.log +.PHONY: clean + +ultraclean: clean + rm -rf hdf/*.hdf +.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c new file mode 100644 index 000000000..7dd2be22a --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/common/main.c @@ -0,0 +1,262 @@ +/** + * + * Set Heap Size in ldscript.ld to 0x1000000 (16MB) + * + */ + +#include "xmyproject_axi.h" /* TODO: design-dependent name */ +#include "stdio.h" /* PRINTF */ +#include "unistd.h" /* sleep */ +#include "stdlib.h" +#include "malloc.h" +#include "assert.h" +#include "xil_io.h" /* peripheral read/write wrappers */ +#include "xtime_l.h" /* to measure performance of the system */ +#include "platform.h" /* platform init/cleanup functions */ +#include "xil_cache.h" /* enable/disable caches etc */ +#include "xil_printf.h" /* UART debug print functions */ +#include "xparameters.h" /* peripherals base addresses */ + +#include "data.h" + +//#define __DEBUG__ + +#define MAX_PRINT_ELEMENTS (16) + +#define PRINTF printf + +const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; +const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; + +#if 1 +/* Accelerator verification */ +#define REFERENCE_OUTPUTS data_y_hls_outputs +#else +/* Accelerator validation */ +#define REFERENCE_OUTPUTS data_y_outputs +//#define REFERENCE_OUTPUTS data_y_keras_outputs +#endif + +unsigned get_max(float *data, unsigned n_elements) { + float max_value = 0.0; + unsigned max_index = 0; + for (unsigned i = 0; i < n_elements; i++) + if (data[i] >= max_value) { + max_index = i; + max_value = data[i]; + } + return max_index; +} + +float *inputs_mem = NULL; +float *outputs_mem = NULL; +float *reference_mem = NULL; + +/* Accelerator configuration */ +XMyproject_axi accelerator; /* TODO: design-dependent name */ +XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ + +/* Accelerator initialization routine */ +void init_accelerators() { + PRINTF("INFO: Initializing accelerator\r\n"); + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ + if (accelerator_cfg) { + int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ + if (status != XST_SUCCESS) { + PRINTF("ERROR: Initializing accelerator\r\n"); + } + } +} + +/* Reference implementation of the accelerator in software */ +int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { +#ifdef __DEBUG__ + PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); +#endif + /* See data.h for inputs and outputs */ + for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { + sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; + } + return 0; +} + +/* Profiling function */ +double get_elapsed_time(XTime start, XTime stop) { + return 1.0 * (stop - start) / (COUNTS_PER_SECOND); +} + +/* Dump data to the console */ +void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { + PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); + /* Print at most MAX_PRINT_ELEMENTS */ + for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { + PRINTF("INFO: [%u] ", i); + for (unsigned j = 0; j < feature_count; j++) { + unsigned index = i * feature_count + j; + PRINTF("%f ", data[index]); + } + PRINTF("\r\n"); + } +} + +/* The top of the hill :-) */ +int main(int argc, char** argv) { + + XTime start, stop; + double calibration_time; + double sw_elapsed = 0; + double hw_elapsed = 0; + double cache_elapsed = 0; + unsigned hw_errors; + + char __attribute__ ((unused)) dummy; /* dummy input */ + + /* Initialize platform (uart and caches) */ + init_platform(); + + PRINTF("\r\n"); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ + PRINTF("INFO: ==================================================\r\n"); + + init_accelerators(); + + inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); + outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + + /* Calibration */ + XTime_GetTime(&start); + sleep(1); + XTime_GetTime(&stop); + calibration_time = get_elapsed_time(start, stop); + PRINTF("INFO: Time calibration for one second (%lf sec)\r\n", calibration_time); + + /* Initialize memory */ + PRINTF("INFO: Initialize memory\r\n"); + PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ + PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); + PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); + PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); + PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + + // Set Heap Size in ldscript.ld to 0x1000000 (16MB) + //malloc_stats(); + + for (int i = 0; i < INPUT_N_ELEMENTS; i++) { + inputs_mem[i] = data_X_inputs[i]; + } + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + outputs_mem[i] = 0x0; + } + + /* ****** SW REFERENCE ****** */ + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Start SW reference implementation\r\n"); + XTime_GetTime(&start); + sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); + XTime_GetTime(&stop); + sw_elapsed = get_elapsed_time(start, stop); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + //PRINTF("INFO:"); + + /* ****** HW ACCELERATOR ****** */ + PRINTF("INFO: Start HW accelerator\r\n"); + + XTime_GetTime(&start); + Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + XTime_GetTime(&stop); + cache_elapsed = get_elapsed_time(start, stop); + + for (unsigned j = 0; j < N_SAMPLES; j++) { + float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; + float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; + + /* Configure the accelerator */ + XTime_GetTime(&start); + XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ + XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ + + XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ + + /* Polling */ + while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ + + /* Get error status */ + //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ + XTime_GetTime(&stop); + hw_elapsed += get_elapsed_time(start, stop); + } + + XTime_GetTime(&start); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + XTime_GetTime(&stop); + cache_elapsed += get_elapsed_time(start, stop); + + PRINTF("INFO: HW accelerator done!\r\n"); + + /* ****** VALIDATION ****** */ + PRINTF("INFO: ================== Verification ==================\r\n"); +#ifdef __DEBUG__ + PRINTF("INFO: Dump data\r\n"); + dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); + dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); + dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); +#endif + +#ifdef __DEBUG__ + PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); +#endif + PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); + PRINTF("INFO: - total %f sec\r\n", hw_elapsed); + PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", hw_elapsed / (N_SAMPLES), (hw_elapsed*1000.0) / (N_SAMPLES)); + PRINTF("INFO: Cache flush time: %f sec\r\n", cache_elapsed); +#ifdef __DEBUG__ + PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); +#endif + + hw_errors = 0; +#if 1 + /* Accelerator verification */ + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + if (outputs_mem[i] != reference_mem[i]) { + PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); + hw_errors++; + } + } + PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); + if (hw_errors > 0) + PRINTF("INFO: Verification: FAIL\r\n"); + else + PRINTF("INFO: Verification: PASS!\r\n"); +#else + /* Accelerator validation */ + for (unsigned s = 0; s < N_SAMPLES; s++) { + unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + if (hw_digit != ref_digit) { +#ifdef __DEBUG__ + PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); +#endif + hw_errors++; + } + } + float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; + float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); + PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); + PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); + PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); +#endif + PRINTF("INFO: ==================================================\r\n"); + + cleanup_platform(); + + return 0; +} + + diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl new file mode 100644 index 000000000..5e9e92d50 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/c_drivers/sdk/setup.tcl @@ -0,0 +1,14 @@ +# See +# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html + +setws . +if { $::argc == 1 } { + set myproject [lindex $::argv 0] + createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf + createapp -name ${myproject}\_standalone -app {Hello World} -proc ps7_cortexa9_0 -hwproject ${myproject}\_platform -os standalone + configapp -app ${myproject}\_standalone build-config release + configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} + configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} + projects -build + #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} +} diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py new file mode 100644 index 000000000..4adb187ab --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/python_drivers/axi_stream_driver.py @@ -0,0 +1,75 @@ +from pynq import DefaultHierarchy, DefaultIP, allocate +from pynq import Overlay +from datetime import datetime +import pynq.lib.dma +import numpy as np + + +class NeuralNetworkOverlay(Overlay): + def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, + device=None): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.sendchannel = self.hier_0.axi_dma_0.sendchannel + self.recvchannel = self.hier_0.axi_dma_0.recvchannel + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def _print_dt(self, timea, timeb, N): + dt = (timeb - timea) + dts = dt.seconds + dt.microseconds * 10 ** -6 + rate = N / dts + print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) + return dts, rate + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + if profile: + timea = datetime.now() + if encode is not None: + X = encode(X) + self.input_buffer[:] = X + self.sendchannel.transfer(self.input_buffer) + self.recvchannel.transfer(self.output_buffer) + if debug: + print("Transfer OK") + self.sendchannel.wait() + if debug: + print("Send OK") + self.recvchannel.wait() + if debug: + print("Receive OK") + # result = self.output_buffer.copy() + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + timeb = datetime.now() + dts, rate = self._print_dt(timea, timeb, len(X)) + return self.output_buffer, dts, rate + else: + return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl new file mode 100644 index 000000000..4f6847ae7 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_lite_design.tcl @@ -0,0 +1,26 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force + +set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +# Create Block Designer design +create_bd_design "design_1" +create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/${myproject}_axi_0/s_axi_AXILiteS} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins ${myproject}_axi_0/s_axi_AXILiteS] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl new file mode 100644 index 000000000..6de05e15a --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_master_design.tcl @@ -0,0 +1,88 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +# Project names +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +set ps_name "processing_system7_0" +set acc_name "${myproject}_axi_0" +set part_name "xc7z020clg400-1" +set board_name "www.digilentinc.com:pynq-z1:part0:1.0" + +# Set board and chip part names +create_project ${project_name} ${myproject}_vivado_accelerator -part ${part_name} -force +set_property board_part ${board_name} [current_project] + +# Create block design +create_bd_design ${design_name} + +# Setup IP repo +#set_property ip_repo_paths ${myproject}_prj [current_project] +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + +# Create and setup PS +create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 ${ps_name} +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells ${ps_name}] +set_property -dict [list CONFIG.PCW_USE_S_AXI_GP0 {1} CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_IRQ_F2P_INTR {1}] [get_bd_cells ${ps_name}] + +# Create accelerator +create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 ${acc_name} + +# Wiring +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {Auto} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master {/myproject_axi_0/m_axi_IN_BUS} \ + Slave {/processing_system7_0/S_AXI_GP0} \ + intc_ip {Auto} \ + master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_GP0] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {Auto} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master {/processing_system7_0/M_AXI_GP0} \ + Slave {/myproject_axi_0/s_axi_CTRL_BUS} \ + intc_ip {New AXI Interconnect} \ + master_apm {0}} [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ + Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ + Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ + Master {/myproject_axi_0/m_axi_OUT_BUS} \ + Slave {/processing_system7_0/S_AXI_GP0} \ + intc_ip {/axi_smc} \ + master_apm {0}} [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] + +# Wiring interrupt signal +connect_bd_net [get_bd_pins myproject_axi_0/interrupt] [get_bd_pins processing_system7_0/IRQ_F2P] + +# Top level wrapper +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top +add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v + +# Memory mapping +delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_IOP] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] +delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_IOP] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] + +# Run synthesis and implementation +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +# Reporting +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages + +# Export HDF file for SDK flow +file mkdir ./hdf +file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl new file mode 100644 index 000000000..f5901c7f3 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z1/tcl_scripts/axi_stream_design.tcl @@ -0,0 +1,59 @@ +#@todo: try to remove startgroup and endgroup and see if it work +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force + +set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +create_bd_design "design_1" + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 +endgroup + +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] + +startgroup +set_property -dict [list CONFIG.PCW_USE_S_AXI_HP0 {1}] [get_bd_cells processing_system7_0] +endgroup + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 +endgroup + +set_property -dict [list CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] +set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] + +startgroup +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_HP0] +endgroup + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {/axi_mem_intercon} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +endgroup + +connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] +connect_bd_intf_net [get_bd_intf_pins ${myproject}_axi_0/out_r] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] + +apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/processing_system7_0/FCLK_CLK0 (100 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] + +group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top + +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile new file mode 100644 index 000000000..03ab9b8de --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/Makefile @@ -0,0 +1,33 @@ +DESIGN := design_1 + +help: + @echo "INFO: make to show targets" +.PHONY: help + +--setup: + xsct ./setup.tcl $(DESIGN) +.PHONY: --setup + +sdk: --setup + rm -f $(DESIGN)_standalone/src/helloworld.c + cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c + cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h +.PHONY: sdk + +gui: + xsdk --workspace . & +.PHONY: gui + +clean: + rm -rf $(DESIGN)_platform + rm -rf $(DESIGN)_standalone + rm -rf $(DESIGN)_standalone_bsp + rm -rf RemoteSystemsTempFiles + rm -rf .Xil + rm -rf .metadata + rm -f *.log +.PHONY: clean + +ultraclean: clean + rm -rf hdf/*.hdf +.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c new file mode 100644 index 000000000..7dd2be22a --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/common/main.c @@ -0,0 +1,262 @@ +/** + * + * Set Heap Size in ldscript.ld to 0x1000000 (16MB) + * + */ + +#include "xmyproject_axi.h" /* TODO: design-dependent name */ +#include "stdio.h" /* PRINTF */ +#include "unistd.h" /* sleep */ +#include "stdlib.h" +#include "malloc.h" +#include "assert.h" +#include "xil_io.h" /* peripheral read/write wrappers */ +#include "xtime_l.h" /* to measure performance of the system */ +#include "platform.h" /* platform init/cleanup functions */ +#include "xil_cache.h" /* enable/disable caches etc */ +#include "xil_printf.h" /* UART debug print functions */ +#include "xparameters.h" /* peripherals base addresses */ + +#include "data.h" + +//#define __DEBUG__ + +#define MAX_PRINT_ELEMENTS (16) + +#define PRINTF printf + +const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; +const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; + +#if 1 +/* Accelerator verification */ +#define REFERENCE_OUTPUTS data_y_hls_outputs +#else +/* Accelerator validation */ +#define REFERENCE_OUTPUTS data_y_outputs +//#define REFERENCE_OUTPUTS data_y_keras_outputs +#endif + +unsigned get_max(float *data, unsigned n_elements) { + float max_value = 0.0; + unsigned max_index = 0; + for (unsigned i = 0; i < n_elements; i++) + if (data[i] >= max_value) { + max_index = i; + max_value = data[i]; + } + return max_index; +} + +float *inputs_mem = NULL; +float *outputs_mem = NULL; +float *reference_mem = NULL; + +/* Accelerator configuration */ +XMyproject_axi accelerator; /* TODO: design-dependent name */ +XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ + +/* Accelerator initialization routine */ +void init_accelerators() { + PRINTF("INFO: Initializing accelerator\r\n"); + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ + if (accelerator_cfg) { + int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ + if (status != XST_SUCCESS) { + PRINTF("ERROR: Initializing accelerator\r\n"); + } + } +} + +/* Reference implementation of the accelerator in software */ +int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { +#ifdef __DEBUG__ + PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); +#endif + /* See data.h for inputs and outputs */ + for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { + sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; + } + return 0; +} + +/* Profiling function */ +double get_elapsed_time(XTime start, XTime stop) { + return 1.0 * (stop - start) / (COUNTS_PER_SECOND); +} + +/* Dump data to the console */ +void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { + PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); + /* Print at most MAX_PRINT_ELEMENTS */ + for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { + PRINTF("INFO: [%u] ", i); + for (unsigned j = 0; j < feature_count; j++) { + unsigned index = i * feature_count + j; + PRINTF("%f ", data[index]); + } + PRINTF("\r\n"); + } +} + +/* The top of the hill :-) */ +int main(int argc, char** argv) { + + XTime start, stop; + double calibration_time; + double sw_elapsed = 0; + double hw_elapsed = 0; + double cache_elapsed = 0; + unsigned hw_errors; + + char __attribute__ ((unused)) dummy; /* dummy input */ + + /* Initialize platform (uart and caches) */ + init_platform(); + + PRINTF("\r\n"); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ + PRINTF("INFO: ==================================================\r\n"); + + init_accelerators(); + + inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); + outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + + /* Calibration */ + XTime_GetTime(&start); + sleep(1); + XTime_GetTime(&stop); + calibration_time = get_elapsed_time(start, stop); + PRINTF("INFO: Time calibration for one second (%lf sec)\r\n", calibration_time); + + /* Initialize memory */ + PRINTF("INFO: Initialize memory\r\n"); + PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ + PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); + PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); + PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); + PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + + // Set Heap Size in ldscript.ld to 0x1000000 (16MB) + //malloc_stats(); + + for (int i = 0; i < INPUT_N_ELEMENTS; i++) { + inputs_mem[i] = data_X_inputs[i]; + } + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + outputs_mem[i] = 0x0; + } + + /* ****** SW REFERENCE ****** */ + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Start SW reference implementation\r\n"); + XTime_GetTime(&start); + sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); + XTime_GetTime(&stop); + sw_elapsed = get_elapsed_time(start, stop); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + //PRINTF("INFO:"); + + /* ****** HW ACCELERATOR ****** */ + PRINTF("INFO: Start HW accelerator\r\n"); + + XTime_GetTime(&start); + Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + XTime_GetTime(&stop); + cache_elapsed = get_elapsed_time(start, stop); + + for (unsigned j = 0; j < N_SAMPLES; j++) { + float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; + float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; + + /* Configure the accelerator */ + XTime_GetTime(&start); + XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ + XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ + + XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ + + /* Polling */ + while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ + + /* Get error status */ + //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ + XTime_GetTime(&stop); + hw_elapsed += get_elapsed_time(start, stop); + } + + XTime_GetTime(&start); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + XTime_GetTime(&stop); + cache_elapsed += get_elapsed_time(start, stop); + + PRINTF("INFO: HW accelerator done!\r\n"); + + /* ****** VALIDATION ****** */ + PRINTF("INFO: ================== Verification ==================\r\n"); +#ifdef __DEBUG__ + PRINTF("INFO: Dump data\r\n"); + dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); + dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); + dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); +#endif + +#ifdef __DEBUG__ + PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); +#endif + PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); + PRINTF("INFO: - total %f sec\r\n", hw_elapsed); + PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", hw_elapsed / (N_SAMPLES), (hw_elapsed*1000.0) / (N_SAMPLES)); + PRINTF("INFO: Cache flush time: %f sec\r\n", cache_elapsed); +#ifdef __DEBUG__ + PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); +#endif + + hw_errors = 0; +#if 1 + /* Accelerator verification */ + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + if (outputs_mem[i] != reference_mem[i]) { + PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); + hw_errors++; + } + } + PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); + if (hw_errors > 0) + PRINTF("INFO: Verification: FAIL\r\n"); + else + PRINTF("INFO: Verification: PASS!\r\n"); +#else + /* Accelerator validation */ + for (unsigned s = 0; s < N_SAMPLES; s++) { + unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + if (hw_digit != ref_digit) { +#ifdef __DEBUG__ + PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); +#endif + hw_errors++; + } + } + float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; + float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); + PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); + PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); + PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); +#endif + PRINTF("INFO: ==================================================\r\n"); + + cleanup_platform(); + + return 0; +} + + diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl new file mode 100644 index 000000000..5e9e92d50 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/c_drivers/sdk/setup.tcl @@ -0,0 +1,14 @@ +# See +# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html + +setws . +if { $::argc == 1 } { + set myproject [lindex $::argv 0] + createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf + createapp -name ${myproject}\_standalone -app {Hello World} -proc ps7_cortexa9_0 -hwproject ${myproject}\_platform -os standalone + configapp -app ${myproject}\_standalone build-config release + configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} + configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} + projects -build + #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} +} diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py new file mode 100644 index 000000000..4adb187ab --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/python_drivers/axi_stream_driver.py @@ -0,0 +1,75 @@ +from pynq import DefaultHierarchy, DefaultIP, allocate +from pynq import Overlay +from datetime import datetime +import pynq.lib.dma +import numpy as np + + +class NeuralNetworkOverlay(Overlay): + def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, + device=None): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.sendchannel = self.hier_0.axi_dma_0.sendchannel + self.recvchannel = self.hier_0.axi_dma_0.recvchannel + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def _print_dt(self, timea, timeb, N): + dt = (timeb - timea) + dts = dt.seconds + dt.microseconds * 10 ** -6 + rate = N / dts + print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) + return dts, rate + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + if profile: + timea = datetime.now() + if encode is not None: + X = encode(X) + self.input_buffer[:] = X + self.sendchannel.transfer(self.input_buffer) + self.recvchannel.transfer(self.output_buffer) + if debug: + print("Transfer OK") + self.sendchannel.wait() + if debug: + print("Send OK") + self.recvchannel.wait() + if debug: + print("Receive OK") + # result = self.output_buffer.copy() + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + timeb = datetime.now() + dts, rate = self._print_dt(timea, timeb, len(X)) + return self.output_buffer, dts, rate + else: + return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl new file mode 100644 index 000000000..4f6847ae7 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_lite_design.tcl @@ -0,0 +1,26 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force + +set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +# Create Block Designer design +create_bd_design "design_1" +create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/${myproject}_axi_0/s_axi_AXILiteS} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins ${myproject}_axi_0/s_axi_AXILiteS] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl new file mode 100644 index 000000000..b3c3ba9c0 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_master_design.tcl @@ -0,0 +1,88 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +# Project names +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +set ps_name "processing_system7_0" +set acc_name "${myproject}_axi_0" +set part_name "xc7z020clg400-1" +set board_name "tul.com.tw:pynq-z2:part0:1.0" + +# Set board and chip part names +create_project ${project_name} ${myproject}_vivado_accelerator -part ${part_name} -force +set_property board_part ${board_name} [current_project] + +# Create block design +create_bd_design ${design_name} + +# Setup IP repo +#set_property ip_repo_paths ${myproject}_prj [current_project] +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + +# Create and setup PS +create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 ${ps_name} +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells ${ps_name}] +set_property -dict [list CONFIG.PCW_USE_S_AXI_GP0 {1} CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_IRQ_F2P_INTR {1}] [get_bd_cells ${ps_name}] + +# Create accelerator +create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 ${acc_name} + +# Wiring +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {Auto} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master {/myproject_axi_0/m_axi_IN_BUS} \ + Slave {/processing_system7_0/S_AXI_GP0} \ + intc_ip {Auto} \ + master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_GP0] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {Auto} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master {/processing_system7_0/M_AXI_GP0} \ + Slave {/myproject_axi_0/s_axi_CTRL_BUS} \ + intc_ip {New AXI Interconnect} \ + master_apm {0}} [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ + Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ + Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} \ + Master {/myproject_axi_0/m_axi_OUT_BUS} \ + Slave {/processing_system7_0/S_AXI_GP0} \ + intc_ip {/axi_smc} \ + master_apm {0}} [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] + +# Wiring interrupt signal +connect_bd_net [get_bd_pins myproject_axi_0/interrupt] [get_bd_pins processing_system7_0/IRQ_F2P] + +# Top level wrapper +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top +add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v + +# Memory mapping +delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_IOP] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_IN_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] +delete_bd_objs [get_bd_addr_segs myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_QSPI_LINEAR] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_IOP] +delete_bd_objs [get_bd_addr_segs -excluded myproject_axi_0/Data_m_axi_OUT_BUS/SEG_processing_system7_0_GP0_M_AXI_GP0] + +# Run synthesis and implementation +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +# Reporting +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages + +# Export HDF file for SDK flow +file mkdir ./hdf +file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl new file mode 100644 index 000000000..f5901c7f3 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/pynq-z2/tcl_scripts/axi_stream_design.tcl @@ -0,0 +1,59 @@ +#@todo: try to remove startgroup and endgroup and see if it work +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xc7z020clg400-1 -force + +set_property board_part tul.com.tw:pynq-z2:part0:1.0 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +create_bd_design "design_1" + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 +endgroup + +apply_bd_automation -rule xilinx.com:bd_rule:processing_system7 -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells processing_system7_0] + +startgroup +set_property -dict [list CONFIG.PCW_USE_S_AXI_HP0 {1}] [get_bd_cells processing_system7_0] +endgroup + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 +endgroup + +set_property -dict [list CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] +set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] + +startgroup +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins processing_system7_0/S_AXI_HP0] +endgroup + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/processing_system7_0/FCLK_CLK0 (100 MHz)} Clk_xbar {/processing_system7_0/FCLK_CLK0 (100 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/processing_system7_0/S_AXI_HP0} ddr_seg {Auto} intc_ip {/axi_mem_intercon} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +endgroup + +connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] +connect_bd_intf_net [get_bd_intf_pins ${myproject}_axi_0/out_r] [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] + +apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/processing_system7_0/FCLK_CLK0 (100 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] + +group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top + +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c new file mode 100644 index 000000000..8a46df8bd --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.c @@ -0,0 +1,6 @@ +#include "xil_printf.h" + +int main(void) { + xil_printf("Hello world!\r\n"); + return 0; +} diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h new file mode 100644 index 000000000..8a46df8bd --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/axi_master_driver.h @@ -0,0 +1,6 @@ +#include "xil_printf.h" + +int main(void) { + xil_printf("Hello world!\r\n"); + return 0; +} diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile new file mode 100644 index 000000000..03ab9b8de --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/Makefile @@ -0,0 +1,33 @@ +DESIGN := design_1 + +help: + @echo "INFO: make to show targets" +.PHONY: help + +--setup: + xsct ./setup.tcl $(DESIGN) +.PHONY: --setup + +sdk: --setup + rm -f $(DESIGN)_standalone/src/helloworld.c + cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c + cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h +.PHONY: sdk + +gui: + xsdk --workspace . & +.PHONY: gui + +clean: + rm -rf $(DESIGN)_platform + rm -rf $(DESIGN)_standalone + rm -rf $(DESIGN)_standalone_bsp + rm -rf RemoteSystemsTempFiles + rm -rf .Xil + rm -rf .metadata + rm -f *.log +.PHONY: clean + +ultraclean: clean + rm -rf hdf/*.hdf +.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c new file mode 100644 index 000000000..7dd2be22a --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/common/main.c @@ -0,0 +1,262 @@ +/** + * + * Set Heap Size in ldscript.ld to 0x1000000 (16MB) + * + */ + +#include "xmyproject_axi.h" /* TODO: design-dependent name */ +#include "stdio.h" /* PRINTF */ +#include "unistd.h" /* sleep */ +#include "stdlib.h" +#include "malloc.h" +#include "assert.h" +#include "xil_io.h" /* peripheral read/write wrappers */ +#include "xtime_l.h" /* to measure performance of the system */ +#include "platform.h" /* platform init/cleanup functions */ +#include "xil_cache.h" /* enable/disable caches etc */ +#include "xil_printf.h" /* UART debug print functions */ +#include "xparameters.h" /* peripherals base addresses */ + +#include "data.h" + +//#define __DEBUG__ + +#define MAX_PRINT_ELEMENTS (16) + +#define PRINTF printf + +const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; +const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; + +#if 1 +/* Accelerator verification */ +#define REFERENCE_OUTPUTS data_y_hls_outputs +#else +/* Accelerator validation */ +#define REFERENCE_OUTPUTS data_y_outputs +//#define REFERENCE_OUTPUTS data_y_keras_outputs +#endif + +unsigned get_max(float *data, unsigned n_elements) { + float max_value = 0.0; + unsigned max_index = 0; + for (unsigned i = 0; i < n_elements; i++) + if (data[i] >= max_value) { + max_index = i; + max_value = data[i]; + } + return max_index; +} + +float *inputs_mem = NULL; +float *outputs_mem = NULL; +float *reference_mem = NULL; + +/* Accelerator configuration */ +XMyproject_axi accelerator; /* TODO: design-dependent name */ +XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ + +/* Accelerator initialization routine */ +void init_accelerators() { + PRINTF("INFO: Initializing accelerator\r\n"); + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ + if (accelerator_cfg) { + int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ + if (status != XST_SUCCESS) { + PRINTF("ERROR: Initializing accelerator\r\n"); + } + } +} + +/* Reference implementation of the accelerator in software */ +int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { +#ifdef __DEBUG__ + PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); +#endif + /* See data.h for inputs and outputs */ + for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { + sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; + } + return 0; +} + +/* Profiling function */ +double get_elapsed_time(XTime start, XTime stop) { + return 1.0 * (stop - start) / (COUNTS_PER_SECOND); +} + +/* Dump data to the console */ +void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { + PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); + /* Print at most MAX_PRINT_ELEMENTS */ + for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { + PRINTF("INFO: [%u] ", i); + for (unsigned j = 0; j < feature_count; j++) { + unsigned index = i * feature_count + j; + PRINTF("%f ", data[index]); + } + PRINTF("\r\n"); + } +} + +/* The top of the hill :-) */ +int main(int argc, char** argv) { + + XTime start, stop; + double calibration_time; + double sw_elapsed = 0; + double hw_elapsed = 0; + double cache_elapsed = 0; + unsigned hw_errors; + + char __attribute__ ((unused)) dummy; /* dummy input */ + + /* Initialize platform (uart and caches) */ + init_platform(); + + PRINTF("\r\n"); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ + PRINTF("INFO: ==================================================\r\n"); + + init_accelerators(); + + inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); + outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + + /* Calibration */ + XTime_GetTime(&start); + sleep(1); + XTime_GetTime(&stop); + calibration_time = get_elapsed_time(start, stop); + PRINTF("INFO: Time calibration for one second (%lf sec)\r\n", calibration_time); + + /* Initialize memory */ + PRINTF("INFO: Initialize memory\r\n"); + PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ + PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); + PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); + PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); + PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + + // Set Heap Size in ldscript.ld to 0x1000000 (16MB) + //malloc_stats(); + + for (int i = 0; i < INPUT_N_ELEMENTS; i++) { + inputs_mem[i] = data_X_inputs[i]; + } + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + outputs_mem[i] = 0x0; + } + + /* ****** SW REFERENCE ****** */ + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Start SW reference implementation\r\n"); + XTime_GetTime(&start); + sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); + XTime_GetTime(&stop); + sw_elapsed = get_elapsed_time(start, stop); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + //PRINTF("INFO:"); + + /* ****** HW ACCELERATOR ****** */ + PRINTF("INFO: Start HW accelerator\r\n"); + + XTime_GetTime(&start); + Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + XTime_GetTime(&stop); + cache_elapsed = get_elapsed_time(start, stop); + + for (unsigned j = 0; j < N_SAMPLES; j++) { + float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; + float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; + + /* Configure the accelerator */ + XTime_GetTime(&start); + XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ + XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ + + XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ + + /* Polling */ + while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ + + /* Get error status */ + //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ + XTime_GetTime(&stop); + hw_elapsed += get_elapsed_time(start, stop); + } + + XTime_GetTime(&start); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + XTime_GetTime(&stop); + cache_elapsed += get_elapsed_time(start, stop); + + PRINTF("INFO: HW accelerator done!\r\n"); + + /* ****** VALIDATION ****** */ + PRINTF("INFO: ================== Verification ==================\r\n"); +#ifdef __DEBUG__ + PRINTF("INFO: Dump data\r\n"); + dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); + dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); + dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); +#endif + +#ifdef __DEBUG__ + PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); +#endif + PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); + PRINTF("INFO: - total %f sec\r\n", hw_elapsed); + PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", hw_elapsed / (N_SAMPLES), (hw_elapsed*1000.0) / (N_SAMPLES)); + PRINTF("INFO: Cache flush time: %f sec\r\n", cache_elapsed); +#ifdef __DEBUG__ + PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); +#endif + + hw_errors = 0; +#if 1 + /* Accelerator verification */ + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + if (outputs_mem[i] != reference_mem[i]) { + PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); + hw_errors++; + } + } + PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); + if (hw_errors > 0) + PRINTF("INFO: Verification: FAIL\r\n"); + else + PRINTF("INFO: Verification: PASS!\r\n"); +#else + /* Accelerator validation */ + for (unsigned s = 0; s < N_SAMPLES; s++) { + unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + if (hw_digit != ref_digit) { +#ifdef __DEBUG__ + PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); +#endif + hw_errors++; + } + } + float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; + float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); + PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); + PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); + PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); +#endif + PRINTF("INFO: ==================================================\r\n"); + + cleanup_platform(); + + return 0; +} + + diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl new file mode 100644 index 000000000..ea386d428 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/c_drivers/sdk/setup.tcl @@ -0,0 +1,18 @@ +# See +# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html + +setws . +if { $::argc == 1 } { + set myproject [lindex $::argv 0] + createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf + createapp -name ${myproject}\_standalone -app {Hello World} -proc psu_cortexa53_0 -hwproject ${myproject}\_platform -os standalone -arch 64 + configbsp -bsp ${myproject}\_standalone_bsp stdin psu_uart_1 + configbsp -bsp ${myproject}\_standalone_bsp stdout psu_uart_1 + updatemss -mss ${myproject}\_standalone_bsp/system.mss + regenbsp -bsp ${myproject}\_standalone_bsp + configapp -app ${myproject}\_standalone build-config release + configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} + configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} + projects -build + #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} +} diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py new file mode 100644 index 000000000..4adb187ab --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/python_drivers/axi_stream_driver.py @@ -0,0 +1,75 @@ +from pynq import DefaultHierarchy, DefaultIP, allocate +from pynq import Overlay +from datetime import datetime +import pynq.lib.dma +import numpy as np + + +class NeuralNetworkOverlay(Overlay): + def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, + device=None): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.sendchannel = self.hier_0.axi_dma_0.sendchannel + self.recvchannel = self.hier_0.axi_dma_0.recvchannel + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def _print_dt(self, timea, timeb, N): + dt = (timeb - timea) + dts = dt.seconds + dt.microseconds * 10 ** -6 + rate = N / dts + print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) + return dts, rate + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + if profile: + timea = datetime.now() + if encode is not None: + X = encode(X) + self.input_buffer[:] = X + self.sendchannel.transfer(self.input_buffer) + self.recvchannel.transfer(self.output_buffer) + if debug: + print("Transfer OK") + self.sendchannel.wait() + if debug: + print("Send OK") + self.recvchannel.wait() + if debug: + print("Receive OK") + # result = self.output_buffer.copy() + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + timeb = datetime.now() + dts, rate = self._print_dt(timea, timeb, len(X)) + return self.output_buffer, dts, rate + else: + return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl new file mode 100644 index 000000000..2df93afca --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_lite_design.tcl @@ -0,0 +1,26 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xczu3eg-sbva484-1-e -force + +set_property board_part em.avnet.com:ultra96:part0:1.2 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +# Create Block Designer design +create_bd_design "design_1" +create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e +apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {make_external "FIXED_IO, DDR" apply_board_preset "1" Master "Disable" Slave "Disable" } [get_bd_cells zynq_ultra_ps_e] +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/processing_system7_0/M_AXI_GP0} Slave {/${myproject}_axi_0/s_axi_AXILiteS} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins ${myproject}_axi_0/s_axi_AXILiteS] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl new file mode 100644 index 000000000..bb91ba9ee --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_master_design.tcl @@ -0,0 +1,91 @@ +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +# Project names +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +set ps_name "zynq_ultra_ps_e_0" +set acc_name "${myproject}_axi_0" + +# Board and chip part names +create_project ${project_name} ${myproject}_vivado_accelerator -part xczu9eg-ffvb1156-2-e -force +set_property board_part avnet.com:ultra96v2:part0:1.2 [current_project] + +# Create block design +create_bd_design ${design_name} + +# Setup IP repo +#set_property ip_repo_paths ${myproject}_prj [current_project] +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + +# Create and setup PS +create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 ${ps_name} +apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } [get_bd_cells ${ps_name}] +set_property -dict [list CONFIG.PSU__USE__S_AXI_GP0 {1} CONFIG.PSU__SAXIGP0__DATA_WIDTH {32}] [get_bd_cells ${ps_name}] + +# Create accelerator +create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 ${acc_name} + +# Wiring +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {Auto} \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master "/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD" \ + Slave "/myproject_axi_0/s_axi_CTRL_BUS" \ + intc_ip {New AXI Interconnect} \ + master_apm {0}} [get_bd_intf_pins ${acc_name}/s_axi_CTRL_BUS] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master {Auto} \ + Clk_slave "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ + Clk_xbar "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ + Master "/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD" \ + Slave "/myproject_axi_0/s_axi_CTRL_BUS" \ + intc_ip {/ps8_0_axi_periph} \ + master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ + Clk_slave {Auto} \ + Clk_xbar {Auto} \ + Master "/myproject_axi_0/m_axi_IN_BUS" \ + Slave "/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD" \ + intc_ip {Auto} \ + master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] + +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { \ + Clk_master "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ + Clk_slave "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ + Clk_xbar "/zynq_ultra_ps_e_0/pl_clk0 (100 MHz)" \ + Master "/myproject_axi_0/m_axi_OUT_BUS" \ + Slave "/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD" \ + intc_ip {/axi_smc} \ + master_apm {0}} [get_bd_intf_pins ${acc_name}/m_axi_OUT_BUS] + +# Wiring interrupt signal +connect_bd_net [get_bd_pins ${acc_name}/interrupt] [get_bd_pins ${ps_name}/pl_ps_irq0] + +# Top level wrapper +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/${design_name}.bd] -top +add_files -norecurse ./${myproject}_vivado_accelerator/${project_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v + +# Memory mapping +delete_bd_objs [get_bd_addr_segs -excluded ${acc_name}/Data_m_axi_IN_BUS/SEG_${ps_name}_HPC0_LPS_OCM] +delete_bd_objs [get_bd_addr_segs -excluded ${acc_name}/Data_m_axi_OUT_BUS/SEG_${ps_name}_HPC0_LPS_OCM] + +# Run synthesis and implementation +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +# Reporting +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages + +# Export HDF file for SDK flow +file mkdir ./hdf +file copy -force ${myproject}_vivado_accelerator/${project_name}.runs/impl_1/${design_name}_wrapper.sysdef ./hdf/${design_name}_wrapper.hdf diff --git a/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl new file mode 100644 index 000000000..4721b5994 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/ultra96v2/tcl_scripts/axi_stream_design.tcl @@ -0,0 +1,58 @@ +#@todo: try to remove startgroup and endgroup and see if it work +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xczu9eg-ffvb1156-2-e -force + +set_property board_part em.avnet.com:ultra96:part0:1.2 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +create_bd_design "design_1" +set_property ip_repo_paths ${myproject}_prj/solution1/impl/ip [current_project] +update_ip_catalog + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e_0 +endgroup + +apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } [get_bd_cells zynq_ultra_ps_e_0] + +set_property -dict [list CONFIG.PSU__USE__S_AXI_GP0 {1} CONFIG.PSU__SAXIGP0__DATA_WIDTH {32}] [get_bd_cells zynq_ultra_ps_e_0] + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 +endgroup +set_property -dict [list CONFIG.c_m_axi_s2mm_data_width.VALUE_SRC USER CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] +set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_m_axi_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] + +startgroup +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {New AXI SmartConnect} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] +endgroup + +startgroup +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {/ps8_0_axi_periph} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] +endgroup + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +endgroup +connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] +connect_bd_intf_net [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] [get_bd_intf_pins ${myproject}_axi_0/out_r] + +apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] +group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top + +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/vcu128/Readme.md b/hls4ml/templates/vivado_accelerator/vcu128/Readme.md new file mode 100644 index 000000000..785d69b84 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/Readme.md @@ -0,0 +1 @@ +This is the test for adding VCU128 board to HLS4ML template. diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile new file mode 100644 index 000000000..03ab9b8de --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/Makefile @@ -0,0 +1,33 @@ +DESIGN := design_1 + +help: + @echo "INFO: make to show targets" +.PHONY: help + +--setup: + xsct ./setup.tcl $(DESIGN) +.PHONY: --setup + +sdk: --setup + rm -f $(DESIGN)_standalone/src/helloworld.c + cd $(DESIGN)_standalone/src && ln -s ../../common/main.c main.c + cd $(DESIGN)_standalone/src && ln -s ../../common/data.h data.h +.PHONY: sdk + +gui: + xsdk --workspace . & +.PHONY: gui + +clean: + rm -rf $(DESIGN)_platform + rm -rf $(DESIGN)_standalone + rm -rf $(DESIGN)_standalone_bsp + rm -rf RemoteSystemsTempFiles + rm -rf .Xil + rm -rf .metadata + rm -f *.log +.PHONY: clean + +ultraclean: clean + rm -rf hdf/*.hdf +.PHONY: ultraclean diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c new file mode 100644 index 000000000..84e3aa3d0 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/common/main.c @@ -0,0 +1,350 @@ +/** + * + * Set Heap Size in ldscript.ld to 0x1000000 (16MB) + * + */ + +#include "xmyproject_axi.h" /* TODO: design-dependent name */ +#include "stdio.h" /* PRINTF */ +#include "unistd.h" /* sleep */ +#include "stdlib.h" +#include "malloc.h" +#include "assert.h" +#include "xil_io.h" /* peripheral read/write wrappers */ +#include "platform.h" /* platform init/cleanup functions */ +#include "xil_cache.h" /* enable/disable caches etc */ +#include "xil_printf.h" /* UART debug print functions */ +#include "xparameters.h" /* peripherals base addresses */ +#include "xtmrctr.h" /* timer, Xilinx IP Timer Counter */ + +#include "data.h" + +/*#define EEMBC_POWER 1 + +#ifdef EEMBC_POWER +#include "xgpio.h" /* AXI GPIO drivers */ + +/*#define PIN 0x01 +#define GPIO_PMOD_PIN_DEVICE_ID XPAR_GPIO_0_DEVICE_ID + +#define set_pin_high(InstancePtr, Mask) \ + XGpio_DiscreteWrite(InstancePtr, 1, Mask) + +#define set_pin_low(InstancePtr, Mask) \ + XGpio_DiscreteClear(InstancePtr, 1, Mask) + +XGpio Gpio; +#endif +*/ + +//#define __DEBUG__ + +#define MAX_PRINT_ELEMENTS (16) + +#define PRINTF printf + +const unsigned INPUT_N_ELEMENTS = N_SAMPLES * N_X_INPUTS; +const unsigned OUTPUT_N_ELEMENTS = N_SAMPLES * N_Y_OUTPUTS; + +#if 1 +/* Accelerator verification */ +#define REFERENCE_OUTPUTS data_y_hls_outputs +#else +/* Accelerator validation */ +#define REFERENCE_OUTPUTS data_y_outputs +//#define REFERENCE_OUTPUTS data_y_keras_outputs +#endif + +unsigned get_max(float *data, unsigned n_elements) { + float max_value = 0.0; + unsigned max_index = 0; + for (unsigned i = 0; i < n_elements; i++) + if (data[i] >= max_value) { + max_index = i; + max_value = data[i]; + } + return max_index; +} + +float *inputs_mem = NULL; +float *outputs_mem = NULL; +float *reference_mem = NULL; + +/* Accelerator configuration */ +XMyproject_axi accelerator; /* TODO: design-dependent name */ +XMyproject_axi_Config *accelerator_cfg; /* TODO: design-dependent name */ + +/* Accelerator initialization routine */ +void init_accelerators() { + PRINTF("INFO: Initializing accelerator\r\n"); + accelerator_cfg = XMyproject_axi_LookupConfig(XPAR_MYPROJECT_AXI_0_DEVICE_ID); /* TODO: design-dependent name */ + if (accelerator_cfg) { + int status = XMyproject_axi_CfgInitialize(&accelerator, accelerator_cfg); /* TODO: design-dependent name */ + if (status != XST_SUCCESS) { + PRINTF("ERROR: Initializing accelerator\r\n"); + } + } +} + +/* Reference implementation of the accelerator in software */ +int sw_reference_implementation(float *sw_inputs_mem, float *sw_outputs_mem, unsigned n_samples, unsigned n_X_inputs, unsigned n_y_ouputs) { +#ifdef __DEBUG__ + PRINTF("INFO: Reference outputs are pre-compiled. It would be nice to run a software model here.\r\n"); +#endif + /* See data.h for inputs and outputs */ + for (unsigned i = 0; i < n_samples * n_y_ouputs; i++) { + sw_outputs_mem[i] = REFERENCE_OUTPUTS[i]; + } + return 0; +} + +/* Profiling utilities */ +static XTmrCtr TimerCounterInst; +#define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID +#define TIMER_CNTR_0 0 +#define TIMER_CNTR_1 1 + +void start_64b_counter() { + XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_0); + XTmrCtr_Start(&TimerCounterInst, TIMER_CNTR_1); +} + +void stop_64b_counter() { + XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_0); + XTmrCtr_Stop(&TimerCounterInst, TIMER_CNTR_1); +} + +u64 get_64b_counter_value() { + //printf("bytes %u\n\r", sizeof(u64)); + u64 lo_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_0); + u64 hi_counter = XTmrCtr_GetValue(&TimerCounterInst, TIMER_CNTR_1); + u64 counter = (hi_counter << 32) | lo_counter; + //printf("INFO: hi = %lu, lo = %lu, total = %lu\n\r", hi_counter, lo_counter, counter); + return counter; +} + +#if 0 +double get_elapsed_time(u64 clk_start, u64 clk_stop) { + return ((clk_stop-clk_start) * (1.0/XPAR_AXI_TIMER_MCU_CLOCK_FREQ_HZ)); +} +#endif + +float get_elapsed_time_ns(u64 clks) { + return clks * 1000000000.0/XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ; +} + + +/* Dump data to the console */ +void dump_data(const char* label, float* data, unsigned n_samples, unsigned feature_count) { + PRINTF("INFO: %s[%u][%u]:\r\n", label, n_samples, feature_count); + /* Print at most MAX_PRINT_ELEMENTS */ + for (unsigned i = 0; i < n_samples && i < MAX_PRINT_ELEMENTS; i++) { + PRINTF("INFO: [%u] ", i); + for (unsigned j = 0; j < feature_count; j++) { + unsigned index = i * feature_count + j; + PRINTF("%f ", data[index]); + } + PRINTF("\r\n"); + } +} + +/* The top of the hill :-) */ +int main(int argc, char** argv) { + + int status; + u64 calibration_time; + double __attribute__ ((unused)) sw_elapsed = 0; + u64 hw_elapsed = 0; + u64 cache_elapsed = 0; + unsigned hw_errors; + + char __attribute__ ((unused)) dummy; /* dummy input */ + + /* Initialize platform (uart and caches) */ + init_platform(); + + PRINTF("\r\n"); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: XMyproject_axi (w/ polling)\r\n"); /* TODO: design-dependent name */ + PRINTF("INFO: ==================================================\r\n"); + + init_accelerators(); + + /* Timer Counter */ + status = XTmrCtr_Initialize(&TimerCounterInst, TMRCTR_DEVICE_ID); + if (status != XST_SUCCESS){ + print("ERROR: Timer counter initialization failed \r\n"); + return status; + } + + XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0, + XTC_AUTO_RELOAD_OPTION | + XTC_CASCADE_MODE_OPTION); + + print("INFO: Timer counter initialized\r\n"); + + inputs_mem = malloc(INPUT_N_ELEMENTS * sizeof(float)); + outputs_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + reference_mem = malloc(OUTPUT_N_ELEMENTS * sizeof(float)); + + /* Calibration */ + start_64b_counter(); + sleep(1); + stop_64b_counter(); + calibration_time = get_64b_counter_value(); + PRINTF("INFO: Time calibration for one second (%lf sec, %llu clk)\r\n", get_elapsed_time_ns(calibration_time), calibration_time); + + /* Initialize memory */ + PRINTF("INFO: Initialize memory\r\n"); + PRINTF("INFO: - Samples count: %u\r\n", N_SAMPLES); /* Same as dst_SAMPLE_COUNT */ + PRINTF("INFO: - Inputs count: %u\r\n", N_X_INPUTS); + PRINTF("INFO: - Outputs count: %u\r\n", N_Y_OUTPUTS); + PRINTF("INFO: - Data size: %u B\r\n", sizeof(float)); + PRINTF("INFO: - Total input size: %u B, %.2f KB, %.2f MB\r\n", N_X_INPUTS * N_SAMPLES * sizeof(float), (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_X_INPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + PRINTF("INFO: - Total output size: %u B, %.2f KB, %.2f MB\r\n", N_Y_OUTPUTS * N_SAMPLES * sizeof(float), (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)1024, (N_Y_OUTPUTS * N_SAMPLES * sizeof(float)) / (float)(1024*1024)); + + // Set Heap Size in ldscript.ld to 0x1000000 (16MB) + //malloc_stats(); + + for (int i = 0; i < INPUT_N_ELEMENTS; i++) { + inputs_mem[i] = data_X_inputs[i]; + } + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + outputs_mem[i] = 0x0; + } + + /* ****** SW REFERENCE ****** */ + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Start SW reference implementation\r\n"); + start_64b_counter(); + sw_reference_implementation(inputs_mem, reference_mem, N_SAMPLES, N_X_INPUTS, N_Y_OUTPUTS); + stop_64b_counter(); + sw_elapsed = get_64b_counter_value(); + PRINTF("INFO: ==================================================\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + //PRINTF("INFO:"); + + /* ****** HW ACCELERATOR ****** */ + PRINTF("INFO: Start HW accelerator\r\n"); + start_64b_counter(); + Xil_DCacheFlushRange((UINTPTR)inputs_mem, INPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + Xil_DCacheFlushRange((UINTPTR)reference_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + stop_64b_counter(); + cache_elapsed = get_64b_counter_value(); + + for (unsigned j = 0; j < N_SAMPLES; j++) { + float *inputs_mem_i = inputs_mem + j * N_X_INPUTS; + float *outputs_mem_i = outputs_mem + j * N_Y_OUTPUTS; + + /* Configure the accelerator */ + start_64b_counter(); + XMyproject_axi_Set_in_r(&accelerator, (unsigned)inputs_mem_i); /* TODO: design-dependent name */ + XMyproject_axi_Set_out_r(&accelerator, (unsigned)outputs_mem_i); /* TODO: design-dependent name */ + + XMyproject_axi_Start(&accelerator); /* TODO: design-dependent name */ + + /* Polling */ + while (!XMyproject_axi_IsDone(&accelerator)); /* TODO: design-dependent name */ + + /* Get error status */ + //hw_flags = XMyproject_axi_Get_return(&accelerator); /* TODO: design-dependent name */ + stop_64b_counter(); + hw_elapsed += get_64b_counter_value(); + } + + start_64b_counter(); + Xil_DCacheFlushRange((UINTPTR)outputs_mem, OUTPUT_N_ELEMENTS * sizeof(float)); + stop_64b_counter(); + cache_elapsed += get_64b_counter_value(); + + PRINTF("INFO: HW accelerator done!\r\n"); + + /* ****** VALIDATION ****** */ + PRINTF("INFO: ================== Verification ==================\r\n"); +#ifdef __DEBUG__ + PRINTF("INFO: Dump data\r\n"); + dump_data("inputs_mem", inputs_mem, N_SAMPLES, N_X_INPUTS); + dump_data("outputs_mem", outputs_mem, N_SAMPLES, N_Y_OUTPUTS); + dump_data("reference_mem", reference_mem, N_SAMPLES, N_Y_OUTPUTS); +#endif + +#ifdef __DEBUG__ + PRINTF("INFO: SW execution time: %f sec\r\n", sw_elapsed); +#endif + PRINTF("INFO: HW-acceleration exec. time (%d inferences):\r\n", N_SAMPLES); + PRINTF("INFO: - total %f sec\r\n", get_elapsed_time_ns(hw_elapsed)); + PRINTF("INFO: - per-inference %.12f sec (%f ns)\r\n", get_elapsed_time_ns(hw_elapsed) / (N_SAMPLES), (get_elapsed_time_ns(hw_elapsed)*1000.0) / (N_SAMPLES)); + PRINTF("INFO: Cache flush time: %f sec\r\n", get_elapsed_time_ns(cache_elapsed)); +#ifdef __DEBUG__ + PRINTF("INFO: HW/SW speedup (the software is fake so this does not count...): %.2f X\r\n", (sw_elapsed >= (hw_elapsed+cache_elapsed))?(sw_elapsed/(hw_elapsed+cache_elapsed)):-((hw_elapsed+cache_elapsed)/sw_elapsed)); +#endif + + hw_errors = 0; +#if 1 + /* Accelerator verification */ + for (int i = 0; i < OUTPUT_N_ELEMENTS; i++) { + if (outputs_mem[i] != reference_mem[i]) { + PRINTF("ERROR: [%d]: Accelerator HW %f != SW %f\r\n", i, outputs_mem[i], reference_mem[i]); + hw_errors++; + } + } + PRINTF("INFO: Total errors = %d (out of %d elements)\r\n", hw_errors, OUTPUT_N_ELEMENTS); + if (hw_errors > 0) + PRINTF("INFO: Verification: FAIL\r\n"); + else + PRINTF("INFO: Verification: PASS!\r\n"); +#else + /* Accelerator validation */ + for (unsigned s = 0; s < N_SAMPLES; s++) { + unsigned ref_digit = get_max(reference_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + unsigned hw_digit = get_max(outputs_mem + s * N_Y_OUTPUTS, N_Y_OUTPUTS); + if (hw_digit != ref_digit) { +#ifdef __DEBUG__ + PRINTF("ERROR: [%d]: Accelerator HW %u != SW %u\r\n", s, hw_digit, ref_digit); +#endif + hw_errors++; + } + } + float error_rate = (hw_errors / (float)(N_SAMPLES)) * 100.0; + float accuracy = 100 - ((hw_errors / (float)(N_SAMPLES)) * 100.0); + PRINTF("INFO: Total errors = %d (out of %d digits)\r\n", hw_errors, N_SAMPLES); + PRINTF("INFO: Error rate = %.2f %%\r\n", error_rate); + PRINTF("INFO: Accuracy = %.2f %%\r\n", accuracy); +#endif + + PRINTF("INFO: ==================================================\r\n"); + + +#ifdef EEMBC_POWER + /* Initialize the GPIO driver */ + status = XGpio_Initialize(&Gpio, GPIO_PMOD_PIN_DEVICE_ID); + if (status != XST_SUCCESS) { + xil_printf("GPIO Initialization Failed\r\n"); + return XST_FAILURE; + } + + set_pin_low(&Gpio, PIN); + + PRINTF("INFO: Connect logic analyzer to the pin 3 of Pmod D\r\n"); + PRINTF("INFO: Press any key to start:\r\n"); + dummy = inbyte(); + + /* Loop forever */ + for (unsigned i; i < 100; i++) { + set_pin_high(&Gpio, PIN); + + sleep(1); + + set_pin_low(&Gpio, PIN); + + sleep(1); + } +#endif + + cleanup_platform(); + + return 0; +} + diff --git a/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl new file mode 100644 index 000000000..383bf39cf --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/c_drivers/sdk/setup.tcl @@ -0,0 +1,14 @@ +# See +# https://www.xilinx.com/html_docs/xilinx2019_1/SDK_Doc/xsct/intro/xsct_introduction.html + +setws . +if { $::argc == 1 } { + set myproject [lindex $::argv 0] + createhw -name ${myproject}\_platform -hwspec ../hdf/${myproject}\_wrapper.hdf + createapp -name ${myproject}\_standalone -app {Hello World} -proc microblaze_mcu -hwproject ${myproject}\_platform -os standalone + configapp -app ${myproject}\_standalone build-config release + #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_HEAP_SIZE=0x1000000} + #configapp -app ${myproject}\_standalone -add linker-misc {-Wl,--defsym=_STACK_SIZE=0x40000} + projects -build + #configapp -app ${myproject}\_standalone -add define-compiler-symbols {FLAG=VALUE} +} diff --git a/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl new file mode 100644 index 000000000..a0540bcb5 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/tcl_scripts/axi_master_design.tcl @@ -0,0 +1,537 @@ + +################################################################ +# +# MIT License +# +# Copyright (c) 2022 University of Sherbrooke +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# Author : Mehdi Rahimifar +# Last update : 2022-08-25 +# Description : This contains the tcl scripts to generate the right block design for VCU128 and the accelerator from hls4ml in Vivado +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + + + +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source design_1_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + + + +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +#set acc_name "${myproject}_axi" +set part_name "xcvu37p-fsvh2892-2L-e" +set board_name "xilinx.com:vcu128:part0:1.0" + + + + + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 ${myproject}_vivado_accelerator -part xcvu37p-fsvh2892-2L-e -force + set_property BOARD_PART xilinx.com:vcu128:part0:1.0 [current_project] +} + + + + +# Setup IP repo +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +#set_property ip_repo_paths /home/subnugler/Desktop/MICROBLAZE_TEST/Microblaze/myproject_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + + + + + + +#CHANGED HERE!!!!!!!!!!! + +# CHANGE DESIGN NAME HERE +#variable design_name +#set design_name design_1 + + + + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:smartconnect:1.0\ +xilinx.com:ip:axi_timer:2.0\ +xilinx.com:ip:axi_uart16550:2.0\ +xilinx.com:ip:clk_wiz:6.0\ +xilinx.com:ip:ddr4:2.2\ +xilinx.com:ip:mdm:3.2\ +xilinx.com:ip:microblaze:11.0\ +xilinx.com:hls:myproject_axi:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:lmb_bram_if_cntlr:4.0\ +xilinx.com:ip:lmb_v10:3.0\ +xilinx.com:ip:blk_mem_gen:8.4\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + +# Hierarchical cell: microblaze_0_local_memory +proc create_hier_cell_microblaze_0_local_memory { parentCell nameHier } { + + variable script_folder + + if { $parentCell eq "" || $nameHier eq "" } { + catch {common::send_msg_id "BD_TCL-102" "ERROR" "create_hier_cell_microblaze_0_local_memory() - Empty argument(s)!"} + return + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + # Create cell and set as current instance + set hier_obj [create_bd_cell -type hier $nameHier] + current_bd_instance $hier_obj + + # Create interface pins + create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 DLMB + + create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 ILMB + + + # Create pins + create_bd_pin -dir I -type clk LMB_Clk + create_bd_pin -dir I -type rst SYS_Rst + + # Create instance: dlmb_bram_if_cntlr, and set properties + set dlmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 dlmb_bram_if_cntlr ] + set_property -dict [ list \ + CONFIG.C_ECC {0} \ + ] $dlmb_bram_if_cntlr + + # Create instance: dlmb_v10, and set properties + set dlmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 dlmb_v10 ] + + # Create instance: ilmb_bram_if_cntlr, and set properties + set ilmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 ilmb_bram_if_cntlr ] + set_property -dict [ list \ + CONFIG.C_ECC {0} \ + ] $ilmb_bram_if_cntlr + + # Create instance: ilmb_v10, and set properties + set ilmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 ilmb_v10 ] + + # Create instance: lmb_bram, and set properties + set lmb_bram [ create_bd_cell -type ip -vlnv xilinx.com:ip:blk_mem_gen:8.4 lmb_bram ] + set_property -dict [ list \ + CONFIG.Memory_Type {True_Dual_Port_RAM} \ + CONFIG.use_bram_block {BRAM_Controller} \ + ] $lmb_bram + + # Create interface connections + connect_bd_intf_net -intf_net microblaze_0_dlmb [get_bd_intf_pins DLMB] [get_bd_intf_pins dlmb_v10/LMB_M] + connect_bd_intf_net -intf_net microblaze_0_dlmb_bus [get_bd_intf_pins dlmb_bram_if_cntlr/SLMB] [get_bd_intf_pins dlmb_v10/LMB_Sl_0] + connect_bd_intf_net -intf_net microblaze_0_dlmb_cntlr [get_bd_intf_pins dlmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTA] + connect_bd_intf_net -intf_net microblaze_0_ilmb [get_bd_intf_pins ILMB] [get_bd_intf_pins ilmb_v10/LMB_M] + connect_bd_intf_net -intf_net microblaze_0_ilmb_bus [get_bd_intf_pins ilmb_bram_if_cntlr/SLMB] [get_bd_intf_pins ilmb_v10/LMB_Sl_0] + connect_bd_intf_net -intf_net microblaze_0_ilmb_cntlr [get_bd_intf_pins ilmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTB] + + # Create port connections + connect_bd_net -net SYS_Rst_1 [get_bd_pins SYS_Rst] [get_bd_pins dlmb_bram_if_cntlr/LMB_Rst] [get_bd_pins dlmb_v10/SYS_Rst] [get_bd_pins ilmb_bram_if_cntlr/LMB_Rst] [get_bd_pins ilmb_v10/SYS_Rst] + connect_bd_net -net microblaze_0_Clk [get_bd_pins LMB_Clk] [get_bd_pins dlmb_bram_if_cntlr/LMB_Clk] [get_bd_pins dlmb_v10/LMB_Clk] [get_bd_pins ilmb_bram_if_cntlr/LMB_Clk] [get_bd_pins ilmb_v10/LMB_Clk] + + # Restore current instance + current_bd_instance $oldCurInst +} + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set ddr4_sdram [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddr4_rtl:1.0 ddr4_sdram ] + + set default_100mhz_clk [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 default_100mhz_clk ] + set_property -dict [ list \ + CONFIG.FREQ_HZ {100000000} \ + ] $default_100mhz_clk + + set rs232_uart_0 [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:uart_rtl:1.0 rs232_uart_0 ] + + + # Create ports + set dummy_port_in [ create_bd_port -dir I -type rst dummy_port_in ] + set_property -dict [ list \ + CONFIG.POLARITY {ACTIVE_HIGH} \ + ] $dummy_port_in + + # Create instance: axi_smc, and set properties + set axi_smc [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_smc ] + set_property -dict [ list \ + CONFIG.NUM_CLKS {2} \ + CONFIG.NUM_SI {4} \ + ] $axi_smc + + # Create instance: axi_timer_0, and set properties + set axi_timer_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_timer:2.0 axi_timer_0 ] + + # Create instance: axi_uart16550_0, and set properties + set axi_uart16550_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uart16550:2.0 axi_uart16550_0 ] + set_property -dict [ list \ + CONFIG.UART_BOARD_INTERFACE {rs232_uart_0} \ + CONFIG.USE_BOARD_FLOW {true} \ + ] $axi_uart16550_0 + + # Create instance: clk_wiz_0, and set properties + set clk_wiz_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 clk_wiz_0 ] + set_property -dict [ list \ + CONFIG.CLKOUT1_JITTER {166.057} \ + CONFIG.CLKOUT1_PHASE_ERROR {298.404} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {125.000} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {125.000} \ + CONFIG.RESET_BOARD_INTERFACE {Custom} \ + CONFIG.USE_BOARD_FLOW {true} \ + ] $clk_wiz_0 + + # Create instance: ddr4_0, and set properties + set ddr4_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:ddr4:2.2 ddr4_0 ] + set_property -dict [ list \ + CONFIG.C0_CLOCK_BOARD_INTERFACE {default_100mhz_clk} \ + CONFIG.C0_DDR4_BOARD_INTERFACE {ddr4_sdram} \ + CONFIG.RESET_BOARD_INTERFACE {dummy_port_in} \ + ] $ddr4_0 + + # Create instance: mdm_1, and set properties + set mdm_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mdm:3.2 mdm_1 ] + + # Create instance: microblaze_0, and set properties + set microblaze_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:11.0 microblaze_0 ] + set_property -dict [ list \ + CONFIG.C_ADDR_TAG_BITS {16} \ + CONFIG.C_CACHE_BYTE_SIZE {32768} \ + CONFIG.C_DCACHE_ADDR_TAG {16} \ + CONFIG.C_DCACHE_BYTE_SIZE {32768} \ + CONFIG.C_DCACHE_USE_WRITEBACK {1} \ + CONFIG.C_DEBUG_ENABLED {1} \ + CONFIG.C_DIV_ZERO_EXCEPTION {1} \ + CONFIG.C_D_AXI {1} \ + CONFIG.C_D_LMB {1} \ + CONFIG.C_FPU_EXCEPTION {1} \ + CONFIG.C_ICACHE_LINE_LEN {8} \ + CONFIG.C_ICACHE_STREAMS {1} \ + CONFIG.C_ICACHE_VICTIMS {8} \ + CONFIG.C_ILL_OPCODE_EXCEPTION {1} \ + CONFIG.C_I_LMB {1} \ + CONFIG.C_MMU_ZONES {2} \ + CONFIG.C_M_AXI_D_BUS_EXCEPTION {1} \ + CONFIG.C_M_AXI_I_BUS_EXCEPTION {1} \ + CONFIG.C_NUMBER_OF_PC_BRK {2} \ + CONFIG.C_NUMBER_OF_RD_ADDR_BRK {1} \ + CONFIG.C_NUMBER_OF_WR_ADDR_BRK {1} \ + CONFIG.C_OPCODE_0x0_ILLEGAL {1} \ + CONFIG.C_PVR {2} \ + CONFIG.C_UNALIGNED_EXCEPTIONS {1} \ + CONFIG.C_USE_BARREL {1} \ + CONFIG.C_USE_DCACHE {1} \ + CONFIG.C_USE_DIV {1} \ + CONFIG.C_USE_FPU {1} \ + CONFIG.C_USE_HW_MUL {2} \ + CONFIG.C_USE_ICACHE {1} \ + CONFIG.C_USE_MMU {3} \ + CONFIG.C_USE_MSR_INSTR {1} \ + CONFIG.C_USE_PCMP_INSTR {1} \ + CONFIG.G_TEMPLATE_LIST {10} \ + CONFIG.G_USE_EXCEPTIONS {1} \ + ] $microblaze_0 + + # Create instance: microblaze_0_axi_periph, and set properties + set microblaze_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 microblaze_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {4} \ + ] $microblaze_0_axi_periph + + # Create instance: microblaze_0_local_memory + create_hier_cell_microblaze_0_local_memory [current_bd_instance .] microblaze_0_local_memory + + # Create instance: myproject_axi_0, and set properties + set myproject_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 myproject_axi_0 ] + + # Create instance: rst_clk_wiz_0_100M, and set properties + set rst_clk_wiz_0_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_clk_wiz_0_100M ] + set_property -dict [ list \ + CONFIG.RESET_BOARD_INTERFACE {Custom} \ + CONFIG.USE_BOARD_FLOW {true} \ + ] $rst_clk_wiz_0_100M + + # Create instance: rst_ddr4_0_333M, and set properties + set rst_ddr4_0_333M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ddr4_0_333M ] + + # Create interface connections + connect_bd_intf_net -intf_net axi_smc_M00_AXI [get_bd_intf_pins axi_smc/M00_AXI] [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI] + connect_bd_intf_net -intf_net axi_uart16550_0_UART [get_bd_intf_ports rs232_uart_0] [get_bd_intf_pins axi_uart16550_0/UART] + connect_bd_intf_net -intf_net ddr4_0_C0_DDR4 [get_bd_intf_ports ddr4_sdram] [get_bd_intf_pins ddr4_0/C0_DDR4] + connect_bd_intf_net -intf_net default_100mhz_clk_1 [get_bd_intf_ports default_100mhz_clk] [get_bd_intf_pins ddr4_0/C0_SYS_CLK] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_DC [get_bd_intf_pins axi_smc/S00_AXI] [get_bd_intf_pins microblaze_0/M_AXI_DC] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_DP [get_bd_intf_pins microblaze_0/M_AXI_DP] [get_bd_intf_pins microblaze_0_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_IC [get_bd_intf_pins axi_smc/S01_AXI] [get_bd_intf_pins microblaze_0/M_AXI_IC] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M00_AXI [get_bd_intf_pins axi_timer_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M00_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M01_AXI [get_bd_intf_pins axi_uart16550_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M01_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M02_AXI [get_bd_intf_pins ddr4_0/C0_DDR4_S_AXI_CTRL] [get_bd_intf_pins microblaze_0_axi_periph/M02_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M03_AXI [get_bd_intf_pins microblaze_0_axi_periph/M03_AXI] [get_bd_intf_pins myproject_axi_0/s_axi_CTRL_BUS] + connect_bd_intf_net -intf_net microblaze_0_debug [get_bd_intf_pins mdm_1/MBDEBUG_0] [get_bd_intf_pins microblaze_0/DEBUG] + connect_bd_intf_net -intf_net microblaze_0_dlmb_1 [get_bd_intf_pins microblaze_0/DLMB] [get_bd_intf_pins microblaze_0_local_memory/DLMB] + connect_bd_intf_net -intf_net microblaze_0_ilmb_1 [get_bd_intf_pins microblaze_0/ILMB] [get_bd_intf_pins microblaze_0_local_memory/ILMB] + connect_bd_intf_net -intf_net myproject_axi_0_m_axi_IN_BUS [get_bd_intf_pins axi_smc/S02_AXI] [get_bd_intf_pins myproject_axi_0/m_axi_IN_BUS] + connect_bd_intf_net -intf_net myproject_axi_0_m_axi_OUT_BUS [get_bd_intf_pins axi_smc/S03_AXI] [get_bd_intf_pins myproject_axi_0/m_axi_OUT_BUS] + + # Create port connections + connect_bd_net -net clk_wiz_0_locked [get_bd_pins clk_wiz_0/locked] [get_bd_pins rst_clk_wiz_0_100M/dcm_locked] + connect_bd_net -net ddr4_0_c0_ddr4_ui_clk [get_bd_pins axi_smc/aclk] [get_bd_pins clk_wiz_0/clk_in1] [get_bd_pins ddr4_0/c0_ddr4_ui_clk] [get_bd_pins microblaze_0_axi_periph/M02_ACLK] [get_bd_pins rst_ddr4_0_333M/slowest_sync_clk] + connect_bd_net -net ddr4_0_c0_ddr4_ui_clk_sync_rst [get_bd_pins clk_wiz_0/reset] [get_bd_pins ddr4_0/c0_ddr4_ui_clk_sync_rst] [get_bd_pins rst_clk_wiz_0_100M/ext_reset_in] [get_bd_pins rst_ddr4_0_333M/ext_reset_in] + connect_bd_net -net dummy_port_in_1 [get_bd_ports dummy_port_in] [get_bd_pins ddr4_0/sys_rst] + connect_bd_net -net mdm_1_debug_sys_rst [get_bd_pins mdm_1/Debug_SYS_Rst] [get_bd_pins rst_clk_wiz_0_100M/mb_debug_sys_rst] + connect_bd_net -net microblaze_0_Clk [get_bd_pins axi_smc/aclk1] [get_bd_pins axi_timer_0/s_axi_aclk] [get_bd_pins axi_uart16550_0/s_axi_aclk] [get_bd_pins clk_wiz_0/clk_out1] [get_bd_pins microblaze_0/Clk] [get_bd_pins microblaze_0_axi_periph/ACLK] [get_bd_pins microblaze_0_axi_periph/M00_ACLK] [get_bd_pins microblaze_0_axi_periph/M01_ACLK] [get_bd_pins microblaze_0_axi_periph/M03_ACLK] [get_bd_pins microblaze_0_axi_periph/S00_ACLK] [get_bd_pins microblaze_0_local_memory/LMB_Clk] [get_bd_pins myproject_axi_0/ap_clk] [get_bd_pins rst_clk_wiz_0_100M/slowest_sync_clk] + connect_bd_net -net rst_clk_wiz_0_100M_bus_struct_reset [get_bd_pins microblaze_0_local_memory/SYS_Rst] [get_bd_pins rst_clk_wiz_0_100M/bus_struct_reset] + connect_bd_net -net rst_clk_wiz_0_100M_mb_reset [get_bd_pins microblaze_0/Reset] [get_bd_pins rst_clk_wiz_0_100M/mb_reset] + connect_bd_net -net rst_clk_wiz_0_100M_peripheral_aresetn [get_bd_pins axi_smc/aresetn] [get_bd_pins axi_timer_0/s_axi_aresetn] [get_bd_pins axi_uart16550_0/s_axi_aresetn] [get_bd_pins microblaze_0_axi_periph/ARESETN] [get_bd_pins microblaze_0_axi_periph/M00_ARESETN] [get_bd_pins microblaze_0_axi_periph/M01_ARESETN] [get_bd_pins microblaze_0_axi_periph/M03_ARESETN] [get_bd_pins microblaze_0_axi_periph/S00_ARESETN] [get_bd_pins myproject_axi_0/ap_rst_n] [get_bd_pins rst_clk_wiz_0_100M/peripheral_aresetn] + connect_bd_net -net rst_ddr4_0_333M_peripheral_aresetn [get_bd_pins ddr4_0/c0_ddr4_aresetn] [get_bd_pins microblaze_0_axi_periph/M02_ARESETN] [get_bd_pins rst_ddr4_0_333M/peripheral_aresetn] + + # Create address segments + assign_bd_address -offset 0x41C00000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_timer_0/S_AXI/Reg] -force + assign_bd_address -offset 0x44A00000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_uart16550_0/S_AXI/Reg] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + assign_bd_address -offset 0x44B00000 -range 0x00100000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP_CTRL/C0_REG] -force + assign_bd_address -offset 0x00000000 -range 0x00002000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs microblaze_0_local_memory/dlmb_bram_if_cntlr/SLMB/Mem] -force + assign_bd_address -offset 0x00000000 -range 0x00002000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs microblaze_0_local_memory/ilmb_bram_if_cntlr/SLMB/Mem] -force + assign_bd_address -offset 0x44A10000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs myproject_axi_0/s_axi_CTRL_BUS/Reg] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces myproject_axi_0/Data_m_axi_IN_BUS] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces myproject_axi_0/Data_m_axi_OUT_BUS] [get_bd_addr_segs ddr4_0/C0_DDR4_MEMORY_MAP/C0_DDR4_ADDRESS_BLOCK] -force + + + # Restore current instance + current_bd_instance $oldCurInst + + validate_bd_design + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + +############################################################################################################# + +#WRAP THE MODEL + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top + +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +#open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages + + + + + + + + + + + + + + + + + diff --git a/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v b/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v new file mode 100644 index 000000000..aa944e12a --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/vcu128/verilog_wrappers/design_1_wrapper.v @@ -0,0 +1,92 @@ +//Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. +//-------------------------------------------------------------------------------- +//Tool Version: Vivado v.2019.2 (lin64) Build 2708876 Wed Nov 6 21:39:14 MST 2019 +//Date : Wed Oct 5 16:49:36 2022 +//Host : subnugler running 64-bit Ubuntu 22.04.1 LTS +//Command : generate_target design_1_wrapper.bd +//Design : design_1_wrapper +//Purpose : IP block netlist +//-------------------------------------------------------------------------------- +`timescale 1 ps / 1 ps + +module design_1_wrapper + (ddr4_sdram_act_n, + ddr4_sdram_adr, + ddr4_sdram_ba, + ddr4_sdram_bg, + ddr4_sdram_ck_c, + ddr4_sdram_ck_t, + ddr4_sdram_cke, + ddr4_sdram_cs_n, + ddr4_sdram_dm_n, + ddr4_sdram_dq, + ddr4_sdram_dqs_c, + ddr4_sdram_dqs_t, + ddr4_sdram_odt, + ddr4_sdram_reset_n, + default_100mhz_clk_clk_n, + default_100mhz_clk_clk_p, + dummy_port_in, + rs232_uart_0_rxd, + rs232_uart_0_txd); + output ddr4_sdram_act_n; + output [16:0]ddr4_sdram_adr; + output [1:0]ddr4_sdram_ba; + output ddr4_sdram_bg; + output ddr4_sdram_ck_c; + output ddr4_sdram_ck_t; + output ddr4_sdram_cke; + output [1:0]ddr4_sdram_cs_n; + inout [8:0]ddr4_sdram_dm_n; + inout [71:0]ddr4_sdram_dq; + inout [8:0]ddr4_sdram_dqs_c; + inout [8:0]ddr4_sdram_dqs_t; + output ddr4_sdram_odt; + output ddr4_sdram_reset_n; + input default_100mhz_clk_clk_n; + input default_100mhz_clk_clk_p; + input dummy_port_in; + input rs232_uart_0_rxd; + output rs232_uart_0_txd; + + wire ddr4_sdram_act_n; + wire [16:0]ddr4_sdram_adr; + wire [1:0]ddr4_sdram_ba; + wire ddr4_sdram_bg; + wire ddr4_sdram_ck_c; + wire ddr4_sdram_ck_t; + wire ddr4_sdram_cke; + wire [1:0]ddr4_sdram_cs_n; + wire [8:0]ddr4_sdram_dm_n; + wire [71:0]ddr4_sdram_dq; + wire [8:0]ddr4_sdram_dqs_c; + wire [8:0]ddr4_sdram_dqs_t; + wire ddr4_sdram_odt; + wire ddr4_sdram_reset_n; + wire default_100mhz_clk_clk_n; + wire default_100mhz_clk_clk_p; + wire dummy_port_in; + wire rs232_uart_0_rxd; + wire rs232_uart_0_txd; + + design_1 design_1_i + (.ddr4_sdram_act_n(ddr4_sdram_act_n), + .ddr4_sdram_adr(ddr4_sdram_adr), + .ddr4_sdram_ba(ddr4_sdram_ba), + .ddr4_sdram_bg(ddr4_sdram_bg), + .ddr4_sdram_ck_c(ddr4_sdram_ck_c), + .ddr4_sdram_ck_t(ddr4_sdram_ck_t), + .ddr4_sdram_cke(ddr4_sdram_cke), + .ddr4_sdram_cs_n(ddr4_sdram_cs_n), + .ddr4_sdram_dm_n(ddr4_sdram_dm_n), + .ddr4_sdram_dq(ddr4_sdram_dq), + .ddr4_sdram_dqs_c(ddr4_sdram_dqs_c), + .ddr4_sdram_dqs_t(ddr4_sdram_dqs_t), + .ddr4_sdram_odt(ddr4_sdram_odt), + .ddr4_sdram_reset_n(ddr4_sdram_reset_n), + .default_100mhz_clk_clk_n(default_100mhz_clk_clk_n), + .default_100mhz_clk_clk_p(default_100mhz_clk_clk_p), + .dummy_port_in(dummy_port_in), + .rs232_uart_0_rxd(rs232_uart_0_rxd), + .rs232_uart_0_txd(rs232_uart_0_txd)); +endmodule diff --git a/hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py new file mode 100644 index 000000000..4adb187ab --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/zcu102/python_drivers/axi_stream_driver.py @@ -0,0 +1,75 @@ +from pynq import DefaultHierarchy, DefaultIP, allocate +from pynq import Overlay +from datetime import datetime +import pynq.lib.dma +import numpy as np + + +class NeuralNetworkOverlay(Overlay): + def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, + device=None): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.sendchannel = self.hier_0.axi_dma_0.sendchannel + self.recvchannel = self.hier_0.axi_dma_0.recvchannel + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def _print_dt(self, timea, timeb, N): + dt = (timeb - timea) + dts = dt.seconds + dt.microseconds * 10 ** -6 + rate = N / dts + print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) + return dts, rate + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + if profile: + timea = datetime.now() + if encode is not None: + X = encode(X) + self.input_buffer[:] = X + self.sendchannel.transfer(self.input_buffer) + self.recvchannel.transfer(self.output_buffer) + if debug: + print("Transfer OK") + self.sendchannel.wait() + if debug: + print("Send OK") + self.recvchannel.wait() + if debug: + print("Receive OK") + # result = self.output_buffer.copy() + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + timeb = datetime.now() + dts, rate = self._print_dt(timea, timeb, len(X)) + return self.output_buffer, dts, rate + else: + return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl new file mode 100644 index 000000000..fb79c8af8 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/zcu102/tcl_scripts/axi_stream_design.tcl @@ -0,0 +1,58 @@ +#@todo: try to remove startgroup and endgroup and see if it work +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] + +create_project project_1 ${myproject}_vivado_accelerator -part xczu9eg-ffvb1156-2-e -force + +set_property board_part xilinx.com:zcu102:part0:3.3 [current_project] +set_property ip_repo_paths ${myproject}_prj [current_project] +update_ip_catalog + +create_bd_design "design_1" +set_property ip_repo_paths ${myproject}_prj/solution1/impl/ip [current_project] +update_ip_catalog + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e_0 +endgroup + +apply_bd_automation -rule xilinx.com:bd_rule:zynq_ultra_ps_e -config {apply_board_preset "1" } [get_bd_cells zynq_ultra_ps_e_0] + +set_property -dict [list CONFIG.PSU__USE__S_AXI_GP0 {1} CONFIG.PSU__SAXIGP0__DATA_WIDTH {32}] [get_bd_cells zynq_ultra_ps_e_0] + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 +endgroup +set_property -dict [list CONFIG.c_m_axi_s2mm_data_width.VALUE_SRC USER CONFIG.c_s_axis_s2mm_tdata_width.VALUE_SRC USER] [get_bd_cells axi_dma_0] +set_property -dict [list CONFIG.c_include_sg {0} CONFIG.c_sg_length_width {26} CONFIG.c_sg_include_stscntrl_strm {0} CONFIG.c_m_axi_mm2s_data_width ${bit_width_hls_input} CONFIG.c_m_axis_mm2s_tdata_width ${bit_width_hls_input} CONFIG.c_mm2s_burst_size {256} CONFIG.c_m_axi_s2mm_data_width ${bit_width_hls_output} CONFIG.c_s_axis_s2mm_tdata_width ${bit_width_hls_output} CONFIG.c_s2mm_burst_size {256}] [get_bd_cells axi_dma_0] + +startgroup +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {New AXI Interconnect} master_apm {0}} [get_bd_intf_pins axi_dma_0/S_AXI_LITE] +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {Auto} Clk_xbar {Auto} Master {/axi_dma_0/M_AXI_MM2S} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {New AXI SmartConnect} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/S_AXI_HPC0_FPD] +endgroup + +startgroup +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/axi_dma_0/M_AXI_S2MM} Slave {/zynq_ultra_ps_e_0/S_AXI_HPC0_FPD} ddr_seg {Auto} intc_ip {/axi_smc} master_apm {0}} [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] +apply_bd_automation -rule xilinx.com:bd_rule:axi4 -config { Clk_master {Auto} Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Master {/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD} Slave {/axi_dma_0/S_AXI_LITE} ddr_seg {Auto} intc_ip {/ps8_0_axi_periph} master_apm {0}} [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD] +endgroup + +startgroup +create_bd_cell -type ip -vlnv xilinx.com:hls:${myproject}_axi:1.0 ${myproject}_axi_0 +endgroup +connect_bd_intf_net [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins ${myproject}_axi_0/in_r] +connect_bd_intf_net [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] [get_bd_intf_pins ${myproject}_axi_0/out_r] + +apply_bd_automation -rule xilinx.com:bd_rule:clkrst -config { Clk {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} Freq {100} Ref_Clk0 {} Ref_Clk1 {} Ref_Clk2 {}} [get_bd_pins ${myproject}_axi_0/ap_clk] +group_bd_cells hier_0 [get_bd_cells axi_dma_0] [get_bd_cells ${myproject}_axi_0] + +make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top + +add_files -norecurse ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v + +reset_run impl_1 +reset_run synth_1 +launch_runs impl_1 -to_step write_bitstream -jobs 6 +wait_on_run -timeout 360 impl_1 + +open_run impl_1 +report_utilization -file util.rpt -hierarchical -hierarchical_percentages diff --git a/hls4ml/templates/vivado_accelerator/zcu104/python_drivers/axi_stream_driver.py b/hls4ml/templates/vivado_accelerator/zcu104/python_drivers/axi_stream_driver.py new file mode 100644 index 000000000..4adb187ab --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/zcu104/python_drivers/axi_stream_driver.py @@ -0,0 +1,75 @@ +from pynq import DefaultHierarchy, DefaultIP, allocate +from pynq import Overlay +from datetime import datetime +import pynq.lib.dma +import numpy as np + + +class NeuralNetworkOverlay(Overlay): + def __init__(self, bitfile_name, x_shape, y_shape, dtype=np.float32, dtbo=None, download=True, ignore_version=False, + device=None): + super().__init__(bitfile_name, dtbo=None, download=True, ignore_version=False, device=None) + self.sendchannel = self.hier_0.axi_dma_0.sendchannel + self.recvchannel = self.hier_0.axi_dma_0.recvchannel + self.input_buffer = allocate(shape=x_shape, dtype=dtype) + self.output_buffer = allocate(shape=y_shape, dtype=dtype) + + def _print_dt(self, timea, timeb, N): + dt = (timeb - timea) + dts = dt.seconds + dt.microseconds * 10 ** -6 + rate = N / dts + print("Classified {} samples in {} seconds ({} inferences / s)".format(N, dts, rate)) + return dts, rate + + def predict(self, X, debug=False, profile=False, encode=None, decode=None): + """ + Obtain the predictions of the NN implemented in the FPGA. + Parameters: + - X : the input vector. Should be numpy ndarray. + - dtype : the data type of the elements of the input/output vectors. + Note: it should be set depending on the interface of the accelerator; if it uses 'float' + types for the 'data' AXI-Stream field, 'np.float32' dtype is the correct one to use. + Instead if it uses 'ap_fixed', 'np.intA' is the correct one to use (note that A cannot + any integer value, but it can assume {..., 8, 16, 32, ...} values. Check `numpy` + doc for more info). + In this case the encoding/decoding has to be computed by the PS. For example for + 'ap_fixed<16,6>' type the following 2 functions are the correct one to use for encode/decode + 'float' -> 'ap_fixed<16,6>': + ``` + def encode(xi): + return np.int16(round(xi * 2**10)) # note 2**10 = 2**(A-B) + def decode(yi): + return yi * 2**-10 + encode_v = np.vectorize(encode) # to apply them element-wise + decode_v = np.vectorize(decode) + ``` + - profile : boolean. Set it to `True` to print the performance of the algorithm in term of `inference/s`. + - encode/decode: function pointers. See `dtype` section for more information. + - return: an output array based on `np.ndarray` with a shape equal to `y_shape` and a `dtype` equal to + the namesake parameter. + """ + if profile: + timea = datetime.now() + if encode is not None: + X = encode(X) + self.input_buffer[:] = X + self.sendchannel.transfer(self.input_buffer) + self.recvchannel.transfer(self.output_buffer) + if debug: + print("Transfer OK") + self.sendchannel.wait() + if debug: + print("Send OK") + self.recvchannel.wait() + if debug: + print("Receive OK") + # result = self.output_buffer.copy() + if decode is not None: + self.output_buffer = decode(self.output_buffer) + + if profile: + timeb = datetime.now() + dts, rate = self._print_dt(timea, timeb, len(X)) + return self.output_buffer, dts, rate + else: + return self.output_buffer \ No newline at end of file diff --git a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl new file mode 100644 index 000000000..5fa7f9bb7 --- /dev/null +++ b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl @@ -0,0 +1,1888 @@ + +################################################################ +# This is a generated script based on design: design_1 +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2019.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +############################################################### +# START +############################################################### + +# To test this script, run the following commands from Vivado Tcl console: +# source design_1_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xczu7ev-ffvc1156-2-e -force + set_property BOARD_PART xilinx.com:zcu104:part0:1.1 [current_project] +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name design_1 + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:smartconnect:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:zynq_ultra_ps_e:3.3\ +xilinx.com:ip:axi_dma:7.1\ +xilinx.com:hls:myproject_axi:1.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + +# Hierarchical cell: hier_0 +proc create_hier_cell_hier_0 { parentCell nameHier } { + + variable script_folder + + if { $parentCell eq "" || $nameHier eq "" } { + catch {common::send_msg_id "BD_TCL-102" "ERROR" "create_hier_cell_hier_0() - Empty argument(s)!"} + return + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + # Create cell and set as current instance + set hier_obj [create_bd_cell -type hier $nameHier] + current_bd_instance $hier_obj + + # Create interface pins + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_MM2S + + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_S2MM + + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_LITE + + + # Create pins + create_bd_pin -dir I -type rst ap_rst_n + create_bd_pin -dir I -type clk m_axi_mm2s_aclk + + # Create instance: axi_dma_0, and set properties + set axi_dma_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_dma:7.1 axi_dma_0 ] + set_property -dict [ list \ + CONFIG.c_include_sg {0} \ + CONFIG.c_m_axi_mm2s_data_width {32} \ + CONFIG.c_m_axi_s2mm_data_width {32} \ + CONFIG.c_m_axis_mm2s_tdata_width {32} \ + CONFIG.c_mm2s_burst_size {256} \ + CONFIG.c_s2mm_burst_size {256} \ + CONFIG.c_s_axis_s2mm_tdata_width {32} \ + CONFIG.c_sg_include_stscntrl_strm {0} \ + CONFIG.c_sg_length_width {26} \ + ] $axi_dma_0 + + # Create instance: myproject_axi_1, and set properties + set myproject_axi_1 [ create_bd_cell -type ip -vlnv xilinx.com:hls:myproject_axi:1.0 myproject_axi_1 ] + + # Create interface connections + connect_bd_intf_net -intf_net axi_dma_0_M_AXIS_MM2S [get_bd_intf_pins axi_dma_0/M_AXIS_MM2S] [get_bd_intf_pins myproject_axi_1/in_r] + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_MM2S [get_bd_intf_pins M_AXI_MM2S] [get_bd_intf_pins axi_dma_0/M_AXI_MM2S] + connect_bd_intf_net -intf_net axi_dma_0_M_AXI_S2MM [get_bd_intf_pins M_AXI_S2MM] [get_bd_intf_pins axi_dma_0/M_AXI_S2MM] + connect_bd_intf_net -intf_net myproject_axi_1_out_r [get_bd_intf_pins axi_dma_0/S_AXIS_S2MM] [get_bd_intf_pins myproject_axi_1/out_r] + connect_bd_intf_net -intf_net ps8_0_axi_periph_M00_AXI [get_bd_intf_pins S_AXI_LITE] [get_bd_intf_pins axi_dma_0/S_AXI_LITE] + + # Create port connections + connect_bd_net -net rst_ps8_0_99M_peripheral_aresetn [get_bd_pins ap_rst_n] [get_bd_pins axi_dma_0/axi_resetn] [get_bd_pins myproject_axi_1/ap_rst_n] + connect_bd_net -net zynq_ultra_ps_e_0_pl_clk0 [get_bd_pins m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_mm2s_aclk] [get_bd_pins axi_dma_0/m_axi_s2mm_aclk] [get_bd_pins axi_dma_0/s_axi_lite_aclk] [get_bd_pins myproject_axi_1/ap_clk] + + # Restore current instance + current_bd_instance $oldCurInst +} + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + + # Create ports + + # Create instance: axi_smc, and set properties + set axi_smc [ create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_smc ] + set_property -dict [ list \ + CONFIG.NUM_SI {2} \ + ] $axi_smc + + # Create instance: hier_0 + create_hier_cell_hier_0 [current_bd_instance .] hier_0 + + # Create instance: ps8_0_axi_periph, and set properties + set ps8_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 ps8_0_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + CONFIG.NUM_SI {2} \ + ] $ps8_0_axi_periph + + # Create instance: rst_ps8_0_99M, and set properties + set rst_ps8_0_99M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_ps8_0_99M ] + + # Create instance: zynq_ultra_ps_e_0, and set properties + set zynq_ultra_ps_e_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:zynq_ultra_ps_e:3.3 zynq_ultra_ps_e_0 ] + set_property -dict [ list \ + CONFIG.CAN0_BOARD_INTERFACE {custom} \ + CONFIG.CAN1_BOARD_INTERFACE {custom} \ + CONFIG.CSU_BOARD_INTERFACE {custom} \ + CONFIG.DP_BOARD_INTERFACE {custom} \ + CONFIG.GEM0_BOARD_INTERFACE {custom} \ + CONFIG.GEM1_BOARD_INTERFACE {custom} \ + CONFIG.GEM2_BOARD_INTERFACE {custom} \ + CONFIG.GEM3_BOARD_INTERFACE {custom} \ + CONFIG.GPIO_BOARD_INTERFACE {custom} \ + CONFIG.IIC0_BOARD_INTERFACE {custom} \ + CONFIG.IIC1_BOARD_INTERFACE {custom} \ + CONFIG.NAND_BOARD_INTERFACE {custom} \ + CONFIG.PCIE_BOARD_INTERFACE {custom} \ + CONFIG.PJTAG_BOARD_INTERFACE {custom} \ + CONFIG.PMU_BOARD_INTERFACE {custom} \ + CONFIG.PSU_BANK_0_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_1_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_2_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_BANK_3_IO_STANDARD {LVCMOS18} \ + CONFIG.PSU_DDR_RAM_HIGHADDR {0xFFFFFFFF} \ + CONFIG.PSU_DDR_RAM_HIGHADDR_OFFSET {0x800000000} \ + CONFIG.PSU_DDR_RAM_LOWADDR_OFFSET {0x80000000} \ + CONFIG.PSU_DYNAMIC_DDR_CONFIG_EN {1} \ + CONFIG.PSU_IMPORT_BOARD_PRESET {} \ + CONFIG.PSU_MIO_0_DIRECTION {out} \ + CONFIG.PSU_MIO_0_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_0_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_0_POLARITY {Default} \ + CONFIG.PSU_MIO_0_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_0_SLEW {fast} \ + CONFIG.PSU_MIO_10_DIRECTION {inout} \ + CONFIG.PSU_MIO_10_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_10_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_10_POLARITY {Default} \ + CONFIG.PSU_MIO_10_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_10_SLEW {fast} \ + CONFIG.PSU_MIO_11_DIRECTION {inout} \ + CONFIG.PSU_MIO_11_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_11_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_11_POLARITY {Default} \ + CONFIG.PSU_MIO_11_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_11_SLEW {fast} \ + CONFIG.PSU_MIO_12_DIRECTION {out} \ + CONFIG.PSU_MIO_12_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_12_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_12_POLARITY {Default} \ + CONFIG.PSU_MIO_12_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_12_SLEW {fast} \ + CONFIG.PSU_MIO_13_DIRECTION {inout} \ + CONFIG.PSU_MIO_13_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_13_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_13_POLARITY {Default} \ + CONFIG.PSU_MIO_13_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_13_SLEW {fast} \ + CONFIG.PSU_MIO_14_DIRECTION {inout} \ + CONFIG.PSU_MIO_14_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_14_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_14_POLARITY {Default} \ + CONFIG.PSU_MIO_14_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_14_SLEW {fast} \ + CONFIG.PSU_MIO_15_DIRECTION {inout} \ + CONFIG.PSU_MIO_15_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_15_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_15_POLARITY {Default} \ + CONFIG.PSU_MIO_15_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_15_SLEW {fast} \ + CONFIG.PSU_MIO_16_DIRECTION {inout} \ + CONFIG.PSU_MIO_16_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_16_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_16_POLARITY {Default} \ + CONFIG.PSU_MIO_16_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_16_SLEW {fast} \ + CONFIG.PSU_MIO_17_DIRECTION {inout} \ + CONFIG.PSU_MIO_17_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_17_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_17_POLARITY {Default} \ + CONFIG.PSU_MIO_17_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_17_SLEW {fast} \ + CONFIG.PSU_MIO_18_DIRECTION {in} \ + CONFIG.PSU_MIO_18_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_18_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_18_POLARITY {Default} \ + CONFIG.PSU_MIO_18_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_18_SLEW {fast} \ + CONFIG.PSU_MIO_19_DIRECTION {out} \ + CONFIG.PSU_MIO_19_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_19_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_19_POLARITY {Default} \ + CONFIG.PSU_MIO_19_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_19_SLEW {fast} \ + CONFIG.PSU_MIO_1_DIRECTION {inout} \ + CONFIG.PSU_MIO_1_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_1_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_1_POLARITY {Default} \ + CONFIG.PSU_MIO_1_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_1_SLEW {fast} \ + CONFIG.PSU_MIO_20_DIRECTION {out} \ + CONFIG.PSU_MIO_20_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_20_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_20_POLARITY {Default} \ + CONFIG.PSU_MIO_20_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_20_SLEW {fast} \ + CONFIG.PSU_MIO_21_DIRECTION {in} \ + CONFIG.PSU_MIO_21_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_21_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_21_POLARITY {Default} \ + CONFIG.PSU_MIO_21_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_21_SLEW {fast} \ + CONFIG.PSU_MIO_22_DIRECTION {inout} \ + CONFIG.PSU_MIO_22_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_22_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_22_POLARITY {Default} \ + CONFIG.PSU_MIO_22_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_22_SLEW {fast} \ + CONFIG.PSU_MIO_23_DIRECTION {inout} \ + CONFIG.PSU_MIO_23_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_23_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_23_POLARITY {Default} \ + CONFIG.PSU_MIO_23_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_23_SLEW {fast} \ + CONFIG.PSU_MIO_24_DIRECTION {out} \ + CONFIG.PSU_MIO_24_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_24_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_24_POLARITY {Default} \ + CONFIG.PSU_MIO_24_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_24_SLEW {fast} \ + CONFIG.PSU_MIO_25_DIRECTION {in} \ + CONFIG.PSU_MIO_25_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_25_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_25_POLARITY {Default} \ + CONFIG.PSU_MIO_25_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_25_SLEW {fast} \ + CONFIG.PSU_MIO_26_DIRECTION {inout} \ + CONFIG.PSU_MIO_26_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_26_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_26_POLARITY {Default} \ + CONFIG.PSU_MIO_26_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_26_SLEW {fast} \ + CONFIG.PSU_MIO_27_DIRECTION {out} \ + CONFIG.PSU_MIO_27_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_27_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_27_POLARITY {Default} \ + CONFIG.PSU_MIO_27_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_27_SLEW {fast} \ + CONFIG.PSU_MIO_28_DIRECTION {in} \ + CONFIG.PSU_MIO_28_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_28_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_28_POLARITY {Default} \ + CONFIG.PSU_MIO_28_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_28_SLEW {fast} \ + CONFIG.PSU_MIO_29_DIRECTION {out} \ + CONFIG.PSU_MIO_29_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_29_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_29_POLARITY {Default} \ + CONFIG.PSU_MIO_29_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_29_SLEW {fast} \ + CONFIG.PSU_MIO_2_DIRECTION {inout} \ + CONFIG.PSU_MIO_2_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_2_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_2_POLARITY {Default} \ + CONFIG.PSU_MIO_2_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_2_SLEW {fast} \ + CONFIG.PSU_MIO_30_DIRECTION {in} \ + CONFIG.PSU_MIO_30_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_30_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_30_POLARITY {Default} \ + CONFIG.PSU_MIO_30_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_30_SLEW {fast} \ + CONFIG.PSU_MIO_31_DIRECTION {out} \ + CONFIG.PSU_MIO_31_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_31_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_31_POLARITY {Default} \ + CONFIG.PSU_MIO_31_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_31_SLEW {fast} \ + CONFIG.PSU_MIO_32_DIRECTION {out} \ + CONFIG.PSU_MIO_32_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_32_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_32_POLARITY {Default} \ + CONFIG.PSU_MIO_32_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_32_SLEW {fast} \ + CONFIG.PSU_MIO_33_DIRECTION {out} \ + CONFIG.PSU_MIO_33_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_33_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_33_POLARITY {Default} \ + CONFIG.PSU_MIO_33_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_33_SLEW {fast} \ + CONFIG.PSU_MIO_34_DIRECTION {out} \ + CONFIG.PSU_MIO_34_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_34_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_34_POLARITY {Default} \ + CONFIG.PSU_MIO_34_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_34_SLEW {fast} \ + CONFIG.PSU_MIO_35_DIRECTION {out} \ + CONFIG.PSU_MIO_35_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_35_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_35_POLARITY {Default} \ + CONFIG.PSU_MIO_35_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_35_SLEW {fast} \ + CONFIG.PSU_MIO_36_DIRECTION {out} \ + CONFIG.PSU_MIO_36_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_36_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_36_POLARITY {Default} \ + CONFIG.PSU_MIO_36_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_36_SLEW {fast} \ + CONFIG.PSU_MIO_37_DIRECTION {out} \ + CONFIG.PSU_MIO_37_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_37_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_37_POLARITY {Default} \ + CONFIG.PSU_MIO_37_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_37_SLEW {fast} \ + CONFIG.PSU_MIO_38_DIRECTION {inout} \ + CONFIG.PSU_MIO_38_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_38_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_38_POLARITY {Default} \ + CONFIG.PSU_MIO_38_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_38_SLEW {fast} \ + CONFIG.PSU_MIO_39_DIRECTION {inout} \ + CONFIG.PSU_MIO_39_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_39_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_39_POLARITY {Default} \ + CONFIG.PSU_MIO_39_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_39_SLEW {fast} \ + CONFIG.PSU_MIO_3_DIRECTION {inout} \ + CONFIG.PSU_MIO_3_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_3_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_3_POLARITY {Default} \ + CONFIG.PSU_MIO_3_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_3_SLEW {fast} \ + CONFIG.PSU_MIO_40_DIRECTION {inout} \ + CONFIG.PSU_MIO_40_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_40_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_40_POLARITY {Default} \ + CONFIG.PSU_MIO_40_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_40_SLEW {fast} \ + CONFIG.PSU_MIO_41_DIRECTION {inout} \ + CONFIG.PSU_MIO_41_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_41_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_41_POLARITY {Default} \ + CONFIG.PSU_MIO_41_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_41_SLEW {fast} \ + CONFIG.PSU_MIO_42_DIRECTION {inout} \ + CONFIG.PSU_MIO_42_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_42_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_42_POLARITY {Default} \ + CONFIG.PSU_MIO_42_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_42_SLEW {fast} \ + CONFIG.PSU_MIO_43_DIRECTION {inout} \ + CONFIG.PSU_MIO_43_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_43_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_43_POLARITY {Default} \ + CONFIG.PSU_MIO_43_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_43_SLEW {fast} \ + CONFIG.PSU_MIO_44_DIRECTION {in} \ + CONFIG.PSU_MIO_44_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_44_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_44_POLARITY {Default} \ + CONFIG.PSU_MIO_44_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_44_SLEW {fast} \ + CONFIG.PSU_MIO_45_DIRECTION {in} \ + CONFIG.PSU_MIO_45_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_45_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_45_POLARITY {Default} \ + CONFIG.PSU_MIO_45_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_45_SLEW {fast} \ + CONFIG.PSU_MIO_46_DIRECTION {inout} \ + CONFIG.PSU_MIO_46_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_46_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_46_POLARITY {Default} \ + CONFIG.PSU_MIO_46_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_46_SLEW {fast} \ + CONFIG.PSU_MIO_47_DIRECTION {inout} \ + CONFIG.PSU_MIO_47_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_47_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_47_POLARITY {Default} \ + CONFIG.PSU_MIO_47_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_47_SLEW {fast} \ + CONFIG.PSU_MIO_48_DIRECTION {inout} \ + CONFIG.PSU_MIO_48_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_48_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_48_POLARITY {Default} \ + CONFIG.PSU_MIO_48_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_48_SLEW {fast} \ + CONFIG.PSU_MIO_49_DIRECTION {inout} \ + CONFIG.PSU_MIO_49_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_49_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_49_POLARITY {Default} \ + CONFIG.PSU_MIO_49_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_49_SLEW {fast} \ + CONFIG.PSU_MIO_4_DIRECTION {inout} \ + CONFIG.PSU_MIO_4_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_4_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_4_POLARITY {Default} \ + CONFIG.PSU_MIO_4_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_4_SLEW {fast} \ + CONFIG.PSU_MIO_50_DIRECTION {inout} \ + CONFIG.PSU_MIO_50_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_50_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_50_POLARITY {Default} \ + CONFIG.PSU_MIO_50_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_50_SLEW {fast} \ + CONFIG.PSU_MIO_51_DIRECTION {out} \ + CONFIG.PSU_MIO_51_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_51_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_51_POLARITY {Default} \ + CONFIG.PSU_MIO_51_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_51_SLEW {fast} \ + CONFIG.PSU_MIO_52_DIRECTION {in} \ + CONFIG.PSU_MIO_52_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_52_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_52_POLARITY {Default} \ + CONFIG.PSU_MIO_52_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_52_SLEW {fast} \ + CONFIG.PSU_MIO_53_DIRECTION {in} \ + CONFIG.PSU_MIO_53_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_53_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_53_POLARITY {Default} \ + CONFIG.PSU_MIO_53_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_53_SLEW {fast} \ + CONFIG.PSU_MIO_54_DIRECTION {inout} \ + CONFIG.PSU_MIO_54_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_54_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_54_POLARITY {Default} \ + CONFIG.PSU_MIO_54_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_54_SLEW {fast} \ + CONFIG.PSU_MIO_55_DIRECTION {in} \ + CONFIG.PSU_MIO_55_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_55_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_55_POLARITY {Default} \ + CONFIG.PSU_MIO_55_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_55_SLEW {fast} \ + CONFIG.PSU_MIO_56_DIRECTION {inout} \ + CONFIG.PSU_MIO_56_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_56_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_56_POLARITY {Default} \ + CONFIG.PSU_MIO_56_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_56_SLEW {fast} \ + CONFIG.PSU_MIO_57_DIRECTION {inout} \ + CONFIG.PSU_MIO_57_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_57_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_57_POLARITY {Default} \ + CONFIG.PSU_MIO_57_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_57_SLEW {fast} \ + CONFIG.PSU_MIO_58_DIRECTION {out} \ + CONFIG.PSU_MIO_58_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_58_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_58_POLARITY {Default} \ + CONFIG.PSU_MIO_58_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_58_SLEW {fast} \ + CONFIG.PSU_MIO_59_DIRECTION {inout} \ + CONFIG.PSU_MIO_59_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_59_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_59_POLARITY {Default} \ + CONFIG.PSU_MIO_59_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_59_SLEW {fast} \ + CONFIG.PSU_MIO_5_DIRECTION {out} \ + CONFIG.PSU_MIO_5_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_5_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_5_POLARITY {Default} \ + CONFIG.PSU_MIO_5_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_5_SLEW {fast} \ + CONFIG.PSU_MIO_60_DIRECTION {inout} \ + CONFIG.PSU_MIO_60_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_60_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_60_POLARITY {Default} \ + CONFIG.PSU_MIO_60_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_60_SLEW {fast} \ + CONFIG.PSU_MIO_61_DIRECTION {inout} \ + CONFIG.PSU_MIO_61_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_61_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_61_POLARITY {Default} \ + CONFIG.PSU_MIO_61_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_61_SLEW {fast} \ + CONFIG.PSU_MIO_62_DIRECTION {inout} \ + CONFIG.PSU_MIO_62_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_62_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_62_POLARITY {Default} \ + CONFIG.PSU_MIO_62_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_62_SLEW {fast} \ + CONFIG.PSU_MIO_63_DIRECTION {inout} \ + CONFIG.PSU_MIO_63_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_63_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_63_POLARITY {Default} \ + CONFIG.PSU_MIO_63_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_63_SLEW {fast} \ + CONFIG.PSU_MIO_64_DIRECTION {out} \ + CONFIG.PSU_MIO_64_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_64_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_64_POLARITY {Default} \ + CONFIG.PSU_MIO_64_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_64_SLEW {fast} \ + CONFIG.PSU_MIO_65_DIRECTION {out} \ + CONFIG.PSU_MIO_65_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_65_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_65_POLARITY {Default} \ + CONFIG.PSU_MIO_65_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_65_SLEW {fast} \ + CONFIG.PSU_MIO_66_DIRECTION {out} \ + CONFIG.PSU_MIO_66_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_66_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_66_POLARITY {Default} \ + CONFIG.PSU_MIO_66_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_66_SLEW {fast} \ + CONFIG.PSU_MIO_67_DIRECTION {out} \ + CONFIG.PSU_MIO_67_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_67_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_67_POLARITY {Default} \ + CONFIG.PSU_MIO_67_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_67_SLEW {fast} \ + CONFIG.PSU_MIO_68_DIRECTION {out} \ + CONFIG.PSU_MIO_68_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_68_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_68_POLARITY {Default} \ + CONFIG.PSU_MIO_68_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_68_SLEW {fast} \ + CONFIG.PSU_MIO_69_DIRECTION {out} \ + CONFIG.PSU_MIO_69_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_69_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_69_POLARITY {Default} \ + CONFIG.PSU_MIO_69_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_69_SLEW {fast} \ + CONFIG.PSU_MIO_6_DIRECTION {out} \ + CONFIG.PSU_MIO_6_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_6_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_6_POLARITY {Default} \ + CONFIG.PSU_MIO_6_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_6_SLEW {fast} \ + CONFIG.PSU_MIO_70_DIRECTION {in} \ + CONFIG.PSU_MIO_70_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_70_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_70_POLARITY {Default} \ + CONFIG.PSU_MIO_70_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_70_SLEW {fast} \ + CONFIG.PSU_MIO_71_DIRECTION {in} \ + CONFIG.PSU_MIO_71_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_71_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_71_POLARITY {Default} \ + CONFIG.PSU_MIO_71_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_71_SLEW {fast} \ + CONFIG.PSU_MIO_72_DIRECTION {in} \ + CONFIG.PSU_MIO_72_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_72_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_72_POLARITY {Default} \ + CONFIG.PSU_MIO_72_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_72_SLEW {fast} \ + CONFIG.PSU_MIO_73_DIRECTION {in} \ + CONFIG.PSU_MIO_73_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_73_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_73_POLARITY {Default} \ + CONFIG.PSU_MIO_73_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_73_SLEW {fast} \ + CONFIG.PSU_MIO_74_DIRECTION {in} \ + CONFIG.PSU_MIO_74_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_74_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_74_POLARITY {Default} \ + CONFIG.PSU_MIO_74_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_74_SLEW {fast} \ + CONFIG.PSU_MIO_75_DIRECTION {in} \ + CONFIG.PSU_MIO_75_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_75_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_75_POLARITY {Default} \ + CONFIG.PSU_MIO_75_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_75_SLEW {fast} \ + CONFIG.PSU_MIO_76_DIRECTION {out} \ + CONFIG.PSU_MIO_76_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_76_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_76_POLARITY {Default} \ + CONFIG.PSU_MIO_76_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_76_SLEW {fast} \ + CONFIG.PSU_MIO_77_DIRECTION {inout} \ + CONFIG.PSU_MIO_77_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_77_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_77_POLARITY {Default} \ + CONFIG.PSU_MIO_77_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_77_SLEW {fast} \ + CONFIG.PSU_MIO_7_DIRECTION {out} \ + CONFIG.PSU_MIO_7_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_7_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_7_POLARITY {Default} \ + CONFIG.PSU_MIO_7_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_7_SLEW {fast} \ + CONFIG.PSU_MIO_8_DIRECTION {inout} \ + CONFIG.PSU_MIO_8_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_8_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_8_POLARITY {Default} \ + CONFIG.PSU_MIO_8_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_8_SLEW {fast} \ + CONFIG.PSU_MIO_9_DIRECTION {inout} \ + CONFIG.PSU_MIO_9_DRIVE_STRENGTH {12} \ + CONFIG.PSU_MIO_9_INPUT_TYPE {cmos} \ + CONFIG.PSU_MIO_9_POLARITY {Default} \ + CONFIG.PSU_MIO_9_PULLUPDOWN {pullup} \ + CONFIG.PSU_MIO_9_SLEW {fast} \ + CONFIG.PSU_MIO_TREE_PERIPHERALS {Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Feedback Clk#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO0 MIO#I2C 0#I2C 0#I2C 1#I2C 1#UART 0#UART 0#UART 1#UART 1#GPIO0 MIO#GPIO0 MIO#CAN 1#CAN 1#GPIO1 MIO#DPAUX#DPAUX#DPAUX#DPAUX#PCIE#PMU GPO 0#PMU GPO 1#PMU GPO 2#PMU GPO 3#PMU GPO 4#PMU GPO 5#GPIO1 MIO#SD 1#SD 1#SD 1#SD 1#GPIO1 MIO#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#Gem 3#MDIO 3#MDIO 3} \ + CONFIG.PSU_MIO_TREE_SIGNALS {sclk_out#miso_mo1#mo2#mo3#mosi_mi0#n_ss_out#clk_for_lpbk#n_ss_out_upper#mo_upper[0]#mo_upper[1]#mo_upper[2]#mo_upper[3]#sclk_out_upper#gpio0[13]#scl_out#sda_out#scl_out#sda_out#rxd#txd#txd#rxd#gpio0[22]#gpio0[23]#phy_tx#phy_rx#gpio1[26]#dp_aux_data_out#dp_hot_plug_detect#dp_aux_data_oe#dp_aux_data_in#reset_n#gpo[0]#gpo[1]#gpo[2]#gpo[3]#gpo[4]#gpo[5]#gpio1[38]#sdio1_data_out[4]#sdio1_data_out[5]#sdio1_data_out[6]#sdio1_data_out[7]#gpio1[43]#sdio1_wp#sdio1_cd_n#sdio1_data_out[0]#sdio1_data_out[1]#sdio1_data_out[2]#sdio1_data_out[3]#sdio1_cmd_out#sdio1_clk_out#ulpi_clk_in#ulpi_dir#ulpi_tx_data[2]#ulpi_nxt#ulpi_tx_data[0]#ulpi_tx_data[1]#ulpi_stp#ulpi_tx_data[3]#ulpi_tx_data[4]#ulpi_tx_data[5]#ulpi_tx_data[6]#ulpi_tx_data[7]#rgmii_tx_clk#rgmii_txd[0]#rgmii_txd[1]#rgmii_txd[2]#rgmii_txd[3]#rgmii_tx_ctl#rgmii_rx_clk#rgmii_rxd[0]#rgmii_rxd[1]#rgmii_rxd[2]#rgmii_rxd[3]#rgmii_rx_ctl#gem3_mdc#gem3_mdio_out} \ + CONFIG.PSU_PERIPHERAL_BOARD_PRESET {} \ + CONFIG.PSU_SD0_INTERNAL_BUS_WIDTH {8} \ + CONFIG.PSU_SD1_INTERNAL_BUS_WIDTH {8} \ + CONFIG.PSU_SMC_CYCLE_T0 {NA} \ + CONFIG.PSU_SMC_CYCLE_T1 {NA} \ + CONFIG.PSU_SMC_CYCLE_T2 {NA} \ + CONFIG.PSU_SMC_CYCLE_T3 {NA} \ + CONFIG.PSU_SMC_CYCLE_T4 {NA} \ + CONFIG.PSU_SMC_CYCLE_T5 {NA} \ + CONFIG.PSU_SMC_CYCLE_T6 {NA} \ + CONFIG.PSU_USB3__DUAL_CLOCK_ENABLE {1} \ + CONFIG.PSU_VALUE_SILVERSION {3} \ + CONFIG.PSU__ACPU0__POWER__ON {1} \ + CONFIG.PSU__ACPU1__POWER__ON {1} \ + CONFIG.PSU__ACPU2__POWER__ON {1} \ + CONFIG.PSU__ACPU3__POWER__ON {1} \ + CONFIG.PSU__ACTUAL__IP {1} \ + CONFIG.PSU__ACT_DDR_FREQ_MHZ {1066.560059} \ + CONFIG.PSU__AFI0_COHERENCY {0} \ + CONFIG.PSU__AFI1_COHERENCY {0} \ + CONFIG.PSU__AUX_REF_CLK__FREQMHZ {33.333} \ + CONFIG.PSU__CAN0_LOOP_CAN1__ENABLE {0} \ + CONFIG.PSU__CAN0__GRP_CLK__ENABLE {0} \ + CONFIG.PSU__CAN0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__CAN1__GRP_CLK__ENABLE {0} \ + CONFIG.PSU__CAN1__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__CAN1__PERIPHERAL__IO {MIO 24 .. 25} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__ACT_FREQMHZ {1199.880127} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__DIVISOR0 {1} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__FREQMHZ {1200} \ + CONFIG.PSU__CRF_APB__ACPU_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__ACPU__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI0_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI0_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI1_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI1_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI2_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI2_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI3_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI3_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI4_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI4_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__ACT_FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__FREQMHZ {667} \ + CONFIG.PSU__CRF_APB__AFI5_REF_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__AFI5_REF__ENABLE {0} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__FBDIV {72} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRF_APB__APLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__APLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRF_APB__APLL_TO_LPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRF_APB__APM_CTRL__ACT_FREQMHZ {1} \ + CONFIG.PSU__CRF_APB__APM_CTRL__DIVISOR0 {1} \ + CONFIG.PSU__CRF_APB__APM_CTRL__FREQMHZ {1} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_FPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__ACT_FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TRACE_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__DBG_TSTMP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__ACT_FREQMHZ {533.280029} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__FREQMHZ {1067} \ + CONFIG.PSU__CRF_APB__DDR_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__ACT_FREQMHZ {599.940063} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__DPDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__FBDIV {64} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRF_APB__DPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__DPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRF_APB__DPLL_TO_LPD_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__ACT_FREQMHZ {24.997501} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__FREQMHZ {25} \ + CONFIG.PSU__CRF_APB__DP_AUDIO_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_AUDIO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__ACT_FREQMHZ {26.783037} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__DIVISOR0 {14} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__FREQMHZ {27} \ + CONFIG.PSU__CRF_APB__DP_STC_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__ACT_FREQMHZ {299.970032} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__FREQMHZ {300} \ + CONFIG.PSU__CRF_APB__DP_VIDEO_REF_CTRL__SRCSEL {VPLL} \ + CONFIG.PSU__CRF_APB__DP_VIDEO__FRAC_ENABLED {0} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__ACT_FREQMHZ {599.940063} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__FREQMHZ {600} \ + CONFIG.PSU__CRF_APB__GDMA_REF_CTRL__SRCSEL {APLL} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__DIVISOR0 {1} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRF_APB__GPU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__ACT_FREQMHZ {-1} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__DIVISOR0 {-1} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__FREQMHZ {-1} \ + CONFIG.PSU__CRF_APB__GTGREF0_REF_CTRL__SRCSEL {NA} \ + CONFIG.PSU__CRF_APB__GTGREF0__ENABLE {NA} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__PCIE_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRF_APB__SATA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__DIVISOR0 {5} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRF_APB__TOPSW_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__ACT_FREQMHZ {533.280029} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__FREQMHZ {533.33} \ + CONFIG.PSU__CRF_APB__TOPSW_MAIN_CTRL__SRCSEL {DPLL} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__FBDIV {90} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRF_APB__VPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRF_APB__VPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRF_APB__VPLL_TO_LPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__ADMA_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__ACT_FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__AFI6_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__AFI6__ENABLE {0} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__ACT_FREQMHZ {49.995003} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__DIVISOR0 {30} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__FREQMHZ {50} \ + CONFIG.PSU__CRL_APB__AMS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__CAN1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__CPU_R5_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__ACT_FREQMHZ {180} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__FREQMHZ {180} \ + CONFIG.PSU__CRL_APB__CSU_PLL_CTRL__SRCSEL {SysOsc} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__DBG_LPD_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__ACT_FREQMHZ {1000} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__FREQMHZ {1000} \ + CONFIG.PSU__CRL_APB__DEBUG_R5_ATCLK_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__ACT_FREQMHZ {1499.850098} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__FREQMHZ {1500} \ + CONFIG.PSU__CRL_APB__DLL_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__ACT_FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__ACT_FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__ACT_FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM2_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__ACT_FREQMHZ {124.987511} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__GEM3_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__GEM_TSU_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__I2C1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__FBDIV {90} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRL_APB__IOPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__IOPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRL_APB__IOPLL_TO_FPD_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__IOU_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__LPD_LSBUS_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__ACT_FREQMHZ {499.950043} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__LPD_SWITCH_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__NAND_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__ACT_FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__DIVISOR0 {3} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__FREQMHZ {500} \ + CONFIG.PSU__CRL_APB__OCM_MAIN_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__ACT_FREQMHZ {187.481262} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__DIVISOR0 {8} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__PCAP_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL1_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL2_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__ACT_FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__DIVISOR0 {4} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__PL3_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__ACT_FREQMHZ {124.987511} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__DIVISOR0 {12} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__FREQMHZ {125} \ + CONFIG.PSU__CRL_APB__QSPI_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__DIV2 {1} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__FBDIV {45} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__FRACDATA {0.000000} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__FRACFREQ {27.138} \ + CONFIG.PSU__CRL_APB__RPLL_CTRL__SRCSEL {PSS_REF_CLK} \ + CONFIG.PSU__CRL_APB__RPLL_FRAC_CFG__ENABLED {0} \ + CONFIG.PSU__CRL_APB__RPLL_TO_FPD_CTRL__DIVISOR0 {2} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__ACT_FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__DIVISOR0 {7} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO0_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__ACT_FREQMHZ {187.481262} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__DIVISOR0 {8} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SDIO1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__ACT_FREQMHZ {214} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__DIVISOR0 {7} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SPI0_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__ACT_FREQMHZ {214} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__DIVISOR0 {7} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__FREQMHZ {200} \ + CONFIG.PSU__CRL_APB__SPI1_REF_CTRL__SRCSEL {RPLL} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__TIMESTAMP_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART0_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__DIVISOR0 {15} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__FREQMHZ {100} \ + CONFIG.PSU__CRL_APB__UART1_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__ACT_FREQMHZ {249.975021} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB0_BUS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__ACT_FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__DIVISOR0 {6} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__DIVISOR1 {1} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__FREQMHZ {250} \ + CONFIG.PSU__CRL_APB__USB1_BUS_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__ACT_FREQMHZ {19.998001} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__DIVISOR0 {25} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__DIVISOR1 {3} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__FREQMHZ {20} \ + CONFIG.PSU__CRL_APB__USB3_DUAL_REF_CTRL__SRCSEL {IOPLL} \ + CONFIG.PSU__CRL_APB__USB3__ENABLE {1} \ + CONFIG.PSU__CSUPMU__PERIPHERAL__VALID {1} \ + CONFIG.PSU__CSU_COHERENCY {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_0__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_0__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_10__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_10__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_11__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_11__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_12__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_12__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_1__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_1__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_2__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_2__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_3__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_3__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_4__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_4__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_5__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_5__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_6__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_6__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_7__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_7__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_8__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_8__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_9__ENABLE {0} \ + CONFIG.PSU__CSU__CSU_TAMPER_9__ERASE_BBRAM {0} \ + CONFIG.PSU__CSU__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__DDRC__ADDR_MIRROR {0} \ + CONFIG.PSU__DDRC__AL {0} \ + CONFIG.PSU__DDRC__BANK_ADDR_COUNT {2} \ + CONFIG.PSU__DDRC__BG_ADDR_COUNT {2} \ + CONFIG.PSU__DDRC__BRC_MAPPING {ROW_BANK_COL} \ + CONFIG.PSU__DDRC__BUS_WIDTH {64 Bit} \ + CONFIG.PSU__DDRC__CL {15} \ + CONFIG.PSU__DDRC__CLOCK_STOP_EN {0} \ + CONFIG.PSU__DDRC__COL_ADDR_COUNT {10} \ + CONFIG.PSU__DDRC__COMPONENTS {UDIMM} \ + CONFIG.PSU__DDRC__CWL {14} \ + CONFIG.PSU__DDRC__DDR3L_T_REF_RANGE {NA} \ + CONFIG.PSU__DDRC__DDR3_T_REF_RANGE {NA} \ + CONFIG.PSU__DDRC__DDR4_ADDR_MAPPING {0} \ + CONFIG.PSU__DDRC__DDR4_CAL_MODE_ENABLE {0} \ + CONFIG.PSU__DDRC__DDR4_CRC_CONTROL {0} \ + CONFIG.PSU__DDRC__DDR4_MAXPWR_SAVING_EN {0} \ + CONFIG.PSU__DDRC__DDR4_T_REF_MODE {0} \ + CONFIG.PSU__DDRC__DDR4_T_REF_RANGE {Normal (0-85)} \ + CONFIG.PSU__DDRC__DEEP_PWR_DOWN_EN {0} \ + CONFIG.PSU__DDRC__DEVICE_CAPACITY {4096 MBits} \ + CONFIG.PSU__DDRC__DIMM_ADDR_MIRROR {0} \ + CONFIG.PSU__DDRC__DM_DBI {DM_NO_DBI} \ + CONFIG.PSU__DDRC__DQMAP_0_3 {0} \ + CONFIG.PSU__DDRC__DQMAP_12_15 {0} \ + CONFIG.PSU__DDRC__DQMAP_16_19 {0} \ + CONFIG.PSU__DDRC__DQMAP_20_23 {0} \ + CONFIG.PSU__DDRC__DQMAP_24_27 {0} \ + CONFIG.PSU__DDRC__DQMAP_28_31 {0} \ + CONFIG.PSU__DDRC__DQMAP_32_35 {0} \ + CONFIG.PSU__DDRC__DQMAP_36_39 {0} \ + CONFIG.PSU__DDRC__DQMAP_40_43 {0} \ + CONFIG.PSU__DDRC__DQMAP_44_47 {0} \ + CONFIG.PSU__DDRC__DQMAP_48_51 {0} \ + CONFIG.PSU__DDRC__DQMAP_4_7 {0} \ + CONFIG.PSU__DDRC__DQMAP_52_55 {0} \ + CONFIG.PSU__DDRC__DQMAP_56_59 {0} \ + CONFIG.PSU__DDRC__DQMAP_60_63 {0} \ + CONFIG.PSU__DDRC__DQMAP_64_67 {0} \ + CONFIG.PSU__DDRC__DQMAP_68_71 {0} \ + CONFIG.PSU__DDRC__DQMAP_8_11 {0} \ + CONFIG.PSU__DDRC__DRAM_WIDTH {8 Bits} \ + CONFIG.PSU__DDRC__ECC {Disabled} \ + CONFIG.PSU__DDRC__ECC_SCRUB {0} \ + CONFIG.PSU__DDRC__ENABLE {1} \ + CONFIG.PSU__DDRC__ENABLE_2T_TIMING {0} \ + CONFIG.PSU__DDRC__ENABLE_DP_SWITCH {0} \ + CONFIG.PSU__DDRC__ENABLE_LP4_HAS_ECC_COMP {0} \ + CONFIG.PSU__DDRC__ENABLE_LP4_SLOWBOOT {0} \ + CONFIG.PSU__DDRC__EN_2ND_CLK {0} \ + CONFIG.PSU__DDRC__FGRM {1X} \ + CONFIG.PSU__DDRC__FREQ_MHZ {1} \ + CONFIG.PSU__DDRC__LPDDR3_DUALRANK_SDP {0} \ + CONFIG.PSU__DDRC__LPDDR3_T_REF_RANGE {NA} \ + CONFIG.PSU__DDRC__LPDDR4_T_REF_RANGE {NA} \ + CONFIG.PSU__DDRC__LP_ASR {manual normal} \ + CONFIG.PSU__DDRC__MEMORY_TYPE {DDR 4} \ + CONFIG.PSU__DDRC__PARITY_ENABLE {0} \ + CONFIG.PSU__DDRC__PER_BANK_REFRESH {0} \ + CONFIG.PSU__DDRC__PHY_DBI_MODE {0} \ + CONFIG.PSU__DDRC__PLL_BYPASS {0} \ + CONFIG.PSU__DDRC__PWR_DOWN_EN {0} \ + CONFIG.PSU__DDRC__RANK_ADDR_COUNT {0} \ + CONFIG.PSU__DDRC__RD_DQS_CENTER {0} \ + CONFIG.PSU__DDRC__ROW_ADDR_COUNT {15} \ + CONFIG.PSU__DDRC__SB_TARGET {15-15-15} \ + CONFIG.PSU__DDRC__SELF_REF_ABORT {0} \ + CONFIG.PSU__DDRC__SPEED_BIN {DDR4_2133P} \ + CONFIG.PSU__DDRC__STATIC_RD_MODE {0} \ + CONFIG.PSU__DDRC__TRAIN_DATA_EYE {1} \ + CONFIG.PSU__DDRC__TRAIN_READ_GATE {1} \ + CONFIG.PSU__DDRC__TRAIN_WRITE_LEVEL {1} \ + CONFIG.PSU__DDRC__T_FAW {30.0} \ + CONFIG.PSU__DDRC__T_RAS_MIN {33} \ + CONFIG.PSU__DDRC__T_RC {47.06} \ + CONFIG.PSU__DDRC__T_RCD {15} \ + CONFIG.PSU__DDRC__T_RP {15} \ + CONFIG.PSU__DDRC__VENDOR_PART {OTHERS} \ + CONFIG.PSU__DDRC__VIDEO_BUFFER_SIZE {0} \ + CONFIG.PSU__DDRC__VREF {1} \ + CONFIG.PSU__DDR_HIGH_ADDRESS_GUI_ENABLE {1} \ + CONFIG.PSU__DDR_QOS_ENABLE {0} \ + CONFIG.PSU__DDR_QOS_FIX_HP0_RDQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP0_WRQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP1_RDQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP1_WRQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP2_RDQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP2_WRQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP3_RDQOS {} \ + CONFIG.PSU__DDR_QOS_FIX_HP3_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP0_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP0_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP1_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP1_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP2_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP2_WRQOS {} \ + CONFIG.PSU__DDR_QOS_HP3_RDQOS {} \ + CONFIG.PSU__DDR_QOS_HP3_WRQOS {} \ + CONFIG.PSU__DDR_QOS_RD_HPR_THRSHLD {} \ + CONFIG.PSU__DDR_QOS_RD_LPR_THRSHLD {} \ + CONFIG.PSU__DDR_QOS_WR_THRSHLD {} \ + CONFIG.PSU__DDR_SW_REFRESH_ENABLED {1} \ + CONFIG.PSU__DDR__INTERFACE__FREQMHZ {533.500} \ + CONFIG.PSU__DEVICE_TYPE {EV} \ + CONFIG.PSU__DISPLAYPORT__LANE0__ENABLE {1} \ + CONFIG.PSU__DISPLAYPORT__LANE0__IO {GT Lane1} \ + CONFIG.PSU__DISPLAYPORT__LANE1__ENABLE {0} \ + CONFIG.PSU__DISPLAYPORT__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DLL__ISUSED {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__DPAUX__PERIPHERAL__IO {MIO 27 .. 30} \ + CONFIG.PSU__DP__LANE_SEL {Single Lower} \ + CONFIG.PSU__DP__REF_CLK_FREQ {27} \ + CONFIG.PSU__DP__REF_CLK_SEL {Ref Clk3} \ + CONFIG.PSU__ENABLE__DDR__REFRESH__SIGNALS {0} \ + CONFIG.PSU__ENET0__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET0__GRP_MDIO__ENABLE {0} \ + CONFIG.PSU__ENET0__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET0__PTP__ENABLE {0} \ + CONFIG.PSU__ENET0__TSU__ENABLE {0} \ + CONFIG.PSU__ENET1__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET1__GRP_MDIO__ENABLE {0} \ + CONFIG.PSU__ENET1__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET1__PTP__ENABLE {0} \ + CONFIG.PSU__ENET1__TSU__ENABLE {0} \ + CONFIG.PSU__ENET2__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET2__GRP_MDIO__ENABLE {0} \ + CONFIG.PSU__ENET2__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__ENET2__PTP__ENABLE {0} \ + CONFIG.PSU__ENET2__TSU__ENABLE {0} \ + CONFIG.PSU__ENET3__FIFO__ENABLE {0} \ + CONFIG.PSU__ENET3__GRP_MDIO__ENABLE {1} \ + CONFIG.PSU__ENET3__GRP_MDIO__IO {MIO 76 .. 77} \ + CONFIG.PSU__ENET3__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__ENET3__PERIPHERAL__IO {MIO 64 .. 75} \ + CONFIG.PSU__ENET3__PTP__ENABLE {0} \ + CONFIG.PSU__ENET3__TSU__ENABLE {0} \ + CONFIG.PSU__EN_AXI_STATUS_PORTS {0} \ + CONFIG.PSU__EN_EMIO_TRACE {0} \ + CONFIG.PSU__EP__IP {0} \ + CONFIG.PSU__EXPAND__CORESIGHT {0} \ + CONFIG.PSU__EXPAND__FPD_SLAVES {0} \ + CONFIG.PSU__EXPAND__GIC {0} \ + CONFIG.PSU__EXPAND__LOWER_LPS_SLAVES {0} \ + CONFIG.PSU__EXPAND__UPPER_LPS_SLAVES {0} \ + CONFIG.PSU__FPDMASTERS_COHERENCY {0} \ + CONFIG.PSU__FPD_SLCR__WDT1__ACT_FREQMHZ {99.990005} \ + CONFIG.PSU__FPD_SLCR__WDT1__FREQMHZ {99.990005} \ + CONFIG.PSU__FPD_SLCR__WDT_CLK_SEL__SELECT {APB} \ + CONFIG.PSU__FPGA_PL0_ENABLE {1} \ + CONFIG.PSU__FPGA_PL1_ENABLE {0} \ + CONFIG.PSU__FPGA_PL2_ENABLE {0} \ + CONFIG.PSU__FPGA_PL3_ENABLE {0} \ + CONFIG.PSU__FP__POWER__ON {1} \ + CONFIG.PSU__FTM__CTI_IN_0 {0} \ + CONFIG.PSU__FTM__CTI_IN_1 {0} \ + CONFIG.PSU__FTM__CTI_IN_2 {0} \ + CONFIG.PSU__FTM__CTI_IN_3 {0} \ + CONFIG.PSU__FTM__CTI_OUT_0 {0} \ + CONFIG.PSU__FTM__CTI_OUT_1 {0} \ + CONFIG.PSU__FTM__CTI_OUT_2 {0} \ + CONFIG.PSU__FTM__CTI_OUT_3 {0} \ + CONFIG.PSU__FTM__GPI {0} \ + CONFIG.PSU__FTM__GPO {0} \ + CONFIG.PSU__GEM0_COHERENCY {0} \ + CONFIG.PSU__GEM0_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__GEM1_COHERENCY {0} \ + CONFIG.PSU__GEM1_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__GEM2_COHERENCY {0} \ + CONFIG.PSU__GEM2_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__GEM3_COHERENCY {0} \ + CONFIG.PSU__GEM3_ROUTE_THROUGH_FPD {0} \ + CONFIG.PSU__GEM__TSU__ENABLE {0} \ + CONFIG.PSU__GEN_IPI_0__MASTER {APU} \ + CONFIG.PSU__GEN_IPI_10__MASTER {NONE} \ + CONFIG.PSU__GEN_IPI_1__MASTER {RPU0} \ + CONFIG.PSU__GEN_IPI_2__MASTER {RPU1} \ + CONFIG.PSU__GEN_IPI_3__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_4__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_5__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_6__MASTER {PMU} \ + CONFIG.PSU__GEN_IPI_7__MASTER {NONE} \ + CONFIG.PSU__GEN_IPI_8__MASTER {NONE} \ + CONFIG.PSU__GEN_IPI_9__MASTER {NONE} \ + CONFIG.PSU__GPIO0_MIO__IO {MIO 0 .. 25} \ + CONFIG.PSU__GPIO0_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO1_MIO__IO {MIO 26 .. 51} \ + CONFIG.PSU__GPIO1_MIO__PERIPHERAL__ENABLE {1} \ + CONFIG.PSU__GPIO2_MIO__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__GPIO_EMIO_WIDTH {1} \ + CONFIG.PSU__GPIO_EMIO__PERIPHERAL__ENABLE {0} \ + CONFIG.PSU__GPIO_EMIO__PERIPHERAL__IO {} \ CONFIG.PSU__GPIO_EMIO__WIDTH {[94:0]} \ CONFIG.PSU__GPU_PP0__POWER__ON {1} \ CONFIG.PSU__GPU_PP1__POWER__ON {1} \ @@ -1403,22 +1349,13 @@ proc create_root_design { parentCell } { CONFIG.PSU__IRQ_P2F_APU_PMU__INT {0} \ CONFIG.PSU__IRQ_P2F_APU_REGS__INT {0} \ CONFIG.PSU__IRQ_P2F_ATB_LPD__INT {0} \ - CONFIG.PSU__IRQ_P2F_CAN0__INT {0} \ CONFIG.PSU__IRQ_P2F_CAN1__INT {0} \ CONFIG.PSU__IRQ_P2F_CLKMON__INT {0} \ CONFIG.PSU__IRQ_P2F_CSUPMU_WDT__INT {0} \ - CONFIG.PSU__IRQ_P2F_CSU_DMA__INT {0} \ - CONFIG.PSU__IRQ_P2F_CSU__INT {0} \ CONFIG.PSU__IRQ_P2F_DDR_SS__INT {0} \ CONFIG.PSU__IRQ_P2F_DPDMA__INT {0} \ CONFIG.PSU__IRQ_P2F_DPORT__INT {0} \ CONFIG.PSU__IRQ_P2F_EFUSE__INT {0} \ - CONFIG.PSU__IRQ_P2F_ENT0_WAKEUP__INT {0} \ - CONFIG.PSU__IRQ_P2F_ENT0__INT {0} \ - CONFIG.PSU__IRQ_P2F_ENT1_WAKEUP__INT {0} \ - CONFIG.PSU__IRQ_P2F_ENT1__INT {0} \ - CONFIG.PSU__IRQ_P2F_ENT2_WAKEUP__INT {0} \ - CONFIG.PSU__IRQ_P2F_ENT2__INT {0} \ CONFIG.PSU__IRQ_P2F_ENT3_WAKEUP__INT {0} \ CONFIG.PSU__IRQ_P2F_ENT3__INT {0} \ CONFIG.PSU__IRQ_P2F_FPD_APB__INT {0} \ @@ -1432,7 +1369,6 @@ proc create_root_design { parentCell } { CONFIG.PSU__IRQ_P2F_LPD_APB__INT {0} \ CONFIG.PSU__IRQ_P2F_LPD_APM__INT {0} \ CONFIG.PSU__IRQ_P2F_LP_WDT__INT {0} \ - CONFIG.PSU__IRQ_P2F_NAND__INT {0} \ CONFIG.PSU__IRQ_P2F_OCM_ERR__INT {0} \ CONFIG.PSU__IRQ_P2F_PCIE_DMA__INT {0} \ CONFIG.PSU__IRQ_P2F_PCIE_LEGACY__INT {0} \ @@ -1447,12 +1383,8 @@ proc create_root_design { parentCell } { CONFIG.PSU__IRQ_P2F_RTC_ALARM__INT {0} \ CONFIG.PSU__IRQ_P2F_RTC_SECONDS__INT {0} \ CONFIG.PSU__IRQ_P2F_SATA__INT {0} \ - CONFIG.PSU__IRQ_P2F_SDIO0_WAKE__INT {0} \ - CONFIG.PSU__IRQ_P2F_SDIO0__INT {0} \ CONFIG.PSU__IRQ_P2F_SDIO1_WAKE__INT {0} \ CONFIG.PSU__IRQ_P2F_SDIO1__INT {0} \ - CONFIG.PSU__IRQ_P2F_SPI0__INT {0} \ - CONFIG.PSU__IRQ_P2F_SPI1__INT {0} \ CONFIG.PSU__IRQ_P2F_TTC0__INT0 {0} \ CONFIG.PSU__IRQ_P2F_TTC0__INT1 {0} \ CONFIG.PSU__IRQ_P2F_TTC0__INT2 {0} \ @@ -1494,13 +1426,7 @@ proc create_root_design { parentCell } { CONFIG.PSU__M_AXI_GP0_SUPPORTS_NARROW_BURST {1} \ CONFIG.PSU__M_AXI_GP1_SUPPORTS_NARROW_BURST {1} \ CONFIG.PSU__M_AXI_GP2_SUPPORTS_NARROW_BURST {1} \ - CONFIG.PSU__NAND_COHERENCY {0} \ - CONFIG.PSU__NAND_ROUTE_THROUGH_FPD {0} \ - CONFIG.PSU__NAND__CHIP_ENABLE__ENABLE {0} \ - CONFIG.PSU__NAND__DATA_STROBE__ENABLE {0} \ CONFIG.PSU__NAND__PERIPHERAL__ENABLE {0} \ - CONFIG.PSU__NAND__READY0_BUSY__ENABLE {0} \ - CONFIG.PSU__NAND__READY1_BUSY__ENABLE {0} \ CONFIG.PSU__NAND__READY_BUSY__ENABLE {0} \ CONFIG.PSU__NUM_FABRIC_RESETS {1} \ CONFIG.PSU__OCM_BANK0__POWER__ON {1} \ @@ -1510,9 +1436,7 @@ proc create_root_design { parentCell } { CONFIG.PSU__OVERRIDE_HPX_QOS {0} \ CONFIG.PSU__OVERRIDE__BASIC_CLOCK {0} \ CONFIG.PSU__PCIE__ACS_VIOLAION {0} \ - CONFIG.PSU__PCIE__ACS_VIOLATION {0} \ CONFIG.PSU__PCIE__AER_CAPABILITY {0} \ - CONFIG.PSU__PCIE__ATOMICOP_EGRESS_BLOCKED {0} \ CONFIG.PSU__PCIE__BAR0_64BIT {0} \ CONFIG.PSU__PCIE__BAR0_ENABLE {0} \ CONFIG.PSU__PCIE__BAR0_PREFETCHABLE {0} \ @@ -1541,20 +1465,11 @@ proc create_root_design { parentCell } { CONFIG.PSU__PCIE__CLASS_CODE_INTERFACE {0x0} \ CONFIG.PSU__PCIE__CLASS_CODE_SUB {0x4} \ CONFIG.PSU__PCIE__CLASS_CODE_VALUE {0x60400} \ - CONFIG.PSU__PCIE__COMPLETER_ABORT {0} \ - CONFIG.PSU__PCIE__COMPLTION_TIMEOUT {0} \ - CONFIG.PSU__PCIE__CORRECTABLE_INT_ERR {0} \ CONFIG.PSU__PCIE__CRS_SW_VISIBILITY {1} \ CONFIG.PSU__PCIE__DEVICE_ID {0xD021} \ CONFIG.PSU__PCIE__DEVICE_PORT_TYPE {Root Port} \ - CONFIG.PSU__PCIE__ECRC_CHECK {0} \ - CONFIG.PSU__PCIE__ECRC_ERR {0} \ - CONFIG.PSU__PCIE__ECRC_GEN {0} \ CONFIG.PSU__PCIE__EROM_ENABLE {0} \ CONFIG.PSU__PCIE__EROM_VAL {0x0} \ - CONFIG.PSU__PCIE__FLOW_CONTROL_ERR {0} \ - CONFIG.PSU__PCIE__FLOW_CONTROL_PROTOCOL_ERR {0} \ - CONFIG.PSU__PCIE__HEADER_LOG_OVERFLOW {0} \ CONFIG.PSU__PCIE__INTX_GENERATION {0} \ CONFIG.PSU__PCIE__LANE0__ENABLE {1} \ CONFIG.PSU__PCIE__LANE0__IO {GT Lane0} \ @@ -1564,7 +1479,6 @@ proc create_root_design { parentCell } { CONFIG.PSU__PCIE__LINK_SPEED {5.0 Gb/s} \ CONFIG.PSU__PCIE__MAXIMUM_LINK_WIDTH {x1} \ CONFIG.PSU__PCIE__MAX_PAYLOAD_SIZE {256 bytes} \ - CONFIG.PSU__PCIE__MC_BLOCKED_TLP {0} \ CONFIG.PSU__PCIE__MSIX_BAR_INDICATOR {} \ CONFIG.PSU__PCIE__MSIX_CAPABILITY {0} \ CONFIG.PSU__PCIE__MSIX_PBA_BAR_INDICATOR {} \ @@ -1573,29 +1487,19 @@ proc create_root_design { parentCell } { CONFIG.PSU__PCIE__MSIX_TABLE_SIZE {0} \ CONFIG.PSU__PCIE__MSI_64BIT_ADDR_CAPABLE {0} \ CONFIG.PSU__PCIE__MSI_CAPABILITY {0} \ - CONFIG.PSU__PCIE__MULTIHEADER {0} \ CONFIG.PSU__PCIE__PERIPHERAL__ENABLE {1} \ CONFIG.PSU__PCIE__PERIPHERAL__ENDPOINT_ENABLE {0} \ CONFIG.PSU__PCIE__PERIPHERAL__ROOTPORT_ENABLE {1} \ CONFIG.PSU__PCIE__PERIPHERAL__ROOTPORT_IO {MIO 31} \ - CONFIG.PSU__PCIE__PERM_ROOT_ERR_UPDATE {0} \ - CONFIG.PSU__PCIE__RECEIVER_ERR {0} \ - CONFIG.PSU__PCIE__RECEIVER_OVERFLOW {0} \ CONFIG.PSU__PCIE__REF_CLK_FREQ {100} \ CONFIG.PSU__PCIE__REF_CLK_SEL {Ref Clk0} \ CONFIG.PSU__PCIE__RESET__POLARITY {Active Low} \ CONFIG.PSU__PCIE__REVISION_ID {0x0} \ CONFIG.PSU__PCIE__SUBSYSTEM_ID {0x7} \ CONFIG.PSU__PCIE__SUBSYSTEM_VENDOR_ID {0x10EE} \ - CONFIG.PSU__PCIE__SURPRISE_DOWN {0} \ - CONFIG.PSU__PCIE__TLP_PREFIX_BLOCKED {0} \ - CONFIG.PSU__PCIE__UNCORRECTABL_INT_ERR {0} \ CONFIG.PSU__PCIE__VENDOR_ID {0x10EE} \ CONFIG.PSU__PJTAG__PERIPHERAL__ENABLE {0} \ CONFIG.PSU__PL_CLK0_BUF {TRUE} \ - CONFIG.PSU__PL_CLK1_BUF {FALSE} \ - CONFIG.PSU__PL_CLK2_BUF {FALSE} \ - CONFIG.PSU__PL_CLK3_BUF {FALSE} \ CONFIG.PSU__PL__POWER__ON {1} \ CONFIG.PSU__PMU_COHERENCY {0} \ CONFIG.PSU__PMU__AIBACK__ENABLE {0} \ @@ -1627,10 +1531,8 @@ proc create_root_design { parentCell } { CONFIG.PSU__PMU__PLERROR__ENABLE {0} \ CONFIG.PSU__PRESET_APPLIED {1} \ CONFIG.PSU__PROTECTION__DDR_SEGMENTS {NONE} \ - CONFIG.PSU__PROTECTION__DEBUG {0} \ CONFIG.PSU__PROTECTION__ENABLE {0} \ CONFIG.PSU__PROTECTION__FPD_SEGMENTS {SA:0xFD1A0000; SIZE:1280; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD000000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD010000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD020000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD030000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD040000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD050000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD610000; SIZE:512; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD5D0000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware | SA:0xFD1A0000 ; SIZE:1280; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem} \ - CONFIG.PSU__PROTECTION__LOCK_UNUSED_SEGMENTS {0} \ CONFIG.PSU__PROTECTION__LPD_SEGMENTS {SA:0xFF980000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFF5E0000; SIZE:2560; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFFCC0000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFF180000; SIZE:768; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFF410000; SIZE:640; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFFA70000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware| SA:0xFF9A0000; SIZE:64; UNIT:KB; RegionTZ:Secure; WrAllowed:Read/Write; subsystemId:PMU Firmware|SA:0xFF5E0000 ; SIZE:2560; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem|SA:0xFFCC0000 ; SIZE:64; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem|SA:0xFF180000 ; SIZE:768; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem|SA:0xFF9A0000 ; SIZE:64; UNIT:KB; RegionTZ:Secure ; WrAllowed:Read/Write; subsystemId:Secure Subsystem} \ CONFIG.PSU__PROTECTION__MASTERS {USB1:NonSecure;0|USB0:NonSecure;1|S_AXI_LPD:NA;0|S_AXI_HPC1_FPD:NA;0|S_AXI_HPC0_FPD:NA;1|S_AXI_HP3_FPD:NA;0|S_AXI_HP2_FPD:NA;0|S_AXI_HP1_FPD:NA;0|S_AXI_HP0_FPD:NA;0|S_AXI_ACP:NA;0|S_AXI_ACE:NA;0|SD1:NonSecure;1|SD0:NonSecure;0|SATA1:NonSecure;1|SATA0:NonSecure;1|RPU1:Secure;1|RPU0:Secure;1|QSPI:NonSecure;1|PMU:NA;1|PCIe:NonSecure;1|NAND:NonSecure;0|LDMA:NonSecure;1|GPU:NonSecure;1|GEM3:NonSecure;1|GEM2:NonSecure;0|GEM1:NonSecure;0|GEM0:NonSecure;0|FDMA:NonSecure;1|DP:NonSecure;1|DAP:NA;1|Coresight:NA;1|CSU:NA;1|APU:NA;1} \ CONFIG.PSU__PROTECTION__MASTERS_TZ {GEM0:NonSecure|SD1:NonSecure|GEM2:NonSecure|GEM1:NonSecure|GEM3:NonSecure|PCIe:NonSecure|DP:NonSecure|NAND:NonSecure|GPU:NonSecure|USB1:NonSecure|USB0:NonSecure|LDMA:NonSecure|FDMA:NonSecure|QSPI:NonSecure|SD0:NonSecure} \ @@ -1659,17 +1561,6 @@ proc create_root_design { parentCell } { CONFIG.PSU__SATA__REF_CLK_FREQ {125} \ CONFIG.PSU__SATA__REF_CLK_SEL {Ref Clk1} \ CONFIG.PSU__SAXIGP0__DATA_WIDTH {32} \ - CONFIG.PSU__SAXIGP1__DATA_WIDTH {128} \ - CONFIG.PSU__SAXIGP2__DATA_WIDTH {128} \ - CONFIG.PSU__SAXIGP3__DATA_WIDTH {128} \ - CONFIG.PSU__SAXIGP4__DATA_WIDTH {128} \ - CONFIG.PSU__SAXIGP5__DATA_WIDTH {128} \ - CONFIG.PSU__SAXIGP6__DATA_WIDTH {128} \ - CONFIG.PSU__SD0_COHERENCY {0} \ - CONFIG.PSU__SD0_ROUTE_THROUGH_FPD {0} \ - CONFIG.PSU__SD0__GRP_CD__ENABLE {0} \ - CONFIG.PSU__SD0__GRP_POW__ENABLE {0} \ - CONFIG.PSU__SD0__GRP_WP__ENABLE {0} \ CONFIG.PSU__SD0__PERIPHERAL__ENABLE {0} \ CONFIG.PSU__SD0__RESET__ENABLE {0} \ CONFIG.PSU__SD1_COHERENCY {0} \ @@ -1685,13 +1576,7 @@ proc create_root_design { parentCell } { CONFIG.PSU__SD1__RESET__ENABLE {0} \ CONFIG.PSU__SD1__SLOT_TYPE {SD 3.0} \ CONFIG.PSU__SPI0_LOOP_SPI1__ENABLE {0} \ - CONFIG.PSU__SPI0__GRP_SS0__ENABLE {0} \ - CONFIG.PSU__SPI0__GRP_SS1__ENABLE {0} \ - CONFIG.PSU__SPI0__GRP_SS2__ENABLE {0} \ CONFIG.PSU__SPI0__PERIPHERAL__ENABLE {0} \ - CONFIG.PSU__SPI1__GRP_SS0__ENABLE {0} \ - CONFIG.PSU__SPI1__GRP_SS1__ENABLE {0} \ - CONFIG.PSU__SPI1__GRP_SS2__ENABLE {0} \ CONFIG.PSU__SPI1__PERIPHERAL__ENABLE {0} \ CONFIG.PSU__SWDT0__CLOCK__ENABLE {0} \ CONFIG.PSU__SWDT0__PERIPHERAL__ENABLE {1} \ @@ -1706,7 +1591,6 @@ proc create_root_design { parentCell } { CONFIG.PSU__TCM1A__POWER__ON {1} \ CONFIG.PSU__TCM1B__POWER__ON {1} \ CONFIG.PSU__TESTSCAN__PERIPHERAL__ENABLE {0} \ - CONFIG.PSU__TRACE_PIPELINE_WIDTH {8} \ CONFIG.PSU__TRACE__INTERNAL_WIDTH {32} \ CONFIG.PSU__TRACE__PERIPHERAL__ENABLE {0} \ CONFIG.PSU__TRISTATE__INVERTED {1} \ @@ -1742,25 +1626,15 @@ proc create_root_design { parentCell } { CONFIG.PSU__USB0__REF_CLK_FREQ {26} \ CONFIG.PSU__USB0__REF_CLK_SEL {Ref Clk2} \ CONFIG.PSU__USB0__RESET__ENABLE {0} \ - CONFIG.PSU__USB1_COHERENCY {0} \ CONFIG.PSU__USB1__PERIPHERAL__ENABLE {0} \ CONFIG.PSU__USB1__RESET__ENABLE {0} \ CONFIG.PSU__USB2_0__EMIO__ENABLE {0} \ - CONFIG.PSU__USB2_1__EMIO__ENABLE {0} \ CONFIG.PSU__USB3_0__EMIO__ENABLE {0} \ CONFIG.PSU__USB3_0__PERIPHERAL__ENABLE {1} \ CONFIG.PSU__USB3_0__PERIPHERAL__IO {GT Lane2} \ - CONFIG.PSU__USB3_1__EMIO__ENABLE {0} \ - CONFIG.PSU__USB3_1__PERIPHERAL__ENABLE {0} \ CONFIG.PSU__USB__RESET__MODE {Boot Pin} \ CONFIG.PSU__USB__RESET__POLARITY {Active Low} \ CONFIG.PSU__USE_DIFF_RW_CLK_GP0 {0} \ - CONFIG.PSU__USE_DIFF_RW_CLK_GP1 {0} \ - CONFIG.PSU__USE_DIFF_RW_CLK_GP2 {0} \ - CONFIG.PSU__USE_DIFF_RW_CLK_GP3 {0} \ - CONFIG.PSU__USE_DIFF_RW_CLK_GP4 {0} \ - CONFIG.PSU__USE_DIFF_RW_CLK_GP5 {0} \ - CONFIG.PSU__USE_DIFF_RW_CLK_GP6 {0} \ CONFIG.PSU__USE__ADMA {0} \ CONFIG.PSU__USE__APU_LEGACY_INTERRUPT {0} \ CONFIG.PSU__USE__AUDIO {0} \ @@ -1839,19 +1713,21 @@ proc create_root_design { parentCell } { connect_bd_net -net zynq_ultra_ps_e_0_pl_resetn0 [get_bd_pins rst_ps8_0_99M/ext_reset_in] [get_bd_pins zynq_ultra_ps_e_0/pl_resetn0] # Create address segments - assign_bd_address -offset 0xA0000000 -range 0x00010000 -target_address_space [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs hier_0/axi_dma_0/S_AXI_LITE/Reg] -force - assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] -force - assign_bd_address -offset 0x00000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] -force - assign_bd_address -offset 0xE0000000 -range 0x10000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_PCIE_LOW] -force - assign_bd_address -offset 0xE0000000 -range 0x10000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_PCIE_LOW] -force - assign_bd_address -offset 0xC0000000 -range 0x20000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] -force - assign_bd_address -offset 0xC0000000 -range 0x20000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] -force + create_bd_addr_seg -range 0x00001000 -offset 0xA0000000 [get_bd_addr_spaces zynq_ultra_ps_e_0/Data] [get_bd_addr_segs hier_0/axi_dma_0/S_AXI_LITE/Reg] SEG_axi_dma_0_Reg + create_bd_addr_seg -range 0x80000000 -offset 0x00000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] SEG_zynq_ultra_ps_e_0_HPC0_DDR_LOW + create_bd_addr_seg -range 0x80000000 -offset 0x00000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_LOW] SEG_zynq_ultra_ps_e_0_HPC0_DDR_LOW + create_bd_addr_seg -range 0x10000000 -offset 0xE0000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_PCIE_LOW] SEG_zynq_ultra_ps_e_0_HPC0_PCIE_LOW + create_bd_addr_seg -range 0x10000000 -offset 0xE0000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_PCIE_LOW] SEG_zynq_ultra_ps_e_0_HPC0_PCIE_LOW + create_bd_addr_seg -range 0x20000000 -offset 0xC0000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] SEG_zynq_ultra_ps_e_0_HPC0_QSPI + create_bd_addr_seg -range 0x20000000 -offset 0xC0000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_QSPI] SEG_zynq_ultra_ps_e_0_HPC0_QSPI # Exclude Address Segments - exclude_bd_addr_seg -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_HIGH] - exclude_bd_addr_seg -offset 0xFF000000 -range 0x01000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] - exclude_bd_addr_seg -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_DDR_HIGH] - exclude_bd_addr_seg -offset 0xFF000000 -range 0x01000000 -target_address_space [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] + create_bd_addr_seg -range 0x01000000 -offset 0xFF000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_MM2S] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] SEG_zynq_ultra_ps_e_0_HPC0_LPS_OCM + exclude_bd_addr_seg [get_bd_addr_segs hier_0/axi_dma_0/Data_MM2S/SEG_zynq_ultra_ps_e_0_HPC0_LPS_OCM] + + create_bd_addr_seg -range 0x01000000 -offset 0xFF000000 [get_bd_addr_spaces hier_0/axi_dma_0/Data_S2MM] [get_bd_addr_segs zynq_ultra_ps_e_0/SAXIGP0/HPC0_LPS_OCM] SEG_zynq_ultra_ps_e_0_HPC0_LPS_OCM + exclude_bd_addr_seg [get_bd_addr_segs hier_0/axi_dma_0/Data_S2MM/SEG_zynq_ultra_ps_e_0_HPC0_LPS_OCM] + # Restore current instance @@ -1871,6 +1747,7 @@ create_root_design "" + #WRAP THE MODEL make_wrapper -files [get_files ./${myproject}_vivado_accelerator/project_1.srcs/sources_1/bd/design_1/design_1.bd] -top @@ -1885,4 +1762,3 @@ wait_on_run -timeout 360 impl_1 #open_run impl_1 report_utilization -file util.rpt -hierarchical -hierarchical_percentages - From d8a2f9a97927b652583bd4ff5331d839e2e6d083 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 18:32:26 -0500 Subject: [PATCH 11/14] Update supported_boards.json --- hls4ml/templates/supported_boards.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/templates/supported_boards.json b/hls4ml/templates/supported_boards.json index ccc961d66..584705f19 100644 --- a/hls4ml/templates/supported_boards.json +++ b/hls4ml/templates/supported_boards.json @@ -39,7 +39,7 @@ "zcu104": { "part": "xczu7ev-ffvc1156-2-e", - "tcl_scripts": {"axi_master": "axi_stream_design.tcl"}, + "tcl_scripts": {"axi_stream": "axi_stream_design.tcl"}, "python_drivers": {"axi_stream": "axi_stream_driver.py"}, "c_drivers": {} } From f632a06f4ea91ba5727c8f9b215efef8c280b140 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 18:41:39 -0500 Subject: [PATCH 12/14] Update axi_stream_design.tcl --- .../vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl index a2507adb8..e7780ab5b 100644 --- a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl +++ b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl @@ -20,7 +20,7 @@ set script_folder [_tcl::get_script_folder] ################################################################ # Check if script is running in correct Vivado version. ################################################################ -set scripts_vivado_version 2019.2 +set scripts_vivado_version 2019.1 set current_vivado_version [version -short] if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { From a8c82f1b63a3be6b7267e4b9415a6bd45813683f Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 18:53:24 -0500 Subject: [PATCH 13/14] Update axi_stream_design.tcl --- .../zcu104/tcl_scripts/axi_stream_design.tcl | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl index e7780ab5b..521dd9441 100644 --- a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl +++ b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl @@ -43,14 +43,25 @@ if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { set list_projs [get_projects -quiet] if { $list_projs eq "" } { - create_project project_1 myproj -part xczu7ev-ffvc1156-2-e -force + create_project project_1 ${myproject}_vivado_accelerator -part xczu7ev-ffvc1156-2-e -force set_property BOARD_PART xilinx.com:zcu104:part0:1.1 [current_project] } + +# Setup IP repo +set_property ip_repo_paths ${myproject}_prj/${hls_solution_name}/impl/ip [current_project] +#set_property ip_repo_paths /home/subnugler/Desktop/MICROBLAZE_TEST/Microblaze/myproject_prj/${hls_solution_name}/impl/ip [current_project] +update_ip_catalog + + + + + + # CHANGE DESIGN NAME HERE -variable design_name -set design_name design_1 +#variable design_name +#set design_name design_1 # If you do not already have an existing IP Integrator design open, # you can create a design using the following command: @@ -1761,4 +1772,3 @@ wait_on_run -timeout 360 impl_1 #open_run impl_1 report_utilization -file util.rpt -hierarchical -hierarchical_percentages - From 4c790b4e324c6d2906075a0bf31d3a4c6459d981 Mon Sep 17 00:00:00 2001 From: Mehdi Rahimifar <92753268+MehdiRh17@users.noreply.github.com> Date: Thu, 19 Jan 2023 19:09:50 -0500 Subject: [PATCH 14/14] Update axi_stream_design.tcl --- .../zcu104/tcl_scripts/axi_stream_design.tcl | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl index 521dd9441..4a35d1bb5 100644 --- a/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl +++ b/hls4ml/templates/vivado_accelerator/zcu104/tcl_scripts/axi_stream_design.tcl @@ -17,18 +17,23 @@ proc get_script_folder {} { variable script_folder set script_folder [_tcl::get_script_folder] + + + +set tcldir [file dirname [info script]] +source [file join $tcldir project.tcl] ################################################################ # Check if script is running in correct Vivado version. ################################################################ -set scripts_vivado_version 2019.1 -set current_vivado_version [version -short] +#set scripts_vivado_version 2019.1 +#set current_vivado_version [version -short] -if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { - puts "" - catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} +#if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { +# puts "" +# catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} - return 1 -} + # return 1 +#} ############################################################### # START @@ -41,6 +46,22 @@ if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { # project, but make sure you do not have an existing project # <./myproj/project_1.xpr> in the current working folder. + + +set project_name "project_1" +set design_name "design_1" +set hls_solution_name "solution1" +#set acc_name "${myproject}_axi" +set part_name "xczu7ev-ffvc1156-2-e" +set board_name "xilinx.com:zcu104:part0:1.1" + + + + + + + + set list_projs [get_projects -quiet] if { $list_projs eq "" } { create_project project_1 ${myproject}_vivado_accelerator -part xczu7ev-ffvc1156-2-e -force