diff --git a/Bender.lock b/Bender.lock index ea2484442..4a1c744bd 100644 --- a/Bender.lock +++ b/Bender.lock @@ -233,7 +233,7 @@ packages: dependencies: - common_cells fpu_interco: - revision: 0769976fa51bdd820656a01161a4c46b88c59ac5 + revision: c985d54c2b078ddfbec8c2a498f453410bbdc93e version: null source: Git: https://github.com/pulp-platform/fpu_interco.git @@ -371,7 +371,7 @@ packages: dependencies: - axi_slice pulp_cluster: - revision: a746000f9dc9965e1351186905b59bca36edef57 + revision: 314f9a04f8dad4a5eeb0b9e8ad84898c6dc3f81e version: null source: Git: https://github.com/pulp-platform/pulp_cluster.git @@ -433,7 +433,7 @@ packages: - common_cells - common_verification riscv: - revision: 4eac53237c6d0062715d17016fe95462eb81ebc3 + revision: 6187537f9994d16bad2d721c0f5ebc5193c0f010 version: null source: Git: git@github.com:AlSaqr-platform/riscv_nn.git diff --git a/Bender.yml b/Bender.yml index 3044307a1..255ca2bcd 100644 --- a/Bender.yml +++ b/Bender.yml @@ -16,7 +16,7 @@ dependencies: hyperbus: { git: https://github.com/pulp-platform/hyperbus.git, rev: 2adb7271438cdb96c19fbaf3e2a6bf89ffeee568 } # branch: lv/phys_in_use car_l2: { git: git@iis-git.ee.ethz.ch:carfield/carfield_l2_mem.git, rev: 08503a05307ef556ed5439619c70c039ff93d77a } # branch: main safety_island: { git: git@iis-git.ee.ethz.ch:carfield/safety-island.git, rev: 60e768a3ef29f47339e31674d497293f5a768893 } # branch: atops - pulp_cluster: { git: https://github.com/pulp-platform/pulp_cluster.git, rev: a746000f9dc9965e1351186905b59bca36edef57 } # branch: yt/carfield-integration + pulp_cluster: { git: https://github.com/pulp-platform/pulp_cluster.git, rev: 314f9a04f8dad4a5eeb0b9e8ad84898c6dc3f81e } # branch: yt/carfield-integration opentitan: { git: https://github.com/alsaqr-platform/opentitan.git, rev: cce5a6e0bacba31374109969adcd7abb0f70f7ec } # branch: yt/hartid mailbox_unit: { git: git@github.com:pulp-platform/mailbox_unit.git, version: 1.1.0 } apb: { git: https://github.com/pulp-platform/apb.git, version: 0.2.3 } @@ -69,11 +69,7 @@ sources: - target/xilinx/src/carfield_top_xilinx.sv - target/xilinx/src/dram_wrapper.sv # Override certain files due to vivado related errors - - target/xilinx/src/overrides/cv32e40p_fpu_wrap.sv - - target/xilinx/src/overrides/fpnew_wrapper.sv - target/xilinx/src/overrides/tc_clk_xilinx.sv - - target/xilinx/src/overrides/tc_sram_xilinx.sv - - target/xilinx/src/overrides/riscv_ex_stage.sv vendor_package: - name: reggen diff --git a/bender-xilinx.mk b/bender-xilinx.mk new file mode 100644 index 000000000..33e59a4f1 --- /dev/null +++ b/bender-xilinx.mk @@ -0,0 +1,25 @@ +# Copyright 2021 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 +# +# Author: Cyril Koenig + +# bender targets +xilinx_targs += -t fpga + +# bender defines +xilinx_defs += -D PULP_FPGA_EMUL + +# Conditionally add GEN_{island} to bender define +define check_enable_island +ifeq ($($(1)),1) +xilinx_defs += -D$(1)=1 +endif +endef + +$(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)) + +# note : bender targets are later modified in xilinx.mk diff --git a/carfield.mk b/carfield.mk index 0d56818b9..d95211d42 100644 --- a/carfield.mk +++ b/carfield.mk @@ -9,10 +9,12 @@ CAR_ROOT ?= . CHS_ROOT ?= $(CAR_ROOT)/cheshire CAR_SW_DIR := $(CAR_ROOT)/sw +CAR_XIL_DIR := $(CAR_ROOT)/target/xilinx # Bender BENDER ?= bender QUESTA ?= questa-2022.3 +VIVADO ?= vitis-2020.2 vivado TBENCH ?= tb_carfield_soc BOOTMODE ?= 0 # default passive bootmode PRELMODE ?= 1 # default serial link preload @@ -43,6 +45,10 @@ CHS_IMAGE ?= # (the following includes are mandatory) include $(CAR_ROOT)/bender-common.mk include $(CAR_ROOT)/bender-synth.mk +include $(CAR_ROOT)/bender-xilinx.mk + +print_stuff: + echo $(xilinx_defs) # Setup Virtual Environment for python scripts (reggen) VENVDIR?=$(WORKDIR)/.venv @@ -235,6 +241,16 @@ SPYGLASS_DEFS += $(synth_defs) lint: $(MAKE) -C scripts lint bender_defs="$(SPYGLASS_DEFS)" bender_targs="$(SPYGLASS_TARGS)" > make.log +############# +# Emulation # +############# + +include $(CAR_XIL_DIR)/xilinx.mk + +######## +# Help # +######## + # Setup Autodocumentation of the Makefile HELP_TITLE="Carfield Open-Source RTL" HELP_DESCRIPTION="Hardware generation and simulation targets for Carfield" diff --git a/target/xilinx/scripts/overrides.sh b/target/xilinx/scripts/overrides.sh index b9185136b..c2d734488 100755 --- a/target/xilinx/scripts/overrides.sh +++ b/target/xilinx/scripts/overrides.sh @@ -1,4 +1,9 @@ #!/bin/bash +# 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 +# +# Cyril Koenig # Replace files in a bender script with override version diff --git a/target/xilinx/src/overrides/cv32e40p_fpu_wrap.sv b/target/xilinx/src/overrides/cv32e40p_fpu_wrap.sv deleted file mode 100644 index 244262140..000000000 --- a/target/xilinx/src/overrides/cv32e40p_fpu_wrap.sv +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2018 ETH Zurich and University of Bologna. -// Copyright and related rights are licensed under the Solderpad Hardware -// License, Version 0.51 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law -// or agreed to in writing, software, hardware and materials distributed under -// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -// Wrapper for a fpnew -// Contributor: Davide Schiavone - -module cv32e40p_fpu_wrap import cv32e40p_apu_core_pkg::*; #( - parameter FP_DIVSQRT = 0 -) -( - // Clock and Reset - input logic clk_i, - input logic rst_ni, - - input logic flush_i, - - // APU Side: Master port - input logic apu_req_i, - output logic apu_gnt_o, - - // request channel - input logic [APU_NARGS_CPU-1:0][31:0] apu_operands_i, - input logic [APU_WOP_CPU-1:0] apu_op_i, - input logic [APU_NDSFLAGS_CPU-1:0] apu_flags_i, - - // response channel - output logic apu_rvalid_o, - output logic [31:0] apu_rdata_o, - output logic [APU_NUSFLAGS_CPU-1:0] apu_rflags_o -); - - -import cv32e40p_pkg::*; -import fpnew_pkg::*; - -logic [fpnew_pkg::OP_BITS-1:0] fpu_op; -logic fpu_op_mod; -logic fpu_vec_op; - -logic [fpnew_pkg::FP_FORMAT_BITS-1:0] fpu_dst_fmt; -logic [fpnew_pkg::FP_FORMAT_BITS-1:0] fpu_src_fmt; -logic [fpnew_pkg::INT_FORMAT_BITS-1:0] fpu_int_fmt; -logic [C_RM-1:0] fp_rnd_mode; - - - -// assign apu_rID_o = '0; -assign {fpu_vec_op, fpu_op_mod, fpu_op} = apu_op_i; - -assign {fpu_int_fmt, fpu_src_fmt, fpu_dst_fmt, fp_rnd_mode} = apu_flags_i; - -localparam fpnew_pkg::unit_type_t C_DIV = FP_DIVSQRT ? fpnew_pkg::MERGED : fpnew_pkg::DISABLED; - -// ----------- -// FPU Config -// ----------- -// Features (enabled formats, vectors etc.) -localparam fpnew_pkg::fpu_features_t FPU_FEATURES = '{ - Width: C_FLEN, - EnableVectors: C_XFVEC, - EnableNanBox: 1'b0, - FpFmtMask: {C_RVF, C_RVD, C_XF16, C_XF8, C_XF16ALT, C_XF8ALT}, - IntFmtMask: {C_XFVEC && (C_XF8 || C_XF8ALT), C_XFVEC && (C_XF16 || C_XF16ALT), 1'b1, 1'b0} -}; - -// Implementation (number of registers etc) -localparam fpnew_pkg::fpu_implementation_t FPU_IMPLEMENTATION = '{ - PipeRegs: '{// FP32, FP64, FP16, FP8, FP16alt - '{C_LAT_FP32, C_LAT_FP64, C_LAT_FP16, C_LAT_FP8, C_LAT_FP16ALT, C_LAT_FP8ALT}, // ADDMUL - '{default: C_LAT_DIVSQRT}, // DIVSQRT - '{default: C_LAT_NONCOMP}, // NONCOMP - '{default: C_LAT_CONV}, // CONV - '{default: C_LAT_DOTP}}, // DOTP - UnitTypes: '{'{default: fpnew_pkg::MERGED}, // ADDMUL - '{default: C_DIV}, // DIVSQRT - '{default: fpnew_pkg::PARALLEL}, // NONCOMP - '{default: fpnew_pkg::MERGED}, // CONV - '{default: fpnew_pkg::DISABLED}}, // DOTP - PipeConfig: fpnew_pkg::AFTER -}; - -//--------------- -// FPU instance -//--------------- - -fpnew_top #( - .Features ( FPU_FEATURES ), - .Implementation ( FPU_IMPLEMENTATION ), - .TagType ( logic ), - .PulpDivsqrt ( 1'b1 ), - .TrueSIMDClass ( 1'b0 ), - .EnableSIMDMask ( 1'b0 ), - .CompressedVecCmpResult ( 1'b0 ), - .StochasticRndImplementation ( fpnew_pkg::DEFAULT_NO_RSR ) -) i_fpnew_bulk ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .hart_id_i ( '0 ), - .operands_i ( apu_operands_i ), - .rnd_mode_i ( fpnew_pkg::roundmode_e'(fp_rnd_mode) ), - .op_i ( fpnew_pkg::operation_e'(fpu_op) ), - .op_mod_i ( fpu_op_mod ), - .src_fmt_i ( fpnew_pkg::fp_format_e'(fpu_src_fmt) ), - .dst_fmt_i ( fpnew_pkg::fp_format_e'(fpu_dst_fmt) ), - .int_fmt_i ( fpnew_pkg::int_format_e'(fpu_int_fmt) ), - .vectorial_op_i ( fpu_vec_op ), - .tag_i ( 1'b0 ), - .simd_mask_i ( '1 ), - .in_valid_i ( apu_req_i ), - .in_ready_o ( apu_gnt_o ), - .flush_i ( flush_i ), - .result_o ( apu_rdata_o ), - .status_o ( apu_rflags_o ), - .tag_o ( /* unused */ ), - .out_valid_o ( apu_rvalid_o ), - .out_ready_i ( 1'b1 ), - .busy_o ( /* unused */ ) -); - -endmodule // cv32e40p_fp_wrapper diff --git a/target/xilinx/src/overrides/fpnew_wrapper.sv b/target/xilinx/src/overrides/fpnew_wrapper.sv deleted file mode 100644 index 10b3af6de..000000000 --- a/target/xilinx/src/overrides/fpnew_wrapper.sv +++ /dev/null @@ -1,182 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// // -// Copyright 2018 ETH Zurich and University of Bologna. // -// Copyright and related rights are licensed under the Solderpad Hardware // -// License, Version 0.51 (the "License"); you may not use this file except in // -// compliance with the License. You may obtain a copy of the License at // -// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law // -// or agreed to in writing, software, hardware and materials distributed under// -// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // -// CONDITIONS OF ANY KIND, either express or implied. See the License for the // -// specific language governing permissions and limitations under the License. // -// // -// Company: Micrel Lab @ DEIS - University of Bologna // -// Viale Risorgimento 2 40136 // -// Bologna - fax 0512093785 - // -// // -// Engineer: Igor Loi - igor.loi@unibo.it // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 19/01/2019 // -// Design Name: FPU_INTERCONNECT // -// Module Name: fpnew_wrapper // -// Project Name: VEGA // -// Language: SystemVerilog // -// // -// Description: wrapper for fpnew system verilog block // -// // -// // -// // -// Revision: // -// Revision v0.1 - 19/01/2019 : File Created // -// // -// Additional Comments: // -// // -// // -// // -// // -//////////////////////////////////////////////////////////////////////////////// - - - -import cv32e40p_pkg::*; -// `define DUMMY_FPNEW - -module fpnew_wrapper -#( - parameter ID_WIDTH = 9, - parameter NB_ARGS = 2, - parameter OPCODE_WIDTH = 6, - parameter DATA_WIDTH = 32, - parameter FLAGS_IN_WIDTH = 15, - parameter FLAGS_OUT_WIDTH = 5, - parameter C_FPNEW_FMTBITS = fpnew_pkg::FP_FORMAT_BITS, - parameter C_FPNEW_IFMTBITS = fpnew_pkg::INT_FORMAT_BITS, - parameter C_ROUND_BITS = 3, - parameter C_FPNEW_OPBITS = fpnew_pkg::OP_BITS, - parameter FP_DIVSQRT = 0 -) -( - // Clock and Reset - input logic clk, - input logic rst_n, - - // APU Side: Master port - input logic apu_req_i, - output logic apu_gnt_o, - input logic [ID_WIDTH-1:0] apu_ID_i, // not used - - // request channel - input logic [NB_ARGS-1:0][DATA_WIDTH-1:0] apu_operands_i, - input logic [OPCODE_WIDTH-1:0] apu_op_i, - input logic [FLAGS_IN_WIDTH-1:0] apu_flags_i, - - // response channel - input logic apu_rready_i, // not used - output logic apu_rvalid_o, - output logic [DATA_WIDTH-1:0] apu_rdata_o, - output logic [FLAGS_OUT_WIDTH-1:0] apu_rflags_o, - output logic [ID_WIDTH-1:0] apu_rID_o // not used -); - - `ifdef DUMMY_FPNEW - always_ff @(posedge clk or negedge rst_n) - begin : proc_ - if(~rst_n) begin - apu_gnt_o = '0; - apu_rvalid_o = '0; - apu_rdata_o = '0; - apu_rflags_o = '0; - apu_rID_o = '0; - end else begin - apu_gnt_o = 1'b1; - apu_rvalid_o = (apu_gnt_o & apu_req_i); - apu_rdata_o = 32'hC1A0C1A0; - apu_rflags_o = '1; - apu_rID_o = apu_ID_i; - end - end - `else - - localparam fpnew_pkg::unit_type_t C_DIV = FP_DIVSQRT ? fpnew_pkg::MERGED : fpnew_pkg::DISABLED; - - logic [C_FPNEW_OPBITS-1:0] fpu_op; - logic fpu_op_mod; - logic fpu_vec_op; - - logic [C_FPNEW_FMTBITS-1:0] dst_fmt; - logic [C_FPNEW_FMTBITS-1:0] src_fmt; - logic [C_FPNEW_IFMTBITS-1:0] int_fmt; - logic [C_ROUND_BITS-1:0] fp_rnd_mode; - - // assign apu_rID_o = '0; - assign {fpu_vec_op, fpu_op_mod, fpu_op} = apu_op_i; - assign {int_fmt, src_fmt, dst_fmt, fp_rnd_mode} = apu_flags_i; - - - // ----------- - // FPU Config - // ----------- - // Features (enabled formats, vectors etc.) - localparam fpnew_pkg::fpu_features_t FPU_FEATURES = '{ - Width: C_FLEN, - EnableVectors: C_XFVEC, - EnableNanBox: 1'b0, - FpFmtMask: {C_RVF, C_RVD, C_XF16, C_XF8, C_XF16ALT, C_XF8ALT}, - IntFmtMask: {C_XFVEC && (C_XF8 || C_XF8ALT), C_XFVEC && (C_XF16 || C_XF16ALT), 1'b1, 1'b0} - }; - - // Implementation (number of registers etc) - localparam fpnew_pkg::fpu_implementation_t FPU_IMPLEMENTATION = '{ - PipeRegs: '{// FP32, FP64, FP16, FP8, FP16alt - '{C_LAT_FP32, C_LAT_FP64, C_LAT_FP16, C_LAT_FP8, C_LAT_FP16ALT, C_LAT_FP8ALT}, // ADDMUL - '{default: C_LAT_DIVSQRT}, // DIVSQRT - '{default: C_LAT_NONCOMP}, // NONCOMP - '{default: C_LAT_CONV}, // CONV - '{default: C_LAT_DOTP}}, // SDOTP - UnitTypes: '{'{default: fpnew_pkg::MERGED}, // ADDMUL - '{default: C_DIV}, // DIVSQRT - '{default: fpnew_pkg::PARALLEL}, // NONCOMP - '{default: fpnew_pkg::MERGED}, // CONV - '{default: fpnew_pkg::DISABLED}}, // SDOTP - PipeConfig: fpnew_pkg::BEFORE - }; - - //--------------- - // FPU instance - //--------------- - fpnew_top #( - .Features ( FPU_FEATURES ), - .Implementation ( FPU_IMPLEMENTATION ), - .TagType ( logic [ID_WIDTH-1:0] ) - ) i_fpnew ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .hart_id_i ( '0 ), - .operands_i ( apu_operands_i ), - .rnd_mode_i ( fpnew_pkg::roundmode_e'(fp_rnd_mode) ), - .op_i ( fpnew_pkg::operation_e'(fpu_op) ), - .op_mod_i ( fpu_op_mod ), - .src_fmt_i ( fpnew_pkg::fp_format_e'(src_fmt) ), - .dst_fmt_i ( fpnew_pkg::fp_format_e'(dst_fmt) ), - .int_fmt_i ( fpnew_pkg::int_format_e'(int_fmt) ), - .vectorial_op_i ( fpu_vec_op ), - .tag_i ( apu_ID_i ), - .simd_mask_i ( '1 ), - .in_valid_i ( apu_req_i ), - .in_ready_o ( apu_gnt_o ), - .flush_i ( 1'b0 ), - .result_o ( apu_rdata_o ), - .status_o ( apu_rflags_o ), - .tag_o ( apu_rID_o ), - .out_valid_o ( apu_rvalid_o ), - .out_ready_i ( 1'b1 ), - .busy_o ( /* unused */ ) - ); - - - `endif -endmodule // fpnew_wrapper diff --git a/target/xilinx/src/overrides/include/prim_assert.sv b/target/xilinx/src/overrides/include/prim_assert.sv deleted file mode 100644 index c3a95e2fb..000000000 --- a/target/xilinx/src/overrides/include/prim_assert.sv +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Macros and helper code for using assertions. -// - Provides default clk and rst options to simplify code -// - Provides boiler plate template for common assertions - -`ifndef OT_PRIM_ASSERT_SV -`define OT_PRIM_ASSERT_SV - -/////////////////// -// Helper macros // -/////////////////// - -// Default clk and reset signals used by assertion macros below. -`define ASSERT_DEFAULT_CLK clk_i -`define ASSERT_DEFAULT_RST !rst_ni - -// Converts an arbitrary block of code into a Verilog string -`define PRIM_STRINGIFY(__x) `"__x`" - -// ASSERT_ERROR logs an error message with either `uvm_error or with $error. -// -// This somewhat duplicates `DV_ERROR macro defined in hw/dv/sv/dv_utils/dv_macros.svh. The reason -// for redefining it here is to avoid creating a dependency. -`define ASSERT_ERROR(__name) \ -`ifdef UVM \ - uvm_pkg::uvm_report_error("ASSERT FAILED", `PRIM_STRINGIFY(__name), uvm_pkg::UVM_NONE, \ - `__FILE__, `__LINE__, "", 1); \ -`else \ - $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, \ - `PRIM_STRINGIFY(__name)); \ -`endif - -// This macro is suitable for conditionally triggering lint errors, e.g., if a Sec parameter takes -// on a non-default value. This may be required for pre-silicon/FPGA evaluation but we don't want -// to allow this for tapeout. -`define ASSERT_STATIC_LINT_ERROR(__name, __prop) \ - localparam int __name = (__prop) ? 1 : 2; \ - always_comb begin \ - logic unused_assert_static_lint_error; \ - unused_assert_static_lint_error = __name'(1'b1); \ - end - -// Static assertions for checks inside SV packages. If the conditions is not true, this will -// trigger an error during elaboration. -`define ASSERT_STATIC_IN_PACKAGE(__name, __prop) \ - function automatic bit assert_static_in_package_``__name(); \ - bit unused_bit [((__prop) ? 1 : -1)]; \ - unused_bit = '{default: 1'b0}; \ - return unused_bit[0]; \ - endfunction - -// The basic helper macros are actually defined in "implementation headers". The macros should do -// the same thing in each case (except for the dummy flavour), but in a way that the respective -// tools support. -// -// If the tool supports assertions in some form, we also define INC_ASSERT (which can be used to -// hide signal definitions that are only used for assertions). -// -// The list of basic macros supported is: -// -// ASSERT_I: Immediate assertion. Note that immediate assertions are sensitive to simulation -// glitches. -// -// ASSERT_INIT: Assertion in initial block. Can be used for things like parameter checking. -// -// ASSERT_INIT_NET: Assertion in initial block. Can be used for initial value of a net. -// -// ASSERT_FINAL: Assertion in final block. Can be used for things like queues being empty at end of -// sim, all credits returned at end of sim, state machines in idle at end of sim. -// -// ASSERT: Assert a concurrent property directly. It can be called as a module (or -// interface) body item. -// -// Note: We use (__rst !== '0) in the disable iff statements instead of (__rst == -// '1). This properly disables the assertion in cases when reset is X at the -// beginning of a simulation. For that case, (reset == '1) does not disable the -// assertion. -// -// ASSERT_NEVER: Assert a concurrent property NEVER happens -// -// ASSERT_KNOWN: Assert that signal has a known value (each bit is either '0' or '1') after reset. -// It can be called as a module (or interface) body item. -// -// COVER: Cover a concurrent property -// -// ASSUME: Assume a concurrent property -// -// ASSUME_I: Assume an immediate property - -`ifdef VERILATOR - `include "prim_assert_dummy_macros.svh" -`elsif SYNTHESIS - `include "prim_assert_dummy_macros.svh" -`elsif YOSYS - `include "prim_assert_yosys_macros.svh" - `define INC_ASSERT -`else - `include "prim_assert_standard_macros.svh" - `define INC_ASSERT -`endif - -`define ASSERT_I(__name, __prop) -`define ASSERT_INIT(__name, __prop) -`define ASSERT_INIT_NET(__name, __prop) -`define ASSERT_FINAL(__name, __prop) -`define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) -`define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) -`define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) -`define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) -`define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) -`define ASSUME_I(__name, __prop) - -////////////////////////////// -// Complex assertion macros // -////////////////////////////// - -// Assert that signal is an active-high pulse with pulse length of 1 clock cycle -`define ASSERT_PULSE(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ - `ASSERT(__name, $rose(__sig) |=> !(__sig), __clk, __rst) - -// Assert that a property is true only when an enable signal is set. It can be called as a module -// (or interface) body item. -`define ASSERT_IF(__name, __prop, __enable, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ - `ASSERT(__name, (__enable) |-> (__prop), __clk, __rst) - -// Assert that signal has a known value (each bit is either '0' or '1') after reset if enable is -// set. It can be called as a module (or interface) body item. -`define ASSERT_KNOWN_IF(__name, __sig, __enable, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ - `ASSERT_KNOWN(__name``KnownEnable, __enable, __clk, __rst) \ - `ASSERT_IF(__name, !$isunknown(__sig), __enable, __clk, __rst) - -////////////////////////////////// -// For formal verification only // -////////////////////////////////// - -// Note that the existing set of ASSERT macros specified above shall be used for FPV, -// thereby ensuring that the assertions are evaluated during DV simulations as well. - -// ASSUME_FPV -// Assume a concurrent property during formal verification only. -`define ASSUME_FPV(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ -`ifdef FPV_ON \ - `ASSUME(__name, __prop, __clk, __rst) \ -`endif - -// ASSUME_I_FPV -// Assume a concurrent property during formal verification only. -`define ASSUME_I_FPV(__name, __prop) \ -`ifdef FPV_ON \ - `ASSUME_I(__name, __prop) \ -`endif - -// COVER_FPV -// Cover a concurrent property during formal verification -`define COVER_FPV(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ -`ifdef FPV_ON \ - `COVER(__name, __prop, __clk, __rst) \ -`endif - -// FPV assertion that proves that the FSM control flow is linear (no loops) -// The sequence triggers whenever the state changes and stores the current state as "initial_state". -// Then thereafter we must never see that state again until reset. -// It is possible for the reset to release ahead of the clock. -// Create a small "gray" window beyond the usual rst time to avoid -// checking. -`define ASSERT_FPV_LINEAR_FSM(__name, __state, __type, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) \ - `ifdef INC_ASSERT \ - bit __name``_cond; \ - always_ff @(posedge __clk or posedge __rst) begin \ - if (__rst) begin \ - __name``_cond <= 0; \ - end else begin \ - __name``_cond <= 1; \ - end \ - end \ - property __name``_p; \ - __type initial_state; \ - (!$stable(__state) & __name``_cond, initial_state = $past(__state)) |-> \ - (__state != initial_state) until (__rst == 1'b1); \ - endproperty \ - `ASSERT(__name, __name``_p, __clk, __rst) \ - `endif - -`include "prim_assert_sec_cm.svh" -`include "prim_flop_macros.sv" - -`endif // OT_PRIM_ASSERT_SV diff --git a/target/xilinx/src/overrides/riscv_ex_stage.sv b/target/xilinx/src/overrides/riscv_ex_stage.sv deleted file mode 100644 index a2bf6afc3..000000000 --- a/target/xilinx/src/overrides/riscv_ex_stage.sv +++ /dev/null @@ -1,723 +0,0 @@ -// Copyright 2018 ETH Zurich and University of Bologna. -// Copyright and related rights are licensed under the Solderpad Hardware -// License, Version 0.51 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law -// or agreed to in writing, software, hardware and materials distributed under -// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -//////////////////////////////////////////////////////////////////////////////// -// Engineer: Renzo Andri - andrire@student.ethz.ch // -// // -// Additional contributions by: // -// Igor Loi - igor.loi@unibo.it // -// Sven Stucki - svstucki@student.ethz.ch // -// Andreas Traber - atraber@iis.ee.ethz.ch // -// Michael Gautschi - gautschi@iis.ee.ethz.ch // -// Davide Schiavone - pschiavo@iis.ee.ethz.ch // -// // -// Design Name: Execute stage // -// Project Name: RI5CY // -// Language: SystemVerilog // -// // -// Description: Execution stage: Hosts ALU and MAC unit // -// ALU: computes additions/subtractions/comparisons // -// MULT: computes normal multiplications // -// APU_DISP: offloads instructions to the shared unit. // -// SHARED_DSP_MULT, SHARED_INT_DIV allow // -// to offload also dot-product, int-div, int-mult to the // -// shared unit. // -// // -//////////////////////////////////////////////////////////////////////////////// - -`include "apu_macros.sv" - -import apu_core_package::*; -import riscv_defines::*; - -module riscv_ex_stage -#( - parameter FPU = 0, - parameter FP_DIVSQRT = 0, - parameter SHARED_FP = 0, - parameter SHARED_DSP_MULT = 0, - parameter SHARED_INT_DIV = 0, - parameter APU_NARGS_CPU = 3, - parameter APU_WOP_CPU = 6, - parameter APU_NDSFLAGS_CPU = 15, - parameter APU_NUSFLAGS_CPU = 5 -) -( - input logic clk, - input logic rst_n, - input logic setback_i, - - // ALU signals from ID stage - input logic [ALU_OP_WIDTH-1:0] alu_operator_i, - input logic [31:0] alu_operand_a_i, - input logic [31:0] alu_operand_b_i, - input logic [31:0] alu_operand_c_i, - input logic alu_en_i, - input logic [ 4:0] bmask_a_i, - input logic [ 4:0] bmask_b_i, - input logic [ 1:0] imm_vec_ext_i, - - input ivec_mode_fmt alu_vec_mode_i, //modified for ivec sb : changed from logic to ivec_mode_fmt - input logic ivec_op_i, //added for ivec sb : needed inside alu to discriminate between scalar and vectorial operations - - input logic alu_is_clpx_i, - input logic alu_is_subrot_i, - input logic [ 1:0] alu_clpx_shift_i, - - // Multiplier signals - input mult_op_type mult_operator_i, //Modified for ivec sb : changed from logic to mult_op_type - - input logic [31:0] mult_operand_a_i, - input logic [31:0] mult_operand_b_i, - input logic [31:0] mult_operand_c_i, - input logic mult_en_i, - input logic mult_sel_subword_i, - input logic [ 1:0] mult_signed_mode_i, - input logic [ 4:0] mult_imm_i, - - input logic [31:0] mult_dot_op_h_a_i, - input logic [31:0] mult_dot_op_h_b_i, - input logic [31:0] mult_dot_op_b_a_i, - input logic [31:0] mult_dot_op_b_b_i, - input logic [31:0] mult_dot_op_n_a_i, - input logic [31:0] mult_dot_op_n_b_i, - input logic [31:0] mult_dot_op_c_a_i, - input logic [31:0] mult_dot_op_c_b_i, - input logic [31:0] mult_dot_op_c_i, - input logic [ 1:0] mult_dot_signed_i, - input logic mult_is_clpx_i, - input logic [ 1:0] mult_clpx_shift_i, - input logic mult_clpx_img_i, - input logic dot_spr_operand_i, - - - input logic [NBITS_MIXED_CYCLES-1:0] current_cycle_csr_i, //added for ivec sb: used to know at which mixed multiplication position we currently are. - input logic [NBITS_MIXED_CYCLES-1:0] current_cycle_ex_i, - input logic curr_cyc_sel_i, - - output logic mult_multicycle_o, - - // FPU signals - input logic [C_PC-1:0] fpu_prec_i, - output logic [C_FFLAG-1:0] fpu_fflags_o, - output logic fpu_fflags_we_o, - - // APU signals - input logic apu_en_i, - input logic [APU_WOP_CPU-1:0] apu_op_i, - input logic [1:0] apu_lat_i, - input logic [APU_NARGS_CPU-1:0][31:0] apu_operands_i, - input logic [5:0] apu_waddr_i, - input logic [APU_NDSFLAGS_CPU-1:0] apu_flags_i, - - input logic [2:0][5:0] apu_read_regs_i, - input logic [2:0] apu_read_regs_valid_i, - output logic apu_read_dep_o, - input logic [1:0][5:0] apu_write_regs_i, - input logic [1:0] apu_write_regs_valid_i, - output logic apu_write_dep_o, - - output logic apu_perf_type_o, - output logic apu_perf_cont_o, - output logic apu_perf_wb_o, - - output logic apu_busy_o, - output logic apu_ready_wb_o, - - // apu-interconnect - // handshake signals - output logic apu_master_req_o, - output logic apu_master_ready_o, - input logic apu_master_gnt_i, - // request channel - output logic [APU_NARGS_CPU-1:0][31:0] apu_master_operands_o, - output logic [APU_WOP_CPU-1:0] apu_master_op_o, - // response channel - input logic apu_master_valid_i, - input logic [31:0] apu_master_result_i, - - input logic lsu_en_i, - input logic [31:0] lsu_rdata_i, - input logic [2:0] lsu_tosprw_ex_i, - input logic [1:0] lsu_tospra_ex_i, - input logic data_rvalid_ex_i, - - // RNN Extension - output logic computeLoadVLIW_ex_o, - - // input from ID stage - input logic branch_in_ex_i, - input logic [5:0] regfile_alu_waddr_i, - input logic [5:0] regfile_alu_waddr2_i, - input logic regfile_alu_we_i, - - // directly passed through to WB stage, not used in EX - input logic regfile_we_i, - input logic [5:0] regfile_waddr_i, - - // CSR access - input logic csr_access_i, - input logic [31:0] csr_rdata_i, - - // Output of EX stage pipeline - output logic [5:0] regfile_waddr_wb_o, - output logic regfile_we_wb_o, - output logic [31:0] regfile_wdata_wb_o, - - // Forwarding ports : to ID stage - output logic [5:0] regfile_alu_waddr_fw_o, - output logic regfile_alu_we_fw_o, - output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL - - // To IF: Jump and branch target and decision - output logic [31:0] jump_target_o, - output logic branch_decision_o, - - // Stall Control - input logic is_decoding_i, // Used to mask data Dependency inside the APU dispatcher in case of an istruction non valid - input logic lsu_ready_ex_i, // EX part of LSU is done - input logic lsu_err_i, - - output logic ex_ready_o, // EX stage ready for new data - output logic ex_valid_o, // EX stage gets new data - input logic wb_ready_i // WB stage ready for new data -); - - logic [31:0] alu_result; - logic [31:0] mult_result; - logic [31:0] mult_result_p; //RNN_EXT - logic [31:0] mult_result_n; //RNN_EXT - logic alu_cmp_result; - - logic regfile_we_lsu; - logic [5:0] regfile_waddr_lsu; - - logic wb_contention; - logic wb_contention_lsu; - - logic alu_ready; - logic mult_ready; - logic fpu_ready; - logic fpu_valid; - - - // APU signals - logic apu_valid; - logic [5:0] apu_waddr; - logic [31:0] apu_result; - logic apu_stall; - logic apu_active; - logic apu_singlecycle; - logic apu_multicycle; - logic apu_req; - logic apu_ready; - logic apu_gnt; - - // RNN Extensions //RNN_EXT - logic spr_rnn_en; //RNN_EXT - logic [3:0][31:0] wspr_rnn, wspr_rnn_n; //RNN_EXT - logic [1:0][31:0] aspr_rnn, aspr_rnn_n; //RNN_EXT - logic [2:0] lsu_tosprw_wb; //RNN_EXT - logic [1:0] lsu_tospra_wb; //RNN_EXT - logic dot_spr_operand_wb; - logic [5:0] regfile_alu_waddr2_wb; //RNN_EXT - logic [31:0] mult_dot_op_h_a_ml; //RNN_EXT - logic [31:0] mult_dot_op_b_a_ml; //RNN_EXT - logic [31:0] mult_dot_op_n_a_ml; //RNN_EXT - logic [31:0] mult_dot_op_c_a_ml; //RNN_EXT - logic [31:0] mult_dot_op_h_b_ml; //RNN_EXT - logic [31:0] mult_dot_op_b_b_ml; //RNN_EXT - logic [31:0] mult_dot_op_n_b_ml; //RNN_EXT - logic [31:0] mult_dot_op_c_b_ml; //RNN_EXT - logic loadComputeVLIW; //RNN_EXT - - logic [NBITS_MIXED_CYCLES-1:0] current_cycle; - - assign loadComputeVLIW = dot_spr_operand_i & mult_en_i; //alu_en_i & mult_en_i; - assign computeLoadVLIW_ex_o = loadComputeVLIW; - // ALU write port mux - always_comb - begin - regfile_alu_wdata_fw_o = '0; - regfile_alu_waddr_fw_o = '0; - regfile_alu_we_fw_o = '0; - wb_contention = 1'b0; - - // APU single cycle operations, and multicycle operations (>2cycles) are written back on ALU port - if (apu_valid & (apu_singlecycle | apu_multicycle)) begin - regfile_alu_we_fw_o = 1'b1; - regfile_alu_waddr_fw_o = apu_waddr; - regfile_alu_wdata_fw_o = apu_result; - - if(regfile_alu_we_i & ~apu_en_i) begin - wb_contention = 1'b1; - end - end else begin - regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; // private fpu incomplete? - regfile_alu_waddr_fw_o = regfile_alu_waddr_i; - if (loadComputeVLIW) begin - regfile_alu_wdata_fw_o = alu_result; - end else begin - if (alu_en_i) - regfile_alu_wdata_fw_o = alu_result; - if (mult_en_i) - regfile_alu_wdata_fw_o = mult_result; - if (csr_access_i) - regfile_alu_wdata_fw_o = csr_rdata_i; - end - end - end - - assign mult_result_n = mult_result; //RNN_EXT - // LSU write port mux - always_comb - begin - spr_rnn_en = 1'b0; //RNN_EXT - regfile_we_wb_o = 1'b0; - regfile_waddr_wb_o = regfile_waddr_lsu; - regfile_wdata_wb_o = lsu_rdata_i; - wb_contention_lsu = 1'b0; - - if (regfile_we_lsu) begin - regfile_we_wb_o = 1'b1; - if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin - wb_contention_lsu = 1'b1; -// $error("%t, wb-contention", $time); - // APU two-cycle operations are written back on LSU port - end - if(lsu_tosprw_wb[0] | lsu_tospra_wb[0]) begin// does not work because of latency - spr_rnn_en = 1'b1; //spr instead of gpr - //regfile_waddr_wb_o = regfile_waddr_lsu; - //regfile_wdata_wb_o = mult_result_p; - // regfile_we_wb_o = 1'b0; //spr instead of gpr - // regfile_waddr_wb_o = regfile_alu_waddr2_wb; - end - end else if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin - regfile_we_wb_o = 1'b1; - regfile_waddr_wb_o = apu_waddr; - regfile_wdata_wb_o = apu_result; - end - //if(lsu_tosprw_wb[0]) begin - if (dot_spr_operand_wb) begin - regfile_waddr_wb_o = regfile_waddr_lsu; - regfile_wdata_wb_o = mult_result_p; - end - - - - end - - // branch handling - assign branch_decision_o = alu_cmp_result; - assign jump_target_o = alu_operand_c_i; - - - //////////////////////////// - // _ _ _ _ // - // / \ | | | | | | // - // / _ \ | | | | | | // - // / ___ \| |__| |_| | // - // /_/ \_\_____\___/ // - // // - //////////////////////////// - - riscv_alu - #( - .SHARED_INT_DIV( SHARED_INT_DIV ), - .FPU ( FPU ) - ) - alu_i - ( - .clk ( clk ), - .rst_n ( rst_n ), - .setback_i ( setback_i ), - .enable_i ( alu_en_i ), - .operator_i ( alu_operator_i ), - .operand_a_i ( alu_operand_a_i ), - .operand_b_i ( alu_operand_b_i ), - .operand_c_i ( alu_operand_c_i ), - - .vector_mode_i ( alu_vec_mode_i ), - - .ivec_op_i ( ivec_op_i ), //added for sb ivec - - .bmask_a_i ( bmask_a_i ), - .bmask_b_i ( bmask_b_i ), - .imm_vec_ext_i ( imm_vec_ext_i ), - - .is_clpx_i ( alu_is_clpx_i ), - .clpx_shift_i ( alu_clpx_shift_i), - .is_subrot_i ( alu_is_subrot_i ), - - .result_o ( alu_result ), - .comparison_result_o ( alu_cmp_result ), - - .ready_o ( alu_ready ), - .ex_ready_i ( ex_ready_o ) - ); - - - //////////////////////////////////////////////////////////////// - // __ __ _ _ _ _____ ___ ____ _ ___ _____ ____ // - // | \/ | | | | | |_ _|_ _| _ \| | |_ _| ____| _ \ // - // | |\/| | | | | | | | | || |_) | | | || _| | |_) | // - // | | | | |_| | |___| | | || __/| |___ | || |___| _ < // - // |_| |_|\___/|_____|_| |___|_| |_____|___|_____|_| \_\ // - // // - //////////////////////////////////////////////////////////////// - - - assign mult_dot_op_h_a_ml = {32{(mult_operator_i == MUL_DOT16) | - (mult_operator_i == MIXED_MUL_8x16) | - (mult_operator_i == MIXED_MUL_4x16) | - (mult_operator_i == MIXED_MUL_2x16)}} & - (dot_spr_operand_i ? aspr_rnn[lsu_tospra_ex_i[1]] : mult_dot_op_h_a_i); - assign mult_dot_op_b_a_ml = {32{(mult_operator_i == MUL_DOT8) | - (mult_operator_i == MIXED_MUL_2x8) | - (mult_operator_i == MIXED_MUL_4x8)}} & - (dot_spr_operand_i ? aspr_rnn[lsu_tospra_ex_i[1]] : mult_dot_op_b_a_i); - assign mult_dot_op_n_a_ml = {32{(mult_operator_i == MUL_DOT4) | - (mult_operator_i == MIXED_MUL_2x4)}} & - (dot_spr_operand_i ? aspr_rnn[lsu_tospra_ex_i[1]] : mult_dot_op_n_a_i); - assign mult_dot_op_c_a_ml = {32{(mult_operator_i == MUL_DOT2)}} & ((dot_spr_operand_i) ? aspr_rnn[lsu_tospra_ex_i[1]] : mult_dot_op_c_a_i); - assign mult_dot_op_h_b_ml = {32{(mult_operator_i == MUL_DOT16) | - (mult_operator_i == MIXED_MUL_8x16) | - (mult_operator_i == MIXED_MUL_4x16) | - (mult_operator_i == MIXED_MUL_2x16)}} & - (dot_spr_operand_i ? wspr_rnn[lsu_tosprw_ex_i[2:1]] : mult_dot_op_h_b_i); - assign mult_dot_op_b_b_ml = {32{(mult_operator_i == MUL_DOT8) | - (mult_operator_i == MIXED_MUL_2x8) | - (mult_operator_i == MIXED_MUL_4x8)}} & - (dot_spr_operand_i ? wspr_rnn[lsu_tosprw_ex_i[2:1]] : mult_dot_op_b_b_i); - assign mult_dot_op_n_b_ml = {32{(mult_operator_i == MUL_DOT4) | - (mult_operator_i == MIXED_MUL_2x4)}} & - (dot_spr_operand_i ? wspr_rnn[lsu_tosprw_ex_i[2:1]] : mult_dot_op_n_b_i); - assign mult_dot_op_c_b_ml = {32{(mult_operator_i == MUL_DOT2)}} & - (dot_spr_operand_i ? wspr_rnn[lsu_tosprw_ex_i[2:1]] : mult_dot_op_c_b_i); - - assign current_cycle = curr_cyc_sel_i ? current_cycle_csr_i : current_cycle_ex_i; - - riscv_mult - #( - .SHARED_DSP_MULT(SHARED_DSP_MULT) - ) - mult_i - ( - .clk ( clk ), - .rst_n ( rst_n ), - .setback_i ( setback_i ), - - .enable_i ( mult_en_i ), - .operator_i ( mult_operator_i ), - - .short_subword_i ( mult_sel_subword_i ), - .short_signed_i ( mult_signed_mode_i ), - - .op_a_i ( mult_operand_a_i ), - .op_b_i ( mult_operand_b_i ), - .op_c_i ( mult_operand_c_i ), - .imm_i ( mult_imm_i ), - - .dot_op_h_a_i ( mult_dot_op_h_a_ml ), - .dot_op_h_b_i ( mult_dot_op_h_b_ml ), - .dot_op_b_a_i ( mult_dot_op_b_a_ml ), - .dot_op_b_b_i ( mult_dot_op_b_b_ml ), - .dot_op_n_a_i ( mult_dot_op_n_a_ml ), - .dot_op_n_b_i ( mult_dot_op_n_b_ml ), - .dot_op_c_a_i ( mult_dot_op_c_a_ml ), - .dot_op_c_b_i ( mult_dot_op_c_b_ml ), - .dot_op_c_i ( mult_dot_op_c_i ), - .dot_signed_i ( mult_dot_signed_i ), - - .current_cycle_i ( current_cycle ), - - .is_clpx_i ( mult_is_clpx_i ), - .clpx_shift_i ( mult_clpx_shift_i ), - .clpx_img_i ( mult_clpx_img_i ), - - .result_o ( mult_result ), - - .multicycle_o ( mult_multicycle_o ), - .ready_o ( mult_ready ), - .ex_ready_i ( ex_ready_o ) - ); - - generate - if (FPU == 1) begin - //////////////////////////////////////////////////// - // _ ____ _ _ ____ ___ ____ ____ // - // / \ | _ \| | | | | _ \_ _/ ___|| _ \ // - // / _ \ | |_) | | | | | | | | |\___ \| |_) | // - // / ___ \| __/| |_| | | |_| | | ___) | __/ // - // /_/ \_\_| \___/ |____/___|____/|_| // - // // - //////////////////////////////////////////////////// - - riscv_apu_disp apu_disp_i - ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .setback_i ( setback_i ), - - .enable_i ( apu_en_i ), - .apu_lat_i ( apu_lat_i ), - .apu_waddr_i ( apu_waddr_i ), - - .apu_waddr_o ( apu_waddr ), - .apu_multicycle_o ( apu_multicycle ), - .apu_singlecycle_o ( apu_singlecycle ), - - .active_o ( apu_active ), - .stall_o ( apu_stall ), - - .is_decoding_i ( is_decoding_i ), - .read_regs_i ( apu_read_regs_i ), - .read_regs_valid_i ( apu_read_regs_valid_i ), - .read_dep_o ( apu_read_dep_o ), - .write_regs_i ( apu_write_regs_i ), - .write_regs_valid_i ( apu_write_regs_valid_i ), - .write_dep_o ( apu_write_dep_o ), - - .perf_type_o ( apu_perf_type_o ), - .perf_cont_o ( apu_perf_cont_o ), - - // apu-interconnect - // handshake signals - .apu_master_req_o ( apu_req ), - .apu_master_ready_o ( apu_ready ), - .apu_master_gnt_i ( apu_gnt ), - // response channel - .apu_master_valid_i ( apu_valid ) - ); - - assign apu_perf_wb_o = wb_contention | wb_contention_lsu; - assign apu_ready_wb_o = ~(apu_active | apu_en_i | apu_stall) | apu_valid; - - if ( SHARED_FP ) begin - assign apu_master_req_o = apu_req; - assign apu_master_ready_o = apu_ready; - assign apu_gnt = apu_master_gnt_i; - assign apu_valid = apu_master_valid_i; - assign apu_master_operands_o = apu_operands_i; - assign apu_master_op_o = apu_op_i; - assign apu_result = apu_master_result_i; - assign fpu_fflags_we_o = apu_valid; - assign fpu_ready = 1'b1; - end - else begin - - ////////////////////////////// - // ______ _____ _ _ // - // | ____| __ \| | | | // - // | |__ | |__) | | | | // - // | __| | ___/| | | | // - // | | | | | |__| | // - // |_| |_| \____/ // - ////////////////////////////// - - - logic [C_FPNEW_OPBITS-1:0] fpu_op; - logic fpu_op_mod; - logic fpu_vec_op; - - logic [C_FPNEW_FMTBITS-1:0] fpu_dst_fmt; - logic [C_FPNEW_FMTBITS-1:0] fpu_src_fmt; - logic [C_FPNEW_IFMTBITS-1:0] fpu_int_fmt; - logic [C_RM-1:0] fp_rnd_mode; - - assign {fpu_vec_op, fpu_op_mod, fpu_op} = apu_op_i; - assign {fpu_int_fmt, fpu_src_fmt, fpu_dst_fmt, fp_rnd_mode} = apu_flags_i; - - localparam unit_type_t C_DIV = FP_DIVSQRT ? fpnew_pkg::MERGED : fpnew_pkg::DISABLED; - - logic FPU_ready_int; - - // ----------- - // FPU Config - // ----------- - // Features (enabled formats, vectors etc.) - localparam fpnew_pkg::fpu_features_t FPU_FEATURES = '{ - Width: C_FLEN, - EnableVectors: C_XFVEC, - EnableNanBox: 1'b0, - FpFmtMask: {C_RVF, C_RVD, C_XF16, C_XF8, C_XF16ALT, C_XF8ALT}, - IntFmtMask: {C_XFVEC && (C_XF8 || C_XF8ALT), C_XFVEC && (C_XF16 || C_XF16ALT), 1'b1, 1'b0} - }; - - // Implementation (number of registers etc) - localparam fpnew_pkg::fpu_implementation_t FPU_IMPLEMENTATION = '{ - PipeRegs: '{// FP32, FP64, FP16, FP8, FP16alt - '{C_LAT_FP32, C_LAT_FP64, C_LAT_FP16, C_LAT_FP8, C_LAT_FP16ALT, C_LAT_FP8ALT}, // ADDMUL - '{default: C_LAT_DIVSQRT}, // DIVSQRT - '{default: C_LAT_NONCOMP}, // NONCOMP - '{default: C_LAT_CONV}, // CONV - '{default: C_LAT_DOTP}}, // SDOTP - UnitTypes: '{'{default: fpnew_pkg::MERGED}, // ADDMUL - '{default: C_DIV}, // DIVSQRT - '{default: fpnew_pkg::PARALLEL}, // NONCOMP - '{default: fpnew_pkg::MERGED}, // CONV - '{default: fpnew_pkg::DISABLED}}, // SDOTP - PipeConfig: fpnew_pkg::AFTER - }; - - //--------------- - // FPU instance - //--------------- - - fpnew_top #( - .Features ( FPU_FEATURES ), - .Implementation ( FPU_IMPLEMENTATION ), - .TagType ( logic ) - ) i_fpnew_bulk ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .hart_id_i ( '0 ), - .operands_i ( apu_operands_i ), - .rnd_mode_i ( fpnew_pkg::roundmode_e'(fp_rnd_mode) ), - .op_i ( fpnew_pkg::operation_e'(fpu_op) ), - .op_mod_i ( fpu_op_mod ), - .src_fmt_i ( fpnew_pkg::fp_format_e'(fpu_src_fmt) ), - .dst_fmt_i ( fpnew_pkg::fp_format_e'(fpu_dst_fmt) ), - .int_fmt_i ( fpnew_pkg::int_format_e'(fpu_int_fmt) ), - .vectorial_op_i ( fpu_vec_op ), - .tag_i ( 1'b0 ), - .simd_mask_i ( '1 ), - .in_valid_i ( apu_req ), - .in_ready_o ( FPU_ready_int ), - .flush_i ( 1'b0 ), - .result_o ( apu_result ), - .status_o ( fpu_fflags_o ), - .tag_o ( /* unused */ ), - .out_valid_o ( apu_valid ), - .out_ready_i ( 1'b1 ), - .busy_o ( /* unused */ ) - ); - - assign fpu_fflags_we_o = apu_valid; - assign apu_master_req_o = '0; - assign apu_master_ready_o = 1'b1; - assign apu_master_operands_o[0] = '0; - assign apu_master_operands_o[1] = '0; - assign apu_master_operands_o[2] = '0; - assign apu_master_op_o = '0; - assign apu_gnt = 1'b1; - - assign fpu_ready = (FPU_ready_int & apu_req) | (~apu_req); - - end - - end - else begin - // default assignements for the case when no FPU/APU is attached. - assign apu_master_req_o = '0; - assign apu_master_ready_o = 1'b1; - assign apu_master_operands_o[0] = '0; - assign apu_master_operands_o[1] = '0; - assign apu_master_operands_o[2] = '0; - assign apu_master_op_o = '0; - assign apu_valid = 1'b0; - assign apu_waddr = 6'b0; - assign apu_stall = 1'b0; - assign apu_active = 1'b0; - assign apu_ready_wb_o = 1'b1; - assign apu_perf_wb_o = 1'b0; - assign apu_perf_cont_o = 1'b0; - assign apu_perf_type_o = 1'b0; - assign apu_singlecycle = 1'b0; - assign apu_multicycle = 1'b0; - assign apu_read_dep_o = 1'b0; - assign apu_write_dep_o = 1'b0; - assign fpu_fflags_we_o = 1'b0; - assign fpu_fflags_o = '0; - // we need this because we want ex_ready_o to go high otherwise the - // pipeline can't progress - assign fpu_ready = 1'b1; - - end - endgenerate - - assign apu_busy_o = apu_active; - - // SPR - assign wspr_rnn_n[0] = (lsu_tosprw_wb[0] && spr_rnn_en && lsu_tosprw_wb[2:1]==2'b00) ? lsu_rdata_i : wspr_rnn[0]; //RNN_EXT - assign wspr_rnn_n[1] = (lsu_tosprw_wb[0] && spr_rnn_en && lsu_tosprw_wb[2:1]==2'b01) ? lsu_rdata_i : wspr_rnn[1]; //RNN_EXT - assign wspr_rnn_n[2] = (lsu_tosprw_wb[0] && spr_rnn_en && lsu_tosprw_wb[2:1]==2'b10) ? lsu_rdata_i : wspr_rnn[2]; //RNN_EXT - assign wspr_rnn_n[3] = (lsu_tosprw_wb[0] && spr_rnn_en && lsu_tosprw_wb[2:1]==2'b11) ? lsu_rdata_i : wspr_rnn[3]; //RNN_EXT - assign aspr_rnn_n[0] = (lsu_tospra_wb[0] && spr_rnn_en && lsu_tospra_wb[1]==1'b0) ? lsu_rdata_i : aspr_rnn[0]; //RNN_EXT - assign aspr_rnn_n[1] = (lsu_tospra_wb[0] && spr_rnn_en && lsu_tospra_wb[1]==1'b1) ? lsu_rdata_i : aspr_rnn[1]; //RNN_EXT - -always_ff @(posedge clk, negedge rst_n) begin : SPR - if (~rst_n) begin - wspr_rnn <= '0; - aspr_rnn <= '0; - mult_result_p <= '0; //RNN_EXT - end else begin - if (setback_i) begin - wspr_rnn <= '0; - aspr_rnn <= '0; - mult_result_p <= '0; //RNN_EXT - end else begin - wspr_rnn <= wspr_rnn_n; - aspr_rnn <= aspr_rnn_n; - mult_result_p <= mult_result_n; //RNN_EXT - end - end -end - - - - /////////////////////////////////////// - // EX/WB Pipeline Register // - /////////////////////////////////////// - always_ff @(posedge clk, negedge rst_n) begin : EX_WB_Pipeline_Register - if (~rst_n) begin - regfile_waddr_lsu <= '0; - regfile_we_lsu <= 1'b0; - lsu_tosprw_wb <= 3'b0; //RNN_EXT - lsu_tospra_wb <= 2'b0; - regfile_alu_waddr2_wb <= 'b0; //RNN_EXT - dot_spr_operand_wb <= '0; - end else begin - if (setback_i) begin - regfile_waddr_lsu <= '0; - regfile_we_lsu <= 1'b0; - lsu_tosprw_wb <= 3'b0; //RNN_EXT - lsu_tospra_wb <= 2'b0; - regfile_alu_waddr2_wb <= 'b0; //RNN_EXT - dot_spr_operand_wb <= '0; - end else begin - if (ex_valid_o) // wb_ready_i is implied - begin - regfile_we_lsu <= regfile_we_i & ~lsu_err_i; - lsu_tosprw_wb <= lsu_tosprw_ex_i; //RNN_EXT//RNN_EXT - lsu_tospra_wb <= lsu_tospra_ex_i;//RNN_EXT - dot_spr_operand_wb <= dot_spr_operand_i; - regfile_alu_waddr2_wb <= regfile_alu_waddr2_i; //RNN_EXT - if (regfile_we_i & ~lsu_err_i ) begin - regfile_waddr_lsu <= regfile_waddr_i; - end - end else if (wb_ready_i) begin - // we are ready for a new instruction, but there is none available, - // so we just flush the current one out of the pipe - regfile_we_lsu <= 1'b0; - end - end - end - end - - // As valid always goes to the right and ready to the left, and we are able - // to finish branches without going to the WB stage, ex_valid does not - // depend on ex_ready. - assign ex_ready_o = (~apu_stall & alu_ready & mult_ready & lsu_ready_ex_i - & wb_ready_i & ~wb_contention & fpu_ready) | (branch_in_ex_i); - assign ex_valid_o = (apu_valid | alu_en_i | mult_en_i | csr_access_i | lsu_en_i) - & (alu_ready & mult_ready & lsu_ready_ex_i & wb_ready_i); - -endmodule diff --git a/target/xilinx/src/overrides/tc_clk_xilinx.sv b/target/xilinx/src/overrides/tc_clk_xilinx.sv index 0c1e4b9cd..b8f553efb 100644 --- a/target/xilinx/src/overrides/tc_clk_xilinx.sv +++ b/target/xilinx/src/overrides/tc_clk_xilinx.sv @@ -1,4 +1,4 @@ -// Copyright 2019 ETH Zurich and University of Bologna. +// Copyright 2023 ETH Zurich and University of Bologna. // Copyright and related rights are licensed under the Solderpad Hardware // License, Version 0.51 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at diff --git a/target/xilinx/src/overrides/tc_sram_xilinx.sv b/target/xilinx/src/overrides/tc_sram_xilinx.sv deleted file mode 100644 index e20454795..000000000 --- a/target/xilinx/src/overrides/tc_sram_xilinx.sv +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2020 ETH Zurich and University of Bologna. -// Copyright and related rights are licensed under the Solderpad Hardware -// License, Version 0.51 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law -// or agreed to in writing, software, hardware and materials distributed under -// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. -// -// Author: Wolfgang Roenninger , ETH Zurich -// -// Description: Xilinx implementation using the XPM constructs for `tc_sram` -// Make sure that Vivado can detect the XPM macros by issuing -// the `auto_detect_xpm` or `set_property XPM_LIBRARIES XPM_MEMORY [current_project]` -// command. Currently the Xilinx macros are always initialized to all zero! -// The behaviour, parameters and ports are described in the header of `rtl/tc_sram.sv`. - -module tc_sram #( - parameter int unsigned NumWords = 32'd1024, // Number of Words in data array - parameter int unsigned DataWidth = 32'd128, // Data signal width (in bits) - parameter int unsigned ByteWidth = 32'd8, // Width of a data byte (in bits) - parameter int unsigned NumPorts = 32'd2, // Number of read and write ports - parameter int unsigned Latency = 32'd1, // Latency when the read data is available - parameter SimInit = "zeros", // Simulation initialization, fixed to zero here! - parameter bit PrintSimCfg = 1'b0, // Print configuration - parameter ImplKey = "none", // Reference to specific implementation - // DEPENDENT PARAMETERS, DO NOT OVERWRITE! - parameter int unsigned AddrWidth = (NumWords > 32'd1) ? $clog2(NumWords) : 32'd1, - parameter int unsigned BeWidth = (DataWidth + ByteWidth - 32'd1) / ByteWidth, // ceil_div - parameter type addr_t = logic [AddrWidth-1:0], - parameter type data_t = logic [DataWidth-1:0], - parameter type be_t = logic [BeWidth-1:0] -) ( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low - // input ports - input logic [NumPorts-1:0] req_i, // request - input logic [NumPorts-1:0] we_i, // write enable - input addr_t [NumPorts-1:0] addr_i, // request address - input data_t [NumPorts-1:0] wdata_i, // write data - input be_t [NumPorts-1:0] be_i, // write byte enable - // output ports - output data_t [NumPorts-1:0] rdata_o // read data -); - - localparam int unsigned DataWidthAligned = ByteWidth * BeWidth; - localparam int unsigned Size = NumWords * DataWidthAligned; - - typedef logic [DataWidthAligned-1:0] data_aligned_t; - - data_aligned_t [NumPorts-1:0] wdata_al; - data_aligned_t [NumPorts-1:0] rdata_al; - be_t [NumPorts-1:0] we; - - // pad with 0 to next byte for inferable macro below, as the macro wants - // READ_DATA_WIDTH_A be a multiple of BYTE_WRITE_WIDTH_A - always_comb begin : p_align - wdata_al = '0; - for (int unsigned i = 0; i < NumPorts; i++) begin - wdata_al[i][DataWidth-1:0] = wdata_i[i]; - end - end - - for (genvar i = 0; i < NumPorts; i++) begin : gen_port_assign - for (genvar j = 0; j < BeWidth; j++) begin : gen_we_assign - assign we[i][j] = be_i[i][j] & we_i[i]; - end - assign rdata_o[i] = data_t'(rdata_al[i]); - end - - if (NumPorts == 32'd1) begin : gen_1_ports - // xpm_memory_spram: Single Port RAM - // XilinxParameterizedMacro, version 2018.1 - xpm_memory_spram#( - .ADDR_WIDTH_A ( AddrWidth ), // DECIMAL - .AUTO_SLEEP_TIME ( 0 ), // DECIMAL - .BYTE_WRITE_WIDTH_A ( ByteWidth ), // DECIMAL - .ECC_MODE ( "no_ecc" ), // String - .MEMORY_INIT_FILE ( "none" ), // String - .MEMORY_INIT_PARAM ( "0" ), // String - .MEMORY_OPTIMIZATION ( "true" ), // String - .MEMORY_PRIMITIVE ( "auto" ), // String - .MEMORY_SIZE ( Size ), // DECIMAL in bit! - .MESSAGE_CONTROL ( 0 ), // DECIMAL - .READ_DATA_WIDTH_A ( DataWidthAligned ), // DECIMAL - .READ_LATENCY_A ( Latency ), // DECIMAL - .READ_RESET_VALUE_A ( "0" ), // String - .USE_MEM_INIT ( 1 ), // DECIMAL - .WAKEUP_TIME ( "disable_sleep" ), // String - .WRITE_DATA_WIDTH_A ( DataWidthAligned ), // DECIMAL - .WRITE_MODE_A ( "no_change" ) // String - ) i_xpm_memory_spram ( - .dbiterra ( /*not used*/ ), // 1-bit output: Status signal to indicate double biterror - .douta ( rdata_al[0] ), // READ_DATA_WIDTH_A-bitoutput: Data output for port A - .sbiterra ( /*not used*/ ), // 1-bit output: Status signal to indicate single biterror - .addra ( addr_i[0] ), // ADDR_WIDTH_A-bit input: Address for port A - .clka ( clk_i ), // 1-bit input: Clock signal for port A. - .dina ( wdata_al[0] ), // WRITE_DATA_WIDTH_A-bitinput: Data input for port A - .ena ( req_i[0] ), // 1-bit input: Memory enable signal for port A. - .injectdbiterra ( 1'b0 ), // 1-bit input: Controls double biterror injection - .injectsbiterra ( 1'b0 ), // 1-bit input: Controls single biterror injection - .regcea ( 1'b1 ), // 1-bit input: Clock Enable for the last register - .rsta ( ~rst_ni ), // 1-bit input: Reset signal for the final port A output - .sleep ( 1'b0 ), // 1-bit input: sleep signal to enable the dynamic power save - .wea ( we[0] ) - ); - end else if (NumPorts == 32'd2) begin : gen_2_ports - // xpm_memory_tdpram: True Dual Port RAM - // XilinxParameterizedMacro, version 2018.1 - xpm_memory_tdpram#( - .ADDR_WIDTH_A ( AddrWidth ), // DECIMAL - .ADDR_WIDTH_B ( AddrWidth ), // DECIMAL - .AUTO_SLEEP_TIME ( 0 ), // DECIMAL - .BYTE_WRITE_WIDTH_A ( ByteWidth ), // DECIMAL - .BYTE_WRITE_WIDTH_B ( ByteWidth ), // DECIMAL - .CLOCKING_MODE ( "common_clock" ), // String - .ECC_MODE ( "no_ecc" ), // String - .MEMORY_INIT_FILE ( "none" ), // String - .MEMORY_INIT_PARAM ( "0" ), // String - .MEMORY_OPTIMIZATION ( "true" ), // String - .MEMORY_PRIMITIVE ( "auto" ), // String - .MEMORY_SIZE ( Size ), // DECIMAL in bits! - .MESSAGE_CONTROL ( 0 ), // DECIMAL - .READ_DATA_WIDTH_A ( DataWidthAligned ), // DECIMAL - .READ_DATA_WIDTH_B ( DataWidthAligned ), // DECIMAL - .READ_LATENCY_A ( Latency ), // DECIMAL - .READ_LATENCY_B ( Latency ), // DECIMAL - .READ_RESET_VALUE_A ( "0" ), // String - .READ_RESET_VALUE_B ( "0" ), // String - .USE_EMBEDDED_CONSTRAINT ( 0 ), // DECIMAL - .USE_MEM_INIT ( 1 ), // DECIMAL - .WAKEUP_TIME ( "disable_sleep" ), // String - .WRITE_DATA_WIDTH_A ( DataWidthAligned ), // DECIMAL - .WRITE_DATA_WIDTH_B ( DataWidthAligned ), // DECIMAL - .WRITE_MODE_A ( "no_change" ), // String - .WRITE_MODE_B ( "no_change" ) // String - ) i_xpm_memory_tdpram ( - .dbiterra ( /*not used*/ ), // 1-bit output: Doubble bit error A - .dbiterrb ( /*not used*/ ), // 1-bit output: Doubble bit error B - .sbiterra ( /*not used*/ ), // 1-bit output: Single bit error A - .sbiterrb ( /*not used*/ ), // 1-bit output: Single bit error B - .addra ( addr_i[0] ), // ADDR_WIDTH_A-bit input: Address for port A - .addrb ( addr_i[1] ), // ADDR_WIDTH_B-bit input: Address for port B - .clka ( clk_i ), // 1-bit input: Clock signal for port A - .clkb ( clk_i ), // 1-bit input: Clock signal for port B - .dina ( wdata_al[0] ), // WRITE_DATA_WIDTH_A-bit input: Data input for port A - .dinb ( wdata_al[1] ), // WRITE_DATA_WIDTH_B-bit input: Data input for port B - .douta ( rdata_al[0] ), // READ_DATA_WIDTH_A-bit output: Data output for port A - .doutb ( rdata_al[1] ), // READ_DATA_WIDTH_B-bit output: Data output for port B - .ena ( req_i[0] ), // 1-bit input: Memory enable signal for port A - .enb ( req_i[1] ), // 1-bit input: Memory enable signal for port B - .injectdbiterra ( 1'b0 ), // 1-bit input: Controls doublebiterror injection on input data - .injectdbiterrb ( 1'b0 ), // 1-bit input: Controls doublebiterror injection on input data - .injectsbiterra ( 1'b0 ), // 1-bit input: Controls singlebiterror injection on input data - .injectsbiterrb ( 1'b0 ), // 1-bit input: Controls singlebiterror injection on input data - .regcea ( 1'b1 ), // 1-bit input: Clock Enable for the last register stage - .regceb ( 1'b1 ), // 1-bit input: Clock Enable for the last register stage - .rsta ( ~rst_ni ), // 1-bit input: Reset signal for the final port A output - .rstb ( ~rst_ni ), // 1-bit input: Reset signal for the final port B output - .sleep ( 1'b0 ), // 1-bit input: sleep signal to enable the dynamic power - .wea ( we[0] ), // WRITE_DATA_WIDTH_A-bit input: Write enable vector for port A - .web ( we[1] ) // WRITE_DATA_WIDTH_B-bit input: Write enable vector for port B - ); - end else begin : gen_err_ports - $fatal(1, "Not supported port parametrization for NumPorts: %0d", NumPorts); - end - -// Validate parameters. -// pragma translate_off -`ifndef VERILATOR -`ifndef TARGET_SYNTHESIS - initial begin: p_assertions - //assert (SimInit == "zeros") else $fatal(1, "The Xilinx `tc_sram` has fixed SimInit: zeros"); - assert ($bits(addr_i) == NumPorts * AddrWidth) else $fatal(1, "AddrWidth problem on `addr_i`"); - assert ($bits(wdata_i) == NumPorts * DataWidth) else $fatal(1, "DataWidth problem on `wdata_i`"); - assert ($bits(be_i) == NumPorts * BeWidth) else $fatal(1, "BeWidth problem on `be_i`" ); - assert ($bits(rdata_o) == NumPorts * DataWidth) else $fatal(1, "DataWidth problem on `rdata_o`"); - assert (NumWords >= 32'd1) else $fatal(1, "NumWords has to be > 0"); - assert (DataWidth >= 32'd1) else $fatal(1, "DataWidth has to be > 0"); - assert (ByteWidth >= 32'd1) else $fatal(1, "ByteWidth has to be > 0"); - assert (NumPorts >= 32'd1) else $fatal(1, "The number of ports must be at least 1!"); - end - initial begin: p_sim_hello - if (PrintSimCfg) begin - $display("#################################################################################"); - $display("tc_sram functional instantiated with the configuration:" ); - $display("Instance: %m" ); - $display("Number of ports (dec): %0d", NumPorts ); - $display("Number of words (dec): %0d", NumWords ); - $display("Address width (dec): %0d", AddrWidth ); - $display("Data width (dec): %0d", DataWidth ); - $display("Byte width (dec): %0d", ByteWidth ); - $display("Byte enable width (dec): %0d", BeWidth ); - $display("Latency Cycles (dec): %0d", Latency ); - $display("Simulation init (str): %0s", SimInit ); - $display("#################################################################################"); - end - end - for (genvar i = 0; i < NumPorts; i++) begin : gen_assertions - assert property ( @(posedge clk_i) disable iff (!rst_ni) - (req_i[i] |-> (addr_i[i] < NumWords))) else - $warning("Request address %0h not mapped, port %0d, expect random write or read behavior!", - addr_i[i], i); - end - -`endif -`endif -// pragma translate_on - -endmodule diff --git a/target/xilinx/Makefile b/target/xilinx/xilinx.mk similarity index 50% rename from target/xilinx/Makefile rename to target/xilinx/xilinx.mk index ad4ec9739..0efeb5496 100644 --- a/target/xilinx/Makefile +++ b/target/xilinx/xilinx.mk @@ -6,19 +6,10 @@ # Christopher Reinwardt # Cyril Koenig -BENDER ?= bender - PROJECT ?= carfield - # Board in {genesys2, zcu102, vcu128} BOARD ?= vcu128 -ip-dir := xilinx - -# Derive from board -bender-targets := -t fpga -t $(BOARD) -t cv64a6_imafdcsclic_sv39 -t cva6 -t mchan -t spatz -t cv32e40p_use_ff_regfile -bender-defines := -D FEATURE_ICACHE_STAT -D PRIVATE_ICACHE -D HIERARCHY_ICACHE_32BIT -D CLUSTER_ALIAS -D PULP_FPGA_EMUL - -VIVADO ?= vitis-2020.2 vivado +ip-dir := $(CAR_XIL_DIR)/xilinx # Select board specific variables ifeq ($(BOARD),vcu128) @@ -38,28 +29,18 @@ ifeq ($(BOARD),zcu102) ips-names := xlnx_mig_ddr4 xlnx_clk_wiz xlnx_vio endif -# Derive from ips -ips := $(addsuffix .xci ,$(basename $(ips-names))) -bender-targets := $(bender-targets) $(addprefix -t ,$(basename $(ips))) - -# Select islands -ifeq ($(GEN_PULP_CLUSTER), 1) -bender-defines += -D GEN_PULP_CLUSTER=1 -endif -ifeq ($(GEN_SAFETY_ISLAND), 1) -bender-defines += -D GEN_SAFETY_ISLAND=1 -endif -ifeq ($(GEN_SPATZ_CLUSTER), 1) -bender-defines += -D GEN_SPATZ_CLUSTER=1 -endif -ifeq ($(GEN_OPEN_TITAN), 1) -bender-defines += -D GEN_OPEN_TITAN=1 -endif +# Location of ip outputs +ips := $(addprefix $(CAR_XIL_DIR)/,$(addsuffix .xci ,$(basename $(ips-names)))) +# Derive bender args from enabled ips +xilinx_targs += $(foreach ip-name,$(ips-names),$(addprefix -t ,$(ip-name))) +xilinx_targs += $(addprefix -t ,$(BOARD)) -out := out +# Outputs +out := $(CAR_XIL_DIR)/out bit := $(out)/$(PROJECT)_top_xilinx.bit mcs := $(out)/$(PROJECT)_top_xilinx.mcs +# Vivado variables VIVADOENV ?= PROJECT=$(PROJECT) \ BOARD=$(BOARD) \ XILINX_PART=$(XILINX_PART) \ @@ -67,61 +48,59 @@ VIVADOENV ?= PROJECT=$(PROJECT) \ PORT=$(XILINX_PORT) \ HOST=$(XILINX_HOST) \ FPGA_PATH=$(FPGA_PATH) \ - BIT=$(BIT) - -# select IIS-internal tool commands if we run on IIS machines -ifneq (,$(wildcard /etc/iis.version)) - VIVADO ?= vitis-2020.2 vivado -else - VIVADO ?= vivado -endif - + BIT=$(bit) MODE ?= gui VIVADOFLAGS ?= -nojournal -mode $(MODE) -source scripts/prologue.tcl -all: $(bit) +car-xil-all: $(bit) # Generate mcs from bitstream $(mcs): $(bit) - $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/write_cfgmem.tcl -tclargs $@ $^ + cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/write_cfgmem.tcl -tclargs $@ $^ -$(bit): $(ips) scripts/add_sources.tcl +# Compile bitstream +$(bit): $(ips) $(CAR_XIL_DIR)/scripts/add_sources.tcl @mkdir -p $(out) - $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/run.tcl + cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/run.tcl cp $(PROJECT).runs/impl_1/$(PROJECT)* ./$(out) +# Generate ips %.xci: + @echo $@ + @echo $(CAR_XIL_DIR) @echo "Generating IP $(basename $@)" - cd $(ip-dir)/$(basename $@) && $(MAKE) clean && $(VIVADOENV) VIVADO="$(VIVADO)" $(MAKE) - cp $(ip-dir)/$(basename $@)/$(basename $@).srcs/sources_1/ip/$(basename $@)/$@ $@ + IP_NAME=$(basename $(notdir $@)) ; cd $(ip-dir)/$$IP_NAME && $(MAKE) clean && $(VIVADOENV) VIVADO="$(VIVADO)" $(MAKE) + IP_NAME=$(basename $(notdir $@)) ; cp $(ip-dir)/$$IP_NAME/$$IP_NAME.srcs/sources_1/ip/$$IP_NAME/$$IP_NAME.xci $@ -gui: +car-xil-gui: @echo "Starting $(vivado) GUI" - @$(VIVADOENV) $(VIVADO) -nojournal -mode gui $(PROJECT).xpr & + cd $(CAR_XIL_DIR) && @$(VIVADOENV) $(VIVADO) -nojournal -mode gui $(PROJECT).xpr & -program: #$(bit) +car-xil-program: #$(bit) @echo "Programming board $(BOARD) ($(XILINX_PART))" - $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/program.tcl + cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/program.tcl -clean: - rm -rf *.log *.jou *.str *.mif *.xci *.xpr .Xil/ $(out) $(PROJECT).cache $(PROJECT).hw $(PROJECT).ioplanning $(PROJECT).ip_user_files $(PROJECT).runs $(PROJECT).sim +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 -# Clean only top and copy back the IPs output here -rebuild_top: - ${MAKE} clean - rm -f scripts/add_sources.tcl - find xilinx -wholename "**/*.srcs/**/*.xci" | xargs -n 1 -I {} cp {} . +# Re-compile only top and not ips +car-xil-rebuild-top: + ${MAKE} car-xil-clean + find $(CAR_XIL_DIR)/xilinx -wholename "**/*.srcs/**/*.xci" | xargs -n 1 -I {} cp {} $(CAR_XIL_DIR) ${MAKE} $(bit) # Bender -scripts/add_sources.tcl: ../../Bender.yml - $(BENDER) script vivado $(bender-targets) $(bender-defines) > $@ +$(CAR_XIL_DIR)/scripts/add_sources.tcl: Bender.yml + $(BENDER) script vivado $(common_targs) $(xilinx_targs) $(common_defs) $(xilinx_defs) > $@ cp $@ $@.bak - ./scripts/overrides.sh $@ +# Remove ibex + grep -v -P "lowrisc_ip/ip/prim/rtl" $@ > $@-tmp + mv $@-tmp $@ + $(CAR_XIL_DIR)/scripts/overrides.sh $@ echo "" >> $@ echo "#Put the overrides folder at the head of the include list" >> $@ echo "set_property include_dirs [ \\" >> $@ echo " concat \"\$$ROOT/target/xilinx/src/overrides/include \" [get_property include_dirs [current_fileset]] \\" >> $@ echo "] [current_fileset]" >> $@ -.PHONY: clean sim +.PHONY: car-xil-gui car-xil-program car-xil-clean car-xil-rebuild-top car-xil-all