diff --git a/Bender.yml b/Bender.yml index d93b0b0e3..29c015f4e 100644 --- a/Bender.yml +++ b/Bender.yml @@ -72,6 +72,7 @@ sources: files: - target/xilinx/src/carfield_top_xilinx.sv - target/xilinx/src/dram_wrapper.sv + - target/xilinx/src/cdc_dst_axi_err.sv - target/xilinx/src/overrides/tc_clk_xilinx.sv - target: intel16_elab_only diff --git a/bender-xilinx.mk b/bender-xilinx.mk index 33e59a4f1..b11c04668 100644 --- a/bender-xilinx.mk +++ b/bender-xilinx.mk @@ -21,5 +21,6 @@ $(eval $(call check_enable_island,GEN_PULP_CLUSTER)) $(eval $(call check_enable_island,GEN_SAFETY_ISLAND)) $(eval $(call check_enable_island,GEN_SPATZ_CLUSTER)) $(eval $(call check_enable_island,GEN_OPEN_TITAN)) +$(eval $(call check_enable_island,NO_HYPERBUS)) # note : bender targets are later modified in xilinx.mk diff --git a/carfield.mk b/carfield.mk index d1b67d80f..d0bf6a148 100644 --- a/carfield.mk +++ b/carfield.mk @@ -100,7 +100,7 @@ endif ###################### CAR_NONFREE_REMOTE ?= git@iis-git.ee.ethz.ch:carfield/carfield-nonfree.git -CAR_NONFREE_COMMIT ?= 56a40e56f60b6a1e1ead1373c273d51bbb5c9c4f +CAR_NONFREE_COMMIT ?= cbabc86ab678ccf6ad60c2651d1f1bbbe3897f66 ## Clone the non-free verification IP for the Carfield TB car-nonfree-init: diff --git a/hw/carfield.sv b/hw/carfield.sv index 85e9e391d..b24804a49 100644 --- a/hw/carfield.sv +++ b/hw/carfield.sv @@ -25,6 +25,14 @@ module carfield parameter islands_cfg_t IslandsCfg = carfield_pkg::IslandsCfgDefault, parameter int unsigned HypNumPhys = 2, parameter int unsigned HypNumChips = 2, +`ifdef NO_HYPERBUS // bender-xilinx.mk + parameter int unsigned LlcIdWidth, + parameter int unsigned LlcArWidth, + parameter int unsigned LlcAwWidth, + parameter int unsigned LlcBWidth, + parameter int unsigned LlcRWidth, + parameter int unsigned LlcWWidth, +`endif parameter type reg_req_t = logic, parameter type reg_rsp_t = logic ) ( @@ -122,6 +130,7 @@ module carfield output logic [SlinkNumChan-1:0] slink_rcv_clk_o, input logic [SlinkNumChan-1:0][SlinkNumLanes-1:0] slink_i, output logic [SlinkNumChan-1:0][SlinkNumLanes-1:0] slink_o, +`ifndef NO_HYPERBUS // bender-xilinx.mk // HyperBus interface output logic [HypNumPhys-1:0][HypNumChips-1:0] hyper_cs_no, output logic [HypNumPhys-1:0] hyper_ck_o, @@ -133,6 +142,25 @@ module carfield output logic [HypNumPhys-1:0][7:0] hyper_dq_o, output logic [HypNumPhys-1:0] hyper_dq_oe_o, output logic [HypNumPhys-1:0] hyper_reset_no, +`else + // LLC interface + output logic [LlcArWidth-1:0] llc_ar_data, + output logic [ LogDepth:0] llc_ar_wptr, + input logic [ LogDepth:0] llc_ar_rptr, + output logic [LlcAwWidth-1:0] llc_aw_data, + output logic [ LogDepth:0] llc_aw_wptr, + input logic [ LogDepth:0] llc_aw_rptr, + input logic [ LlcBWidth-1:0] llc_b_data, + input logic [ LogDepth:0] llc_b_wptr, + output logic [ LogDepth:0] llc_b_rptr, + input logic [ LlcRWidth-1:0] llc_r_data, + input logic [ LogDepth:0] llc_r_wptr, + output logic [ LogDepth:0] llc_r_rptr, + output logic [ LlcWWidth-1:0] llc_w_data, + output logic [ LogDepth:0] llc_w_wptr, + input logic [ LogDepth:0] llc_w_rptr, +`endif // NO_HYPERBUS + // External reg interface slaves (async) // Currently for PLL and Padframe output logic [1:0] ext_reg_async_slv_req_o, @@ -401,6 +429,7 @@ localparam int unsigned IntClusterAxiMstRWidth = carfield_reg_req_t [iomsb(NumSyncRegSlv):0] ext_reg_req; carfield_reg_rsp_t [iomsb(NumSyncRegSlv):0] ext_reg_rsp; +`ifndef NO_HYPERBUS // bender-xilinx.mk localparam int unsigned LlcIdWidth = Cfg.AxiMstIdWidth + $clog2(AxiIn.num_in)+ Cfg.LlcNotBypass ; @@ -423,12 +452,6 @@ localparam int unsigned LlcWWidth = (2**LogDepth)* axi_pkg::w_width(Cfg.AxiDataWidth, Cfg.AxiUserWidth ); -logic hyper_isolate_req, hyper_isolated_rsp; -logic security_island_isolate_req; - -logic [iomsb(Cfg.AxiExtNumSlv-1):0] slave_isolate_req, slave_isolated_rsp, slave_isolated; -logic [iomsb(Cfg.AxiExtNumMst):0] master_isolated_rsp; - logic [LlcArWidth-1:0] llc_ar_data; logic [ LogDepth:0] llc_ar_wptr; logic [ LogDepth:0] llc_ar_rptr; @@ -445,6 +468,14 @@ logic [ LlcWWidth-1:0] llc_w_data; logic [ LogDepth:0] llc_w_wptr; logic [ LogDepth:0] llc_w_rptr; +`endif // NO_HYPERBUS + +logic hyper_isolate_req, hyper_isolated_rsp; +logic security_island_isolate_req; + +logic [iomsb(Cfg.AxiExtNumSlv-1):0] slave_isolate_req, slave_isolated_rsp, slave_isolated; +logic [iomsb(Cfg.AxiExtNumMst):0] master_isolated_rsp; + // All AXI Slaves (except the Integer Cluster and the Mailbox) logic [iomsb(Cfg.AxiExtNumSlv-2):0][CarfieldAxiSlvAwWidth-1:0] axi_slv_ext_aw_data; logic [iomsb(Cfg.AxiExtNumSlv-2):0][ LogDepth:0] axi_slv_ext_aw_wptr; @@ -1084,6 +1115,7 @@ cheshire i_cheshire_wrap ( .vga_blue_o ( ) ); +`ifndef NO_HYPERBUS // bender-xilinx.mk // Hyperbus hyperbus_wrap #( .NumChips ( HypNumChips ), @@ -1155,6 +1187,7 @@ hyperbus_wrap #( .hyper_dq_oe_o, .hyper_reset_no ); +`endif // NO_HYPERBUS // Reconfigurable L2 Memory // Host Clock Domain @@ -1368,6 +1401,42 @@ safety_island_synth_wrapper #( end else begin : gen_no_safety_island assign jtag_safety_island_tdo_o = jtag_safety_island_tdi_i; + cdc_dst_axi_err #( + .AxiInIdWidth ( AxiSlvIdWidth ), + .LogDepth ( LogDepth ), + .CdcSyncStages ( SyncStages ), + .axi_in_aw_chan_t ( carfield_axi_slv_aw_chan_t ), + .axi_in_w_chan_t ( carfield_axi_slv_w_chan_t ), + .axi_in_b_chan_t ( carfield_axi_slv_b_chan_t ), + .axi_in_ar_chan_t ( carfield_axi_slv_ar_chan_t ), + .axi_in_r_chan_t ( carfield_axi_slv_r_chan_t ), + .axi_in_resp_t ( carfield_axi_slv_rsp_t ), + .axi_in_req_t ( carfield_axi_slv_req_t ), + .AsyncAxiInAwWidth ( CarfieldAxiSlvAwWidth ), + .AsyncAxiInWWidth ( CarfieldAxiSlvWWidth ), + .AsyncAxiInBWidth ( CarfieldAxiSlvBWidth ), + .AsyncAxiInArWidth ( CarfieldAxiSlvArWidth ), + .AsyncAxiInRWidth ( CarfieldAxiSlvRWidth ) + ) i_safety_island_axi_err ( + .clk_i ( safety_clk ), + .rst_ni ( safety_rst_n ), + .pwr_on_rst_ni ( safety_pwr_on_rst_n ), + .async_axi_in_aw_data_i ( axi_slv_ext_aw_data [SafetyIslandSlvIdx] ), + .async_axi_in_aw_wptr_i ( axi_slv_ext_aw_wptr [SafetyIslandSlvIdx] ), + .async_axi_in_aw_rptr_o ( axi_slv_ext_aw_rptr [SafetyIslandSlvIdx] ), + .async_axi_in_ar_data_i ( axi_slv_ext_ar_data [SafetyIslandSlvIdx] ), + .async_axi_in_ar_wptr_i ( axi_slv_ext_ar_wptr [SafetyIslandSlvIdx] ), + .async_axi_in_ar_rptr_o ( axi_slv_ext_ar_rptr [SafetyIslandSlvIdx] ), + .async_axi_in_w_data_i ( axi_slv_ext_w_data [SafetyIslandSlvIdx] ), + .async_axi_in_w_wptr_i ( axi_slv_ext_w_wptr [SafetyIslandSlvIdx] ), + .async_axi_in_w_rptr_o ( axi_slv_ext_w_rptr [SafetyIslandSlvIdx] ), + .async_axi_in_r_data_o ( axi_slv_ext_r_data [SafetyIslandSlvIdx] ), + .async_axi_in_r_wptr_o ( axi_slv_ext_r_wptr [SafetyIslandSlvIdx] ), + .async_axi_in_r_rptr_i ( axi_slv_ext_r_rptr [SafetyIslandSlvIdx] ), + .async_axi_in_b_data_o ( axi_slv_ext_b_data [SafetyIslandSlvIdx] ), + .async_axi_in_b_wptr_o ( axi_slv_ext_b_wptr [SafetyIslandSlvIdx] ), + .async_axi_in_b_rptr_i ( axi_slv_ext_b_rptr [SafetyIslandSlvIdx] ) + ); end // PULP integer cluster @@ -1484,6 +1553,47 @@ int_cluster i_integer_cluster ( .async_data_master_b_rptr_o ( axi_mst_intcluster_b_rptr ) ); end +else begin : gen_no_pulp_cluster + cdc_dst_axi_err #( + .AxiInIdWidth ( IntClusterAxiIdInWidth ), + .LogDepth ( LogDepth ), + .CdcSyncStages ( SyncStages ), + .axi_in_aw_chan_t ( axi_intcluster_slv_aw_chan_t ), + .axi_in_w_chan_t ( axi_intcluster_slv_w_chan_t ), + .axi_in_b_chan_t ( axi_intcluster_slv_b_chan_t ), + .axi_in_ar_chan_t ( axi_intcluster_slv_ar_chan_t ), + .axi_in_r_chan_t ( axi_intcluster_slv_r_chan_t ), + .axi_in_resp_t ( axi_intcluster_slv_rsp_t ), + .axi_in_req_t ( axi_intcluster_slv_req_t ), + .AsyncAxiInAwWidth ( (2**LogDepth)*axi_pkg::aw_width(Cfg.AddrWidth,IntClusterAxiIdInWidth, + Cfg.AxiUserWidth)), + .AsyncAxiInWWidth ( (2**LogDepth)*axi_pkg::w_width(Cfg.AxiDataWidth,Cfg.AxiUserWidth) ), + .AsyncAxiInBWidth ( (2**LogDepth)*axi_pkg::b_width(IntClusterAxiIdInWidth,Cfg.AxiUserWidth) ), + .AsyncAxiInArWidth ( (2**LogDepth)*axi_pkg::ar_width(Cfg.AddrWidth,IntClusterAxiIdInWidth, + Cfg.AxiUserWidth)), + .AsyncAxiInRWidth ( (2**LogDepth)*axi_pkg::r_width(Cfg.AxiDataWidth,IntClusterAxiIdInWidth, + Cfg.AxiUserWidth)) + ) i_pulp_cluster_axi_err ( + .clk_i ( pulp_clk ), + .rst_ni ( pulp_rst_n ), + .pwr_on_rst_ni ( pulp_pwr_on_rst_n ), + .async_axi_in_aw_data_i ( axi_slv_intcluster_aw_data ), + .async_axi_in_aw_wptr_i ( axi_slv_intcluster_aw_wptr ), + .async_axi_in_aw_rptr_o ( axi_slv_intcluster_aw_rptr ), + .async_axi_in_ar_data_i ( axi_slv_intcluster_ar_data ), + .async_axi_in_ar_wptr_i ( axi_slv_intcluster_ar_wptr ), + .async_axi_in_ar_rptr_o ( axi_slv_intcluster_ar_rptr ), + .async_axi_in_w_data_i ( axi_slv_intcluster_w_data ), + .async_axi_in_w_wptr_i ( axi_slv_intcluster_w_wptr ), + .async_axi_in_w_rptr_o ( axi_slv_intcluster_w_rptr ), + .async_axi_in_r_data_o ( axi_slv_intcluster_r_data ), + .async_axi_in_r_wptr_o ( axi_slv_intcluster_r_wptr ), + .async_axi_in_r_rptr_i ( axi_slv_intcluster_r_rptr ), + .async_axi_in_b_data_o ( axi_slv_intcluster_b_data ), + .async_axi_in_b_wptr_o ( axi_slv_intcluster_b_wptr ), + .async_axi_in_b_rptr_i ( axi_slv_intcluster_b_rptr ) + ); +end // Floating Point Spatz Cluster @@ -1584,6 +1694,44 @@ if (IslandsCfg.EnSpatzCluster) begin : gen_spatz_cluster .cluster_probe_o ( car_regs_hw2reg.spatz_cluster_busy.d ) ); end +else begin : gen_no_spatz_cluster + cdc_dst_axi_err #( + .AxiInIdWidth ( AxiSlvIdWidth ), + .LogDepth ( LogDepth ), + .CdcSyncStages ( SyncStages ), + .axi_in_aw_chan_t ( carfield_axi_slv_aw_chan_t ), + .axi_in_w_chan_t ( carfield_axi_slv_w_chan_t ), + .axi_in_b_chan_t ( carfield_axi_slv_b_chan_t ), + .axi_in_ar_chan_t ( carfield_axi_slv_ar_chan_t ), + .axi_in_r_chan_t ( carfield_axi_slv_r_chan_t ), + .axi_in_resp_t ( carfield_axi_slv_rsp_t ), + .axi_in_req_t ( carfield_axi_slv_req_t ), + .AsyncAxiInAwWidth ( CarfieldAxiSlvAwWidth ), + .AsyncAxiInWWidth ( CarfieldAxiSlvWWidth ), + .AsyncAxiInBWidth ( CarfieldAxiSlvBWidth ), + .AsyncAxiInArWidth ( CarfieldAxiSlvArWidth ), + .AsyncAxiInRWidth ( CarfieldAxiSlvRWidth ) + ) i_spatz_cluster_axi_err ( + .clk_i ( spatz_clk ), + .rst_ni ( spatz_rst_n ), + .pwr_on_rst_ni ( spatz_pwr_on_rst_n ), + .async_axi_in_aw_data_i ( axi_slv_ext_aw_data [FPClusterSlvIdx] ), + .async_axi_in_aw_wptr_i ( axi_slv_ext_aw_wptr [FPClusterSlvIdx] ), + .async_axi_in_aw_rptr_o ( axi_slv_ext_aw_rptr [FPClusterSlvIdx] ), + .async_axi_in_ar_data_i ( axi_slv_ext_ar_data [FPClusterSlvIdx] ), + .async_axi_in_ar_wptr_i ( axi_slv_ext_ar_wptr [FPClusterSlvIdx] ), + .async_axi_in_ar_rptr_o ( axi_slv_ext_ar_rptr [FPClusterSlvIdx] ), + .async_axi_in_w_data_i ( axi_slv_ext_w_data [FPClusterSlvIdx] ), + .async_axi_in_w_wptr_i ( axi_slv_ext_w_wptr [FPClusterSlvIdx] ), + .async_axi_in_w_rptr_o ( axi_slv_ext_w_rptr [FPClusterSlvIdx] ), + .async_axi_in_r_data_o ( axi_slv_ext_r_data [FPClusterSlvIdx] ), + .async_axi_in_r_wptr_o ( axi_slv_ext_r_wptr [FPClusterSlvIdx] ), + .async_axi_in_r_rptr_i ( axi_slv_ext_r_rptr [FPClusterSlvIdx] ), + .async_axi_in_b_data_o ( axi_slv_ext_b_data [FPClusterSlvIdx] ), + .async_axi_in_b_wptr_o ( axi_slv_ext_b_wptr [FPClusterSlvIdx] ), + .async_axi_in_b_rptr_i ( axi_slv_ext_b_rptr [FPClusterSlvIdx] ) + ); +end // Security Island logic secd_mbox_intr; diff --git a/sw/boot/carfield.dts b/sw/boot/carfield.dts new file mode 100644 index 000000000..4b281e5ef --- /dev/null +++ b/sw/boot/carfield.dts @@ -0,0 +1,148 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Cyril Koenig + +/dts-v1/; +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "eth,carfield-dev"; + model = "eth,carfield"; + chosen { + stdout-path = "/soc/serial@3002000:38400"; + }; + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x40000000>; + }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <1000000>; // 1 MHz + CPU0: cpu@0 { + device_type = "cpu"; + status = "okay"; + compatible = "eth,ariane", "riscv"; + clock-frequency = <50000000>; // 50 MHz + riscv,isa = "rv64imafdc"; + mmu-type = "riscv,sv39"; + tlb-split; + reg = <0>; + CPU0_intc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + }; + soc: soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "eth,carfield-soc", "eth,cheshire-bare-soc", "simple-bus"; + ranges; + debug@0 { + compatible = "riscv,debug-013"; + reg-names = "control"; + reg = <0x0 0x0 0x0 0x1000>; + }; + axi_llc@3001000 { + compatible = "eth,axi-llc"; + reg = <0x0 0x3001000 0x0 0x5000>; + }; + ddr_link: memory-controller@3006000 { + compatible = "eth,ddr-link"; + reg = <0x0 0x3006000 0x0 0x1000>; + }; + serial@3002000 { + compatible = "ns16550a"; + clock-frequency = <50000000>; // 50 MHz + current-speed = <38400>; + interrupt-parent = <&PLIC0>; + interrupts = <1>; + reg = <0x0 0x3002000 0x0 0x1000>; + reg-shift = <2>; // regs are spaced on 32 bit boundary + reg-io-width = <4>; // only 32-bit access are supported + }; + spi@3004000 { + compatible = "opentitan,spi-host", "lowrisc,spi"; + interrupt-parent = <&PLIC0>; + interrupts = <17 18>; + reg = <0x0 0x3004000 0x0 0x1000>; + clock-frequency = <50000000>; + max-frequency = <20000000>; + #address-cells = <1>; + #size-cells = <0>; + boot-with = <1>; + nor@1 { + #address-cells = <0x1>; + #size-cells = <0x1>; + // Note : u-boot does not find mt25qu02g + compatible = "mt25qu02g", "jedec,spi-nor"; + reg = <0x1>; // CS + spi-max-frequency = <20000000>; + spi-rx-bus-width = <0x1>; + spi-tx-bus-width = <0x1>; + disable-wp; + partition@0 { + label = "all"; + reg = <0x0 0x6000000>; // 96 MB + read-only; + }; + }; + }; + clint@2040000 { + compatible = "riscv,clint0"; + interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7>; + reg-names = "control"; + reg = <0x0 0x2040000 0x0 0x040000>; + }; + PLIC0: interrupt-controller@4000000 { + compatible = "riscv,plic0"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; + riscv,max-priority = <7>; + riscv,ndev = <51>; + reg = <0x0 0x4000000 0x0 0x4000000>; + }; + tcdm@10000000 { + reg = <0x0 0x10000000 0x0 0x400000>; + }; + soc-ctrl@20010000 { + compatible = "soc-ctrl,carfield"; + reg = <0x0 0x20010000 0x0 0x1000>; + }; + l2-intl-0@78000000 { + compatible = "l2-intl,carfield"; + reg = <0x0 0x78000000 0x0 0x100000>; + }; + l2-cont-0@78100000 { + compatible = "l2-cont,carfield"; + reg = <0x0 0x78100000 0x0 0x100000>; + }; + l2-intl-1@78200000 { + compatible = "l2-intl,carfield"; + reg = <0x0 0x78200000 0x0 0x100000>; + }; + l2-cont-1@78300000 { + compatible = "l2-cont,carfield"; + reg = <0x0 0x78300000 0x0 0x100000>; + }; + safety-island@60000000 { + compatible = "safety-island,carfield"; + reg = <0x0 0x60000000 0x0 0x800000>; + }; + integer-cluster@50000000 { + compatible = "integer-cluster,carfield"; + reg = <0x0 0x50000000 0x0 0x800000>; + }; + spatz-cluster@51000000 { + compatible = "spatz-cluster,carfield"; + reg = <0x0 0x51000000 0x0 0x800000>; + }; + }; +}; diff --git a/sw/include/car_linux_mmap.h b/sw/include/car_linux_mmap.h new file mode 100644 index 000000000..f71e26672 --- /dev/null +++ b/sw/include/car_linux_mmap.h @@ -0,0 +1,60 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Cyril Koenig +// +// This file wraps mmap calls to the Carfield driver + +#pragma once + +#include +#include +#include +#include +#include + +#include // mmap + +#include "car_params.h" // car_soc_ctrl, ... + +int carfield_mmap(int device_fd, unsigned int page_offset, size_t length, + void **res) { + *res = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, + page_offset * getpagesize()); + + if (*res == MAP_FAILED) { + printf("mmap() failed %s for offset: %x length: %x\n", strerror(errno), + page_offset, length); + *res = NULL; + return -EIO; + } + return 0; +} + +int carfield_platform_init(int fd) { + if (carfield_mmap(fd, 0, 0x1000, &car_soc_ctrl)) { + printf("mmap() failed for car_soc_ctrl\n"); + } + if (carfield_mmap(fd, 10, 0x100000, &car_l2_intl_0)) { + printf("mmap() failed for car_l2_intl_0\n"); + } + if (carfield_mmap(fd, 11, 0x100000, &car_l2_cont_0)) { + printf("mmap() failed for car_l2_cont_0\n"); + } + if (carfield_mmap(fd, 12, 0x100000, &car_l2_intl_1)) { + printf("mmap() failed for car_l2_intl_1\n"); + } + if (carfield_mmap(fd, 13, 0x100000, &car_l2_cont_1)) { + printf("mmap() failed for car_l2_cont_1\n"); + } + if (carfield_mmap(fd, 100, 0x800000, &car_safety_island)) { + printf("mmap() failed for car_safety_island\n"); + } + if (carfield_mmap(fd, 200, 0x800000, &car_integer_cluster)) { + printf("mmap() failed for car_integer_cluster\n"); + } + if (carfield_mmap(fd, 300, 0x800000, &car_spatz_cluster)) { + printf("mmap() failed for car_spatz_cluster\n"); + } +} diff --git a/sw/include/car_memory_map.h b/sw/include/car_memory_map.h index 5dbd358d3..843348b26 100644 --- a/sw/include/car_memory_map.h +++ b/sw/include/car_memory_map.h @@ -15,6 +15,7 @@ #ifndef __CAR_MEMORY_MAP_H #define __CAR_MEMORY_MAP_H +#include "car_params.h" #include "regs/safety_soc_ctrl.h" #include "regs/soc_ctrl.h" @@ -24,48 +25,48 @@ extern void *__base_l2; // Main Islands and accelerators // L2 port 0 -#define CAR_L2_SPM_PORT0_INTERLEAVED_BASE_ADDR 0x78000000 -#define CAR_L2_SPM_PORT0_INTERLEAVED_END_ADDR 0x78100000 -#define CAR_L2_SPM_PORT0_CONTIGUOUS_BASE_ADDR 0x78100000 -#define CAR_L2_SPM_PORT0_CONTIGUOUS_END_ADDR 0x78200000 +#define CAR_L2_SPM_PORT0_INTERLEAVED_BASE_ADDR(BASE) BASE +#define CAR_L2_SPM_PORT0_INTERLEAVED_END_ADDR(BASE) (BASE + 0x100000) +#define CAR_L2_SPM_PORT0_CONTIGUOUS_BASE_ADDR(BASE) BASE +#define CAR_L2_SPM_PORT0_CONTIGUOUS_END_ADDR(BASE) (BASE + 0x100000) // L2 port 1 -#define CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR 0x78200000 -#define CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR 0x78300000 -#define CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR 0x78300000 -#define CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR 0x78400000 +#define CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR(BASE) BASE +#define CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR(BASE) (BASE + 0x100000) +#define CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR(BASE) BASE +#define CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR(BASE) (BASE + 0x100000) // Safety Island -#define CAR_SAFETY_ISLAND_SPM_BASE_ADDR 0x60000000 -#define CAR_SAFETY_ISLAND_SPM_END_ADDR 0x60020000 +#define CAR_SAFETY_ISLAND_SPM_BASE_ADDR(BASE) BASE +#define CAR_SAFETY_ISLAND_SPM_END_ADDR(BASE) (CAR_SAFETY_ISLAND_SPM_BASE_ADDR(BASE) + 0x20000) #define CAR_SAFETY_ISLAND_PERIPHERALS_OFFSET 0x00200000 #define CAR_SAFETY_ISLAND_SOC_CTRL_OFFSET 0x00000000 -#define CAR_SAFETY_ISLAND_ENTRY_POINT (CAR_SAFETY_ISLAND_SPM_BASE_ADDR + 0x00010080) -#define CAR_SAFETY_ISLAND_SOC_CTRL_ADDR (CAR_SAFETY_ISLAND_SPM_BASE_ADDR + CAR_SAFETY_ISLAND_PERIPHERALS_OFFSET + CAR_SAFETY_ISLAND_SOC_CTRL_OFFSET) +#define CAR_SAFETY_ISLAND_ENTRY_POINT(BASE) (CAR_SAFETY_ISLAND_SPM_BASE_ADDR(BASE) + 0x00010080) +#define CAR_SAFETY_ISLAND_SOC_CTRL_ADDR(BASE) (CAR_SAFETY_ISLAND_SPM_BASE_ADDR(BASE) + CAR_SAFETY_ISLAND_PERIPHERALS_OFFSET + CAR_SAFETY_ISLAND_SOC_CTRL_OFFSET) -#define CAR_SAFETY_ISLAND_BOOTADDR_ADDR (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET) -#define CAR_SAFETY_ISLAND_FETCHEN_ADDR (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR + SAFETY_SOC_CTRL_FETCHEN_REG_OFFSET) -#define CAR_SAFETY_ISLAND_BOOTMODE_ADDR (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR + SAFETY_SOC_CTRL_BOOTMODE_REG_OFFSET) -#define CAR_SAFETY_ISLAND_CORESTATUS_ADDR (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR + SAFETY_SOC_CTRL_CORESTATUS_REG_OFFSET) +#define CAR_SAFETY_ISLAND_BOOTADDR_ADDR(BASE) (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR(BASE) + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET) +#define CAR_SAFETY_ISLAND_FETCHEN_ADDR(BASE) (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR(BASE) + SAFETY_SOC_CTRL_FETCHEN_REG_OFFSET) +#define CAR_SAFETY_ISLAND_BOOTMODE_ADDR(BASE) (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR(BASE) + SAFETY_SOC_CTRL_BOOTMODE_REG_OFFSET) +#define CAR_SAFETY_ISLAND_CORESTATUS_ADDR(BASE) (CAR_SAFETY_ISLAND_SOC_CTRL_ADDR(BASE) + SAFETY_SOC_CTRL_CORESTATUS_REG_OFFSET) -#define CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR 0x60200000 -#define CAR_SAFETY_ISLAND_PERIPHS_END_ADDR 0x60300000 +#define CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR(BASE) (CAR_SAFETY_ISLAND_SPM_BASE_ADDR(BASE) + CAR_SAFETY_ISLAND_PERIPHERALS_OFFSET) +#define CAR_SAFETY_ISLAND_PERIPHS_END_ADDR(BASE) (CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR(BASE) + 0x100000) // Integer Cluster -#define CAR_INT_CLUSTER_SPM_BASE_ADDR 0x50000000 -#define CAR_INT_CLUSTER_SPM_END_ADDR 0x50040000 +#define CAR_INT_CLUSTER_SPM_BASE_ADDR(BASE) BASE +#define CAR_INT_CLUSTER_SPM_END_ADDR(BASE) (BASE + 0x40000) #define CAR_INT_CLUSTER_PERIPH_OFFS 0x00200000 #define CAR_INT_CLUSTER_CTRL_UNIT_OFFS 0x00000000 #define CAR_INT_CLUSTER_BOOT_ADDR_OFFS 0x40 -#define CAR_INT_CLUSTER_BOOT_ADDR_REG (CAR_INT_CLUSTER_SPM_BASE_ADDR + CAR_INT_CLUSTER_PERIPH_OFFS + CAR_INT_CLUSTER_CTRL_UNIT_OFFS + CAR_INT_CLUSTER_BOOT_ADDR_OFFS) +#define CAR_INT_CLUSTER_BOOT_ADDR_REG(BASE) (CAR_INT_CLUSTER_SPM_BASE_ADDR(BASE) + CAR_INT_CLUSTER_PERIPH_OFFS + CAR_INT_CLUSTER_CTRL_UNIT_OFFS + CAR_INT_CLUSTER_BOOT_ADDR_OFFS) // Floating Point Spatz Cluster -#define CAR_FP_CLUSTER_SPM_BASE_ADDR 0x51000000 -#define CAR_FP_CLUSTER_SPM_END_ADDR 0x51020000 +#define CAR_FP_CLUSTER_SPM_BASE_ADDR(BASE) BASE +#define CAR_FP_CLUSTER_SPM_END_ADDR(BASE) (BASE + 0x20000) -#define CAR_FP_CLUSTER_PERIPHS_BASE_ADDR 0x51020000 +#define CAR_FP_CLUSTER_PERIPHS_BASE_ADDR(BASE) (BASE + 0x20000) // #define CAR_FP_CLUSTER_PERIPHS_END_ADDR unknown // HyperRAM @@ -82,7 +83,6 @@ extern void *__base_l2; #define CAR_WATCHDOG_TIMER_OFFSET 0x7000 #define CAR_HYPERBUS_CFG_OFFSET 0x9000 #define CAR_PAD_CFG_OFFSET 0xa000 -#define CAR_SOC_CTRL_OFFSET 0x10000 #define CAR_ETHERNET_BASE_ADDR (CAR_PERIPHS_BASE_ADDR + CAR_ETHERNET_OFFSET) #define CAR_CAN_BASE_ADDR (CAR_PERIPHS_BASE_ADDR + CAR_CAN_OFFSET) @@ -91,7 +91,7 @@ extern void *__base_l2; #define CAR_WATCHDOG_TIMER_BASE_ADDR (CAR_PERIPHS_BASE_ADDR + CAR_WATCHDOG_TIMER_OFFSET) #define CAR_HYPERBUS_CFG_BASE_ADDR (CAR_PERIPHS_BASE_ADDR + CAR_HYPERBUS_CFG_OFFSET) #define CAR_PAD_CFG_BASE_ADDR (CAR_PERIPHS_BASE_ADDR + CAR_PAD_CFG_OFFSET) -#define CAR_SOC_CTRL_BASE_ADDR (CAR_PERIPHS_BASE_ADDR + CAR_SOC_CTRL_OFFSET) +#define CAR_SOC_CTRL_BASE_ADDR(BASE) BASE #define CAR_MBOX_BASE_ADDR 0x40000000 @@ -107,9 +107,9 @@ extern void *__base_l2; #define EFPCLEXEC 4 // Execution error floating point cluster // Memory-mapped registers -#define CAR_INT_CLUSTER_FETCHEN_ADDR (CAR_SOC_CTRL_BASE_ADDR + CARFIELD_PULP_CLUSTER_FETCH_ENABLE_REG_OFFSET) -#define CAR_INT_CLUSTER_BOOTEN_ADDR (CAR_SOC_CTRL_BASE_ADDR + CARFIELD_PULP_CLUSTER_BOOT_ENABLE_REG_OFFSET) -#define CAR_INT_CLUSTER_BUSY_ADDR (CAR_SOC_CTRL_BASE_ADDR + CARFIELD_PULP_CLUSTER_BUSY_REG_OFFSET) -#define CAR_INT_CLUSTER_EOC_ADDR (CAR_SOC_CTRL_BASE_ADDR + CARFIELD_PULP_CLUSTER_EOC_REG_OFFSET) +#define CAR_INT_CLUSTER_FETCHEN_ADDR(BASE) (CAR_SOC_CTRL_BASE_ADDR(BASE) + CARFIELD_PULP_CLUSTER_FETCH_ENABLE_REG_OFFSET) +#define CAR_INT_CLUSTER_BOOTEN_ADDR(BASE) (CAR_SOC_CTRL_BASE_ADDR(BASE) + CARFIELD_PULP_CLUSTER_BOOT_ENABLE_REG_OFFSET) +#define CAR_INT_CLUSTER_BUSY_ADDR(BASE) (CAR_SOC_CTRL_BASE_ADDR(BASE) + CARFIELD_PULP_CLUSTER_BUSY_REG_OFFSET) +#define CAR_INT_CLUSTER_EOC_ADDR(BASE) (CAR_SOC_CTRL_BASE_ADDR(BASE) + CARFIELD_PULP_CLUSTER_EOC_REG_OFFSET) #endif /* __CAR_MEMORY_MAP_H */ diff --git a/sw/include/car_params.h b/sw/include/car_params.h new file mode 100644 index 000000000..449044601 --- /dev/null +++ b/sw/include/car_params.h @@ -0,0 +1,31 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Cyril Koenig +// +// This file resolves the pointers used in car_memory_map.h +// In the linux case these pointers are attributed by calling carfield_mmap() + +#pragma once + +#ifndef LINUX_APP // Hardcoded const pointers +const void* car_soc_ctrl = 0x20010000; +const void* car_safety_island = 0x60000000; +const void* car_integer_cluster = 0x50000000; +const void* car_spatz_cluster = 0x51000000; +const void* car_l2_intl_0 = 0x78000000; +const void* car_l2_cont_0 = 0x78100000; +const void* car_l2_intl_1 = 0x78200000; +const void* car_l2_cont_1 = 0x78300000; + +#else // Pointers to be mapped by the driver +void* car_soc_ctrl; +void* car_safety_island; +void* car_integer_cluster; +void* car_spatz_cluster; +void* car_l2_intl_0; +void* car_l2_cont_0; +void* car_l2_intl_1; +void* car_l2_cont_1; +#endif diff --git a/sw/include/car_util.h b/sw/include/car_util.h index 3ccb192da..70f019ffc 100644 --- a/sw/include/car_util.h +++ b/sw/include/car_util.h @@ -10,6 +10,7 @@ #include "util.h" #include "car_memory_map.h" +#include "car_params.h" #include "car_properties.h" #include "regs/soc_ctrl.h" #include "io.h" @@ -30,7 +31,7 @@ // Clock and reset control // for the calculation check safety island top -#define SAFETY_ISLAND_BOOT_ADDR_RSVAL (CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + 0x1080) +#define SAFETY_ISLAND_BOOT_ADDR_RSVAL (CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR(car_safety_island) + 0x1080) enum car_isolation_status { CAR_ISOLATE_DISABLE = 0, CAR_ISOLATE_ENABLE = 1 }; @@ -142,34 +143,34 @@ static inline enum car_clk car_clkd_from_rstd(enum car_rst rst) void car_set_isolate(enum car_rst rst, enum car_isolation_status status) { - writew(status, CAR_SOC_CTRL_BASE_ADDR + car_get_ISOLATE_offset(rst)); + writew(status, CAR_SOC_CTRL_BASE_ADDR(car_soc_ctrl) + car_get_ISOLATE_offset(rst)); fence(); - while (readw(CAR_SOC_CTRL_BASE_ADDR + car_get_ISOLATE_STATUS_offset(rst)) != + while (readw(CAR_SOC_CTRL_BASE_ADDR(car_soc_ctrl) + car_get_ISOLATE_STATUS_offset(rst)) != status) ; } void car_enable_clk(enum car_clk clk) { - writew(1, CAR_SOC_CTRL_BASE_ADDR + car_get_CLK_EN_offset(clk)); + writew(1, CAR_SOC_CTRL_BASE_ADDR(car_soc_ctrl) + car_get_CLK_EN_offset(clk)); fence(); } void car_disable_clk(enum car_clk clk) { - writew(0, CAR_SOC_CTRL_BASE_ADDR + car_get_CLK_EN_offset(clk)); + writew(0, CAR_SOC_CTRL_BASE_ADDR(car_soc_ctrl) + car_get_CLK_EN_offset(clk)); fence(); } void car_select_clk(enum car_src_clk clk_src, enum car_clk clk) { - writew(clk_src, CAR_SOC_CTRL_BASE_ADDR + car_get_CLK_SEL_offset(clk)); + writew(clk_src, CAR_SOC_CTRL_BASE_ADDR(car_soc_ctrl) + car_get_CLK_SEL_offset(clk)); fence(); } void car_set_rst(enum car_rst rst, enum car_rst_status status) { - writew(status, CAR_SOC_CTRL_BASE_ADDR + car_get_RST_offset(rst)); + writew(status, CAR_SOC_CTRL_BASE_ADDR(car_soc_ctrl) + car_get_RST_offset(rst)); fence(); } @@ -234,15 +235,15 @@ void car_init_stop() void prepare_safed_boot () { // Select bootmode - volatile uintptr_t *bootmode_addr = (uintptr_t*)CAR_SAFETY_ISLAND_BOOTMODE_ADDR; + volatile uintptr_t *bootmode_addr = (uintptr_t*)CAR_SAFETY_ISLAND_BOOTMODE_ADDR(car_safety_island); writew(1, bootmode_addr); // Write entry point into boot address - volatile uintptr_t *bootaddr_addr = (uintptr_t*)CAR_SAFETY_ISLAND_BOOTADDR_ADDR; - writew(CAR_SAFETY_ISLAND_ENTRY_POINT, bootaddr_addr); + volatile uintptr_t *bootaddr_addr = (uintptr_t*)CAR_SAFETY_ISLAND_BOOTADDR_ADDR(car_safety_island); + writew(CAR_SAFETY_ISLAND_ENTRY_POINT(car_safety_island), bootaddr_addr); // Assert fetch enable - volatile uintptr_t *fetchen_addr = (uintptr_t*)CAR_SAFETY_ISLAND_FETCHEN_ADDR; + volatile uintptr_t *fetchen_addr = (uintptr_t*)CAR_SAFETY_ISLAND_FETCHEN_ADDR(car_safety_island); writew(1, fetchen_addr); } @@ -250,7 +251,7 @@ void prepare_safed_boot () { uint32_t poll_safed_corestatus () { volatile uint32_t corestatus; - volatile uintptr_t *corestatus_addr = (uintptr_t*)CAR_SAFETY_ISLAND_CORESTATUS_ADDR; + volatile uintptr_t *corestatus_addr = (uintptr_t*)CAR_SAFETY_ISLAND_CORESTATUS_ADDR(car_safety_island); // TODO: Add a timeut to not poll indefinitely while (((uint32_t)readw(corestatus_addr) & 0x80000000) == 0) ; @@ -285,7 +286,7 @@ uint32_t safed_offloader_blocking () { void pulp_cluster_set_bootaddress(uint32_t pulp_boot_addr) { - volatile uint32_t cluster_boot_reg_addr = CAR_INT_CLUSTER_BOOT_ADDR_REG; + volatile uint32_t cluster_boot_reg_addr = CAR_INT_CLUSTER_BOOT_ADDR_REG(car_integer_cluster); for (int i = 0; i < IntClustNumCores; i++) { writew(pulp_boot_addr, (uint32_t*)(cluster_boot_reg_addr)); @@ -295,16 +296,16 @@ void pulp_cluster_set_bootaddress(uint32_t pulp_boot_addr) { void pulp_cluster_start() { - volatile uint32_t *booten_addr = (uint32_t*)(CAR_INT_CLUSTER_BOOTEN_ADDR); + volatile uint32_t *booten_addr = (uint32_t*)(CAR_INT_CLUSTER_BOOTEN_ADDR(car_soc_ctrl)); writew(1, booten_addr); - volatile uint32_t *fetchen_addr = (uint32_t*)(CAR_INT_CLUSTER_FETCHEN_ADDR); + volatile uint32_t *fetchen_addr = (uint32_t*)(CAR_INT_CLUSTER_FETCHEN_ADDR(car_soc_ctrl)); writew(1, fetchen_addr); } void pulp_cluster_wait_eoc() { - volatile uint32_t *pulp_eoc_addr = (uint32_t*)(CAR_INT_CLUSTER_EOC_ADDR); + volatile uint32_t *pulp_eoc_addr = (uint32_t*)(CAR_INT_CLUSTER_EOC_ADDR(car_soc_ctrl)); while(!readw(pulp_eoc_addr)) ; diff --git a/sw/sw.mk b/sw/sw.mk index ba75f89bf..cc3fc8629 100644 --- a/sw/sw.mk +++ b/sw/sw.mk @@ -20,7 +20,7 @@ car-sw-all: car-sw-libs car-sw-tests .PHONY: car-sw-all car-sw-libs car-sw-headers car-sw-tests # Libraries -CAR_PULPD_BARE ?= $(CAR_SW_DIR)/tests/bare-metal/pulpd +CAR_PULPD_BARE ?= $(CAR_SW_DIR)/tests/bare-metal/pulpd CAR_SW_INCLUDES = -I$(CAR_SW_DIR)/include -I$(CAR_SW_DIR)/tests/bare-metal/safed -I$(CAR_PULPD_BARE) -I$(CHS_SW_DIR)/include $(CHS_SW_DEPS_INCS) CAR_SW_LIB_SRCS_S = $(wildcard $(CAR_SW_DIR)/lib/*.S $(CAR_SW_DIR)/lib/**/*.S) CAR_SW_LIB_SRCS_C = $(wildcard $(CAR_SW_DIR)/lib/*.c $(CAR_SW_DIR)/lib/**/*.c) @@ -135,3 +135,48 @@ mibench-automotive-basicmath: automotive-basicmath mibench-automotive-bitcount: automotive-bitcount mibench-automotive-qsort: automotive-qsort mibench-automotive-susan: automotive-susan + +################### +# GPT Linux image # +################### + +# Create full Linux disk image +$(CAR_SW_DIR)/boot/linux.gpt.bin: $(CHS_SW_DIR)/boot/zsl.rom.bin $(CAR_SW_DIR)/boot/carfield.dtb $(CAR_SW_DIR)/boot/install64/fw_payload.bin $(CAR_SW_DIR)/boot/install64/uImage + truncate -s $(CHS_SW_DISK_SIZE) $@ + sgdisk --clear -g --set-alignment=1 \ + --new=1:64:96 --typecode=1:$(CHS_SW_ZSL_TGUID) \ + --new=2:128:159 --typecode=2:$(CHS_SW_DTB_TGUID) \ + --new=3:2048:8191 --typecode=3:$(CHS_SW_FW_TGUID) \ + --new=4:8192:24575 --typecode=4:8300 \ + --new=5:24576:0 --typecode=5:8200 \ + $@ + dd if=$(word 1,$^) of=$@ bs=512 seek=64 conv=notrunc + dd if=$(word 2,$^) of=$@ bs=512 seek=128 conv=notrunc + dd if=$(word 3,$^) of=$@ bs=512 seek=2048 conv=notrunc + dd if=$(word 4,$^) of=$@ bs=512 seek=8192 conv=notrunc + +######################### +# Linux app compilation # +######################### + +CAR_CVA6_SDK ?= $(realpath cva6-sdk) +CAR_CROSS_COMPILE := $(CAR_CVA6_SDK)/buildroot/output/host/bin/riscv64-buildroot-linux-gnu- +CAR_APP_CC := $(CAR_CROSS_COMPILE)gcc +CAR_APP_OBJDUMP := $(CAR_CROSS_COMPILE)objdump +CAR_APP_CCFLAGS := -std=gnu99 -O0 -g -DLINUX_APP -fdata-sections -ffunction-sections +CAR_APP_LDFLAGS := -Wl,--gc-sections + +CAR_SW_APP_SRCS_C = $(wildcard $(CAR_SW_DIR)/tests/linux/*.c) +CAR_SW_APPS = $(CAR_SW_APP_SRCS_C:.c=.car.app) + +car-sw-apps: $(CAR_SW_APPS) + cp $(CAR_SW_APPS) $(CAR_CVA6_SDK)/rootfs/root/tests + +%.car.app: %.car.app.o + $(CAR_APP_CC) $(CAR_SW_INCLUDES) $(CAR_APP_LDFLAGS) -o $@ $< + +%.car.app.dump: %.car.app.o + $(CAR_APP_OBJDUMP) -S -d $< > $@ + +%.car.app.o: %.c + $(CAR_APP_CC) $(CAR_SW_INCLUDES) $(CAR_APP_CCFLAGS) -c $< -o $@ diff --git a/sw/tests/bare-metal/hostd/addressability_test.c b/sw/tests/bare-metal/hostd/addressability_test.c index de1b4bb98..c59ed207c 100644 --- a/sw/tests/bare-metal/hostd/addressability_test.c +++ b/sw/tests/bare-metal/hostd/addressability_test.c @@ -148,29 +148,29 @@ int main(void) { // (wrwr) // L2 shared memory - errors += probe_range_lfsr_wrwr((uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR, - (uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR, N_SAMPLES); + errors += probe_range_lfsr_wrwr((uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR(car_l2_intl_1), + (uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR(car_l2_intl_1), N_SAMPLES); if (errors) { char str[] = "1\n"; diyprintf(str, sizeof(str)); } - errors += probe_range_lfsr_wrwr((uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR, - (uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR, N_SAMPLES); + errors += probe_range_lfsr_wrwr((uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR(car_l2_cont_1), + (uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR(car_l2_cont_1), N_SAMPLES); if (errors) { char str[] = "2\n"; diyprintf(str, sizeof(str)); } // Safety Island - errors += probe_range_lfsr_wrwr((uint64_t *)CAR_SAFETY_ISLAND_SPM_BASE_ADDR, - (uint64_t *)CAR_SAFETY_ISLAND_SPM_END_ADDR, N_SAMPLES); + errors += probe_range_lfsr_wrwr((uint64_t *)CAR_SAFETY_ISLAND_SPM_BASE_ADDR(car_safety_island), + (uint64_t *)CAR_SAFETY_ISLAND_SPM_END_ADDR(car_safety_island), N_SAMPLES); if (errors) { char str[] = "3\n"; diyprintf(str, sizeof(str)); } // Integer Cluster - errors += probe_range_lfsr_wrwr((uint64_t *)CAR_INT_CLUSTER_SPM_BASE_ADDR, (uint64_t *)CAR_INT_CLUSTER_SPM_END_ADDR, + errors += probe_range_lfsr_wrwr((uint64_t *)CAR_INT_CLUSTER_SPM_BASE_ADDR(car_integer_cluster), (uint64_t *)CAR_INT_CLUSTER_SPM_END_ADDR(car_integer_cluster), N_SAMPLES); if (errors) { char str[] = "4\n"; @@ -183,7 +183,7 @@ int main(void) { diyprintf(str, sizeof(str)); } // FP Cluster - errors += probe_range_lfsr_wrwr((uint64_t *)CAR_FP_CLUSTER_SPM_BASE_ADDR, (uint64_t *)CAR_FP_CLUSTER_SPM_END_ADDR, + errors += probe_range_lfsr_wrwr((uint64_t *)CAR_FP_CLUSTER_SPM_BASE_ADDR(car_spatz_cluster), (uint64_t *)CAR_FP_CLUSTER_SPM_END_ADDR(car_spatz_cluster), N_SAMPLES); if (errors) { char str[] = "6\n"; @@ -195,28 +195,28 @@ int main(void) { // writing (wwrr) // L2 shared memory - errors += probe_range_lfsr_wwrr((uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR, - (uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR, N_SAMPLES); + errors += probe_range_lfsr_wwrr((uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR(car_l2_intl_1), + (uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR(car_l2_intl_1), N_SAMPLES); if (errors) { char str[] = "7\n"; diyprintf(str, sizeof(str)); } - errors += probe_range_lfsr_wwrr((uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR, - (uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR, N_SAMPLES); + errors += probe_range_lfsr_wwrr((uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR(car_l2_cont_1), + (uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR(car_l2_cont_1), N_SAMPLES); if (errors) { char str[] = "8\n"; diyprintf(str, sizeof(str)); } // Safety Island - errors += probe_range_lfsr_wwrr((uint64_t *)CAR_SAFETY_ISLAND_SPM_BASE_ADDR, - (uint64_t *)CAR_SAFETY_ISLAND_SPM_END_ADDR, N_SAMPLES); + errors += probe_range_lfsr_wwrr((uint64_t *)CAR_SAFETY_ISLAND_SPM_BASE_ADDR(car_safety_island), + (uint64_t *)CAR_SAFETY_ISLAND_SPM_END_ADDR(car_safety_island), N_SAMPLES); if (errors) { char str[] = "9\n"; diyprintf(str, sizeof(str)); } // Integer Cluster - errors += probe_range_lfsr_wwrr((uint64_t *)CAR_INT_CLUSTER_SPM_BASE_ADDR, (uint64_t *)CAR_INT_CLUSTER_SPM_END_ADDR, + errors += probe_range_lfsr_wwrr((uint64_t *)CAR_INT_CLUSTER_SPM_BASE_ADDR(car_integer_cluster), (uint64_t *)CAR_INT_CLUSTER_SPM_END_ADDR(car_integer_cluster), N_SAMPLES); if (errors) { char str[] = "a\n"; @@ -229,7 +229,7 @@ int main(void) { diyprintf(str, sizeof(str)); } // FP Cluster - errors += probe_range_lfsr_wrwr((uint64_t *)CAR_FP_CLUSTER_SPM_BASE_ADDR, (uint64_t *)CAR_FP_CLUSTER_SPM_END_ADDR, + errors += probe_range_lfsr_wrwr((uint64_t *)CAR_FP_CLUSTER_SPM_BASE_ADDR(car_spatz_cluster), (uint64_t *)CAR_FP_CLUSTER_SPM_END_ADDR(car_spatz_cluster), N_SAMPLES); if (errors) { char str[] = "c\n"; diff --git a/sw/tests/bare-metal/hostd/sw_rst_seq.c b/sw/tests/bare-metal/hostd/sw_rst_seq.c index 89b7329a8..9c060f66b 100644 --- a/sw/tests/bare-metal/hostd/sw_rst_seq.c +++ b/sw/tests/bare-metal/hostd/sw_rst_seq.c @@ -31,11 +31,11 @@ int main(void) uint64_t magic = 0xcafebeef; // Write a pattern to safety island boot addr - writew(magic, CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + + writew(magic, CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR(car_safety_island) + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET); // Double check - if (readw(CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + + if (readw(CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR(car_safety_island) + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET) != magic) return ESAFEDNOACCES; @@ -43,32 +43,32 @@ int main(void) car_reset_domain(CAR_SAFETY_RST); // After the reset we should only see zeros - if (readw(CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR + + if (readw(CAR_SAFETY_ISLAND_PERIPHS_BASE_ADDR(car_safety_island) + SAFETY_SOC_CTRL_BOOTADDR_REG_OFFSET) != SAFETY_ISLAND_BOOT_ADDR_RSVAL) return ESAFEDNOACCES; // Spatz - writew(magic, CAR_FP_CLUSTER_PERIPHS_BASE_ADDR + + writew(magic, CAR_FP_CLUSTER_PERIPHS_BASE_ADDR(car_spatz_cluster) + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET); - if (readw(CAR_FP_CLUSTER_PERIPHS_BASE_ADDR + + if (readw(CAR_FP_CLUSTER_PERIPHS_BASE_ADDR(car_spatz_cluster) + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET) != magic) return EFPCLNOACCES; car_reset_domain(CAR_SPATZ_RST); - if (readw(CAR_FP_CLUSTER_PERIPHS_BASE_ADDR + + if (readw(CAR_FP_CLUSTER_PERIPHS_BASE_ADDR(car_spatz_cluster) + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_REG_OFFSET) != 0) return EFPCLNOACCES; // PULP Reset - writew(magic, CAR_INT_CLUSTER_BOOT_ADDR_REG); - if (readw(CAR_INT_CLUSTER_BOOT_ADDR_REG) != magic) + writew(magic, CAR_INT_CLUSTER_BOOT_ADDR_REG(car_integer_cluster)); + if (readw(CAR_INT_CLUSTER_BOOT_ADDR_REG(car_integer_cluster)) != magic) return EINTCLNOACCES; volatile uint32_t pulp_boot_addr_rst_value = 0x78200000; car_reset_domain(CAR_PULP_RST); - if (readw(CAR_INT_CLUSTER_BOOT_ADDR_REG) != pulp_boot_addr_rst_value) + if (readw(CAR_INT_CLUSTER_BOOT_ADDR_REG(car_integer_cluster)) != pulp_boot_addr_rst_value) return EINTCLNOACCES; // L2 Reset diff --git a/sw/tests/linux/addressability_test.c b/sw/tests/linux/addressability_test.c new file mode 100644 index 000000000..d2efd5f1b --- /dev/null +++ b/sw/tests/linux/addressability_test.c @@ -0,0 +1,233 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Alessandro Ottaviano +// + +#include "car_linux_mmap.h" +#include "car_memory_map.h" +#include "car_util.h" +#include "dif/clint.h" +#include "dif/uart.h" +#include "io.h" +#include "params.h" +#include "regs/cheshire.h" +#include "util.h" + +#define N_SAMPLES 1024 +#define DEFAULT_SEED 0xcaca5a5adeadbeef +#define FEEDBACK 0x6c0000397f000032 + +#define DUMP_REGION(PTR, SIZE, LINE) \ + do { \ + printf("\nDumping region %s\n", #PTR); \ + for (int i = 0; i < SIZE; i++) { \ + if (i % LINE == 0) \ + printf("\n%#04x - ", i); \ + printf("%02x ", ((uint8_t *)PTR)[i]); \ + } \ + printf("\n"); \ + } while (0) + +uint64_t *lfsr_byte_feedback; + +/* probe address range "samples" time, evenly spaced */ +int probe_range_direct(volatile uintptr_t from, volatile uintptr_t to, + int samples) { + // check whether arguments passed make sense + if ((samples < 0) && (to < from)) + return 2; + + uintptr_t addr = from; + + if(samples > (to - from)) samples = to - from; + + uintptr_t incr = ((to - from) / samples); + + for (int i = 0; i < samples; i++) { + // write + uint32_t expected = 0xcafedead + 0xab + i; + writed(expected, addr); + // read + if (expected != readd(addr)) + return 1; + // increment + addr += incr; + } + return 0; +} + +uint32_t lfsr_iter_bit(uint64_t lfsr) { + return (lfsr & 1) ? ((lfsr >> 1) ^ FEEDBACK) : (lfsr >> 1); +} + +uint32_t lfsr_iter_byte(uint64_t lfsr, uint64_t *lfsr_byte_feedback) { + uint32_t l = lfsr; + for (int i = 0; i < 8; i++) + l = lfsr_iter_bit(l); + return l; +} + +uint32_t lfsr_iter_word(uint64_t lfsr, uint64_t *lfsr_byte_feedback) { + uint32_t l = lfsr_iter_byte(lfsr, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + return lfsr_iter_byte(l, lfsr_byte_feedback); +} + +uint64_t lfsr_64bits(uint64_t lfsr, uint64_t *lfsr_byte_feedback) { + uint64_t l = lfsr_iter_byte(lfsr, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + l = lfsr_iter_byte(l, lfsr_byte_feedback); + return lfsr_iter_byte(l, lfsr_byte_feedback); +} + +int probe_range_lfsr_wrwr(volatile uintptr_t from, volatile uintptr_t to, + int samples) { + // check whether arguments passed make sense + if ((samples < 0) && (to < from)) + return 2; + + uintptr_t addr = from; + uintptr_t incr = ((to - from) / samples); + + uint64_t lfsr = DEFAULT_SEED; + for (int i = 0; i < samples; i++) { + // write + lfsr = lfsr_64bits(lfsr, lfsr_byte_feedback); + writed(lfsr, addr); + fence(); + // read + if (lfsr != readd(addr)) + return 1; + // increment + addr += incr; + } + return 0; +} + +int probe_range_lfsr_wwrr(volatile uintptr_t from, volatile uintptr_t to, + int samples) { + // check whether arguments passed make sense + if ((samples < 0) && (to < from)) + return 2; + + uintptr_t addr = from; + uintptr_t incr = ((to - from) / samples); + + // write + uint64_t lfsr = DEFAULT_SEED; + for (int i = 0; i < samples; i++) { + lfsr = lfsr_64bits(lfsr, lfsr_byte_feedback); + // write + writed(lfsr, addr); + // increment + addr += incr; + } + + fence(); + + // read + addr = from; + lfsr = DEFAULT_SEED; + for (int i = 0; i < samples; i++) { + lfsr = lfsr_64bits(lfsr, lfsr_byte_feedback); + // read + if (lfsr != readd(addr)) + return 1; + // increment + addr += incr; + } + + return 0; +} + +int main(int argc, char *argv[]) { + + int errors = 0; + char *device_path; + int device_fd; + + // Receive device path as argument (/dev/carfield for instance) + if (argc != 2) { + printf("Wrong usage : %s device\n", argv[0]); + return -1; + } + + device_path = argv[1]; + device_fd = open(device_path, O_RDWR | O_SYNC); + + carfield_platform_init(device_fd); + + // Probe an address range with pseudo-random values and read after each + // write + // (wrwr) + + // L2 shared memory + if (car_l2_intl_1) { + errors += probe_range_lfsr_wrwr( + (uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_BASE_ADDR(car_l2_intl_1), + (uint64_t *)CAR_L2_SPM_PORT1_INTERLEAVED_END_ADDR(car_l2_intl_1), + N_SAMPLES); + if (errors) { + printf("ERROR on car_l2_intl_1\n"); + } + DUMP_REGION(car_l2_intl_1, 64, 8); + } else printf("NOT FOUND car_l2_intl_1\n"); + + if (car_l2_cont_1) { + errors += probe_range_lfsr_wrwr( + (uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR(car_l2_cont_1), + (uint64_t *)CAR_L2_SPM_PORT1_CONTIGUOUS_END_ADDR(car_l2_cont_1), + N_SAMPLES); + if (errors) { + printf("ERROR on car_l2_cont_1\n"); + } + DUMP_REGION(CAR_L2_SPM_PORT1_CONTIGUOUS_BASE_ADDR(car_l2_cont_1), 64, 8); + } else printf("NOT FOUND car_l2_cont_1\n"); + + + // Safety Island + if (car_safety_island) { + errors += probe_range_lfsr_wrwr( + (uint64_t *)CAR_SAFETY_ISLAND_SPM_BASE_ADDR(car_safety_island), + (uint64_t *)CAR_SAFETY_ISLAND_SPM_END_ADDR(car_safety_island), + N_SAMPLES); + if (errors) { + printf("ERROR on car_safety_island\n"); + } + DUMP_REGION(CAR_SAFETY_ISLAND_SPM_BASE_ADDR(car_safety_island), 64, 8); + } else printf("NOT FOUND car_safety_island\n"); + + + // Integer Cluster + if (car_integer_cluster) { + errors += probe_range_lfsr_wrwr( + (uint64_t *)CAR_INT_CLUSTER_SPM_BASE_ADDR(car_integer_cluster), + (uint64_t *)CAR_INT_CLUSTER_SPM_END_ADDR(car_integer_cluster), + N_SAMPLES); + if (errors) { + printf("ERROR on car_integer_cluster\n"); + } + DUMP_REGION(CAR_INT_CLUSTER_SPM_BASE_ADDR(car_integer_cluster), 64, 8); + } else printf("NOT FOUND car_integer_cluster\n"); + + // FP Cluster + if (car_spatz_cluster) { + errors += probe_range_lfsr_wrwr( + (uint64_t *)CAR_FP_CLUSTER_SPM_BASE_ADDR(car_spatz_cluster), + (uint64_t *)CAR_FP_CLUSTER_SPM_END_ADDR(car_spatz_cluster), + N_SAMPLES); + if (errors) { + printf("ERROR on car_spatz_cluster\n"); + } + DUMP_REGION(CAR_FP_CLUSTER_SPM_BASE_ADDR(car_spatz_cluster), 64, 8); + } else printf("NOT FOUND car_spatz_cluster\n"); + + return errors; +} diff --git a/target/xilinx/constraints/carfield.xdc b/target/xilinx/constraints/carfield.xdc index dfea146ee..e01b35e59 100644 --- a/target/xilinx/constraints/carfield.xdc +++ b/target/xilinx/constraints/carfield.xdc @@ -2,67 +2,108 @@ # Solderpad Hardware License, Version 0.51, see LICENSE for details. # SPDX-License-Identifier: SHL-0.51 # -# Nicole Narr -# Christopher Reinwardt +# Cyril Koenig + ################### # Global Settings # ################### -# Preserve the output mux of the clock divider -set_property DONT_TOUCH TRUE [get_cells i_sys_clk_div/i_clk_bypass_mux] - -# The net of which we get the 200 MHz single ended clock from the MIG -set MIG_CLK_SRC [get_pins -filter {DIRECTION == OUT} -leaf -of_objects [get_nets dram_clock_out]] -set MIG_RST_SRC [get_pins -filter {DIRECTION == OUT} -leaf -of_objects [get_nets dram_sync_reset]] - +# The output of the reset synchronizer set SOC_RST_SRC [get_pins -filter {DIRECTION == OUT} -leaf -of_objects [get_nets rst_n]] ##################### # Timing Parameters # ##################### -# 333 MHz (max) DRAM Axi clock -set FPGA_TCK 3.0 - -# 200 MHz DRAM Generated clock -set DRAM_TCK 5.0 - -# 20 MHz SoC clock -set SOC_TCK 50.0 - # 10 MHz (max) JTAG clock set JTAG_TCK 100.0 -# I2C High-speed mode is 3.2 Mb/s -set I2C_IO_SPEED 312.5 - # UART speed is at most 5 Mb/s set UART_IO_SPEED 200.0 +# Host on clk_50 +set SOC_TCK 20 + ########## # Clocks # ########## +# Rtc clock is asynchronous +create_generated_clock -source [get_pins i_xlnx_clk_wiz/inst/mmcme4_adv_inst/CLKOUT3] -divide_by 10 -name rtc_clk [get_pins rtc_clk_q_reg/Q] +set_clock_groups -asynchronous -group {rtc_clk} +set_max_delay -from [get_pin rtc_clk_q_reg/Q] $SOC_TCK + # System Clock -# create_generated_clock -name clk_soc -source $MIG_CLK_SRC -divide_by 4 [get_nets soc_clk] +# [see in board.xdc] + # JTAG Clock create_clock -period $JTAG_TCK -name clk_jtag [get_ports jtag_tck_i] set_input_jitter clk_jtag 1.000 +set_clock_groups -name jtag_grp -asynchronous -group {clk_jtag} -################ -# Clock Groups # -################ -# JTAG Clock is asynchronous to all other clocks -set_clock_groups -name jtag_async -asynchronous -group [get_clocks clk_jtag] +#################### +# Clock generators # +#################### + +# Do not optimize anything in them +set_property DONT_TOUCH TRUE [get_cells i_carfield/gen_domain_clock_mux[*].i_clk_mux] + +# TODO Check this +set_false_path -from [get_pins i_carfield/gen_domain_clock_mux[*].i_clk_mux/gen_input_stages[*].clock_has_been_disabled_q_reg[*]/C] -to [get_pins i_carfield/gen_domain_clock_mux[*].i_clk_mux/gen_input_stages[*].clock_has_been_disabled_q_reg[*]/D] +set_false_path -from [get_pins i_carfield/gen_domain_clock_mux[*].i_clk_mux/gen_input_stages[*].clock_has_been_disabled_q_reg[*]/C] -to [get_pins i_carfield/gen_domain_clock_mux[*].i_clk_mux/gen_input_stages[*].glitch_filter_q_reg[*][*]/D] + +# Periph domain +create_generated_clock -source [get_pins i_carfield/gen_domain_clock_mux[0].i_clk_mux/clks_i[2]] -divide_by 1 -name periph_domain_clk [get_pins i_carfield/gen_domain_clock_mux[0].i_clk_mux/clk_o] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_periph_clk_sel/q_reg[0]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_periph_clk_sel/q_reg[1]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_periph_clk_en/q_reg[0]/Q}] + +# Safety domain +create_generated_clock -source [get_pins i_carfield/gen_domain_clock_mux[1].i_clk_mux/clks_i[1]] -divide_by 1 -name safety_domain_clk [get_pins i_carfield/gen_domain_clock_mux[1].i_clk_mux/clk_o] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_safety_island_clk_sel/q_reg[0]/Q}] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_safety_island_clk_sel/q_reg[1]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_safety_island_clk_en/q_reg[0]/Q}] + +# Security domain +create_generated_clock -source [get_pins i_carfield/gen_domain_clock_mux[2].i_clk_mux/clks_i[1]] -divide_by 1 -name security_domain_clk [get_pins i_carfield/gen_domain_clock_mux[2].i_clk_mux/clk_o] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_security_island_clk_sel/q_reg[0]/Q}] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_security_island_clk_sel/q_reg[1]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_security_island_clk_en/q_reg[0]/Q}] + +# Pulp domain +create_generated_clock -source [get_pins i_carfield/gen_domain_clock_mux[3].i_clk_mux/clks_i[1]] -divide_by 1 -name pulp_domain_clk [get_pins i_carfield/gen_domain_clock_mux[3].i_clk_mux/clk_o] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_pulp_cluster_clk_sel/q_reg[0]/Q}] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_pulp_cluster_clk_sel/q_reg[1]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_pulp_cluster_clk_en/q_reg[0]/Q}] + +# Spatz domain +create_generated_clock -source [get_pins i_carfield/gen_domain_clock_mux[4].i_clk_mux/clks_i[1]] -divide_by 1 -name spatz_domain_clk [get_pins i_carfield/gen_domain_clock_mux[4].i_clk_mux/clk_o] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_spatz_cluster_clk_sel/q_reg[0]/Q}] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_spatz_cluster_clk_sel/q_reg[1]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_spatz_cluster_clk_en/q_reg[0]/Q}] + +# L2 Domain +create_generated_clock -source [get_pins i_carfield/gen_domain_clock_mux[5].i_clk_mux/clks_i[0]] -divide_by 1 -name l2_domain_clk [get_pins i_carfield/gen_domain_clock_mux[5].i_clk_mux/clk_o] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_l2_clk_sel/q_reg[0]/Q}] +set_case_analysis 0 [get_pins {i_carfield/i_carfield_reg_top/u_l2_clk_sel/q_reg[1]/Q}] +set_case_analysis 1 [get_pins {i_carfield/i_carfield_reg_top/u_l2_clk_en/q_reg[0]/Q}] -####################### -# Placement Overrides # -####################### +########## +# BUFG # +########## -# Accept suboptimal BUFG-BUFG cascades -set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets i_sys_clk_div/i_clk_mux/clk0_i] +# JTAG are on non clock capable GPIOs (if not using BSCANE) +set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets -of [get_ports jtag_tck_i]] +set_property CLOCK_BUFFER_TYPE NONE [get_nets -of [get_ports jtag_tck_i]] + +set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets -of [get_ports cpu_reset]] +set_property CLOCK_BUFFER_TYPE NONE [get_nets -of [get_ports cpu_reset]] + +set all_in_mux [get_nets -of [ get_pins -filter { DIRECTION == IN } -of [get_cells -hier -filter { ORIG_REF_NAME == tc_clk_mux2 || REF_NAME == tc_clk_mux2 }]]] +set_property CLOCK_DEDICATED_ROUTE FALSE $all_in_mux +set_property CLOCK_BUFFER_TYPE NONE $all_in_mux ######## # JTAG # @@ -77,13 +118,6 @@ set_output_delay -max -clock clk_jtag [expr 0.20 * $JTAG_TCK] [get_ports jtag_td set_max_delay -from [get_ports jtag_trst_ni] $JTAG_TCK set_false_path -hold -from [get_ports jtag_trst_ni] -####### -# MIG # -####### - -set_max_delay -from $MIG_RST_SRC $FPGA_TCK -set_false_path -hold -from $MIG_RST_SRC - ######## # UART # ######## @@ -94,20 +128,321 @@ set_false_path -hold -from [get_ports uart_rx_i] set_max_delay [expr $UART_IO_SPEED * 0.35] -to [get_ports uart_tx_o] set_false_path -hold -to [get_ports uart_tx_o] -######## -# CDCs # -######## +################# +# Carfield CDCs # +################# + +# Note : +# For the 2 phases CDC we use max_delay and hold path as we grab everything grossly +# On the AXI CDC as we precisely select the Clk-to-Q path we use a unique set_max_delay -datapath +# All the delays are assumed to be SOC_TCK (host domain) + +# Hold and max delay on 2 phases and 2 phases clearable +set_max_delay -through [get_nets -filter {NAME=~"*async*"} -of_objects [get_cells -hier -filter {REF_NAME =~ cdc_2phase_src* || ORIG_REF_NAME =~ cdc_2phase_src*}]] $SOC_TCK +set_false_path -hold -through [get_nets -filter {NAME=~"*async*"} -of_objects [get_cells -hier -filter {REF_NAME =~ cdc_2phase_src* || ORIG_REF_NAME =~ cdc_2phase_src*}]] + +# Hold and max delay on 4 phases +set_max_delay -through [get_nets -filter {NAME=~"*async*"} -of_objects [get_cells -hier -filter {REF_NAME == cdc_4phase_src || ORIG_REF_NAME == cdc_4phase_src}]] $SOC_TCK +set_false_path -hold -through [get_nets -filter {NAME=~"*async*"} -of_objects [get_cells -hier -filter {REF_NAME == cdc_4phase_src || ORIG_REF_NAME == cdc_4phase_src}]] + +# Hold and max delay on synchronizers +set all_sync_cells [get_cells -hier -filter {ORIG_REF_NAME=="sync" || REF_NAME=="sync"}] +set_property KEEP_HIERARCHY SOFT $all_sync_cells +set_false_path -hold -through [get_pins -of_objects $all_sync_cells -filter {REF_PIN_NAME=~serial_i}] +set_max_delay -through [get_pins -of_objects $all_sync_cells -filter {REF_PIN_NAME=~serial_i}] $SOC_TCK + +# Hold and max delay on pulp synchronizers +set all_pulp_sync_cells [get_cells -hier -filter {ORIG_REF_NAME=="pulp_sync" || REF_NAME=="pulp_sync"}] +set_property KEEP_HIERARCHY SOFT $all_pulp_sync_cells +set_false_path -hold -through [get_pins -of_objects $all_pulp_sync_cells -filter {REF_PIN_NAME=~serial_i}] +set_max_delay -through [get_pins -of_objects $all_pulp_sync_cells -filter {REF_PIN_NAME=~serial_i}] $SOC_TCK + +# Hold and max delay on OT synchronizers +set all_ot_sync_cells [get_cells -hier -filter {ORIG_REF_NAME=="prim_ot_flop_2sync" || REF_NAME=="prim_ot_flop_2sync"}] +set_property KEEP_HIERARCHY SOFT $all_ot_sync_cells +set_false_path -hold -through [get_pins -of_objects $all_ot_sync_cells -filter {REF_PIN_NAME=~d_i*}] +set_max_delay -through [get_pins -of_objects $all_ot_sync_cells -filter {REF_PIN_NAME=~d_i*}] $SOC_TCK + +set all_edge_propagator_ack [get_cells -hier -filter {ORIG_REF_NAME=="edge_propagator_ack" || REF_NAME=="edge_propagator_ack"}] +set_property KEEP_HIERARCHY SOFT $all_edge_propagator_ack +set_false_path -through [get_nets -filter {NAME=~*sync_b} -of_object [get_cells -hier -filter {ORIG_REF_NAME==pulp_sync_wedge || REF_NAME==pulp_sync_wedge}]] + +# Peripherals +############## + +# i_carfield/i_cdc_dst_peripherals +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cdc_dst_peripherals/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[4].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[4].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cdc_dst_peripherals/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cdc_dst_peripherals/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[4].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[4].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cdc_dst_peripherals/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# Safety Island +################ -# cdc_fifo_gray: Disable hold checks, limit datapath delay and bus skew -set_property KEEP_HIERARCHY SOFT [get_cells i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*i_sync] -set_false_path -hold -through [get_pins -of_objects [get_cells i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*]] -through [get_pins -of_objects [get_cells i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*]] -set_max_delay -datapath -from [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_dst_*/*i_sync/reg*/D] $FPGA_TCK -set_max_delay -datapath -from [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_src_*/*i_sync/reg*/D] $FPGA_TCK -set_max_delay -datapath -from [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] $FPGA_TCK +# To Safety Island error slave +# i_carfield/gen_no_safety_island.i_safety_island_axi_err/i_cdc_in +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_no_safety_island.i_safety_island_axi_err/i_cdc_in/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_no_safety_island.i_safety_island_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_no_safety_island.i_safety_island_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_no_safety_island.i_safety_island_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# To Safety Island slave +# i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_in +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_in/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_in/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[2].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# From Safety Island master +# i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[0].i_cheshire_ext_mst_cdc_dst +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_out/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[0].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[0].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_out/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_out/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[0].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[0].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_safety_island.i_safety_island_wrap/i_cdc_out/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# Pulp Cluster +################ -set_false_path -through [get_pins -of_objects [get_cells -hier -filter {ORIG_REF_NAME == axi_cdc_src || REF_NAME == axi_cdc_src}] -filter {NAME =~ *async*}] -set_false_path -through [get_pins -of_objects [get_cells -hier -filter {ORIG_REF_NAME == axi_cdc_dst || REF_NAME == axi_cdc_dst}] -filter {NAME =~ *async*}] +# To Pulp cluster error slave +# i_carfield/gen_no_pulp_cluster.i_pulp_cluster_axi_err/i_cdc_in +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_no_pulp_cluster.i_pulp_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_no_pulp_cluster.i_pulp_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_no_pulp_cluster.i_pulp_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_no_pulp_cluster.i_pulp_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# To Pulp cluster slave +# i_carfield/gen_pulp_cluster.i_integer_cluster/axi_slave_cdc_i +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_slave_cdc_i/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_slave_cdc_i/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_slave_cdc_i/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_slave_cdc_i/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_intcluster_slv_cdc/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# From Pulp cluster master +# i_carfield/i_cheshire_wrap/i_intcluster_mst_cdc +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_master_cdc_i/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_intcluster_mst_cdc/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_intcluster_mst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_master_cdc_i/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_master_cdc_i/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_intcluster_mst_cdc/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_intcluster_mst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_pulp_cluster.i_integer_cluster/axi_master_cdc_i/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# Spatz cluster +############### + +# To Spatz cluster error slave +# i_carfield/gen_no_spatz_cluster.i_spatz_cluster_axi_err/i_cdc_in +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_no_spatz_cluster.i_spatz_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_no_spatz_cluster.i_spatz_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_no_spatz_cluster.i_spatz_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_no_spatz_cluster.i_spatz_cluster_axi_err/i_cdc_in/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# To Spatz cluster slave +# i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_dst +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_dst/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_dst/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[5].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# From Spatz cluster master +# i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[2].i_cheshire_ext_mst_cdc_dst +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[2].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[2].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[2].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_mst_dst_cdc[2].i_cheshire_ext_mst_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/gen_spatz_cluster.i_fp_cluster_wrapper/i_spatz_cluster_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# Reconfigurable L2 +################### +# i_carfield/i_reconfigurable_l2/gen_cdc_fifos[0].i_dst_cdc +set_max_delay -datapath \ + -from [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[0].i_dst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[0].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D +] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[0].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[0].i_dst_cdc/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[0].i_dst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[0].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[0].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[0].i_dst_cdc/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc +set_max_delay -datapath \ + -from [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +# i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc +set_max_delay -datapath \ + -from [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/gen_ext_slv_src_cdc[1].i_cheshire_ext_slv_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_reconfigurable_l2/gen_cdc_fifos[1].i_dst_cdc/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK + +#i_hyper_cdc_dst +set_max_delay -datapath \ + -from [get_pins i_hyper_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_cheshire_ext_llc_cdc_src/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_cheshire_ext_llc_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_hyper_cdc_dst/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_hyper_cdc_dst/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_carfield/i_cheshire_wrap/i_cheshire_ext_llc_cdc_src/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK +set_max_delay -datapath \ + -from [get_pins i_carfield/i_cheshire_wrap/i_cheshire_ext_llc_cdc_src/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_hyper_cdc_dst/i_cdc_fifo_gray_*/*i_sync/*reg*/D] \ + $SOC_TCK #################### # Reset Generators # @@ -115,6 +450,7 @@ set_false_path -through [get_pins -of_objects [get_cells -hier -filter {ORIG_REF set_max_delay -from $SOC_RST_SRC $SOC_TCK set_false_path -hold -from $SOC_RST_SRC -set_false_path -hold -through [get_pins i_carfield/i_carfield_rstgen/rsts_no] -set_false_path -hold -through [get_pins i_carfield/i_carfield_rstgen/pwr_on_rsts_no] -set_false_path -hold -through [get_pins -filter {REF_PIN_NAME == rst_no} -of_objects [get_cells -hier -filter {REF_NAME == rstgen || ORIG_REF_NAME == rstgen}]] +# No max delay on sw reset since clock can be gated anyways +set_false_path -through [get_pins -of_objects [get_cells i_carfield/i_carfield_rstgen] -filter {DIRECTION==OUT}] +set_property KEEP_HIERARCHY SOFT [get_cells -hier -filter {ORIG_REF_NAME=="rstgen" || REF_NAME=="rstgen"}] +set_false_path -hold -through [get_pins -filter {DIRECTION==OUT} -of_objects [get_cells -hier -filter {REF_NAME == rstgen || ORIG_REF_NAME == rstgen}]] diff --git a/target/xilinx/constraints/vcu128.xdc b/target/xilinx/constraints/vcu128.xdc index 4c639a35e..a55db78d3 100644 --- a/target/xilinx/constraints/vcu128.xdc +++ b/target/xilinx/constraints/vcu128.xdc @@ -2,9 +2,42 @@ # BOARD SPECIFIC CONSTRAINTS # ############################## -# JTAG are on non clock capable GPIOs (if not using BSCANE) -set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets -of [get_ports jtag_tck_i]] -set_property CLOCK_BUFFER_TYPE NONE [get_nets -of [get_ports jtag_tck_i]] +############# +# Sys clock # +############# + +# 100 MHz ref clock +set SYS_TCK 10 +create_clock -period $SYS_TCK -name sys_clk [get_pins u_ibufg_sys_clk/O] +set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_pins u_ibufg_sys_clk/O] + +############# +# Mig clock # +############# + +# Dram axi clock : 750ps * 4 +set MIG_TCK 3 +create_generated_clock -source [get_pins i_dram_wrapper/i_dram/inst/u_ddr4_infrastructure/gen_mmcme4.u_mmcme_adv_inst/CLKOUT0] \ + -divide_by 1 -add -master_clock mmcm_clkout0 -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk] +# Aynch reset in +set MIG_RST_I [get_pin i_dram_wrapper/i_dram/inst/c0_ddr4_aresetn] +set_false_path -hold -setup -through $MIG_RST_I +# Synch reset out +set MIG_RST_O [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk_sync_rst] +set_false_path -hold -through $MIG_RST_O +set_max_delay -through $MIG_RST_O $MIG_TCK + +######## +# CDCs # +######## + +set_max_delay -datapath \ + -from [get_pins i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*i_sync/reg*/D] $MIG_TCK + +set_max_delay -datapath \ + -from [get_pins i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] \ + -to [get_pins i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] $MIG_TCK ################################################################################# @@ -1764,12 +1797,12 @@ set_property IOSTANDARD LVCMOS18 [get_ports jtag_tdi_i] #set_property PACKAGE_PIN C7 [get_ports "No Connect"] ;# Bank 235 - MGTYTXP2_235 #set_property PACKAGE_PIN A6 [get_ports "No Connect"] ;# Bank 235 - MGTYTXP3_235 -#set_property BOARD_PART_PIN default_100mhz_clk_n [get_ports c0_sys_clk_n] -#set_property IOSTANDARD DIFF_SSTL12 [get_ports c0_sys_clk_n] -#set_property BOARD_PART_PIN default_100mhz_clk_p [get_ports c0_sys_clk_p] -#set_property IOSTANDARD DIFF_SSTL12 [get_ports c0_sys_clk_p] -#set_property PACKAGE_PIN BH51 [get_ports c0_sys_clk_p] -#set_property PACKAGE_PIN BJ51 [get_ports c0_sys_clk_n] +set_property BOARD_PART_PIN default_100mhz_clk_n [get_ports sys_clk_n] +set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_n] +set_property BOARD_PART_PIN default_100mhz_clk_p [get_ports sys_clk_p] +set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_p] +set_property PACKAGE_PIN BH51 [get_ports sys_clk_p] +set_property PACKAGE_PIN BJ51 [get_ports sys_clk_n] #set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub] #set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub] diff --git a/target/xilinx/scripts/flash_spi.tcl b/target/xilinx/scripts/flash_spi.tcl new file mode 100644 index 000000000..75eca913e --- /dev/null +++ b/target/xilinx/scripts/flash_spi.tcl @@ -0,0 +1,48 @@ +# Copyright 2020 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 +# +# Nils Wistoff +# Noah Huetter + +open_hw_manager + +connect_hw_server -url $::env(HOST):$::env(PORT) +open_hw_target $::env(HOST):$::env(PORT)/$::env(FPGA_PATH) + +set file $::env(FILE) +set offset $::env(OFFSET) +set mcs_file image.mcs + +if {$::env(BOARD) eq "vcu128"} { + set hw_device [get_hw_devices xcvu37p_0] + set hw_mem_device [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0] +} + +# Create flash configuration file +write_cfgmem -force -format mcs -size 256 -interface SPIx4 \ + -loaddata "up $offset $file" \ + -checksum \ + -file $mcs_file + +set_property PARAM.FREQUENCY 15000000 [get_hw_targets *] + +create_hw_cfgmem -hw_device $hw_device $hw_mem_device +set hw_cfgmem [get_property PROGRAM.HW_CFGMEM $hw_device] +set_property PROGRAM.ADDRESS_RANGE {use_file} $hw_cfgmem +set_property PROGRAM.FILES [list $mcs_file ] $hw_cfgmem +set_property PROGRAM.PRM_FILE {} $hw_cfgmem +set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} $hw_cfgmem +set_property PROGRAM.BLANK_CHECK 0 $hw_cfgmem +set_property PROGRAM.ERASE 1 $hw_cfgmem +set_property PROGRAM.CFG_PROGRAM 1 $hw_cfgmem +set_property PROGRAM.VERIFY 1 $hw_cfgmem +set_property PROGRAM.CHECKSUM 0 $hw_cfgmem + +# Create bitstream to access SPI flash +create_hw_bitstream -hw_device $hw_device [get_property PROGRAM.HW_CFGMEM_BITFILE $hw_device]; +program_hw_devices $hw_device; +refresh_hw_device $hw_device; + +# Program SPI flash +program_hw_cfgmem -hw_cfgmem $hw_cfgmem diff --git a/target/xilinx/scripts/program.tcl b/target/xilinx/scripts/program.tcl index f5f4e711b..17479a931 100644 --- a/target/xilinx/scripts/program.tcl +++ b/target/xilinx/scripts/program.tcl @@ -3,26 +3,22 @@ # SPDX-License-Identifier: SHL-0.51 # # Author: Florian Zaruba -# Description: Program Genesys II -open_hw +open_hw_manager -connect_hw_server -url localhost:3121 +connect_hw_server -url $::env(HOST):$::env(PORT) +open_hw_target $::env(HOST):$::env(PORT)/$::env(FPGA_PATH) if {$::env(BOARD) eq "genesys2"} { - open_hw_target {localhost:3121/xilinx_tcf/Digilent/200300A8CD43B} + set hw_device [get_hw_devices xc7k325t_0] +} +if {$::env(BOARD) eq "vcu128"} { + set hw_device [get_hw_devices xcvu37p_0] +} - current_hw_device [get_hw_devices xc7k325t_0] - set_property PROGRAM.FILE {$::env(BIT)} [get_hw_devices xc7k325t_0] - program_hw_devices [get_hw_devices xc7k325t_0] - refresh_hw_device [lindex [get_hw_devices xc7k325t_0] 0] -} elseif {$::env(BOARD) eq "vc707"} { - open_hw_target {localhost:3121/xilinx_tcf/Digilent/210203A5FC70A} +set_property PARAM.FREQUENCY 15000000 [get_hw_targets *] - current_hw_device [get_hw_devices xc7vx485t_0] - set_property PROGRAM.FILE {$::env(BIT)} [get_hw_devices xc7vx485t_0] - program_hw_devices [get_hw_devices xc7vx485t_0] - refresh_hw_device [lindex [get_hw_devices xc7vx485t_0] 0] -} else { - exit 1 -} +current_hw_device $hw_device +set_property PROGRAM.FILE $::env(BIT) $hw_device +program_hw_devices $hw_device +refresh_hw_device [lindex $hw_device 0] diff --git a/target/xilinx/scripts/run.tcl b/target/xilinx/scripts/run.tcl index 29c16b1fc..b47e208ce 100644 --- a/target/xilinx/scripts/run.tcl +++ b/target/xilinx/scripts/run.tcl @@ -4,13 +4,11 @@ # # Author: Florian Zaruba -if {![info exists ELABORATION_ONLY]} {set ELABORATION_ONLY 0} - # Contraints files selection switch $::env(BOARD) { "genesys2" - "kc705" - "vc707" - "vcu128" - "zcu102" { - import_files -fileset constrs_1 -norecurse constraints/$::env(PROJECT).xdc import_files -fileset constrs_1 -norecurse constraints/$::env(BOARD).xdc + import_files -fileset constrs_1 -norecurse constraints/$::env(PROJECT).xdc } default { exit 1 @@ -18,26 +16,7 @@ switch $::env(BOARD) { } # Ips selection -switch $::env(BOARD) { - "genesys2" - "kc705" - "vc707" { - set ips { "xilinx/xlnx_mig_7_ddr3/xlnx_mig_7_ddr3.srcs/sources_1/ip/xlnx_mig_7_ddr3/xlnx_mig_7_ddr3.xci" \ - "xilinx/xlnx_clk_wiz/xlnx_clk_wiz.srcs/sources_1/ip/xlnx_clk_wiz/xlnx_clk_wiz.xci" \ - "xilinx/xlnx_vio/xlnx_vio.srcs/sources_1/ip/xlnx_vio/xlnx_vio.xci" } - } - "vcu128" { - set ips { "xilinx/xlnx_clk_wiz/xlnx_clk_wiz.srcs/sources_1/ip/xlnx_clk_wiz/xlnx_clk_wiz.xci" \ - "xilinx/xlnx_vio/xlnx_vio.srcs/sources_1/ip/xlnx_vio/xlnx_vio.xci" } - } - "zcu102" { - set ips { "xilinx/xlnx_mig_ddr4/xlnx_mig_ddr4.srcs/sources_1/ip/xlnx_mig_ddr4/xlnx_mig_ddr4.xci" \ - "xilinx/xlnx_clk_wiz/xlnx_clk_wiz.srcs/sources_1/ip/xlnx_clk_wiz/xlnx_clk_wiz.xci" \ - "xilinx/xlnx_vio/xlnx_vio.srcs/sources_1/ip/xlnx_vio/xlnx_vio.xci" } - } - default { - set ips {} - } -} - +set ips $::env(IP_PATHS) read_ip $ips source scripts/add_sources.tcl @@ -46,15 +25,13 @@ set_property top ${project}_top_xilinx [current_fileset] update_compile_order -fileset sources_1 -if {$ELABORATION_ONLY} { - set_property flow.runs.elaborate 1 [get_runs synth_1] - set_property flow.runs.synth 0 [get_runs synth_1] +if {[info exists ::env(ELABORATION_ONLY)] && $::env(ELABORATION_ONLY)==1} { + puts "Running with ELABORATION_ONLY" + set_property XPM_LIBRARIES XPM_MEMORY [current_project] + + synth_design -rtl -name rtl_1 -sfcu - launch_runs synth_1 - wait_on_run synth_1 - } else { - # Runtime optimized due to the low frequency (20MHz) set_property strategy Flow_RuntimeOptimized [get_runs synth_1] set_property strategy Flow_RuntimeOptimized [get_runs impl_1] @@ -85,45 +62,45 @@ if {$ELABORATION_ONLY} { # Instantiate ILA set DEBUG [llength [get_nets -hier -filter {MARK_DEBUG == 1}]] if ($DEBUG) { - # Create core - puts "Creating debug core..." - create_debug_core u_ila_0 ila - set_property -dict "ALL_PROBE_SAME_MU true ALL_PROBE_SAME_MU_CNT 4 C_ADV_TRIGGER true C_DATA_DEPTH 16384 \ - C_EN_STRG_QUAL true C_INPUT_PIPE_STAGES 0 C_TRIGIN_EN false C_TRIGOUT_EN false" [get_debug_cores u_ila_0] - ## Clock - set_property port_width 1 [get_debug_ports u_ila_0/clk] - connect_debug_port u_ila_0/clk [get_nets soc_clk] - # Get nets to debug - set debugNets [lsort -dictionary [get_nets -hier -filter {MARK_DEBUG == 1}]] - set netNameLast "" - set probe_i 0 - # Loop through all nets (add extra list element to ensure last net is processed) - foreach net [concat $debugNets {""}] { - # Remove trailing array index - regsub {\[[0-9]*\]$} $net {} netName - # Create probe after all signals with the same name have been collected - if {$netNameLast != $netName} { - if {$netNameLast != ""} { - puts "Creating probe $probe_i with width [llength $sigList] for signal '$netNameLast'" - # probe0 already exists, and does not need to be created - if {$probe_i != 0} { - create_debug_port u_ila_0 probe - } - set_property port_width [llength $sigList] [get_debug_ports u_ila_0/probe$probe_i] - set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe$probe_i] - connect_debug_port u_ila_0/probe$probe_i [get_nets $sigList] - incr probe_i - } - set sigList "" - } - lappend sigList $net - set netNameLast $netName + # Create core + puts "Creating debug core..." + create_debug_core u_ila_0 ila + set_property -dict "ALL_PROBE_SAME_MU true ALL_PROBE_SAME_MU_CNT 4 C_ADV_TRIGGER true C_DATA_DEPTH 16384 \ + C_EN_STRG_QUAL true C_INPUT_PIPE_STAGES 0 C_TRIGIN_EN false C_TRIGOUT_EN false" [get_debug_cores u_ila_0] + ## Clock + set_property port_width 1 [get_debug_ports u_ila_0/clk] + connect_debug_port u_ila_0/clk [get_nets soc_clk] + # Get nets to debug + set debugNets [lsort -dictionary [get_nets -hier -filter {MARK_DEBUG == 1}]] + set netNameLast "" + set probe_i 0 + # Loop through all nets (add extra list element to ensure last net is processed) + foreach net [concat $debugNets {""}] { + # Remove trailing array index + regsub {\[[0-9]*\]$} $net {} netName + # Create probe after all signals with the same name have been collected + if {$netNameLast != $netName} { + if {$netNameLast != ""} { + puts "Creating probe $probe_i with width [llength $sigList] for signal '$netNameLast'" + # probe0 already exists, and does not need to be created + if {$probe_i != 0} { + create_debug_port u_ila_0 probe + } + set_property port_width [llength $sigList] [get_debug_ports u_ila_0/probe$probe_i] + set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe$probe_i] + connect_debug_port u_ila_0/probe$probe_i [get_nets $sigList] + incr probe_i + } + set sigList "" } - # Need to save save constraints before implementing the core - # set_property target_constrs_file cheshire.srcs/constrs_1/imports/constraints/$::env(BOARD).xdc [current_fileset -constrset] - save_constraints -force - implement_debug_core - write_debug_probes -force probes.ltx + lappend sigList $net + set netNameLast $netName + } + # Need to save save constraints before implementing the core + # set_property target_constrs_file cheshire.srcs/constrs_1/imports/constraints/$::env(BOARD).xdc [current_fileset -constrset] + save_constraints -force + implement_debug_core + write_debug_probes -force probes.ltx } # Implementation diff --git a/target/xilinx/src/carfield_top_xilinx.sv b/target/xilinx/src/carfield_top_xilinx.sv index ae683507d..1e982d24d 100644 --- a/target/xilinx/src/carfield_top_xilinx.sv +++ b/target/xilinx/src/carfield_top_xilinx.sv @@ -22,6 +22,10 @@ module carfield_top_xilinx input logic cpu_resetn, `endif + // System clock for clk_wiz + input logic sys_clk_p, + input logic sys_clk_n, + `ifdef USE_SWITCHES input logic testmode_i, input logic [1:0] boot_mode_i, @@ -60,13 +64,10 @@ module carfield_top_xilinx `endif `ifdef USE_QSPI - output logic qspi_clk, - input logic qspi_dq0, - input logic qspi_dq1, - input logic qspi_dq2, - input logic qspi_dq3, - output logic qspi_cs_b, -`endif +`ifndef USE_STARTUPE3 + // TODO: off-chip qspi interface +`endif // USE_STARTUPE3 +`endif // USE_QSPI `ifdef USE_VGA // VGA Colour signals @@ -93,11 +94,6 @@ module carfield_top_xilinx `DDR3_INTF `endif -`ifdef USE_CLK_WIZ - input clk_in1_p, - input clk_in1_n, -`endif - // Phy interface for Hyperbus `ifdef USE_HYPERBUS // Physical interace: HyperBus PADs @@ -115,6 +111,10 @@ module carfield_top_xilinx ); + /////////////////////////// + // Clk reset definitions // + /////////////////////////// + `ifdef USE_RESET logic cpu_resetn; assign cpu_resetn = ~cpu_reset; @@ -124,11 +124,9 @@ module carfield_top_xilinx `endif logic sys_rst; - (* dont_touch = "yes" *) wire master_clk; - (* dont_touch = "yes" *) wire master_sync_rst; - (* dont_touch = "yes" *) wire soc_clk; - (* dont_touch = "yes" *) wire rst_n; - + wire clk_100, clk_50, clk_20, clk_10; + wire soc_clk, host_clk, alt_clk, periph_clk; + (* dont_touch = "yes" *) wire rst_n; /////////////////// // GPIOs // @@ -153,6 +151,52 @@ module carfield_top_xilinx assign jtag_trst_ni = '1; `endif + ////////////////// + // Clock Wizard // + ////////////////// + + wire sys_clk; + + // Get from the diff board pins a single ended buffered clock that + // can be sent to clk_wiz and DDR separately (without cascading MMCMs) + // As sys_clk frequency depends on the boards /!\ in IPs configurations + IBUFDS # + ( + .IBUF_LOW_PWR ("FALSE") + ) + u_ibufg_sys_clk + ( + .I (sys_clk_p), + .IB (sys_clk_n), + .O (sys_clk) + ); + + + xlnx_clk_wiz i_xlnx_clk_wiz ( + .clk_in1 ( sys_clk ), + .reset ( '0 ), + .clk_100 ( clk_100 ), + .clk_50 ( clk_50 ), + .clk_20 ( clk_20 ), + .clk_10 ( clk_10 ) + ); + localparam rtc_clk_divider = 4; + assign soc_clk = clk_50; + assign alt_clk = clk_20; + assign host_clk = soc_clk; + assign periph_clk = soc_clk; + + ///////////////////// + // Reset Generator // + ///////////////////// + + rstgen i_rstgen_main ( + .clk_i ( soc_clk ), + .rst_ni ( ~sys_rst ), + .test_mode_i ( testmode_i ), + .rst_no ( rst_n ), + .init_no ( ) // keep open + ); /////////////////// // VIOs // @@ -179,63 +223,6 @@ module carfield_top_xilinx assign boot_mode_safety = boot_mode_safety_i; `endif - - ////////////////// - // Clock Wizard // - ////////////////// - -`ifdef USE_CLK_WIZ - xlnx_clk_wiz i_xlnx_clk_wiz ( - .clk_in1_p, - .clk_in1_n, - .reset(master_clk), - // 50 MHz clock out - .clk_out1( soc_clk ) - ); - - //rstgen i_rstgen_main ( - // .clk_i ( soc_clk ), - // .rst_ni ( ~sys_rst ), - // .test_mode_i ( testmode_i ), - // .rst_no ( rst_n ), - // .init_no ( ) // keep open - //); - assign rst_n = ~sys_rst; -`endif - - - ////////////////// - // DRAM WRAPPER // - ////////////////// - -`ifdef USE_DDR - - dram_wrapper #( - .axi_soc_aw_chan_t ( axi_llc_aw_chan_t ), - .axi_soc_w_chan_t ( axi_llc_w_chan_t ), - .axi_soc_b_chan_t ( axi_llc_b_chan_t ), - .axi_soc_ar_chan_t ( axi_llc_ar_chan_t ), - .axi_soc_r_chan_t ( axi_llc_r_chan_t ), - .axi_soc_req_t (axi_llc_req_t), - .axi_soc_resp_t (axi_llc_rsp_t) - ) i_dram_wrapper ( - // Rst - .sys_rst_i ( cpu_reset ), - .soc_resetn_i ( rst_n ), - .soc_clk_i ( soc_clk ), - // Clk rst out - .dram_clk_o ( master_clk ), - .dram_rst_o ( master_sync_reset ), - // Axi - .soc_req_i ( '0 ), - .soc_rsp_o ( ), - // Phy - .* - ); - -`endif - - ////////////////// // I2C Adaption // ////////////////// @@ -293,13 +280,6 @@ module carfield_top_xilinx logic spi_sck_en; logic [1:0] spi_cs_en; logic [3:0] spi_sd_en; - logic spi_sck_en_n; - logic [1:0] spi_cs_en_n; - logic [3:0] spi_sd_en_n; - - assign spi_sck_en = ~spi_sck_en_n; - assign spi_cs_en = ~spi_cs_en_n; - assign spi_sd_en = ~spi_sd_en_n; `ifdef USE_SD // Assert reset low => Apply power to the SD Card @@ -320,32 +300,78 @@ module carfield_top_xilinx assign spi_sd_soc_in[3] = 1'b0; `endif + ////////////////// + // QSPI // + ////////////////// + `ifdef USE_QSPI - assign qspi_clk = spi_sck_en ? spi_sck_soc : 1'b1; - assign qspi_cs_b = spi_cs_soc[0]; - assign spi_sd_soc_in[1] = qspi_dq0; -`endif + logic qspi_clk; + logic qspi_clk_ts; + logic [3:0] qspi_dqi; + logic [3:0] qspi_dqo_ts; + logic [3:0] qspi_dqo; + logic [SpihNumCs-1:0] qspi_cs_b; + logic [SpihNumCs-1:0] qspi_cs_b_ts; + + assign qspi_clk = spi_sck_soc; + assign qspi_cs_b = spi_cs_soc; + assign qspi_dqo = spi_sd_soc_out; + assign spi_sd_soc_in = qspi_dqi; + // Tristate - Enable + assign qspi_clk_ts = ~spi_sck_en; + assign qspi_cs_b_ts = ~spi_cs_en; + assign qspi_dqo_ts = ~spi_sd_en; + + // On VCU128/ZCU102, SPI ports are not directly available +`ifdef USE_STARTUPE3 + STARTUPE3 #( + .PROG_USR("FALSE"), + .SIM_CCLK_FREQ(0.0) + ) + STARTUPE3_inst ( + .CFGCLK (), + .CFGMCLK (), + .DI (qspi_dqi), + .EOS (), + .PREQ (), + .DO (qspi_dqo), + .DTS (qspi_dqo_ts), + .FCSBO (qspi_cs_b[1]), + .FCSBTS (qspi_cs_b_ts[1]), + .GSR (1'b0), + .GTS (1'b0), + .KEYCLEARB (1'b1), + .PACK (1'b0), + .USRCCLKO (qspi_clk), + .USRCCLKTS (qspi_clk_ts), + .USRDONEO (1'b1), + .USRDONETS (1'b1) + ); +`else + // TODO: off-chip qspi interface +`endif // USE_STARTUPE3 +`endif // USE_QSPI ///////////////////////// // "RTC" Clock Divider // ///////////////////////// - logic rtc_clk_d, rtc_clk_q; + (* dont_touch = "yes" *) logic rtc_clk_d, rtc_clk_q; logic [4:0] counter_d, counter_q; - // Divide soc_clk (20 MHz) by 20 => 1 MHz RTC Clock + // Divide clk_10 => 1 MHz RTC Clock always_comb begin counter_d = counter_q + 1; rtc_clk_d = rtc_clk_q; - if(counter_q == 19) begin + if(counter_q == rtc_clk_divider) begin counter_d = 5'b0; rtc_clk_d = ~rtc_clk_q; end end - always_ff @(posedge soc_clk, negedge rst_n) begin + always_ff @(posedge clk_10, negedge rst_n) begin if(~rst_n) begin counter_q <= 5'b0; rtc_clk_q <= 0; @@ -369,7 +395,6 @@ module carfield_top_xilinx ); `endif - ////////////////// // Carfield Cfg // ////////////////// @@ -400,6 +425,71 @@ module carfield_top_xilinx default : '1 }; + /////////////////// + // LLC interface // + /////////////////// + +`ifdef NO_HYPERBUS // bender-xilinx.mk + localparam axi_in_t AxiIn = gen_axi_in(Cfg); + localparam int unsigned LlcIdWidth = Cfg.AxiMstIdWidth+$clog2(AxiIn.num_in)+Cfg.LlcNotBypass; + localparam int unsigned LlcArWidth = (2**LogDepth)*axi_pkg::ar_width(Cfg.AddrWidth,LlcIdWidth,Cfg.AxiUserWidth); + localparam int unsigned LlcAwWidth = (2**LogDepth)*axi_pkg::aw_width(Cfg.AddrWidth,LlcIdWidth,Cfg.AxiUserWidth); + localparam int unsigned LlcBWidth = (2**LogDepth)*axi_pkg::b_width(LlcIdWidth,Cfg.AxiUserWidth); + localparam int unsigned LlcRWidth = (2**LogDepth)*axi_pkg::r_width(Cfg.AxiDataWidth,LlcIdWidth,Cfg.AxiUserWidth); + localparam int unsigned LlcWWidth = (2**LogDepth)*axi_pkg::w_width(Cfg.AxiDataWidth,Cfg.AxiUserWidth); + // LLC interface + logic [LlcArWidth-1:0] llc_ar_data; + logic [ LogDepth:0] llc_ar_wptr; + logic [ LogDepth:0] llc_ar_rptr; + logic [LlcAwWidth-1:0] llc_aw_data; + logic [ LogDepth:0] llc_aw_wptr; + logic [ LogDepth:0] llc_aw_rptr; + logic [ LlcBWidth-1:0] llc_b_data; + logic [ LogDepth:0] llc_b_wptr; + logic [ LogDepth:0] llc_b_rptr; + logic [ LlcRWidth-1:0] llc_r_data; + logic [ LogDepth:0] llc_r_wptr; + logic [ LogDepth:0] llc_r_rptr; + logic [ LlcWWidth-1:0] llc_w_data; + logic [ LogDepth:0] llc_w_wptr; + logic [ LogDepth:0] llc_w_rptr; + // Axi interface + carfield_axi_llc_req_t llc_req; + carfield_axi_llc_rsp_t llc_rsp; + + axi_cdc_dst #( + .LogDepth ( LogDepth ), + .axi_req_t ( carfield_axi_llc_req_t ), + .axi_resp_t ( carfield_axi_llc_rsp_t ), + .w_chan_t ( carfield_axi_llc_w_chan_t ), + .b_chan_t ( carfield_axi_llc_b_chan_t ), + .ar_chan_t ( carfield_axi_llc_ar_chan_t ), + .r_chan_t ( carfield_axi_llc_r_chan_t ), + .aw_chan_t ( carfield_axi_llc_aw_chan_t ) + ) i_hyper_cdc_dst ( + .async_data_slave_aw_data_i ( llc_aw_data ), + .async_data_slave_aw_wptr_i ( llc_aw_wptr ), + .async_data_slave_aw_rptr_o ( llc_aw_rptr ), + .async_data_slave_w_data_i ( llc_w_data ), + .async_data_slave_w_wptr_i ( llc_w_wptr ), + .async_data_slave_w_rptr_o ( llc_w_rptr ), + .async_data_slave_b_data_o ( llc_b_data ), + .async_data_slave_b_wptr_o ( llc_b_wptr ), + .async_data_slave_b_rptr_i ( llc_b_rptr ), + .async_data_slave_ar_data_i ( llc_ar_data ), + .async_data_slave_ar_wptr_i ( llc_ar_wptr ), + .async_data_slave_ar_rptr_o ( llc_ar_rptr ), + .async_data_slave_r_data_o ( llc_r_data ), + .async_data_slave_r_wptr_o ( llc_r_wptr ), + .async_data_slave_r_rptr_i ( llc_r_rptr ), + // synchronous master port + .dst_clk_i ( soc_clk ), + .dst_rst_ni ( rst_n ), + .dst_req_o ( llc_req ), + .dst_resp_i ( llc_rsp ) +); +`endif // NO_HYPERBUS + ////////////////// // Carfield SoC // ////////////////// @@ -411,12 +501,20 @@ module carfield_top_xilinx .IslandsCfg(IslandsCfg), .reg_req_t(carfield_reg_req_t), .reg_rsp_t(carfield_reg_rsp_t), +`ifdef NO_HYPERBUS + .LlcIdWidth ( LlcIdWidth ), + .LlcArWidth ( LlcArWidth ), + .LlcAwWidth ( LlcAwWidth ), + .LlcBWidth ( LlcBWidth ), + .LlcRWidth ( LlcRWidth ), + .LlcWWidth ( LlcWWidth ), +`endif .HypNumPhys (`HypNumPhys), .HypNumChips (`HypNumChips) ) i_carfield ( - .host_clk_i (soc_clk), - .periph_clk_i (soc_clk), - .alt_clk_i (soc_clk), + .host_clk_i (host_clk), + .periph_clk_i (periph_clk), + .alt_clk_i (alt_clk), .rt_clk_i (rtc_clk_q), .pwr_on_rst_ni (rst_n), .test_mode_i (testmode_i), @@ -464,49 +562,68 @@ module carfield_top_xilinx .i2c_scl_i (), .i2c_scl_en_o (), // SPI Host Interface - .spih_sck_o (), - .spih_sck_en_o (), - .spih_csb_o (), - .spih_csb_en_o (), - .spih_sd_o (), - .spih_sd_en_o (), - .spih_sd_i (), + .spih_sck_o (spi_sck_soc), + .spih_sck_en_o (spi_sck_en), + .spih_csb_o (spi_cs_soc), + .spih_csb_en_o (spi_cs_en), + .spih_sd_o (spi_sd_soc_out), + .spih_sd_en_o (spi_sd_en), + .spih_sd_i (spi_sd_soc_in), // GPIO interface .gpio_i (), .gpio_o (), .gpio_en_o (), +`ifdef NO_HYPERBUS + // LLC Interface + .llc_ar_data, + .llc_ar_wptr, + .llc_ar_rptr, + .llc_aw_data, + .llc_aw_wptr, + .llc_aw_rptr, + .llc_b_data, + .llc_b_wptr, + .llc_b_rptr, + .llc_r_data, + .llc_r_wptr, + .llc_r_rptr, + .llc_w_data, + .llc_w_wptr, + .llc_w_rptr, +`endif // Serial link interface .slink_rcv_clk_i (), .slink_rcv_clk_o (), .slink_i (), .slink_o () + ); + + ////////////////// + // DRAM WRAPPER // + ////////////////// - // LLC (DRAM) Interace - //.llc_ar_data, - //.llc_ar_wptr, - //.llc_ar_rptr, - //.llc_aw_data, - //.llc_aw_wptr, - //.llc_aw_rptr, - //.llc_b_data, - //.llc_b_wptr, - //.llc_b_rptr, - //.llc_r_data, - //.llc_r_wptr, - //.llc_r_rptr, - //.llc_w_data, - //.llc_w_wptr, - //.llc_w_rptr, - //.hyper_cs_n_wire, - //.hyper_ck_wire, - //.hyper_ck_n_wire, - //.hyper_rwds_o, - //.hyper_rwds_i, - //.hyper_rwds_oe, - //.hyper_dq_i, - //.hyper_dq_o, - //.hyper_dq_oe, - //.hyper_reset_n_wire +`ifdef USE_DDR + dram_wrapper #( + .axi_soc_aw_chan_t ( carfield_axi_llc_aw_chan_t ), + .axi_soc_w_chan_t ( carfield_axi_llc_w_chan_t ), + .axi_soc_b_chan_t ( carfield_axi_llc_b_chan_t ), + .axi_soc_ar_chan_t ( carfield_axi_llc_ar_chan_t ), + .axi_soc_r_chan_t ( carfield_axi_llc_r_chan_t ), + .axi_soc_req_t ( carfield_axi_llc_req_t ), + .axi_soc_resp_t ( carfield_axi_llc_rsp_t ) + ) i_dram_wrapper ( + // Rst + .sys_rst_i ( sys_rst ), + .soc_resetn_i ( rst_n ), + .soc_clk_i ( soc_clk ), + // Sys clk + .dram_clk_i ( sys_clk ), + // Axi + .soc_req_i ( llc_req ), + .soc_rsp_o ( llc_rsp ), + // Phy + .* ); +`endif endmodule diff --git a/target/xilinx/src/cdc_dst_axi_err.sv b/target/xilinx/src/cdc_dst_axi_err.sv new file mode 100644 index 000000000..b3cc5b0a9 --- /dev/null +++ b/target/xilinx/src/cdc_dst_axi_err.sv @@ -0,0 +1,101 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Cyril Koenig + +module cdc_dst_axi_err #( + + parameter int unsigned AxiInIdWidth = 1, + parameter int unsigned LogDepth = 2, + parameter int unsigned CdcSyncStages = 2, + + parameter type axi_in_aw_chan_t = logic, + parameter type axi_in_w_chan_t = logic, + parameter type axi_in_b_chan_t = logic, + parameter type axi_in_ar_chan_t = logic, + parameter type axi_in_r_chan_t = logic, + parameter type axi_in_req_t = logic, + parameter type axi_in_resp_t = logic, + + parameter int unsigned AsyncAxiInAwWidth = 1, + parameter int unsigned AsyncAxiInWWidth = 1, + parameter int unsigned AsyncAxiInBWidth = 1, + parameter int unsigned AsyncAxiInArWidth = 1, + parameter int unsigned AsyncAxiInRWidth = 1 + +) ( + input logic clk_i, + input logic rst_ni, + input logic pwr_on_rst_ni, + + input logic [AsyncAxiInAwWidth-1:0] async_axi_in_aw_data_i, + input logic [LogDepth:0] async_axi_in_aw_wptr_i, + output logic [LogDepth:0] async_axi_in_aw_rptr_o, + input logic [ AsyncAxiInWWidth-1:0] async_axi_in_w_data_i, + input logic [LogDepth:0] async_axi_in_w_wptr_i, + output logic [LogDepth:0] async_axi_in_w_rptr_o, + output logic [ AsyncAxiInBWidth-1:0] async_axi_in_b_data_o, + output logic [LogDepth:0] async_axi_in_b_wptr_o, + input logic [LogDepth:0] async_axi_in_b_rptr_i, + input logic [AsyncAxiInArWidth-1:0] async_axi_in_ar_data_i, + input logic [LogDepth:0] async_axi_in_ar_wptr_i, + output logic [LogDepth:0] async_axi_in_ar_rptr_o, + output logic [ AsyncAxiInRWidth-1:0] async_axi_in_r_data_o, + output logic [LogDepth:0] async_axi_in_r_wptr_o, + input logic [LogDepth:0] async_axi_in_r_rptr_i +); + + axi_in_req_t axi_in_req; + axi_in_resp_t axi_in_resp; + + axi_cdc_dst #( + .LogDepth ( LogDepth ), + .SyncStages ( CdcSyncStages ), + .aw_chan_t ( axi_in_aw_chan_t ), + .w_chan_t ( axi_in_w_chan_t ), + .b_chan_t ( axi_in_b_chan_t ), + .ar_chan_t ( axi_in_ar_chan_t ), + .r_chan_t ( axi_in_r_chan_t ), + .axi_req_t ( axi_in_req_t ), + .axi_resp_t ( axi_in_resp_t ) + ) i_cdc_in ( + .async_data_slave_aw_data_i( async_axi_in_aw_data_i ), + .async_data_slave_aw_wptr_i( async_axi_in_aw_wptr_i ), + .async_data_slave_aw_rptr_o( async_axi_in_aw_rptr_o ), + .async_data_slave_w_data_i ( async_axi_in_w_data_i ), + .async_data_slave_w_wptr_i ( async_axi_in_w_wptr_i ), + .async_data_slave_w_rptr_o ( async_axi_in_w_rptr_o ), + .async_data_slave_b_data_o ( async_axi_in_b_data_o ), + .async_data_slave_b_wptr_o ( async_axi_in_b_wptr_o ), + .async_data_slave_b_rptr_i ( async_axi_in_b_rptr_i ), + .async_data_slave_ar_data_i( async_axi_in_ar_data_i ), + .async_data_slave_ar_wptr_i( async_axi_in_ar_wptr_i ), + .async_data_slave_ar_rptr_o( async_axi_in_ar_rptr_o ), + .async_data_slave_r_data_o ( async_axi_in_r_data_o ), + .async_data_slave_r_wptr_o ( async_axi_in_r_wptr_o ), + .async_data_slave_r_rptr_i ( async_axi_in_r_rptr_i ), + .dst_clk_i ( clk_i ), + .dst_rst_ni ( pwr_on_rst_ni ), + .dst_req_o ( axi_in_req ), + .dst_resp_i ( axi_in_resp ) + ); + + axi_err_slv #( + .AxiIdWidth ( AxiInIdWidth ), + .axi_req_t ( axi_in_req_t ), + .axi_resp_t ( axi_in_resp_t ), + .Resp ( axi_pkg::RESP_DECERR ), + .ATOPs ( 1'b0 ), + .MaxTrans ( 4 ) + ) i_axi_err_slv ( + .clk_i ( clk_i ), + .rst_ni ( pwr_on_rst_ni ), + .test_i ( '0 ), + // slave port + .slv_req_i ( axi_in_req ), + .slv_resp_o ( axi_in_resp ) + ); + + +endmodule diff --git a/target/xilinx/src/dram_wrapper.sv b/target/xilinx/src/dram_wrapper.sv index 2e7b4423d..5b7ec049d 100644 --- a/target/xilinx/src/dram_wrapper.sv +++ b/target/xilinx/src/dram_wrapper.sv @@ -20,6 +20,7 @@ module dram_wrapper #( ) ( // System reset input sys_rst_i, + input dram_clk_i, // Controller reset input soc_resetn_i, input soc_clk_i, @@ -32,11 +33,7 @@ module dram_wrapper #( `endif // Dram axi interface input axi_soc_req_t soc_req_i, - output axi_soc_resp_t soc_rsp_o, - // Generated clk/rst for SoC - output dram_clk_o, - // Synchronous with dram_axi_clk (not dram_clk_o) - output dram_rst_o + output axi_soc_resp_t soc_rsp_o ); //////////////////////////////////// @@ -54,29 +51,42 @@ module dram_wrapper #( integer StrobeWidth; } dram_cfg_t; -`ifdef USE_DDR4 +`ifdef TARGET_VCU128 localparam dram_cfg_t cfg = '{ EnSpill0 : 1, EnResizer : 1, - EnCDC : 1, // 333 MHz + EnCDC : 1, // 333 MHz axi EnSpill1 : 1, - IdWidth : 4, + IdWidth : 8, AddrWidth : 32, DataWidth : 512, - StrobeWidth : 64 + StrobeWidth : 64 }; `endif -`ifdef USE_DDR3 +`ifdef TARGET_ZCU102 localparam dram_cfg_t cfg = '{ - EnSpill0 : 0, + EnSpill0 : 1, + EnResizer : 1, + EnCDC : 1, // ??? MHz axi + EnSpill1 : 1, + IdWidth : 6, + AddrWidth : 29, + DataWidth : 128, + StrobeWidth : 16 + }; +`endif + +`ifdef TARGET_GENESYS2 + localparam dram_cfg_t cfg = '{ + EnSpill0 : 1, EnResizer : 0, - EnCDC : 1, // 200 MHz + EnCDC : 1, // 200 MHz axi EnSpill1 : 1, IdWidth : 6, AddrWidth : 30, DataWidth : 64, - StrobeWidth : 8 + StrobeWidth : 8 }; `endif @@ -86,16 +96,17 @@ module dram_wrapper #( logic[$bits(soc_req_i.ar.user)-1:0]) // Clock on which is clocked the DRAM AXI - // (May or may not be the dram_clk_o) - logic dram_axi_clk; + logic dram_axi_clk, dram_rst_o; // Signals before resizing axi_soc_req_t soc_spill_req, spill_resizer_req; axi_soc_resp_t soc_spill_rsp, spill_resizer_rsp; // Signals after resizing - axi_ddr_req_t resizer_cdc_req, cdc_spill_req, spill_dram_req; - axi_ddr_resp_t resizer_cdc_rsp, cdc_spill_rsp, spill_dram_rsp; + axi_ddr_req_t resizer_cdc_req, cdc_spill_req; + axi_ddr_req_t spill_dram_req; + axi_ddr_resp_t resizer_cdc_rsp, cdc_spill_rsp; + axi_ddr_resp_t spill_dram_rsp; // Entry signals assign soc_spill_req = soc_req_i; @@ -243,24 +254,12 @@ module dram_wrapper #( // Process ids if (IdPadding > 0) begin : gen_downsize_ids - // Sample full rid and bid from arid and awid on request - assign spill_dram_rsp_rid_d = spill_dram_req.ar_valid ? spill_dram_req.ar.id : spill_dram_rsp_rid_q; - assign spill_dram_rsp_bid_d = spill_dram_req.aw_valid ? spill_dram_req.aw.id : spill_dram_rsp_bid_q; - // Send reduced ids to DRAM - assign spill_dram_req_arid = spill_dram_req.ar.id[cfg.IdWidth-1:0]; - assign spill_dram_req_awid = spill_dram_req.aw.id[cfg.IdWidth-1:0]; - // Send full sampled rid and bid to SoC on response - assign spill_dram_rsp.r.id = spill_dram_rsp.r_valid ? { - {IdPadding{1'b0}}, spill_dram_rsp_rid_q - } : '0; - assign spill_dram_rsp.b.id = spill_dram_rsp.b_valid ? { - {IdPadding{1'b0}}, spill_dram_rsp_bid_q - } : '0; - + // NOT SUPPORTED + do_not_enter_here i_error(); end else begin : gen_upsize_ids // Forward arid awid rid bid to and from DDR - assign spill_dram_req_arid = spill_dram_req.ar.id; - assign spill_dram_req_awid = spill_dram_req.aw.id; + assign spill_dram_req_arid = {{-IdPadding{1'b0}}, spill_dram_req.ar.id}; + assign spill_dram_req_awid = {{-IdPadding{1'b0}}, spill_dram_req.aw.id}; assign spill_dram_rsp.r.id = spill_dram_rsp_rid; assign spill_dram_rsp.b.id = spill_dram_rsp_bid; end @@ -287,7 +286,8 @@ module dram_wrapper #( xlnx_mig_ddr4 i_dram ( // Rst - .sys_rst (sys_rst_i), + .sys_rst (sys_rst_i), // Active high + .c0_sys_clk_i (dram_clk_i), .c0_ddr4_aresetn (soc_resetn_i), // Clk rst out .c0_ddr4_ui_clk (dram_axi_clk), @@ -330,6 +330,26 @@ module dram_wrapper #( .c0_ddr4_s_axi_rresp (spill_dram_rsp.r.resp), .c0_ddr4_s_axi_rlast (spill_dram_rsp.r.last), .c0_ddr4_s_axi_rvalid (spill_dram_rsp.r_valid), +`ifdef TARGET_VCU128 + // Axi ctrl + .c0_ddr4_s_axi_ctrl_awvalid('0), + .c0_ddr4_s_axi_ctrl_awready(), + .c0_ddr4_s_axi_ctrl_awaddr ('0), + .c0_ddr4_s_axi_ctrl_wvalid ('0), + .c0_ddr4_s_axi_ctrl_wready (), + .c0_ddr4_s_axi_ctrl_wdata ('0), + .c0_ddr4_s_axi_ctrl_bvalid (), + .c0_ddr4_s_axi_ctrl_bready ('0), + .c0_ddr4_s_axi_ctrl_bresp (), + .c0_ddr4_s_axi_ctrl_arvalid('0), + .c0_ddr4_s_axi_ctrl_arready(), + .c0_ddr4_s_axi_ctrl_araddr ('0), + .c0_ddr4_s_axi_ctrl_rvalid (), + .c0_ddr4_s_axi_ctrl_rready ('0), + .c0_ddr4_s_axi_ctrl_rdata (), + .c0_ddr4_s_axi_ctrl_rresp (), + .c0_ddr4_interrupt (), +`endif // Others .c0_init_calib_complete (), // keep open .addn_ui_clkout1 (dram_clk_o), @@ -338,6 +358,7 @@ module dram_wrapper #( // Phy .* ); + `endif // USE_DDR4 @@ -348,11 +369,9 @@ module dram_wrapper #( `ifdef USE_DDR3 - // AXI is already on 200 MHz no need for secondary clock - assign dram_clk_o = dram_axi_clk; - xlnx_mig_7_ddr3 i_dram ( - .sys_rst (~sys_rst_i), + .sys_rst (sys_rst_i), // Active high + .sys_clk_i (dram_clk_i), .ui_clk (dram_axi_clk), .ui_clk_sync_rst (dram_rst_o), .mmcm_locked (), // keep open diff --git a/target/xilinx/src/phy_definitions.svh b/target/xilinx/src/phy_definitions.svh index dbfc659fb..068147b21 100644 --- a/target/xilinx/src/phy_definitions.svh +++ b/target/xilinx/src/phy_definitions.svh @@ -6,103 +6,69 @@ `ifdef TARGET_VCU128 `define USE_RESET - // 20 MHz clock wiz - `define USE_CLK_WIZ - // External jtag on gpios `define USE_JTAG `define USE_JTAG_VDDGND - // Reset VIO + `define USE_QSPI + `define USE_STARTUPE3 `define USE_VIO - // RAMs + `define HypNumChips 1 `define HypNumPhys 1 - `define HypNumChips 2 - //`USE_DDR4 - /* DRAM outputs aux clock at 200MHz */ - //`define DDR_CLK_DIVIDER 4'h4 + `ifdef NO_HYPERBUS + `define USE_DDR4 + `endif `endif `ifdef TARGET_GENESYS2 `define USE_RESETN - // 20 MHz clock wiz - `define USE_CLK_WIZ - // JTAG on fpga pins `define USE_JTAG `define USE_JTAG_TRSTN `define USE_SD - // Reset VIO - `define USE_VIO - // RAMs - `define USE_HYPERBUS - `define HYPERRAM_CLK_DIVIDER 4'h2 - `define HypNumPhys 1 - `define HypNumChips 2 - //`USE_DDR3 - /* DRAM runs at 200MHz */ - //`define DDR_CLK_DIVIDER 4'h4 + `define USE_SWITCHES + `define USE_DDR3 `define USE_FAN + `define USE_VIO `endif `ifdef TARGET_ZCU102 `define USE_RESET - `define USE_CLK_WIZ `define USE_JTAG - `define USE_HYPERBUS + `define USE_DDR4 + `define USE_QSPI + `define USE_STARTUPE3 `define USE_VIO - `define HYPERRAM_CLK_DIVIDER 4'h5 - `define HypNumPhys 1 - `define HypNumChips 2 - //`define USE_DDR4 - ///* DRAM runs at 100MHz */ - //`define DDR_CLK_DIVIDER 4'h2 `endif -// Common USE_DDR flag +///////////////////// +// DRAM INTERFACES // +///////////////////// `ifdef USE_DDR4 - `define USE_DDR +`define USE_DDR `endif `ifdef USE_DDR3 - `define USE_DDR +`define USE_DDR `endif -// DDR Phy interfaces - `define DDR4_INTF \ -`ifdef TARGET_VCU128 \ - /* Diff clock */ \ - input c0_sys_clk_p, \ - input c0_sys_clk_n, \ /* DDR4 intf */ \ + output c0_ddr4_reset_n, \ + output [0:0] c0_ddr4_ck_t, \ + output [0:0] c0_ddr4_ck_c, \ output c0_ddr4_act_n, \ output [16:0] c0_ddr4_adr, \ output [1:0] c0_ddr4_ba, \ output [0:0] c0_ddr4_bg, \ output [0:0] c0_ddr4_cke, \ output [0:0] c0_ddr4_odt, \ +`ifdef TARGET_VCU128 \ output [1:0] c0_ddr4_cs_n, \ - output [0:0] c0_ddr4_ck_t, \ - output [0:0] c0_ddr4_ck_c, \ - output c0_ddr4_reset_n, \ inout [8:0] c0_ddr4_dm_dbi_n, \ inout [71:0] c0_ddr4_dq, \ inout [8:0] c0_ddr4_dqs_c, \ inout [8:0] c0_ddr4_dqs_t, \ `endif \ `ifdef TARGET_ZCU102 \ - /* Diff clock */ \ - input c0_sys_clk_p, \ - input c0_sys_clk_n, \ - /* DDR4 intf */ \ - output c0_ddr4_act_n, \ - output [16:0] c0_ddr4_adr, \ - output [1:0] c0_ddr4_ba, \ - output [0:0] c0_ddr4_bg, \ - output [0:0] c0_ddr4_cke, \ - output [0:0] c0_ddr4_odt, \ output [0:0] c0_ddr4_cs_n, \ - output [0:0] c0_ddr4_ck_t, \ - output [0:0] c0_ddr4_ck_c, \ - output c0_ddr4_reset_n, \ inout [1:0] c0_ddr4_dm_dbi_n, \ inout [15:0] c0_ddr4_dq, \ inout [1:0] c0_ddr4_dqs_c, \ @@ -110,6 +76,8 @@ `endif `define DDR3_INTF \ + output ddr3_ck_p, \ + output ddr3_ck_n, \ inout [31:0] ddr3_dq, \ inout [3:0] ddr3_dqs_n, \ inout [3:0] ddr3_dqs_p, \ @@ -119,16 +87,10 @@ output ddr3_cas_n, \ output ddr3_we_n, \ output ddr3_reset_n, \ - output [0:0] ddr3_ck_p, \ - output [0:0] ddr3_ck_n, \ output [0:0] ddr3_cke, \ output [0:0] ddr3_cs_n, \ output [3:0] ddr3_dm, \ - output [0:0] ddr3_odt, \ - input sys_clk_p, \ - input sys_clk_n, - -// ILA Macro + output [0:0] ddr3_odt, `define ila(__name, __signal) \ (* dont_touch = "yes" *) (* mark_debug = "true" *) logic [$bits(__signal)-1:0] __name; \ diff --git a/target/xilinx/xilinx.mk b/target/xilinx/xilinx.mk index 4aec8c737..d6713568f 100644 --- a/target/xilinx/xilinx.mk +++ b/target/xilinx/xilinx.mk @@ -6,27 +6,21 @@ # Christopher Reinwardt # Cyril Koenig -PROJECT ?= carfield -# Board in {genesys2, zcu102, vcu128} -BOARD ?= vcu128 -ip-dir := $(CAR_XIL_DIR)/xilinx +PROJECT ?= carfield +# Board in {vcu128} +BOARD ?= vcu128 +ip-dir := $(CAR_XIL_DIR)/xilinx +USE_ARTIFACTS ?= 0 + # Select board specific variables ifeq ($(BOARD),vcu128) XILINX_PART ?= xcvu37p-fsvh2892-2L-e XILINX_BOARD ?= xilinx.com:vcu128:part0:1.0 - ips-names := xlnx_clk_wiz xlnx_vio -endif -ifeq ($(BOARD),genesys2) - XILINX_PART ?= xc7k325tffg900-2 - XILINX_BOARD ?= digilentinc.com:genesys2:part0:1.1 - ips-names := xlnx_mig_7_ddr3 xlnx_clk_wiz xlnx_vio - FPGA_PATH ?= xilinx_tcf/Digilent/200300A8C60DB -endif -ifeq ($(BOARD),zcu102) - XILINX_PART ?= xczu9eg-ffvb1156-2-e - XILINX_BOARD ?= xilinx.com:zcu102:part0:3.4 - ips-names := xlnx_mig_ddr4 xlnx_clk_wiz xlnx_vio + XILINX_PORT ?= 3232 + FPGA_PATH ?= xilinx_tcf/Xilinx/091847100638A + XILINX_HOST ?= bordcomputer + ips-names := xlnx_mig_ddr4 xlnx_clk_wiz xlnx_vio endif # Location of ip outputs @@ -48,11 +42,14 @@ VIVADOENV ?= PROJECT=$(PROJECT) \ PORT=$(XILINX_PORT) \ HOST=$(XILINX_HOST) \ FPGA_PATH=$(FPGA_PATH) \ - BIT=$(bit) -MODE ?= gui -VIVADOFLAGS ?= -nojournal -mode $(MODE) -source scripts/prologue.tcl + BIT=$(bit) \ + IP_PATHS="$(foreach ip-name,$(ips-names),xilinx/$(ip-name)/$(ip-name).srcs/sources_1/ip/$(ip-name)/$(ip-name).xci)" \ + ROUTED_DCP=$(ROUTED_DCP) \ + CHECK_TIMING=$(CHECK_TIMING) \ + ELABORATION_ONLY=$(ELABORATION_ONLY) -ELABORATION_ONLY ?= 0 +MODE ?= gui +VIVADOFLAGS ?= -nojournal -mode $(MODE) car-xil-all: $(bit) @@ -63,15 +60,17 @@ $(mcs): $(bit) # Compile bitstream $(bit): $(ips) $(CAR_XIL_DIR)/scripts/add_sources.tcl @mkdir -p $(out) - cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/run.tcl -tclargs $(ELABORATION_ONLY) - [ $(ELABORATION_ONLY) -eq 0 ] && cp $(CAR_XIL_DIR)/$(PROJECT).runs/impl_1/$(PROJECT)* $(out) + cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/prologue.tcl -source scripts/run.tcl + cp $(CAR_XIL_DIR)/$(PROJECT).runs/impl_1/*.bit $(out) + cp $(CAR_XIL_DIR)/$(PROJECT).runs/impl_1/*.ltx $(out) + cp $(CAR_XIL_DIR)/$(PROJECT).runs/impl_1/*_routed.dcp $(out) # Generate ips %.xci: @echo $@ @echo $(CAR_XIL_DIR) @echo "Generating IP $(basename $@)" - IP_NAME=$(basename $(notdir $@)) ; cd $(ip-dir)/$$IP_NAME && $(MAKE) clean && $(VIVADOENV) VIVADO="$(VIVADO)" $(MAKE) + IP_NAME=$(basename $(notdir $@)) ; cd $(ip-dir)/$$IP_NAME && make clean && USE_ARTIFACTS=$(USE_ARTIFACTS) VIVADOENV="$(subst ",\",$(VIVADOENV))" VIVADO="$(VIVADO)" make IP_NAME=$(basename $(notdir $@)) ; cp $(ip-dir)/$$IP_NAME/$$IP_NAME.srcs/sources_1/ip/$$IP_NAME/$$IP_NAME.xci $@ car-xil-gui: @@ -80,7 +79,10 @@ car-xil-gui: car-xil-program: #$(bit) @echo "Programming board $(BOARD) ($(XILINX_PART))" - cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/program.tcl + $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source $(CAR_XIL_DIR)/scripts/program.tcl + +car-xil-flash: $(CAR_SW_DIR)/boot/linux.gpt.bin + $(VIVADOENV) FILE=$< OFFSET=0 $(VIVADO) $(VIVADOFLAGS) -source $(CAR_XIL_DIR)/scripts/flash_spi.tcl car-xil-clean: cd $(CAR_XIL_DIR) && rm -rf scripts/add_sources.tcl* *.log *.jou *.str *.mif *.xci *.xpr .Xil/ $(out) $(PROJECT).srcs $(PROJECT).cache $(PROJECT).hw $(PROJECT).ioplanning $(PROJECT).ip_user_files $(PROJECT).runs $(PROJECT).sim diff --git a/target/xilinx/xilinx/common.mk b/target/xilinx/xilinx/common.mk index 457496ed9..0f14db964 100644 --- a/target/xilinx/xilinx/common.mk +++ b/target/xilinx/xilinx/common.mk @@ -9,11 +9,47 @@ else VIVADO ?= vivado endif +# Note: We do not use Memora as it is bound to Git versionning +# and not standalone on files hash / environment variables +ARTIFACTS_PATH=/usr/scratch2/wuerzburg/cykoenig/memora/carfield +GREEN='\033[0;32m' +NC='\033[0m' + all: - $(VIVADO) -mode batch -source tcl/run.tcl + +ifeq ($(USE_ARTIFACTS),1) +all: save-artifacts +else +all: $(PROJECT).xpr +endif + +# Build IP +$(PROJECT).xpr: + $(VIVADOENV) $(VIVADO) -mode batch -source tcl/run.tcl + +.PHONY: generate_sha256 load-artifacts + +# Generate a sha based on env variables and artifacts_in +generate_sha256: + @echo $(VIVADOENV) $(VIVADO) $(PROJECT) $(ARTIFACTS_IN) > .generated_env + @sha256sum $(ARTIFACTS_IN) >> .generated_env + @sha256sum .generated_env | awk '{print $$1}' > .generated_sha256 + +# Load artifacts based on .generated_sha256 +load-artifacts: .generated_sha256 + @if [ -d "$(ARTIFACTS_PATH)/`cat $<`" ]; then\ + echo -e $(GREEN)"Fetching $(PROJECT) from $(ARTIFACTS_PATH)/`cat $<`"$(NC); \ + cp -r $(ARTIFACTS_PATH)/`cat $<`/* .; \ + fi + +# Save artifacts (this folder) based on .generated_sha256 +save-artifacts: generate_sha256 load-artifacts $(PROJECT).xpr + @if [ ! -d "$(ARTIFACTS_PATH)/`cat .generated_sha256`" ]; then \ + cp -r . $(ARTIFACTS_PATH)/`cat .generated_sha256`; \ + fi gui: - $(VIVADO) -mode gui -source tcl/run.tcl & + $(VIVADOENV) $(VIVADO) -mode gui -source tcl/run.tcl & clean: rm -rf ip/* @@ -26,3 +62,4 @@ clean: rm -rf xgui rm -rf .Xil rm -rf tmp + rm -rf .generated* diff --git a/target/xilinx/xilinx/xlnx_clk_wiz/Makefile b/target/xilinx/xilinx/xlnx_clk_wiz/Makefile index 8fa393238..70060cea5 100644 --- a/target/xilinx/xilinx/xlnx_clk_wiz/Makefile +++ b/target/xilinx/xilinx/xlnx_clk_wiz/Makefile @@ -3,4 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 PROJECT:=xlnx_clk_wiz +ARTIFACTS_IN:=Makefile tcl/run.tcl + include ../common.mk \ No newline at end of file diff --git a/target/xilinx/xilinx/xlnx_clk_wiz/tcl/run.tcl b/target/xilinx/xilinx/xlnx_clk_wiz/tcl/run.tcl index b096046e4..7b734a1c0 100644 --- a/target/xilinx/xilinx/xlnx_clk_wiz/tcl/run.tcl +++ b/target/xilinx/xilinx/xlnx_clk_wiz/tcl/run.tcl @@ -2,6 +2,7 @@ # Solderpad Hardware License, Version 0.51, see LICENSE for details. # SPDX-License-Identifier: SHL-0.51 # +# Cyril Koenig set partNumber $::env(XILINX_PART) set boardName $::env(XILINX_BOARD) @@ -14,43 +15,94 @@ set_property board_part $boardName [current_project] create_ip -name clk_wiz -vendor xilinx.com -library ip -version 6.0 -module_name $ipName if {$::env(BOARD) eq "vcu128"} { - set_property -dict [list CONFIG.CLK_IN1_BOARD_INTERFACE {default_100mhz_clk} \ - CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {20.000} \ - CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} \ - CONFIG.MMCM_DIVCLK_DIVIDE {5} \ - CONFIG.MMCM_CLKFBOUT_MULT_F {52.375} \ - CONFIG.MMCM_CLKOUT0_DIVIDE_F {52.375} \ - CONFIG.CLKOUT1_JITTER {294.871} \ - CONFIG.CLKOUT1_PHASE_ERROR {297.237} + set_property -dict [list CONFIG.CLK_IN1_BOARD_INTERFACE {Custom} \ + CONFIG.RESET_BOARD_INTERFACE {Custom} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT4_USED {true} \ + CONFIG.CLK_OUT1_PORT {clk_100} \ + CONFIG.CLK_OUT2_PORT {clk_50} \ + CONFIG.CLK_OUT3_PORT {clk_20} \ + CONFIG.CLK_OUT4_PORT {clk_10} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {50.000} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20.000} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {10.000} \ + CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.USE_RESET {true} \ + CONFIG.MMCM_CLKOUT1_DIVIDE {24} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {60} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {120} \ + CONFIG.NUM_OUT_CLKS {4} \ + CONFIG.CLKOUT2_JITTER {132.683} \ + CONFIG.CLKOUT2_PHASE_ERROR {87.180} \ + CONFIG.CLKOUT3_JITTER {162.167} \ + CONFIG.CLKOUT3_PHASE_ERROR {87.180} \ + CONFIG.CLKOUT4_JITTER {188.586} \ + CONFIG.CLKOUT4_PHASE_ERROR {87.180} \ ] [get_ips $ipName] - } + if {$::env(BOARD) eq "zcu102"} { - set_property -dict [list CONFIG.CLK_IN1_BOARD_INTERFACE {user_si570_sysclk} \ - CONFIG.RESET_BOARD_INTERFACE {Custom} \ - CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50.000} \ - CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} \ + set_property -dict [list CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.PRIM_IN_FREQ {300.000} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT4_USED {true} \ + CONFIG.CLK_OUT1_PORT {clk_100} \ + CONFIG.CLK_OUT2_PORT {clk_50} \ + CONFIG.CLK_OUT3_PORT {clk_20} \ + CONFIG.CLK_OUT4_PORT {clk_10} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {50.000} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20.000} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {10.000} \ CONFIG.CLKIN1_JITTER_PS {33.330000000000005} \ CONFIG.MMCM_CLKFBOUT_MULT_F {4.000} \ CONFIG.MMCM_CLKIN1_PERIOD {3.333} \ CONFIG.MMCM_CLKIN2_PERIOD {10.0} \ - CONFIG.MMCM_CLKOUT0_DIVIDE_F {24.000} \ - CONFIG.CLKOUT1_JITTER {116.415} \ - CONFIG.CLKOUT1_PHASE_ERROR {77.836} + CONFIG.MMCM_CLKOUT1_DIVIDE {24} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {60} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {120} \ + CONFIG.NUM_OUT_CLKS {4} \ + CONFIG.CLKOUT1_JITTER {101.475} \ + CONFIG.CLKOUT1_PHASE_ERROR {77.836} \ + CONFIG.CLKOUT2_JITTER {116.415} \ + CONFIG.CLKOUT2_PHASE_ERROR {77.836} \ + CONFIG.CLKOUT3_JITTER {140.023} \ + CONFIG.CLKOUT3_PHASE_ERROR {77.836} \ + CONFIG.CLKOUT4_JITTER {160.570} \ + CONFIG.CLKOUT4_PHASE_ERROR {77.836} \ ] [get_ips $ipName] } + if {$::env(BOARD) eq "genesys2"} { - set_property -dict [list CONFIG.CLK_IN1_BOARD_INTERFACE {sys_diff_clock} \ - CONFIG.RESET_BOARD_INTERFACE {Custom} \ - CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {20.000} \ - CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} \ + set_property -dict [list CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT4_USED {true} \ + CONFIG.CLK_OUT1_PORT {clk_100} \ + CONFIG.CLK_OUT2_PORT {clk_50} \ + CONFIG.CLK_OUT3_PORT {clk_20} \ + CONFIG.CLK_OUT4_PORT {clk_10} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {50.000} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20.000} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {10.000} \ CONFIG.CLKIN1_JITTER_PS {50.0} \ - CONFIG.MMCM_CLKFBOUT_MULT_F {4.250} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {5.000} \ CONFIG.MMCM_CLKIN1_PERIOD {5.000} \ CONFIG.MMCM_CLKIN2_PERIOD {10.0} \ - CONFIG.MMCM_CLKOUT0_DIVIDE_F {42.500} \ - CONFIG.CLKOUT1_JITTER {155.788} \ - CONFIG.CLKOUT1_PHASE_ERROR {94.329} + CONFIG.MMCM_CLKOUT1_DIVIDE {20} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {50} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {100} \ + CONFIG.NUM_OUT_CLKS {4} \ + CONFIG.CLKOUT1_JITTER {112.316} \ + CONFIG.CLKOUT1_PHASE_ERROR {89.971} \ + CONFIG.CLKOUT2_JITTER {129.198} \ + CONFIG.CLKOUT2_PHASE_ERROR {89.971} \ + CONFIG.CLKOUT3_JITTER {155.330} \ + CONFIG.CLKOUT3_PHASE_ERROR {89.971} \ + CONFIG.CLKOUT4_JITTER {178.053} \ + CONFIG.CLKOUT4_PHASE_ERROR {89.971} \ ] [get_ips $ipName] } diff --git a/target/xilinx/xilinx/xlnx_mig_7_ddr3/Makefile b/target/xilinx/xilinx/xlnx_mig_7_ddr3/Makefile deleted file mode 100644 index 68d05f97e..000000000 --- a/target/xilinx/xilinx/xlnx_mig_7_ddr3/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright 2022 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -PROJECT:=xlnx_mig_7_ddr3 -include ../common.mk diff --git a/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_genesys2.prj b/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_genesys2.prj deleted file mode 100755 index eca037822..000000000 --- a/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_genesys2.prj +++ /dev/null @@ -1,160 +0,0 @@ - - - - xlnx_mig_7_ddr3 - 1 - 1 - OFF - 1024 - ON - Enabled - xc7k325t-ffg900/-2 - 4.1 - Differential - Use System Clock - ACTIVE LOW - FALSE - 0 - 50 Ohms - 0 - - DDR3_SDRAM/Components/MT41J256m16XX-107 - 1250 - 2.0V - 4:1 - 200 - 0 - 800 - 1.000 - 1 - 1 - 1 - 1 - 32 - 1 - 1 - Disabled - Normal - 4 - FALSE - - 15 - 10 - 3 - 1.5V - BANK_ROW_COLUMN - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8 - Fixed - Sequential - 11 - Normal - No - Slow Exit - Enable - RZQ/7 - Disable - Enable - RZQ/6 - 0 - Disabled - Enabled - Output Buffer Enabled - Full Array - 8 - Enabled - Normal - Dynamic ODT off - AXI - - RD_PRI_REG - 30 - 64 - 6 - 0 - - - - diff --git a/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_kc705.prj b/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_kc705.prj deleted file mode 100644 index a523f9730..000000000 --- a/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_kc705.prj +++ /dev/null @@ -1,200 +0,0 @@ - - - - xlnx_mig_7_ddr3 - 1 - 1 - OFF - 1024 - ON - Enabled - xc7k325t-ffg900/-2 - 4.1 - Differential - Use System Clock - ACTIVE LOW - FALSE - 0 - 50 Ohms - 1 - - DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 - 1250 - 2.0V - 4:1 - 200 - 0 - 800 - 16 - 1 - 1 - 1 - 1 - 64 - 1 - 1 - Disabled - Normal - 4 - FALSE - - 14 - 10 - 3 - 1.5V - BANK_ROW_COLUMN - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8 - Fixed - Sequential - 11 - Normal - No - Slow Exit - Enable - RZQ/7 - Disable - Enable - RZQ/6 - 0 - Disabled - Enabled - Output Buffer Enabled - Full Array - 8 - Enabled - Normal - Dynamic ODT off - AXI - - RD_PRI_REG - 30 - 64 - 4 - 0 - - - - diff --git a/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_vc707.prj b/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_vc707.prj deleted file mode 100644 index fcf0bbe95..000000000 --- a/target/xilinx/xilinx/xlnx_mig_7_ddr3/mig_vc707.prj +++ /dev/null @@ -1,203 +0,0 @@ - - - - xlnx_mig_7_ddr3 - 1 - 1 - OFF - 1024 - ON - Enabled - xc7vx485t-ffg1761/-2 - 4.1 - Differential - Use System Clock - ACTIVE LOW - FALSE - 0 - 50 Ohms - 0 - - DDR3_SDRAM/SODIMMs/MT8JTF12864HZ-1G6 - 1250 - 2.0V - 4:1 - 200 - 0 - 800 - 1.000 - 1 - 1 - 1 - 1 - 64 - 1 - 1 - Disabled - Normal - 4 - FALSE - - 14 - 10 - 3 - 1.5V - BANK_ROW_COLUMN - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8 - Fixed - Sequential - 11 - Normal - No - Slow Exit - Enable - RZQ/7 - Disable - Enable - RZQ/6 - 0 - Disabled - Enabled - Output Buffer Enabled - Full Array - 8 - Enabled - Normal - Dynamic ODT off - AXI - - RD_PRI_REG - 30 - 64 - 5 - 0 - - - - diff --git a/target/xilinx/xilinx/xlnx_mig_7_ddr3/tcl/run.tcl b/target/xilinx/xilinx/xlnx_mig_7_ddr3/tcl/run.tcl deleted file mode 100644 index 9fc5f5cd1..000000000 --- a/target/xilinx/xilinx/xlnx_mig_7_ddr3/tcl/run.tcl +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2018 ETH Zurich and University of Bologna. -# Solderpad Hardware License, Version 0.51, see LICENSE for details. -# SPDX-License-Identifier: SHL-0.51 -# -# Author: Florian Zaruba - -set partNumber $::env(XILINX_PART) -set boardName $::env(XILINX_BOARD) -set boardNameShort $::env(BOARD) - -set ipName xlnx_mig_7_ddr3 - -create_project $ipName . -force -part $partNumber -set_property board_part $boardName [current_project] - -create_ip -name mig_7series -vendor xilinx.com -library ip -module_name $ipName - -exec cp mig_$boardNameShort.prj ./$ipName.srcs/sources_1/ip/$ipName/mig_a.prj - -set_property -dict [list CONFIG.XML_INPUT_FILE {mig_a.prj} CONFIG.RESET_BOARD_INTERFACE {Custom} CONFIG.MIG_DONT_TOUCH_PARAM {Custom} CONFIG.BOARD_MIG_PARAM {Custom}] [get_ips $ipName] - -generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] -generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] -create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] -launch_run -jobs 8 ${ipName}_synth_1 -wait_on_run ${ipName}_synth_1 diff --git a/target/xilinx/xilinx/xlnx_mig_ddr4/Makefile b/target/xilinx/xilinx/xlnx_mig_ddr4/Makefile index 5624b3bf4..5bd52cca7 100644 --- a/target/xilinx/xilinx/xlnx_mig_ddr4/Makefile +++ b/target/xilinx/xilinx/xlnx_mig_ddr4/Makefile @@ -3,4 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 PROJECT:=xlnx_mig_ddr4 +ARTIFACTS_IN:=Makefile tcl/run.tcl + include ../common.mk diff --git a/target/xilinx/xilinx/xlnx_mig_ddr4/tcl/run.tcl b/target/xilinx/xilinx/xlnx_mig_ddr4/tcl/run.tcl index adefb7e8e..8a05eb8cd 100644 --- a/target/xilinx/xilinx/xlnx_mig_ddr4/tcl/run.tcl +++ b/target/xilinx/xilinx/xlnx_mig_ddr4/tcl/run.tcl @@ -14,28 +14,29 @@ set_property board_part $boardName [current_project] create_ip -name ddr4 -vendor xilinx.com -library ip -version 2.2 -module_name $ipName + if {$::env(BOARD) eq "vcu128"} { - set_property -dict [list CONFIG.RESET_BOARD_INTERFACE {Custom} \ - CONFIG.C0_CLOCK_BOARD_INTERFACE {default_100mhz_clk} \ - CONFIG.C0.DDR4_Clamshell {true} \ + set_property -dict [list CONFIG.C0.DDR4_Clamshell {true} \ CONFIG.C0_DDR4_BOARD_INTERFACE {ddr4_sdram} \ + CONFIG.System_Clock {No_Buffer} \ + CONFIG.Reference_Clock {No_Buffer} \ CONFIG.C0.DDR4_InputClockPeriod {10000} \ CONFIG.C0.DDR4_CLKOUT0_DIVIDE {3} \ CONFIG.C0.DDR4_MemoryPart {MT40A512M16HA-075E} \ CONFIG.C0.DDR4_DataWidth {72} \ CONFIG.C0.DDR4_DataMask {NO_DM_NO_DBI} \ CONFIG.C0.DDR4_Ecc {true} \ - CONFIG.C0.DDR4_AxiSelection {true} \ CONFIG.C0.DDR4_AxiDataWidth {512} \ CONFIG.C0.DDR4_AxiAddressWidth {32} \ - CONFIG.ADDN_UI_CLKOUT1_FREQ_HZ {200} \ + CONFIG.C0.DDR4_AxiIDWidth {8} \ + CONFIG.ADDN_UI_CLKOUT1_FREQ_HZ {100} \ CONFIG.C0.BANK_GROUP_WIDTH {1} \ CONFIG.C0.CS_WIDTH {2} \ + CONFIG.C0.DDR4_AxiSelection {true} \ ] [get_ips $ipName] + } elseif {$::env(BOARD) eq "zcu102"} { - set_property -dict [list CONFIG.RESET_BOARD_INTERFACE {reset} \ - CONFIG.C0_CLOCK_BOARD_INTERFACE {user_si570_sysclk} \ - CONFIG.C0_DDR4_BOARD_INTERFACE {ddr4_sdram_062} \ + set_property -dict [list CONFIG.C0_DDR4_BOARD_INTERFACE {ddr4_sdram_062} \ CONFIG.C0.DDR4_TimePeriod {833} \ CONFIG.C0.DDR4_InputClockPeriod {3332} \ CONFIG.C0.DDR4_CLKOUT0_DIVIDE {5} \ @@ -44,13 +45,15 @@ if {$::env(BOARD) eq "vcu128"} { CONFIG.C0.DDR4_CasWriteLatency {12} \ CONFIG.C0.DDR4_AxiDataWidth {128} \ CONFIG.C0.DDR4_AxiAddressWidth {29} \ + CONFIG.C0.DDR4_AxiIDWidth {8} \ CONFIG.ADDN_UI_CLKOUT1_FREQ_HZ {100} \ + CONFIG.System_Clock {No_Buffer} \ + CONFIG.Reference_Clock {No_Buffer} \ CONFIG.C0.BANK_GROUP_WIDTH {1} \ CONFIG.C0.DDR4_AxiSelection {true} \ ] [get_ips $ipName] } -puts "END" generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] diff --git a/target/xilinx/xilinx/xlnx_protocol_checker/Makefile b/target/xilinx/xilinx/xlnx_protocol_checker/Makefile deleted file mode 100644 index f67c6a7b6..000000000 --- a/target/xilinx/xilinx/xlnx_protocol_checker/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright 2022 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -PROJECT:=xlnx_protocol_checker -include ../common.mk \ No newline at end of file diff --git a/target/xilinx/xilinx/xlnx_protocol_checker/tcl/run.tcl b/target/xilinx/xilinx/xlnx_protocol_checker/tcl/run.tcl deleted file mode 100644 index 1b2d302c0..000000000 --- a/target/xilinx/xilinx/xlnx_protocol_checker/tcl/run.tcl +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2018 ETH Zurich and University of Bologna. -# Solderpad Hardware License, Version 0.51, see LICENSE for details. -# SPDX-License-Identifier: SHL-0.51 -# - -set partNumber $::env(XILINX_PART) -set boardName $::env(XILINX_BOARD) - -set ipName xlnx_protocol_checker - -create_project $ipName . -force -part $partNumber -set_property board_part $boardName [current_project] - -create_ip -name axi_protocol_checker -vendor xilinx.com -library ip -version 2.0 -module_name $ipName - -set_property -dict [list CONFIG.ADDR_WIDTH {48} \ - CONFIG.DATA_WIDTH {64} \ - CONFIG.ID_WIDTH {6} \ - CONFIG.AWUSER_WIDTH {1} \ - CONFIG.ARUSER_WIDTH {1} \ - CONFIG.RUSER_WIDTH {1} \ - CONFIG.WUSER_WIDTH {1} \ - CONFIG.BUSER_WIDTH {1} \ - CONFIG.MAX_AW_WAITS {1024} \ - CONFIG.MAX_AR_WAITS {1024} \ - CONFIG.MAX_W_WAITS {1024} \ - CONFIG.MAX_R_WAITS {1024} \ - CONFIG.MAX_B_WAITS {1024} \ - CONFIG.MAX_CONTINUOUS_WTRANSFERS_WAITS {1024} \ - CONFIG.MAX_WLAST_TO_AWVALID_WAITS {1024} \ - CONFIG.MAX_WRITE_TO_BVALID_WAITS {1024} \ - CONFIG.MAX_CONTINUOUS_RTRANSFERS_WAITS {1024} \ - ] [get_ips $ipName] - - -generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] -generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] -create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] -launch_run -jobs 8 ${ipName}_synth_1 -wait_on_run ${ipName}_synth_1 diff --git a/target/xilinx/xilinx/xlnx_vio/Makefile b/target/xilinx/xilinx/xlnx_vio/Makefile index 70dcc3263..17949698b 100644 --- a/target/xilinx/xilinx/xlnx_vio/Makefile +++ b/target/xilinx/xilinx/xlnx_vio/Makefile @@ -3,4 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 PROJECT:=xlnx_vio +ARTIFACTS_IN:=Makefile tcl/run.tcl + include ../common.mk diff --git a/target/xilinx/xilinx/xlnx_vio/tcl/run.tcl b/target/xilinx/xilinx/xlnx_vio/tcl/run.tcl index a36e9408a..566fd2313 100644 --- a/target/xilinx/xilinx/xlnx_vio/tcl/run.tcl +++ b/target/xilinx/xilinx/xlnx_vio/tcl/run.tcl @@ -14,7 +14,9 @@ set_property board_part $boardName [current_project] create_ip -name vio -vendor xilinx.com -library ip -version 3.0 -module_name $ipName set_property -dict [list CONFIG.C_NUM_PROBE_OUT {3} \ - CONFIG.C_PROBE_OUT1_INIT_VAL {0x0} \ + CONFIG.C_PROBE_OUT0_INIT_VAL {0x0} \ + CONFIG.C_PROBE_OUT0_WIDTH {1} \ + CONFIG.C_PROBE_OUT1_INIT_VAL {0x2} \ CONFIG.C_PROBE_OUT1_WIDTH {2} \ CONFIG.C_PROBE_OUT2_INIT_VAL {0x1} \ CONFIG.C_PROBE_OUT2_WIDTH {2} \