From e0a77d8c882a074e1a32fe2e83ec61fee73e61f2 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 3 Jan 2024 13:55:37 +0000 Subject: [PATCH 01/69] Rename lec folder to slec --- scripts/lec/clone_reference.sh | 22 ------------------- scripts/{lec => slec}/README.md | 0 .../check_lec.tcl => slec/cadence/lec.tcl} | 11 +++++----- scripts/{lec/lec.sh => slec/run.sh} | 0 .../check_lec.tcl => slec/synopsys/lec.tcl} | 0 5 files changed, 6 insertions(+), 27 deletions(-) delete mode 100755 scripts/lec/clone_reference.sh rename scripts/{lec => slec}/README.md (100%) rename scripts/{lec/cadence_conformal/check_lec.tcl => slec/cadence/lec.tcl} (74%) rename scripts/{lec/lec.sh => slec/run.sh} (100%) rename scripts/{lec/synopsys_formality/check_lec.tcl => slec/synopsys/lec.tcl} (100%) diff --git a/scripts/lec/clone_reference.sh b/scripts/lec/clone_reference.sh deleted file mode 100755 index 76a7510eb..000000000 --- a/scripts/lec/clone_reference.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# Copyright 2021 OpenHW Group -# -# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://solderpad.org/licenses/ -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -if [ ! -d "./golden_reference_design" ]; then - mkdir -p ./golden_reference_design - cd ./golden_reference_design - git clone https://github.com/openhwgroup/cv32e40p.git --branch cv32e40p_v1.0.0 - cd ../ -fi diff --git a/scripts/lec/README.md b/scripts/slec/README.md similarity index 100% rename from scripts/lec/README.md rename to scripts/slec/README.md diff --git a/scripts/lec/cadence_conformal/check_lec.tcl b/scripts/slec/cadence/lec.tcl similarity index 74% rename from scripts/lec/cadence_conformal/check_lec.tcl rename to scripts/slec/cadence/lec.tcl index d8b918a36..7d527ac4b 100644 --- a/scripts/lec/cadence_conformal/check_lec.tcl +++ b/scripts/slec/cadence/lec.tcl @@ -11,12 +11,13 @@ // 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. +set summary_log $::env(summary_log) -read_design -SV -replace -noelaborate -golden -File ../golden.src +read_design -SV -replace -noelaborate -golden -File ./golden.src elaborate_design -golden -read_design -SV -replace -noelaborate -revised -File ../revised.src +read_design -SV -replace -noelaborate -revised -File ./revised.src elaborate_design -revised @@ -31,8 +32,8 @@ write_hier_compare_dofile hier_compare_r2r.do -constraint -replace run_hier_compare hier_compare_r2r.do -ROOT_module cv32e40p_core cv32e40p_core -report_hier_compare_result -all -usage > ./reports/result.rpt -report_hier_compare_result -NONEQuivalent -usage > ./reports/result_noneq.rpt -report_verification -verbose -hier > ./reports/result_verfication.rpt +report_hier_compare_result -all -usage > $sumary_log +report_verification -verbose -hier >> $sumary_log +report_hier_compare_result -NONEQuivalent -usage > $sumary_log.noneq.rpt exit 0 diff --git a/scripts/lec/lec.sh b/scripts/slec/run.sh similarity index 100% rename from scripts/lec/lec.sh rename to scripts/slec/run.sh diff --git a/scripts/lec/synopsys_formality/check_lec.tcl b/scripts/slec/synopsys/lec.tcl similarity index 100% rename from scripts/lec/synopsys_formality/check_lec.tcl rename to scripts/slec/synopsys/lec.tcl From c05040dd67d8d59e1253f6ad1a8ac042c36f2e50 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 8 Jan 2024 10:50:19 +0100 Subject: [PATCH 02/69] RTL LINT scripts. Signed-off-by: Pascal Gouedo --- .gitignore | 6 + scripts/lint/README.md | 28 +++++ scripts/lint/autocheck_common_rules.do | 14 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ .../cv32e40p_config_pkg.sv | 19 +++ scripts/lint/cv32e40p_wrapper.sv | 113 ++++++++++++++++++ scripts/lint/formal_lint_rules.do | 16 +++ scripts/lint/lint.sh | 60 ++++++++++ scripts/lint/proc_dumpAutoCheckSummary.tcl | 74 ++++++++++++ scripts/lint/qverify_analysis.do | 8 ++ scripts/lint/qverify_autocheck.do | 4 + 18 files changed, 494 insertions(+) create mode 100644 scripts/lint/README.md create mode 100644 scripts/lint/autocheck_common_rules.do create mode 100644 scripts/lint/config_0p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_0z_0lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_0z_1lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_0z_2lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_1z_0lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_1z_1lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_1z_2lat_0c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/config_1p_1f_1z_2lat_1c/cv32e40p_config_pkg.sv create mode 100644 scripts/lint/cv32e40p_wrapper.sv create mode 100644 scripts/lint/formal_lint_rules.do create mode 100755 scripts/lint/lint.sh create mode 100644 scripts/lint/proc_dumpAutoCheckSummary.tcl create mode 100644 scripts/lint/qverify_analysis.do create mode 100644 scripts/lint/qverify_autocheck.do diff --git a/.gitignore b/.gitignore index ef351b194..66eb251ac 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,9 @@ TAGS /build /Bender.lock /Bender.local +golden_reference_design +golden.src +revised.src +cadence_conformal +synopsys_formality +questa_autocheck diff --git a/scripts/lint/README.md b/scripts/lint/README.md new file mode 100644 index 000000000..8aade066c --- /dev/null +++ b/scripts/lint/README.md @@ -0,0 +1,28 @@ +# RTL source Lint + +This folder contains LINT scripts that runs using SiemensEDA Questa AutoCheck tool. It requires SiemensEDA QuestaSim to first compile the design. + +Those scripts allow to check RTL coding quality using common guidelines and rules. It can find syntax errors or issues leading to bad/incorrect synthesis (like latches in combinational process). +Common practice is to launch LINT check prior to committing RTL sources to git repository. + +As cv32e40p\_top has 5 parameters and to be able to check different parameters values, a new top level module (cv32e40p\_wrapper) has been created together with some predefined configuration packages (in config\_?p\_?f\_?z\_?lat\_??c directories). + +Configuration directory naming style is: +- \_?p : PULP enabled or not (0 or 1) +- \_?f : FPU enabled or not (0 or 1) +- \_?z : ZFINX enabled or not (0 or 1) +- \_?lat : FPU instructions latency (0, 1 or 2) +- \_?c : PULP\_CLUSTER enabled or not (0 or 1) + +### Running the script + +From a shell, please execute: + +``` +./lint.sh 1p_0f_0z_0lat_0c +``` + +The script uses `../../rtl` as design sources to check. + +Intermediate logs are visible in `questa_autocheck/config_?p_?f_?z_?lat_?c` and `questa_autocheck/config_?p_?f_?z_?lat_?c/formal_lint_out` and final lint report in `questa_autocheck/config_?p_?f_?z_?lat_?c/formal_lint.rpt` + diff --git a/scripts/lint/autocheck_common_rules.do b/scripts/lint/autocheck_common_rules.do new file mode 100644 index 000000000..f977f2cd7 --- /dev/null +++ b/scripts/lint/autocheck_common_rules.do @@ -0,0 +1,14 @@ +autocheck enable +autocheck disable -type ARITH_OVERFLOW_SUB +autocheck disable -type ARITH_OVERFLOW_VAL +autocheck disable -type CASE_DEFAULT +autocheck disable -type DECLARATION_UNUSED_UNDRIVEN +autocheck disable -type FUNCTION_INCOMPLETE_ASSIGN +autocheck disable -type INDEX_UNREACHABLE +autocheck disable -type INIT_X_OPTIMISM +autocheck disable -type INIT_X_PESSIMISM +autocheck disable -type INIT_X_UNRESOLVED +autocheck disable -type INIT_X_UNRESOLVED_MEM +autocheck disable -type REG_RACE +autocheck disable -type REG_STUCK_AT +configure message severity fatal -id elaboration-835 diff --git a/scripts/lint/config_0p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_0p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..aeb194c04 --- /dev/null +++ b/scripts/lint/config_0p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 0; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 0; + parameter int FPU_ADDMUL_LAT = 0; + parameter int FPU_OTHERS_LAT = 0; + parameter bit ZFINX = 0; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..03894df90 --- /dev/null +++ b/scripts/lint/config_1p_0f_0z_0lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 0; + parameter int FPU_ADDMUL_LAT = 0; + parameter int FPU_OTHERS_LAT = 0; + parameter bit ZFINX = 0; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_0z_0lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_0z_0lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..fc7ba9e7c --- /dev/null +++ b/scripts/lint/config_1p_1f_0z_0lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 0; + parameter int FPU_OTHERS_LAT = 0; + parameter bit ZFINX = 0; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_0z_1lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_0z_1lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..c74225582 --- /dev/null +++ b/scripts/lint/config_1p_1f_0z_1lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 1; + parameter int FPU_OTHERS_LAT = 1; + parameter bit ZFINX = 0; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_0z_2lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_0z_2lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..e17cc8b70 --- /dev/null +++ b/scripts/lint/config_1p_1f_0z_2lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 2; + parameter int FPU_OTHERS_LAT = 2; + parameter bit ZFINX = 0; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_1z_0lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_1z_0lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..0d28e20ef --- /dev/null +++ b/scripts/lint/config_1p_1f_1z_0lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 0; + parameter int FPU_OTHERS_LAT = 0; + parameter bit ZFINX = 1; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_1z_1lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_1z_1lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..e47e861c1 --- /dev/null +++ b/scripts/lint/config_1p_1f_1z_1lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 1; + parameter int FPU_OTHERS_LAT = 1; + parameter bit ZFINX = 1; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_1z_2lat_0c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_1z_2lat_0c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..af5b4b732 --- /dev/null +++ b/scripts/lint/config_1p_1f_1z_2lat_0c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 0; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 2; + parameter int FPU_OTHERS_LAT = 2; + parameter bit ZFINX = 1; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/config_1p_1f_1z_2lat_1c/cv32e40p_config_pkg.sv b/scripts/lint/config_1p_1f_1z_2lat_1c/cv32e40p_config_pkg.sv new file mode 100644 index 000000000..f0a16fe74 --- /dev/null +++ b/scripts/lint/config_1p_1f_1z_2lat_1c/cv32e40p_config_pkg.sv @@ -0,0 +1,19 @@ +`ifndef CV32E40P_CONFIG_PKG +`define CV32E40P_CONFIG_PKG + +package cv32e40p_config_pkg; + + parameter bit COREV_PULP = 1; + parameter bit COREV_CLUSTER = 1; + parameter bit FPU = 1; + parameter int FPU_ADDMUL_LAT = 2; + parameter int FPU_OTHERS_LAT = 2; + parameter bit ZFINX = 1; + parameter int INSTR_ADDR_MEM_WIDTH = 13; + parameter int DATA_ADDR_MEM_WIDTH = 13; + +endpackage + +`endif + + diff --git a/scripts/lint/cv32e40p_wrapper.sv b/scripts/lint/cv32e40p_wrapper.sv new file mode 100644 index 000000000..760712c6f --- /dev/null +++ b/scripts/lint/cv32e40p_wrapper.sv @@ -0,0 +1,113 @@ +// 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. + +// Top file instantiating a CV32E40P top for lint + +module cv32e40p_wrapper ( + // Clock and Reset + input logic clk_i, + input logic rst_ni, + + input logic pulp_clock_en_i, // PULP clock enable (only used if COREV_CLUSTER = 1) + input logic scan_cg_en_i, // Enable all clock gates for testing + + // Core ID, Cluster ID, debug mode halt address and boot address are considered more or less static + input logic [31:0] boot_addr_i, + input logic [31:0] mtvec_addr_i, + input logic [31:0] dm_halt_addr_i, + input logic [31:0] hart_id_i, + input logic [31:0] dm_exception_addr_i, + + // Instruction memory interface + output logic instr_req_o, + input logic instr_gnt_i, + input logic instr_rvalid_i, + output logic [31:0] instr_addr_o, + input logic [31:0] instr_rdata_i, + + // Data memory interface + output logic data_req_o, + input logic data_gnt_i, + input logic data_rvalid_i, + output logic data_we_o, + output logic [ 3:0] data_be_o, + output logic [31:0] data_addr_o, + output logic [31:0] data_wdata_o, + input logic [31:0] data_rdata_i, + + // Interrupt inputs + input logic [31:0] irq_i, // CLINT interrupts + CLINT extension interrupts + output logic irq_ack_o, + output logic [ 4:0] irq_id_o, + + // Debug Interface + input logic debug_req_i, + output logic debug_havereset_o, + output logic debug_running_o, + output logic debug_halted_o, + + // CPU Control Signals + input logic fetch_enable_i, + output logic core_sleep_o +); + + import cv32e40p_config_pkg::*; + + // Instantiate the Core + cv32e40p_top #( + .COREV_PULP (COREV_PULP), + .COREV_CLUSTER (COREV_CLUSTER), + .FPU (FPU), + .FPU_ADDMUL_LAT (FPU_ADDMUL_LAT), + .FPU_OTHERS_LAT (FPU_OTHERS_LAT), + .ZFINX (ZFINX), + .NUM_MHPMCOUNTERS(1) + ) top_i ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .pulp_clock_en_i(pulp_clock_en_i), + .scan_cg_en_i (scan_cg_en_i), + + .boot_addr_i (boot_addr_i), + .mtvec_addr_i (mtvec_addr_i), + .dm_halt_addr_i (dm_halt_addr_i), + .hart_id_i (hart_id_i), + .dm_exception_addr_i(dm_exception_addr_i), + + .instr_req_o (instr_req_o), + .instr_gnt_i (instr_gnt_i), + .instr_rvalid_i(instr_rvalid_i), + .instr_addr_o (instr_addr_o), + .instr_rdata_i (instr_rdata_i), + + .data_req_o (data_req_o), + .data_gnt_i (data_gnt_i), + .data_rvalid_i(data_rvalid_i), + .data_we_o (data_we_o), + .data_be_o (data_be_o), + .data_addr_o (data_addr_o), + .data_wdata_o (data_wdata_o), + .data_rdata_i (data_rdata_i), + + .irq_i (irq_i), + .irq_ack_o(irq_ack_o), + .irq_id_o (irq_id_o), + + .debug_req_i (debug_req_i), + .debug_havereset_o(debug_havereset_o), + .debug_running_o (debug_running_o), + .debug_halted_o (debug_halted_o), + + .fetch_enable_i(fetch_enable_i), + .core_sleep_o (core_sleep_o) + ); + +endmodule diff --git a/scripts/lint/formal_lint_rules.do b/scripts/lint/formal_lint_rules.do new file mode 100644 index 000000000..a52229177 --- /dev/null +++ b/scripts/lint/formal_lint_rules.do @@ -0,0 +1,16 @@ +# define all clocks +netlist clock clk_i -period 100 -waveform 0 50 + +# define all reset +netlist reset rst_ni -active_low -async + +# define clock domain for reset +netlist port domain rst_ni -clock clk_i + +# define special case +netlist constant scan_cg_en_i 1'b0 +netlist constant pulp_clock_en_i 1'b0 + +# disable rules +autocheck disable -type FSM_DEADLOCK_STATE FSM_LOCKOUT_STATE + diff --git a/scripts/lint/lint.sh b/scripts/lint/lint.sh new file mode 100755 index 000000000..259f9dae6 --- /dev/null +++ b/scripts/lint/lint.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright 2023 OpenHW Group +# Copyright 2023 Dolphin Design +# +# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://solderpad.org/licenses/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contributor: Pascal Gouedo + +if [[ $# -eq 0 ]]; then + CONFIG=config_0p_0f_0z_0lat_0c +else + CONFIG=config_$1 + if [[ ! -d $CONFIG ]]; then + echo "Config $CONFIG does not exists." + exit + fi +fi +echo "Lint of $CONFIG" + +if [[ -d questa_autocheck/$CONFIG ]]; then + rm -rf questa_autocheck/$CONFIG +fi +mkdir -p questa_autocheck/$CONFIG + +# Creating RTL file list +if [[ $CONFIG == *1f* ]]; then + MANIFEST=cv32e40p_fpu_manifest +else + MANIFEST=cv32e40p_manifest +fi + +UPSTREAM_DIR=$(pwd)/../../rtl +echo "$upstream_dir" +sed -n '/^+incdir+/s:${DESIGN_RTL_DIR}:'"$UPSTREAM_DIR"':p' ../../$MANIFEST.flist > questa_autocheck/$CONFIG/inc_design.f +sed -n '1,/cv32e40p_sim_clock_gate/{s:^${DESIGN_RTL_DIR}:'"$UPSTREAM_DIR"':p}' ../../$MANIFEST.flist > questa_autocheck/$CONFIG/src_design.f +echo "$(pwd)/$CONFIG/cv32e40p_config_pkg.sv" >> questa_autocheck/$CONFIG/src_design.f +echo "$(pwd)/cv32e40p_wrapper.sv" >> questa_autocheck/$CONFIG/src_design.f + +cd questa_autocheck/$CONFIG + +# Compiling Verilog / SystemVerilog RTL files +vlog -64 -nologo -source -timescale "1 ns / 1 ps" -sv -f inc_design.f -f src_design.f -assertdebug -work design_lib |& tee compile_design.log + +# Launching formal lint analysis +qverify -licq -c -od formal_lint_out -do ../../qverify_analysis.do |& tee formal_lint.log + +# Launching formal lint AutoCheck Summary +qverify -licq -c -od formal_lint_out -do ../../qverify_autocheck.do + diff --git a/scripts/lint/proc_dumpAutoCheckSummary.tcl b/scripts/lint/proc_dumpAutoCheckSummary.tcl new file mode 100644 index 000000000..3c3f2f710 --- /dev/null +++ b/scripts/lint/proc_dumpAutoCheckSummary.tcl @@ -0,0 +1,74 @@ +proc dumpAutoCheckSummary { filename } { + namespace import -force Autocheck::* + if { [catch { set fp [open $filename a] } msg] } { + puts "Unable to open $filename : $msg" + exit 1 + } + + set typecnt 0 + #--------- Find types --------------------------------------- + set checks [GetChecks] + while { [set check [GetNext $checks]] != "" } { + set type [GetType $check] + set severity($type) [GetSeverity $check] + lappend types $type + } + set types [lsort [lrmdups $types]] + #--------- Collect data for each type ----------------------- + foreach type $types { + set cnt 0 + set cnt_waiv 0 + set cnt_viol 0 + set cnt_caut 0 + set cnt_inconcl 0 + set cnt_info 0 + set cnt_eval 0 + set cnt_off 0 + set cnt_def 0 + set checks [GetChecks] + while { [set check [GetNext $checks]] != "" } { + if {[GetType $check] == $type} { +# debug +#puts $fp "[GetType $check]" +#puts $fp "[GetStatus $check]" +#puts $fp "[GetSeverity $check]" + ### DM ### increment different counters depending of status + if {[GetStatus $check] == "Waived"} { + incr cnt_waiv + } else { + set Severity [GetSeverity $check] + switch $Severity { + Violation {incr cnt_viol} + Caution {incr cnt_caut} + Inconclusive {incr cnt_inconcl} + } + ### DM ### add other (off, ...) if needed + } + } + } + + ### DM ### only prints when waived exist / or when violation or inconclusive + if {$cnt_waiv != 0} { + puts $fp "# ** Waived:\t$type ($cnt_waiv)" + puts "# ** Waived:\t$type ($cnt_waiv)" + } + if {$cnt_viol != 0} { + puts $fp "# ** Violation:\t$type ($cnt_viol)" + puts "# ** Violation:\t$type ($cnt_viol)" + } + if {$cnt_caut != 0} { + puts $fp "# ** Caution:\t$type ($cnt_caut)" + puts "# ** Caution:\t$type ($cnt_caut)" + } + if {$cnt_inconcl != 0} { + puts $fp "# ** Inconclusive:\t$type ($cnt_inconcl)" + puts "# ** Inconclusive:\t$type ($cnt_inconcl)" + } + ### DM ### add other (caution, off, ...) if needed + + } + puts $fp "==============================================" + puts $fp " [llength $types] Types; [GetCount $checks] Checks" + close $fp +} + diff --git a/scripts/lint/qverify_analysis.do b/scripts/lint/qverify_analysis.do new file mode 100644 index 000000000..e66554992 --- /dev/null +++ b/scripts/lint/qverify_analysis.do @@ -0,0 +1,8 @@ +set top cv32e40p_wrapper +source ../../autocheck_common_rules.do +source ../../formal_lint_rules.do +autocheck report inconclusives +autocheck compile -work design_lib -d cv32e40p_wrapper -L design_lib -L work +autocheck verify -jobs 1 +exit + diff --git a/scripts/lint/qverify_autocheck.do b/scripts/lint/qverify_autocheck.do new file mode 100644 index 000000000..9bbcc18a4 --- /dev/null +++ b/scripts/lint/qverify_autocheck.do @@ -0,0 +1,4 @@ +autocheck load db formal_lint_out/autocheck_verify.db +source ../../proc_dumpAutoCheckSummary.tcl +dumpAutoCheckSummary formal_lint.rpt +exit From 28695f35fbc1321c48e9c48a379f00fe03f67e54 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 8 Jan 2024 16:05:51 +0100 Subject: [PATCH 03/69] RTL files header proposal. Signed-off-by: Pascal Gouedo --- scripts/lint/cv32e40p_wrapper.sv | 39 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/scripts/lint/cv32e40p_wrapper.sv b/scripts/lint/cv32e40p_wrapper.sv index 760712c6f..1f2449f19 100644 --- a/scripts/lint/cv32e40p_wrapper.sv +++ b/scripts/lint/cv32e40p_wrapper.sv @@ -1,24 +1,35 @@ // 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. - -// Top file instantiating a CV32E40P top for lint +// Copyright 2023 OpenHW Group +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 + +// Contributor(s): Pascal Gouedo, Dolphin Design +// +// Design Name: CV32E40P RTL Lint wrapper +// +// Description: Wrapper file instantiating CV32E40P top and importing +// a configuration package to be used for RTL LINT checks. module cv32e40p_wrapper ( // Clock and Reset input logic clk_i, input logic rst_ni, - input logic pulp_clock_en_i, // PULP clock enable (only used if COREV_CLUSTER = 1) - input logic scan_cg_en_i, // Enable all clock gates for testing + input logic pulp_clock_en_i, + input logic scan_cg_en_i, - // Core ID, Cluster ID, debug mode halt address and boot address are considered more or less static input logic [31:0] boot_addr_i, input logic [31:0] mtvec_addr_i, input logic [31:0] dm_halt_addr_i, @@ -43,7 +54,7 @@ module cv32e40p_wrapper ( input logic [31:0] data_rdata_i, // Interrupt inputs - input logic [31:0] irq_i, // CLINT interrupts + CLINT extension interrupts + input logic [31:0] irq_i, output logic irq_ack_o, output logic [ 4:0] irq_id_o, From 71d83549e1a9b0f29122cf5962fdf9926ea26020 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 10 Jan 2024 15:29:10 +0100 Subject: [PATCH 04/69] Header corrected. Signed-off-by: Pascal Gouedo --- scripts/lint/cv32e40p_wrapper.sv | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/lint/cv32e40p_wrapper.sv b/scripts/lint/cv32e40p_wrapper.sv index 1f2449f19..135ee4fa9 100644 --- a/scripts/lint/cv32e40p_wrapper.sv +++ b/scripts/lint/cv32e40p_wrapper.sv @@ -1,5 +1,4 @@ -// Copyright 2018 ETH Zurich and University of Bologna. -// Copyright 2023 OpenHW Group +// Copyright 2024 OpenHW Group and Dolphin Design // // Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // Contributor(s): Pascal Gouedo, Dolphin Design // From 92b8040b1a3d0ecc32bc6767047c9bf8a0d264f5 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 12 Jan 2024 12:59:58 +0000 Subject: [PATCH 05/69] SEC/LEC scripts refactor --- scripts/slec/README.md | 72 +++++++----- scripts/slec/cadence/lec.tcl | 11 +- scripts/slec/cadence/sec.tcl | 40 +++++++ scripts/slec/run.sh | 214 +++++++++++++++++++++++----------- scripts/slec/siemens/Makefile | 41 +++++++ scripts/slec/synopsys/lec.tcl | 30 ++--- 6 files changed, 289 insertions(+), 119 deletions(-) create mode 100644 scripts/slec/cadence/sec.tcl create mode 100755 scripts/slec/siemens/Makefile diff --git a/scripts/slec/README.md b/scripts/slec/README.md index 51befbc2f..ff5311322 100644 --- a/scripts/slec/README.md +++ b/scripts/slec/README.md @@ -1,51 +1,61 @@ -# Logic Equivalence Checking (LEC) +# Sequential Logic Equivalence Checking (SLEC) -This folder contains a LEC script that runs on both -Synopsys Formality and Cadence Design Systems Conformal. +This folder contains a SLEC script that runs: -This script allows to catch non-logical equivalent changes on the RTL which are forbidden -on the verified paramter set. +- LEC: Synopsys Formality and Cadence Design Systems Conformal. +- SEC: Siemens SLEC App Please have a look at: https://cv32e40p.readthedocs.io/en/latest/core_versions/ -The `cv32e40p_v1.0.0` tag refers to the frozen RTL. The RTL has been verified and frozen on a given value of the input parameter of the design. Unless a bug is found, it is forbidden to change the RTL -in a non-logical equivalent manner for PPA optimizations of any other change. -Instead, it is possible to change the RTL on a different value of the parameter set, which has not been verified yet. -For example, it is possible to change the RTL design when the `FPU` parameter is set to 1 as this configuration has not been verified yet. However, the design must be logically equivalent when the parameter is set back to 0. -It is possible to change the `apu` interface and the `pulp_clock_en_i` signal on the frozen parameter set as these -signals are not used when the parameter `FPU` and `PULP_CLUSTER` are set to 0, respectively. - -The current scripts have been tried on Synopsys Formality `2021.06-SP5` and Cadence Design Systems Conformal `20.20` on a 64 bit executable. +The `cv32e40p_v1.0.0` tag refers to the frozen RTL. The RTL has been verified +and frozen on a given value of the input parameter of the design. Unless a bug +is found, it is forbidden to change the RTL in a non-logical equivalent manner +for PPA optimizations of any other change. +Instead, it is possible to change the RTL on a different value of the parameter +set, which has not been verified yet. +For example, it is possible to change the RTL design when the `FPU` parameter is +set to 1 as this configuration has not been verified yet. However, the design +must be logically equivalent when the parameter is set back to 0. +It is possible to change the `apu` interface and the `pulp_clock_en_i` signal on +the frozen parameter set as these signals are not used when the parameter `FPU` +and `PULP_CLUSTER` are set to 0, respectively. + +The current scripts have been tried on Synopsys Formality `2021.06-SP5` , +Cadence Design Systems Conformal `20.20` and Siemens SLEC App `2023.4`. ### Running the script -From a bash shell, please execute: +From a bash shell using LEC, please execute: ``` -./lec.sh synopsys +./run.sh -t synopsys -p lec ``` or -``` -./lec.sh cadence -``` + ``` + ./run.sh -t cadence -p lec + ``` -to use one of the tools. synopsys is used by default if no tool is specified,. + From a bash shell to use SEC, please execute: + ``` + ./run.sh -t siemens -p sec + ``` -Use `sh ./les.sh {synopsys, cadence}` if you run it from a tcsh shell. + By default `cv32e40p_core` is used as a top module, if you want to use + another one set the `TOP_MODULE` environment variable. -The script clones the `cv32e40p_v1.0.0` tag of the core as a golden reference, and uses the current repository's `rtl` as revised version. + The script clones the `cv32e40p_v1.0.0` tag of the core as a golden reference, + and uses the current repository's `rtl` as revised version. -If you want to use another golden reference rtl, Set the `GOLDEN_RTL` enviromental variable to the new rtl before calling the `lec.sh` script. + If you want to use another golden reference RTL, set the `GOLDEN_RTL` + environmental variable to the new RTL before calling the `run.sh` script. -``` -export GOLDEN_RTL=YOUR_GOLDEN_CORE_RTL_PATH -``` -or + ``` + export GOLDEN_RTL=YOUR_GOLDEN_CORE_RTL_PATH + ``` + or -``` -setenv GOLDEN_RTL YOUR_GOLDEN_CORE_RTL_PATH -``` -If the script succeeds, it returns 0, otherwise -1. + ``` + setenv GOLDEN_RTL YOUR_GOLDEN_CORE_RTL_PATH + ``` -The `check_lec.tcl` scripts in the tool specific folders are executed on the tools to perform `RTL to RTL` logic equivalence checking. diff --git a/scripts/slec/cadence/lec.tcl b/scripts/slec/cadence/lec.tcl index 7d527ac4b..3cc8bea7b 100644 --- a/scripts/slec/cadence/lec.tcl +++ b/scripts/slec/cadence/lec.tcl @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. set summary_log $::env(summary_log) +set top_module $::env(top_module) read_design -SV -replace -noelaborate -golden -File ./golden.src @@ -21,7 +22,7 @@ read_design -SV -replace -noelaborate -revised -File ./revised.src elaborate_design -revised -report_design_data > ./reports/report_design.log +report_design_data add_ignored_outputs apu_req_o -Both add_ignored_outputs apu_operands_o* -Both @@ -30,10 +31,10 @@ add_ignored_outputs apu_flags_o* -Both write_hier_compare_dofile hier_compare_r2r.do -constraint -replace -run_hier_compare hier_compare_r2r.do -ROOT_module cv32e40p_core cv32e40p_core +run_hier_compare hier_compare_r2r.do -ROOT_module $top_module $top_module -report_hier_compare_result -all -usage > $sumary_log -report_verification -verbose -hier >> $sumary_log -report_hier_compare_result -NONEQuivalent -usage > $sumary_log.noneq.rpt +report_hier_compare_result -all -usage > $summary_log +report_verification -verbose -hier >> $summary_log +report_hier_compare_result -NONEQuivalent -usage > $summary_log.noneq.rpt exit 0 diff --git a/scripts/slec/cadence/sec.tcl b/scripts/slec/cadence/sec.tcl new file mode 100644 index 000000000..7107eb9e3 --- /dev/null +++ b/scripts/slec/cadence/sec.tcl @@ -0,0 +1,40 @@ +# Copyright 2021 OpenHW Group +# +# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://solderpad.org/licenses/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set summary_log $::env(summary_log) +set top_module $::env(top_module) + +check_sec -setup -spec_top $top_module -imp_top $top_module \ + -spec_analyze "-sv -f ./golden.src" \ + -imp_analyze "-sv -f ./revised.src"\ + -auto_map_reset_x_values + + +clock clk_i +reset ~rst_ni + +check_sec -map -auto + +if {"$top_module" == "cv32e40p_core"} { + check_sec -waive -waive_signals ex_stage_i.alu_i.ff_one_i.sel_nodes + check_sec -waive -waive_signals cv32e40p_core_imp.ex_stage_i.alu_i.ff_one_i.sel_nodes + + check_sec -waive -waive_signals ex_stage_i.alu_i.ff_one_i.index_nodes + check_sec -waive -waive_signals cv32e40p_core_imp.ex_stage_i.alu_i.ff_one_i.index_nodes +} + +check_sec -prove + +check_sec -signoff -get_valid_status -summary -file $summary_log + +exit 0 diff --git a/scripts/slec/run.sh b/scripts/slec/run.sh index 5e9f7387f..5ecd62f88 100755 --- a/scripts/slec/run.sh +++ b/scripts/slec/run.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2021 OpenHW Group +# Copyright 2023 OpenHW Group # # Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,85 +14,159 @@ # See the License for the specific language governing permissions and # limitations under the License. -if [[ -z "${GOLDEN_RTL}" ]]; then - echo "The env variable GOLDEN_RTL is empty." - echo "Cloning Golden Design...." - sh clone_reference.sh - export GOLDEN_RTL=$(pwd)/golden_reference_design/cv32e40p/rtl -else - echo "Using ${GOLDEN_RTL} as reference design" +usage() { # Function: Print a help message. + echo "Usage: $0 [ -t {cadence,synopsys,siemens} -p {sec,lec} ]" 1>&2 +} + +exit_abnormal() { # Function: Exit with error. + usage + exit 1 +} + +not_implemented() { + echo "$1 does not have yet $2 implemented" + exit 1 +} + +print_log() { + echo "[LOG] $1" +} + +while getopts "t:p:" flag +do + case "${flag}" in + t) + target_tool=${OPTARG} + ;; + p) + target_process=${OPTARG} + ;; + :) + exit_abnormal + ;; + *) + exit_abnormal + ;; + ?) + exit_abnormal + ;; + esac +done + +if [[ "${target_tool}" != "cadence" && "${target_tool}" != "synopsys" && "${target_tool}" != "siemens" ]]; then + exit_abnormal +fi + +if [[ "${target_process}" != "sec" && "${target_process}" != "lec" ]]; then + exit_abnormal +fi + +if [ -z "${REF_REPO}" ]; then + print_log "Empty REF_REPO env variable" + REF_REPO=https://github.com/openhwgroup/cv32e40p.git + REF_FOLDER=ref_design + REF_BRANCH=master + print_log " * Setting REF_REPO ${REF_REPO}" + print_log " * Setting REF_FOLDER ${REF_FOLDER}" + print_log " * Setting REF_BRANCH ${REF_BRANCH}" fi -REVISED_RTL=$(pwd)/../../rtl - - -var_golden_rtl=$(awk '{ if ($0 ~ "sv" && $0 !~ "incdir" && $0 !~ "wrapper" && $0 !~ "tracer") print $0 }' $GOLDEN_RTL/../cv32e40p_manifest.flist | awk -v rtlpath=$GOLDEN_RTL -F "/" '{$1=rtlpath} OFS="/"') - -var_revised_rtl=$(awk '{ if ($0 ~ "sv" && $0 !~ "incdir" && $0 !~ "wrapper" && $0 !~ "_top" && $0 !~ "tracer") print $0 }' $REVISED_RTL/../cv32e40p_manifest.flist | awk -v rtlpath=$REVISED_RTL -F "/" '{$1=rtlpath} OFS="/"') - -echo $var_golden_rtl > golden.src -echo $var_revised_rtl > revised.src - -if [[ $# -gt 0 ]]; then - if [[ $1 == "cadence" ]]; then - echo "Using Cadence Conformal" - if [[ -d ./cadence_conformal/reports ]]; then - rm -rf ./cadence_conformal/reports - mkdir ./cadence_conformal/reports - else - mkdir ./cadence_conformal/reports - fi - else - echo "Using Synopsys Formality" - if [[ -d ./synopsys_formality/reports ]]; then - rm -rf ./synopsys_formality/reports - mkdir ./synopsys_formality/reports - else - mkdir ./synopsys_formality/reports - fi +RTL_FOLDER=$(readlink -f ../..) + +FLIST=cv32e40p_manifest.flist + +if [[ -z "${TOP_MODULE}" ]]; then + print_log "Empty TOP_MODULE env variable" + TOP_MODULE=cv32e40p_core + print_log " * Setting TOP_MODULE ${TOP_MODULE}" +fi + +if [ ! -d ./reports/ ]; then + mkdir -p ./reports/ +fi + +if [[ -z "${GOLDEN_RTL}" ]]; then + print_log "The env variable GOLDEN_RTL is empty." + if [ ! -d "./${REF_FOLDER}" ]; then + print_log " * Cloning Golden Design...." + git clone $REF_REPO --single-branch -b $REF_BRANCH $REF_FOLDER; + git -C ${REF_FOLDER} checkout $REF_COMMIT fi + export GOLDEN_RTL=$(pwd)/${REF_FOLDER}/rtl else - echo "No tool specified...." - echo "Using Synopsys Formality" - if [[ -d ./synopsys_formality/reports ]]; then - rm -rf ./synopsys_formality/reports - mkdir ./synopsys_formality/reports - else - mkdir ./synopsys_formality/reports - fi + print_log "${target_process^^}: Using ${GOLDEN_RTL} as reference design" fi -if [[ $1 == "cadence" ]]; then - echo "Running Cadence Conformal" - cd ./cadence_conformal - lec -Dofile check_lec.tcl -TclMode -LOGfile cv32e40p_lec_log.log -NoGUI -xl - if [ -f "./reports/result.rpt" ]; then - NonLec=$(awk '{ if ($0 ~ "Hierarchical compare : Equivalent") print "0"}' ./reports/result.rpt) - else - echo "FATAL: could not find reports..." - NonLec="-1" +REVISED_DIR=$RTL_FOLDER +REVISED_FLIST=$(pwd)/revised.src + +GOLDEN_DIR=$(readlink -f ./${REF_FOLDER}/) +GOLDEN_FLIST=$(pwd)/golden.src + +var_golden_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper") print $0 }' ${GOLDEN_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${GOLDEN_DIR}"'/rtl/|') + +var_revised_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper") print $0 }' ${REVISED_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${REVISED_DIR}"'/rtl/|') + +print_log "Generating GOLDEN flist in path: ${GOLDEN_FLIST}" +echo $var_golden_rtl > ${GOLDEN_FLIST} +print_log "Generating REVISED flist in path: ${REVISED_FLIST}" +echo $var_revised_rtl > ${REVISED_FLIST} + +export report_dir=$(readlink -f $(dirname "${BASH_SOURCE[0]}"))/reports/$(date +%Y-%m-%d)/ + +if [[ -d ${report_dir} ]]; then + rm -rf ${report_dir} +fi +mkdir -p ${report_dir} + +export tcl_script=$(readlink -f $(dirname "${BASH_SOURCE[0]}"))/${target_tool}/${target_process}.tcl +export output_log=${report_dir}/output.${target_tool}-${target_process}.log +export summary_log=${report_dir}/summary.${target_tool}-${target_process}.log + +export expected_grep_exit_code=1 + +if [[ "${target_tool}" == "cadence" ]]; then + + if [[ "${target_process}" == "lec" ]]; then + lec -Dofile ${tcl_script} -TclMode -NoGUI -xl | tee ${output_log} + regex_string="Hierarchical compare : Equivalent" + elif [[ "${target_process}" == "sec" ]]; then + jg -sec -proj ${report_dir} -batch -tcl ${tcl_script} -define report_dir ${report_dir} | tee ${output_log} + regex_string="Overall SEC status[ ]+- Complete" fi - cd ../ -else - echo "Running Synopsys Formality" - cd ./synopsys_formality - fm_shell -f check_lec.tcl |& tee cv32e40p_lec_log.log - if [ -f "./reports/verify.rpt" ]; then - NonLec=$(awk '{ if ($0 ~ "Verification SUCCEEDED") print "0"}' ./reports/verify.rpt) - else - echo "FATAL: could not find reports..." - NonLec="-1" + +elif [[ "${target_tool}" == "synopsys" ]]; then + + if [[ "${target_process}" == "lec" ]]; then + fm_shell -work_path $report_dir/work/ -f ${tcl_script} | tee ${output_log} + regex_string="Verification SUCCEEDED" + elif [[ "${target_process}" == "sec" ]]; then + not_implemented ${target_tool} ${target_process} + fi + +elif [[ "${target_tool}" == "siemens" ]]; then + + if [[ "${target_process}" == "lec" ]]; then + not_implemented ${target_tool} ${target_process} + elif [[ "${target_process}" == "sec" ]]; then + make -C siemens/ run_sec_vl SPEC_FLIST=${GOLDEN_FLIST} IMPL_FLIST=${REVISED_FLIST} TOP_MODULE=${TOP_MODULE} SUMMARY_LOG=${summary_log} | tee ${output_log} + regex_string="^Fired" + expected_grep_exit_code=0 fi - cd ../ + fi -if [[ $NonLec == "0" ]]; then - echo "The DESIGN IS LOGICALLY EQUIVALENT" -else - NonLec="-1" - echo "The DESIGN IS NOT LOGICALLY EQUIVALENT" +if [[ ! -f ${output_log} || ! -f ${summary_log} ]]; then + print_log "Something went wrong during the process" + exit 1 fi -echo "$0 returns $NonLec" +grep -Eq "${regex_string}" ${summary_log}; grep_exit_code=$? + +if [[ ${grep_exit_code} != ${expected_grep_exit_code} ]]; then + print_log "${target_process^^}: THE DESIGN IS EQUIVALENT" +else + print_log "${target_process^^}: THE DESIGN IS NOT EQUIVALENT" +fi -exit $NonLec +exit ${exit_code} diff --git a/scripts/slec/siemens/Makefile b/scripts/slec/siemens/Makefile new file mode 100755 index 000000000..15e281f93 --- /dev/null +++ b/scripts/slec/siemens/Makefile @@ -0,0 +1,41 @@ +############################################################################## +# Copyright 2006-Mentor Graphics Corporation +# +# THIS SOFTWARE AND RELATED DOCUMENTATION +# ARE PROPRIETARY AND CONFIDENTIAL TO SIEMENS. +# © 2023 Siemens + +INSTALL := $(shell qverify -install_path) +VLIB = $(INSTALL)/modeltech/linux_x86_64/vlib +VMAP = $(INSTALL)/modeltech/linux_x86_64/vmap +VLOG = $(INSTALL)/modeltech/linux_x86_64/vlog +VCOM = $(INSTALL)/modeltech/linux_x86_64/vcom + +run_sec_vl: clean run_sec + +run_sec: + $(VLIB) work_ip_orig + $(VLIB) work_ip_mod + $(VMAP) work_spec work_ip_orig + $(VMAP) work_impl work_ip_mod + $(VLOG) -sv -f $(SPEC_FLIST) -work work_spec + $(VLOG) -sv -f $(IMPL_FLIST) -work work_impl + + qverify -c -od log -do " \ + onerror { exit 1 }; \ + slec configure -spec -d $(TOP_MODULE) -work work_spec; \ + slec configure -impl -d $(TOP_MODULE) -work work_impl; \ + slec compile; \ + slec verify -timeout 10m; \ + exit" + @cp log/slec_verify.log $(SUMMARY_LOG) + + +debug: + qverify log/slec.db + +clean: + qverify_clean + rm -rf log* work* *.rpt modelsim.ini .visualizer visualizer* + + diff --git a/scripts/slec/synopsys/lec.tcl b/scripts/slec/synopsys/lec.tcl index 612aba257..1f6b41936 100644 --- a/scripts/slec/synopsys/lec.tcl +++ b/scripts/slec/synopsys/lec.tcl @@ -1,22 +1,26 @@ -set synopsys_auto_setup true +set synopsys_auto_setup true +set summary_log $::env(summary_log) +set top_module $::env(top_module) -read_sverilog -container r -libname WORK -12 -f ../golden.src -set_top r:/WORK/cv32e40p_core +read_sverilog -container r -libname WORK -12 -f golden.src +set_top r:/WORK/$top_module -read_sverilog -container i -libname WORK -12 -f ../revised.src -set_top i:/WORK/cv32e40p_core +read_sverilog -container i -libname WORK -12 -f revised.src +set_top i:/WORK/$top_module match > ./reports/match.rpt -set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_req_o -set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_operands_o* -set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_op_o* -set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_flags_o* +if {"$top_module" == "cv32e40p_core"} { + set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_req_o + set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_operands_o* + set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_op_o* + set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_flags_o* +} -verify > ./reports/verify.rpt +verify > $summary_log -report_aborted_points > ./reports/aborted_points.rpt -report_failing_points > ./reports/failing_points.rpt -analyze_points -failing > ./reports/analyze.rpt +report_aborted_points > $summary_log.aborted_points.rpt +report_failing_points > $summary_log.failing_points.rpt +analyze_points -failing >> $summary_log exit From 084ffa158047c7e0f00e4b716b81730204dba541 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 30 Jan 2024 17:45:38 +0100 Subject: [PATCH 06/69] Text font changed to black for User Manaul html search window. Signed-off-by: Pascal Gouedo --- docs/source/_static/css/custom.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css index 3ae7d9ae9..34a579c86 100644 --- a/docs/source/_static/css/custom.css +++ b/docs/source/_static/css/custom.css @@ -1,3 +1,9 @@ .no-scrollbar-table td { white-space: normal !important; } +.wy-side-nav-search>div.version { + color:black +} +.wy-side-nav-search>a.icon.icon-home { + color:black +} From 376c854954624c283676284045b781762d569c15 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 30 Jan 2024 17:46:51 +0100 Subject: [PATCH 07/69] Updated copyright date, navigation button added on top, removed sphinx text and link to rst file. Signed-off-by: Pascal Gouedo --- docs/source/conf.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index dbb7b0203..bb18fa6a2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,7 +38,7 @@ # -- Project information ----------------------------------------------------- project = u'CORE-V CV32E40P User Manual' -copyright = u'2023, OpenHW Group' +copyright = u'2024, OpenHW Group' author = u'PULP Platform and OpenHW Group' # The short X.Y version @@ -111,8 +111,10 @@ # further. For a list of options available for each theme, see the # documentation. # -html_theme_options = {'style_nav_header_background': '#DDDDDD'} +html_theme_options = {'style_nav_header_background': '#DDDDDD', 'prev_next_buttons_location': 'both'} html_logo = '../images/openhw-landscape.svg' +html_show_sphinx = False +html_show_sourcelink = False # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, From f5ba683c3e5211280648c0129ead72d191a57cd5 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 15 Feb 2024 15:17:05 +0100 Subject: [PATCH 08/69] Corrected HWloop constraint checking assertion to fire only during real nested HWloops execution and not between HWloop programming steps. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_controller.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/cv32e40p_controller.sv b/rtl/cv32e40p_controller.sv index d2d7b2fe9..a41e345d4 100644 --- a/rtl/cv32e40p_controller.sv +++ b/rtl/cv32e40p_controller.sv @@ -1561,7 +1561,7 @@ endgenerate // HWLoop 0 and 1 having target address constraints property p_hwlp_same_target_address; - @(posedge clk) (hwlp_counter_i[1] > 1 && hwlp_counter_i[0] > 1) |-> ( hwlp_end_addr_i[1] - 4 >= hwlp_end_addr_i[0] - 4 + 8 ); + @(posedge clk) (hwlp_counter_i[1] > 1 && hwlp_counter_i[0] > 1 && pc_id_i >= hwlp_start_addr_i[0] && pc_id_i <= hwlp_end_addr_i[0] - 4) |-> ( hwlp_end_addr_i[1] - 4 >= hwlp_end_addr_i[0] - 4 + 8 ); endproperty a_hwlp_same_target_address : assert property(p_hwlp_same_target_address) else $warning("%t, HWLoops target address do not respect constraints", $time); From ca41d319cf64f3c4db9c8af8f3e817f315411dfc Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 15 Feb 2024 17:44:40 +0100 Subject: [PATCH 09/69] Some corrections for cadence & synopsys lec. Signed-off-by: Pascal Gouedo --- scripts/slec/run.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/slec/run.sh b/scripts/slec/run.sh index 5ecd62f88..63de085c1 100755 --- a/scripts/slec/run.sh +++ b/scripts/slec/run.sh @@ -65,7 +65,7 @@ if [ -z "${REF_REPO}" ]; then print_log "Empty REF_REPO env variable" REF_REPO=https://github.com/openhwgroup/cv32e40p.git REF_FOLDER=ref_design - REF_BRANCH=master + REF_BRANCH=cv32e40p_v1.0.0 print_log " * Setting REF_REPO ${REF_REPO}" print_log " * Setting REF_FOLDER ${REF_FOLDER}" print_log " * Setting REF_BRANCH ${REF_BRANCH}" @@ -79,6 +79,7 @@ if [[ -z "${TOP_MODULE}" ]]; then print_log "Empty TOP_MODULE env variable" TOP_MODULE=cv32e40p_core print_log " * Setting TOP_MODULE ${TOP_MODULE}" + export top_module=${TOP_MODULE} fi if [ ! -d ./reports/ ]; then @@ -105,7 +106,7 @@ GOLDEN_FLIST=$(pwd)/golden.src var_golden_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper") print $0 }' ${GOLDEN_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${GOLDEN_DIR}"'/rtl/|') -var_revised_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper") print $0 }' ${REVISED_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${REVISED_DIR}"'/rtl/|') +var_revised_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper" && $0 !~ "_top") print $0 }' ${REVISED_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${REVISED_DIR}"'/rtl/|') print_log "Generating GOLDEN flist in path: ${GOLDEN_FLIST}" echo $var_golden_rtl > ${GOLDEN_FLIST} From 29ccf9b2fc73a81456e25046b7717de2634050e4 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 15 Feb 2024 18:25:15 +0100 Subject: [PATCH 10/69] Additional proposals about reports centralization. Signed-off-by: Pascal Gouedo --- scripts/slec/run.sh | 4 ++-- scripts/slec/synopsys/lec.tcl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/slec/run.sh b/scripts/slec/run.sh index 63de085c1..064154815 100755 --- a/scripts/slec/run.sh +++ b/scripts/slec/run.sh @@ -113,7 +113,7 @@ echo $var_golden_rtl > ${GOLDEN_FLIST} print_log "Generating REVISED flist in path: ${REVISED_FLIST}" echo $var_revised_rtl > ${REVISED_FLIST} -export report_dir=$(readlink -f $(dirname "${BASH_SOURCE[0]}"))/reports/$(date +%Y-%m-%d)/ +export report_dir=$(readlink -f $(dirname "${BASH_SOURCE[0]}"))/reports/$(date +%Y-%m-%d)/${target_tool} if [[ -d ${report_dir} ]]; then rm -rf ${report_dir} @@ -139,7 +139,7 @@ if [[ "${target_tool}" == "cadence" ]]; then elif [[ "${target_tool}" == "synopsys" ]]; then if [[ "${target_process}" == "lec" ]]; then - fm_shell -work_path $report_dir/work/ -f ${tcl_script} | tee ${output_log} + fm_shell -work_path ${report_dir} -f ${tcl_script} | tee ${output_log} regex_string="Verification SUCCEEDED" elif [[ "${target_process}" == "sec" ]]; then not_implemented ${target_tool} ${target_process} diff --git a/scripts/slec/synopsys/lec.tcl b/scripts/slec/synopsys/lec.tcl index 1f6b41936..5d8f9130d 100644 --- a/scripts/slec/synopsys/lec.tcl +++ b/scripts/slec/synopsys/lec.tcl @@ -8,7 +8,7 @@ set_top r:/WORK/$top_module read_sverilog -container i -libname WORK -12 -f revised.src set_top i:/WORK/$top_module -match > ./reports/match.rpt +match > $summary_log.match.rpt if {"$top_module" == "cv32e40p_core"} { set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_req_o From d9ef378c51b7e4873fe99dfd0394342670a412e1 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 28 Feb 2024 15:41:50 +0100 Subject: [PATCH 11/69] RTL correction for verilator (no added/removed lines). Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_core.sv | 6 +++--- rtl/cv32e40p_cs_registers.sv | 2 +- rtl/cv32e40p_ex_stage.sv | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index 7d83e548b..d72fae9e4 100644 --- a/rtl/cv32e40p_core.sv +++ b/rtl/cv32e40p_core.sv @@ -1057,9 +1057,9 @@ module cv32e40p_core assign csr_addr_int = csr_num_e'(csr_access_ex ? alu_operand_b_ex[11:0] : '0); // Floating-Point registers write - assign fregs_we = (FPU & !ZFINX) ? ((regfile_alu_we_fw && regfile_alu_waddr_fw[5]) || - (regfile_we_wb && regfile_waddr_fw_wb_o[5])) - : 1'b0; + assign fregs_we = (FPU == 1 & ZFINX == 0) ? ((regfile_alu_we_fw && regfile_alu_waddr_fw[5]) || + (regfile_we_wb && regfile_waddr_fw_wb_o[5])) + : 1'b0; /////////////////////////// // ____ __ __ ____ // diff --git a/rtl/cv32e40p_cs_registers.sv b/rtl/cv32e40p_cs_registers.sv index 609662830..d543179f5 100644 --- a/rtl/cv32e40p_cs_registers.sv +++ b/rtl/cv32e40p_cs_registers.sv @@ -509,7 +509,7 @@ module cv32e40p_cs_registers // mimpid, Machine Implementation ID CSR_MIMPID: begin - csr_rdata_int = (FPU || COREV_PULP || COREV_CLUSTER) ? 32'h1 : 'b0; + csr_rdata_int = (FPU == 1 || COREV_PULP == 1 || COREV_CLUSTER == 1) ? 32'h1 : 'b0; end // unimplemented, read 0 CSRs diff --git a/rtl/cv32e40p_ex_stage.sv b/rtl/cv32e40p_ex_stage.sv index 4d870a969..488a83dc2 100644 --- a/rtl/cv32e40p_ex_stage.sv +++ b/rtl/cv32e40p_ex_stage.sv @@ -213,9 +213,9 @@ module cv32e40p_ex_stage end end else begin regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; - regfile_alu_we_fw_power_o = !COREV_PULP ? regfile_alu_we_i & ~apu_en_i : - regfile_alu_we_i & ~apu_en_i & - mult_ready & alu_ready & lsu_ready_ex_i; + regfile_alu_we_fw_power_o = (COREV_PULP == 0) ? regfile_alu_we_i & ~apu_en_i : + regfile_alu_we_i & ~apu_en_i & + mult_ready & alu_ready & lsu_ready_ex_i; regfile_alu_waddr_fw_o = regfile_alu_waddr_i; if (alu_en_i) regfile_alu_wdata_fw_o = alu_result; if (mult_en_i) regfile_alu_wdata_fw_o = mult_result; @@ -233,7 +233,7 @@ module cv32e40p_ex_stage if (regfile_we_lsu) begin regfile_we_wb_o = 1'b1; - regfile_we_wb_power_o = !COREV_PULP ? 1'b1 : ~data_misaligned_ex_i & wb_ready_i; + regfile_we_wb_power_o = (COREV_PULP == 0) ? 1'b1 : ~data_misaligned_ex_i & wb_ready_i; if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin wb_contention_lsu = 1'b1; end From 158975d1d9cd712f326eeca1599a86ea348cd436 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 29 Feb 2024 11:55:58 +0100 Subject: [PATCH 12/69] Removed unused vendorized PULP FPU DIV/SQRT module. Signed-off-by: Pascal Gouedo --- .../pulp_platform_fpu_div_sqrt_mvp.lock.hjson | 14 - ...ulp_platform_fpu_div_sqrt_mvp.vendor.hjson | 19 - .../pulp_platform_fpu_div_sqrt_mvp/LICENSE | 176 - .../hdl/.gitignore | 2 - .../hdl/control_mvp.sv | 3413 ----------------- .../hdl/defs_div_sqrt_mvp.sv | 83 - .../hdl/div_sqrt_mvp_wrapper.sv | 232 -- .../hdl/div_sqrt_top_mvp.sv | 180 - .../hdl/iteration_div_sqrt_mvp.sv | 61 - .../hdl/norm_div_sqrt_mvp.sv | 470 --- .../hdl/nrbd_nrsc_mvp.sv | 104 - .../hdl/preprocess_mvp.sv | 425 -- 12 files changed, 5179 deletions(-) delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.lock.hjson delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.vendor.hjson delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/LICENSE delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/.gitignore delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/control_mvp.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv delete mode 100644 rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.lock.hjson b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.lock.hjson deleted file mode 100644 index f9ec4482c..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.lock.hjson +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This file is generated by the util/vendor script. Please do not modify it -// manually. - -{ - upstream: - { - url: https://github.com/pulp-platform/fpu_div_sqrt_mvp.git - rev: 86e1f558b3c95e91577c41b2fc452c86b04e85ac - } -} diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.vendor.hjson b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.vendor.hjson deleted file mode 100644 index 4e10e4e1a..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp.vendor.hjson +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2022 OpenHW Group -// Solderpad Hardware License, Version 2.1, see LICENSE.md for details. -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -{ - name: "pulp_platform_fpu_div_sqrt_mvp", - target_dir: "pulp_platform_fpu_div_sqrt_mvp", - - upstream: { - url: "https://github.com/pulp-platform/fpu_div_sqrt_mvp.git", - rev: "86e1f558b3c95e91577c41b2fc452c86b04e85ac", - }, - - exclude_from_upstream: [ - "CHANGELOG.md", - "Bender.yml", - "src_files.yml", - "document" - ] -} diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/LICENSE b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/LICENSE deleted file mode 100644 index 18e4f6769..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ -SOLDERPAD HARDWARE LICENSE version 0.51 - -This license is based closely on the Apache License Version 2.0, but is not -approved or endorsed by the Apache Foundation. A copy of the non-modified -Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0. - -As this license is not currently OSI or FSF approved, the Licensor permits any -Work licensed under this License, at the option of the Licensee, to be treated -as licensed under the Apache License Version 2.0 (which is so approved). - -This License is licensed under the terms of this License and in particular -clause 7 below (Disclaimer of Warranties) applies in relation to its use. - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the Rights owner or entity authorized by the Rights owner -that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Rights" means copyright and any similar right including design right (whether -registered or unregistered), semiconductor topography (mask) rights and -database rights (but excluding Patents and Trademarks). - -"Source" form shall mean the preferred form for making modifications, including -but not limited to source code, net lists, board layouts, CAD files, -documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object -code, generated documentation, the instantiation of a hardware design and -conversions to other media types, including intermediate forms such as -bytecodes, FPGA bitstreams, artwork and semiconductor topographies (mask -works). - -"Work" shall mean the work of authorship, whether in Source form or other -Object form, made available under the License, as indicated by a Rights notice -that is included in or attached to the work (an example is provided in the -Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) or physically connect to or interoperate with the interfaces of, the Work -and Derivative Works thereof. - -"Contribution" shall mean any design or work of authorship, including the -original version of the Work and any modifications or additions to that Work or -Derivative Works thereof, that is intentionally submitted to Licensor for -inclusion in the Work by the Rights owner or by an individual or Legal Entity -authorized to submit on behalf of the Rights owner. For the purposes of this -definition, "submitted" means any form of electronic, verbal, or written -communication sent to the Licensor or its representatives, including but not -limited to communication on electronic mailing lists, source code control -systems, and issue tracking systems that are managed by, or on behalf of, the -Licensor for the purpose of discussing and improving the Work, but excluding -communication that is conspicuously marked or otherwise designated in writing -by the Rights owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of License. Subject to the terms and conditions of this License, each -Contributor hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable license under the Rights to reproduce, -prepare Derivative Works of, publicly display, publicly perform, sublicense, -and distribute the Work and such Derivative Works in Source or Object form and -do anything in relation to the Work as if the Rights did not exist. - -3. Grant of Patent License. Subject to the terms and conditions of this -License, each Contributor hereby grants to You a perpetual, worldwide, -non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this -section) patent license to make, have made, use, offer to sell, sell, import, -and otherwise transfer the Work, where such license applies only to those -patent claims licensable by such Contributor that are necessarily infringed by -their Contribution(s) alone or by combination of their Contribution(s) with the -Work to which such Contribution(s) was submitted. If You institute patent -litigation against any entity (including a cross-claim or counterclaim in a -lawsuit) alleging that the Work or a Contribution incorporated within the Work -constitutes direct or contributory patent infringement, then any patent -licenses granted to You under this License for that Work shall terminate as of -the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or -Derivative Works thereof in any medium, with or without modifications, and in -Source or Object form, provided that You meet the following conditions: - - You must give any other recipients of the Work or Derivative Works a copy - of this License; and - - You must cause any modified files to carry prominent notices stating that - You changed the files; and - - You must retain, in the Source form of any Derivative Works that You - distribute, all copyright, patent, trademark, and attribution notices from - the Source form of the Work, excluding those notices that do not pertain to - any part of the Derivative Works; and - - If the Work includes a "NOTICE" text file as part of its distribution, then - any Derivative Works that You distribute must include a readable copy of - the attribution notices contained within such NOTICE file, excluding those - notices that do not pertain to any part of the Derivative Works, in at - least one of the following places: within a NOTICE text file distributed as - part of the Derivative Works; within the Source form or documentation, if - provided along with the Derivative Works; or, within a display generated by - the Derivative Works, if and wherever such third-party notices normally - appear. The contents of the NOTICE file are for informational purposes only - and do not modify the License. You may add Your own attribution notices - within Derivative Works that You distribute, alongside or as an addendum to - the NOTICE text from the Work, provided that such additional attribution - notices cannot be construed as modifying the License. You may add Your own - copyright statement to Your modifications and may provide additional or - different license terms and conditions for use, reproduction, or - distribution of Your modifications, or for any such Derivative Works as a - whole, provided Your use, reproduction, and distribution of the Work - otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any -Contribution intentionally submitted for inclusion in the Work by You to the -Licensor shall be under the terms and conditions of this License, without any -additional terms or conditions. Notwithstanding the above, nothing herein shall -supersede or modify the terms of any separate license agreement you may have -executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, -trademarks, service marks, or product names of the Licensor, except as required -for reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in -writing, Licensor provides the Work (and each Contributor provides its -Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied, including, without limitation, any warranties -or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -PARTICULAR PURPOSE. You are solely responsible for determining the -appropriateness of using or redistributing the Work and assume any risks -associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in -tort (including negligence), contract, or otherwise, unless required by -applicable law (such as deliberate and grossly negligent acts) or agreed to in -writing, shall any Contributor be liable to You for damages, including any -direct, indirect, special, incidental, or consequential damages of any -character arising as a result of this License or out of the use or inability to -use the Work (including but not limited to damages for loss of goodwill, work -stoppage, computer failure or malfunction, or any and all other commercial -damages or losses), even if such Contributor has been advised of the -possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or -Derivative Works thereof, You may choose to offer, and charge a fee for, -acceptance of support, warranty, indemnity, or other liability obligations -and/or rights consistent with this License. However, in accepting such -obligations, You may act only on Your own behalf and on Your sole -responsibility, not on behalf of any other Contributor, and only if You agree -to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/.gitignore b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/.gitignore deleted file mode 100644 index 5c405f7b5..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*~ -*/*~ \ No newline at end of file diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/control_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/control_mvp.sv deleted file mode 100644 index bda9c01fb..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/control_mvp.sv +++ /dev/null @@ -1,3413 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 04/03/2018 // -// Design Name: FPU // -// Module Name: control_mvp.sv // -// Project Name: Private FPU // -// Language: SystemVerilog // -// // -// Description: the control logic of div and sqrt // -// // -// Revision Date: 12/04/2018 // -// Lei Li // -// To address some requirements by Stefan and add low power // -// control for special cases // -// Revision Date: 13/04/2018 // -// Lei Li // -// To fix some bug found in Control FSM // -// when Iteration_unit_num_S = 2'b10 // -// // -// // -// // -//////////////////////////////////////////////////////////////////////////////// - -import defs_div_sqrt_mvp::*; - -module control_mvp - - (//Input - input logic Clk_CI, - input logic Rst_RBI, - input logic Div_start_SI , - input logic Sqrt_start_SI, - input logic Start_SI, - input logic Kill_SI, - input logic Special_case_SBI, - input logic Special_case_dly_SBI, - input logic [C_PC-1:0] Precision_ctl_SI, - input logic [1:0] Format_sel_SI, - input logic [C_MANT_FP64:0] Numerator_DI, - input logic [C_EXP_FP64:0] Exp_num_DI, - input logic [C_MANT_FP64:0] Denominator_DI, - input logic [C_EXP_FP64:0] Exp_den_DI, - - - output logic Div_start_dly_SO , - output logic Sqrt_start_dly_SO, - output logic Div_enable_SO, - output logic Sqrt_enable_SO, - - - //To next stage - output logic Full_precision_SO, - output logic FP32_SO, - output logic FP64_SO, - output logic FP16_SO, - output logic FP16ALT_SO, - - output logic Ready_SO, - output logic Done_SO, - - output logic [C_MANT_FP64+4:0] Mant_result_prenorm_DO, - // output logic [3:0] Round_bit_DO, - output logic [C_EXP_FP64+1:0] Exp_result_prenorm_DO - ); - - logic [C_MANT_FP64+1+4:0] Partial_remainder_DN,Partial_remainder_DP; //58bits,r=q+2 - logic [C_MANT_FP64+4:0] Quotient_DP; //57bits - ///////////////////////////////////////////////////////////////////////////// - // Assign Inputs // - ///////////////////////////////////////////////////////////////////////////// - logic [C_MANT_FP64+1:0] Numerator_se_D; //sign extension and hidden bit - logic [C_MANT_FP64+1:0] Denominator_se_D; //signa extension and hidden bit - logic [C_MANT_FP64+1:0] Denominator_se_DB; //1's complement - - assign Numerator_se_D={1'b0,Numerator_DI}; - - assign Denominator_se_D={1'b0,Denominator_DI}; - - always_comb - begin - if(FP32_SO) - begin - Denominator_se_DB={~Denominator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP32], {(C_MANT_FP64-C_MANT_FP32){1'b0}} }; - end - else if(FP64_SO) begin - Denominator_se_DB=~Denominator_se_D; - end - else if(FP16_SO) begin - Denominator_se_DB={~Denominator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16], {(C_MANT_FP64-C_MANT_FP16){1'b0}} }; - end - else begin - Denominator_se_DB={~Denominator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16ALT], {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; - end - end - - - logic [C_MANT_FP64+1:0] Mant_D_sqrt_Norm; - - assign Mant_D_sqrt_Norm=Exp_num_DI[0]?{1'b0,Numerator_DI}:{Numerator_DI,1'b0}; //for sqrt - - ///////////////////////////////////////////////////////////////////////////// - // Format Selection // - ///////////////////////////////////////////////////////////////////////////// - logic [1:0] Format_sel_S; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Format_sel_S<='b0; - end - else if(Start_SI&&Ready_SO) - begin - Format_sel_S<=Format_sel_SI; - end - else - begin - Format_sel_S<=Format_sel_S; - end - end - - assign FP32_SO = (Format_sel_S==2'b00); - assign FP64_SO = (Format_sel_S==2'b01); - assign FP16_SO = (Format_sel_S==2'b10); - assign FP16ALT_SO = (Format_sel_S==2'b11); - - - - ///////////////////////////////////////////////////////////////////////////// - // Precision Control // - ///////////////////////////////////////////////////////////////////////////// - - logic [C_PC-1:0] Precision_ctl_S; - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Precision_ctl_S<='b0; - end - else if(Start_SI&&Ready_SO) - begin - Precision_ctl_S<=Precision_ctl_SI; - end - else - begin - Precision_ctl_S<=Precision_ctl_S; - end - end - assign Full_precision_SO = (Precision_ctl_S==6'h00); - - - - logic [5:0] State_ctl_S; - logic [5:0] State_Two_iteration_unit_S; - logic [5:0] State_Four_iteration_unit_S; - - assign State_Two_iteration_unit_S = Precision_ctl_S[C_PC-1:1]; //Two iteration units - assign State_Four_iteration_unit_S = Precision_ctl_S[C_PC-1:2]; //Four iteration units - always_comb - begin - case(Iteration_unit_num_S) -//////////////////////one iteration unit, start/////////////////////////////////////// - 2'b00: //one iteration unit - begin - case(Format_sel_S) - 2'b00: //FP32 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h1b; //24+4 more iterations for rounding bits - end - else - begin - State_ctl_S = Precision_ctl_S; - end - end - 2'b01: //FP64 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h38; //53+4 more iterations for rounding bits - end - else - begin - State_ctl_S = Precision_ctl_S; - end - end - 2'b10: //FP16 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h0e; //11+4 more iterations for rounding bits - end - else - begin - State_ctl_S = Precision_ctl_S; - end - end - 2'b11: //FP16ALT - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h0b; //8+4 more iterations for rounding bits - end - else - begin - State_ctl_S = Precision_ctl_S; - end - end - endcase - end -//////////////////////one iteration unit, end/////////////////////////////////////// - -//////////////////////two iteration units, start/////////////////////////////////////// - 2'b01: //two iteration units - begin - case(Format_sel_S) - 2'b00: //FP32 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h0d; //24+4 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Two_iteration_unit_S; - end - end - 2'b01: //FP64 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h1b; //53+3 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Two_iteration_unit_S; - end - end - 2'b10: //FP16 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h06; //11+3 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Two_iteration_unit_S; - end - end - 2'b11: //FP16ALT - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h05; //8+4 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Two_iteration_unit_S; - end - end - endcase - end -//////////////////////two iteration units, end/////////////////////////////////////// - -//////////////////////three iteration units, start/////////////////////////////////////// - 2'b10: //three iteration units - begin - case(Format_sel_S) - 2'b00: //FP32 - begin - case(Precision_ctl_S) - 6'h00: - begin - State_ctl_S = 6'h08; //24+3 more iterations for rounding bits - end - 6'h06,6'h07,6'h08: - begin - State_ctl_S = 6'h02; - end - 6'h09,6'h0a,6'h0b: - begin - State_ctl_S = 6'h03; - end - 6'h0c,6'h0d,6'h0e: - begin - State_ctl_S = 6'h04; - end - 6'h0f,6'h10,6'h11: - begin - State_ctl_S = 6'h05; - end - 6'h12,6'h13,6'h14: - begin - State_ctl_S = 6'h06; - end - 6'h15,6'h16,6'h17: - begin - State_ctl_S = 6'h07; - end - default: - begin - State_ctl_S = 6'h08; //24+3 more iterations for rounding bits - end - endcase - end - 2'b01: //FP64 - begin - case(Precision_ctl_S) - 6'h00: - begin - State_ctl_S = 6'h12; //53+4 more iterations for rounding bits - end - 6'h06,6'h07,6'h08: - begin - State_ctl_S = 6'h02; - end - 6'h09,6'h0a,6'h0b: - begin - State_ctl_S = 6'h03; - end - 6'h0c,6'h0d,6'h0e: - begin - State_ctl_S = 6'h04; - end - 6'h0f,6'h10,6'h11: - begin - State_ctl_S = 6'h05; - end - 6'h12,6'h13,6'h14: - begin - State_ctl_S = 6'h06; - end - 6'h15,6'h16,6'h17: - begin - State_ctl_S = 6'h07; - end - 6'h18,6'h19,6'h1a: - begin - State_ctl_S = 6'h08; - end - 6'h1b,6'h1c,6'h1d: - begin - State_ctl_S = 6'h09; - end - 6'h1e,6'h1f,6'h20: - begin - State_ctl_S = 6'h0a; - end - 6'h21,6'h22,6'h23: - begin - State_ctl_S = 6'h0b; - end - 6'h24,6'h25,6'h26: - begin - State_ctl_S = 6'h0c; - end - 6'h27,6'h28,6'h29: - begin - State_ctl_S = 6'h0d; - end - 6'h2a,6'h2b,6'h2c: - begin - State_ctl_S = 6'h0e; - end - 6'h2d,6'h2e,6'h2f: - begin - State_ctl_S = 6'h0f; - end - 6'h30,6'h31,6'h32: - begin - State_ctl_S = 6'h10; - end - 6'h33,6'h34,6'h35: - begin - State_ctl_S = 6'h11; - end - default: - begin - State_ctl_S = 6'h12; //53+4 more iterations for rounding bits - end - endcase - end - 2'b10: //FP16 - begin - case(Precision_ctl_S) - 6'h00: - begin - State_ctl_S = 6'h04; //12+3 more iterations for rounding bits - end - 6'h06,6'h07,6'h08: - begin - State_ctl_S = 6'h02; - end - 6'h09,6'h0a,6'h0b: - begin - State_ctl_S = 6'h03; - end - default: - begin - State_ctl_S = 6'h04; //12+3 more iterations for rounding bits - end - endcase - end - 2'b11: //FP16ALT - begin - case(Precision_ctl_S) - 6'h00: - begin - State_ctl_S = 6'h03; //8+4 more iterations for rounding bits - end - 6'h06,6'h07,6'h08: - begin - State_ctl_S = 6'h02; - end - default: - begin - State_ctl_S = 6'h03; //8+4 more iterations for rounding bits - end - endcase - end - endcase - end -//////////////////////three iteration units, end/////////////////////////////////////// - -//////////////////////four iteration units, start/////////////////////////////////////// - 2'b11: //four iteration units - begin - case(Format_sel_S) - 2'b00: //FP32 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h06; //24+4 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Four_iteration_unit_S; - end - end - 2'b01: //FP64 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h0d; //53+3 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Four_iteration_unit_S; - end - end - 2'b10: //FP16 - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h03; //11+4 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Four_iteration_unit_S; - end - end - 2'b11: //FP16ALT - begin - if(Full_precision_SO) - begin - State_ctl_S = 6'h02; //8+4 more iterations for rounding bits - end - else - begin - State_ctl_S = State_Four_iteration_unit_S; - end - end - endcase - end -//////////////////////four iteration units, end/////////////////////////////////////// - - endcase - end - - - ///////////////////////////////////////////////////////////////////////////// - // control logic // - ///////////////////////////////////////////////////////////////////////////// - - logic Div_start_dly_S; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) // generate Div_start_dly_S signal - begin - if(~Rst_RBI) - begin - Div_start_dly_S<=1'b0; - end - else if(Div_start_SI&&Ready_SO) - begin - Div_start_dly_S<=1'b1; - end - else - begin - Div_start_dly_S<=1'b0; - end - end - - assign Div_start_dly_SO=Div_start_dly_S; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) begin // generate Div_enable_SO signal - if(~Rst_RBI) - Div_enable_SO<=1'b0; - // Synchronous reset with Flush - else if (Kill_SI) - Div_enable_SO <= 1'b0; - else if(Div_start_SI&&Ready_SO) - Div_enable_SO<=1'b1; - else if(Done_SO) - Div_enable_SO<=1'b0; - else - Div_enable_SO<=Div_enable_SO; - end - - logic Sqrt_start_dly_S; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) // generate Sqrt_start_dly_SI signal - begin - if(~Rst_RBI) - begin - Sqrt_start_dly_S<=1'b0; - end - else if(Sqrt_start_SI&&Ready_SO) - begin - Sqrt_start_dly_S<=1'b1; - end - else - begin - Sqrt_start_dly_S<=1'b0; - end - end - assign Sqrt_start_dly_SO=Sqrt_start_dly_S; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) begin // generate Sqrt_enable_SO signal - if(~Rst_RBI) - Sqrt_enable_SO<=1'b0; - else if (Kill_SI) - Sqrt_enable_SO <= 1'b0; - else if(Sqrt_start_SI&&Ready_SO) - Sqrt_enable_SO<=1'b1; - else if(Done_SO) - Sqrt_enable_SO<=1'b0; - else - Sqrt_enable_SO<=Sqrt_enable_SO; - end - - logic [5:0] Crtl_cnt_S; - logic Start_dly_S; - - assign Start_dly_S=Div_start_dly_S |Sqrt_start_dly_S; - - logic Fsm_enable_S; - assign Fsm_enable_S=( (Start_dly_S | (| Crtl_cnt_S)) && (~Kill_SI) && Special_case_dly_SBI); - - logic Final_state_S; - assign Final_state_S= (Crtl_cnt_S==State_ctl_S); - - - always_ff @(posedge Clk_CI, negedge Rst_RBI) //control_FSM - begin - if (~Rst_RBI) - begin - Crtl_cnt_S <= '0; - end - else if (Final_state_S | Kill_SI) - begin - Crtl_cnt_S <= '0; - end - else if(Fsm_enable_S) // one cycle Start_SI - begin - Crtl_cnt_S <= Crtl_cnt_S+1; - end - else - begin - Crtl_cnt_S <= '0; - end - end // always_ff - - - - always_ff @(posedge Clk_CI, negedge Rst_RBI) //Generate Done_SO, they can share this Done_SO. - begin - if(~Rst_RBI) - begin - Done_SO<=1'b0; - end - else if(Start_SI&&Ready_SO) - begin - if(~Special_case_SBI) - begin - Done_SO<=1'b1; - end - else - begin - Done_SO<=1'b0; - end - end - else if(Final_state_S) - begin - Done_SO<=1'b1; - end - else - begin - Done_SO<=1'b0; - end - end - - - - - always_ff @(posedge Clk_CI, negedge Rst_RBI) //Generate Ready_SO - begin - if(~Rst_RBI) - begin - Ready_SO<=1'b1; - end - - else if(Start_SI&&Ready_SO) - begin - if(~Special_case_SBI) - begin - Ready_SO<=1'b1; - end - else - begin - Ready_SO<=1'b0; - end - end - else if(Final_state_S | Kill_SI) - begin - Ready_SO<=1'b1; - end - else - begin - Ready_SO<=Ready_SO; - end - end - - - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b00, start // - //////////////////////////////////////////////////////////////////////////// - - logic Qcnt_one_0; - logic Qcnt_one_1; - logic [1:0] Qcnt_one_2; - logic [2:0] Qcnt_one_3; - logic [3:0] Qcnt_one_4; - logic [4:0] Qcnt_one_5; - logic [5:0] Qcnt_one_6; - logic [6:0] Qcnt_one_7; - logic [7:0] Qcnt_one_8; - logic [8:0] Qcnt_one_9; - logic [9:0] Qcnt_one_10; - logic [10:0] Qcnt_one_11; - logic [11:0] Qcnt_one_12; - logic [12:0] Qcnt_one_13; - logic [13:0] Qcnt_one_14; - logic [14:0] Qcnt_one_15; - logic [15:0] Qcnt_one_16; - logic [16:0] Qcnt_one_17; - logic [17:0] Qcnt_one_18; - logic [18:0] Qcnt_one_19; - logic [19:0] Qcnt_one_20; - logic [20:0] Qcnt_one_21; - logic [21:0] Qcnt_one_22; - logic [22:0] Qcnt_one_23; - logic [23:0] Qcnt_one_24; - logic [24:0] Qcnt_one_25; - logic [25:0] Qcnt_one_26; - logic [26:0] Qcnt_one_27; - logic [27:0] Qcnt_one_28; - logic [28:0] Qcnt_one_29; - logic [29:0] Qcnt_one_30; - logic [30:0] Qcnt_one_31; - logic [31:0] Qcnt_one_32; - logic [32:0] Qcnt_one_33; - logic [33:0] Qcnt_one_34; - logic [34:0] Qcnt_one_35; - logic [35:0] Qcnt_one_36; - logic [36:0] Qcnt_one_37; - logic [37:0] Qcnt_one_38; - logic [38:0] Qcnt_one_39; - logic [39:0] Qcnt_one_40; - logic [40:0] Qcnt_one_41; - logic [41:0] Qcnt_one_42; - logic [42:0] Qcnt_one_43; - logic [43:0] Qcnt_one_44; - logic [44:0] Qcnt_one_45; - logic [45:0] Qcnt_one_46; - logic [46:0] Qcnt_one_47; - logic [47:0] Qcnt_one_48; - logic [48:0] Qcnt_one_49; - logic [49:0] Qcnt_one_50; - logic [50:0] Qcnt_one_51; - logic [51:0] Qcnt_one_52; - logic [52:0] Qcnt_one_53; - logic [53:0] Qcnt_one_54; - logic [54:0] Qcnt_one_55; - logic [55:0] Qcnt_one_56; - logic [56:0] Qcnt_one_57; - logic [57:0] Qcnt_one_58; - logic [58:0] Qcnt_one_59; - logic [59:0] Qcnt_one_60; - - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b00, end // - //////////////////////////////////////////////////////////////////////////// - - - - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b01, start // - //////////////////////////////////////////////////////////////////////////// - logic [1:0] Qcnt_two_0; - logic [2:0] Qcnt_two_1; - logic [4:0] Qcnt_two_2; - logic [6:0] Qcnt_two_3; - logic [8:0] Qcnt_two_4; - logic [10:0] Qcnt_two_5; - logic [12:0] Qcnt_two_6; - logic [14:0] Qcnt_two_7; - logic [16:0] Qcnt_two_8; - logic [18:0] Qcnt_two_9; - logic [20:0] Qcnt_two_10; - logic [22:0] Qcnt_two_11; - logic [24:0] Qcnt_two_12; - logic [26:0] Qcnt_two_13; - logic [28:0] Qcnt_two_14; - logic [30:0] Qcnt_two_15; - logic [32:0] Qcnt_two_16; - logic [34:0] Qcnt_two_17; - logic [36:0] Qcnt_two_18; - logic [38:0] Qcnt_two_19; - logic [40:0] Qcnt_two_20; - logic [42:0] Qcnt_two_21; - logic [44:0] Qcnt_two_22; - logic [46:0] Qcnt_two_23; - logic [48:0] Qcnt_two_24; - logic [50:0] Qcnt_two_25; - logic [52:0] Qcnt_two_26; - logic [54:0] Qcnt_two_27; - logic [56:0] Qcnt_two_28; - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b01, end // - //////////////////////////////////////////////////////////////////////////// - - - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b10, start // - //////////////////////////////////////////////////////////////////////////// - logic [2:0] Qcnt_three_0; - logic [4:0] Qcnt_three_1; - logic [7:0] Qcnt_three_2; - logic [10:0] Qcnt_three_3; - logic [13:0] Qcnt_three_4; - logic [16:0] Qcnt_three_5; - logic [19:0] Qcnt_three_6; - logic [22:0] Qcnt_three_7; - logic [25:0] Qcnt_three_8; - logic [28:0] Qcnt_three_9; - logic [31:0] Qcnt_three_10; - logic [34:0] Qcnt_three_11; - logic [37:0] Qcnt_three_12; - logic [40:0] Qcnt_three_13; - logic [43:0] Qcnt_three_14; - logic [46:0] Qcnt_three_15; - logic [49:0] Qcnt_three_16; - logic [52:0] Qcnt_three_17; - logic [55:0] Qcnt_three_18; - logic [58:0] Qcnt_three_19; - logic [61:0] Qcnt_three_20; - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b10, end // - //////////////////////////////////////////////////////////////////////////// - - - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b11, start // - //////////////////////////////////////////////////////////////////////////// - logic [3:0] Qcnt_four_0; - logic [6:0] Qcnt_four_1; - logic [10:0] Qcnt_four_2; - logic [14:0] Qcnt_four_3; - logic [18:0] Qcnt_four_4; - logic [22:0] Qcnt_four_5; - logic [26:0] Qcnt_four_6; - logic [30:0] Qcnt_four_7; - logic [34:0] Qcnt_four_8; - logic [38:0] Qcnt_four_9; - logic [42:0] Qcnt_four_10; - logic [46:0] Qcnt_four_11; - logic [50:0] Qcnt_four_12; - logic [54:0] Qcnt_four_13; - logic [58:0] Qcnt_four_14; - - ///////////////////////////////////////////////////////////////////////////// - // Declarations for square root when Iteration_unit_num_S = 2'b11, end // - //////////////////////////////////////////////////////////////////////////// - - - - logic [C_MANT_FP64+1+4:0] Sqrt_R0,Sqrt_Q0,Q_sqrt0,Q_sqrt_com_0; - logic [C_MANT_FP64+1+4:0] Sqrt_R1,Sqrt_Q1,Q_sqrt1,Q_sqrt_com_1; - logic [C_MANT_FP64+1+4:0] Sqrt_R2,Sqrt_Q2,Q_sqrt2,Q_sqrt_com_2; - logic [C_MANT_FP64+1+4:0] Sqrt_R3,Sqrt_Q3,Q_sqrt3,Q_sqrt_com_3,Sqrt_R4; //Sqrt_Q4; - - - logic [1:0] Sqrt_DI [3:0]; - logic [1:0] Sqrt_DO [3:0]; - logic Sqrt_carry_DO; - - - logic [C_MANT_FP64+1+4:0] Iteration_cell_a_D [3:0]; - logic [C_MANT_FP64+1+4:0] Iteration_cell_b_D [3:0]; - logic [C_MANT_FP64+1+4:0] Iteration_cell_a_BMASK_D [3:0]; - logic [C_MANT_FP64+1+4:0] Iteration_cell_b_BMASK_D [3:0]; - logic Iteration_cell_carry_D [3:0]; - logic [C_MANT_FP64+1+4:0] Iteration_cell_sum_D [3:0]; - logic [C_MANT_FP64+1+4:0] Iteration_cell_sum_AMASK_D [3:0]; - - - logic [3:0] Sqrt_quotinent_S; - - - always_comb - begin // - case (Format_sel_S) - 2'b00: - begin - Sqrt_quotinent_S = {(~Iteration_cell_sum_AMASK_D[0][C_MANT_FP32+5]),(~Iteration_cell_sum_AMASK_D[1][C_MANT_FP32+5]),(~Iteration_cell_sum_AMASK_D[2][C_MANT_FP32+5]),(~Iteration_cell_sum_AMASK_D[3][C_MANT_FP32+5])}; - Q_sqrt_com_0 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt0[C_MANT_FP32+5:0] }; - Q_sqrt_com_1 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt1[C_MANT_FP32+5:0] }; - Q_sqrt_com_2 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt2[C_MANT_FP32+5:0] }; - Q_sqrt_com_3 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt3[C_MANT_FP32+5:0] }; - end - 2'b01: - begin - Sqrt_quotinent_S = {Iteration_cell_carry_D[0],Iteration_cell_carry_D[1],Iteration_cell_carry_D[2],Iteration_cell_carry_D[3]}; - Q_sqrt_com_0=~Q_sqrt0; - Q_sqrt_com_1=~Q_sqrt1; - Q_sqrt_com_2=~Q_sqrt2; - Q_sqrt_com_3=~Q_sqrt3; - end - 2'b10: - begin - Sqrt_quotinent_S = {(~Iteration_cell_sum_AMASK_D[0][C_MANT_FP16+5]),(~Iteration_cell_sum_AMASK_D[1][C_MANT_FP16+5]),(~Iteration_cell_sum_AMASK_D[2][C_MANT_FP16+5]),(~Iteration_cell_sum_AMASK_D[3][C_MANT_FP16+5])}; - Q_sqrt_com_0 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt0[C_MANT_FP16+5:0] }; - Q_sqrt_com_1 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt1[C_MANT_FP16+5:0] }; - Q_sqrt_com_2 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt2[C_MANT_FP16+5:0] }; - Q_sqrt_com_3 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt3[C_MANT_FP16+5:0] }; - end - 2'b11: - begin - Sqrt_quotinent_S = {(~Iteration_cell_sum_AMASK_D[0][C_MANT_FP16ALT+5]),(~Iteration_cell_sum_AMASK_D[1][C_MANT_FP16ALT+5]),(~Iteration_cell_sum_AMASK_D[2][C_MANT_FP16ALT+5]),(~Iteration_cell_sum_AMASK_D[3][C_MANT_FP16ALT+5])}; - Q_sqrt_com_0 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt0[C_MANT_FP16ALT+5:0] }; - Q_sqrt_com_1 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt1[C_MANT_FP16ALT+5:0] }; - Q_sqrt_com_2 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt2[C_MANT_FP16ALT+5:0] }; - Q_sqrt_com_3 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt3[C_MANT_FP16ALT+5:0] }; - end - endcase - end - - - - assign Qcnt_one_0= {1'b0}; //qk for each feedback - assign Qcnt_one_1= {Quotient_DP[0]}; - assign Qcnt_one_2= {Quotient_DP[1:0]}; - assign Qcnt_one_3= {Quotient_DP[2:0]}; - assign Qcnt_one_4= {Quotient_DP[3:0]}; - assign Qcnt_one_5= {Quotient_DP[4:0]}; - assign Qcnt_one_6= {Quotient_DP[5:0]}; - assign Qcnt_one_7= {Quotient_DP[6:0]}; - assign Qcnt_one_8= {Quotient_DP[7:0]}; - assign Qcnt_one_9= {Quotient_DP[8:0]}; - assign Qcnt_one_10= {Quotient_DP[9:0]}; - assign Qcnt_one_11= {Quotient_DP[10:0]}; - assign Qcnt_one_12= {Quotient_DP[11:0]}; - assign Qcnt_one_13= {Quotient_DP[12:0]}; - assign Qcnt_one_14= {Quotient_DP[13:0]}; - assign Qcnt_one_15= {Quotient_DP[14:0]}; - assign Qcnt_one_16= {Quotient_DP[15:0]}; - assign Qcnt_one_17= {Quotient_DP[16:0]}; - assign Qcnt_one_18= {Quotient_DP[17:0]}; - assign Qcnt_one_19= {Quotient_DP[18:0]}; - assign Qcnt_one_20= {Quotient_DP[19:0]}; - assign Qcnt_one_21= {Quotient_DP[20:0]}; - assign Qcnt_one_22= {Quotient_DP[21:0]}; - assign Qcnt_one_23= {Quotient_DP[22:0]}; - assign Qcnt_one_24= {Quotient_DP[23:0]}; - assign Qcnt_one_25= {Quotient_DP[24:0]}; - assign Qcnt_one_26= {Quotient_DP[25:0]}; - assign Qcnt_one_27= {Quotient_DP[26:0]}; - assign Qcnt_one_28= {Quotient_DP[27:0]}; - assign Qcnt_one_29= {Quotient_DP[28:0]}; - assign Qcnt_one_30= {Quotient_DP[29:0]}; - assign Qcnt_one_31= {Quotient_DP[30:0]}; - assign Qcnt_one_32= {Quotient_DP[31:0]}; - assign Qcnt_one_33= {Quotient_DP[32:0]}; - assign Qcnt_one_34= {Quotient_DP[33:0]}; - assign Qcnt_one_35= {Quotient_DP[34:0]}; - assign Qcnt_one_36= {Quotient_DP[35:0]}; - assign Qcnt_one_37= {Quotient_DP[36:0]}; - assign Qcnt_one_38= {Quotient_DP[37:0]}; - assign Qcnt_one_39= {Quotient_DP[38:0]}; - assign Qcnt_one_40= {Quotient_DP[39:0]}; - assign Qcnt_one_41= {Quotient_DP[40:0]}; - assign Qcnt_one_42= {Quotient_DP[41:0]}; - assign Qcnt_one_43= {Quotient_DP[42:0]}; - assign Qcnt_one_44= {Quotient_DP[43:0]}; - assign Qcnt_one_45= {Quotient_DP[44:0]}; - assign Qcnt_one_46= {Quotient_DP[45:0]}; - assign Qcnt_one_47= {Quotient_DP[46:0]}; - assign Qcnt_one_48= {Quotient_DP[47:0]}; - assign Qcnt_one_49= {Quotient_DP[48:0]}; - assign Qcnt_one_50= {Quotient_DP[49:0]}; - assign Qcnt_one_51= {Quotient_DP[50:0]}; - assign Qcnt_one_52= {Quotient_DP[51:0]}; - assign Qcnt_one_53= {Quotient_DP[52:0]}; - assign Qcnt_one_54= {Quotient_DP[53:0]}; - assign Qcnt_one_55= {Quotient_DP[54:0]}; - assign Qcnt_one_56= {Quotient_DP[55:0]}; - assign Qcnt_one_57= {Quotient_DP[56:0]}; - - - assign Qcnt_two_0 = {1'b0, Sqrt_quotinent_S[3]}; //qk for each feedback - assign Qcnt_two_1 = {Quotient_DP[1:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_2 = {Quotient_DP[3:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_3 = {Quotient_DP[5:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_4 = {Quotient_DP[7:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_5 = {Quotient_DP[9:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_6 = {Quotient_DP[11:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_7 = {Quotient_DP[13:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_8 = {Quotient_DP[15:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_9 = {Quotient_DP[17:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_10 = {Quotient_DP[19:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_11 = {Quotient_DP[21:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_12 = {Quotient_DP[23:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_13 = {Quotient_DP[25:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_14 = {Quotient_DP[27:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_15 = {Quotient_DP[29:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_16 = {Quotient_DP[31:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_17 = {Quotient_DP[33:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_18 = {Quotient_DP[35:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_19 = {Quotient_DP[37:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_20 = {Quotient_DP[39:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_21 = {Quotient_DP[41:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_22 = {Quotient_DP[43:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_23 = {Quotient_DP[45:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_24 = {Quotient_DP[47:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_25 = {Quotient_DP[49:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_26 = {Quotient_DP[51:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_27 = {Quotient_DP[53:0],Sqrt_quotinent_S[3]}; - assign Qcnt_two_28 = {Quotient_DP[55:0],Sqrt_quotinent_S[3]}; - - - assign Qcnt_three_0 = {1'b0, Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; //qk for each feedback - assign Qcnt_three_1 = {Quotient_DP[2:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_2 = {Quotient_DP[5:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_3 = {Quotient_DP[8:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_4 = {Quotient_DP[11:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_5 = {Quotient_DP[14:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_6 = {Quotient_DP[17:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_7 = {Quotient_DP[20:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_8 = {Quotient_DP[23:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_9 = {Quotient_DP[26:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_10 = {Quotient_DP[29:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_11 = {Quotient_DP[32:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_12 = {Quotient_DP[35:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_13 = {Quotient_DP[38:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_14 = {Quotient_DP[41:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_15 = {Quotient_DP[44:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_16 = {Quotient_DP[47:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_17 = {Quotient_DP[50:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_18 = {Quotient_DP[53:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - assign Qcnt_three_19 = {Quotient_DP[56:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; - - - assign Qcnt_four_0 = {1'b0, Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_1 = {Quotient_DP[3:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_2 = {Quotient_DP[7:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_3 = {Quotient_DP[11:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_4 = {Quotient_DP[15:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_5 = {Quotient_DP[19:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_6 = {Quotient_DP[23:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_7 = {Quotient_DP[27:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_8 = {Quotient_DP[31:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_9 = {Quotient_DP[35:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_10 = {Quotient_DP[39:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_11 = {Quotient_DP[43:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_12 = {Quotient_DP[47:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_13 = {Quotient_DP[51:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - assign Qcnt_four_14 = {Quotient_DP[55:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]}; - - - - - always_comb begin // the intermediate operands for sqrt - - case(Iteration_unit_num_S) - 2'b00: - begin - - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b00, start // - ///////////////////////////////////////////////////////////////////////////// - - - - - case(Crtl_cnt_S) - - 6'b000000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_one_0}; - Sqrt_Q0=Q_sqrt_com_0; - end - 6'b000001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_one_1}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b000010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4]; - Q_sqrt0={{(C_MANT_FP64+4){1'b0}},Qcnt_one_2}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b000011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6]; - Q_sqrt0={{(C_MANT_FP64+3){1'b0}},Qcnt_one_3}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b000100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8]; - Q_sqrt0={{(C_MANT_FP64+2){1'b0}},Qcnt_one_4}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b000101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10]; - Q_sqrt0={{(C_MANT_FP64+1){1'b0}},Qcnt_one_5}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b000110: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12]; - Q_sqrt0={{(C_MANT_FP64){1'b0}},Qcnt_one_6}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b000111: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14]; - Q_sqrt0={{(C_MANT_FP64-1){1'b0}},Qcnt_one_7}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16]; - Q_sqrt0={{(C_MANT_FP64-2){1'b0}},Qcnt_one_8}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18]; - Q_sqrt0={{(C_MANT_FP64-3){1'b0}},Qcnt_one_9}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20]; - Q_sqrt0={{(C_MANT_FP64-4){1'b0}},Qcnt_one_10}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22]; - Q_sqrt0={{(C_MANT_FP64-5){1'b0}},Qcnt_one_11}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24]; - Q_sqrt0={{(C_MANT_FP64-6){1'b0}},Qcnt_one_12}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26]; - Q_sqrt0={{(C_MANT_FP64-7){1'b0}},Qcnt_one_13}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001110: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28]; - Q_sqrt0={{(C_MANT_FP64-8){1'b0}},Qcnt_one_14}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b001111: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30]; - Q_sqrt0={{(C_MANT_FP64-9){1'b0}},Qcnt_one_15}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32]; - Q_sqrt0={{(C_MANT_FP64-10){1'b0}},Qcnt_one_16}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34]; - Q_sqrt0={{(C_MANT_FP64-11){1'b0}},Qcnt_one_17}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36]; - Q_sqrt0={{(C_MANT_FP64-12){1'b0}},Qcnt_one_18}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38]; - Q_sqrt0={{(C_MANT_FP64-13){1'b0}},Qcnt_one_19}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40]; - Q_sqrt0={{(C_MANT_FP64-14){1'b0}},Qcnt_one_20}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42]; - Q_sqrt0={{(C_MANT_FP64-15){1'b0}},Qcnt_one_21}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010110: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44]; - Q_sqrt0={{(C_MANT_FP64-16){1'b0}},Qcnt_one_22}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b010111: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46]; - Q_sqrt0={{(C_MANT_FP64-17){1'b0}},Qcnt_one_23}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48]; - Q_sqrt0={{(C_MANT_FP64-18){1'b0}},Qcnt_one_24}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50]; - Q_sqrt0={{(C_MANT_FP64-19){1'b0}},Qcnt_one_25}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52]; - Q_sqrt0={{(C_MANT_FP64-20){1'b0}},Qcnt_one_26}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-21){1'b0}},Qcnt_one_27}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-22){1'b0}},Qcnt_one_28}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-23){1'b0}},Qcnt_one_29}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-24){1'b0}},Qcnt_one_30}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b011111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-25){1'b0}},Qcnt_one_31}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-26){1'b0}},Qcnt_one_32}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-27){1'b0}},Qcnt_one_33}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-28){1'b0}},Qcnt_one_34}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-29){1'b0}},Qcnt_one_35}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-30){1'b0}},Qcnt_one_36}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-31){1'b0}},Qcnt_one_37}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-32){1'b0}},Qcnt_one_38}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b100111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-33){1'b0}},Qcnt_one_39}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-34){1'b0}},Qcnt_one_40}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-35){1'b0}},Qcnt_one_41}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-36){1'b0}},Qcnt_one_42}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-37){1'b0}},Qcnt_one_43}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-38){1'b0}},Qcnt_one_44}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-39){1'b0}},Qcnt_one_45}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-40){1'b0}},Qcnt_one_46}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b101111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-41){1'b0}},Qcnt_one_47}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-42){1'b0}},Qcnt_one_48}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-43){1'b0}},Qcnt_one_49}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-44){1'b0}},Qcnt_one_50}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-45){1'b0}},Qcnt_one_51}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-46){1'b0}},Qcnt_one_52}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-47){1'b0}},Qcnt_one_53}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-48){1'b0}},Qcnt_one_54}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b110111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-49){1'b0}},Qcnt_one_55}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - 6'b111000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-50){1'b0}},Qcnt_one_56}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - end - - default: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0='0; - Sqrt_Q0='0; - end - endcase - end - - - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b00, end // - ///////////////////////////////////////////////////////////////////////////// - - - 2'b01: - begin - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b01, start // - ///////////////////////////////////////////////////////////////////////////// - case(Crtl_cnt_S) - - 6'b000000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_two_0[1]}; - Sqrt_Q0=Q_sqrt_com_0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_two_0[1:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4]; - Q_sqrt0={{(C_MANT_FP64+4){1'b0}},Qcnt_two_1[2:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6]; - Q_sqrt1={{(C_MANT_FP64+3){1'b0}},Qcnt_two_1[2:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8]; - Q_sqrt0={{(C_MANT_FP64+2){1'b0}},Qcnt_two_2[4:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10]; - Q_sqrt1={{(C_MANT_FP64+1){1'b0}},Qcnt_two_2[4:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12]; - Q_sqrt0={{(C_MANT_FP64){1'b0}},Qcnt_two_3[6:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14]; - Q_sqrt1={{(C_MANT_FP64-1){1'b0}},Qcnt_two_3[6:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16]; - Q_sqrt0={{(C_MANT_FP64-2){1'b0}},Qcnt_two_4[8:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18]; - Q_sqrt1={{(C_MANT_FP64-3){1'b0}},Qcnt_two_4[8:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20]; - Q_sqrt0={{(C_MANT_FP64-4){1'b0}},Qcnt_two_5[10:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22]; - Q_sqrt1={{(C_MANT_FP64-5){1'b0}},Qcnt_two_5[10:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000110: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24]; - Q_sqrt0={{(C_MANT_FP64-6){1'b0}},Qcnt_two_6[12:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26]; - Q_sqrt1={{(C_MANT_FP64-7){1'b0}},Qcnt_two_6[12:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b000111: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28]; - Q_sqrt0={{(C_MANT_FP64-8){1'b0}},Qcnt_two_7[14:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30]; - Q_sqrt1={{(C_MANT_FP64-9){1'b0}},Qcnt_two_7[14:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32]; - Q_sqrt0={{(C_MANT_FP64-10){1'b0}},Qcnt_two_8[16:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34]; - Q_sqrt1={{(C_MANT_FP64-11){1'b0}},Qcnt_two_8[16:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36]; - Q_sqrt0={{(C_MANT_FP64-12){1'b0}},Qcnt_two_9[18:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38]; - Q_sqrt1={{(C_MANT_FP64-13){1'b0}},Qcnt_two_9[18:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40]; - Q_sqrt0={{(C_MANT_FP64-14){1'b0}},Qcnt_two_10[20:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42]; - Q_sqrt1={{(C_MANT_FP64-15){1'b0}},Qcnt_two_10[20:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44]; - Q_sqrt0={{(C_MANT_FP64-16){1'b0}},Qcnt_two_11[22:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46]; - Q_sqrt1={{(C_MANT_FP64-17){1'b0}},Qcnt_two_11[22:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48]; - Q_sqrt0={{(C_MANT_FP64-18){1'b0}},Qcnt_two_12[24:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50]; - Q_sqrt1={{(C_MANT_FP64-19){1'b0}},Qcnt_two_12[24:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52]; - Q_sqrt0={{(C_MANT_FP64-20){1'b0}},Qcnt_two_13[26:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-21){1'b0}},Qcnt_two_13[26:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-22){1'b0}},Qcnt_two_14[28:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-23){1'b0}},Qcnt_two_14[28:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b001111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-24){1'b0}},Qcnt_two_15[30:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-25){1'b0}},Qcnt_two_15[30:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-26){1'b0}},Qcnt_two_16[32:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-27){1'b0}},Qcnt_two_16[32:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-28){1'b0}},Qcnt_two_17[34:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-29){1'b0}},Qcnt_two_17[34:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-30){1'b0}},Qcnt_two_18[36:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-31){1'b0}},Qcnt_two_18[36:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-32){1'b0}},Qcnt_two_19[38:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-33){1'b0}},Qcnt_two_19[38:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-34){1'b0}},Qcnt_two_20[40:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-35){1'b0}},Qcnt_two_20[40:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-36){1'b0}},Qcnt_two_21[42:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-37){1'b0}},Qcnt_two_21[42:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-38){1'b0}},Qcnt_two_22[44:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-39){1'b0}},Qcnt_two_22[44:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b010111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-40){1'b0}},Qcnt_two_23[46:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-41){1'b0}},Qcnt_two_23[46:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b011000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-42){1'b0}},Qcnt_two_24[48:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-43){1'b0}},Qcnt_two_24[48:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b011001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-44){1'b0}},Qcnt_two_25[50:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-45){1'b0}},Qcnt_two_25[50:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b011010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-46){1'b0}},Qcnt_two_26[52:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-47){1'b0}},Qcnt_two_26[52:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b011011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-48){1'b0}},Qcnt_two_27[54:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-49){1'b0}},Qcnt_two_27[54:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - 6'b011100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-50){1'b0}},Qcnt_two_28[56:1]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-51){1'b0}},Qcnt_two_28[56:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - default: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_two_0[1]}; - Sqrt_Q0=Q_sqrt_com_0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_two_0[1:0]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - end - - endcase - end - - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b01, end // - ///////////////////////////////////////////////////////////////////////////// - - - 2'b10: - begin - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b10, start // - ///////////////////////////////////////////////////////////////////////////// - - case(Crtl_cnt_S) - 6'b000000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_three_0[2]}; - Sqrt_Q0=Q_sqrt_com_0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_three_0[2:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4]; - Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_three_0[2:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6]; - Q_sqrt0={{(C_MANT_FP64+2){1'b0}},Qcnt_three_1[4:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8]; - Q_sqrt1={{(C_MANT_FP64+1){1'b0}},Qcnt_three_1[4:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10]; - Q_sqrt2={{(C_MANT_FP64){1'b0}},Qcnt_three_1[4:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12]; - Q_sqrt0={{(C_MANT_FP64-1){1'b0}},Qcnt_three_2[7:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14]; - Q_sqrt1={{(C_MANT_FP64-2){1'b0}},Qcnt_three_2[7:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16]; - Q_sqrt2={{(C_MANT_FP64-3){1'b0}},Qcnt_three_2[7:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18]; - Q_sqrt0={{(C_MANT_FP64-4){1'b0}},Qcnt_three_3[10:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20]; - Q_sqrt1={{(C_MANT_FP64-5){1'b0}},Qcnt_three_3[10:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22]; - Q_sqrt2={{(C_MANT_FP64-6){1'b0}},Qcnt_three_3[10:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24]; - Q_sqrt0={{(C_MANT_FP64-7){1'b0}},Qcnt_three_4[13:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26]; - Q_sqrt1={{(C_MANT_FP64-8){1'b0}},Qcnt_three_4[13:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28]; - Q_sqrt2={{(C_MANT_FP64-9){1'b0}},Qcnt_three_4[13:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30]; - Q_sqrt0={{(C_MANT_FP64-10){1'b0}},Qcnt_three_5[16:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32]; - Q_sqrt1={{(C_MANT_FP64-11){1'b0}},Qcnt_three_5[16:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34]; - Q_sqrt2={{(C_MANT_FP64-12){1'b0}},Qcnt_three_5[16:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000110: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36]; - Q_sqrt0={{(C_MANT_FP64-13){1'b0}},Qcnt_three_6[19:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38]; - Q_sqrt1={{(C_MANT_FP64-14){1'b0}},Qcnt_three_6[19:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40]; - Q_sqrt2={{(C_MANT_FP64-15){1'b0}},Qcnt_three_6[19:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b000111: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42]; - Q_sqrt0={{(C_MANT_FP64-16){1'b0}},Qcnt_three_7[22:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44]; - Q_sqrt1={{(C_MANT_FP64-17){1'b0}},Qcnt_three_7[22:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46]; - Q_sqrt2={{(C_MANT_FP64-18){1'b0}},Qcnt_three_7[22:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48]; - Q_sqrt0={{(C_MANT_FP64-19){1'b0}},Qcnt_three_8[25:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50]; - Q_sqrt1={{(C_MANT_FP64-20){1'b0}},Qcnt_three_8[25:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52]; - Q_sqrt2={{(C_MANT_FP64-21){1'b0}},Qcnt_three_8[25:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-22){1'b0}},Qcnt_three_9[28:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-23){1'b0}},Qcnt_three_9[28:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-24){1'b0}},Qcnt_three_9[28:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-25){1'b0}},Qcnt_three_10[31:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-26){1'b0}},Qcnt_three_10[31:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-27){1'b0}},Qcnt_three_10[31:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-28){1'b0}},Qcnt_three_11[34:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-29){1'b0}},Qcnt_three_11[34:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-30){1'b0}},Qcnt_three_11[34:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-31){1'b0}},Qcnt_three_12[37:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-32){1'b0}},Qcnt_three_12[37:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-33){1'b0}},Qcnt_three_12[37:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-34){1'b0}},Qcnt_three_13[40:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-35){1'b0}},Qcnt_three_13[40:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-36){1'b0}},Qcnt_three_13[40:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001110: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-37){1'b0}},Qcnt_three_14[43:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-38){1'b0}},Qcnt_three_14[43:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-39){1'b0}},Qcnt_three_14[43:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b001111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-40){1'b0}},Qcnt_three_15[46:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-41){1'b0}},Qcnt_three_15[46:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-42){1'b0}},Qcnt_three_15[46:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b010000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-43){1'b0}},Qcnt_three_16[49:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-44){1'b0}},Qcnt_three_16[49:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-45){1'b0}},Qcnt_three_16[49:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b010001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-46){1'b0}},Qcnt_three_17[52:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-47){1'b0}},Qcnt_three_17[52:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-48){1'b0}},Qcnt_three_17[52:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - 6'b010010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-49){1'b0}},Qcnt_three_18[55:2]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-50){1'b0}},Qcnt_three_18[55:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-51){1'b0}},Qcnt_three_18[55:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - - default : - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_three_0[2]}; - Sqrt_Q0=Q_sqrt_com_0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_three_0[2:1]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4]; - Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_three_0[2:0]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - end - endcase - - end - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b10, end // - ///////////////////////////////////////////////////////////////////////////// - - - 2'b11: - begin - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b11, start // - ///////////////////////////////////////////////////////////////////////////// - - case(Crtl_cnt_S) - - 6'b000000: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_four_0[3]}; - Sqrt_Q0=Q_sqrt_com_0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_four_0[3:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4]; - Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_four_0[3:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6]; - Q_sqrt3={{(C_MANT_FP64+2){1'b0}},Qcnt_four_0[3:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000001: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8]; - Q_sqrt0={{(C_MANT_FP64+1){1'b0}},Qcnt_four_1[6:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10]; - Q_sqrt1={{(C_MANT_FP64){1'b0}},Qcnt_four_1[6:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12]; - Q_sqrt2={{(C_MANT_FP64-1){1'b0}},Qcnt_four_1[6:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14]; - Q_sqrt3={{(C_MANT_FP64-2){1'b0}},Qcnt_four_1[6:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000010: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16]; - Q_sqrt0={{(C_MANT_FP64-3){1'b0}},Qcnt_four_2[10:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18]; - Q_sqrt1={{(C_MANT_FP64-4){1'b0}},Qcnt_four_2[10:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20]; - Q_sqrt2={{(C_MANT_FP64-5){1'b0}},Qcnt_four_2[10:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22]; - Q_sqrt3={{(C_MANT_FP64-6){1'b0}},Qcnt_four_2[10:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000011: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24]; - Q_sqrt0={{(C_MANT_FP64-7){1'b0}},Qcnt_four_3[14:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26]; - Q_sqrt1={{(C_MANT_FP64-8){1'b0}},Qcnt_four_3[14:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28]; - Q_sqrt2={{(C_MANT_FP64-9){1'b0}},Qcnt_four_3[14:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30]; - Q_sqrt3={{(C_MANT_FP64-10){1'b0}},Qcnt_four_3[14:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000100: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32]; - Q_sqrt0={{(C_MANT_FP64-11){1'b0}},Qcnt_four_4[18:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34]; - Q_sqrt1={{(C_MANT_FP64-12){1'b0}},Qcnt_four_4[18:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36]; - Q_sqrt2={{(C_MANT_FP64-13){1'b0}},Qcnt_four_4[18:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38]; - Q_sqrt3={{(C_MANT_FP64-14){1'b0}},Qcnt_four_4[18:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000101: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40]; - Q_sqrt0={{(C_MANT_FP64-15){1'b0}},Qcnt_four_5[22:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42]; - Q_sqrt1={{(C_MANT_FP64-16){1'b0}},Qcnt_four_5[22:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44]; - Q_sqrt2={{(C_MANT_FP64-17){1'b0}},Qcnt_four_5[22:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46]; - Q_sqrt3={{(C_MANT_FP64-18){1'b0}},Qcnt_four_5[22:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000110: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48]; - Q_sqrt0={{(C_MANT_FP64-19){1'b0}},Qcnt_four_6[26:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50]; - Q_sqrt1={{(C_MANT_FP64-20){1'b0}},Qcnt_four_6[26:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52]; - Q_sqrt2={{(C_MANT_FP64-21){1'b0}},Qcnt_four_6[26:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-22){1'b0}},Qcnt_four_6[26:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b000111: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-23){1'b0}},Qcnt_four_7[30:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-24){1'b0}},Qcnt_four_7[30:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-25){1'b0}},Qcnt_four_7[30:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-26){1'b0}},Qcnt_four_7[30:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b001000: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-27){1'b0}},Qcnt_four_8[34:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-28){1'b0}},Qcnt_four_8[34:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-29){1'b0}},Qcnt_four_8[34:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-30){1'b0}},Qcnt_four_8[34:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b001001: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-31){1'b0}},Qcnt_four_9[38:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-32){1'b0}},Qcnt_four_9[38:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-33){1'b0}},Qcnt_four_9[38:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-34){1'b0}},Qcnt_four_9[38:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b001010: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-35){1'b0}},Qcnt_four_10[42:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-36){1'b0}},Qcnt_four_10[42:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-37){1'b0}},Qcnt_four_10[42:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-38){1'b0}},Qcnt_four_10[42:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b001011: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-39){1'b0}},Qcnt_four_11[46:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-40){1'b0}},Qcnt_four_11[46:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-41){1'b0}},Qcnt_four_11[46:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-42){1'b0}},Qcnt_four_11[46:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b001100: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-43){1'b0}},Qcnt_four_12[50:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-44){1'b0}},Qcnt_four_12[50:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-45){1'b0}},Qcnt_four_12[50:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-46){1'b0}},Qcnt_four_12[50:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - 6'b001101: - begin - Sqrt_DI[0]=2'b00; - Q_sqrt0={{(C_MANT_FP64-47){1'b0}},Qcnt_four_13[54:3]}; - Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0; - Sqrt_DI[1]=2'b00; - Q_sqrt1={{(C_MANT_FP64-48){1'b0}},Qcnt_four_13[54:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=2'b00; - Q_sqrt2={{(C_MANT_FP64-49){1'b0}},Qcnt_four_13[54:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=2'b00; - Q_sqrt3={{(C_MANT_FP64-50){1'b0}},Qcnt_four_13[54:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - - default: - begin - Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64]; - Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_four_0[3]}; - Sqrt_Q0=Q_sqrt_com_0; - Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2]; - Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_four_0[3:2]}; - Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1; - Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4]; - Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_four_0[3:1]}; - Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2; - Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6]; - Q_sqrt3={{(C_MANT_FP64+2){1'b0}},Qcnt_four_0[3:0]}; - Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3; - end - endcase - end - endcase - ///////////////////////////////////////////////////////////////////////////// - // Operands for square root when Iteration_unit_num_S = 2'b11, end // - ///////////////////////////////////////////////////////////////////////////// - end - - - - assign Sqrt_R0= ((Sqrt_start_dly_S)?'0:{Partial_remainder_DP[C_MANT_FP64+5:0]}); - assign Sqrt_R1= {Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+2:0],Sqrt_DO[0]} ; - assign Sqrt_R2= {Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+2:0],Sqrt_DO[1]}; - assign Sqrt_R3= {Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+2:0],Sqrt_DO[2]}; - assign Sqrt_R4= {Iteration_cell_sum_AMASK_D[3][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[3][C_MANT_FP64+2:0],Sqrt_DO[3]}; - - logic [C_MANT_FP64+5:0] Denominator_se_format_DB; // - - assign Denominator_se_format_DB={Denominator_se_DB[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16ALT],{FP16ALT_SO?FP16ALT_SO:Denominator_se_DB[C_MANT_FP64-C_MANT_FP16ALT-1]}, - Denominator_se_DB[C_MANT_FP64-C_MANT_FP16ALT-2:C_MANT_FP64-C_MANT_FP16],{FP16_SO?FP16_SO:Denominator_se_DB[C_MANT_FP64-C_MANT_FP16-1]}, - Denominator_se_DB[C_MANT_FP64-C_MANT_FP16-2:C_MANT_FP64-C_MANT_FP32],{FP32_SO?FP32_SO:Denominator_se_DB[C_MANT_FP64-C_MANT_FP32-1]}, - Denominator_se_DB[C_MANT_FP64-C_MANT_FP32-2:C_MANT_FP64-C_MANT_FP64],FP64_SO,3'b0} ; - // for iteration cell_U0 - logic [C_MANT_FP64+5:0] First_iteration_cell_div_a_D,First_iteration_cell_div_b_D; - logic Sel_b_for_first_S; - - - assign First_iteration_cell_div_a_D=(Div_start_dly_S)?{Numerator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16ALT],{FP16ALT_SO?FP16ALT_SO:Numerator_se_D[C_MANT_FP64-C_MANT_FP16ALT-1]}, - Numerator_se_D[C_MANT_FP64-C_MANT_FP16ALT-2:C_MANT_FP64-C_MANT_FP16],{FP16_SO?FP16_SO:Numerator_se_D[C_MANT_FP64-C_MANT_FP16-1]}, - Numerator_se_D[C_MANT_FP64-C_MANT_FP16-2:C_MANT_FP64-C_MANT_FP32],{FP32_SO?FP32_SO:Numerator_se_D[C_MANT_FP64-C_MANT_FP32-1]}, - Numerator_se_D[C_MANT_FP64-C_MANT_FP32-2:C_MANT_FP64-C_MANT_FP64],FP64_SO,3'b0} - :{Partial_remainder_DP[C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Quotient_DP[0]:Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16ALT+2]}, - Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Quotient_DP[0]:Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16+2]}, - Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Quotient_DP[0]:Partial_remainder_DP[C_MANT_FP64-C_MANT_FP32+2]}, - Partial_remainder_DP[C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Quotient_DP[0],3'b0}; - assign Sel_b_for_first_S=(Div_start_dly_S)?1:Quotient_DP[0]; - assign First_iteration_cell_div_b_D=Sel_b_for_first_S?Denominator_se_format_DB:{Denominator_se_D,4'b0}; - assign Iteration_cell_a_BMASK_D[0]=Sqrt_enable_SO?Sqrt_R0:{First_iteration_cell_div_a_D}; - assign Iteration_cell_b_BMASK_D[0]=Sqrt_enable_SO?Sqrt_Q0:{First_iteration_cell_div_b_D}; - - - - // for iteration cell_U1 - logic [C_MANT_FP64+5:0] Sec_iteration_cell_div_a_D,Sec_iteration_cell_div_b_D; - logic Sel_b_for_sec_S; - generate - if(|Iteration_unit_num_S) - begin - assign Sel_b_for_sec_S=~Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+5]; - assign Sec_iteration_cell_div_a_D={Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Sel_b_for_sec_S:Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16ALT+2]}, - Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Sel_b_for_sec_S:Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16+2]}, - Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Sel_b_for_sec_S:Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP32+2]}, - Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Sel_b_for_sec_S,3'b0}; - assign Sec_iteration_cell_div_b_D=Sel_b_for_sec_S?Denominator_se_format_DB:{Denominator_se_D,4'b0}; - assign Iteration_cell_a_BMASK_D[1]=Sqrt_enable_SO?Sqrt_R1:{Sec_iteration_cell_div_a_D}; - assign Iteration_cell_b_BMASK_D[1]=Sqrt_enable_SO?Sqrt_Q1:{Sec_iteration_cell_div_b_D}; - end - endgenerate - - // for iteration cell_U2 - logic [C_MANT_FP64+5:0] Thi_iteration_cell_div_a_D,Thi_iteration_cell_div_b_D; - logic Sel_b_for_thi_S; - generate - if((Iteration_unit_num_S==2'b10) | (Iteration_unit_num_S==2'b11)) - begin - assign Sel_b_for_thi_S=~Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+5]; - assign Thi_iteration_cell_div_a_D={Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Sel_b_for_thi_S:Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16ALT+2]}, - Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Sel_b_for_thi_S:Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16+2]}, - Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Sel_b_for_thi_S:Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP32+2]}, - Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Sel_b_for_thi_S,3'b0}; - assign Thi_iteration_cell_div_b_D=Sel_b_for_thi_S?Denominator_se_format_DB:{Denominator_se_D,4'b0}; - assign Iteration_cell_a_BMASK_D[2]=Sqrt_enable_SO?Sqrt_R2:{Thi_iteration_cell_div_a_D}; - assign Iteration_cell_b_BMASK_D[2]=Sqrt_enable_SO?Sqrt_Q2:{Thi_iteration_cell_div_b_D}; - end - endgenerate - - // for iteration cell_U3 - logic [C_MANT_FP64+5:0] Fou_iteration_cell_div_a_D,Fou_iteration_cell_div_b_D; - logic Sel_b_for_fou_S; - - generate - if(Iteration_unit_num_S==2'b11) - begin - assign Sel_b_for_fou_S=~Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+5]; - assign Fou_iteration_cell_div_a_D={Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Sel_b_for_fou_S:Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16ALT+2]}, - Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Sel_b_for_fou_S:Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16+2]}, - Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Sel_b_for_fou_S:Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP32+2]}, - Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Sel_b_for_fou_S,3'b0}; - assign Fou_iteration_cell_div_b_D=Sel_b_for_fou_S?Denominator_se_format_DB:{Denominator_se_D,4'b0}; - assign Iteration_cell_a_BMASK_D[3]=Sqrt_enable_SO?Sqrt_R3:{Fou_iteration_cell_div_a_D}; - assign Iteration_cell_b_BMASK_D[3]=Sqrt_enable_SO?Sqrt_Q3:{Fou_iteration_cell_div_b_D}; - end - endgenerate - - ///////////////////////////////////////////////////////////////////////////// - // Masking Contrl // - ///////////////////////////////////////////////////////////////////////////// - - - logic [C_MANT_FP64+1+4:0] Mask_bits_ctl_S; //For extension - - assign Mask_bits_ctl_S =58'h3ff_ffff_ffff_ffff; //It is not needed. The corresponding process is handled the above codes - - ///////////////////////////////////////////////////////////////////////////// - // Iteration Instances with masking control // - ///////////////////////////////////////////////////////////////////////////// - - - logic Div_enable_SI [3:0]; - logic Div_start_dly_SI [3:0]; - logic Sqrt_enable_SI [3:0]; - generate - genvar i,j; - for (i=0; i <= Iteration_unit_num_S ; i++) - begin - for (j = 0; j <= C_MANT_FP64+5; j++) begin - assign Iteration_cell_a_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_a_BMASK_D[i][j]; - assign Iteration_cell_b_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_b_BMASK_D[i][j]; - assign Iteration_cell_sum_AMASK_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_sum_D[i][j]; - end - - assign Div_enable_SI[i] = Div_enable_SO; - assign Div_start_dly_SI[i] = Div_start_dly_S; - assign Sqrt_enable_SI[i] = Sqrt_enable_SO; - iteration_div_sqrt_mvp #(C_MANT_FP64+6) iteration_div_sqrt - ( - .A_DI (Iteration_cell_a_D[i] ), - .B_DI (Iteration_cell_b_D[i] ), - .Div_enable_SI (Div_enable_SI[i] ), - .Div_start_dly_SI (Div_start_dly_SI[i] ), - .Sqrt_enable_SI (Sqrt_enable_SI[i] ), - .D_DI (Sqrt_DI[i] ), - .D_DO (Sqrt_DO[i] ), - .Sum_DO (Iteration_cell_sum_D[i] ), - .Carry_out_DO (Iteration_cell_carry_D[i] ) - ); - - end - - endgenerate - - - - always_comb - begin - case (Iteration_unit_num_S) - 2'b00: - begin - if(Fsm_enable_S) - Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R1:Iteration_cell_sum_AMASK_D[0]; - else - Partial_remainder_DN = Partial_remainder_DP; - end - 2'b01: - begin - if(Fsm_enable_S) - Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R2:Iteration_cell_sum_AMASK_D[1]; - else - Partial_remainder_DN = Partial_remainder_DP; - end - 2'b10: - begin - if(Fsm_enable_S) - Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R3:Iteration_cell_sum_AMASK_D[2]; - else - Partial_remainder_DN = Partial_remainder_DP; - end - 2'b11: - begin - if(Fsm_enable_S) - Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R4:Iteration_cell_sum_AMASK_D[3]; - else - Partial_remainder_DN = Partial_remainder_DP; - end - endcase - end - - - - always_ff @(posedge Clk_CI, negedge Rst_RBI) // partial_remainder - begin - if(~Rst_RBI) - begin - Partial_remainder_DP <= '0; - end - else - begin - Partial_remainder_DP <= Partial_remainder_DN; - end - end - - logic [C_MANT_FP64+4:0] Quotient_DN; - - always_comb // Can choosen the different carry-outs based on different operations - begin - case (Iteration_unit_num_S) - 2'b00: - begin - if(Fsm_enable_S) - Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64+3:0],Sqrt_quotinent_S[3]} :{Quotient_DP[C_MANT_FP64+3:0],Iteration_cell_carry_D[0]}; - else - Quotient_DN= Quotient_DP; - end - 2'b01: - begin - if(Fsm_enable_S) - Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64+2:0],Sqrt_quotinent_S[3:2]} :{Quotient_DP[C_MANT_FP64+2:0],Iteration_cell_carry_D[0],Iteration_cell_carry_D[1]}; - else - Quotient_DN= Quotient_DP; - end - 2'b10: - begin - if(Fsm_enable_S) - Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64+1:0],Sqrt_quotinent_S[3:1]} : {Quotient_DP[C_MANT_FP64+1:0],Iteration_cell_carry_D[0],Iteration_cell_carry_D[1],Iteration_cell_carry_D[2]}; - else - Quotient_DN= Quotient_DP; - end - 2'b11: - begin - if(Fsm_enable_S) - Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64:0],Sqrt_quotinent_S } : {Quotient_DP[C_MANT_FP64:0],Iteration_cell_carry_D[0],Iteration_cell_carry_D[1],Iteration_cell_carry_D[2],Iteration_cell_carry_D[3]}; - else - Quotient_DN= Quotient_DP; - end - endcase - end - - always_ff @(posedge Clk_CI, negedge Rst_RBI) // Quotient - begin - if(~Rst_RBI) - begin - Quotient_DP <= '0; - end - else - Quotient_DP <= Quotient_DN; - end - - - ///////////////////////////////////////////////////////////////////////////// - // Precision Control for outputs // - ///////////////////////////////////////////////////////////////////////////// - - -//////////////////////one iteration unit, start/////////////////////////////////////// - generate - if(Iteration_unit_num_S==2'b00) - begin - always_comb - begin - case (Format_sel_S) - 2'b00: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4 - end - 6'h17: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h16: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-1:0],{(C_MANT_FP64-C_MANT_FP32+4+1){1'b0}}}; //Precision_ctl_S+1 - end - 6'h15: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-2:0],{(C_MANT_FP64-C_MANT_FP32+4+2){1'b0}}}; //Precision_ctl_S+1 - end - 6'h14: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-3:0],{(C_MANT_FP64-C_MANT_FP32+4+3){1'b0}}}; //Precision_ctl_S+1 - end - 6'h13: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-4:0],{(C_MANT_FP64-C_MANT_FP32+4+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h12: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-5:0],{(C_MANT_FP64-C_MANT_FP32+4+5){1'b0}}}; //Precision_ctl_S+1 - end - 6'h11: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-6:0],{(C_MANT_FP64-C_MANT_FP32+4+6){1'b0}}}; //Precision_ctl_S+1 - end - 6'h10: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-7:0],{(C_MANT_FP64-C_MANT_FP32+4+7){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0f: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-8:0],{(C_MANT_FP64-C_MANT_FP32+4+8){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-9:0],{(C_MANT_FP64-C_MANT_FP32+4+9){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0d: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-10:0],{(C_MANT_FP64-C_MANT_FP32+4+10){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-11:0],{(C_MANT_FP64-C_MANT_FP32+4+11){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0b: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-13:0],{(C_MANT_FP64-C_MANT_FP32+4+13){1'b0}}}; //Precision_ctl_S+1 - end - 6'h09: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-14:0],{(C_MANT_FP64-C_MANT_FP32+4+14){1'b0}}}; //Precision_ctl_S+1 - end - 6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-15:0],{(C_MANT_FP64-C_MANT_FP32+4+15){1'b0}}}; //Precision_ctl_S+1 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-16:0],{(C_MANT_FP64-C_MANT_FP32+4+16){1'b0}}}; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4 - end - endcase - end - - 2'b01: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4 - end - 6'h34: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64:0],{(4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h33: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-1:0],{(4+1){1'b0}}}; //Precision_ctl_S+1 - end - 6'h32: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-2:0],{(4+2){1'b0}}}; //Precision_ctl_S+1 - end - 6'h31: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-3:0],{(4+3){1'b0}}}; //Precision_ctl_S+1 - end - 6'h30: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-4:0],{(4+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h2f: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(4+5){1'b0}}}; //Precision_ctl_S+1 - end - 6'h2e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-6:0],{(4+6){1'b0}}}; //Precision_ctl_S+1 - end - 6'h2d: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-7:0],{(4+7){1'b0}}}; //Precision_ctl_S+1 - end - 6'h2c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-8:0],{(4+8){1'b0}}}; //Precision_ctl_S+1 - end - 6'h2b: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-9:0],{(4+9){1'b0}}}; //Precision_ctl_S+1 - end - 6'h2a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-10:0],{(4+10){1'b0}}}; //Precision_ctl_S+1 - end - 6'h29: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-11:0],{(4+11){1'b0}}}; //Precision_ctl_S+1 - end - 6'h28: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-12:0],{(4+12){1'b0}}}; //Precision_ctl_S+1 - end - 6'h27: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-13:0],{(4+13){1'b0}}}; //Precision_ctl_S+1 - end - 6'h26: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-14:0],{(4+14){1'b0}}}; //Precision_ctl_S+1 - end - 6'h25: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-15:0],{(4+15){1'b0}}}; //Precision_ctl_S+1 - end - 6'h24: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-16:0],{(4+16){1'b0}}}; //Precision_ctl_S+1 - end - 6'h23: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(4+17){1'b0}}}; //Precision_ctl_S+1 - end - 6'h22: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-18:0],{(4+18){1'b0}}}; //Precision_ctl_S+1 - end - 6'h21: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-19:0],{(4+19){1'b0}}}; //Precision_ctl_S+1 - end - 6'h20: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-20:0],{(4+20){1'b0}}}; //Precision_ctl_S+1 - end - 6'h1f: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-21:0],{(4+21){1'b0}}}; //Precision_ctl_S+1 - end - 6'h1e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-22:0],{(4+22){1'b0}}}; //Precision_ctl_S+1 - end - 6'h1d: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-23:0],{(4+23){1'b0}}}; //Precision_ctl_S+1 - end - 6'h1c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-24:0],{(4+24){1'b0}}}; //Precision_ctl_S+1 - end - 6'h1b: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-25:0],{(4+25){1'b0}}}; //Precision_ctl_S+1 - end - 6'h1a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-26:0],{(4+26){1'b0}}}; //Precision_ctl_S+1 - end - 6'h19: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-27:0],{(4+27){1'b0}}}; //Precision_ctl_S+1 - end - 6'h18: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-28:0],{(4+28){1'b0}}}; //Precision_ctl_S+1 - end - 6'h17: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(4+29){1'b0}}}; //Precision_ctl_S+1 - end - 6'h16: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-30:0],{(4+30){1'b0}}}; //Precision_ctl_S+1 - end - 6'h15: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-31:0],{(4+31){1'b0}}}; //Precision_ctl_S+1 - end - 6'h14: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-32:0],{(4+32){1'b0}}}; //Precision_ctl_S+1 - end - 6'h13: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-33:0],{(4+33){1'b0}}}; //Precision_ctl_S+1 - end - 6'h12: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-34:0],{(4+34){1'b0}}}; //Precision_ctl_S+1 - end - 6'h11: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-35:0],{(4+35){1'b0}}}; //Precision_ctl_S+1 - end - 6'h10: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-36:0],{(4+36){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0f: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-37:0],{(4+37){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-38:0],{(4+38){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0d: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-39:0],{(4+39){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-40:0],{(4+40){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0b: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(4+41){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-42:0],{(4+42){1'b0}}}; //Precision_ctl_S+1 - end - 6'h09: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-43:0],{(4+43){1'b0}}}; //Precision_ctl_S+1 - end - 6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-44:0],{(4+44){1'b0}}}; //Precision_ctl_S+1 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-45:0],{(4+45){1'b0}}}; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4 - end - endcase - end - - 2'b10: - begin - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}}}; //+4 - end - 6'h0a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16:0],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h09: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-1:0],{(C_MANT_FP64-C_MANT_FP16+4+1){1'b0}}}; //Precision_ctl_S+1 - end - 6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-2:0],{(C_MANT_FP64-C_MANT_FP16+4+2){1'b0}}}; //Precision_ctl_S+1 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-3:0],{(C_MANT_FP64-C_MANT_FP16+4+3){1'b0}}}; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}}}; //+4 - end - endcase - end - - 2'b11: - begin - - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}}}; //+4 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT:0],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}}}; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}}}; //+4 - end - endcase - end - endcase - end - end - endgenerate -//////////////////////one iteration unit, end////////////////////////////////////////// - -//////////////////////two iteration units, start/////////////////////////////////////// - generate - if(Iteration_unit_num_S==2'b01) - begin - always_comb - begin - case (Format_sel_S) - 2'b00: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4 - end - 6'h17,6'h16: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h15,6'h14: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-2:0],{(C_MANT_FP64-C_MANT_FP32+4+2){1'b0}}}; //Precision_ctl_S+1 - end - 6'h13,6'h12: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-4:0],{(C_MANT_FP64-C_MANT_FP32+4+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h11,6'h10: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-6:0],{(C_MANT_FP64-C_MANT_FP32+4+6){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0f,6'h0e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-8:0],{(C_MANT_FP64-C_MANT_FP32+4+8){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0d,6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-10:0],{(C_MANT_FP64-C_MANT_FP32+4+10){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0b,6'h0a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1 - end - 6'h09,6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-14:0],{(C_MANT_FP64-C_MANT_FP32+4+14){1'b0}}}; //Precision_ctl_S+1 - end - 6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-16:0],{(C_MANT_FP64-C_MANT_FP32+4+16){1'b0}}}; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4 - end - endcase - end - 2'b01: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],1'b0}; //+3 - end - 6'h34: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+1:1],{(4){1'b0}} }; //Precision_ctl_S+1 - end - 6'h33,6'h32: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-1:0],{(4+1){1'b0}} }; //Precision_ctl_S+1 - end - 6'h31,6'h30: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-3:0],{(4+3){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2f,6'h2e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(4+5){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2d,6'h2c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-7:0],{(4+7){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2b,6'h2a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-9:0],{(4+9){1'b0}} }; //Precision_ctl_S+1 - end - 6'h29,6'h28: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-11:0],{(4+11){1'b0}} }; //Precision_ctl_S+1 - end - 6'h27,6'h26: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-13:0],{(4+13){1'b0}} }; //Precision_ctl_S+1 - end - 6'h25,6'h24: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-15:0],{(4+15){1'b0}} }; //Precision_ctl_S+1 - end - 6'h23,6'h22: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(4+17){1'b0}} }; //Precision_ctl_S+1 - end - 6'h21,6'h20: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-19:0],{(4+19){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1f,6'h1e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-21:0],{(4+21){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1d,6'h1c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-23:0],{(4+23){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1b,6'h1a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-25:0],{(4+25){1'b0}} }; //Precision_ctl_S+1 - end - 6'h19,6'h18: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-27:0],{(4+27){1'b0}} }; //Precision_ctl_S+1 - end - 6'h17,6'h16: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(4+29){1'b0}} }; //Precision_ctl_S+1 - end - 6'h15,6'h14: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-31:0],{(4+31){1'b0}} }; //Precision_ctl_S+1 - end - 6'h13,6'h12: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-33:0],{(4+33){1'b0}} }; //Precision_ctl_S+1 - end - 6'h11,6'h10: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-35:0],{(4+35){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0f,6'h0e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-37:0],{(4+37){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0d,6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-39:0],{(4+39){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0b,6'h0a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(4+41){1'b0}} }; //Precision_ctl_S+1 - end - 6'h09,6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-43:0],{(4+43){1'b0}} }; //Precision_ctl_S+1 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-45:0],{(4+45){1'b0}} }; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],1'b0}; //+3 - end - endcase - end - - 2'b10: - begin - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+3:0],{(C_MANT_FP64-C_MANT_FP16+1){1'b0}} }; //+3 - end - 6'h0a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1:1],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}} }; //Precision_ctl_S+1 - end - 6'h09,6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-1:0],{(C_MANT_FP64-C_MANT_FP16+4+1){1'b0}} }; //Precision_ctl_S+1 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-3:0],{(C_MANT_FP64-C_MANT_FP16+4+3){1'b0}} }; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}} }; //+4 - end - endcase - end - - 2'b11: - begin - - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4 - end - 6'h07: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT:0],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}} }; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4 - end - endcase - end - endcase - end - end - endgenerate -//////////////////////two iteration units, end////////////////////////////////////////// - -//////////////////////three iteration units, start/////////////////////////////////////// - generate - if(Iteration_unit_num_S==2'b10) - begin - always_comb - begin - case (Format_sel_S) - 2'b00: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+3:0],{(C_MANT_FP64-C_MANT_FP32+1){1'b0}}}; //+3 - end - 6'h17,6'h16,6'h15: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h14,6'h13,6'h12: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-3:0],{(C_MANT_FP64-C_MANT_FP32+4+3){1'b0}}}; //Precision_ctl_S+1 - end - 6'h11,6'h10,6'h0f: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-6:0],{(C_MANT_FP64-C_MANT_FP32+4+6){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0e,6'h0d,6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-9:0],{(C_MANT_FP64-C_MANT_FP32+4+9){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0b,6'h0a,6'h09: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1 - end - 6'h08,6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-15:0],{(C_MANT_FP64-C_MANT_FP32+4+15){1'b0}}}; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+3:0],{(C_MANT_FP64-C_MANT_FP32+1){1'b0}}}; //+3 - end - endcase - end - - 2'b01: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4 - end - 6'h34,6'h33: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+1:1],{(4){1'b0}} }; //Precision_ctl_S+1 - end - 6'h32,6'h31,6'h30: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-2:0],{(4+2){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2f,6'h2e,6'h2d: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(4+5){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2c,6'h2b,6'h2a: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-8:0],{(4+8){1'b0}} }; //Precision_ctl_S+1 - end - 6'h29,6'h28,6'h27: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-11:0],{(4+11){1'b0}} }; //Precision_ctl_S+1 - end - 6'h26,6'h25,6'h24: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-14:0],{(4+14){1'b0}} }; //Precision_ctl_S+1 - end - 6'h23,6'h22,6'h21: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(4+17){1'b0}} }; //Precision_ctl_S+1 - end - 6'h20,6'h1f,6'h1e: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-20:0],{(4+20){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1d,6'h1c,6'h1b: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-23:0],{(4+23){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1a,6'h19,6'h18: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-26:0],{(4+26){1'b0}} }; //Precision_ctl_S+1 - end - 6'h17,6'h16,6'h15: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(4+29){1'b0}} }; //Precision_ctl_S+1 - end - 6'h14,6'h13,6'h12: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-32:0],{(4+32){1'b0}} }; //Precision_ctl_S+1 - end - 6'h11,6'h10,6'h0f: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-35:0],{(4+35){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0e,6'h0d,6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-38:0],{(4+38){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0b,6'h0a,6'h09: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(4+41){1'b0}} }; //Precision_ctl_S+1 - end - 6'h08,6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-44:0],{(4+44){1'b0}} }; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4 - end - endcase - end - - 2'b10: - begin - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}} }; //+4 - end - 6'h0a,6'h09: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1:1],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}} }; //Precision_ctl_S+1 - end - 6'h08,6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-2:0],{(C_MANT_FP64-C_MANT_FP16+4+2){1'b0}} }; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}} }; //+4 - end - endcase - end - - 2'b11: - begin - - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4 - end - 6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+1:1],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}} }; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4 - end - endcase - end - endcase - end - end - endgenerate -//////////////////////three iteration units, end////////////////////////////////////////// - -//////////////////////four iteration units, start/////////////////////////////////////// - generate - if(Iteration_unit_num_S==2'b11) - begin - always_comb - begin - case (Format_sel_S) - 2'b00: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4 - end - 6'h17,6'h16,6'h15,6'h14: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h13,6'h12,6'h11,6'h10: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-4:0],{(C_MANT_FP64-C_MANT_FP32+4+4){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0f,6'h0e,6'h0d,6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-8:0],{(C_MANT_FP64-C_MANT_FP32+4+8){1'b0}}}; //Precision_ctl_S+1 - end - 6'h0b,6'h0a,6'h09,6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1 - end - 6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-16:0],{(C_MANT_FP64-C_MANT_FP32+4+16){1'b0}}}; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4 - end - endcase - end - - 2'b01: - begin - case (Precision_ctl_S) - 6'h00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],{(1){1'b0}}}; //+3 - end - 6'h34: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],{(1){1'b0}} }; //Precision_ctl_S+1 - end - 6'h33,6'h32,6'h31,6'h30: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-1:0],{(5){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2f,6'h2e,6'h2d,6'h2c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(9){1'b0}} }; //Precision_ctl_S+1 - end - 6'h2b,6'h2a,6'h29,6'h28: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-9:0],{(13){1'b0}} }; //Precision_ctl_S+1 - end - 6'h27,6'h26,6'h25,6'h24: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-13:0],{(17){1'b0}} }; //Precision_ctl_S+1 - end - 6'h23,6'h22,6'h21,6'h20: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(21){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1f,6'h1e,6'h1d,6'h1c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-21:0],{(25){1'b0}} }; //Precision_ctl_S+1 - end - 6'h1b,6'h1a,6'h19,6'h18: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-25:0],{(29){1'b0}} }; //Precision_ctl_S+1 - end - 6'h17,6'h16,6'h15,6'h14: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(33){1'b0}} }; //Precision_ctl_S+1 - end - 6'h13,6'h12,6'h11,6'h10: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-33:0],{(37){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0f,6'h0e,6'h0d,6'h0c: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-37:0],{(41){1'b0}} }; //Precision_ctl_S+1 - end - 6'h0b,6'h0a,6'h09,6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(45){1'b0}} }; //Precision_ctl_S+1 - end - 6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-45:0],{(49){1'b0}} }; //Precision_ctl_S+1 - end - default: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],{(1){1'b0}}}; //+3 - end - endcase - end - - 2'b10: - begin - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+5:0],{(C_MANT_FP64-C_MANT_FP16-1){1'b0}} }; //+5 - end - 6'h0a,6'h09,6'h08: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1:1],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}} }; //Precision_ctl_S+1 - end - 6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1-4:0],{(C_MANT_FP64-C_MANT_FP16+4+3){1'b0}} }; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+5:0],{(C_MANT_FP64-C_MANT_FP16-1){1'b0}} }; //+5 - end - endcase - end - - 2'b11: - begin - - case (Precision_ctl_S) - 6'b00: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4 - end - 6'h07,6'h06: - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT:0],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}} }; //Precision_ctl_S+1 - end - default : - begin - Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4 - end - endcase - end - endcase - end - end - endgenerate -//////////////////////four iteration units, end/////////////////////////////////////// - - - - - -// resultant exponent - logic [C_EXP_FP64+1:0] Exp_result_prenorm_DN,Exp_result_prenorm_DP; - - logic [C_EXP_FP64+1:0] Exp_add_a_D; - logic [C_EXP_FP64+1:0] Exp_add_b_D; - logic [C_EXP_FP64+1:0] Exp_add_c_D; - - integer C_BIAS_AONE, C_HALF_BIAS; - always_comb - begin // - case (Format_sel_S) - 2'b00: - begin - C_BIAS_AONE =C_BIAS_AONE_FP32; - C_HALF_BIAS =C_HALF_BIAS_FP32; - end - 2'b01: - begin - C_BIAS_AONE =C_BIAS_AONE_FP64; - C_HALF_BIAS =C_HALF_BIAS_FP64; - end - 2'b10: - begin - C_BIAS_AONE =C_BIAS_AONE_FP16; - C_HALF_BIAS =C_HALF_BIAS_FP16; - end - 2'b11: - begin - C_BIAS_AONE =C_BIAS_AONE_FP16ALT; - C_HALF_BIAS =C_HALF_BIAS_FP16ALT; - end - endcase - end - -//For division, exponent=(Exp_a_D-LZ1)-(Exp_b_D-LZ2)+BIAS -//For square root, exponent=(Exp_a_D-LZ1)/2+(Exp_a_D-LZ1)%2+C_HALF_BIAS -//For exponent, in preprorces module, (Exp_a_D-LZ1) and (Exp_b_D-LZ2) have been processed with the corresponding process for denormal numbers. - - assign Exp_add_a_D = {Sqrt_start_dly_S?{Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64:1]}:{Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64],Exp_num_DI}}; - assign Exp_add_b_D = {Sqrt_start_dly_S?{1'b0,{C_EXP_ZERO_FP64},Exp_num_DI[0]}:{~Exp_den_DI[C_EXP_FP64],~Exp_den_DI[C_EXP_FP64],~Exp_den_DI}}; - assign Exp_add_c_D = {Div_start_dly_S?{{C_BIAS_AONE}}:{{C_HALF_BIAS}}}; - assign Exp_result_prenorm_DN = (Start_dly_S)?{Exp_add_a_D + Exp_add_b_D + Exp_add_c_D}:Exp_result_prenorm_DP; - - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Exp_result_prenorm_DP <= '0; - end - else - begin - Exp_result_prenorm_DP<= Exp_result_prenorm_DN; - end - end - - assign Exp_result_prenorm_DO = Exp_result_prenorm_DP; - -endmodule diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv deleted file mode 100644 index b3f41fec6..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv +++ /dev/null @@ -1,83 +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. -// -// This file contains all div_sqrt_top_mvp parameters -// Authors : Lei Li (lile@iis.ee.ethz.ch) - -package defs_div_sqrt_mvp; - - // op command - localparam C_RM = 3; - localparam C_RM_NEAREST = 3'h0; - localparam C_RM_TRUNC = 3'h1; - localparam C_RM_PLUSINF = 3'h2; - localparam C_RM_MINUSINF = 3'h3; - localparam C_PC = 6; // Precision Control - localparam C_FS = 2; // Format Selection - localparam C_IUNC = 2; // Iteration Unit Number Control - localparam Iteration_unit_num_S = 2'b10; - - // FP64 - localparam C_OP_FP64 = 64; - localparam C_MANT_FP64 = 52; - localparam C_EXP_FP64 = 11; - localparam C_BIAS_FP64 = 1023; - localparam C_BIAS_AONE_FP64 = 11'h400; - localparam C_HALF_BIAS_FP64 = 511; - localparam C_EXP_ZERO_FP64 = 11'h000; - localparam C_EXP_ONE_FP64 = 13'h001; // Bit width is in agreement with in norm - localparam C_EXP_INF_FP64 = 11'h7FF; - localparam C_MANT_ZERO_FP64 = 52'h0; - localparam C_MANT_NAN_FP64 = 52'h8_0000_0000_0000; - localparam C_PZERO_FP64 = 64'h0000_0000_0000_0000; - localparam C_MZERO_FP64 = 64'h8000_0000_0000_0000; - localparam C_QNAN_FP64 = 64'h7FF8_0000_0000_0000; - - // FP32 - localparam C_OP_FP32 = 32; - localparam C_MANT_FP32 = 23; - localparam C_EXP_FP32 = 8; - localparam C_BIAS_FP32 = 127; - localparam C_BIAS_AONE_FP32 = 8'h80; - localparam C_HALF_BIAS_FP32 = 63; - localparam C_EXP_ZERO_FP32 = 8'h00; - localparam C_EXP_INF_FP32 = 8'hFF; - localparam C_MANT_ZERO_FP32 = 23'h0; - localparam C_PZERO_FP32 = 32'h0000_0000; - localparam C_MZERO_FP32 = 32'h8000_0000; - localparam C_QNAN_FP32 = 32'h7FC0_0000; - - // FP16 - localparam C_OP_FP16 = 16; - localparam C_MANT_FP16 = 10; - localparam C_EXP_FP16 = 5; - localparam C_BIAS_FP16 = 15; - localparam C_BIAS_AONE_FP16 = 5'h10; - localparam C_HALF_BIAS_FP16 = 7; - localparam C_EXP_ZERO_FP16 = 5'h00; - localparam C_EXP_INF_FP16 = 5'h1F; - localparam C_MANT_ZERO_FP16 = 10'h0; - localparam C_PZERO_FP16 = 16'h0000; - localparam C_MZERO_FP16 = 16'h8000; - localparam C_QNAN_FP16 = 16'h7E00; - - // FP16alt - localparam C_OP_FP16ALT = 16; - localparam C_MANT_FP16ALT = 7; - localparam C_EXP_FP16ALT = 8; - localparam C_BIAS_FP16ALT = 127; - localparam C_BIAS_AONE_FP16ALT = 8'h80; - localparam C_HALF_BIAS_FP16ALT = 63; - localparam C_EXP_ZERO_FP16ALT = 8'h00; - localparam C_EXP_INF_FP16ALT = 8'hFF; - localparam C_MANT_ZERO_FP16ALT = 7'h0; - localparam C_QNAN_FP16ALT = 16'h7FC0; - -endpackage : defs_div_sqrt_mvp diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv deleted file mode 100644 index 051bcc3ad..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv +++ /dev/null @@ -1,232 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li -- lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 20/04/2018 // -// Design Name: FPU // -// Module Name: div_sqrt_mvp_wrapper.sv // -// Project Name: The shared divisor and square root // -// Language: SystemVerilog // -// // -// Description: The wrapper of div_sqrt_top_mvp // -// // -// // -// // -// // -// // -// // -// // -// // -// // -// // -// // -//////////////////////////////////////////////////////////////////////////////// - -import defs_div_sqrt_mvp::*; - -module div_sqrt_mvp_wrapper -#( - parameter PrePipeline_depth_S = 0, // If you want to add a flip/flop stage before preprocess, set it to 1. - parameter PostPipeline_depth_S = 2 // The output delay stages -) - (//Input - input logic Clk_CI, - input logic Rst_RBI, - input logic Div_start_SI, - input logic Sqrt_start_SI, - - //Input Operands - input logic [C_OP_FP64-1:0] Operand_a_DI, - input logic [C_OP_FP64-1:0] Operand_b_DI, - - // Input Control - input logic [C_RM-1:0] RM_SI, //Rounding Mode - input logic [C_PC-1:0] Precision_ctl_SI, // Precision Control - input logic [C_FS-1:0] Format_sel_SI, // Format Selection, - input logic Kill_SI, - - //Output Result - output logic [C_OP_FP64-1:0] Result_DO, - - //Output-Flags - output logic [4:0] Fflags_SO, - output logic Ready_SO, - output logic Done_SO - ); - - - logic Div_start_S_S,Sqrt_start_S_S; - logic [C_OP_FP64-1:0] Operand_a_S_D; - logic [C_OP_FP64-1:0] Operand_b_S_D; - - // Input Control - logic [C_RM-1:0] RM_S_S; //Rounding Mode - logic [C_PC-1:0] Precision_ctl_S_S; // Precision Control - logic [C_FS-1:0] Format_sel_S_S; // Format Selection, - logic Kill_S_S; - - - logic [C_OP_FP64-1:0] Result_D; - logic Ready_S; - logic Done_S; - logic [4:0] Fflags_S; - - - generate - if(PrePipeline_depth_S==1) - begin - - div_sqrt_top_mvp div_top_U0 //for RTL - - (//Input - .Clk_CI (Clk_CI), - .Rst_RBI (Rst_RBI), - .Div_start_SI (Div_start_S_S), - .Sqrt_start_SI (Sqrt_start_S_S), - //Input Operands - .Operand_a_DI (Operand_a_S_D), - .Operand_b_DI (Operand_b_S_D), - .RM_SI (RM_S_S), //Rounding Mode - .Precision_ctl_SI (Precision_ctl_S_S), - .Format_sel_SI (Format_sel_S_S), - .Kill_SI (Kill_S_S), - .Result_DO (Result_D), - .Fflags_SO (Fflags_S), - .Ready_SO (Ready_S), - .Done_SO (Done_S) - ); - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Div_start_S_S<='0; - Sqrt_start_S_S<=1'b0; - Operand_a_S_D<='0; - Operand_b_S_D<='0; - RM_S_S <=1'b0; - Precision_ctl_S_S<='0; - Format_sel_S_S<='0; - Kill_S_S<='0; - end - else - begin - Div_start_S_S<=Div_start_SI; - Sqrt_start_S_S<=Sqrt_start_SI; - Operand_a_S_D<=Operand_a_DI; - Operand_b_S_D<=Operand_b_DI; - RM_S_S <=RM_SI; - Precision_ctl_S_S<=Precision_ctl_SI; - Format_sel_S_S<=Format_sel_SI; - Kill_S_S<=Kill_SI; - end - end - end - - else - begin - div_sqrt_top_mvp div_top_U0 //for RTL - (//Input - .Clk_CI (Clk_CI), - .Rst_RBI (Rst_RBI), - .Div_start_SI (Div_start_SI), - .Sqrt_start_SI (Sqrt_start_SI), - //Input Operands - .Operand_a_DI (Operand_a_DI), - .Operand_b_DI (Operand_b_DI), - .RM_SI (RM_SI), //Rounding Mode - .Precision_ctl_SI (Precision_ctl_SI), - .Format_sel_SI (Format_sel_SI), - .Kill_SI (Kill_SI), - .Result_DO (Result_D), - .Fflags_SO (Fflags_S), - .Ready_SO (Ready_S), - .Done_SO (Done_S) - ); - end - endgenerate - - ///////////////////////////////////////////////////////////////////////////// - // First Stage of Outputs - ///////////////////////////////////////////////////////////////////////////// - logic [C_OP_FP64-1:0] Result_dly_S_D; - logic Ready_dly_S_S; - logic Done_dly_S_S; - logic [4:0] Fflags_dly_S_S; - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Result_dly_S_D<='0; - Ready_dly_S_S<=1'b0; - Done_dly_S_S<=1'b0; - Fflags_dly_S_S<=1'b0; - end - else - begin - Result_dly_S_D<=Result_D; - Ready_dly_S_S<=Ready_S; - Done_dly_S_S<=Done_S; - Fflags_dly_S_S<=Fflags_S; - end - end - - ///////////////////////////////////////////////////////////////////////////// - // Second Stage of Outputs - ///////////////////////////////////////////////////////////////////////////// - - logic [C_OP_FP64-1:0] Result_dly_D_D; - logic Ready_dly_D_S; - logic Done_dly_D_S; - logic [4:0] Fflags_dly_D_S; - generate - if(PostPipeline_depth_S==2) - begin - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Result_dly_D_D<='0; - Ready_dly_D_S<=1'b0; - Done_dly_D_S<=1'b0; - Fflags_dly_D_S<=1'b0; - end - else - begin - Result_dly_D_D<=Result_dly_S_D; - Ready_dly_D_S<=Ready_dly_S_S; - Done_dly_D_S<=Done_dly_S_S; - Fflags_dly_D_S<=Fflags_dly_S_S; - end - end - assign Result_DO = Result_dly_D_D; - assign Ready_SO = Ready_dly_D_S; - assign Done_SO = Done_dly_D_S; - assign Fflags_SO=Fflags_dly_D_S; - end - - else - begin - assign Result_DO = Result_dly_S_D; - assign Ready_SO = Ready_dly_S_S; - assign Done_SO = Done_dly_S_S; - assign Fflags_SO = Fflags_dly_S_S; - end - - endgenerate - -endmodule // diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv deleted file mode 100644 index 3af6081b7..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv +++ /dev/null @@ -1,180 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li -- lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 03/03/2018 // -// Design Name: div_sqrt_top_mvp // -// Module Name: div_sqrt_top_mvp.sv // -// Project Name: The shared divisor and square root // -// Language: SystemVerilog // -// // -// Description: The top of div and sqrt // -// // -// // -// Revision Date: 12/04/2018 // -// Lei Li // -// To address some requirements by Stefan and add low power // -// control for special cases // -//////////////////////////////////////////////////////////////////////////////// - -import defs_div_sqrt_mvp::*; - -module div_sqrt_top_mvp - - (//Input - input logic Clk_CI, - input logic Rst_RBI, - input logic Div_start_SI, - input logic Sqrt_start_SI, - - //Input Operands - input logic [C_OP_FP64-1:0] Operand_a_DI, - input logic [C_OP_FP64-1:0] Operand_b_DI, - - // Input Control - input logic [C_RM-1:0] RM_SI, //Rounding Mode - input logic [C_PC-1:0] Precision_ctl_SI, // Precision Control - input logic [C_FS-1:0] Format_sel_SI, // Format Selection, - input logic Kill_SI, - - //Output Result - output logic [C_OP_FP64-1:0] Result_DO, - - //Output-Flags - output logic [4:0] Fflags_SO, - output logic Ready_SO, - output logic Done_SO - ); - - - - - - //Operand components - logic [C_EXP_FP64:0] Exp_a_D; - logic [C_EXP_FP64:0] Exp_b_D; - logic [C_MANT_FP64:0] Mant_a_D; - logic [C_MANT_FP64:0] Mant_b_D; - - logic [C_EXP_FP64+1:0] Exp_z_D; - logic [C_MANT_FP64+4:0] Mant_z_D; - logic Sign_z_D; - logic Start_S; - logic [C_RM-1:0] RM_dly_S; - logic Div_enable_S; - logic Sqrt_enable_S; - logic Inf_a_S; - logic Inf_b_S; - logic Zero_a_S; - logic Zero_b_S; - logic NaN_a_S; - logic NaN_b_S; - logic SNaN_S; - logic Special_case_SB,Special_case_dly_SB; - - logic Full_precision_S; - logic FP32_S; - logic FP64_S; - logic FP16_S; - logic FP16ALT_S; - - - preprocess_mvp preprocess_U0 - ( - .Clk_CI (Clk_CI ), - .Rst_RBI (Rst_RBI ), - .Div_start_SI (Div_start_SI ), - .Sqrt_start_SI (Sqrt_start_SI ), - .Ready_SI (Ready_SO ), - .Operand_a_DI (Operand_a_DI ), - .Operand_b_DI (Operand_b_DI ), - .RM_SI (RM_SI ), - .Format_sel_SI (Format_sel_SI ), - .Start_SO (Start_S ), - .Exp_a_DO_norm (Exp_a_D ), - .Exp_b_DO_norm (Exp_b_D ), - .Mant_a_DO_norm (Mant_a_D ), - .Mant_b_DO_norm (Mant_b_D ), - .RM_dly_SO (RM_dly_S ), - .Sign_z_DO (Sign_z_D ), - .Inf_a_SO (Inf_a_S ), - .Inf_b_SO (Inf_b_S ), - .Zero_a_SO (Zero_a_S ), - .Zero_b_SO (Zero_b_S ), - .NaN_a_SO (NaN_a_S ), - .NaN_b_SO (NaN_b_S ), - .SNaN_SO (SNaN_S ), - .Special_case_SBO (Special_case_SB ), - .Special_case_dly_SBO (Special_case_dly_SB) - ); - - nrbd_nrsc_mvp nrbd_nrsc_U0 - ( - .Clk_CI (Clk_CI ), - .Rst_RBI (Rst_RBI ), - .Div_start_SI (Div_start_SI ) , - .Sqrt_start_SI (Sqrt_start_SI ), - .Start_SI (Start_S ), - .Kill_SI (Kill_SI ), - .Special_case_SBI (Special_case_SB ), - .Special_case_dly_SBI (Special_case_dly_SB), - .Div_enable_SO (Div_enable_S ), - .Sqrt_enable_SO (Sqrt_enable_S ), - .Precision_ctl_SI (Precision_ctl_SI ), - .Format_sel_SI (Format_sel_SI ), - .Exp_a_DI (Exp_a_D ), - .Exp_b_DI (Exp_b_D ), - .Mant_a_DI (Mant_a_D ), - .Mant_b_DI (Mant_b_D ), - .Full_precision_SO (Full_precision_S ), - .FP32_SO (FP32_S ), - .FP64_SO (FP64_S ), - .FP16_SO (FP16_S ), - .FP16ALT_SO (FP16ALT_S ), - .Ready_SO (Ready_SO ), - .Done_SO (Done_SO ), - .Exp_z_DO (Exp_z_D ), - .Mant_z_DO (Mant_z_D ) - ); - - - norm_div_sqrt_mvp fpu_norm_U0 - ( - .Mant_in_DI (Mant_z_D ), - .Exp_in_DI (Exp_z_D ), - .Sign_in_DI (Sign_z_D ), - .Div_enable_SI (Div_enable_S ), - .Sqrt_enable_SI (Sqrt_enable_S ), - .Inf_a_SI (Inf_a_S ), - .Inf_b_SI (Inf_b_S ), - .Zero_a_SI (Zero_a_S ), - .Zero_b_SI (Zero_b_S ), - .NaN_a_SI (NaN_a_S ), - .NaN_b_SI (NaN_b_S ), - .SNaN_SI (SNaN_S ), - .RM_SI (RM_dly_S ), - .Full_precision_SI (Full_precision_S ), - .FP32_SI (FP32_S ), - .FP64_SI (FP64_S ), - .FP16_SI (FP16_S ), - .FP16ALT_SI (FP16ALT_S ), - .Result_DO (Result_DO ), - .Fflags_SO (Fflags_SO ) //{NV,DZ,OF,UF,NX} - ); - -endmodule diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv deleted file mode 100644 index 0c645e6eb..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv +++ /dev/null @@ -1,61 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 12/01/2017 // -// Design Name: FPU // -// Module Name: iteration_div_sqrt_mvp // -// Project Name: Private FPU // -// Language: SystemVerilog // -// // -// Description: iteration unit for div and sqrt // -// // -// // -// Revision: 03/14/2018 // -// For div_sqrt_mvp // -//////////////////////////////////////////////////////////////////////////////// - -module iteration_div_sqrt_mvp -#( - parameter WIDTH=25 -) - (//Input - - input logic [WIDTH-1:0] A_DI, - input logic [WIDTH-1:0] B_DI, - input logic Div_enable_SI, - input logic Div_start_dly_SI, - input logic Sqrt_enable_SI, - input logic [1:0] D_DI, - - output logic [1:0] D_DO, - output logic [WIDTH-1:0] Sum_DO, - output logic Carry_out_DO - ); - - logic D_carry_D; - logic Sqrt_cin_D; - logic Cin_D; - - assign D_DO[0]=~D_DI[0]; - assign D_DO[1]=~(D_DI[1] ^ D_DI[0]); - assign D_carry_D=D_DI[1] | D_DI[0]; - assign Sqrt_cin_D=Sqrt_enable_SI&&D_carry_D; - assign Cin_D=Div_enable_SI?1'b0:Sqrt_cin_D; - assign {Carry_out_DO,Sum_DO}=A_DI+B_DI+Cin_D; - -endmodule diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv deleted file mode 100644 index 590abe969..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv +++ /dev/null @@ -1,470 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 09/03/2018 // -// Design Name: FPU // -// Module Name: norm_div_sqrt_mvp.sv // -// Project Name: // -// Language: SystemVerilog // -// // -// Description: Floating point Normalizer/Rounding unit // -// Since this module is design as a combinatinal logic, it can// -// be added arbinary register stages for different frequency // -// in the wrapper module. // -// // -// // -// // -// Revision Date: 12/04/2018 // -// Lei Li // -// To address some requirements by Stefan // -// // -// // -// // -// // -// // -// // -//////////////////////////////////////////////////////////////////////////////// - -import defs_div_sqrt_mvp::*; - -module norm_div_sqrt_mvp - (//Inputs - input logic [C_MANT_FP64+4:0] Mant_in_DI, // Include the needed 4-bit for rounding and hidden bit - input logic signed [C_EXP_FP64+1:0] Exp_in_DI, - input logic Sign_in_DI, - input logic Div_enable_SI, - input logic Sqrt_enable_SI, - input logic Inf_a_SI, - input logic Inf_b_SI, - input logic Zero_a_SI, - input logic Zero_b_SI, - input logic NaN_a_SI, - input logic NaN_b_SI, - input logic SNaN_SI, - input logic [C_RM-1:0] RM_SI, - input logic Full_precision_SI, - input logic FP32_SI, - input logic FP64_SI, - input logic FP16_SI, - input logic FP16ALT_SI, - //Outputs - output logic [C_EXP_FP64+C_MANT_FP64:0] Result_DO, - output logic [4:0] Fflags_SO //{NV,DZ,OF,UF,NX} - ); - - - logic Sign_res_D; - - logic NV_OP_S; - logic Exp_OF_S; - logic Exp_UF_S; - logic Div_Zero_S; - logic In_Exact_S; - - ///////////////////////////////////////////////////////////////////////////// - // Normalization // - ///////////////////////////////////////////////////////////////////////////// - logic [C_MANT_FP64:0] Mant_res_norm_D; - logic [C_EXP_FP64-1:0] Exp_res_norm_D; - - ///////////////////////////////////////////////////////////////////////////// - // Right shift operations for negtive exponents // - ///////////////////////////////////////////////////////////////////////////// - - logic [C_EXP_FP64+1:0] Exp_Max_RS_FP64_D; - logic [C_EXP_FP32+1:0] Exp_Max_RS_FP32_D; - logic [C_EXP_FP16+1:0] Exp_Max_RS_FP16_D; - logic [C_EXP_FP16ALT+1:0] Exp_Max_RS_FP16ALT_D; - // - assign Exp_Max_RS_FP64_D=Exp_in_DI[C_EXP_FP64:0]+C_MANT_FP64+1; // to check exponent after (C_MANT_FP64+1)-bit >> when Exp_in_DI is negative - assign Exp_Max_RS_FP32_D=Exp_in_DI[C_EXP_FP32:0]+C_MANT_FP32+1; // to check exponent after (C_MANT_FP32+1)-bit >> when Exp_in_DI is negative - assign Exp_Max_RS_FP16_D=Exp_in_DI[C_EXP_FP16:0]+C_MANT_FP16+1; // to check exponent after (C_MANT_FP16+1)-bit >> when Exp_in_DI is negative - assign Exp_Max_RS_FP16ALT_D=Exp_in_DI[C_EXP_FP16ALT:0]+C_MANT_FP16ALT+1; // to check exponent after (C_MANT_FP16ALT+1)-bit >> when Exp_in_DI is negative - logic [C_EXP_FP64+1:0] Num_RS_D; - assign Num_RS_D=~Exp_in_DI+1+1; // How many right shifts(RS) are needed to generate a denormal number? >> is need only when Exp_in_DI is negative - logic [C_MANT_FP64:0] Mant_RS_D; - logic [C_MANT_FP64+4:0] Mant_forsticky_D; - assign {Mant_RS_D,Mant_forsticky_D} ={Mant_in_DI,{(C_MANT_FP64+1){1'b0}} } >>(Num_RS_D); // -// - logic [C_EXP_FP64+1:0] Exp_subOne_D; - assign Exp_subOne_D = Exp_in_DI -1; - - //normalization - logic [1:0] Mant_lower_D; - logic Mant_sticky_bit_D; - logic [C_MANT_FP64+4:0] Mant_forround_D; - - always_comb - begin - - if(NaN_a_SI) // if a is NaN, return NaN - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D={1'b0,C_MANT_NAN_FP64}; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=1'b0; - NV_OP_S = SNaN_SI; - end - - else if(NaN_b_SI) //if b is NaN, return NaN - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D={1'b0,C_MANT_NAN_FP64}; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=1'b0; - NV_OP_S = SNaN_SI; - end - - else if(Inf_a_SI) - begin - if(Div_enable_SI&&Inf_b_SI) //Inf/Inf, retrurn NaN - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D={1'b0,C_MANT_NAN_FP64}; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=1'b0; - NV_OP_S = 1'b1; - end - else if (Sqrt_enable_SI && Sign_in_DI) begin // catch sqrt(-inf) - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D={1'b0,C_MANT_NAN_FP64}; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=1'b0; - NV_OP_S = 1'b1; - end else begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b1; - Exp_UF_S=1'b0; - Mant_res_norm_D= '0; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - end - - else if(Div_enable_SI&&Inf_b_SI) - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b1; - Exp_UF_S=1'b0; - Mant_res_norm_D= '0; - Exp_res_norm_D='0; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - else if(Zero_a_SI) - begin - if(Div_enable_SI&&Zero_b_SI) - begin - Div_Zero_S=1'b1; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D={1'b0,C_MANT_NAN_FP64}; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=1'b0; - NV_OP_S = 1'b1; - end - else - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D='0; - Exp_res_norm_D='0; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - end - - else if(Div_enable_SI&&(Zero_b_SI)) //div Zero - begin - Div_Zero_S=1'b1; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D='0; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - else if(Sign_in_DI&&Sqrt_enable_SI) //sqrt(-a) - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D={1'b0,C_MANT_NAN_FP64}; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=1'b0; - NV_OP_S = 1'b1; - end - - else if((Exp_in_DI[C_EXP_FP64:0]=='0)) - begin - if(Mant_in_DI!='0) //Exp=0, Mant!=0, it is denormal - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b1; - Mant_res_norm_D={1'b0,Mant_in_DI[C_MANT_FP64+4:5]}; - Exp_res_norm_D='0; - Mant_forround_D={Mant_in_DI[4:0],{(C_MANT_FP64){1'b0}} }; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - else // Zero - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D='0; - Exp_res_norm_D='0; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - end - - else if((Exp_in_DI[C_EXP_FP64:0]==C_EXP_ONE_FP64)&&(~Mant_in_DI[C_MANT_FP64+4])) //denormal - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b1; - Mant_res_norm_D=Mant_in_DI[C_MANT_FP64+4:4]; - Exp_res_norm_D='0; - Mant_forround_D={Mant_in_DI[3:0],{(C_MANT_FP64+1){1'b0}}}; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - else if(Exp_in_DI[C_EXP_FP64+1]) //minus //consider format - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b1; - Mant_res_norm_D={Mant_RS_D[C_MANT_FP64:0]}; - Exp_res_norm_D='0; - Mant_forround_D={Mant_forsticky_D[C_MANT_FP64+4:0]}; //?? - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - else if( (Exp_in_DI[C_EXP_FP32]&&FP32_SI) | (Exp_in_DI[C_EXP_FP64]&&FP64_SI) | (Exp_in_DI[C_EXP_FP16]&&FP16_SI) | (Exp_in_DI[C_EXP_FP16ALT]&&FP16ALT_SI) ) //OF - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b1; - Exp_UF_S=1'b0; - Mant_res_norm_D='0; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - else if( ((Exp_in_DI[C_EXP_FP32-1:0]=='1)&&FP32_SI) | ((Exp_in_DI[C_EXP_FP64-1:0]=='1)&&FP64_SI) | ((Exp_in_DI[C_EXP_FP16-1:0]=='1)&&FP16_SI) | ((Exp_in_DI[C_EXP_FP16ALT-1:0]=='1)&&FP16ALT_SI) )//255 - begin - if(~Mant_in_DI[C_MANT_FP64+4]) // MSB=0 - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D=Mant_in_DI[C_MANT_FP64+3:3]; - Exp_res_norm_D=Exp_subOne_D; - Mant_forround_D={Mant_in_DI[2:0],{(C_MANT_FP64+2){1'b0}}}; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - else if(Mant_in_DI!='0) //NaN - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b1; - Exp_UF_S=1'b0; - Mant_res_norm_D= '0; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - else //infinity - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b1; - Exp_UF_S=1'b0; - Mant_res_norm_D= '0; - Exp_res_norm_D='1; - Mant_forround_D='0; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - end - - else if(Mant_in_DI[C_MANT_FP64+4]) //normal numbers with 1.XXX - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D= Mant_in_DI[C_MANT_FP64+4:4]; - Exp_res_norm_D=Exp_in_DI[C_EXP_FP64-1:0]; - Mant_forround_D={Mant_in_DI[3:0],{(C_MANT_FP64+1){1'b0}}}; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - else //normal numbers with 0.1XX - begin - Div_Zero_S=1'b0; - Exp_OF_S=1'b0; - Exp_UF_S=1'b0; - Mant_res_norm_D=Mant_in_DI[C_MANT_FP64+3:3]; - Exp_res_norm_D=Exp_subOne_D; - Mant_forround_D={Mant_in_DI[2:0],{(C_MANT_FP64+2){1'b0}}}; - Sign_res_D=Sign_in_DI; - NV_OP_S = 1'b0; - end - - end - - ///////////////////////////////////////////////////////////////////////////// - // Rounding enable only for full precision (Full_precision_SI==1'b1) // - ///////////////////////////////////////////////////////////////////////////// - - logic [C_MANT_FP64:0] Mant_upper_D; - logic [C_MANT_FP64+1:0] Mant_upperRounded_D; - logic Mant_roundUp_S; - logic Mant_rounded_S; - - always_comb //determine which bits for Mant_lower_D and Mant_sticky_bit_D - begin - if(FP32_SI) - begin - Mant_upper_D = {Mant_res_norm_D[C_MANT_FP64:C_MANT_FP64-C_MANT_FP32], {(C_MANT_FP64-C_MANT_FP32){1'b0}} }; - Mant_lower_D = Mant_res_norm_D[C_MANT_FP64-C_MANT_FP32-1:C_MANT_FP64-C_MANT_FP32-2]; - Mant_sticky_bit_D = | Mant_res_norm_D[C_MANT_FP64-C_MANT_FP32-3:0]; - end - else if(FP64_SI) - begin - Mant_upper_D = Mant_res_norm_D[C_MANT_FP64:0]; - Mant_lower_D = Mant_forround_D[C_MANT_FP64+4:C_MANT_FP64+3]; - Mant_sticky_bit_D = | Mant_forround_D[C_MANT_FP64+3:0]; - end - else if(FP16_SI) - begin - Mant_upper_D = {Mant_res_norm_D[C_MANT_FP64:C_MANT_FP64-C_MANT_FP16], {(C_MANT_FP64-C_MANT_FP16){1'b0}} }; - Mant_lower_D = Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16-1:C_MANT_FP64-C_MANT_FP16-2]; - Mant_sticky_bit_D = | Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16-3:30]; - end - else //FP16ALT - begin - Mant_upper_D = {Mant_res_norm_D[C_MANT_FP64:C_MANT_FP64-C_MANT_FP16ALT], {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; - Mant_lower_D = Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16ALT-1:C_MANT_FP64-C_MANT_FP16ALT-2]; - Mant_sticky_bit_D = | Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16ALT-3:30]; - end - end - - assign Mant_rounded_S = (|(Mant_lower_D))| Mant_sticky_bit_D; - - - - - always_comb //determine whether to round up or not - begin - Mant_roundUp_S = 1'b0; - case (RM_SI) - C_RM_NEAREST : - Mant_roundUp_S = Mant_lower_D[1] && ((Mant_lower_D[0] | Mant_sticky_bit_D )| ( (FP32_SI&&Mant_upper_D[C_MANT_FP64-C_MANT_FP32]) | (FP64_SI&&Mant_upper_D[0]) | (FP16_SI&&Mant_upper_D[C_MANT_FP64-C_MANT_FP16]) | (FP16ALT_SI&&Mant_upper_D[C_MANT_FP64-C_MANT_FP16ALT]) ) ); - C_RM_TRUNC : - Mant_roundUp_S = 0; - C_RM_PLUSINF : - Mant_roundUp_S = Mant_rounded_S & ~Sign_in_DI; - C_RM_MINUSINF: - Mant_roundUp_S = Mant_rounded_S & Sign_in_DI; - default : - Mant_roundUp_S = 0; - endcase // case (RM_DI) - end // always_comb begin - - logic Mant_renorm_S; - logic [C_MANT_FP64:0] Mant_roundUp_Vector_S; // for all the formats - - assign Mant_roundUp_Vector_S={7'h0,(FP16ALT_SI&&Mant_roundUp_S),2'h0,(FP16_SI&&Mant_roundUp_S),12'h0,(FP32_SI&&Mant_roundUp_S),28'h0,(FP64_SI&&Mant_roundUp_S)}; - - - assign Mant_upperRounded_D = Mant_upper_D + Mant_roundUp_Vector_S; - assign Mant_renorm_S = Mant_upperRounded_D[C_MANT_FP64+1]; - - ///////////////////////////////////////////////////////////////////////////// - // Renormalization for Rounding // - ///////////////////////////////////////////////////////////////////////////// - logic [C_MANT_FP64-1:0] Mant_res_round_D; - logic [C_EXP_FP64-1:0] Exp_res_round_D; - - - assign Mant_res_round_D = (Mant_renorm_S)?Mant_upperRounded_D[C_MANT_FP64:1]:Mant_upperRounded_D[C_MANT_FP64-1:0]; // including the process of the hidden bit - assign Exp_res_round_D = Exp_res_norm_D+Mant_renorm_S; - - ///////////////////////////////////////////////////////////////////////////// - // Output Assignments // - ///////////////////////////////////////////////////////////////////////////// - logic [C_MANT_FP64-1:0] Mant_before_format_ctl_D; - logic [C_EXP_FP64-1:0] Exp_before_format_ctl_D; - assign Mant_before_format_ctl_D = Full_precision_SI ? Mant_res_round_D : Mant_res_norm_D; - assign Exp_before_format_ctl_D = Full_precision_SI ? Exp_res_round_D : Exp_res_norm_D; - - always_comb //NaN Boxing - begin // - if(FP32_SI) - begin - Result_DO ={32'hffff_ffff,Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP32-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:C_MANT_FP64-C_MANT_FP32]}; - end - else if(FP64_SI) - begin - Result_DO ={Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP64-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:0]}; - end - else if(FP16_SI) - begin - Result_DO ={48'hffff_ffff_ffff,Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP16-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:C_MANT_FP64-C_MANT_FP16]}; - end - else - begin - Result_DO ={48'hffff_ffff_ffff,Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP16ALT-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:C_MANT_FP64-C_MANT_FP16ALT]}; - end - end - -assign In_Exact_S = (~Full_precision_SI) | Mant_rounded_S; -assign Fflags_SO = {NV_OP_S,Div_Zero_S,Exp_OF_S,Exp_UF_S,In_Exact_S}; //{NV,DZ,OF,UF,NX} - -endmodule // norm_div_sqrt_mvp diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv deleted file mode 100644 index 62bd147f6..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv +++ /dev/null @@ -1,104 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 10/04/2018 // -// Design Name: FPU // -// Module Name: nrbd_nrsc_mvp.sv // -// Project Name: Private FPU // -// Language: SystemVerilog // -// // -// Description: non restroring binary divisior/ square root // -// // -// Revision Date: 12/04/2018 // -// Lei Li // -// To address some requirements by Stefan and add low power // -// control for special cases // -// // -//////////////////////////////////////////////////////////////////////////////// - -import defs_div_sqrt_mvp::*; - -module nrbd_nrsc_mvp - - (//Input - input logic Clk_CI, - input logic Rst_RBI, - input logic Div_start_SI, - input logic Sqrt_start_SI, - input logic Start_SI, - input logic Kill_SI, - input logic Special_case_SBI, - input logic Special_case_dly_SBI, - input logic [C_PC-1:0] Precision_ctl_SI, - input logic [1:0] Format_sel_SI, - input logic [C_MANT_FP64:0] Mant_a_DI, - input logic [C_MANT_FP64:0] Mant_b_DI, - input logic [C_EXP_FP64:0] Exp_a_DI, - input logic [C_EXP_FP64:0] Exp_b_DI, - //output - output logic Div_enable_SO, - output logic Sqrt_enable_SO, - - output logic Full_precision_SO, - output logic FP32_SO, - output logic FP64_SO, - output logic FP16_SO, - output logic FP16ALT_SO, - output logic Ready_SO, - output logic Done_SO, - output logic [C_MANT_FP64+4:0] Mant_z_DO, - output logic [C_EXP_FP64+1:0] Exp_z_DO - ); - - - logic Div_start_dly_S,Sqrt_start_dly_S; - - -control_mvp control_U0 -( .Clk_CI (Clk_CI ), - .Rst_RBI (Rst_RBI ), - .Div_start_SI (Div_start_SI ), - .Sqrt_start_SI (Sqrt_start_SI ), - .Start_SI (Start_SI ), - .Kill_SI (Kill_SI ), - .Special_case_SBI (Special_case_SBI ), - .Special_case_dly_SBI (Special_case_dly_SBI ), - .Precision_ctl_SI (Precision_ctl_SI ), - .Format_sel_SI (Format_sel_SI ), - .Numerator_DI (Mant_a_DI ), - .Exp_num_DI (Exp_a_DI ), - .Denominator_DI (Mant_b_DI ), - .Exp_den_DI (Exp_b_DI ), - .Div_start_dly_SO (Div_start_dly_S ), - .Sqrt_start_dly_SO (Sqrt_start_dly_S ), - .Div_enable_SO (Div_enable_SO ), - .Sqrt_enable_SO (Sqrt_enable_SO ), - .Full_precision_SO (Full_precision_SO ), - .FP32_SO (FP32_SO ), - .FP64_SO (FP64_SO ), - .FP16_SO (FP16_SO ), - .FP16ALT_SO (FP16ALT_SO ), - .Ready_SO (Ready_SO ), - .Done_SO (Done_SO ), - .Mant_result_prenorm_DO (Mant_z_DO ), - .Exp_result_prenorm_DO (Exp_z_DO ) -); - - - -endmodule diff --git a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv b/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv deleted file mode 100644 index 9e0d25f38..000000000 --- a/rtl/vendor/pulp_platform_fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv +++ /dev/null @@ -1,425 +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: IIS @ ETHZ - Federal Institute of Technology // -// // -// Engineers: Lei Li //lile@iis.ee.ethz.ch // -// // -// Additional contributions by: // -// // -// // -// // -// Create Date: 01/03/2018 // -// Design Name: FPU // -// Module Name: preprocess_mvp.sv // -// Project Name: Private FPU // -// Language: SystemVerilog // -// // -// Description: decode and data preparation // -// // -// Revision Date: 12/04/2018 // -// Lei Li // -// To address some requirements by Stefan and add low power // -// control for special cases // -// // -// // -//////////////////////////////////////////////////////////////////////////////// - -import defs_div_sqrt_mvp::*; - -module preprocess_mvp - ( - input logic Clk_CI, - input logic Rst_RBI, - input logic Div_start_SI, - input logic Sqrt_start_SI, - input logic Ready_SI, - //Input Operands - input logic [C_OP_FP64-1:0] Operand_a_DI, - input logic [C_OP_FP64-1:0] Operand_b_DI, - input logic [C_RM-1:0] RM_SI, //Rounding Mode - input logic [C_FS-1:0] Format_sel_SI, // Format Selection - - // to control - output logic Start_SO, - output logic [C_EXP_FP64:0] Exp_a_DO_norm, - output logic [C_EXP_FP64:0] Exp_b_DO_norm, - output logic [C_MANT_FP64:0] Mant_a_DO_norm, - output logic [C_MANT_FP64:0] Mant_b_DO_norm, - - output logic [C_RM-1:0] RM_dly_SO, - - output logic Sign_z_DO, - output logic Inf_a_SO, - output logic Inf_b_SO, - output logic Zero_a_SO, - output logic Zero_b_SO, - output logic NaN_a_SO, - output logic NaN_b_SO, - output logic SNaN_SO, - output logic Special_case_SBO, - output logic Special_case_dly_SBO - ); - - //Hidden Bits - logic Hb_a_D; - logic Hb_b_D; - - logic [C_EXP_FP64-1:0] Exp_a_D; - logic [C_EXP_FP64-1:0] Exp_b_D; - logic [C_MANT_FP64-1:0] Mant_a_NonH_D; - logic [C_MANT_FP64-1:0] Mant_b_NonH_D; - logic [C_MANT_FP64:0] Mant_a_D; - logic [C_MANT_FP64:0] Mant_b_D; - - ///////////////////////////////////////////////////////////////////////////// - // Disassemble operands - ///////////////////////////////////////////////////////////////////////////// - logic Sign_a_D,Sign_b_D; - logic Start_S; - - always_comb - begin - case(Format_sel_SI) - 2'b00: - begin - Sign_a_D = Operand_a_DI[C_OP_FP32-1]; - Sign_b_D = Operand_b_DI[C_OP_FP32-1]; - Exp_a_D = {3'h0, Operand_a_DI[C_OP_FP32-2:C_MANT_FP32]}; - Exp_b_D = {3'h0, Operand_b_DI[C_OP_FP32-2:C_MANT_FP32]}; - Mant_a_NonH_D = {Operand_a_DI[C_MANT_FP32-1:0],29'h0}; - Mant_b_NonH_D = {Operand_b_DI[C_MANT_FP32-1:0],29'h0}; - end - 2'b01: - begin - Sign_a_D = Operand_a_DI[C_OP_FP64-1]; - Sign_b_D = Operand_b_DI[C_OP_FP64-1]; - Exp_a_D = Operand_a_DI[C_OP_FP64-2:C_MANT_FP64]; - Exp_b_D = Operand_b_DI[C_OP_FP64-2:C_MANT_FP64]; - Mant_a_NonH_D = Operand_a_DI[C_MANT_FP64-1:0]; - Mant_b_NonH_D = Operand_b_DI[C_MANT_FP64-1:0]; - end - 2'b10: - begin - Sign_a_D = Operand_a_DI[C_OP_FP16-1]; - Sign_b_D = Operand_b_DI[C_OP_FP16-1]; - Exp_a_D = {6'h00, Operand_a_DI[C_OP_FP16-2:C_MANT_FP16]}; - Exp_b_D = {6'h00, Operand_b_DI[C_OP_FP16-2:C_MANT_FP16]}; - Mant_a_NonH_D = {Operand_a_DI[C_MANT_FP16-1:0],42'h0}; - Mant_b_NonH_D = {Operand_b_DI[C_MANT_FP16-1:0],42'h0}; - end - 2'b11: - begin - Sign_a_D = Operand_a_DI[C_OP_FP16ALT-1]; - Sign_b_D = Operand_b_DI[C_OP_FP16ALT-1]; - Exp_a_D = {3'h0, Operand_a_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT]}; - Exp_b_D = {3'h0, Operand_b_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT]}; - Mant_a_NonH_D = {Operand_a_DI[C_MANT_FP16ALT-1:0],45'h0}; - Mant_b_NonH_D = {Operand_b_DI[C_MANT_FP16ALT-1:0],45'h0}; - end - endcase - end - - - assign Mant_a_D = {Hb_a_D,Mant_a_NonH_D}; - assign Mant_b_D = {Hb_b_D,Mant_b_NonH_D}; - - assign Hb_a_D = | Exp_a_D; // hidden bit - assign Hb_b_D = | Exp_b_D; // hidden bit - - assign Start_S= Div_start_SI | Sqrt_start_SI; - - - - ///////////////////////////////////////////////////////////////////////////// - // preliminary checks for infinite/zero/NaN operands // - ///////////////////////////////////////////////////////////////////////////// - - logic Mant_a_prenorm_zero_S; - logic Mant_b_prenorm_zero_S; - - logic Exp_a_prenorm_zero_S; - logic Exp_b_prenorm_zero_S; - assign Exp_a_prenorm_zero_S = ~Hb_a_D; - assign Exp_b_prenorm_zero_S = ~Hb_b_D; - - logic Exp_a_prenorm_Inf_NaN_S; - logic Exp_b_prenorm_Inf_NaN_S; - - logic Mant_a_prenorm_QNaN_S; - logic Mant_a_prenorm_SNaN_S; - logic Mant_b_prenorm_QNaN_S; - logic Mant_b_prenorm_SNaN_S; - - assign Mant_a_prenorm_QNaN_S=Mant_a_NonH_D[C_MANT_FP64-1]&&(~(|Mant_a_NonH_D[C_MANT_FP64-2:0])); - assign Mant_a_prenorm_SNaN_S=(~Mant_a_NonH_D[C_MANT_FP64-1])&&((|Mant_a_NonH_D[C_MANT_FP64-2:0])); - assign Mant_b_prenorm_QNaN_S=Mant_b_NonH_D[C_MANT_FP64-1]&&(~(|Mant_b_NonH_D[C_MANT_FP64-2:0])); - assign Mant_b_prenorm_SNaN_S=(~Mant_b_NonH_D[C_MANT_FP64-1])&&((|Mant_b_NonH_D[C_MANT_FP64-2:0])); - - always_comb - begin - case(Format_sel_SI) - 2'b00: - begin - Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP32-1:0] == C_MANT_ZERO_FP32); - Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP32-1:0] == C_MANT_ZERO_FP32); - Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP32-2:C_MANT_FP32] == C_EXP_INF_FP32); - Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP32-2:C_MANT_FP32] == C_EXP_INF_FP32); - end - 2'b01: - begin - Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP64-1:0] == C_MANT_ZERO_FP64); - Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP64-1:0] == C_MANT_ZERO_FP64); - Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP64-2:C_MANT_FP64] == C_EXP_INF_FP64); - Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP64-2:C_MANT_FP64] == C_EXP_INF_FP64); - end - 2'b10: - begin - Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP16-1:0] == C_MANT_ZERO_FP16); - Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP16-1:0] == C_MANT_ZERO_FP16); - Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP16-2:C_MANT_FP16] == C_EXP_INF_FP16); - Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP16-2:C_MANT_FP16] == C_EXP_INF_FP16); - end - 2'b11: - begin - Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP16ALT-1:0] == C_MANT_ZERO_FP16ALT); - Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP16ALT-1:0] == C_MANT_ZERO_FP16ALT); - Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT] == C_EXP_INF_FP16ALT); - Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT] == C_EXP_INF_FP16ALT); - end - endcase - end - - - - - logic Zero_a_SN,Zero_a_SP; - logic Zero_b_SN,Zero_b_SP; - logic Inf_a_SN,Inf_a_SP; - logic Inf_b_SN,Inf_b_SP; - logic NaN_a_SN,NaN_a_SP; - logic NaN_b_SN,NaN_b_SP; - logic SNaN_SN,SNaN_SP; - - assign Zero_a_SN = (Start_S&&Ready_SI)?(Exp_a_prenorm_zero_S&&Mant_a_prenorm_zero_S):Zero_a_SP; - assign Zero_b_SN = (Start_S&&Ready_SI)?(Exp_b_prenorm_zero_S&&Mant_b_prenorm_zero_S):Zero_b_SP; - assign Inf_a_SN = (Start_S&&Ready_SI)?(Exp_a_prenorm_Inf_NaN_S&&Mant_a_prenorm_zero_S):Inf_a_SP; - assign Inf_b_SN = (Start_S&&Ready_SI)?(Exp_b_prenorm_Inf_NaN_S&&Mant_b_prenorm_zero_S):Inf_b_SP; - assign NaN_a_SN = (Start_S&&Ready_SI)?(Exp_a_prenorm_Inf_NaN_S&&(~Mant_a_prenorm_zero_S)):NaN_a_SP; - assign NaN_b_SN = (Start_S&&Ready_SI)?(Exp_b_prenorm_Inf_NaN_S&&(~Mant_b_prenorm_zero_S)):NaN_b_SP; - assign SNaN_SN = (Start_S&&Ready_SI) ? ((Mant_a_prenorm_SNaN_S&&NaN_a_SN) | (Mant_b_prenorm_SNaN_S&&NaN_b_SN)) : SNaN_SP; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Zero_a_SP <='0; - Zero_b_SP <='0; - Inf_a_SP <='0; - Inf_b_SP <='0; - NaN_a_SP <='0; - NaN_b_SP <='0; - SNaN_SP <= '0; - end - else - begin - Inf_a_SP <=Inf_a_SN; - Inf_b_SP <=Inf_b_SN; - Zero_a_SP <=Zero_a_SN; - Zero_b_SP <=Zero_b_SN; - NaN_a_SP <=NaN_a_SN; - NaN_b_SP <=NaN_b_SN; - SNaN_SP <= SNaN_SN; - end - end - - ///////////////////////////////////////////////////////////////////////////// - // Low power control - ///////////////////////////////////////////////////////////////////////////// - - assign Special_case_SBO=(~{(Div_start_SI)?(Zero_a_SN | Zero_b_SN | Inf_a_SN | Inf_b_SN | NaN_a_SN | NaN_b_SN): (Zero_a_SN | Inf_a_SN | NaN_a_SN | Sign_a_D) })&&(Start_S&&Ready_SI); - - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Special_case_dly_SBO <= '0; - end - else if((Start_S&&Ready_SI)) - begin - Special_case_dly_SBO <= Special_case_SBO; - end - else if(Special_case_dly_SBO) - begin - Special_case_dly_SBO <= 1'b1; - end - else - begin - Special_case_dly_SBO <= '0; - end - end - - ///////////////////////////////////////////////////////////////////////////// - // Delay sign for normalization and round // - ///////////////////////////////////////////////////////////////////////////// - - logic Sign_z_DN; - logic Sign_z_DP; - - always_comb - begin - if(Div_start_SI&&Ready_SI) - Sign_z_DN = Sign_a_D ^ Sign_b_D; - else if(Sqrt_start_SI&&Ready_SI) - Sign_z_DN = Sign_a_D; - else - Sign_z_DN = Sign_z_DP; - end - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Sign_z_DP <= '0; - end - else - begin - Sign_z_DP <= Sign_z_DN; - end - end - - logic [C_RM-1:0] RM_DN; - logic [C_RM-1:0] RM_DP; - - always_comb - begin - if(Start_S&&Ready_SI) - RM_DN = RM_SI; - else - RM_DN = RM_DP; - end - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - RM_DP <= '0; - end - else - begin - RM_DP <= RM_DN; - end - end - assign RM_dly_SO = RM_DP; - - logic [5:0] Mant_leadingOne_a, Mant_leadingOne_b; - logic Mant_zero_S_a,Mant_zero_S_b; - - lzc #( - .WIDTH ( C_MANT_FP64+1 ), - .MODE ( 1 ) - ) LOD_Ua ( - .in_i ( Mant_a_D ), - .cnt_o ( Mant_leadingOne_a ), - .empty_o ( Mant_zero_S_a ) - ); - - logic [C_MANT_FP64:0] Mant_a_norm_DN,Mant_a_norm_DP; - - assign Mant_a_norm_DN = ((Start_S&&Ready_SI))?(Mant_a_D<<(Mant_leadingOne_a)):Mant_a_norm_DP; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Mant_a_norm_DP <= '0; - end - else - begin - Mant_a_norm_DP<=Mant_a_norm_DN; - end - end - - logic [C_EXP_FP64:0] Exp_a_norm_DN,Exp_a_norm_DP; - assign Exp_a_norm_DN = ((Start_S&&Ready_SI))?(Exp_a_D-Mant_leadingOne_a+(|Mant_leadingOne_a)):Exp_a_norm_DP; //Covering the process of denormal numbers - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Exp_a_norm_DP <= '0; - end - else - begin - Exp_a_norm_DP<=Exp_a_norm_DN; - end - end - - lzc #( - .WIDTH ( C_MANT_FP64+1 ), - .MODE ( 1 ) - ) LOD_Ub ( - .in_i ( Mant_b_D ), - .cnt_o ( Mant_leadingOne_b ), - .empty_o ( Mant_zero_S_b ) - ); - - - logic [C_MANT_FP64:0] Mant_b_norm_DN,Mant_b_norm_DP; - - assign Mant_b_norm_DN = ((Start_S&&Ready_SI))?(Mant_b_D<<(Mant_leadingOne_b)):Mant_b_norm_DP; - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Mant_b_norm_DP <= '0; - end - else - begin - Mant_b_norm_DP<=Mant_b_norm_DN; - end - end - - logic [C_EXP_FP64:0] Exp_b_norm_DN,Exp_b_norm_DP; - assign Exp_b_norm_DN = ((Start_S&&Ready_SI))?(Exp_b_D-Mant_leadingOne_b+(|Mant_leadingOne_b)):Exp_b_norm_DP; //Covering the process of denormal numbers - - always_ff @(posedge Clk_CI, negedge Rst_RBI) - begin - if(~Rst_RBI) - begin - Exp_b_norm_DP <= '0; - end - else - begin - Exp_b_norm_DP<=Exp_b_norm_DN; - end - end - - ///////////////////////////////////////////////////////////////////////////// - // Output assignments // - ///////////////////////////////////////////////////////////////////////////// - - assign Start_SO=Start_S; - assign Exp_a_DO_norm=Exp_a_norm_DP; - assign Exp_b_DO_norm=Exp_b_norm_DP; - assign Mant_a_DO_norm=Mant_a_norm_DP; - assign Mant_b_DO_norm=Mant_b_norm_DP; - assign Sign_z_DO=Sign_z_DP; - assign Inf_a_SO=Inf_a_SP; - assign Inf_b_SO=Inf_b_SP; - assign Zero_a_SO=Zero_a_SP; - assign Zero_b_SO=Zero_b_SP; - assign NaN_a_SO=NaN_a_SP; - assign NaN_b_SO=NaN_b_SP; - assign SNaN_SO=SNaN_SP; - -endmodule From 90317bd804b79827ee545c40b259fe0d4dae8e6b Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 12 Mar 2024 14:15:01 +0100 Subject: [PATCH 13/69] Issue #948 correction. Signed-off-by: Pascal Gouedo --- docs/source/integration.rst | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/source/integration.rst b/docs/source/integration.rst index d2fa3eac8..f355d2b1d 100644 --- a/docs/source/integration.rst +++ b/docs/source/integration.rst @@ -259,21 +259,27 @@ be provided. FPGA Synthesis ^^^^^^^^^^^^^^^ -FPGA synthesis is only supported for CV32E40P. -The user needs to provide a technology specific implementation of a clock gating cell as described -in :ref:`clock-gating-cell`. +FPGA synthesis is supported for CV32E40P and it has been successfully implemented using both AMD® Vivado® and Intel® Quartus® Prime Pro Edition tools. + +Due to some advanced System Verilog features used by CV32E40P RTL design, Intel® Quartus® Prime Standard Edition isn't able to parse some CV32E40P System Verilog files. + +The user needs to provide a technology specific implementation of a clock gating cell as described in :ref:`clock-gating-cell`. .. _synthesis_with_fpu: Synthesizing with the FPU ^^^^^^^^^^^^^^^^^^^^^^^^^ -By default the pipeline of the FPU is purely combinatorial (FPU_*_LAT = 0). In this case FPU instructions latency is the same than simple ALU operations (except FP multicycle DIV/SQRT ones). +By default the pipeline of the FPU is purely combinatorial (FPU_*_LAT = 0). In this case FPU instructions latency is the same than simple ALU operations (except multicycle FDIV/FSQRT ones). But as FPU operations are much more complex than ALU ones, maximum achievable frequency is much lower than ALU one when FPU is enabled. + If this can be fine for low frequency systems, it is possible to indicate how many pipeline registers are instantiated in the FPU to reach higher target frequency. -This is done with FPU_*_LAT CV32E40P parameters setting to perfectly fit target frequency. +This is done by adjusting FPU_*_LAT CV32E40P parameters setting to perfectly fit target frequency. + It should be noted that any additional pipeline register is impacting FPU instructions latency and could cause performances degradation depending of applications using Floating-Point operations. + Those pipeline registers are all added at the end of the FPU pipeline with all operators before them. Optimal frequency is only achievable using automatic retiming commands in implementation tools. -This can be achieved with the following command for Synopsys Design Compiler: +As an exemple, this can be done for Synopsys® Design Compiler with the following command: + “set_optimize_registers true -designs [get_object_name [get_designs "\*cv32e40p_fp_wrapper\*"]]”. From 98c63f94a65f06aa9f0256802a8c5bbf25e5bba4 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 12 Mar 2024 14:16:48 +0100 Subject: [PATCH 14/69] Refined 1 blurry Hardware Loop constraint description. Signed-off-by: Pascal Gouedo --- docs/source/corev_hw_loop.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index e51b0fe8f..2156ec410 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -63,9 +63,12 @@ The HWLoop constraints are: - HWLoop body must contain at least 3 instructions. -- When both loops are nested, the End address of the outermost HWLoop (must be #1) must be at least 2 - instructions further than the End address of the innermost HWLoop (must be #0), - i.e. HWLoop[1].endaddress >= HWLoop[0].endaddress + 8. +- When both loops are nested, at least 1 instruction should be present between last innermost HWLoop (must be #0) instruction and + last outermost HWLoop (must be #1) instruction. In other words the End address of the outermost HWLoop must be at least 8 + bytes further than the End address of the innermost HWLoop (HWLoop[1].endaddress >= HWLoop[0].endaddress + 8). + + In the example below the first "addi %[j], %[j], 2;" instruction is the one added due to this constraint. + The code could have been simpler by using only one "addi %[j], %[j], 4;" instruction but to respect this constraint it has been split in two instructions. - HWLoop must always be entered from its start location (no branch/jump to a location inside a HWLoop body). From c1744a9cc1851974e49e1f6970ac38c2eaea4973 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 12 Mar 2024 14:32:41 +0100 Subject: [PATCH 15/69] Added a comment on clipr/clipur instructions. Signed-off-by: Pascal Gouedo --- docs/source/instruction_set_extensions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index de3dc3ea8..625f48247 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -789,7 +789,7 @@ General ALU operations | | | | | else rD = rs1 | | | | - | | Note: rs2 is unsigned. | + | | Note: rs2 is unsigned and must be in the range (0x0-0x7FFFFFFF). | +-------------------------------------------+------------------------------------------------------------------------+ | **cv.clipur rD, rs1, rs2** | if rs1 <= 0, rD = 0, | | | | @@ -797,7 +797,7 @@ General ALU operations | | | | | else rD = rs1 | | | | - | | Note: rs2 is unsigned. | + | | Note: rs2 is unsigned and must be in the range (0x0-0x7FFFFFFF). | +-------------------------------------------+------------------------------------------------------------------------+ | **cv.addN rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >>> Is3 | | | | From 3a3b4c41dca7d1ef1af58d69b4e4561ecf505201 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 12 Mar 2024 14:44:00 +0100 Subject: [PATCH 16/69] Added command examples for conditional text. Signed-off-by: Pascal Gouedo --- docs/source/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index bb18fa6a2..53badd35b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -98,6 +98,9 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = None +# Tags for conditional text +#tags.add('USER') +#tags.add('PMP') # -- Options for HTML output ------------------------------------------------- From 765029c2c8ff9a7b72359c4b9d5783c90b5b4f80 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 8 Feb 2024 16:13:19 +0800 Subject: [PATCH 17/69] RVFI - Adding missing perf counters csr --- bhv/cv32e40p_rvfi.sv | 190 +++++++++++++++++++++++++++++++++---- bhv/cv32e40p_tb_wrapper.sv | 5 +- bhv/insn_trace.sv | 37 +++++++- 3 files changed, 210 insertions(+), 22 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 13a5beb00..55a63b8e5 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -27,7 +27,8 @@ module cv32e40p_rvfi import cv32e40p_rvfi_pkg::*; #( parameter FPU = 0, - parameter ZFINX = 0 + parameter ZFINX = 0, + parameter NUM_MHPMCOUNTERS = 1 ) ( input logic clk_i, input logic rst_ni, @@ -290,7 +291,7 @@ module cv32e40p_rvfi // performance counters // cycle, instret, hpcounter, cycleh, instreth, hpcounterh // mcycle, minstret, mhpcounter, mcycleh, minstreth, mhpcounterh - input logic [31:0][MHPMCOUNTER_WIDTH-1:0] csr_mhpmcounter_q_i, + input logic [63:0][MHPMCOUNTER_WIDTH-1:0] csr_mhpmcounter_q_i, input logic [31:0] csr_mhpmcounter_write_lower_i, input logic [31:0] csr_mhpmcounter_write_upper_i, @@ -626,6 +627,7 @@ module cv32e40p_rvfi logic pc_mux_nmi; localparam logic [31:0] MSTATUS_WRITE_MASK = 32'h0000_6088; + localparam logic [31:0] MCOUNTINHIBIT_WRITE_MASK = {{(29-NUM_MHPMCOUNTERS){1'b0}}, {(NUM_MHPMCOUNTERS){1'b1}}, 3'b101}; `include "pipe_freeze_trace.sv" @@ -905,15 +907,45 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `SET_RVFI_CSR_FROM_INSN(misa) `SET_RVFI_CSR_FROM_INSN(mie) `SET_RVFI_CSR_FROM_INSN(mtvec) - `SET_RVFI_CSR_FROM_INSN(mcountinhibit) + + rvfi_csr_mcountinhibit_rdata = new_rvfi_trace.m_csr.mcountinhibit_rdata; + rvfi_csr_mcountinhibit_rmask = new_rvfi_trace.m_csr.mcountinhibit_rmask; + rvfi_csr_mcountinhibit_wdata = new_rvfi_trace.m_csr.mcountinhibit_wdata; + rvfi_csr_mcountinhibit_wmask = new_rvfi_trace.m_csr.mcountinhibit_wmask & MCOUNTINHIBIT_WRITE_MASK; + `SET_RVFI_CSR_FROM_INSN(mscratch) `SET_RVFI_CSR_FROM_INSN(mepc) `SET_RVFI_CSR_FROM_INSN(mcause) + `SET_RVFI_CSR_FROM_INSN(mcycle) `SET_RVFI_CSR_FROM_INSN(minstret) + `SET_RVFI_CSR_FROM_INSN(minstreth) + + // `SET_RVFI_CSR_FROM_INSN(cycle) + // `SET_RVFI_CSR_FROM_INSN(instret) + rvfi_csr_instret_rdata = new_rvfi_trace.m_csr.minstret_rdata; + rvfi_csr_instret_rmask = new_rvfi_trace.m_csr.minstret_rmask; + rvfi_csr_instret_wdata = new_rvfi_trace.m_csr.minstret_wdata; + rvfi_csr_instret_wmask = new_rvfi_trace.m_csr.minstret_wmask; + + for(int idx=3; idx<32; idx++) begin + rvfi_csr_mhpmcounter_rmask[idx] = new_rvfi_trace.m_csr.mhpmcounter_rmask[idx][31:0]; + rvfi_csr_mhpmcounter_wmask[idx] = new_rvfi_trace.m_csr.mhpmcounter_wmask[idx][31:0]; + rvfi_csr_mhpmcounter_rdata[idx] = new_rvfi_trace.m_csr.mhpmcounter_rdata[idx][31:0]; + rvfi_csr_mhpmcounter_wdata[idx] = new_rvfi_trace.m_csr.mhpmcounter_wdata[idx][31:0]; + + rvfi_csr_mhpmcounterh_rmask[idx] = new_rvfi_trace.m_csr.mhpmcounter_rmask[idx][63:32]; + rvfi_csr_mhpmcounterh_wmask[idx] = new_rvfi_trace.m_csr.mhpmcounter_wmask[idx][63:32]; + rvfi_csr_mhpmcounterh_rdata[idx] = new_rvfi_trace.m_csr.mhpmcounter_rdata[idx][63:32]; + rvfi_csr_mhpmcounterh_wdata[idx] = new_rvfi_trace.m_csr.mhpmcounter_wdata[idx][63:32]; + end + // `SET_RVFI_CSR_FROM_INSN(instreth) + rvfi_csr_instreth_rdata = new_rvfi_trace.m_csr.minstreth_rdata; + rvfi_csr_instreth_rmask = new_rvfi_trace.m_csr.minstreth_rmask; + rvfi_csr_instreth_wdata = new_rvfi_trace.m_csr.minstreth_wdata; + rvfi_csr_instreth_wmask = new_rvfi_trace.m_csr.minstreth_wmask; + `SET_RVFI_CSR_FROM_INSN(mip) - // if(rvfi_order == 64'h00000000_00000167) begin - // rvfi_csr_mip_rdata = 32'h0010_0000; - // end + rvfi_csr_tdata_rdata[0] = 'Z; rvfi_csr_tdata_rmask[0] = '0; // Does not exist rvfi_csr_tdata_wdata[0] = 'Z; // Does not exist @@ -959,20 +991,115 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; endfunction // set_rvfi - function void minstret_to_id(); - trace_id.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; - trace_id.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2]; + function void sample_perf_counter_to_id(int idx); + trace_id.m_csr.mhpmcounter_rdata[idx][31:0] = r_pipe_freeze_trace.csr.mhpmcounter_q[idx][31:0]; + trace_id.m_csr.mhpmcounter_rmask[idx][31:0] = '1; + endfunction + + function void perf_counter_to_id(int idx); + if(!trace_id.m_csr.mhpmcounter_we[idx][0]) begin + trace_id.m_csr.mhpmcounter_wdata[idx][31:0] = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]) begin + trace_id.m_csr.mhpmcounter_we[idx][0] = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]; + trace_id.m_csr.mhpmcounter_wdata[idx][31:0] = r_pipe_freeze_trace.csr.wdata_int; + trace_id.m_csr.mhpmcounter_wmask[idx][31:0] = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx] ? '1 : '0; + end + sample_perf_counter_to_id(idx); + endfunction + + function void sample_minstret_to_id(); + trace_id.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][31:0]; trace_id.m_csr.minstret_rmask = '1; - trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; - trace_id.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; endfunction - function void minstret_to_ex(); - trace_ex.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; - trace_ex.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2]; + function void minstret_to_id(); + if(!trace_id.m_csr.minstret_we) begin + trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin + trace_id.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; + trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; + trace_id.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; + end + sample_minstret_to_id(); + endfunction + + function void sample_perf_counter_h_to_id(int idx); + trace_id.m_csr.mhpmcounter_rdata[idx][63:32] = r_pipe_freeze_trace.csr.mhpmcounter_q[idx][63:0]; + trace_id.m_csr.mhpmcounter_rmask[idx][63:32] = '1; + endfunction + + function void perf_counter_h_to_id(int idx); + if(!trace_id.m_csr.mhpmcounter_we[idx][1]) begin + trace_id.m_csr.mhpmcounter_wdata[idx][63:32] = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]) begin + trace_id.m_csr.mhpmcounter_we[idx][1] = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]; + trace_id.m_csr.mhpmcounter_wdata[idx][63:32] = r_pipe_freeze_trace.csr.wdata_int; + trace_id.m_csr.mhpmcounter_wmask[idx][63:32] = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx] ? '1 : '0; + end + sample_perf_counter_h_to_id(idx); + endfunction + + function void sample_minstreth_to_id(); + trace_id.m_csr.minstreth_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][63:32]; + trace_id.m_csr.minstreth_rmask = '1; + endfunction + + function void minstreth_to_id(); + if(!trace_id.m_csr.minstreth_we) begin + trace_id.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin + trace_id.m_csr.minstreth_we = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]; + trace_id.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; + trace_id.m_csr.minstreth_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2] ? '1 : '0; + end + sample_minstreth_to_id(); + endfunction + + function void mcycle_to_id(); + trace_id.m_csr.mcycle_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0]; + trace_id.m_csr.mcycle_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[0][31:0]; + trace_id.m_csr.mcycle_rmask = '1; + trace_id.m_csr.mcycle_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q[31:0]; + trace_id.m_csr.mcycle_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0] ? '1 : '0; + endfunction + + function void sample_minstret_to_ex(); + trace_ex.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][31:0]; trace_ex.m_csr.minstret_rmask = '1; - trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; - trace_ex.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; + trace_ex.m_csr.minstreth_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][63:32]; + trace_ex.m_csr.minstreth_rmask = '1; + endfunction + + function void minstret_to_ex(); + if(!trace_id.m_csr.minstret_we) begin + trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin + trace_ex.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; + trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; + trace_ex.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; + end + if(!trace_id.m_csr.minstreth_we) begin + trace_ex.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin + trace_ex.m_csr.minstreth_we = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]; + trace_ex.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; + trace_ex.m_csr.minstreth_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2] ? '1 : '0; + end + sample_minstret_to_ex(); + endfunction + + function void mcycle_to_ex(); + trace_ex.m_csr.mcycle_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0]; + trace_ex.m_csr.mcycle_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[0]; + trace_ex.m_csr.mcycle_rmask = '1; + trace_ex.m_csr.mcycle_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; + trace_ex.m_csr.mcycle_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0] ? '1 : '0; endfunction function void tinfo_to_id(); @@ -1409,7 +1536,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_ex.m_valid & s_wb_valid_adjusted) begin // Used flopped values in case write happened before wb_valid - minstret_to_ex(); + sample_minstret_to_ex(); + mcycle_to_ex(); trace_ex.m_csr.got_minstret = '1; end @@ -1486,7 +1614,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_ex.m_valid) begin if(trace_ex.m_instret_smaple_trigger == 1) begin //time to sample instret - minstret_to_ex(); + sample_minstret_to_ex(); + mcycle_to_ex(); end trace_ex.m_instret_smaple_trigger = trace_ex.m_instret_smaple_trigger + 1; @@ -1578,7 +1707,13 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_id.m_valid) begin if(trace_id.m_instret_smaple_trigger == 1) begin //time to sample instret - minstret_to_id(); + sample_minstret_to_id(); + sample_minstreth_to_id(); + mcycle_to_id(); + for(int idx=3; idx<32; idx++) begin + sample_perf_counter_to_id(idx); + sample_perf_counter_h_to_id(idx); + end end trace_id.m_instret_smaple_trigger = trace_id.m_instret_smaple_trigger + 1; @@ -1594,6 +1729,23 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if(r_pipe_freeze_trace.csr.we && (r_pipe_freeze_trace.csr.addr == CSR_DPC)) begin `CSR_FROM_PIPE(id, dpc) end + + `CSR_FROM_PIPE(id, mcountinhibit) + + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin + minstret_to_id(); + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin + minstreth_to_id(); + end + for(int idx=3; idx<32; idx++) begin + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]) begin + perf_counter_to_id(3); + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[idx]) begin + perf_counter_h_to_id(3); + end + end ->e_csr_in_ex; end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index ca703682a..1716c8c6c 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -234,8 +234,9 @@ module cv32e40p_tb_wrapper endgenerate cv32e40p_rvfi #( - .FPU (FPU), - .ZFINX(ZFINX) + .FPU(FPU), + .ZFINX(ZFINX), + .NUM_MHPMCOUNTERS(NUM_MHPMCOUNTERS) ) rvfi_i ( .clk_i (cv32e40p_top_i.core_i.clk_i), .rst_ni(cv32e40p_top_i.core_i.rst_ni), diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index 71cbaaff4..bf73c6dc4 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -103,9 +103,22 @@ `DEFINE_CSR(mscratch) `DEFINE_CSR(mepc) `DEFINE_CSR(mcause) + `DEFINE_CSR(mcycle) `DEFINE_CSR(minstret) bit got_minstret; - + `DEFINE_CSR(mcycleh) + `DEFINE_CSR(minstreth) + `DEFINE_CSR(cycle) + `DEFINE_CSR(instret) + // bit got_minstret; + `DEFINE_CSR(cycleh) + `DEFINE_CSR(instreth) + + logic [31:0][ 1:0] mhpmcounter_we; + logic [31:0][63:0] mhpmcounter_rdata; + logic [31:0][63:0] mhpmcounter_rmask; + logic [31:0][63:0] mhpmcounter_wdata; + logic [31:0][63:0] mhpmcounter_wmask; `DEFINE_CSR(mip) //mnxti //mintstatus @@ -849,7 +862,16 @@ `INIT_CSR(mscratch) `INIT_CSR(mepc) `INIT_CSR(mcause) + `INIT_CSR(mcycle) `INIT_CSR(minstret) + `INIT_CSR(mcycleh) + `INIT_CSR(minstreth) + `INIT_CSR(cycle) + `INIT_CSR(instret) + `INIT_CSR(cycleh) + `INIT_CSR(instreth) + this.m_csr.mhpmcounter_we = '0; + this.m_csr.mhpmcounter_wmask = '0; `INIT_CSR(mip) `INIT_CSR(tdata1) `INIT_CSR(tdata2) @@ -1004,8 +1026,21 @@ `ASSIGN_CSR(mscratch) `ASSIGN_CSR(mepc) `ASSIGN_CSR(mcause) + `ASSIGN_CSR(mcycle) `ASSIGN_CSR(minstret) this.m_csr.got_minstret = m_source.m_csr.got_minstret; + `ASSIGN_CSR(mcycleh) + `ASSIGN_CSR(minstreth) + `ASSIGN_CSR(cycle) + `ASSIGN_CSR(instret) + // this.m_csr.got_minstret = m_source.m_csr.got_minstret; + `ASSIGN_CSR(cycleh) + `ASSIGN_CSR(instreth) + this.m_csr.mhpmcounter_we = m_source.m_csr.mhpmcounter_we; + this.m_csr.mhpmcounter_rdata = m_source.m_csr.mhpmcounter_rdata; + this.m_csr.mhpmcounter_rmask = m_source.m_csr.mhpmcounter_rmask; + this.m_csr.mhpmcounter_wdata = m_source.m_csr.mhpmcounter_wdata; + this.m_csr.mhpmcounter_wmask = m_source.m_csr.mhpmcounter_wmask; `ASSIGN_CSR(mip) `ASSIGN_CSR(tdata1) `ASSIGN_CSR(tdata2) From 8e266d3adbc7cea2086d457eea9729da43ae5794 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 9 Feb 2024 12:29:42 +0800 Subject: [PATCH 18/69] RVFI _ Some refactoring --- bhv/cv32e40p_rvfi.sv | 110 ++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 55a63b8e5..c202cd89f 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1008,21 +1008,21 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; sample_perf_counter_to_id(idx); endfunction - function void sample_minstret_to_id(); - trace_id.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][31:0]; - trace_id.m_csr.minstret_rmask = '1; + function void sample_minstret_to_trace(insn_trace_t m_trace); + m_trace.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][31:0]; + m_trace.m_csr.minstret_rmask = '1; endfunction - function void minstret_to_id(); - if(!trace_id.m_csr.minstret_we) begin - trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; + function void minstret_to_trace(insn_trace_t m_trace); + if(!m_trace.m_csr.minstret_we) begin + m_trace.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; end if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin - trace_id.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; - trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; - trace_id.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; + m_trace.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; + m_trace.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; + m_trace.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; end - sample_minstret_to_id(); + sample_minstret_to_trace(m_trace); endfunction function void sample_perf_counter_h_to_id(int idx); @@ -1042,21 +1042,43 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; sample_perf_counter_h_to_id(idx); endfunction - function void sample_minstreth_to_id(); - trace_id.m_csr.minstreth_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][63:32]; - trace_id.m_csr.minstreth_rmask = '1; + function void sample_minstreth_to_trace(insn_trace_t m_trace); + m_trace.m_csr.minstreth_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][63:32]; + m_trace.m_csr.minstreth_rmask = '1; endfunction - function void minstreth_to_id(); - if(!trace_id.m_csr.minstreth_we) begin - trace_id.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; + function void minstreth_to_trace(insn_trace_t m_trace); + if(!m_trace.m_csr.minstreth_we) begin + m_trace.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; end if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin - trace_id.m_csr.minstreth_we = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]; - trace_id.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; - trace_id.m_csr.minstreth_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2] ? '1 : '0; + m_trace.m_csr.minstreth_we = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]; + m_trace.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; + m_trace.m_csr.minstreth_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2] ? '1 : '0; end - sample_minstreth_to_id(); + sample_minstreth_to_trace(m_trace); + endfunction + + function void sample_perf_counter_to_trace(insn_trace_t m_trace); + sample_minstret_to_trace(m_trace); + sample_minstreth_to_trace(m_trace); + endfunction + + function void perf_counter_to_trace(insn_trace_t m_trace); + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin + minstret_to_trace(m_trace); + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin + minstreth_to_trace(m_trace); + end + for(int idx=3; idx<32; idx++) begin + if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]) begin + perf_counter_to_id(3); + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[idx]) begin + perf_counter_h_to_id(3); + end + end endfunction function void mcycle_to_id(); @@ -1067,32 +1089,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_csr.mcycle_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0] ? '1 : '0; endfunction - function void sample_minstret_to_ex(); - trace_ex.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][31:0]; - trace_ex.m_csr.minstret_rmask = '1; - trace_ex.m_csr.minstreth_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][63:32]; - trace_ex.m_csr.minstreth_rmask = '1; - endfunction - - function void minstret_to_ex(); - if(!trace_id.m_csr.minstret_we) begin - trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; - end - if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin - trace_ex.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; - trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.wdata_int; - trace_ex.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; - end - if(!trace_id.m_csr.minstreth_we) begin - trace_ex.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; - end - if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin - trace_ex.m_csr.minstreth_we = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]; - trace_ex.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; - trace_ex.m_csr.minstreth_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2] ? '1 : '0; - end - sample_minstret_to_ex(); - endfunction function void mcycle_to_ex(); trace_ex.m_csr.mcycle_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0]; @@ -1536,7 +1532,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_ex.m_valid & s_wb_valid_adjusted) begin // Used flopped values in case write happened before wb_valid - sample_minstret_to_ex(); + sample_perf_counter_to_trace(trace_ex); mcycle_to_ex(); trace_ex.m_csr.got_minstret = '1; end @@ -1614,7 +1610,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_ex.m_valid) begin if(trace_ex.m_instret_smaple_trigger == 1) begin //time to sample instret - sample_minstret_to_ex(); + sample_perf_counter_to_trace(trace_ex); mcycle_to_ex(); end trace_ex.m_instret_smaple_trigger = trace_ex.m_instret_smaple_trigger + 1; @@ -1707,8 +1703,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_id.m_valid) begin if(trace_id.m_instret_smaple_trigger == 1) begin //time to sample instret - sample_minstret_to_id(); - sample_minstreth_to_id(); + sample_perf_counter_to_trace(trace_id); mcycle_to_id(); for(int idx=3; idx<32; idx++) begin sample_perf_counter_to_id(idx); @@ -1732,20 +1727,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, mcountinhibit) - if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]) begin - minstret_to_id(); - end - if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin - minstreth_to_id(); - end - for(int idx=3; idx<32; idx++) begin - if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]) begin - perf_counter_to_id(3); - end - if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[idx]) begin - perf_counter_h_to_id(3); - end - end + perf_counter_to_trace(trace_id); ->e_csr_in_ex; end From f9e8863860a3b7c04855efbb5a4c46c50ceb6509 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Thu, 14 Mar 2024 16:27:46 +0800 Subject: [PATCH 19/69] RVFI - Updating mstatus_fs udpate due to flw --- bhv/cv32e40p_rvfi.sv | 94 +++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 59 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index c202cd89f..ab86e917b 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1047,6 +1047,14 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; m_trace.m_csr.minstreth_rmask = '1; endfunction + function void sample_mcycle_to_trace(insn_trace_t m_trace); + m_trace.m_csr.mcycle_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0]; + m_trace.m_csr.mcycle_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[0][31:0]; + m_trace.m_csr.mcycle_rmask = '1; + m_trace.m_csr.mcycle_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q[31:0]; + m_trace.m_csr.mcycle_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0] ? '1 : '0; + endfunction + function void minstreth_to_trace(insn_trace_t m_trace); if(!m_trace.m_csr.minstreth_we) begin m_trace.m_csr.minstreth_wdata = r_pipe_freeze_trace.csr.wdata_int; @@ -1062,6 +1070,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; function void sample_perf_counter_to_trace(insn_trace_t m_trace); sample_minstret_to_trace(m_trace); sample_minstreth_to_trace(m_trace); + sample_mcycle_to_trace(m_trace); endfunction function void perf_counter_to_trace(insn_trace_t m_trace); @@ -1081,37 +1090,12 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end endfunction - function void mcycle_to_id(); - trace_id.m_csr.mcycle_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0]; - trace_id.m_csr.mcycle_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[0][31:0]; - trace_id.m_csr.mcycle_rmask = '1; - trace_id.m_csr.mcycle_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q[31:0]; - trace_id.m_csr.mcycle_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0] ? '1 : '0; - endfunction - - - function void mcycle_to_ex(); - trace_ex.m_csr.mcycle_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0]; - trace_ex.m_csr.mcycle_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[0]; - trace_ex.m_csr.mcycle_rmask = '1; - trace_ex.m_csr.mcycle_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; - trace_ex.m_csr.mcycle_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[0] ? '1 : '0; - endfunction - - function void tinfo_to_id(); - trace_id.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; - trace_id.m_csr.tinfo_rdata = r_pipe_freeze_trace.csr.tinfo_q; - trace_id.m_csr.tinfo_rmask = '1; - trace_id.m_csr.tinfo_wdata = r_pipe_freeze_trace.csr.tinfo_n; - trace_id.m_csr.tinfo_wmask = '0; - endfunction - - function void tinfo_to_ex(); - trace_ex.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; - trace_ex.m_csr.tinfo_rdata = r_pipe_freeze_trace.csr.tinfo_q; - trace_ex.m_csr.tinfo_rmask = '1; - trace_ex.m_csr.tinfo_wdata = r_pipe_freeze_trace.csr.tinfo_n; - trace_ex.m_csr.tinfo_wmask = '0; + function void tinfo_to_trace(insn_trace_t m_trace); + m_trace.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; + m_trace.m_csr.tinfo_rdata = r_pipe_freeze_trace.csr.tinfo_q; + m_trace.m_csr.tinfo_rmask = '1; + m_trace.m_csr.tinfo_wdata = r_pipe_freeze_trace.csr.tinfo_n; + m_trace.m_csr.tinfo_wmask = '0; endfunction function void mtvec_to_id(); @@ -1398,7 +1382,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, misa) `CSR_FROM_PIPE(id, tdata1) `CSR_FROM_PIPE(id, tdata2) - tinfo_to_id(); + tinfo_to_trace(trace_id); `CSR_FROM_PIPE(id, mip) send_rvfi(trace_id); end @@ -1423,6 +1407,19 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; return mask; endfunction + function void commit_rf_to_trace(insn_trace_t m_trace); + if (m_trace.m_got_ex_reg) begin + m_trace.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + m_trace.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + m_trace.m_2_rd_insn = 1'b1; + m_trace.m_got_first_data = 1'b1; + end else begin + m_trace.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + m_trace.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; + m_trace.m_got_first_data = 1'b1; + end + endfunction + task compute_pipeline(); bit s_new_valid_insn; bit s_ex_valid_adjusted; @@ -1498,7 +1495,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, misa) `CSR_FROM_PIPE(id, tdata1) `CSR_FROM_PIPE(id, tdata2) - tinfo_to_id(); + tinfo_to_trace(trace_id); `CSR_FROM_PIPE(id, mip) end end @@ -1533,7 +1530,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_ex.m_valid & s_wb_valid_adjusted) begin // Used flopped values in case write happened before wb_valid sample_perf_counter_to_trace(trace_ex); - mcycle_to_ex(); trace_ex.m_csr.got_minstret = '1; end @@ -1611,14 +1607,13 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_ex.m_valid) begin if(trace_ex.m_instret_smaple_trigger == 1) begin //time to sample instret sample_perf_counter_to_trace(trace_ex); - mcycle_to_ex(); end trace_ex.m_instret_smaple_trigger = trace_ex.m_instret_smaple_trigger + 1; `CSR_FROM_PIPE(ex, misa) `CSR_FROM_PIPE(ex, tdata1) `CSR_FROM_PIPE(ex, tdata2) - tinfo_to_ex(); + tinfo_to_trace(trace_ex); if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_4; @@ -1644,18 +1639,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_1; - if (trace_ex.m_got_ex_reg) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; - trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_2_rd_insn = 1'b1; - trace_ex.m_got_first_data = 1'b1; - end else begin - trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_got_first_data = 1'b1; - end + commit_rf_to_trace(trace_ex); - if (r_pipe_freeze_trace.csr.fregs_we && !r_pipe_freeze_trace.apu_rvalid) begin //Catching mstatus_fs updates caused by flw + if (r_pipe_freeze_trace.csr.fregs_we && (r_pipe_freeze_trace.rf_we_wb && r_pipe_freeze_trace.rf_addr_wb[5])) begin //Catching mstatus_fs updates caused by flw `CSR_FROM_PIPE(ex, mstatus_fs) trace_ex.m_csr.mstatus_fs_we = 1'b1; trace_ex.m_csr.mstatus_fs_wmask = '1; @@ -1684,16 +1670,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end else if (s_rf_we_wb_adjusted && !s_was_flush) begin ->e_dev_commit_rf_to_ex_2; - if (trace_ex.m_got_ex_reg) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; - trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_2_rd_insn = 1'b1; - trace_ex.m_got_first_data = 1'b1; - end else begin - trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_got_first_data = 1'b1; - end + commit_rf_to_trace(trace_ex); end end @@ -1704,7 +1681,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (trace_id.m_valid) begin if(trace_id.m_instret_smaple_trigger == 1) begin //time to sample instret sample_perf_counter_to_trace(trace_id); - mcycle_to_id(); for(int idx=3; idx<32; idx++) begin sample_perf_counter_to_id(idx); sample_perf_counter_h_to_id(idx); @@ -1768,7 +1744,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_csr.fcsr_wmask = '0; if(r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin //xret exit pipeline - tinfo_to_id(); + tinfo_to_trace(trace_id); `CSR_FROM_PIPE(id, tdata1) `CSR_FROM_PIPE(id, tdata2) send_rvfi(trace_id); From 6ac231642433e6532f4351d20f09aa593a9a1b49 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 14 Mar 2024 19:25:01 +0100 Subject: [PATCH 20/69] Issue #959 correction. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_load_store_unit.sv | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/rtl/cv32e40p_load_store_unit.sv b/rtl/cv32e40p_load_store_unit.sv index 7c08ffe11..f9c4db4a8 100644 --- a/rtl/cv32e40p_load_store_unit.sv +++ b/rtl/cv32e40p_load_store_unit.sv @@ -121,18 +121,18 @@ module cv32e40p_load_store_unit #( 2'b00: begin // Writing a word if (misaligned_st == 1'b0) begin // non-misaligned case case (data_addr_int[1:0]) - 2'b00: data_be = 4'b1111; - 2'b01: data_be = 4'b1110; - 2'b10: data_be = 4'b1100; - 2'b11: data_be = 4'b1000; + 2'b00: data_be = 4'b1111; + 2'b01: data_be = 4'b1110; + 2'b10: data_be = 4'b1100; + default: data_be = 4'b1000; endcase ; // case (data_addr_int[1:0]) end else begin // misaligned case case (data_addr_int[1:0]) - 2'b00: data_be = 4'b0000; // this is not used, but included for completeness - 2'b01: data_be = 4'b0001; - 2'b10: data_be = 4'b0011; - 2'b11: data_be = 4'b0111; + 2'b01: data_be = 4'b0001; + 2'b10: data_be = 4'b0011; + 2'b11: data_be = 4'b0111; + default: data_be = 4'b0000; // this is not used, but included for completeness endcase ; // case (data_addr_int[1:0]) end @@ -141,10 +141,10 @@ module cv32e40p_load_store_unit #( 2'b01: begin // Writing a half word if (misaligned_st == 1'b0) begin // non-misaligned case case (data_addr_int[1:0]) - 2'b00: data_be = 4'b0011; - 2'b01: data_be = 4'b0110; - 2'b10: data_be = 4'b1100; - 2'b11: data_be = 4'b1000; + 2'b00: data_be = 4'b0011; + 2'b01: data_be = 4'b0110; + 2'b10: data_be = 4'b1100; + default: data_be = 4'b1000; endcase ; // case (data_addr_int[1:0]) end else begin // misaligned case @@ -154,10 +154,10 @@ module cv32e40p_load_store_unit #( 2'b10, 2'b11: begin // Writing a byte case (data_addr_int[1:0]) - 2'b00: data_be = 4'b0001; - 2'b01: data_be = 4'b0010; - 2'b10: data_be = 4'b0100; - 2'b11: data_be = 4'b1000; + 2'b00: data_be = 4'b0001; + 2'b01: data_be = 4'b0010; + 2'b10: data_be = 4'b0100; + default: data_be = 4'b1000; endcase ; // case (data_addr_int[1:0]) end From 85146dc90533e18dcb49bb8d9dfa0a5367dae01b Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 14 Mar 2024 19:25:32 +0100 Subject: [PATCH 21/69] Issue #960 correction. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_decoder.sv | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/rtl/cv32e40p_decoder.sv b/rtl/cv32e40p_decoder.sv index d03027bae..7d7fb676b 100644 --- a/rtl/cv32e40p_decoder.sv +++ b/rtl/cv32e40p_decoder.sv @@ -1900,15 +1900,14 @@ module cv32e40p_decoder alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD; unique case (instr_rdata_i[27:25]) - 3'b000: alu_operator_o = ALU_ADD; // cv.addNr - 3'b001: alu_operator_o = ALU_ADDU; // cv.adduNr - 3'b010: alu_operator_o = ALU_ADDR; // cv.addRNr - 3'b011: alu_operator_o = ALU_ADDUR; // cv.adduRNr - 3'b100: alu_operator_o = ALU_SUB; // cv.subNr - 3'b101: alu_operator_o = ALU_SUBU; // cv.subuNr - 3'b110: alu_operator_o = ALU_SUBR; // cv.subRNr - 3'b111: alu_operator_o = ALU_SUBUR; // cv.subuRNr - default: alu_operator_o = ALU_ADD; + 3'b001: alu_operator_o = ALU_ADDU; // cv.adduNr + 3'b010: alu_operator_o = ALU_ADDR; // cv.addRNr + 3'b011: alu_operator_o = ALU_ADDUR; // cv.adduRNr + 3'b100: alu_operator_o = ALU_SUB; // cv.subNr + 3'b101: alu_operator_o = ALU_SUBU; // cv.subuNr + 3'b110: alu_operator_o = ALU_SUBR; // cv.subRNr + 3'b111: alu_operator_o = ALU_SUBUR; // cv.subuRNr + default: alu_operator_o = ALU_ADD; // cv.addNr endcase end @@ -2085,7 +2084,6 @@ module cv32e40p_decoder // decide between using unsigned and rounding, and combinations unique case ({instr_rdata_i[31:30], instr_rdata_i[12]}) - {2'b00, 1'b0}: alu_operator_o = ALU_ADD; // cv.addN {2'b01, 1'b0}: alu_operator_o = ALU_ADDU; // cv.adduN {2'b10, 1'b0}: alu_operator_o = ALU_ADDR; // cv.addRN {2'b11, 1'b0}: alu_operator_o = ALU_ADDUR; // cv.adduRN @@ -2093,12 +2091,12 @@ module cv32e40p_decoder {2'b01, 1'b1}: alu_operator_o = ALU_SUBU; // cv.subuN {2'b10, 1'b1}: alu_operator_o = ALU_SUBR; // cv.subRN {2'b11, 1'b1}: alu_operator_o = ALU_SUBUR; // cv.subuRN - default : alu_operator_o = ALU_ADD; + default : alu_operator_o = ALU_ADD; // cv.addN endcase end - 2'b10, 2'b11: begin + default: begin // MUL/MAC with subword selection alu_en = 1'b0; mult_int_en = 1'b1; @@ -2126,7 +2124,6 @@ module cv32e40p_decoder mult_operator_o = MUL_I; end end - default: illegal_insn_o = 1'b1; endcase end else begin illegal_insn_o = 1'b1; From 8407734678772c17d3fc0fc8a5223bab1f1e5625 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 18 Mar 2024 18:54:01 +0100 Subject: [PATCH 22/69] Added possibility to make lec between v2 versions. Updated headers date and moved to Solderpad 2.1 Signed-off-by: Pascal Gouedo --- scripts/slec/README.md | 18 ++++++ scripts/slec/cadence/lec.tcl | 43 ++++++++++----- scripts/slec/run.sh | 100 +++++++++++++++++++++++++++------- scripts/slec/synopsys/lec.tcl | 47 +++++++++++++--- 4 files changed, 168 insertions(+), 40 deletions(-) diff --git a/scripts/slec/README.md b/scripts/slec/README.md index ff5311322..6249563cc 100644 --- a/scripts/slec/README.md +++ b/scripts/slec/README.md @@ -59,3 +59,21 @@ From a bash shell using LEC, please execute: setenv GOLDEN_RTL YOUR_GOLDEN_CORE_RTL_PATH ``` +### Additional improvements for v2 + +To be able to make LEC checks between v2 versions, the scripts have been augmented with additional optional switches: +* for RTL version : -v v1 or v2 +* for PULP instructions selection : -x 0 or 1 +* for FPU instructions selection : -f 0 or 1 +* for ZFINX selection : -z 0 or 1 + +When those options are not used, present behavior is happenning, meaning verifying local RTL files with `cv32e40p_v1.0.0` tag. +When v2 option is selected, `cv32e40p_top` is used as a top module, including both `cv32e40p_core` and `CVFPU`. +CAUTION : Right now dev branch is cloned as a golden reference when v2 version is used. It will have to be changed to `cv32e40p_v2.0.0` tag after CV32E40Pv2 RTL freeze. + +From a bash shell using LEC, please execute: + +``` +./run.sh -t synopsys -p lec -v v2 -x 1 -f 1 +``` + diff --git a/scripts/slec/cadence/lec.tcl b/scripts/slec/cadence/lec.tcl index 3cc8bea7b..7acbfd3a5 100644 --- a/scripts/slec/cadence/lec.tcl +++ b/scripts/slec/cadence/lec.tcl @@ -1,33 +1,48 @@ -// Copyright 2021 OpenHW Group +// Copyright 2024 OpenHW Group and Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. // You may obtain a copy of the License at // -// https://solderpad.org/licenses/ +// https://solderpad.org/licenses/SHL-2.1/ // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an “AS IS” BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + set summary_log $::env(summary_log) set top_module $::env(top_module) +set version $::env(version) +set pulp_cfg $::env(pulp_cfg) +set fpu_cfg $::env(fpu_cfg) +set zfinx_cfg $::env(zfinx_cfg) + +if {"$version" == "v1"} { + set golden_parameter_list "-parameter PULP_XPULP 0 -parameter FPU 0 -parameter PULP_ZFINX 0" +} else { + set golden_parameter_list "-parameter COREV_PULP $pulp_cfg -parameter FPU $fpu_cfg -parameter ZFINX $zfinx_cfg" +} -read_design -SV -replace -noelaborate -golden -File ./golden.src +read_design -SV09 -replace -noelaborate -golden -File ./golden.src -elaborate_design -golden +elaborate_design -golden -root $top_module $golden_parameter_list -read_design -SV -replace -noelaborate -revised -File ./revised.src +read_design -SV09 -replace -noelaborate -revised -File ./revised.src -elaborate_design -revised +elaborate_design -revised -root $top_module -parameter COREV_PULP $pulp_cfg -parameter FPU $fpu_cfg -parameter ZFINX $zfinx_cfg report_design_data -add_ignored_outputs apu_req_o -Both -add_ignored_outputs apu_operands_o* -Both -add_ignored_outputs apu_op_o* -Both -add_ignored_outputs apu_flags_o* -Both +if {"$top_module" == "cv32e40p_core"} { + add_ignored_outputs apu_req_o -Both + add_ignored_outputs apu_operands_o* -Both + add_ignored_outputs apu_op_o* -Both + add_ignored_outputs apu_flags_o* -Both +} write_hier_compare_dofile hier_compare_r2r.do -constraint -replace diff --git a/scripts/slec/run.sh b/scripts/slec/run.sh index 064154815..23a51bab5 100755 --- a/scripts/slec/run.sh +++ b/scripts/slec/run.sh @@ -1,21 +1,25 @@ #!/bin/bash -# Copyright 2023 OpenHW Group +# Copyright 2024 OpenHW Group and Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 # -# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. +# Licensed under the Solderpad Hardware License v 2.1 (the “License”); +# you may not use this file except in compliance with the License, or, +# at your option, the Apache License version 2.0. # You may obtain a copy of the License at # -# https://solderpad.org/licenses/ +# https://solderpad.org/licenses/SHL-2.1/ # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, +# Unless required by applicable law or agreed to in writing, any work +# distributed under the License is distributed on an “AS IS” BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. usage() { # Function: Print a help message. - echo "Usage: $0 [ -t {cadence,synopsys,siemens} -p {sec,lec} ]" 1>&2 + echo "Usage: $0 -t {cadence,synopsys,siemens} -p {sec,lec} [-v {v1,v2}] [-x {0,1}] [-f {0,1}] [-z {0,1}]]" 1>&2 + echo "For v2 : if f or z is 1 then p must be 1" 1>&2 + echo " if z is 1 then f must be 1" 1>&2 } exit_abnormal() { # Function: Exit with error. @@ -32,7 +36,12 @@ print_log() { echo "[LOG] $1" } -while getopts "t:p:" flag +VERSION=v1 +PULP_CFG=0 +FPU_CFG=0 +ZFINX_CFG=0 + +while getopts "t:p:v:x:f:z:" flag do case "${flag}" in t) @@ -41,6 +50,18 @@ do p) target_process=${OPTARG} ;; + v) + VERSION=${OPTARG} + ;; + x) + PULP_CFG=${OPTARG} + ;; + f) + FPU_CFG=${OPTARG} + ;; + z) + ZFINX_CFG=${OPTARG} + ;; :) exit_abnormal ;; @@ -61,25 +82,63 @@ if [[ "${target_process}" != "sec" && "${target_process}" != "lec" ]]; then exit_abnormal fi +if [[ "${VERSION}" != "v1" && "${VERSION}" != "v2" ]]; then + exit_abnormal +elif [[ "${VERSION}" == "v1" && ("${PULP_CFG}" != "0" || "${FPU_CFG}" != "0" || "${ZFINX_CFG}" != "0") ]]; then + exit_abnormal +fi + +if [[ "${PULP_CFG}" != 0 && "${PULP_CFG}" != 1 ]]; then + exit_abnormal +fi + +if [[ "${FPU_CFG}" != 0 && "${FPU_CFG}" != 1 ]]; then + exit_abnormal +fi + +if [[ "${ZFINX_CFG}" != 0 && "${ZFINX_CFG}" != 1 ]]; then + exit_abnormal +fi + +if [[ (("${PULP_CFG}" == 0 && ("${FPU_CFG}" == 1 || "${ZFINX_CFG}" == 1)) || ("${PULP_CFG}" == 1 && "${FPU_CFG}" == 0 && "${ZFINX_CFG}" == 1)) ]]; then + exit_abnormal +fi + +if [[ "${VERSION}" == "v1" ]]; then + REF_BRANCH=cv32e40p_v1.0.0 + TOP_MODULE=cv32e40p_core +else + REF_BRANCH=dev + TOP_MODULE=cv32e40p_top +fi + +export top_module=${TOP_MODULE} +export version=${VERSION} +export pulp_cfg=${PULP_CFG} +export fpu_cfg=${FPU_CFG} +export zfinx_cfg=${ZFINX_CFG} + if [ -z "${REF_REPO}" ]; then print_log "Empty REF_REPO env variable" REF_REPO=https://github.com/openhwgroup/cv32e40p.git REF_FOLDER=ref_design - REF_BRANCH=cv32e40p_v1.0.0 print_log " * Setting REF_REPO ${REF_REPO}" print_log " * Setting REF_FOLDER ${REF_FOLDER}" print_log " * Setting REF_BRANCH ${REF_BRANCH}" + print_log " * Setting TOP_MODULE ${TOP_MODULE}" fi RTL_FOLDER=$(readlink -f ../..) -FLIST=cv32e40p_manifest.flist +if [[ "${PULP_CFG}" == 0 && "${ZFINX_CFG}" == 0 ]]; then + FLIST=cv32e40p_manifest.flist +else + FLIST=cv32e40p_fpu_manifest.flist +fi if [[ -z "${TOP_MODULE}" ]]; then print_log "Empty TOP_MODULE env variable" - TOP_MODULE=cv32e40p_core print_log " * Setting TOP_MODULE ${TOP_MODULE}" - export top_module=${TOP_MODULE} fi if [ ! -d ./reports/ ]; then @@ -88,11 +147,10 @@ fi if [[ -z "${GOLDEN_RTL}" ]]; then print_log "The env variable GOLDEN_RTL is empty." - if [ ! -d "./${REF_FOLDER}" ]; then - print_log " * Cloning Golden Design...." - git clone $REF_REPO --single-branch -b $REF_BRANCH $REF_FOLDER; - git -C ${REF_FOLDER} checkout $REF_COMMIT - fi + \rm -rf "./${REF_FOLDER}" + print_log " * Cloning Golden Design...." + git clone $REF_REPO --single-branch -b $REF_BRANCH $REF_FOLDER; + git -C ${REF_FOLDER} checkout $REF_COMMIT export GOLDEN_RTL=$(pwd)/${REF_FOLDER}/rtl else print_log "${target_process^^}: Using ${GOLDEN_RTL} as reference design" @@ -104,9 +162,13 @@ REVISED_FLIST=$(pwd)/revised.src GOLDEN_DIR=$(readlink -f ./${REF_FOLDER}/) GOLDEN_FLIST=$(pwd)/golden.src -var_golden_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper") print $0 }' ${GOLDEN_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${GOLDEN_DIR}"'/rtl/|') +var_golden_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "tb_wrapper" && $0 !~ "cv32e40p_wrapper") print $0 }' ${GOLDEN_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${GOLDEN_DIR}"'/rtl/|') -var_revised_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "wrapper" && $0 !~ "_top") print $0 }' ${REVISED_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${REVISED_DIR}"'/rtl/|') +if [[ "${VERSION}" == "v1" ]]; then + var_revised_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "tb_wrapper" && $0 !~ "cv32e40p_wrapper" && $0 !~ "top") print $0 }' ${REVISED_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${REVISED_DIR}"'/rtl/|') +else + var_revised_rtl=$(awk '{ if ($0 ~ "{DESIGN_RTL_DIR}" && $0 !~ "#" && $0 !~ "tracer" && $0 !~ "tb_wrapper") print $0 }' ${REVISED_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${REVISED_DIR}"'/rtl/|') +fi print_log "Generating GOLDEN flist in path: ${GOLDEN_FLIST}" echo $var_golden_rtl > ${GOLDEN_FLIST} diff --git a/scripts/slec/synopsys/lec.tcl b/scripts/slec/synopsys/lec.tcl index 5d8f9130d..b8683fce5 100644 --- a/scripts/slec/synopsys/lec.tcl +++ b/scripts/slec/synopsys/lec.tcl @@ -1,26 +1,59 @@ +# Copyright 2024 OpenHW Group and Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# +# Licensed under the Solderpad Hardware License v 2.1 (the “License”); +# you may not use this file except in compliance with the License, or, +# at your option, the Apache License version 2.0. +# You may obtain a copy of the License at +# +# https://solderpad.org/licenses/SHL-2.1/ +# +# Unless required by applicable law or agreed to in writing, any work +# distributed under the License is distributed on an “AS IS” BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + set synopsys_auto_setup true set summary_log $::env(summary_log) set top_module $::env(top_module) +set version $::env(version) +set pulp_cfg $::env(pulp_cfg) +set fpu_cfg $::env(fpu_cfg) +set zfinx_cfg $::env(zfinx_cfg) + +set top_impl_name cv32e40p_core_COREV_PULP${pulp_cfg}_FPU${fpu_cfg}_ZFINX${zfinx_cfg} + +if {"$version" == "v1"} { + set golden_parameter_list "PULP_XPULP = 0, FPU = 0, PULP_ZFINX = 0" + set top_ref_name cv32e40p_core_PULP_XPULP0_FPU0_PULP_ZFINX0 +} else { + set golden_parameter_list "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg" + set top_ref_name $top_impl_name +} read_sverilog -container r -libname WORK -12 -f golden.src -set_top r:/WORK/$top_module +set_top r:/WORK/$top_module -parameter $golden_parameter_list read_sverilog -container i -libname WORK -12 -f revised.src -set_top i:/WORK/$top_module +set_top i:/WORK/$top_module -parameter "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg" match > $summary_log.match.rpt if {"$top_module" == "cv32e40p_core"} { - set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_req_o - set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_operands_o* - set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_op_o* - set_dont_verify_point -type port i:WORK/cv32e40p_core/apu_flags_o* + set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_req_o + set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_operands_o* + set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_op_o* + set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_flags_o* + set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_req_o + set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_operands_o* + set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_op_o* + set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_flags_o* } verify > $summary_log report_aborted_points > $summary_log.aborted_points.rpt report_failing_points > $summary_log.failing_points.rpt -analyze_points -failing >> $summary_log exit From cb465fa53d63637ed6edb9285b8a5af80b02aea3 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 20 Mar 2024 17:13:51 +0100 Subject: [PATCH 23/69] Restored v1 headers and added same header to new files. Signed-off-by: Pascal Gouedo --- bhv/cv32e40p_instr_trace.svh | 40 ++++++++++++++++++--------- bhv/cv32e40p_rvfi.sv | 28 +++++++++++-------- bhv/cv32e40p_rvfi_trace.sv | 26 ++++++++++-------- bhv/cv32e40p_tb_wrapper.sv | 26 ++++++++++-------- bhv/cv32e40p_tracer.sv | 44 ++++++++++++++++-------------- bhv/include/cv32e40p_rvfi_pkg.sv | 28 +++++++++++-------- bhv/include/cv32e40p_tracer_pkg.sv | 30 +++++++------------- bhv/insn_trace.sv | 25 +++++++++++++++-- bhv/pipe_freeze_trace.sv | 30 ++++++++++---------- rtl/cv32e40p_fp_wrapper.sv | 2 +- rtl/cv32e40p_top.sv | 36 ++++++++++++++++-------- 11 files changed, 186 insertions(+), 129 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index a89ed4e45..0b92c5cc4 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -1,23 +1,37 @@ -// Copyright (c) 2020 OpenHW Group +// Copyright 2020 Silicon Labs, Inc. // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// This file, and derivatives thereof are licensed under the +// Solderpad License, Version 2.0 (the "License"). // -// https://solderpad.org/licenses/ +// Use of this file means you agree to the terms and conditions +// of the license and are in full compliance with the License. +// +// You may obtain a copy of the License at: +// +// https://solderpad.org/licenses/SHL-2.0/ // // Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// and hardware implementations thereof distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, EITHER EXPRESSED OR IMPLIED. +// // See the License for the specific language governing permissions and // limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// Tracer data structures and functions -// -// Contributors: Steve Richmond, Silicon Labs -// Pascal Gouedo, Dolphin Design +//////////////////////////////////////////////////////////////////////////////// +// Engineer: Steve Richmond - steve.richmond@silabs.com // +// // +// Design Name: cv32e40p_tracer data structures // +// Project Name: CV32E40P // +// Language: SystemVerilog // +// // +// Description: Moves the class definition for instr_trace_t out of the // +// tracer module for readability and code partitioning // +// // +// Includes various enhancements to make the instr_trace_t // +// class more comprehensive // +// // +//////////////////////////////////////////////////////////////////////////////// typedef struct { logic [5:0] addr; diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index ab86e917b..442ed878e 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -1,24 +1,28 @@ -// Copyright (c) 2020 OpenHW Group +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. // You may obtain a copy of the License at // -// https://solderpad.org/licenses/ +// https://solderpad.org/licenses/SHL-2.1/ // -// Unless required by applicable law or agreed to in writing, software +// Unless required by applicable law or agreed to in writing, any work // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// CV32E40P RVFI interface -// -// Contributors: Davide Schiavone, OpenHW Group -// Halfdan Bechmann, Silicon Labs -// Yoann Pruvost, Dolphin Design +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Davide Schiavone, OpenHW Group // +// Halfdan Bechmann, Silicon Labs // +// Yoann Pruvost, Dolphin Design // +// // +// Description: CV32E40P RVFI interface // +// // +//////////////////////////////////////////////////////////////////////////////////// `include "cv32e40p_rvfi_pkg.sv" diff --git a/bhv/cv32e40p_rvfi_trace.sv b/bhv/cv32e40p_rvfi_trace.sv index 417f562a2..c4a595c62 100644 --- a/bhv/cv32e40p_rvfi_trace.sv +++ b/bhv/cv32e40p_rvfi_trace.sv @@ -1,23 +1,27 @@ -// Copyright (c) 2020 OpenHW Group +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. // You may obtain a copy of the License at // -// https://solderpad.org/licenses/ +// https://solderpad.org/licenses/SHL-2.1/ // -// Unless required by applicable law or agreed to in writing, software +// Unless required by applicable law or agreed to in writing, any work // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// CV32E40P RVFI interface -// -// Contributors: Halfdan Bechmann, Silicon Labs -// Yoann Pruvost, Dolphin Design +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Halfdan Bechmann, Silicon Labs // +// Yoann Pruvost, Dolphin Design // +// // +// Description: CV32E40P RVFI tracer // +// // +//////////////////////////////////////////////////////////////////////////////////// module cv32e40p_rvfi_trace import cv32e40p_pkg::*; diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 1716c8c6c..887c403fd 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -1,23 +1,27 @@ -// Copyright (c) 2020 OpenHW Group +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. // You may obtain a copy of the License at // -// https://solderpad.org/licenses/ +// https://solderpad.org/licenses/SHL-2.1/ // -// Unless required by applicable law or agreed to in writing, software +// Unless required by applicable law or agreed to in writing, any work // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// Wrapper for a cv32e40p, containing cv32e40p_top, and rvfi_tracer -// -// Contributors: Davide Schiavone, OpenHW Group -// Yoann Pruvost, Dolphin Design +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Davide Schiavone, OpenHW Group // +// Yoann Pruvost, Dolphin Design // +// // +// Description: Test-bench wrapper for cv32e40p_top, tracer and and rvfi_tracer // +// // +//////////////////////////////////////////////////////////////////////////////////// `ifdef CV32E40P_ASSERT_ON `include "cv32e40p_prefetch_controller_sva.sv" diff --git a/bhv/cv32e40p_tracer.sv b/bhv/cv32e40p_tracer.sv index 8208f2e61..845875778 100644 --- a/bhv/cv32e40p_tracer.sv +++ b/bhv/cv32e40p_tracer.sv @@ -1,24 +1,26 @@ -// Copyright (c) 2020 OpenHW Group -// -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://solderpad.org/licenses/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - -// Traces the executed instructions -// -// Contributors: Andreas Traber, ETHZ -// Davide Schiavone, OpenHW Group -// Pascal Gouedo, Dolphin Design +// 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: Andreas Traber - atraber@iis.ee.ethz.ch // +// // +// Additional contributions by: // +// Davide Schiavone - pschiavo@iis.ee.ethz.ch // +// // +// Design Name: RISC-V Tracer // +// Project Name: RI5CY // +// Language: SystemVerilog // +// // +// Description: Traces the executed instructions // +// // +//////////////////////////////////////////////////////////////////////////////// `ifdef CV32E40P_TRACE_EXECUTION diff --git a/bhv/include/cv32e40p_rvfi_pkg.sv b/bhv/include/cv32e40p_rvfi_pkg.sv index 688795690..f4044e6ec 100644 --- a/bhv/include/cv32e40p_rvfi_pkg.sv +++ b/bhv/include/cv32e40p_rvfi_pkg.sv @@ -1,24 +1,28 @@ -// Copyright (c) 2020 OpenHW Group +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. // You may obtain a copy of the License at // -// https://solderpad.org/licenses/ +// https://solderpad.org/licenses/SHL-2.1/ // -// Unless required by applicable law or agreed to in writing, software +// Unless required by applicable law or agreed to in writing, any work // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// Includes to print info about the RVFI output -// -// Contributors: Davide Schiavone, OpenHW Group -// Halfdan Bechmann, Silicon Labs -// Yoann Pruvost, Dolphin Design +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Davide Schiavone, OpenHW Group // +// Halfdan Bechmann, Silicon Labs // +// Yoann Pruvost, Dolphin Design // +// // +// Description: Package to print info on RVFI interface // +// // +//////////////////////////////////////////////////////////////////////////////////// package cv32e40p_rvfi_pkg; import cv32e40p_pkg::*; diff --git a/bhv/include/cv32e40p_tracer_pkg.sv b/bhv/include/cv32e40p_tracer_pkg.sv index d026c4aad..b9ce57df4 100644 --- a/bhv/include/cv32e40p_tracer_pkg.sv +++ b/bhv/include/cv32e40p_tracer_pkg.sv @@ -1,23 +1,13 @@ -// Copyright (c) 2020 OpenHW Group -// -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://solderpad.org/licenses/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - -// Tracer package -// -// Contributors: Steve Richmond, Silicon Labs -// Pascal Gouedo, Dolphin Design +// 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. + package cv32e40p_tracer_pkg; import cv32e40p_pkg::*; diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index bf73c6dc4..8d56a6e1b 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -1,5 +1,26 @@ -// Copyright 2022 Dolphin Design -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 +// Copyright 2024 OpenHW Group and Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Macros and Functions to print information on RVFI interface // +// // +//////////////////////////////////////////////////////////////////////////////////// `define DEFINE_CSR(CSR_NAME) \ logic ``CSR_NAME``_we; \ diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 88d65d0b0..47ab01ef4 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -1,27 +1,29 @@ -// Copyright (c) 2023 OpenHW Group +// Copyright 2024 OpenHW Group and Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. // You may obtain a copy of the License at // -// https://solderpad.org/licenses/ +// https://solderpad.org/licenses/SHL-2.1/ // -// Unless required by applicable law or agreed to in writing, software +// Unless required by applicable law or agreed to in writing, any work // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 -// CV32E40P -// -// Contributors: Yoann Pruvost, Dolphin Design +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Structures, Functions and Task used to store all information // +// coming from the core pipeline at every posedge. // +// Those information will then be processed by RVFI. // +// // +//////////////////////////////////////////////////////////////////////////////////// -/* - * This struct is used to store all information comming from the core at every posedge - * The information will then be processed - */ typedef struct { logic is_decoding; logic is_illegal; diff --git a/rtl/cv32e40p_fp_wrapper.sv b/rtl/cv32e40p_fp_wrapper.sv index 62ec46c2f..839d58aae 100644 --- a/rtl/cv32e40p_fp_wrapper.sv +++ b/rtl/cv32e40p_fp_wrapper.sv @@ -14,7 +14,7 @@ module cv32e40p_fp_wrapper import cv32e40p_apu_core_pkg::*; #( - parameter FPU_ADDMUL_LAT = 0, // Floating-Point ADDition/MULtiplication computing lane pipeline registers number + parameter FPU_ADDMUL_LAT = 0, // Floating-Point ADDition/MULtiplication computing lane pipeline registers number parameter FPU_OTHERS_LAT = 0 // Floating-Point COMParison/CONVersion computing lanes pipeline registers number ) ( // Clock and Reset diff --git a/rtl/cv32e40p_top.sv b/rtl/cv32e40p_top.sv index 7ddd2d5a2..3861d181a 100644 --- a/rtl/cv32e40p_top.sv +++ b/rtl/cv32e40p_top.sv @@ -1,15 +1,27 @@ -// 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. - -// Top file instantiating a CV32E40P core and an optional FPU -// Contributor: Davide Schiavone +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Pascal Gouedo, Dolphin Design // +// // +// Description: Top level module of CV32E40P instantiating the Core and // +// an optional CVFPU with its clock gating cell. // +// // +///////////////////////////////////////////////////////////////////////////// module cv32e40p_top #( parameter COREV_PULP = 0, // PULP ISA Extension (incl. custom CSRs and hardware loop, excl. cv.elw) From 0d56c5673f485ac1549f580af6a6d3d3ce4b5a67 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 21 Mar 2024 14:45:43 +0100 Subject: [PATCH 24/69] Corrected mis-leading variable name. Signed-off-by: Pascal Gouedo --- scripts/slec/synopsys/lec.tcl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/slec/synopsys/lec.tcl b/scripts/slec/synopsys/lec.tcl index b8683fce5..e4365fc20 100644 --- a/scripts/slec/synopsys/lec.tcl +++ b/scripts/slec/synopsys/lec.tcl @@ -22,14 +22,14 @@ set pulp_cfg $::env(pulp_cfg) set fpu_cfg $::env(fpu_cfg) set zfinx_cfg $::env(zfinx_cfg) -set top_impl_name cv32e40p_core_COREV_PULP${pulp_cfg}_FPU${fpu_cfg}_ZFINX${zfinx_cfg} +set core_impl_name cv32e40p_core_COREV_PULP${pulp_cfg}_FPU${fpu_cfg}_ZFINX${zfinx_cfg} if {"$version" == "v1"} { set golden_parameter_list "PULP_XPULP = 0, FPU = 0, PULP_ZFINX = 0" - set top_ref_name cv32e40p_core_PULP_XPULP0_FPU0_PULP_ZFINX0 + set core_ref_name cv32e40p_core_PULP_XPULP0_FPU0_PULP_ZFINX0 } else { set golden_parameter_list "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg" - set top_ref_name $top_impl_name + set core_ref_name $core_impl_name } read_sverilog -container r -libname WORK -12 -f golden.src @@ -41,14 +41,14 @@ set_top i:/WORK/$top_module -parameter "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, match > $summary_log.match.rpt if {"$top_module" == "cv32e40p_core"} { - set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_req_o - set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_operands_o* - set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_op_o* - set_dont_verify_point -type port r:/WORK/$top_ref_name/apu_flags_o* - set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_req_o - set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_operands_o* - set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_op_o* - set_dont_verify_point -type port i:/WORK/$top_impl_name/apu_flags_o* + set_dont_verify_point -type port r:/WORK/$core_ref_name/apu_req_o + set_dont_verify_point -type port r:/WORK/$core_ref_name/apu_operands_o* + set_dont_verify_point -type port r:/WORK/$core_ref_name/apu_op_o* + set_dont_verify_point -type port r:/WORK/$core_ref_name/apu_flags_o* + set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_req_o + set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_operands_o* + set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_op_o* + set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_flags_o* } verify > $summary_log From 3654122e07e8a30a6c062e897a04d3184de8dc82 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 21 Mar 2024 14:47:59 +0100 Subject: [PATCH 25/69] Updated gitignore Signed-off-by: Pascal Gouedo --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 66eb251ac..582002c7b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ revised.src cadence_conformal synopsys_formality questa_autocheck +slec/reports From 9420d7d53378ae5984e115b6f161d97d10c675af Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 21 Mar 2024 14:14:08 +0100 Subject: [PATCH 26/69] Issue #965 correction Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_core.sv | 12 ++++++------ rtl/cv32e40p_top.sv | 14 ++++++++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/rtl/cv32e40p_core.sv b/rtl/cv32e40p_core.sv index d72fae9e4..4275cf9c1 100644 --- a/rtl/cv32e40p_core.sv +++ b/rtl/cv32e40p_core.sv @@ -70,7 +70,8 @@ module cv32e40p_core output logic [31:0] data_wdata_o, input logic [31:0] data_rdata_i, - // apu-interconnect + // CVFPU interface + output logic apu_busy_o, // handshake signals output logic apu_req_o, input logic apu_gnt_i, @@ -163,7 +164,6 @@ module cv32e40p_core logic ctrl_busy; logic if_busy; logic lsu_busy; - logic apu_busy; logic [31:0] pc_ex; // PC of last executed branch or cv.elw @@ -399,7 +399,7 @@ module cv32e40p_core .if_busy_i (if_busy), .ctrl_busy_i(ctrl_busy), .lsu_busy_i (lsu_busy), - .apu_busy_i (apu_busy), + .apu_busy_i (apu_busy_o), // PULP cluster .pulp_clock_en_i (pulp_clock_en_i), @@ -634,7 +634,7 @@ module cv32e40p_core .apu_write_regs_valid_o (apu_write_regs_valid), .apu_write_dep_i (apu_write_dep), .apu_perf_dep_o (perf_apu_dep), - .apu_busy_i (apu_busy), + .apu_busy_i (apu_busy_o), // CSR ID/EX .csr_access_ex_o (csr_access_ex), @@ -818,9 +818,9 @@ module cv32e40p_core .apu_perf_cont_o(perf_apu_cont), .apu_perf_wb_o (perf_apu_wb), .apu_ready_wb_o (apu_ready_wb), - .apu_busy_o (apu_busy), + .apu_busy_o (apu_busy_o), - // apu-interconnect + // CVFPU interface // handshake signals .apu_req_o (apu_req_o), .apu_gnt_i (apu_gnt_i), diff --git a/rtl/cv32e40p_top.sv b/rtl/cv32e40p_top.sv index 7ddd2d5a2..4dea26a53 100644 --- a/rtl/cv32e40p_top.sv +++ b/rtl/cv32e40p_top.sv @@ -70,7 +70,7 @@ module cv32e40p_top #( import cv32e40p_apu_core_pkg::*; // Core to FPU - logic clk; + logic apu_busy; logic apu_req; logic [ APU_NARGS_CPU-1:0][31:0] apu_operands; logic [ APU_WOP_CPU-1:0] apu_op; @@ -82,6 +82,8 @@ module cv32e40p_top #( logic [ 31:0] apu_rdata; logic [APU_NUSFLAGS_CPU-1:0] apu_rflags; + logic apu_clk_en, apu_clk; + // Instantiate the Core cv32e40p_core #( .COREV_PULP (COREV_PULP), @@ -119,6 +121,7 @@ module cv32e40p_top #( .data_wdata_o (data_wdata_o), .data_rdata_i (data_rdata_i), + .apu_busy_o (apu_busy), .apu_req_o (apu_req), .apu_gnt_i (apu_gnt), .apu_operands_o(apu_operands), @@ -143,12 +146,15 @@ module cv32e40p_top #( generate if (FPU) begin : fpu_gen + + assign apu_clk_en = apu_req | apu_busy; + // FPU clock gate cv32e40p_clock_gate core_clock_gate_i ( .clk_i (clk_i), - .en_i (!core_sleep_o), + .en_i (apu_clk_en), .scan_cg_en_i(scan_cg_en_i), - .clk_o (clk) + .clk_o (apu_clk) ); // Instantiate the FPU wrapper @@ -156,7 +162,7 @@ module cv32e40p_top #( .FPU_ADDMUL_LAT(FPU_ADDMUL_LAT), .FPU_OTHERS_LAT(FPU_OTHERS_LAT) ) fp_wrapper_i ( - .clk_i (clk), + .clk_i (apu_clk), .rst_ni (rst_ni), .apu_req_i (apu_req), .apu_gnt_o (apu_gnt), From d52b7333e3bcec7a5ab142053d04b80c7be813d3 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 25 Mar 2024 11:42:58 +0100 Subject: [PATCH 27/69] Slight update to allow many lec parallel runs. Signed-off-by: Pascal Gouedo --- scripts/slec/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/slec/run.sh b/scripts/slec/run.sh index 23a51bab5..f1579cbb2 100755 --- a/scripts/slec/run.sh +++ b/scripts/slec/run.sh @@ -175,7 +175,7 @@ echo $var_golden_rtl > ${GOLDEN_FLIST} print_log "Generating REVISED flist in path: ${REVISED_FLIST}" echo $var_revised_rtl > ${REVISED_FLIST} -export report_dir=$(readlink -f $(dirname "${BASH_SOURCE[0]}"))/reports/$(date +%Y-%m-%d)/${target_tool} +export report_dir=$(readlink -f $(dirname "${BASH_SOURCE[0]}"))/reports/${target_tool}/$(date +%Y-%m-%d-%Hh%Mm%Ss) if [[ -d ${report_dir} ]]; then rm -rf ${report_dir} From 76dbe3f198a5bbe5fbb9bf1a72e2f6210fa01670 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 25 Mar 2024 11:58:49 +0100 Subject: [PATCH 28/69] Issue #756 correction. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_register_file_latch.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtl/cv32e40p_register_file_latch.sv b/rtl/cv32e40p_register_file_latch.sv index d8e2f4aa0..57383e6a5 100644 --- a/rtl/cv32e40p_register_file_latch.sv +++ b/rtl/cv32e40p_register_file_latch.sv @@ -172,8 +172,8 @@ module cv32e40p_register_file #( mem[0] = '0; for (k = 1; k < NUM_WORDS; k++) begin : w_WordIter - if (~rst_n) mem[k] = '0; - else if (mem_clocks[k] == 1'b1) mem[k] = waddr_onehot_b_q[k] ? wdata_b_q : wdata_a_q; + if (~rst_n) mem[k] <= '0; + else if (mem_clocks[k] == 1'b1) mem[k] <= waddr_onehot_b_q[k] ? wdata_b_q : wdata_a_q; end end @@ -182,9 +182,9 @@ module cv32e40p_register_file #( always_latch begin : latch_wdata_fp if (FPU == 1) begin for (l = 0; l < NUM_FP_WORDS; l++) begin : w_WordIter - if (~rst_n) mem_fp[l] = '0; + if (~rst_n) mem_fp[l] <= '0; else if (mem_clocks[l+NUM_WORDS] == 1'b1) - mem_fp[l] = waddr_onehot_b_q[l+NUM_WORDS] ? wdata_b_q : wdata_a_q; + mem_fp[l] <= waddr_onehot_b_q[l+NUM_WORDS] ? wdata_b_q : wdata_a_q; end end end From 5c9a14df76dc9087bd96f208821bdd349f4bd7e9 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 25 Mar 2024 12:21:38 +0100 Subject: [PATCH 29/69] Correction for issue #967 and https://github.com/openhwgroup/cv32e40p/commit/1a58c7b7666ac693d936c45b4ed9dc0d762e1bf6#commitcomment-138230716 Signed-off-by: Pascal Gouedo --- docs/source/instruction_set_extensions.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index 625f48247..b669e2836 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -783,21 +783,21 @@ General ALU operations | | | | | Note: If Is2 is equal to 0, (2^(Is2-1)-1) is equivalent to 0. | +-------------------------------------------+------------------------------------------------------------------------+ - | **cv.clipr rD, rs1, rs2** | if rs1 <= -(rs2+1), rD = -(rs2+1), | + | **cv.clipr rD, rs1, rs2** | rs2' = rs2 & 0x7FFFFFFF | | | | - | | else if rs1 >=rs2, rD = rs2, | + | | if rs1 <= -(rs2'+1), rD = -(rs2'+1), | | | | - | | else rD = rs1 | + | | else if rs1 >=rs2', rD = rs2', | | | | - | | Note: rs2 is unsigned and must be in the range (0x0-0x7FFFFFFF). | + | | else rD = rs1 | +-------------------------------------------+------------------------------------------------------------------------+ - | **cv.clipur rD, rs1, rs2** | if rs1 <= 0, rD = 0, | + | **cv.clipur rD, rs1, rs2** | rs2' = rs2 & 0x7FFFFFFF | | | | - | | else if rs1 >= rs2, rD = rs2, | + | | if rs1 <= 0, rD = 0, | | | | - | | else rD = rs1 | + | | else if rs1 >= rs2', rD = rs2', | | | | - | | Note: rs2 is unsigned and must be in the range (0x0-0x7FFFFFFF). | + | | else rD = rs1 | +-------------------------------------------+------------------------------------------------------------------------+ | **cv.addN rD, rs1, rs2, Is3** | rD = (rs1 + rs2) >>> Is3 | | | | From 7a843ea6dd14555d918f7159264afd232316713f Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 25 Mar 2024 12:27:49 +0100 Subject: [PATCH 30/69] Alignement to PR #970 for User Manual update of clipr/clipur behavior. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_id_stage.sv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index 93bb13803..da8cff3f5 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -1516,7 +1516,11 @@ module cv32e40p_id_stage if (alu_en) begin alu_operator_ex_o <= alu_operator; alu_operand_a_ex_o <= alu_operand_a; - alu_operand_b_ex_o <= alu_operand_b; + if (alu_op_b_mux_sel == OP_B_REGB_OR_FWD && (alu_operator == ALU_CLIP || alu_operator == ALU_CLIPU)) begin + alu_operand_b_ex_o <= {1'b0, alu_operand_b[30:0]}; + end else begin + alu_operand_b_ex_o <= alu_operand_b; + end alu_operand_c_ex_o <= alu_operand_c; bmask_a_ex_o <= bmask_a_id; bmask_b_ex_o <= bmask_b_id; From 3bbcbe9e2f339c9640e9377660745992e78f7d22 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 25 Mar 2024 18:19:19 +0100 Subject: [PATCH 31/69] verible Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_id_stage.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index da8cff3f5..f323cbe5f 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -1514,8 +1514,8 @@ module cv32e40p_id_stage if (id_valid_o) begin // unstall the whole pipeline alu_en_ex_o <= alu_en; if (alu_en) begin - alu_operator_ex_o <= alu_operator; - alu_operand_a_ex_o <= alu_operand_a; + alu_operator_ex_o <= alu_operator; + alu_operand_a_ex_o <= alu_operand_a; if (alu_op_b_mux_sel == OP_B_REGB_OR_FWD && (alu_operator == ALU_CLIP || alu_operator == ALU_CLIPU)) begin alu_operand_b_ex_o <= {1'b0, alu_operand_b[30:0]}; end else begin From 8f983684c488bf3bba95f7432f4097fbd22b9934 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 26 Mar 2024 11:44:35 +0800 Subject: [PATCH 32/69] RVFI - Correcting issue on trace log generation from rvfi --- bhv/cv32e40p_instr_trace.svh | 34 ++++++++++++- bhv/cv32e40p_rvfi.sv | 32 +++++++++--- bhv/cv32e40p_rvfi_trace.sv | 94 ++++++++++++++++++++++-------------- bhv/cv32e40p_tb_wrapper.sv | 5 ++ bhv/cv32e40p_tracer.sv | 3 +- bhv/insn_trace.sv | 20 +++++++- 6 files changed, 142 insertions(+), 46 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index a89ed4e45..9b1bd3b7f 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -35,7 +35,10 @@ typedef struct { class instr_trace_t; time simtime; + time stoptime; + bit external_time; int cycles; + int stopcycles; logic [31:0] pc; logic [31:0] instr; bit compressed; @@ -56,10 +59,15 @@ class instr_trace_t; regs_read = {}; regs_write = {}; mem_access = {}; + external_time = 0; + stoptime = 0; + stopcycles = 0; endfunction function void init(int unsigned cycles, bit [31:0] pc, bit compressed, bit [31:0] instr); - this.simtime = $time; + if(!this.external_time) begin + this.simtime = $time; + end this.cycles = cycles; this.pc = pc; this.compressed = compressed; @@ -308,7 +316,23 @@ class instr_trace_t; begin string insn_str; // Accumulate writes into a single string to enable single $fwrite - insn_str = $sformatf("%t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + if(simtime < 100ns) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 1us) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 10us) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 100us) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 1ms) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 10ms) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 100ms) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else begin + insn_str = $sformatf("%t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end foreach (regs_write[i]) begin if (regs_write[i].addr != 0) @@ -330,6 +354,12 @@ class instr_trace_t; insn_str = $sformatf("%s PA:%08x", insn_str, mem_acc.addr); end + casex (instr) + INSTR_FDIV: insn_str = $sformatf("%s %15d %t", insn_str, stopcycles, stoptime); + INSTR_FSQRT:insn_str = $sformatf("%s %15d %t", insn_str, stopcycles, stoptime); + default: ; + endcase + $fwrite(f, "%s\n", insn_str); end endfunction diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index ab86e917b..607f889ab 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -328,6 +328,10 @@ module cv32e40p_rvfi // the convention of RISC-V Formal Interface Specification. output logic [ 0:0] rvfi_valid, output logic [63:0] rvfi_order, + output integer rvfi_start_cycle, + output time rvfi_start_time, + output integer rvfi_stop_cycle, + output time rvfi_stop_time, output logic [31:0] rvfi_insn, output rvfi_trap_t rvfi_trap, output logic [ 0:0] rvfi_halt, @@ -347,6 +351,7 @@ module cv32e40p_rvfi output logic rvfi_frd_wvalid [1:0], output logic [ 4:0] rvfi_frd_addr [1:0], output logic [31:0] rvfi_frd_wdata [1:0], + output logic rvfi_2_rd, output logic [ 4:0] rvfi_rs1_addr, output logic [ 4:0] rvfi_rs2_addr, output logic [ 4:0] rvfi_rs3_addr, @@ -367,8 +372,8 @@ module cv32e40p_rvfi output logic [31:0] rvfi_pc_wdata, output logic [31:0] rvfi_mem_addr, - output logic [ 3:0] rvfi_mem_rmask, - output logic [ 3:0] rvfi_mem_wmask, + output logic [31:0] rvfi_mem_rmask, + output logic [31:0] rvfi_mem_wmask, output logic [31:0] rvfi_mem_rdata, output logic [31:0] rvfi_mem_wdata, @@ -619,6 +624,13 @@ module cv32e40p_rvfi bit clk_i_d; assign #0.01 clk_i_d = clk_i; + integer cycles; + // cycle counter + always_ff @(posedge clk_i_d, negedge rst_ni) begin + if (rst_ni == 1'b0) cycles <= 0; + else cycles <= cycles + 1; + end + logic pc_mux_debug; logic pc_mux_dret; logic pc_mux_exception; @@ -749,6 +761,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end rvfi_order = new_rvfi_trace.m_order; + rvfi_start_cycle = new_rvfi_trace.m_start_cycle; + rvfi_start_time = new_rvfi_trace.m_start_time; + rvfi_stop_cycle = new_rvfi_trace.m_stop_cycle; + rvfi_stop_time = new_rvfi_trace.m_stop_time; rvfi_pc_rdata = new_rvfi_trace.m_pc_rdata; rvfi_insn = new_rvfi_trace.m_insn; @@ -803,6 +819,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; rvfi_frd_addr[1] = '0; rvfi_frd_wdata[1] = '0; + rvfi_2_rd = new_rvfi_trace.m_2_rd_insn; if (new_rvfi_trace.m_rd_addr[0][5] == 1'b0) begin rvfi_rd_addr[0] = new_rvfi_trace.m_rd_addr[0][4:0]; rvfi_rd_wdata[0] = new_rvfi_trace.m_rd_wdata[0]; @@ -1364,6 +1381,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end csr_to_apu_resp(); + + trace_apu_resp.m_stop_cycle = cycles; + trace_apu_resp.m_stop_time = $time; send_rvfi(trace_apu_resp); ->e_send_rvfi_trace_apu_resp; end @@ -1398,10 +1418,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; function logic [31:0] be_to_mask(logic [3:0] be); logic [31:0] mask; - mask[7:0] = be[0] ? 8'hFF : 8'h00; - mask[15:8] = be[0] ? 8'hFF : 8'h00; - mask[23:16] = be[0] ? 8'hFF : 8'h00; - mask[31:24] = be[0] ? 8'hFF : 8'h00; + mask[7:0] = (be[0] == 1'b1) ? 8'hFF : 8'h00; + mask[15:8] = (be[1] == 1'b1) ? 8'hFF : 8'h00; + mask[23:16] = (be[2] == 1'b1) ? 8'hFF : 8'h00; + mask[31:24] = (be[3] == 1'b1) ? 8'hFF : 8'h00; be_to_mask = mask; return mask; diff --git a/bhv/cv32e40p_rvfi_trace.sv b/bhv/cv32e40p_rvfi_trace.sv index 417f562a2..a7b2c7b22 100644 --- a/bhv/cv32e40p_rvfi_trace.sv +++ b/bhv/cv32e40p_rvfi_trace.sv @@ -32,9 +32,13 @@ module cv32e40p_rvfi_trace input logic [31:0] imm_s3_type, - input logic rvfi_valid, - input logic [31:0] rvfi_insn, - input logic [31:0] rvfi_pc_rdata, + input logic rvfi_valid, + input logic [31:0] rvfi_insn, + input integer rvfi_start_cycle, + input time rvfi_start_time, + input integer rvfi_stop_cycle, + input time rvfi_stop_time, + input logic [31:0] rvfi_pc_rdata, input logic [ 4:0] rvfi_rd_addr [1:0], input logic [31:0] rvfi_rd_wdata[1:0], @@ -42,6 +46,7 @@ module cv32e40p_rvfi_trace input logic rvfi_frd_wvalid[1:0], input logic [ 4:0] rvfi_frd_addr [1:0], input logic [31:0] rvfi_frd_wdata [1:0], + input logic rvfi_2_rd, input logic [ 4:0] rvfi_rs1_addr, input logic [ 4:0] rvfi_rs2_addr, @@ -61,8 +66,8 @@ module cv32e40p_rvfi_trace input logic [31:0] rvfi_frs3_rdata, input logic [31:0] rvfi_mem_addr, - input logic [ 3:0] rvfi_mem_rmask, - input logic [ 3:0] rvfi_mem_wmask, + input logic [31:0] rvfi_mem_rmask, + input logic [31:0] rvfi_mem_wmask, input logic [31:0] rvfi_mem_rdata, input logic [31:0] rvfi_mem_wdata ); @@ -74,7 +79,7 @@ module cv32e40p_rvfi_trace integer f; //file pointer string fn; - integer cycles; + // integer cycles; string info_tag; logic is_compressed; @@ -125,7 +130,13 @@ module cv32e40p_rvfi_trace rs3_value = rvfi_rs3_rdata; end - if (rvfi_frd_wvalid[0]) begin + if (rvfi_2_rd) begin + if (rvfi_frd_wvalid[1]) begin + rd = {1'b1, rvfi_frd_addr[1]}; + end else begin + rd = {1'b0, rvfi_rd_addr[1]}; + end + end else if (rvfi_frd_wvalid[0]) begin rd = {1'b1, rvfi_frd_addr[0]}; end else begin rd = {1'b0, rvfi_rd_addr[0]}; @@ -134,57 +145,68 @@ module cv32e40p_rvfi_trace assign rs4 = rs3; - assign imm_i_type = {{20{rvfi_insn[31]}}, rvfi_insn[31:20]}; - assign imm_iz_type = {20'b0, rvfi_insn[31:20]}; - assign imm_s_type = {{20{rvfi_insn[31]}}, rvfi_insn[31:25], rvfi_insn[11:7]}; + cv32e40p_compressed_decoder #( + .FPU(FPU) + ) rvfi_trace_decompress_i ( + .instr_i(rvfi_insn), + .instr_o(decomp_insn), + .is_compressed_o(is_compressed) + ); + + assign imm_i_type = {{20{decomp_insn[31]}}, decomp_insn[31:20]}; + assign imm_iz_type = {20'b0, decomp_insn[31:20]}; + assign imm_s_type = {{20{decomp_insn[31]}}, decomp_insn[31:25], decomp_insn[11:7]}; assign imm_sb_type = { - {19{rvfi_insn[31]}}, rvfi_insn[31], rvfi_insn[7], rvfi_insn[30:25], rvfi_insn[11:8], 1'b0 + {19{decomp_insn[31]}}, + decomp_insn[31], + decomp_insn[7], + decomp_insn[30:25], + decomp_insn[11:8], + 1'b0 }; - assign imm_u_type = {rvfi_insn[31:12], 12'b0}; + assign imm_u_type = {decomp_insn[31:12], 12'b0}; assign imm_uj_type = { - {12{rvfi_insn[31]}}, rvfi_insn[19:12], rvfi_insn[20], rvfi_insn[30:21], 1'b0 + {12{decomp_insn[31]}}, decomp_insn[19:12], decomp_insn[20], decomp_insn[30:21], 1'b0 }; - assign imm_z_type = '0; //{27'b0, rvfi_insn[REG_S1_MSB:REG_S1_LSB]}; + assign imm_z_type = '0; //{27'b0, decomp_insn[REG_S1_MSB:REG_S1_LSB]}; - assign imm_s2_type = {27'b0, rvfi_insn[24:20]}; + assign imm_s2_type = {27'b0, decomp_insn[24:20]}; assign imm_vs_type = '0; assign imm_vu_type = '0; assign imm_shuffle_type = '0; assign imm_clip_type = '0; - cv32e40p_compressed_decoder #( - .FPU(FPU) - ) rvfi_trace_decompress_i ( - .instr_i(rvfi_insn), - .instr_o(decomp_insn), - .is_compressed_o(is_compressed) - ); - `include "cv32e40p_instr_trace.svh" instr_trace_t trace_retire; function instr_trace_t trace_new_instr(); instr_trace_t trace; trace = new(); - trace.init(.cycles(cycles), .pc(rvfi_pc_rdata), .compressed(is_compressed), + trace.external_time = 1; + trace.simtime = rvfi_start_time - 1ns; + trace.stoptime = rvfi_stop_time; + trace.stopcycles = rvfi_stop_cycle; + trace.init(.cycles(rvfi_start_cycle), .pc(rvfi_pc_rdata), .compressed(is_compressed), .instr(decomp_insn)); return trace; endfunction : trace_new_instr function void apply_reg_write(); foreach (trace_retire.regs_write[i]) begin - if (rvfi_frd_wvalid[0] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[0]})) begin - trace_retire.regs_write[i].value = rvfi_frd_wdata[0]; - end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[0]) begin - trace_retire.regs_write[i].value = rvfi_rd_wdata[0]; - end if (rvfi_frd_wvalid[1] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[1]})) begin trace_retire.regs_write[i].value = rvfi_frd_wdata[1]; end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[1]) begin trace_retire.regs_write[i].value = rvfi_rd_wdata[1]; end end + foreach (trace_retire.regs_write[i]) begin + if (rvfi_frd_wvalid[0] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[0]})) begin + trace_retire.regs_write[i].value = rvfi_frd_wdata[0]; + end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[0]) begin + trace_retire.regs_write[i].value = rvfi_rd_wdata[0]; + end + end endfunction : apply_reg_write function void apply_mem_access(); @@ -202,11 +224,9 @@ instr_trace_t trace_retire; end endfunction : apply_mem_access - // cycle counter - always_ff @(posedge clk_i, negedge rst_ni) begin - if (rst_ni == 1'b0) cycles <= 0; - else cycles <= cycles + 1; - end + string insn_disas; + logic [31:0] insn_pc; + logic [31:0] insn_val; always @(posedge clk_i) begin if (rvfi_valid) begin @@ -214,6 +234,9 @@ instr_trace_t trace_retire; apply_reg_write(); apply_mem_access(); trace_retire.printInstrTrace(); + insn_disas = trace_retire.str; + insn_pc = trace_retire.pc; + insn_val = trace_retire.instr; end end @@ -223,7 +246,8 @@ instr_trace_t trace_retire; $sformat(info_tag, "CORE_TRACER %2d", hart_id_i); $display("[%s] Output filename is: %s", info_tag, fn); f = $fopen(fn, "w"); - $fwrite(f, "Time\tCycle\tPC\tInstr\tDecoded instruction\tRegister and memory contents\n"); + $fwrite(f, + " Time Cycle PC Instr Decoded instruction Register and memory contents Stop cycle Stop time\n"); end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 1716c8c6c..f50b42686 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -455,12 +455,17 @@ module cv32e40p_tb_wrapper .rvfi_valid(rvfi_valid), .rvfi_insn(rvfi_insn), + .rvfi_start_cycle(rvfi_start_cycle), + .rvfi_start_time(rvfi_start_time), + .rvfi_stop_cycle(rvfi_stop_cycle), + .rvfi_stop_time(rvfi_stop_time), .rvfi_pc_rdata(rvfi_pc_rdata), .rvfi_rd_addr(rvfi_rd_addr), .rvfi_rd_wdata(rvfi_rd_wdata), .rvfi_frd_wvalid(rvfi_frd_wvalid), .rvfi_frd_addr(rvfi_frd_addr), .rvfi_frd_wdata(rvfi_frd_wdata), + .rvfi_2_rd(rvfi_2_rd), .rvfi_rs1_addr(rvfi_rs1_addr), .rvfi_rs2_addr(rvfi_rs2_addr), .rvfi_rs3_addr(rvfi_rs3_addr), diff --git a/bhv/cv32e40p_tracer.sv b/bhv/cv32e40p_tracer.sv index 8208f2e61..199482407 100644 --- a/bhv/cv32e40p_tracer.sv +++ b/bhv/cv32e40p_tracer.sv @@ -183,7 +183,8 @@ module cv32e40p_tracer $sformat(info_tag, "CORE_TRACER %2d", hart_id_i); $display("[%s] Output filename is: %s", info_tag, fn); f = $fopen(fn, "w"); - $fwrite(f, "Time\tCycle\tPC\tInstr\tDecoded instruction\tRegister and memory contents\n"); + $fwrite(f, + " Time Cycle PC Instr Decoded instruction Register and memory contents\n"); end //initial begin diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index bf73c6dc4..61048f27f 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -23,6 +23,10 @@ class insn_trace_t; bit m_valid; logic [63:0] m_order; + integer m_start_cycle; + integer m_stop_cycle; + time m_start_time; + time m_stop_time; bit m_skip_order; //next order was used by trap; logic [31:0] m_pc_rdata; logic [31:0] m_insn; @@ -71,9 +75,9 @@ struct { logic [31:0] addr ; - logic [ 3:0] rmask; + logic [31:0] rmask; logic [31:0] rdata; - logic [ 3:0] wmask; + logic [31:0] wmask; logic [31:0] wdata; } m_mem; @@ -162,6 +166,10 @@ function new(); this.m_order = 0; + this.m_start_cycle = 0; + this.m_stop_cycle = 0; + this.m_start_time = 0; + this.m_stop_time = 0; this.m_skip_order = 1'b0; this.m_valid = 1'b0; this.m_move_down_pipe = 1'b0; @@ -899,6 +907,10 @@ this.m_valid = 1'b1; this.m_stage = ID; this.m_order = this.m_order + 64'h1; + this.m_start_cycle = cycles; + this.m_stop_cycle = 0; + this.m_start_time = $time; + this.m_stop_time = 0; if(this.m_skip_order) begin this.m_order = this.m_order + 64'h1; end @@ -976,6 +988,10 @@ this.m_valid = m_source.m_valid; this.m_stage = m_source.m_stage; this.m_order = m_source.m_order; + this.m_start_cycle = m_source.m_start_cycle; + this.m_stop_cycle = m_source.m_stop_cycle; + this.m_start_time = m_source.m_start_time; + this.m_stop_time = m_source.m_stop_time; this.m_pc_rdata = m_source.m_pc_rdata; this.m_insn = m_source.m_insn; this.m_mnemonic = m_source.m_mnemonic; From 252f70c0ae7ab7d82969eb6b88222fab8aa00e72 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 3 Apr 2024 08:25:10 +0200 Subject: [PATCH 33/69] Refined HWLoop instructions list that must be 32-bit aligned. Signed-off-by: Pascal Gouedo --- docs/source/corev_hw_loop.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 2156ec410..71964d2d2 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -51,7 +51,7 @@ Those constraint checks could be done only for each instruction in the hardware The HWLoop constraints are: -- HWLoop start, end and setup instructions addresses must be 32-bit aligned (short or long commands). +- HWLoop starti, endi, setupi and setup instructions addresses must be 32-bit aligned (PC-related instructions). - Start and End addresses of an HWLoop body must be 32-bit aligned. From aa1bac6e3d119372096051252783329f6130b2f2 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 4 Apr 2024 17:44:31 +0200 Subject: [PATCH 34/69] Added new apu_busy_o at cv32e40p_core level. Added fpu latency parameters for v2 lec. Signed-off-by: Pascal Gouedo --- .gitignore | 3 ++- scripts/slec/cadence/lec.tcl | 6 ++++-- scripts/slec/run.sh | 14 ++++++++++++-- scripts/slec/synopsys/lec.tcl | 8 +++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 582002c7b..6c2cd7917 100644 --- a/.gitignore +++ b/.gitignore @@ -19,9 +19,10 @@ TAGS /Bender.lock /Bender.local golden_reference_design +ref_design golden.src revised.src cadence_conformal synopsys_formality questa_autocheck -slec/reports +reports diff --git a/scripts/slec/cadence/lec.tcl b/scripts/slec/cadence/lec.tcl index 7acbfd3a5..e62046b73 100644 --- a/scripts/slec/cadence/lec.tcl +++ b/scripts/slec/cadence/lec.tcl @@ -20,11 +20,12 @@ set version $::env(version) set pulp_cfg $::env(pulp_cfg) set fpu_cfg $::env(fpu_cfg) set zfinx_cfg $::env(zfinx_cfg) +set latency_cfg $::env(latency_cfg) if {"$version" == "v1"} { set golden_parameter_list "-parameter PULP_XPULP 0 -parameter FPU 0 -parameter PULP_ZFINX 0" } else { - set golden_parameter_list "-parameter COREV_PULP $pulp_cfg -parameter FPU $fpu_cfg -parameter ZFINX $zfinx_cfg" + set golden_parameter_list "-parameter COREV_PULP $pulp_cfg -parameter FPU $fpu_cfg -parameter ZFINX $zfinx_cfg -parameter FPU_ADDMUL_LAT $latency_cfg -parameter FPU_OTHERS_LAT $latency_cfg" } read_design -SV09 -replace -noelaborate -golden -File ./golden.src @@ -33,7 +34,7 @@ elaborate_design -golden -root $top_module $golden_parameter_list read_design -SV09 -replace -noelaborate -revised -File ./revised.src -elaborate_design -revised -root $top_module -parameter COREV_PULP $pulp_cfg -parameter FPU $fpu_cfg -parameter ZFINX $zfinx_cfg +elaborate_design -revised -root $top_module -parameter COREV_PULP $pulp_cfg -parameter FPU $fpu_cfg -parameter ZFINX $zfinx_cfg -parameter FPU_ADDMUL_LAT $latency_cfg -parameter FPU_OTHERS_LAT $latency_cfg report_design_data @@ -42,6 +43,7 @@ if {"$top_module" == "cv32e40p_core"} { add_ignored_outputs apu_operands_o* -Both add_ignored_outputs apu_op_o* -Both add_ignored_outputs apu_flags_o* -Both + add_ignored_outputs apu_busy_o -Revised } write_hier_compare_dofile hier_compare_r2r.do -constraint -replace diff --git a/scripts/slec/run.sh b/scripts/slec/run.sh index f1579cbb2..01bb1b126 100755 --- a/scripts/slec/run.sh +++ b/scripts/slec/run.sh @@ -17,9 +17,10 @@ # limitations under the License. usage() { # Function: Print a help message. - echo "Usage: $0 -t {cadence,synopsys,siemens} -p {sec,lec} [-v {v1,v2}] [-x {0,1}] [-f {0,1}] [-z {0,1}]]" 1>&2 + echo "Usage: $0 -t {cadence,synopsys,siemens} -p {sec,lec} [-v {v1,v2}] [-x {0,1}] [-f {0,1}] [-z {0,1}] [-l {0,1,2}]]" 1>&2 echo "For v2 : if f or z is 1 then p must be 1" 1>&2 echo " if z is 1 then f must be 1" 1>&2 + echo " l only 1 or 2 if f is 1" 1>&2 } exit_abnormal() { # Function: Exit with error. @@ -40,8 +41,9 @@ VERSION=v1 PULP_CFG=0 FPU_CFG=0 ZFINX_CFG=0 +LATENCY_CFG=0 -while getopts "t:p:v:x:f:z:" flag +while getopts "t:p:v:x:f:z:l:" flag do case "${flag}" in t) @@ -62,6 +64,9 @@ do z) ZFINX_CFG=${OPTARG} ;; + l) + LATENCY_CFG=${OPTARG} + ;; :) exit_abnormal ;; @@ -104,6 +109,10 @@ if [[ (("${PULP_CFG}" == 0 && ("${FPU_CFG}" == 1 || "${ZFINX_CFG}" == 1)) || ("$ exit_abnormal fi +if [[ ("${FPU_CFG}" == 0 && ("${LATENCY_CFG}" == 1 || "${LATENCY_CFG}" == 2)) ]]; then + exit_abnormal +fi + if [[ "${VERSION}" == "v1" ]]; then REF_BRANCH=cv32e40p_v1.0.0 TOP_MODULE=cv32e40p_core @@ -117,6 +126,7 @@ export version=${VERSION} export pulp_cfg=${PULP_CFG} export fpu_cfg=${FPU_CFG} export zfinx_cfg=${ZFINX_CFG} +export latency_cfg=${LATENCY_CFG} if [ -z "${REF_REPO}" ]; then print_log "Empty REF_REPO env variable" diff --git a/scripts/slec/synopsys/lec.tcl b/scripts/slec/synopsys/lec.tcl index e4365fc20..7d17722c0 100644 --- a/scripts/slec/synopsys/lec.tcl +++ b/scripts/slec/synopsys/lec.tcl @@ -21,14 +21,15 @@ set version $::env(version) set pulp_cfg $::env(pulp_cfg) set fpu_cfg $::env(fpu_cfg) set zfinx_cfg $::env(zfinx_cfg) +set latency_cfg $::env(latency_cfg) -set core_impl_name cv32e40p_core_COREV_PULP${pulp_cfg}_FPU${fpu_cfg}_ZFINX${zfinx_cfg} +set core_impl_name cv32e40p_core_COREV_PULP${pulp_cfg}_FPU${fpu_cfg}_FPU_ADDMUL_LAT${latency_cfg}_FPU_OTHERS_LAT${latency_cfg}_ZFINX${zfinx_cfg} if {"$version" == "v1"} { set golden_parameter_list "PULP_XPULP = 0, FPU = 0, PULP_ZFINX = 0" set core_ref_name cv32e40p_core_PULP_XPULP0_FPU0_PULP_ZFINX0 } else { - set golden_parameter_list "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg" + set golden_parameter_list "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg, FPU_ADDMUL_LAT = $latency_cfg, FPU_OTHERS_LAT = $latency_cfg" set core_ref_name $core_impl_name } @@ -36,7 +37,7 @@ read_sverilog -container r -libname WORK -12 -f golden.src set_top r:/WORK/$top_module -parameter $golden_parameter_list read_sverilog -container i -libname WORK -12 -f revised.src -set_top i:/WORK/$top_module -parameter "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg" +set_top i:/WORK/$top_module -parameter "COREV_PULP = $pulp_cfg, FPU = $fpu_cfg, ZFINX = $zfinx_cfg, FPU_ADDMUL_LAT = $latency_cfg, FPU_OTHERS_LAT = $latency_cfg" match > $summary_log.match.rpt @@ -49,6 +50,7 @@ if {"$top_module" == "cv32e40p_core"} { set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_operands_o* set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_op_o* set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_flags_o* + set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_busy_o } verify > $summary_log From d62800183376040400ecf023e8d1b8eb76d17856 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 5 Apr 2024 12:30:09 +0800 Subject: [PATCH 35/69] Trace log - Adding insn cancell information --- bhv/cv32e40p_instr_trace.svh | 17 +++++++++-------- bhv/cv32e40p_rvfi_trace.sv | 5 ++++- bhv/cv32e40p_tb_wrapper.sv | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index 321ac2096..491ed76af 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -55,6 +55,7 @@ class instr_trace_t; int stopcycles; logic [31:0] pc; logic [31:0] instr; + string ctx; //Used to add context in the trace log file (Canceled, debug, interrput,....) bit compressed; bit wb_bypass; bit misaligned; @@ -331,21 +332,21 @@ class instr_trace_t; string insn_str; // Accumulate writes into a single string to enable single $fwrite if(simtime < 100ns) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else if (simtime < 1us) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else if (simtime < 10us) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else if (simtime < 100us) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else if (simtime < 1ms) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else if (simtime < 10ms) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else if (simtime < 100ms) begin - insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf(" %t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end else begin - insn_str = $sformatf("%t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + insn_str = $sformatf("%t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); end foreach (regs_write[i]) begin diff --git a/bhv/cv32e40p_rvfi_trace.sv b/bhv/cv32e40p_rvfi_trace.sv index ba3030803..bcebddf1a 100644 --- a/bhv/cv32e40p_rvfi_trace.sv +++ b/bhv/cv32e40p_rvfi_trace.sv @@ -25,6 +25,7 @@ module cv32e40p_rvfi_trace import cv32e40p_pkg::*; + import cv32e40p_rvfi_pkg::*; #( parameter FPU = 0, parameter ZFINX = 0 @@ -43,6 +44,7 @@ module cv32e40p_rvfi_trace input integer rvfi_stop_cycle, input time rvfi_stop_time, input logic [31:0] rvfi_pc_rdata, + input rvfi_trap_t rvfi_trap, input logic [ 4:0] rvfi_rd_addr [1:0], input logic [31:0] rvfi_rd_wdata[1:0], @@ -191,6 +193,7 @@ instr_trace_t trace_retire; trace.simtime = rvfi_start_time - 1ns; trace.stoptime = rvfi_stop_time; trace.stopcycles = rvfi_stop_cycle; + trace.ctx = (rvfi_trap.trap) ? "(C)" : ""; trace.init(.cycles(rvfi_start_cycle), .pc(rvfi_pc_rdata), .compressed(is_compressed), .instr(decomp_insn)); return trace; @@ -251,7 +254,7 @@ instr_trace_t trace_retire; $display("[%s] Output filename is: %s", info_tag, fn); f = $fopen(fn, "w"); $fwrite(f, - " Time Cycle PC Instr Decoded instruction Register and memory contents Stop cycle Stop time\n"); + " Time Cycle PC Instr Ctx Decoded instruction Register and memory contents Stop cycle Stop time\n"); end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index f8556b893..4d219fc3f 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -464,6 +464,7 @@ module cv32e40p_tb_wrapper .rvfi_stop_cycle(rvfi_stop_cycle), .rvfi_stop_time(rvfi_stop_time), .rvfi_pc_rdata(rvfi_pc_rdata), + .rvfi_trap(rvfi_trap), .rvfi_rd_addr(rvfi_rd_addr), .rvfi_rd_wdata(rvfi_rd_wdata), .rvfi_frd_wvalid(rvfi_frd_wvalid), From 12e83d7d2381643485d7619de7eb2bcfd3bab174 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 5 Apr 2024 12:31:41 +0800 Subject: [PATCH 36/69] Trace log - Updating post increment insn print to match user manual --- bhv/cv32e40p_instr_trace.svh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index 491ed76af..5075e600e 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -632,14 +632,14 @@ class instr_trace_t; // immediate post-incremented load regs_read.push_back('{rs1, rs1_value, 0}); regs_write.push_back('{rs1, 'x, 0}); - str = $sformatf("cv.%-13s %s, %0d(x%0d!)", mnemonic, regAddrToStr(rd), $signed(imm_i_type), rs1); + str = $sformatf("cv.%-13s %s, (x%0d), %0d", mnemonic, regAddrToStr(rd), rs1, $signed(imm_i_type)); end else if (instr[6:0] == OPCODE_CUSTOM_1) begin if (instr[27] == 1'b0) begin // reg-reg post-incremented load regs_read.push_back('{rs2, rs2_value, 0}); regs_read.push_back('{rs1, rs1_value, 0}); regs_write.push_back('{rs1, 'x, 0}); - str = $sformatf("cv.%-13s %s, %s(x%0d!)", mnemonic, regAddrToStr(rd), regAddrToStr(rs2), rs1); + str = $sformatf("cv.%-13s %s, (x%0d), %s", mnemonic, regAddrToStr(rd), rs1, regAddrToStr(rs2)); end else begin // reg-reg indexed load regs_read.push_back('{rs2, rs2_value, 0}); @@ -682,7 +682,7 @@ class instr_trace_t; regs_read.push_back('{rs2, rs2_value, 0}); regs_read.push_back('{rs1, rs1_value, 0}); regs_write.push_back('{rs1, 'x, 0}); - str = $sformatf("cv.%-14s %s, %0d(x%0d!)", mnemonic, regAddrToStr(rs2), $signed(imm_s_type), rs1); + str = $sformatf("cv.%-14s %s, (x%0d), %0d", mnemonic, regAddrToStr(rs2), rs1, $signed(imm_s_type)); end else if (instr[31:28] == 4'b0010) begin if (instr[27] == 1'b0) begin // reg-reg post-incremented store @@ -690,7 +690,7 @@ class instr_trace_t; regs_read.push_back('{rs3, rs3_value, 0}); regs_read.push_back('{rs1, rs1_value, 0}); regs_write.push_back('{rs1, 'x, 0}); - str = $sformatf("cv.%-13s %s, %s(x%0d!)", mnemonic, regAddrToStr(rs2), regAddrToStr(rs3), rs1); + str = $sformatf("cv.%-13s %s, (x%0d), %s", mnemonic, regAddrToStr(rs2), rs1, regAddrToStr(rs3)); end else begin // reg-reg indexed store regs_read.push_back('{rs2, rs2_value, 0}); From ac54b7e3aecde52ff489122f3cc0e1d73e26e0e6 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 5 Apr 2024 12:33:08 +0800 Subject: [PATCH 37/69] Trace log - Better invalid printing on custom opcode --- bhv/cv32e40p_instr_trace.svh | 381 ++++++++++++++++++++++++++--------- 1 file changed, 286 insertions(+), 95 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index 5075e600e..8b08105b1 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -802,238 +802,429 @@ class instr_trace_t; else str_hb = ".h"; // set mnemonic - case (instr[31:26]) - 6'b000000: begin + case (instr) + INSTR_CVADDH , + INSTR_CVADDSCH , + INSTR_CVADDSCIH, + INSTR_CVADDB , + INSTR_CVADDSCB , + INSTR_CVADDSCIB : begin mnemonic = "cv.add"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b000010: begin + INSTR_CVSUBH , + INSTR_CVSUBSCH , + INSTR_CVSUBSCIH, + INSTR_CVSUBB , + INSTR_CVSUBSCB , + INSTR_CVSUBSCIB : begin mnemonic = "cv.sub"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b000100: begin + INSTR_CVAVGH , + INSTR_CVAVGSCH , + INSTR_CVAVGSCIH , + INSTR_CVAVGB , + INSTR_CVAVGSCB , + INSTR_CVAVGSCIB : begin mnemonic = "cv.avg"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b000110: begin + INSTR_CVAVGUH , + INSTR_CVAVGUSCH , + INSTR_CVAVGUSCIH, + INSTR_CVAVGUB , + INSTR_CVAVGUSCB , + INSTR_CVAVGUSCIB : begin mnemonic = "cv.avgu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b001000: begin + INSTR_CVMINH , + INSTR_CVMINSCH , + INSTR_CVMINSCIH, + INSTR_CVMINB , + INSTR_CVMINSCB , + INSTR_CVMINSCIB : begin mnemonic = "cv.min"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b001010: begin + INSTR_CVMINUH , + INSTR_CVMINUSCH , + INSTR_CVMINUSCIH, + INSTR_CVMINUB , + INSTR_CVMINUSCB , + INSTR_CVMINUSCIB : begin mnemonic = "cv.minu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b001100: begin + INSTR_CVMAXH , + INSTR_CVMAXSCH , + INSTR_CVMAXSCIH , + INSTR_CVMAXB , + INSTR_CVMAXSCB , + INSTR_CVMAXSCIB : begin mnemonic = "cv.max"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b001110: begin + INSTR_CVMAXUH , + INSTR_CVMAXUSCH , + INSTR_CVMAXUSCIH , + INSTR_CVMAXUB , + INSTR_CVMAXUSCB , + INSTR_CVMAXUSCIB : begin mnemonic = "cv.maxu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b010000: begin + INSTR_CVSRLH , + INSTR_CVSRLSCH , + INSTR_CVSRLSCIH , + INSTR_CVSRLB , + INSTR_CVSRLSCB , + INSTR_CVSRLSCIB : begin mnemonic = "cv.srl"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b010010: begin + INSTR_CVSRAH , + INSTR_CVSRASCH , + INSTR_CVSRASCIH, + INSTR_CVSRAB , + INSTR_CVSRASCB , + INSTR_CVSRASCIB : begin mnemonic = "cv.sra"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b010100: begin + INSTR_CVSLLH , + INSTR_CVSLLSCH , + INSTR_CVSLLSCIH, + INSTR_CVSLLB , + INSTR_CVSLLSCB , + INSTR_CVSLLSCIB : begin mnemonic = "cv.sll"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b010110: begin + INSTR_CVORH , + INSTR_CVORSCH , + INSTR_CVORSCIH, + INSTR_CVORB , + INSTR_CVORSCB , + INSTR_CVORSCIB : begin mnemonic = "cv.or"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b011000: begin + INSTR_CVXORH , + INSTR_CVXORSCH , + INSTR_CVXORSCIH , + INSTR_CVXORB , + INSTR_CVXORSCB , + INSTR_CVXORSCIB : begin mnemonic = "cv.xor"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b011010: begin + INSTR_CVANDH , + INSTR_CVANDSCH , + INSTR_CVANDSCIH , + INSTR_CVANDB , + INSTR_CVANDSCB , + INSTR_CVANDSCIB : begin mnemonic = "cv.and"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b011100: begin + INSTR_CVABSH, + INSTR_CVABSB : begin mnemonic = "cv.abs"; str_imm = $sformatf("0x%0h", imm_vs_type); end // dot products - 6'b100000: begin + INSTR_CVDOTUPH , + INSTR_CVDOTUPSCH , + INSTR_CVDOTUPSCIH, + INSTR_CVDOTUPB , + INSTR_CVDOTUPSCB , + INSTR_CVDOTUPSCIB : begin mnemonic = "cv.dotup"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b100010: begin + INSTR_CVDOTUSPH , + INSTR_CVDOTUSPSCH , + INSTR_CVDOTUSPSCIH, + INSTR_CVDOTUSPB , + INSTR_CVDOTUSPSCB , + INSTR_CVDOTUSPSCIB : begin mnemonic = "cv.dotusp"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b100100: begin + INSTR_CVDOTSPH , + INSTR_CVDOTSPSCH , + INSTR_CVDOTSPSCIH, + INSTR_CVDOTSPB , + INSTR_CVDOTSPSCB , + INSTR_CVDOTSPSCIB : begin mnemonic = "cv.dotsp"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b100110: begin + INSTR_CVSDOTUPH , + INSTR_CVSDOTUPSCH , + INSTR_CVSDOTUPSCIH, + INSTR_CVSDOTUPB , + INSTR_CVSDOTUPSCB , + INSTR_CVSDOTUPSCIB : begin mnemonic = "cv.sdotup"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b101000: begin + INSTR_CVSDOTUSPH , + INSTR_CVSDOTUSPSCH , + INSTR_CVSDOTUSPSCIH, + INSTR_CVSDOTUSPB , + INSTR_CVSDOTUSPSCB , + INSTR_CVSDOTUSPSCIB : begin mnemonic = "cv.sdotusp"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b101010: begin + INSTR_CVSDOTSPH , + INSTR_CVSDOTSPSCH , + INSTR_CVSDOTSPSCIH, + INSTR_CVSDOTSPB , + INSTR_CVSDOTSPSCB , + INSTR_CVSDOTSPSCIB : begin mnemonic = "cv.sdotsp"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b101110: begin - case (instr[14:13]) - 2'b00 : begin - mnemonic = "cv.extract"; - str_imm = $sformatf("0x%0h", imm_vs_type); - end - 2'b01 : begin - mnemonic = "cv.extractu"; - str_imm = $sformatf("0x%0h", imm_vu_type); - end - 2'b10 : begin - mnemonic = "cv.insert"; - str_imm = $sformatf("0x%0h", imm_vs_type); - end - endcase - str_sci = ""; + INSTR_CVEXTRACTH, + INSTR_CVEXTRACTB : begin + mnemonic = "cv.extract"; + str_imm = $sformatf("0x%0h", imm_vs_type); + str_sci = ""; + end + INSTR_CVEXTRACTUH, + INSTR_CVEXTRACTUB : begin + mnemonic = "cv.extractu"; + str_imm = $sformatf("0x%0h", imm_vu_type); + str_sci = ""; + end + INSTR_CVINSERTH, + INSTR_CVINSERTB : begin + mnemonic = "cv.insert"; + str_imm = $sformatf("0x%0h", imm_vs_type); + str_sci = ""; end // shuffle/pack - 6'b110000: begin - if (instr[14:12] == 3'b111) begin - mnemonic = "cv.shuffleI0"; - str_imm = $sformatf("0x%8h", imm_shuffle_type); - end else begin + INSTR_CVSHUFFLEH , + INSTR_CVSHUFFLESCIH, + INSTR_CVSHUFFLEB : begin mnemonic = "cv.shuffle"; if (instr[14:12] == 3'b110) begin str_imm = $sformatf("0x%8h", imm_shuffle_type); end - end end - 6'b110010: begin + + INSTR_CVSHUFFLEL0SCIB : begin + mnemonic = "cv.shuffleI0"; + str_imm = $sformatf("0x%8h", imm_shuffle_type); + end + INSTR_CVSHUFFLEL1SCIB : begin mnemonic = "cv.shuffleI1"; str_imm = $sformatf("0x%8h", imm_shuffle_type); end - 6'b110100: begin + INSTR_CVSHUFFLEL2SCIB : begin mnemonic = "cv.shuffleI2"; str_imm = $sformatf("0x%8h", imm_shuffle_type); end - 6'b110110: begin + INSTR_CVSHUFFLEL3SCIB : begin mnemonic = "cv.shuffleI3"; str_imm = $sformatf("0x%8h", imm_shuffle_type); end - 6'b111000: begin + INSTR_CVSHUFFLE2H, + INSTR_CVSHUFFLE2B : begin mnemonic = "cv.shuffle2"; end - 6'b111100: begin + INSTR_CVPACK, + INSTR_CVPACKH : begin mnemonic = "cv.pack"; if (instr[25] == 1'b0) begin str_hb = ""; end end - 6'b111110: begin - mnemonic = instr[25] ? "cv.packhi" : "cv.packlo"; - end + INSTR_CVPACKHIB : mnemonic = "cv.packhi"; + INSTR_CVPACKLOB : mnemonic = "cv.packlo"; // comparisons - 6'b000001: begin + INSTR_CVCMPEQH , + INSTR_CVCMPEQSCH , + INSTR_CVCMPEQSCIH, + INSTR_CVCMPEQB , + INSTR_CVCMPEQSCB , + INSTR_CVCMPEQSCIB : begin mnemonic = "cv.cmpeq"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b000011: begin + INSTR_CVCMPNEH , + INSTR_CVCMPNESCH , + INSTR_CVCMPNESCIH, + INSTR_CVCMPNEB , + INSTR_CVCMPNESCB , + INSTR_CVCMPNESCIB : begin mnemonic = "cv.cmpne"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b000101: begin + INSTR_CVCMPGTH , + INSTR_CVCMPGTSCH , + INSTR_CVCMPGTSCIH, + INSTR_CVCMPGTB , + INSTR_CVCMPGTSCB , + INSTR_CVCMPGTSCIB : begin mnemonic = "cv.cmpgt"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b000111: begin + INSTR_CVCMPGEH , + INSTR_CVCMPGESCH , + INSTR_CVCMPGESCIH, + INSTR_CVCMPGEB , + INSTR_CVCMPGESCB , + INSTR_CVCMPGESCIB : begin mnemonic = "cv.cmpge"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b001001: begin + INSTR_CVCMPLTH , + INSTR_CVCMPLTSCH , + INSTR_CVCMPLTSCIH, + INSTR_CVCMPLTB , + INSTR_CVCMPLTSCB , + INSTR_CVCMPLTSCIB : begin mnemonic = "cv.cmplt"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b001011: begin + INSTR_CVCMPLEH , + INSTR_CVCMPLESCH , + INSTR_CVCMPLESCIH, + INSTR_CVCMPLEB , + INSTR_CVCMPLESCB , + INSTR_CVCMPLESCIB : begin mnemonic = "cv.cmple"; str_imm = $sformatf("0x%0h", imm_vs_type); end - 6'b001101: begin + INSTR_CVCMPGTUH , + INSTR_CVCMPGTUSCH , + INSTR_CVCMPGTUSCIH, + INSTR_CVCMPGTUB , + INSTR_CVCMPGTUSCB , + INSTR_CVCMPGTUSCIB : begin mnemonic = "cv.cmpgtu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b001111: begin + INSTR_CVCMPGEUH , + INSTR_CVCMPGEUSCH , + INSTR_CVCMPGEUSCIH, + INSTR_CVCMPGEUB , + INSTR_CVCMPGEUSCB , + INSTR_CVCMPGEUSCIB : begin mnemonic = "cv.cmpgeu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b010001: begin + INSTR_CVCMPLTUH , + INSTR_CVCMPLTUSCH , + INSTR_CVCMPLTUSCIH, + INSTR_CVCMPLTUB , + INSTR_CVCMPLTUSCB , + INSTR_CVCMPLTUSCIB : begin mnemonic = "cv.cmpltu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b010011: begin + INSTR_CVCMPLEUH , + INSTR_CVCMPLEUSCH , + INSTR_CVCMPLEUSCIH, + INSTR_CVCMPLEUB , + INSTR_CVCMPLEUSCB , + INSTR_CVCMPLEUSCIB : begin mnemonic = "cv.cmpleu"; str_imm = $sformatf("0x%0h", imm_vu_type); end - 6'b010101: begin - unique case (instr[14:13]) - 2'b00: mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r" : "cv.cplxmul.i"; - 2'b01: mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r.div2" : "cv.cplxmul.i.div2"; - 2'b10: mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r.div4" : "cv.cplxmul.i.div4"; - 2'b11: mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r.div8" : "cv.cplxmul.i.div8"; - endcase + INSTR_CVCPLXMULR, + INSTR_CVCPLXMULI : begin + mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r" : "cv.cplxmul.i"; str_sci = ""; str_hb = ""; end - - 6'b010111: begin - mnemonic = "cv.cplxconj"; - str_sci = ""; + INSTR_CVCPLXMULRDIV2, + INSTR_CVCPLXMULIDIV2 : begin + mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r.div2" : "cv.cplxmul.i.div2"; + str_sci = ""; str_hb = ""; end - - 6'b011001: begin - unique case (instr[14:13]) - 2'b00: mnemonic = "cv.subrotmj"; - 2'b01: mnemonic = "cv.subrotmj.div2"; - 2'b10: mnemonic = "cv.subrotmj.div4"; - 2'b11: mnemonic = "cv.subrotmj.div8"; - endcase + INSTR_CVCPLXMULRDIV4, + INSTR_CVCPLXMULIDIV4 : begin + mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r.div4" : "cv.cplxmul.i.div4"; str_sci = ""; str_hb = ""; end - - 6'b011011: begin - unique case (instr[14:13]) - 2'b01: mnemonic = "cv.add.div2"; - 2'b10: mnemonic = "cv.add.div4"; - 2'b11: mnemonic = "cv.add.div8"; - endcase + INSTR_CVCPLXMULRDIV8, + INSTR_CVCPLXMULIDIV8 : begin + mnemonic = instr[25] == 1'b0 ? "cv.cplxmul.r.div8" : "cv.cplxmul.i.div8"; str_sci = ""; str_hb = ""; end - 6'b011101: begin - unique case (instr[14:13]) - 2'b01: mnemonic = "cv.sub.div2"; - 2'b10: mnemonic = "cv.sub.div4"; - 2'b11: mnemonic = "cv.sub.div8"; - endcase - str_sci = ""; + INSTR_CVCPLXCONJ : begin + mnemonic = "cv.cplxconj"; + str_sci = ""; str_hb = ""; end + INSTR_CVSUBROTMJ : begin + mnemonic = "cv.subrotmj"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVSUBROTMJDIV2 : begin + mnemonic = "cv.subrotmj.div2"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVSUBROTMJDIV4 : begin + mnemonic = "cv.subrotmj.div4"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVSUBROTMJDIV8 : begin + mnemonic = "cv.subrotmj.div8"; + str_sci = ""; + str_hb = ""; + end + + INSTR_CVADDIV2 : begin + mnemonic = "cv.add.div2"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVADDIV4 : begin + mnemonic = "cv.add.div4"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVADDIV8 : begin + mnemonic = "cv.add.div8"; + str_sci = ""; + str_hb = ""; + end + + INSTR_CVSUBIV2 : begin + mnemonic = "cv.sub.div2"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVSUBIV4 : begin + mnemonic = "cv.sub.div4"; + str_sci = ""; + str_hb = ""; + end + INSTR_CVSUBIV8 : begin + mnemonic = "cv.sub.div8"; + str_sci = ""; + str_hb = ""; + end + default: begin printMnemonic("INVALID"); return; From c0bdfab0764233726d1478be7a14ed4fd605013d Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 5 Apr 2024 12:34:54 +0800 Subject: [PATCH 38/69] Trace log - Updating legacy tracer file top line to match new one --- bhv/cv32e40p_tracer.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bhv/cv32e40p_tracer.sv b/bhv/cv32e40p_tracer.sv index 742b20383..59ed6fd7c 100644 --- a/bhv/cv32e40p_tracer.sv +++ b/bhv/cv32e40p_tracer.sv @@ -186,7 +186,7 @@ module cv32e40p_tracer $display("[%s] Output filename is: %s", info_tag, fn); f = $fopen(fn, "w"); $fwrite(f, - " Time Cycle PC Instr Decoded instruction Register and memory contents\n"); + " Time Cycle PC Instr Ctx Decoded instruction Register and memory contents\n"); end //initial begin From 663a17d9840eaf4bb88ccce97edbe1a9c381d35c Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 5 Apr 2024 12:35:44 +0800 Subject: [PATCH 39/69] RVFI - Adding mhpmevents csr reporting --- bhv/cv32e40p_rvfi.sv | 37 +++++++++++++++++++++++++++++++++---- bhv/cv32e40p_tb_wrapper.sv | 3 +++ bhv/insn_trace.sv | 25 +++++++++++++++++++------ bhv/pipe_freeze_trace.sv | 6 +++++- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index 0b34710de..99429d90d 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -644,6 +644,8 @@ module cv32e40p_rvfi localparam logic [31:0] MSTATUS_WRITE_MASK = 32'h0000_6088; localparam logic [31:0] MCOUNTINHIBIT_WRITE_MASK = {{(29-NUM_MHPMCOUNTERS){1'b0}}, {(NUM_MHPMCOUNTERS){1'b1}}, 3'b101}; + localparam NUM_HPM_EVENTS = 16; + localparam logic [31:0] MHPMEVENT_WRITE_MASK = {{(31-NUM_HPM_EVENTS){1'b0}}, {(NUM_HPM_EVENTS){1'b1}}}; `include "pipe_freeze_trace.sv" @@ -958,6 +960,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; rvfi_csr_mhpmcounterh_wmask[idx] = new_rvfi_trace.m_csr.mhpmcounter_wmask[idx][63:32]; rvfi_csr_mhpmcounterh_rdata[idx] = new_rvfi_trace.m_csr.mhpmcounter_rdata[idx][63:32]; rvfi_csr_mhpmcounterh_wdata[idx] = new_rvfi_trace.m_csr.mhpmcounter_wdata[idx][63:32]; + + rvfi_csr_mhpmevent_rmask[idx] = new_rvfi_trace.m_csr.mhpmevent_rmask[idx]; + rvfi_csr_mhpmevent_wmask[idx] = new_rvfi_trace.m_csr.mhpmevent_wmask[idx] & MHPMEVENT_WRITE_MASK; + rvfi_csr_mhpmevent_rdata[idx] = new_rvfi_trace.m_csr.mhpmevent_rdata[idx]; + rvfi_csr_mhpmevent_wdata[idx] = new_rvfi_trace.m_csr.mhpmevent_wdata[idx]; end // `SET_RVFI_CSR_FROM_INSN(instreth) rvfi_csr_instreth_rdata = new_rvfi_trace.m_csr.minstreth_rdata; @@ -1029,6 +1036,23 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; sample_perf_counter_to_id(idx); endfunction + function void sample_perf_event_to_trace(int idx, insn_trace_t m_trace); + m_trace.m_csr.mhpmevent_rdata[idx] = r_pipe_freeze_trace.csr.mhpmevent_q[idx]; + m_trace.m_csr.mhpmevent_rmask[idx] = '1; + endfunction + + function void perf_event_to_trace(int idx, insn_trace_t m_trace); + if(!m_trace.m_csr.mhpmevent_we[idx]) begin + m_trace.m_csr.mhpmevent_wdata[idx] = r_pipe_freeze_trace.csr.wdata_int; + end + if(r_pipe_freeze_trace.csr.mhpmevent_we[idx]) begin + m_trace.m_csr.mhpmevent_we[idx] = r_pipe_freeze_trace.csr.mhpmevent_we[idx]; + m_trace.m_csr.mhpmevent_wdata[idx] = r_pipe_freeze_trace.csr.wdata_int; + m_trace.m_csr.mhpmevent_wmask[idx] = r_pipe_freeze_trace.csr.mhpmevent_we[idx] ? '1 : '0; + end + sample_perf_event_to_trace(idx, m_trace); + endfunction + function void sample_minstret_to_trace(insn_trace_t m_trace); m_trace.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2][31:0]; m_trace.m_csr.minstret_rmask = '1; @@ -1092,6 +1116,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; sample_minstret_to_trace(m_trace); sample_minstreth_to_trace(m_trace); sample_mcycle_to_trace(m_trace); + for(int idx=3; idx<32; idx++)begin + sample_perf_event_to_trace(idx, m_trace); //TO CHANGE + end endfunction function void perf_counter_to_trace(insn_trace_t m_trace); @@ -1103,10 +1130,13 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end for(int idx=3; idx<32; idx++) begin if(r_pipe_freeze_trace.csr.mhpmcounter_write_lower[idx]) begin - perf_counter_to_id(3); + perf_counter_to_id(idx); end if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[idx]) begin - perf_counter_h_to_id(3); + perf_counter_h_to_id(idx); + end + if(r_pipe_freeze_trace.csr.mhpmevent_we[idx]) begin + perf_event_to_trace(idx, m_trace); end end endfunction @@ -1211,8 +1241,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; lpcount1_to_id(); lpend1_to_id(); lpstart1_to_id(); - - endfunction bit s_was_flush; //debug exception is flagged as trap only if preceed by a flush @@ -1708,6 +1736,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; for(int idx=3; idx<32; idx++) begin sample_perf_counter_to_id(idx); sample_perf_counter_h_to_id(idx); + sample_perf_event_to_trace(idx, trace_id); end end trace_id.m_instret_smaple_trigger = trace_id.m_instret_smaple_trigger + 1; diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 4d219fc3f..7cc24d02d 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -404,6 +404,9 @@ module cv32e40p_tb_wrapper .csr_mcountinhibit_n_i (cv32e40p_top_i.core_i.cs_registers_i.mcountinhibit_n), .csr_mcountinhibit_we_i(cv32e40p_top_i.core_i.cs_registers_i.mcountinhibit_we), + .csr_mhpmevent_n_i (cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_n), + .csr_mhpmevent_q_i (cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_q), + .csr_mhpmevent_we_i(cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_we), .csr_mscratch_q_i(cv32e40p_top_i.core_i.cs_registers_i.mscratch_q), .csr_mscratch_n_i(cv32e40p_top_i.core_i.cs_registers_i.mscratch_n), .csr_mepc_q_i(cv32e40p_top_i.core_i.cs_registers_i.mepc_q), diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index d97f31a7d..8cdc06d9e 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -144,6 +144,12 @@ logic [31:0][63:0] mhpmcounter_rmask; logic [31:0][63:0] mhpmcounter_wdata; logic [31:0][63:0] mhpmcounter_wmask; + + logic [31:0] mhpmevent_we; + logic [31:0][31:0] mhpmevent_rdata; + logic [31:0][31:0] mhpmevent_rmask; + logic [31:0][31:0] mhpmevent_wdata; + logic [31:0][31:0] mhpmevent_wmask; `DEFINE_CSR(mip) //mnxti //mintstatus @@ -657,12 +663,12 @@ INSTR_CVCMPLEB : this.m_mnemonic = "cv.cmple.b"; INSTR_CVCMPLESCB : this.m_mnemonic = "cv.cmple.sc.b"; INSTR_CVCMPLESCIB : this.m_mnemonic = "cv.cmple.sci.b"; - INSTR_CVCMPGTUH : this.m_mnemonic = "cv.cmptu.h"; - INSTR_CVCMPGTUSCH : this.m_mnemonic = "cv.cmptu.sc.h"; - INSTR_CVCMPGTUSCIH : this.m_mnemonic = "cv.cmptu.sci.h"; - INSTR_CVCMPGTUB : this.m_mnemonic = "cv.cmptu.b"; - INSTR_CVCMPGTUSCB : this.m_mnemonic = "cv.cmptu.sc.b"; - INSTR_CVCMPGTUSCIB : this.m_mnemonic = "cv.cmptu.sci.b"; + INSTR_CVCMPGTUH : this.m_mnemonic = "cv.cmpgtu.h"; + INSTR_CVCMPGTUSCH : this.m_mnemonic = "cv.cmpgtu.sc.h"; + INSTR_CVCMPGTUSCIH : this.m_mnemonic = "cv.cmpgtu.sci.h"; + INSTR_CVCMPGTUB : this.m_mnemonic = "cv.cmpgtu.b"; + INSTR_CVCMPGTUSCB : this.m_mnemonic = "cv.cmpgtu.sc.b"; + INSTR_CVCMPGTUSCIB : this.m_mnemonic = "cv.cmpgtu.sci.b"; INSTR_CVCMPGEUH : this.m_mnemonic = "cv.cmpgeu.h"; INSTR_CVCMPGEUSCH : this.m_mnemonic = "cv.cmpgeu.sc.h"; INSTR_CVCMPGEUSCIH : this.m_mnemonic = "cv.cmpgeu.sci.h"; @@ -901,6 +907,8 @@ `INIT_CSR(instreth) this.m_csr.mhpmcounter_we = '0; this.m_csr.mhpmcounter_wmask = '0; + this.m_csr.mhpmevent_we = '0; + this.m_csr.mhpmevent_wmask = '0; `INIT_CSR(mip) `INIT_CSR(tdata1) `INIT_CSR(tdata2) @@ -1078,6 +1086,11 @@ this.m_csr.mhpmcounter_rmask = m_source.m_csr.mhpmcounter_rmask; this.m_csr.mhpmcounter_wdata = m_source.m_csr.mhpmcounter_wdata; this.m_csr.mhpmcounter_wmask = m_source.m_csr.mhpmcounter_wmask; + this.m_csr.mhpmevent_we = m_source.m_csr.mhpmevent_we; + this.m_csr.mhpmevent_rdata = m_source.m_csr.mhpmevent_rdata; + this.m_csr.mhpmevent_rmask = m_source.m_csr.mhpmevent_rmask; + this.m_csr.mhpmevent_wdata = m_source.m_csr.mhpmevent_wdata; + this.m_csr.mhpmevent_wmask = m_source.m_csr.mhpmevent_wmask; `ASSIGN_CSR(mip) `ASSIGN_CSR(tdata1) `ASSIGN_CSR(tdata2) diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index 47ab01ef4..bc18d54b8 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -351,6 +351,7 @@ function compute_csr_we(); r_pipe_freeze_trace.csr.fflags_we = 1'b0; r_pipe_freeze_trace.csr.frm_we = 1'b0; r_pipe_freeze_trace.csr.fcsr_we = 1'b0; + r_pipe_freeze_trace.csr.mhpmevent_we = '0; r_pipe_freeze_trace.csr.dpc_we = csr_dpc_we_i; if (r_pipe_freeze_trace.csr.we) begin case (r_pipe_freeze_trace.csr.addr) @@ -378,6 +379,10 @@ function compute_csr_we(); CSR_DSCRATCH1: r_pipe_freeze_trace.csr.dscratch1_we = 1'b1; endcase end + + if(csr_mhpmevent_we_i)begin + r_pipe_freeze_trace.csr.mhpmevent_we[r_pipe_freeze_trace.csr.addr[4:0]] = 1'b1; + end // CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = r_pipe_freeze_trace.csr.mcause_n != r_pipe_freeze_trace.csr.mcause_q; //for debug purpose endfunction /* @@ -575,7 +580,6 @@ task monitor_pipeline(); r_pipe_freeze_trace.csr.mcountinhibit_we = csr_mcountinhibit_we_i; r_pipe_freeze_trace.csr.mhpmevent_n = csr_mhpmevent_n_i; r_pipe_freeze_trace.csr.mhpmevent_q = csr_mhpmevent_q_i; - r_pipe_freeze_trace.csr.mhpmevent_we = csr_mhpmevent_we_i; r_pipe_freeze_trace.csr.mscratch_n = csr_mscratch_n_i; r_pipe_freeze_trace.csr.mscratch_q = csr_mscratch_q_i; r_pipe_freeze_trace.csr.mepc_n = csr_mepc_n_i; From a963928255336cf51570f9746c1fe8222e94b8d6 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 9 Apr 2024 16:03:36 +0800 Subject: [PATCH 40/69] Running verible --- bhv/cv32e40p_rvfi_trace.sv | 16 ++++++++-------- bhv/cv32e40p_tb_wrapper.sv | 4 ++-- bhv/pipe_freeze_trace.sv | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bhv/cv32e40p_rvfi_trace.sv b/bhv/cv32e40p_rvfi_trace.sv index bcebddf1a..adf851759 100644 --- a/bhv/cv32e40p_rvfi_trace.sv +++ b/bhv/cv32e40p_rvfi_trace.sv @@ -37,14 +37,14 @@ module cv32e40p_rvfi_trace input logic [31:0] imm_s3_type, - input logic rvfi_valid, - input logic [31:0] rvfi_insn, - input integer rvfi_start_cycle, - input time rvfi_start_time, - input integer rvfi_stop_cycle, - input time rvfi_stop_time, - input logic [31:0] rvfi_pc_rdata, - input rvfi_trap_t rvfi_trap, + input logic rvfi_valid, + input logic [31:0] rvfi_insn, + input integer rvfi_start_cycle, + input time rvfi_start_time, + input integer rvfi_stop_cycle, + input time rvfi_stop_time, + input logic [31:0] rvfi_pc_rdata, + input rvfi_trap_t rvfi_trap, input logic [ 4:0] rvfi_rd_addr [1:0], input logic [31:0] rvfi_rd_wdata[1:0], diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 7cc24d02d..25245407e 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -404,8 +404,8 @@ module cv32e40p_tb_wrapper .csr_mcountinhibit_n_i (cv32e40p_top_i.core_i.cs_registers_i.mcountinhibit_n), .csr_mcountinhibit_we_i(cv32e40p_top_i.core_i.cs_registers_i.mcountinhibit_we), - .csr_mhpmevent_n_i (cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_n), - .csr_mhpmevent_q_i (cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_q), + .csr_mhpmevent_n_i(cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_n), + .csr_mhpmevent_q_i(cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_q), .csr_mhpmevent_we_i(cv32e40p_top_i.core_i.cs_registers_i.mhpmevent_we), .csr_mscratch_q_i(cv32e40p_top_i.core_i.cs_registers_i.mscratch_q), .csr_mscratch_n_i(cv32e40p_top_i.core_i.cs_registers_i.mscratch_n), diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index bc18d54b8..fe6e6bfae 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -380,8 +380,8 @@ function compute_csr_we(); endcase end - if(csr_mhpmevent_we_i)begin - r_pipe_freeze_trace.csr.mhpmevent_we[r_pipe_freeze_trace.csr.addr[4:0]] = 1'b1; + if (csr_mhpmevent_we_i) begin + r_pipe_freeze_trace.csr.mhpmevent_we[r_pipe_freeze_trace.csr.addr[4:0]] = 1'b1; end // CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = r_pipe_freeze_trace.csr.mcause_n != r_pipe_freeze_trace.csr.mcause_q; //for debug purpose endfunction From aef99830347c6ffd825145a4fb0561f81f7f7bf0 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 9 Apr 2024 14:47:35 +0200 Subject: [PATCH 41/69] Updated incorrect table names. Signed-off-by: Pascal Gouedo --- docs/source/instruction_set_extensions.rst | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index b669e2836..15513c974 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -1019,7 +1019,7 @@ Immediate Branching Encoding ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. table:: Immediate Branching encoding - :name: General ALU operations encoding + :name: Immediate Branching encoding :widths: 13 14 8 6 8 12 12 11 16 :class: no-scrollbar-table @@ -1046,8 +1046,8 @@ The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` = 16-Bit x 16-Bit Multiplication operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. table:: 16-Bit Multiplication operations - :name: 16-Bit Multiplication operations +.. table:: 16-Bit x 16-Bit Multiplication operations + :name: 16-Bit x 16-Bit Multiplication operations :widths: 30 70 :class: no-scrollbar-table @@ -1099,8 +1099,8 @@ The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` = 16-Bit x 16-Bit Multiplication pseudo-instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. table:: 16-Bit Multiplication pseudo-instructions - :name: 16-Bit Multiplication pseudo-instructions +.. table:: 16-Bit x 16-Bit Multiplication pseudo-instructions + :name: 16-Bit x 16-Bit Multiplication pseudo-instructions :widths: 23 27 50 :class: no-scrollbar-table @@ -1127,8 +1127,8 @@ The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` = 16-Bit x 16-Bit Multiply-Accumulate operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. table:: 16-Bit Multiply-Accumulate operations - :name: 16-Bit Multiply-Accumulate operations +.. table:: 16-Bit x 16-Bit Multiply-Accumulate operations + :name: 16-Bit x 16-Bit Multiply-Accumulate operations :widths: 30 70 :class: no-scrollbar-table @@ -1179,8 +1179,8 @@ The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` = 32-Bit x 32-Bit Multiply-Accumulate operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. table:: 32-Bit Multiply-Accumulate operations - :name: 32-Bit Multiply-Accumulate operations +.. table:: 32-Bit x 32-Bit Multiply-Accumulate operations + :name: 32-Bit x 32-Bit Multiply-Accumulate operations :widths: 30 70 :class: no-scrollbar-table @@ -1195,8 +1195,8 @@ The custom multiply-accumulate extensions are only supported if ``COREV_PULP`` = Encoding ^^^^^^^^ -.. table:: 16-Bit Multiplication operations - :name: 16-Bit Multiplication operations +.. table:: 16-Bit x 16-Bit Multiplication encoding + :name: 16-Bit x 16-Bit Multiplication encoding :widths: 5 16 6 6 9 6 11 39 :class: no-scrollbar-table @@ -1222,8 +1222,8 @@ Encoding | 11 | Luimm5[4:0] | src2 | src1 | 100 | dest | 101 1011 | **cv.mulhhsRN rD, rs1, rs2, Is3** | +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ -.. table:: 16-Bit Multiply-Accumulate operations - :name: 16-Bit Multiply-Accumulate operations +.. table:: 16-Bit x 16-Bit Multiply-Accumulate encoding + :name: 16-Bit x 16-Bit Multiply-Accumulate encoding :widths: 5 16 6 6 9 6 11 39 :class: no-scrollbar-table @@ -1249,8 +1249,8 @@ Encoding | 11 | Luimm5[4:0] | src2 | src1 | 110 | dest | 101 1011 | **cv.machhsRN rD, rs1, rs2, Is3** | +--------+---------------+---------+---------+------------+--------+------------+------------------------------------+ -.. table:: 32-Bit Multiply-Accumulate operations - :name: 32-Bit Multiply-Accumulate operations +.. table:: 32-Bit x 32-Bit Multiply-Accumulate encoding + :name: 32-Bit x 32-Bit Multiply-Accumulate encoding :widths: 21 6 6 9 6 11 39 :class: no-scrollbar-table From f2cd0b4def31b257e3facf010f3f5111cb9365bd Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 9 Apr 2024 14:48:19 +0200 Subject: [PATCH 42/69] Added missing paragraph carriage return. Signed-off-by: Pascal Gouedo --- docs/source/pipeline.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/pipeline.rst b/docs/source/pipeline.rst index 971a0a9e1..8cbf907e9 100644 --- a/docs/source/pipeline.rst +++ b/docs/source/pipeline.rst @@ -47,6 +47,7 @@ Execute (EX) * There is a multi-cycle MULH in EX. * There is a Misaligned LOAD/STORE in EX. * There is a Post-Increment LOAD/STORE in EX. + In those 3 exceptions, EX will not be stalled, FPU result (and flags) are memorized and will be written back in the register file (and FPU CSR) as soon as there is no conflict anymore. Writeback (WB) From 5aa98cb3f225c876a779134ab01585f7ad03e361 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 9 Apr 2024 17:13:42 +0200 Subject: [PATCH 43/69] Forbid floating figures. Signed-off-by: Pascal Gouedo --- docs/source/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index 53badd35b..803228d89 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -164,6 +164,7 @@ # Latex figure (float) alignment # # 'figure_align': 'htbp', + 'figure_align': 'H', } # Grouping the document tree into LaTeX files. List of tuples From d6d94f461e957f5d4dab1b3fc053a1a1acd4db2c Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 9 Apr 2024 17:14:22 +0200 Subject: [PATCH 44/69] Updated Verification section. Signed-off-by: Pascal Gouedo --- docs/source/verification.rst | 241 ++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 120 deletions(-) diff --git a/docs/source/verification.rst b/docs/source/verification.rst index afc645886..56d71a834 100644 --- a/docs/source/verification.rst +++ b/docs/source/verification.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _verification: @@ -29,8 +29,8 @@ v1.0.0 verification ------------------- In early 2021 the CV32E40P achieved Functional RTL Freeze (released with cv32e40p_v1.0.0 version), meaning that is has been fully verified as per its -`Verification Plan `_. -Final functional, code and test coverage reports can be found `here `_. +`Verification Plan `_. +Final functional, code and test coverage reports can be found `here `_. The unofficial start date for the CV32E40P verification effort is 2020-02-27, which is the date the core-v-verif environment "went live". Between then and @@ -97,45 +97,106 @@ A classification of the issues themselves: | Invalid | 1 | | +------------------------------+-----------+----------------------------------------------------------------------------------------+ -Additional details are available as part of the `CV32E40P v1.0.0 Report `_. +Additional details are available as part of the `CV32E40P v1.0.0 Report `_. .. [1] It is a testament on the quality of the work done by the PULP platform team - that it took a team of professonal verification engineers more than 9 months + that it took a team of professional verification engineers more than 9 months to find all these issues. +.. raw:: latex + + \newpage + v2.0.0 verification ------------------- -The table below lists the 9 configurations with ``cv32e40p_top`` parameters values verified in the scope of CV32E40Pv2 project using both Formal-based and Simulation-based methodologies. +The table below lists the 7 configurations with ``cv32e40p_top`` parameters values verified in the scope of CV32E40Pv2 project using both Formal-based and Simulation-based methodologies. .. table:: Verified configurations :name: Verified configurations :align: center + :widths: 23 11 11 11 11 11 11 11 :class: no-scrollbar-table - +--------------------+-----------------------------------+ - | **Top Parameters** | **Verified Configurations** | - +====================+===+===+===+===+===+===+===+===+===+ - | COREV_PULP | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | - +--------------------+---+---+---+---+---+---+---+---+---+ - | COREV_CLUSTER | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | - +--------------------+---+---+---+---+---+---+---+---+---+ - | FPU | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | - +--------------------+---+---+---+---+---+---+---+---+---+ - | ZFINX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | - +--------------------+---+---+---+---+---+---+---+---+---+ - | FPU_ADDMUL_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 2 | - +--------------------+---+---+---+---+---+---+---+---+---+ - | FPU_OTHERS_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 2 | - +--------------------+---+---+---+---+---+---+---+---+---+ - -A total of resp. 30 and xx RTL issues were identified by resp. Formal Verification and Simulation methodologies, all have been resolved. + +--------------------+-------------------------------------------------------------------------+ + | | **Verified Configurations (CFG_"config name")** | + +====================+=======+==========+==========+==========+==========+==========+==========+ + | **Top Parameters** | **P** | **P_F0** | **P_F1** | **P_F2** | **P_Z0** | **P_Z1** | **P_Z2** | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + | COREV_PULP | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + | COREV_CLUSTER | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + | FPU | 0 | 1 | 1 | 1 | 1 | 1 | 1 | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + | ZFINX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + | FPU_ADDMUL_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + | FPU_OTHERS_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | + +--------------------+-------+----------+----------+----------+----------+----------+----------+ + +Verification environment is described in `CORE-V Verification Strategy `_ and used the so-called `Step-and-Compare 2.0 `_ methodology. It is using an Imperas® model connected in the test-bench through an RVVI interface as shown by following figure: + +.. figure:: ../images/ImperasDV_diagram_May_2023-reduced.jpg + :name: ImperasDV framework + :align: center -A breakdown of the RTL issues is as follows: + ImperasDV framework + +CV32E40Pv2 achieved RTL Freeze (released with cv32e40p_v2.0.0 version) mid-April 2024, meaning that is has been fully verified as per its +`Verification Plan `_. +Final functional, code and test coverage reports can be found here: `CV32E40P v2.0.0 Report `_. + +It is to be mentioned that CV32E40Pv2 has successfully executed `RISCOF (RISC-V COmpatibility Framework) `_ for RV32IMCF extensions. +Report can be found `here `_. + +Formal verification +^^^^^^^^^^^^^^^^^^^ + +To accelerate the verification of more than 300 XPULP instructions, Formal Verification methodology has been used with Siemens EDA Onespin tool and its RISC-V ISA Processor Verification app. + +The XPULP instructions pseudo-code description using Sail language have been added to the RISC-V ISA app to successfully formally verify all the CV32E40P instructions, including the previously verified standard IMC together with the new F, Zfinx and XPULP extensions and all additional custom CSRs. + +Example: + +.. code-block:: text + + { + "name": "CV.SDOTUP.B", + "disassembly": "cv.sdotup.b {rd},{rs1},{rs2}", + "decoding": "1001100 rs2 rs1 001 rd/rs3 1111011", + "restrictions": "", + "execution": "X(rd) = X(rs3) + EXTZ(mul(X(rs1)[7..0],X(rs2)[7..0])) + + EXTZ(mul(X(rs1)[15..8],X(rs2)[15..8])) + + EXTZ(mul(X(rs1)[23..16],X(rs2)[23..16])) + + EXTZ(mul(X(rs1)[31..24],X(rs2)[31..24]))" + }, + +Those SAIL instructions description are then used to automatically generate more than 430 assertions and 29 CSRs descriptions. +Those assertions have been applied on the 7 different configurations listed in :ref:`Verified configurations` table. + +RTL code coverage is generated using Siemens EDA Onespin Quantify tool which uses RTL mutation to check assertions quality and can produce standard UCDB database that can be merged with simulation one afterwards. + +Simulation verification +^^^^^^^^^^^^^^^^^^^^^^^ + +core-v-verif verification environment for v1.0.0 was using a *step&compare* methodology with an instruction set simulator (ISS) from Imperas Software as the reference model. +This strategy was successful, but inefficient because the *step&compare* logic in the testbench must compensate for the cycle-time effects of events that are asynchronous to the instruction stream such as interrupts, debug resets plus bus errors and random delays on instruction fetch and load/store memory buses. +For verification of v2.0.0 release of the CV32E40P core, the step-and-compare and the ISS have been replaced by a true reference model (RM) called ImperasDV. In addition, the Imperas Reference Model has been extended to support the v2 XPULP instructions specification. + +Another innovation for v2.0.0 was the adoption of a standardized tracer interface to the DUT and RM, based on the open-source RISC-V Verification Interface (RVVI). The use of well documented, standardized interfaces greatly simplifies the integration of the DUT with the RM. + +Results summary +^^^^^^^^^^^^^^^ -.. table:: How RTL Issues Were Found in v2.0.0 - :name: How RTL Issues Were Found in v2.0.0 +30 issues were identified by Formal Verification and 10 by Simulation methodologies, all have been resolved. + +Here is the breakdown of all the issues: + +.. table:: How Issues Were Found in v2.0.0 + :name: How Issues Were Found in v2.0.0 :widths: 27 9 64 :class: no-scrollbar-table @@ -144,12 +205,12 @@ A breakdown of the RTL issues is as follows: +=====================+===========+===============================================================+ | Formal Verification | 30 | All related to features enabled by ``COREV_PULP`` or ``FPU``. | +---------------------+-----------+---------------------------------------------------------------+ - | Simulation | | | + | Simulation | 10 | | +---------------------+-----------+---------------------------------------------------------------+ - | Lint | | | + | Lint | 2 | | +---------------------+-----------+---------------------------------------------------------------+ -A classification of the Formal Verification issues by type and their description are listed in the two following tables: +A classification of the Formal Verification issues by type and their description are listed in the following tables: .. table:: Breakdown of Issues found by Formal Verification in v2.0.0 :name: Breakdown of Issues found by Formal Verification in v2.0.0 @@ -186,7 +247,7 @@ A classification of the Formal Verification issues by type and their description | F instructions result or flags | 5 | F result or flags computations is incorrect with respect to IEEE 754-2008 standard. | +--------------------------------+-----------+---------------------------------------------------------------------------------------+ -A classification of the simulation issues by method used to identify them is informative: +A classification of the Simulation issues by type and their description are listed in the following tables: .. table:: Breakdown of Issues found by Simulation in v2.0.0 :name: Breakdown of Issues found by Simulation in v2.0.0 @@ -194,92 +255,32 @@ A classification of the simulation issues by method used to identify them is inf :class: no-scrollbar-table +------------------------------+-----------+----------------------------------------------------------------------------------------+ - | **Simulation Method** | **Count** | **Note** | + | **Type** | **Count** | **Note** | +==============================+===========+========================================================================================+ - | Directed, self-checking test | | Many test supplied by Design team and a couple from the Open Source Community at large | - +------------------------------+-----------+----------------------------------------------------------------------------------------+ - | RVFI/RVVI | | Issues directly attributed to comparison against Reference Model | - +------------------------------+-----------+----------------------------------------------------------------------------------------+ - | Constrained-Random | | Test generated by corev-dv (extension of riscv-dv) | + | RTL bugs | 10 | See classification below | +------------------------------+-----------+----------------------------------------------------------------------------------------+ - -A classification of the Simulation issues themselves: - -.. table:: Simulation Issue Classification in v2.0.0 - :name: Simulation Issue Classification in v2.0.0 - :widths: 27 9 64 +.. table:: Simulation Issues Classification in v2.0.0 + :name: Simulation Issues Classification in v2.0.0 + :widths: 38 9 53 :class: no-scrollbar-table - +------------------------------+-----------+----------------------------------------------------------------------------------------+ - | **Issue Type** | **Count** | **Note** | - +==============================+===========+========================================================================================+ - | RTL Functional bug | | | - +------------------------------+-----------+----------------------------------------------------------------------------------------+ - | | | | - +------------------------------+-----------+----------------------------------------------------------------------------------------+ - -Formal verification -^^^^^^^^^^^^^^^^^^^ - -To accelerate the verification of more than 300 Xpulp instructions, Formal Verification methodology has been used with Siemens EDA Onespin tools and its RISC-V ISA Processor Verification app. - -The Xpulp instructions pseudo-code description using Sail language have been added to the RISC-V ISA app to successfully formally verify all the CV32E40P instructions, including the previously verified standard IMC together with the new F, Zfinx and Xpulp extensions and all additional custom CSRs. - -Example: - -.. code-block:: text - - { - "name": "CV.SDOTUP.B", - "disassembly": "cv.sdotup.b {rd},{rs1},{rs2}", - "decoding": "1001100 rs2 rs1 001 rd/rs3 1111011", - "restrictions": "", - "execution": "X(rd) = X(rs3) + EXTZ(mul(X(rs1)[7..0],X(rs2)[7..0])) + - EXTZ(mul(X(rs1)[15..8],X(rs2)[15..8])) + - EXTZ(mul(X(rs1)[23..16],X(rs2)[23..16])) + - EXTZ(mul(X(rs1)[31..24],X(rs2)[31..24]))" - }, - -Those SAIL instructions description are then used to automatically generate more than 430 assertions and 29 CSRs descriptions. -Those assertions have been applied on the 9 different configurations listed in :ref:`Verified configurations` table. - -RTL code coverage is generated using Siemens EDA Onespin Quantify tool which uses RTL mutation to check assertions quality and can produce standard UCDB database that can be merged with simulation one afterwards. - -WIP... - -.. ADD PLANS AND REPORTS LINKS - -.. Formal Verification assertions and RTL code coverage reports can be found `here `_. - -.. TO DEVELOP ... - -Simulation verification -^^^^^^^^^^^^^^^^^^^^^^^ - -core-v-verif verification environment for v1.0.0 was using a *step&compare* methodology with an instruction set simulator (ISS) from Imperas Software as the reference model. -This strategy was successful, but inefficient because the *step&compare* logic in the testbench must compensate for the cycle-time effects of events that are asynchronous to the instruction stream such as interrupts, debug resets plus bus errors and random delays on instruction fetch and load/store memory buses. -For verification of v2.0.0 release of the CV32E40P core, the step-and-compare and the ISS have been replaced by a true reference model (RM) called ImperasDV. In addition, the Imperas Reference Model has been extended to support the v2 Xpulp instructions specification. - -Another innovation for v2.0.0 was the adoption of a standardized tracer interface to the DUT and RM, based on the open-source RISC-V Verification Interface (RVVI). The use of well documented, standardized interfaces greatly simplifies the integration of the DUT with the RM. - -Additionaly to V1 Verification plans, `Verification Plan `_ contains a `new section `_ related to F and XPULP verification. - -WIP... - -.. ADD REPORTS LINKS - -.. TO DEVELOP ... - -Reports -^^^^^^^ - -WIP... - -.. ADD BUG LIST LINK AND TABLE LIKE ABOVE - -.. ADD MERGED RTL CODE COVERAGE GENERATED REPORTS LINK - + +--------------------------------+-----------+---------------------------------------------------------------------------------------+ + | **Issue Type** | **Count** | **Note** | + +================================+===========+=======================================================================================+ + | Multi-cycle F instructions | 5 | Data forward violation between XPULP instructions and muticycle F instructions. | + +--------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Hardware Loops | 3 | Incorrect behavior when count programmed with 0 value. | + | | | | + | | | lpendX CSR updated by a cancelled instruction. | + | | | | + | | | lpcountX not updated after a pipeline flush due to a CSR access. | + +--------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Deadlock | 1 | Bug resolution for multicycle F instructions created a deadlock when conflicting | + | | | Register File write between ALU and FPU. | + +--------------------------------+-----------+---------------------------------------------------------------------------------------+ + | MSTATUS.FS incorrect value | 1 | FS was not updated following any Floating Point Load instruction. | + +--------------------------------+-----------+---------------------------------------------------------------------------------------+ Tracer ------ @@ -292,7 +293,7 @@ Output file ^^^^^^^^^^^ All traced instructions are written to a log file. -The log file is named ``trace_core_.log``, with ```` being the 32 digit hart ID of the core being traced. +The log file is named ``trace_core.log``. Trace output format ^^^^^^^^^^^^^^^^^^^ @@ -309,7 +310,7 @@ The trace output is in tab-separated columns. - Numeric register names are used (e.g. ``x1``). - Symbolic CSR names are used. - Jump/branch targets are given as absolute address if possible (PC + immediate). -6. **Register and memory contents**: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as ``registername=value``, reads as ``registername:value``. For memory accesses, the physical address (PA), the loaded and stored data are given. +6. **Register and memory contents**: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as ``registername=value``, reads as ``registername:value``. For memory accesses, the physical address (PA) of the loaded or stored data is reported as well. From ad7efbf0aee56be9cde52e55994685751412fc6d Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 9 Apr 2024 17:21:50 +0200 Subject: [PATCH 45/69] Issue #975 correction. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_id_stage.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index f323cbe5f..6d8b884d2 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -1355,7 +1355,7 @@ module cv32e40p_id_stage .hwlp_dec_cnt_i(hwlp_dec_cnt) ); - assign hwlp_valid = instr_valid_i & clear_instr_valid_o; + assign hwlp_valid = (instr_valid_i | csr_status) & clear_instr_valid_o; // hwloop register id assign hwlp_regid = instr[7]; // rd contains hwloop register id From 6293b395ea8f3a836872aa42d7a39eecc805d071 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 10 Apr 2024 09:33:29 +0200 Subject: [PATCH 46/69] Add forgotten image. Signed-off-by: Pascal Gouedo --- .../ImperasDV_diagram_May_2023-reduced.jpg | Bin 0 -> 43870 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 docs/images/ImperasDV_diagram_May_2023-reduced.jpg diff --git a/docs/images/ImperasDV_diagram_May_2023-reduced.jpg b/docs/images/ImperasDV_diagram_May_2023-reduced.jpg new file mode 100755 index 0000000000000000000000000000000000000000..5e45af88919c38e4236a96d57cced8fe43ee8f5b GIT binary patch literal 43870 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 Date: Wed, 10 Apr 2024 11:00:49 +0200 Subject: [PATCH 47/69] Updated documentation rst files headers. Signed-off-by: Pascal Gouedo --- docs/source/conf.py | 16 ++++++++-------- docs/source/control_status_registers.rst | 20 ++++++++++---------- docs/source/core_versions.rst | 16 ++++++++-------- docs/source/corev_hw_loop.rst | 16 ++++++++-------- docs/source/debug.rst | 16 ++++++++-------- docs/source/exceptions_interrupts.rst | 16 ++++++++-------- docs/source/fpu.rst | 15 ++++++++------- docs/source/glossary.rst | 16 ++++++++-------- docs/source/index.rst | 16 ++++++++-------- docs/source/instruction_fetch.rst | 16 ++++++++-------- docs/source/instruction_set_extensions.rst | 16 ++++++++-------- docs/source/integration.rst | 16 ++++++++-------- docs/source/intro.rst | 20 ++++++++++---------- docs/source/load_store_unit.rst | 16 ++++++++-------- docs/source/perf_counters.rst | 16 ++++++++-------- docs/source/pipeline.rst | 16 ++++++++-------- docs/source/preface.rst | 17 +++++++++++++++++ docs/source/register_file.rst | 16 ++++++++-------- docs/source/sleep.rst | 16 ++++++++-------- 19 files changed, 165 insertions(+), 147 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 803228d89..573f5073e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,20 +1,20 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2020 OpenHW Group -# -# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. +# Copyright 2024 OpenHW Group and Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# +# Licensed under the Solderpad Hardware License v 2.1 (the "License"); +# you may not use this file except in compliance with the License, or, +# at your option, the Apache License version 2.0. # You may obtain a copy of the License at # -# https://solderpad.org/licenses/ +# https://solderpad.org/licenses/SHL-2.1/ # -# Unless required by applicable law or agreed to in writing, software +# Unless required by applicable law or agreed to in writing, any work # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 # ############################################################################### # diff --git a/docs/source/control_status_registers.rst b/docs/source/control_status_registers.rst index 28f3d2fe6..7eee4b64d 100644 --- a/docs/source/control_status_registers.rst +++ b/docs/source/control_status_registers.rst @@ -1,20 +1,20 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - - https://solderpad.org/licenses/ - - Unless required by applicable law or agreed to in writing, software + + https://solderpad.org/licenses/SHL-2.1/ + + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - .. _cs-registers: Control and Status Registers diff --git a/docs/source/core_versions.rst b/docs/source/core_versions.rst index c23169985..83dbb56f6 100644 --- a/docs/source/core_versions.rst +++ b/docs/source/core_versions.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2020 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _core_versions: diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 71964d2d2..01eaca33f 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _hwloop-specs: diff --git a/docs/source/debug.rst b/docs/source/debug.rst index b18da9699..c7e35e126 100644 --- a/docs/source/debug.rst +++ b/docs/source/debug.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _debug-support: diff --git a/docs/source/exceptions_interrupts.rst b/docs/source/exceptions_interrupts.rst index 086ce723a..91489ef09 100644 --- a/docs/source/exceptions_interrupts.rst +++ b/docs/source/exceptions_interrupts.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _exceptions-interrupts: diff --git a/docs/source/fpu.rst b/docs/source/fpu.rst index 019630a35..23245a970 100644 --- a/docs/source/fpu.rst +++ b/docs/source/fpu.rst @@ -1,18 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _fpu: diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst index 7269f96a9..effecfa33 100644 --- a/docs/source/glossary.rst +++ b/docs/source/glossary.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2020 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _glossary: diff --git a/docs/source/index.rst b/docs/source/index.rst index 88a1283cb..a8848922a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 OpenHW Group CV32E40P User Manual ================================= diff --git a/docs/source/instruction_fetch.rst b/docs/source/instruction_fetch.rst index 2e5f77083..9624498cc 100644 --- a/docs/source/instruction_fetch.rst +++ b/docs/source/instruction_fetch.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _instruction-fetch: diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index 15513c974..1aa54bbcf 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _custom-isa-extensions: diff --git a/docs/source/integration.rst b/docs/source/integration.rst index f355d2b1d..f98e29fcd 100644 --- a/docs/source/integration.rst +++ b/docs/source/integration.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _core-integration: diff --git a/docs/source/intro.rst b/docs/source/intro.rst index 853ef357c..4db1c51b0 100644 --- a/docs/source/intro.rst +++ b/docs/source/intro.rst @@ -1,20 +1,20 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - - https://solderpad.org/licenses/ - - Unless required by applicable law or agreed to in writing, software + + https://solderpad.org/licenses/SHL-2.1/ + + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 - Introduction ============= diff --git a/docs/source/load_store_unit.rst b/docs/source/load_store_unit.rst index ebaf837cc..34b683377 100644 --- a/docs/source/load_store_unit.rst +++ b/docs/source/load_store_unit.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _load-store-unit: diff --git a/docs/source/perf_counters.rst b/docs/source/perf_counters.rst index bbed0c545..81e0f21f7 100644 --- a/docs/source/perf_counters.rst +++ b/docs/source/perf_counters.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _performance-counters: diff --git a/docs/source/pipeline.rst b/docs/source/pipeline.rst index 8cbf907e9..9faf965d3 100644 --- a/docs/source/pipeline.rst +++ b/docs/source/pipeline.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _pipeline-details: diff --git a/docs/source/preface.rst b/docs/source/preface.rst index f6b516214..daa3446d4 100644 --- a/docs/source/preface.rst +++ b/docs/source/preface.rst @@ -1,3 +1,20 @@ +.. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. + You may obtain a copy of the License at + + https://solderpad.org/licenses/SHL-2.1/ + + Unless required by applicable law or agreed to in writing, any work + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + Changelog ========= diff --git a/docs/source/register_file.rst b/docs/source/register_file.rst index 2c16e90e7..662c2882a 100644 --- a/docs/source/register_file.rst +++ b/docs/source/register_file.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _register-file: diff --git a/docs/source/sleep.rst b/docs/source/sleep.rst index cc01f4c65..0a4b793a5 100644 --- a/docs/source/sleep.rst +++ b/docs/source/sleep.rst @@ -1,19 +1,19 @@ .. - Copyright (c) 2023 OpenHW Group - - Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. + Copyright 2024 OpenHW Group and Dolphin Design + SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 + + Licensed under the Solderpad Hardware License v 2.1 (the "License"); + you may not use this file except in compliance with the License, or, + at your option, the Apache License version 2.0. You may obtain a copy of the License at - https://solderpad.org/licenses/ + https://solderpad.org/licenses/SHL-2.1/ - Unless required by applicable law or agreed to in writing, software + Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 .. _sleep_unit: From 2b3c047a23441b9b4bbb4de3cf81e97861bd6220 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 10 Apr 2024 11:03:55 +0200 Subject: [PATCH 48/69] Added OpenHW group logo on pdf front page. Signed-off-by: Pascal Gouedo --- docs/images/openhw-landscape.png | Bin 0 -> 26149 bytes docs/source/conf.py | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100755 docs/images/openhw-landscape.png diff --git a/docs/images/openhw-landscape.png b/docs/images/openhw-landscape.png new file mode 100755 index 0000000000000000000000000000000000000000..fab0f7e7154a97825c89b5449a229cdf6ef9f963 GIT binary patch literal 26149 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 literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py index 573f5073e..a233ce83e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -44,7 +44,7 @@ # The short X.Y version version = u'' # The full version, including alpha/beta/rc tags -release = u'' +release = u'v1.7.1' # -- General configuration --------------------------------------------------- @@ -148,6 +148,8 @@ # -- Options for LaTeX output ------------------------------------------------ +latex_logo = '../images/openhw-landscape.png' + latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # From dbcd1cb3a0caf153e7474488acd0e52898ca258a Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 10 Apr 2024 19:03:36 +0200 Subject: [PATCH 49/69] Reverted PR #977 correction for Issue #975 Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_id_stage.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/cv32e40p_id_stage.sv b/rtl/cv32e40p_id_stage.sv index 6d8b884d2..f323cbe5f 100644 --- a/rtl/cv32e40p_id_stage.sv +++ b/rtl/cv32e40p_id_stage.sv @@ -1355,7 +1355,7 @@ module cv32e40p_id_stage .hwlp_dec_cnt_i(hwlp_dec_cnt) ); - assign hwlp_valid = (instr_valid_i | csr_status) & clear_instr_valid_o; + assign hwlp_valid = instr_valid_i & clear_instr_valid_o; // hwloop register id assign hwlp_regid = instr[7]; // rd contains hwloop register id From 07050d7456c52c414754ae1ffda1c49697e33363 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Wed, 10 Apr 2024 19:04:14 +0200 Subject: [PATCH 50/69] New correction for Issue #975 Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_controller.sv | 40 +++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/rtl/cv32e40p_controller.sv b/rtl/cv32e40p_controller.sv index a41e345d4..d1c86d6c8 100644 --- a/rtl/cv32e40p_controller.sv +++ b/rtl/cv32e40p_controller.sv @@ -597,7 +597,17 @@ module cv32e40p_controller import cv32e40p_pkg::*; csr_status_i: begin halt_if_o = 1'b1; - ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE; + if (~id_ready_i) begin + ctrl_fsm_ns = DECODE; + end else begin + ctrl_fsm_ns = FLUSH_EX; + if (hwlp_end0_eq_pc) begin + hwlp_dec_cnt_o[0] = 1'b1; + end + if (hwlp_end1_eq_pc) begin + hwlp_dec_cnt_o[1] = 1'b1; + end + end end data_load_event_i: begin @@ -617,7 +627,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; ctrl_fsm_ns = hwlp_end0_eq_pc_plus4 || hwlp_end1_eq_pc_plus4 ? DECODE : DECODE_HWLOOP; // we can be at the end of HWloop due to a return from interrupt or ecall or ebreak or exceptions - if(hwlp_end0_eq_pc && hwlp_counter0_gt_1) begin + if (hwlp_end0_eq_pc && hwlp_counter0_gt_1) begin pc_mux_o = PC_HWLOOP; if (~jump_done_q) begin pc_set_o = 1'b1; @@ -791,7 +801,17 @@ module cv32e40p_controller import cv32e40p_pkg::*; csr_status_i: begin halt_if_o = 1'b1; - ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE_HWLOOP; + if (~id_ready_i) begin + ctrl_fsm_ns = DECODE_HWLOOP; + end else begin + ctrl_fsm_ns = FLUSH_EX; + if (hwlp_end0_eq_pc) begin + hwlp_dec_cnt_o[0] = 1'b1; + end + if (hwlp_end1_eq_pc) begin + hwlp_dec_cnt_o[1] = 1'b1; + end + end end data_load_event_i: begin @@ -1067,16 +1087,10 @@ module cv32e40p_controller import cv32e40p_pkg::*; end csr_status_i: begin - - if(hwlp_end0_eq_pc && hwlp_counter0_gt_1) begin - pc_mux_o = PC_HWLOOP; - pc_set_o = 1'b1; - hwlp_dec_cnt_o[0] = 1'b1; - end - if(hwlp_end1_eq_pc && hwlp_counter1_gt_1) begin - pc_mux_o = PC_HWLOOP; - pc_set_o = 1'b1; - hwlp_dec_cnt_o[1] = 1'b1; + if ((hwlp_end0_eq_pc && !hwlp_counter0_eq_0) || + (hwlp_end1_eq_pc && !hwlp_counter1_eq_0)) begin + pc_mux_o = PC_HWLOOP; + pc_set_o = 1'b1; end end From 8156053a5f4be30d9031df8169b7e25aa6a4b17a Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 15 Apr 2024 11:21:45 +0200 Subject: [PATCH 51/69] User Manual piepline section slight correction. Signed-off-by: Pascal Gouedo --- docs/source/pipeline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/pipeline.rst b/docs/source/pipeline.rst index 9faf965d3..8b5501e37 100644 --- a/docs/source/pipeline.rst +++ b/docs/source/pipeline.rst @@ -151,7 +151,7 @@ The cycle counts assume zero stall on the instruction-side interface and zero st | Comparison, Conversion | | If there are enough instructions between FPU one and | | or Classify | | the instruction using the result then cycle number is 1. | +------------------------+--------------------------------------+ "Enough instruction" number is either FPU_ADDMUL_LAT, | - | Single Precision | 1..19 | FPU_OTHERS_LAT or 11. | + | Single Precision | 1..19 | FPU_OTHERS_LAT or 19. | | Floating-Point | | If there are no instruction in between then cycle number is | | Division and | | the maximum value for each category. | | Square-Root | | | From 9937e76e19fad7f3ee98f1f91f8320b767790b4e Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 16 Apr 2024 11:12:54 +0200 Subject: [PATCH 52/69] Removed redundant statements (v1 and all v2 configs LEC compliant). Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_decoder.sv | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/rtl/cv32e40p_decoder.sv b/rtl/cv32e40p_decoder.sv index 7d7fb676b..e2ffa38d5 100644 --- a/rtl/cv32e40p_decoder.sv +++ b/rtl/cv32e40p_decoder.sv @@ -1057,7 +1057,6 @@ module cv32e40p_decoder 5'b00000: begin fpu_op = cv32e40p_fpu_pkg::ADD; fp_op_group = ADDMUL; - apu_op_o = 2'b0; alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD; alu_op_c_mux_sel_o = OP_C_REGB_OR_FWD; end @@ -1066,7 +1065,6 @@ module cv32e40p_decoder fpu_op = cv32e40p_fpu_pkg::ADD; fpu_op_mod = 1'b1; fp_op_group = ADDMUL; - apu_op_o = 2'b1; alu_op_b_mux_sel_o = OP_B_REGA_OR_FWD; alu_op_c_mux_sel_o = OP_C_REGB_OR_FWD; end @@ -1085,7 +1083,6 @@ module cv32e40p_decoder regb_used_o = 1'b0; fpu_op = cv32e40p_fpu_pkg::SQRT; fp_op_group = DIVSQRT; - apu_op_o = 1'b1; // rs2 must be zero if (instr_rdata_i[24:20] != 5'b00000) illegal_insn_o = 1'b1; end @@ -1213,7 +1210,6 @@ module cv32e40p_decoder fpu_op = cv32e40p_fpu_pkg::F2I; fp_op_group = CONV; fpu_op_mod = instr_rdata_i[20]; // signed/unsigned switch - apu_op_o = 2'b1; unique case (instr_rdata_i[26:25]) //fix for casting to different formats other than FP32 2'b00: begin @@ -1249,7 +1245,6 @@ module cv32e40p_decoder fpu_op = cv32e40p_fpu_pkg::I2F; fp_op_group = CONV; fpu_op_mod = instr_rdata_i[20]; // signed/unsigned switch - apu_op_o = 2'b0; // bits [21:20] used, other bits must be 0 if (instr_rdata_i[24:21]) illegal_insn_o = 1'b1; // in RV32, no casts to L allowed. end @@ -1425,25 +1420,21 @@ module cv32e40p_decoder unique case (instr_rdata_i[6:0]) // fmadd.fmt - FP Fused multiply-add OPCODE_OP_FMADD : begin - fpu_op = cv32e40p_fpu_pkg::FMADD; - apu_op_o = 2'b00; + fpu_op = cv32e40p_fpu_pkg::FMADD; end // fmsub.fmt - FP Fused multiply-subtract OPCODE_OP_FMSUB : begin - fpu_op = cv32e40p_fpu_pkg::FMADD; - fpu_op_mod = 1'b1; - apu_op_o = 2'b01; + fpu_op = cv32e40p_fpu_pkg::FMADD; + fpu_op_mod = 1'b1; end // fnmsub.fmt - FP Negated fused multiply-subtract OPCODE_OP_FNMSUB : begin - fpu_op = cv32e40p_fpu_pkg::FNMSUB; - apu_op_o = 2'b10; + fpu_op = cv32e40p_fpu_pkg::FNMSUB; end // fnmadd.fmt - FP Negated fused multiply-add OPCODE_OP_FNMADD : begin - fpu_op = cv32e40p_fpu_pkg::FNMSUB; - fpu_op_mod = 1'b1; - apu_op_o = 2'b11; + fpu_op = cv32e40p_fpu_pkg::FNMSUB; + fpu_op_mod = 1'b1; end default : ; endcase @@ -1493,6 +1484,7 @@ module cv32e40p_decoder // Set FPnew OP and OPMOD as the APU op apu_op_o = {fpu_vec_op, fpu_op_mod, fpu_op}; + // No FPU or (ZFINX == 0 && MSTATUS.FS == FS_OFF) end else begin illegal_insn_o = 1'b1; From 0133aa4eea1dec7c437ef37110d7e466d8531748 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Tue, 16 Apr 2024 14:52:03 +0200 Subject: [PATCH 53/69] Added missing case default. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_decoder.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/rtl/cv32e40p_decoder.sv b/rtl/cv32e40p_decoder.sv index e2ffa38d5..b98400b29 100644 --- a/rtl/cv32e40p_decoder.sv +++ b/rtl/cv32e40p_decoder.sv @@ -1359,6 +1359,7 @@ module cv32e40p_decoder NONCOMP : apu_lat_o = (FPU_OTHERS_LAT<2) ? FPU_OTHERS_LAT+1 : 2'h3; // CONV uses the same latency for all formats CONV : apu_lat_o = (FPU_OTHERS_LAT<2) ? FPU_OTHERS_LAT+1 : 2'h3; + default: ; endcase // Set FPnew OP and OPMOD as the APU op From b5455191a776329758839f7fb9f496bdcc3e16ea Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 18 Apr 2024 12:41:59 +0200 Subject: [PATCH 54/69] Better description of some SIMD instructions related to Imm6 unused bits and corrected the encoding description. Signed-off-by: Pascal Gouedo --- docs/source/instruction_set_extensions.rst | 596 +++++++++++---------- 1 file changed, 305 insertions(+), 291 deletions(-) diff --git a/docs/source/instruction_set_extensions.rst b/docs/source/instruction_set_extensions.rst index 1aa54bbcf..03dca5191 100644 --- a/docs/source/instruction_set_extensions.rst +++ b/docs/source/instruction_set_extensions.rst @@ -1384,7 +1384,7 @@ SIMD ALU operations | | Only Imm6[3:0] and rs2[3:0] are used for .h instruction and | | | Imm6[2:0] and rs2[2:0] for .b instruction. | | | | - | | Other bits are not used and must be set to 0. | + | | In .sci case, unused Imm6 bits must be set to 0. | +------------------------------------------------------------+------------------------------------------------------------------+ | **cv.sra[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] >>> op2[i] | | | | @@ -1393,7 +1393,7 @@ SIMD ALU operations | | Only Imm6[3:0] and rs2[3:0] are used for .h instruction and | | | Imm6[2:0] and rs2[2:0] for .b instruction. | | | | - | | Other bits are not used and must be set to 0. | + | | In .sci case, unused Imm6 bits must be set to 0. | +------------------------------------------------------------+------------------------------------------------------------------+ | **cv.sll[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] << op2[i] | | | | @@ -1402,7 +1402,7 @@ SIMD ALU operations | | Only Imm6[3:0] and rs2[3:0] are used for .h instruction and | | | Imm6[2:0] and rs2[2:0] for .b instruction. | | | | - | | Other bits are not used and must be set to 0. | + | | In .sci case, unused Imm6 bits must be set to 0. | +------------------------------------------------------------+------------------------------------------------------------------+ | **cv.or[.sc,.sci]{.h,.b} rD, rs1, [rs2, Imm6]** | rD[i] = rs1[i] \| op2[i] | +------------------------------------------------------------+------------------------------------------------------------------+ @@ -1425,20 +1425,32 @@ SIMD Bit Manipulation operations | **Mnemonic** | **Description** | +=======================================+=======================================================================================+ | **cv.extract.h rD, rs1, Imm6** | rD = Sext(rs1[I0\*16+15:I0\*16]) | + | | | + | | Note: Only Imm6[0] bit is used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ | **cv.extract.b rD, rs1, Imm6** | rD = Sext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | + | | | + | | Note: Only Imm6[1:0] bits are used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ | **cv.extractu.h rD, rs1, Imm6** | rD = Zext(rs1[I0\*16+15:I0\*16]) | + | | | + | | Note: Only Imm6[0] bit is used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ | **cv.extractu.b rD, rs1, Imm6** | rD = Zext(rs1[(I1:I0)\*8+7:(I1:I0)\*8]) | + | | | + | | Note: Only Imm6[1:0] bits are used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ | **cv.insert.h rD, rs1, Imm6** | rD[I0\*16+15:I0\*16] = rs1[15:0] | | | | | | Note: The rest of the bits of rD are untouched and keep their previous value. | + | | | + | | Only Imm6[0] bit is used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ | **cv.insert.b rD, rs1, Imm6** | rD[(I1:I0)\*8+7:(I1:I0)\*8] = rs1[7:0] | | | | | | Note: The rest of the bits of rD are untouched and keep their previous value. | + | | | + | | Only Imm6[1:0] bits are used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ SIMD Dot Product operations @@ -1531,6 +1543,8 @@ SIMD Shuffle and Pack operations | **cv.shuffle.sci.h rD, rs1, Imm6** | rD[31:16] = rs1[I1\*16+15:I1\*16] | | | | | | rD[15:0] = rs1[I0\*16+15:I0\*16] | + | | | + | | Note: Only Imm6[1:0] bits are used and other Imm6 bits must be set to 0. | +---------------------------------------+---------------------------------------------------------------------------------------+ | **cv.shuffle.b rD, rs1, rs2** | rD[31:24] = rs1[rs2[25:24]\*8+7:rs2[25:24]\*8] | | | | @@ -1610,296 +1624,296 @@ SIMD ALU Encoding .. table:: SIMD ALU encoding :name: SIMD ALU encoding - :widths: 11 4 4 9 7 8 8 13 36 + :widths: 11 4 4 13 7 8 8 13 32 :class: no-scrollbar-table - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | - +============+=======+====+=========+=========+============+==========+============+======================================+ - | 0 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.add.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.add.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.add.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.add.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.add.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sub.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sub.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sub.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sub.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sub.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avg.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avg.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avg.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avg.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avg.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avg.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avgu.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avgu.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avgu.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avgu.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avgu.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avgu.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.min.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.min.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.min.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.min.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.min.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.min.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.minu.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.minu.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.minu.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.minu.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.minu.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.minu.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.max.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0110 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.max.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.max.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0110 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.max.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0110 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.max.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.max.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0111 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.maxu.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0111 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.maxu.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.maxu.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.maxu.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0111 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.maxu.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.maxu.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.srl.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.srl.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.srl.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.srl.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.srl.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.srl.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sra.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sra.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sra.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sra.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sra.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sra.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sll.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sll.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sll.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sll.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sll.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sll.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.or.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.or.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.or.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.or.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.or.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.or.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.xor.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.xor.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.xor.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.xor.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.xor.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.xor.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.and.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.and.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.and.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.and.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.and.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.and.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1110 | 0 | 0 | 0 | src1 | 000 | dest | 111 1011 | **cv.abs.h rD, rs1** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 0 1110 | 0 | 0 | 0 | src1 | 001 | dest | 111 1011 | **cv.abs.b rD, rs1** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 000 | dest | 111 1011 | **cv.extract.h rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 001 | dest | 111 1011 | **cv.extract.b rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 010 | dest | 111 1011 | **cv.extractu.h rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 011 | dest | 111 1011 | **cv.extractu.b rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 100 | dest | 111 1011 | **cv.insert.h rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 0111 | 0 | Imm6[0\|5:1] | src1 | 101 | dest | 111 1011 | **cv.insert.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotup.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotup.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotup.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotup.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotup.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotup.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotusp.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotusp.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotusp.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotusp.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotusp.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotusp.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotsp.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotsp.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotsp.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotsp.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotsp.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotsp.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotup.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotup.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotup.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotup.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotup.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotup.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotusp.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotusp.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotusp.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotusp.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotusp.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotusp.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotsp.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotsp.sc.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotsp.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotsp.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotsp.sc.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotsp.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.shuffle.sci.h rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI0.sci.b rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI1.sci.b rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI2.sci.b rD, rs1, Imm6** | - +------------+-------+--------------+---------+------------+----------+------------+--------------------------------------+ - | 1 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI3.sci.b rD, rs1, Imm6** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle2.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle2.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1110 | 0 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack.h rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1111 | 0 | 1 | src2 | src1 | 001 | dest | 111 1011 | **cv.packhi.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ - | 1 1111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.packlo.b rD, rs1, rs2** | - +------------+-------+----+---------+---------+------------+----------+------------+--------------------------------------+ + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 31 : 27 | 26 | 25 | 24 : 20 | 19 : 15 | 14 : 12 | 11 : 7 | 6 : 0 | | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | **funct5** | **F** | | **rs2** | **rs1** | **funct3** | **rD** | **opcode** | | + +============+=======+====+==================+=========+============+==========+============+======================================+ + | 0 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.add.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.add.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.add.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.add.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.add.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.add.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sub.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sub.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sub.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sub.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sub.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sub.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avg.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avg.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avg.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avg.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avg.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avg.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.avgu.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.avgu.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.avgu.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.avgu.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.avgu.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.avgu.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.min.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.min.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.min.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.min.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.min.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.min.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.minu.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.minu.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.minu.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.minu.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.minu.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.minu.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.max.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.max.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.max.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.max.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.max.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0110 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.max.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.maxu.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.maxu.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.maxu.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.maxu.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.maxu.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 0111 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.maxu.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.srl.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.srl.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | Imm6[0] 00 Imm6[3:1] | src1 | 110 | dest | 111 1011 | **cv.srl.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.srl.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.srl.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1000 | 0 | Imm6[0] 000 Imm6[2:1] | src1 | 111 | dest | 111 1011 | **cv.srl.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sra.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sra.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | Imm6[0] 00 Imm6[3:1] | src1 | 110 | dest | 111 1011 | **cv.sra.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sra.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sra.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1001 | 0 | Imm6[0] 000 Imm6[2:1] | src1 | 111 | dest | 111 1011 | **cv.sra.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sll.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sll.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | Imm6[0] 00 Imm6[3:1] | src1 | 110 | dest | 111 1011 | **cv.sll.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sll.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sll.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1010 | 0 | Imm6[0] 000 Imm6[2:1] | src1 | 111 | dest | 111 1011 | **cv.sll.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.or.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.or.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.or.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.or.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.or.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.or.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.xor.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.xor.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.xor.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.xor.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.xor.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.xor.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.and.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.and.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.and.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.and.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.and.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.and.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1110 | 0 | 0 | 0 | src1 | 000 | dest | 111 1011 | **cv.abs.h rD, rs1** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 0 1110 | 0 | 0 | 0 | src1 | 001 | dest | 111 1011 | **cv.abs.b rD, rs1** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0] 00000 | src1 | 000 | dest | 111 1011 | **cv.extract.h rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0] 0000 Imm6[1] | src1 | 001 | dest | 111 1011 | **cv.extract.b rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0] 00000 | src1 | 010 | dest | 111 1011 | **cv.extractu.h rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0] 0000 Imm6[1] | src1 | 011 | dest | 111 1011 | **cv.extractu.b rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0] 00000 | src1 | 100 | dest | 111 1011 | **cv.insert.h rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0111 | 0 | Imm6[0] 0000 Imm6[1] | src1 | 101 | dest | 111 1011 | **cv.insert.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotup.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotup.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotup.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotup.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotup.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotup.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotusp.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotusp.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotusp.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotusp.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotusp.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotusp.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.dotsp.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.dotsp.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.dotsp.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.dotsp.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.dotsp.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.dotsp.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotup.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotup.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotup.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotup.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotup.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotup.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotusp.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotusp.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotusp.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotusp.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotusp.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0100 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotusp.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.sdotsp.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 100 | dest | 111 1011 | **cv.sdotsp.sc.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 110 | dest | 111 1011 | **cv.sdotsp.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.sdotsp.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | 0 | src2 | src1 | 101 | dest | 111 1011 | **cv.sdotsp.sc.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 0101 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.sdotsp.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | Imm6[0] 0000 Imm6[1] | src1 | 110 | dest | 111 1011 | **cv.shuffle.sci.h rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1000 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI0.sci.b rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1001 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI1.sci.b rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1010 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI2.sci.b rD, rs1, Imm6** | + +------------+-------+-----------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1011 | 0 | Imm6[0\|5:1] | src1 | 111 | dest | 111 1011 | **cv.shuffleI3.sci.b rD, rs1, Imm6** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1100 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.shuffle2.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1100 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.shuffle2.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1110 | 0 | 0 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1110 | 0 | 1 | src2 | src1 | 000 | dest | 111 1011 | **cv.pack.h rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1111 | 0 | 1 | src2 | src1 | 001 | dest | 111 1011 | **cv.packhi.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ + | 1 1111 | 0 | 0 | src2 | src1 | 001 | dest | 111 1011 | **cv.packlo.b rD, rs1, rs2** | + +------------+-------+----+------------------+---------+------------+----------+------------+--------------------------------------+ SIMD Comparison operations From e11ee1983ac529a2d0e943fbc4b0e53e0f14a099 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 18 Apr 2024 12:54:45 +0200 Subject: [PATCH 55/69] Added illegal instruction exception decoding on unused Imm6 bits for some SIMD instructions. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_decoder.sv | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rtl/cv32e40p_decoder.sv b/rtl/cv32e40p_decoder.sv index b98400b29..bda732571 100644 --- a/rtl/cv32e40p_decoder.sv +++ b/rtl/cv32e40p_decoder.sv @@ -2257,6 +2257,11 @@ module cv32e40p_decoder instr_rdata_i[25] != 1'b0) begin illegal_insn_o = 1'b1; end + // Imm6 restrictions + if ((instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:23] != 2'b0) || + (instr_rdata_i[14:12] == 3'b111 && instr_rdata_i[24:22] != 3'b0)) begin + illegal_insn_o = 1'b1; + end end 6'b01001_0: begin // cv.sra alu_operator_o = ALU_SRA; @@ -2268,6 +2273,11 @@ module cv32e40p_decoder instr_rdata_i[25] != 1'b0) begin illegal_insn_o = 1'b1; end + // Imm6 restrictions + if ((instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:23] != 2'b0) || + (instr_rdata_i[14:12] == 3'b111 && instr_rdata_i[24:22] != 3'b0)) begin + illegal_insn_o = 1'b1; + end end 6'b01010_0: begin // cv.sll alu_operator_o = ALU_SLL; @@ -2279,6 +2289,11 @@ module cv32e40p_decoder instr_rdata_i[25] != 1'b0) begin illegal_insn_o = 1'b1; end + // Imm6 restrictions + if ((instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:23] != 2'b0) || + (instr_rdata_i[14:12] == 3'b111 && instr_rdata_i[24:22] != 3'b0)) begin + illegal_insn_o = 1'b1; + end end 6'b01011_0: begin // cv.or alu_operator_o = ALU_OR; @@ -2415,6 +2430,11 @@ module cv32e40p_decoder end default: illegal_insn_o = 1'b1; endcase + // Imm6 restrictions + if ((instr_rdata_i[12] == 1'b0 && instr_rdata_i[24:20] != 5'b0) || + (instr_rdata_i[12] == 1'b1 && instr_rdata_i[24:21] != 4'b0)) begin + illegal_insn_o = 1'b1; + end end 6'b11000_0: begin // cv.shuffle, cv.shuffleI0 alu_operator_o = ALU_SHUF; @@ -2429,6 +2449,10 @@ module cv32e40p_decoder instr_rdata_i[25] != 1'b0) begin illegal_insn_o = 1'b1; end + // Imm6 restriction + if (instr_rdata_i[14:12] == 3'b110 && instr_rdata_i[24:21] != 4'b0) begin + illegal_insn_o = 1'b1; + end end 6'b11001_0, 6'b11010_0, From 64e6f27714f9d8eec1c1fcc08e318ba9f9239127 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 18 Apr 2024 13:01:25 +0200 Subject: [PATCH 56/69] Updated User Manual release to v1.8.0 Signed-off-by: Pascal Gouedo --- docs/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index a233ce83e..3e24854b3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -44,7 +44,7 @@ # The short X.Y version version = u'' # The full version, including alpha/beta/rc tags -release = u'v1.7.1' +release = u'v1.8.0' # -- General configuration --------------------------------------------------- From 46dc9b56c3ee518d5926b48cda89c3cbea3365da Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 18 Apr 2024 15:46:00 +0200 Subject: [PATCH 57/69] RTL cleanup for SiemensEDA Tessent. Signed-off-by: Pascal Gouedo --- rtl/cv32e40p_decoder.sv | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/cv32e40p_decoder.sv b/rtl/cv32e40p_decoder.sv index bda732571..c1608eb4a 100644 --- a/rtl/cv32e40p_decoder.sv +++ b/rtl/cv32e40p_decoder.sv @@ -1318,20 +1318,20 @@ module cv32e40p_decoder // check rounding mode if (check_fprm) begin unique case (instr_rdata_i[14:12]) inside - [3'b000:3'b100]: ; //legal rounding modes + 3'b000, 3'b001, 3'b010, 3'b011, 3'b100: ; //legal rounding modes 3'b101: begin // Alternative Half-Precsision encded as fmt=10 and rm=101 if (~C_XF16ALT || fpu_dst_fmt_o != cv32e40p_fpu_pkg::FP16ALT) illegal_insn_o = 1'b1; // actual rounding mode from frm csr unique case (frm_i) inside - [3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes - default : illegal_insn_o = 1'b1; + 3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes + default : illegal_insn_o = 1'b1; endcase end 3'b111: begin // rounding mode from frm csr unique case (frm_i) inside - [3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes - default : illegal_insn_o = 1'b1; + 3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes + default : illegal_insn_o = 1'b1; endcase end default : illegal_insn_o = 1'b1; @@ -1451,19 +1451,19 @@ module cv32e40p_decoder // check rounding mode unique case (instr_rdata_i[14:12]) inside - [3'b000:3'b100]: ; //legal rounding modes + 3'b000, 3'b001, 3'b010, 3'b011, 3'b100: ; //legal rounding modes 3'b101: begin // Alternative Half-Precsision encded as fmt=10 and rm=101 if (~C_XF16ALT || fpu_dst_fmt_o != cv32e40p_fpu_pkg::FP16ALT) illegal_insn_o = 1'b1; // actual rounding mode from frm csr unique case (frm_i) inside - [3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes + 3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes default : illegal_insn_o = 1'b1; endcase end 3'b111: begin // rounding mode from frm csr unique case (frm_i) inside - [3'b000:3'b100] : fp_rnd_mode_o = frm_i; //legal rounding modes + 3'b000, 3'b001, 3'b010, 3'b011, 3'b100 : fp_rnd_mode_o = frm_i; //legal rounding modes default : illegal_insn_o = 1'b1; endcase end From 7b9bf598f8401ef3984ec5a74144e264477f3347 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 26 Apr 2024 13:09:59 +0800 Subject: [PATCH 58/69] Trace log - Correcting cv.bneimm and cv.beqimm printing --- bhv/cv32e40p_instr_trace.svh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index 8b08105b1..355bc7382 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -534,7 +534,7 @@ class instr_trace_t; begin mnemonic = {compressed ? "c." : "", mnemonic}; regs_read.push_back('{rs1, rs1_value, 0}); - str = $sformatf("%-16s %s, %0d", mnemonic, regAddrToStr(rs1), $signed(imm_sb_type)); + str = $sformatf("%-16s %s, %0d, %0d", mnemonic, regAddrToStr(rs1), $signed(imm_s2_type), $signed(imm_sb_type)); end endfunction // printSBInstr From 90e982e7409adb0804d86c03b9ba163af63bd555 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 26 Apr 2024 13:10:27 +0800 Subject: [PATCH 59/69] RVFI - Set proper write mask for mstatus fs when writes to frm --- bhv/pipe_freeze_trace.sv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bhv/pipe_freeze_trace.sv b/bhv/pipe_freeze_trace.sv index fe6e6bfae..39a16fa62 100644 --- a/bhv/pipe_freeze_trace.sv +++ b/bhv/pipe_freeze_trace.sv @@ -369,7 +369,10 @@ function compute_csr_we(); r_pipe_freeze_trace.csr.fflags_we = 1'b1; r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; end - CSR_FRM: r_pipe_freeze_trace.csr.frm_we = 1'b1; + CSR_FRM: begin + r_pipe_freeze_trace.csr.frm_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end CSR_FCSR: begin r_pipe_freeze_trace.csr.fcsr_we = 1'b1; r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; From a33cec0904c6c387071a8d72721b78a11524e499 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Fri, 26 Apr 2024 11:34:40 +0200 Subject: [PATCH 60/69] Added HWloop CSRs save/restore Signed-off-by: Pascal Gouedo --- docs/source/corev_hw_loop.rst | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/source/corev_hw_loop.rst b/docs/source/corev_hw_loop.rst index 01eaca33f..6653ce1f5 100644 --- a/docs/source/corev_hw_loop.rst +++ b/docs/source/corev_hw_loop.rst @@ -142,13 +142,13 @@ At the end of the loop, the register %[i] contains 300 and the register %[j] con .. _hwloop-exceptions_handlers: -Hardware loops impact on application, exceptions handlers and debugger -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Hardware loops impact on application, exception handlers and debug program +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Application and ebreak/ecall exception handlers ----------------------------------------------- -When an ebreak or an ecall instruction is used in an application, special care should be given for those instruction handlers in case they are placed as the last instruction of an HWLoop. +When an ebreak or an ecall instruction is used in an application, special care should be given for their respective exception handler in case those instructions are the last one of an HWLoop. Those handlers should manage MEPC and lpcountX CSRs updates because an hw loop early-exit could happen if not done. At the end of the handlers after restoring the context/CSRs, a piece of smart code should be added with following highest to lowest order of priority: @@ -167,9 +167,7 @@ Interrupt handlers ------------------ When an interrupt is happening on the last HWLoop instruction, its execution is cancelled, its address is saved in MEPC and its execution will be resumed when returning from interrupt handler. -There is nothing special to be done in those interrupt handlers with respect to MEPC and lpcountX updates, they will be correctly managed by design when executing this last HWLoop instruction after interrupt handler execution. - -Moreover since hardware loop could be used in interrupt routine, the registers have to be saved (resp. restored) at the beginning (resp. end) of the interrupt routine together with the general purpose registers. +There is nothing special to be done in those interrupt handlers with respect to MEPC and lpcountX updates (except HWloop CSRs save/restore mentioned below), they will be correctly managed by design when executing this last HWLoop instruction after interrupt handler execution. Illegal instruction exception handler ------------------------------------- @@ -179,11 +177,17 @@ Depending if an application is going to resume or not after Illegal instruction Debugger -------- -If ebreak is used to enter in Debug Mode (:ref:`ebreak_scenario_2`) and put at the last instruction location of an HWLoop (not very likely to happen), same management than above should be done but on DPC rather than on MEPC. +If ebreak is used to enter in Debug Mode (:ref:`ebreak_scenario_2`) and put at the last instruction location of an HWLoop, same management than above should be done but on DPC rather than on MEPC. When ebreak instruction is used as Software Breakpoint by a debugger when in debug mode and is placed at the last instruction location of an HWLoop in instruction memory, no special management is foreseen. When executing the Software Breakpoint/ebreak instruction, control is given back to the debugger which will manage the different cases. For instance in Single-Step case, original instruction is put back in instruction memory, a Single-Step command is executed on this last instruction (with desgin updating PC and lpcountX to correct values) and Software Breakpoint/ebreak is put back by the debugger in memory. -When ecall instruction is used by a debugger to execute System Calls and is placed at the last instruction location of an HWLoop in instruction memory, debugger ecall handler in debug rom should do the same than described above for application case. +When ecall instruction is used by a debugger to execute System Calls and is placed at the last instruction location of an HWLoop in instruction memory, debugger ecall handler in debug program should do the same than described above for application case. + +HWloop CSRs save and restore +---------------------------- + +As synchronous/asynchronous exception or a debug event happening during HWloop execution is interrupting the normal HWloop execution, special care should be given to HWloop CSRs in case any exception handler or debug program is going to use HWloop feature (or even just call functions using them like memmove, memcpy...). +So HWloop CSRs save/restore should be added together with the general purpose registers to exception handlers or debug program. From 9792d3733e1b1577de8ddb5439edd381d47d93e7 Mon Sep 17 00:00:00 2001 From: Mike Thompson Date: Fri, 24 May 2024 12:16:49 -0400 Subject: [PATCH 61/69] Update pointer to v1.0.0 coverage reports --- docs/source/verification.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/verification.rst b/docs/source/verification.rst index 56d71a834..b3f9199a9 100644 --- a/docs/source/verification.rst +++ b/docs/source/verification.rst @@ -30,7 +30,7 @@ v1.0.0 verification In early 2021 the CV32E40P achieved Functional RTL Freeze (released with cv32e40p_v1.0.0 version), meaning that is has been fully verified as per its `Verification Plan `_. -Final functional, code and test coverage reports can be found `here `_. +Final functional, code and test coverage reports can be found `here `_. The unofficial start date for the CV32E40P verification effort is 2020-02-27, which is the date the core-v-verif environment "went live". Between then and From 869d205d2e134152787a7d328a7e1497a1d95680 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 30 May 2024 15:41:10 +0200 Subject: [PATCH 62/69] Few lec scripts cleanup and improvements. Signed-off-by: Pascal Gouedo --- scripts/slec/cadence/lec.tcl | 30 +++++++++++++++--------------- scripts/slec/synopsys/lec.tcl | 3 +++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/scripts/slec/cadence/lec.tcl b/scripts/slec/cadence/lec.tcl index e62046b73..dcc241e63 100644 --- a/scripts/slec/cadence/lec.tcl +++ b/scripts/slec/cadence/lec.tcl @@ -1,18 +1,18 @@ -// Copyright 2024 OpenHW Group and Dolphin Design -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); -// you may not use this file except in compliance with the License, or, -// at your option, the Apache License version 2.0. -// You may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +# Copyright 2024 OpenHW Group and Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# +# Licensed under the Solderpad Hardware License v 2.1 (the “License”); +# you may not use this file except in compliance with the License, or, +# at your option, the Apache License version 2.0. +# You may obtain a copy of the License at +# +# https://solderpad.org/licenses/SHL-2.1/ +# +# Unless required by applicable law or agreed to in writing, any work +# distributed under the License is distributed on an “AS IS” BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. set summary_log $::env(summary_log) set top_module $::env(top_module) diff --git a/scripts/slec/synopsys/lec.tcl b/scripts/slec/synopsys/lec.tcl index 7d17722c0..e3c09e997 100644 --- a/scripts/slec/synopsys/lec.tcl +++ b/scripts/slec/synopsys/lec.tcl @@ -15,6 +15,8 @@ # limitations under the License. set synopsys_auto_setup true +set verification_failing_point_limit 0 + set summary_log $::env(summary_log) set top_module $::env(top_module) set version $::env(version) @@ -55,6 +57,7 @@ if {"$top_module" == "cv32e40p_core"} { verify > $summary_log +report_passing_points > $summary_log.passing_points.rpt report_aborted_points > $summary_log.aborted_points.rpt report_failing_points > $summary_log.failing_points.rpt From cde0b3f1bc5381b26f7d3fa60bda1f44500abe61 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 30 May 2024 16:41:31 +0200 Subject: [PATCH 63/69] User Manual verification section update. Signed-off-by: Pascal Gouedo --- docs/source/verification.rst | 104 ++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/docs/source/verification.rst b/docs/source/verification.rst index b3f9199a9..3b0de4bd8 100644 --- a/docs/source/verification.rst +++ b/docs/source/verification.rst @@ -145,17 +145,17 @@ Verification environment is described in `CORE-V Verification Strategy `_. -Final functional, code and test coverage reports can be found here: `CV32E40P v2.0.0 Report `_. +CV32E40Pv2 achieved RTL Freeze (released with cv32e40p_v1.8.0 version) mid-April 2024, meaning that is has been fully verified as per its +`Verification Plan `_. +Summary and all reports links (RTL code, functional, tests) can be found here: `CV32E40P v2.0.0 Summary and Reports `_. -It is to be mentioned that CV32E40Pv2 has successfully executed `RISCOF (RISC-V COmpatibility Framework) `_ for RV32IMCF extensions. -Report can be found `here `_. +It is to be mentioned that CV32E40Pv2 has successfully executed `RISCOF (RISC-V COmpatibility Framework) `_ for RV32IMCF extensions . +The official RISCOF reports can be found following the link mentioned above. -Formal verification -^^^^^^^^^^^^^^^^^^^ +RISC-V ISA Formal verification +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To accelerate the verification of more than 300 XPULP instructions, Formal Verification methodology has been used with Siemens EDA Onespin tool and its RISC-V ISA Processor Verification app. +To accelerate the verification of more than 300 XPULP instructions, RISC-V ISA Formal Verification methodology has been used with Siemens EDA Onespin tool and its RISC-V ISA Processor Verification app. The XPULP instructions pseudo-code description using Sail language have been added to the RISC-V ISA app to successfully formally verify all the CV32E40P instructions, including the previously verified standard IMC together with the new F, Zfinx and XPULP extensions and all additional custom CSRs. @@ -174,8 +174,8 @@ Example: EXTZ(mul(X(rs1)[31..24],X(rs2)[31..24]))" }, -Those SAIL instructions description are then used to automatically generate more than 430 assertions and 29 CSRs descriptions. -Those assertions have been applied on the 7 different configurations listed in :ref:`Verified configurations` table. +Those SAIL instructions description are then used to automatically generate 277 assertions and 29 CSRs descriptions. +Those assertions have been applied on the 7 different configurations listed in :ref:`Verified configurations` table on intermediate RTL version and were proven as correct. RTL code coverage is generated using Siemens EDA Onespin Quantify tool which uses RTL mutation to check assertions quality and can produce standard UCDB database that can be merged with simulation one afterwards. @@ -191,7 +191,11 @@ Another innovation for v2.0.0 was the adoption of a standardized tracer interfac Results summary ^^^^^^^^^^^^^^^ -30 issues were identified by Formal Verification and 10 by Simulation methodologies, all have been resolved. +RISC-V ISA Formal Verification has been successfully launched on intermediate RTL versions of the 7 different configurations. +But on v1.8.0 RTL tag, only PULP configuration (CFG_P) was fully proven, run-time of more than a month on configurations including the Floating-Point unit prevented to have full results. +Properties status can be found in `CV32E40P v2.0.0 Report `_. + +30 issues were identified by Formal Verification, 20 by Simulation methodologies and 4 by Lint/RTL code review, all have been resolved except 1 about Lint warnings. Here is the breakdown of all the issues: @@ -200,20 +204,20 @@ Here is the breakdown of all the issues: :widths: 27 9 64 :class: no-scrollbar-table - +---------------------+-----------+---------------------------------------------------------------+ - | **"Found By"** | **Count** | **Note** | - +=====================+===========+===============================================================+ - | Formal Verification | 30 | All related to features enabled by ``COREV_PULP`` or ``FPU``. | - +---------------------+-----------+---------------------------------------------------------------+ - | Simulation | 10 | | - +---------------------+-----------+---------------------------------------------------------------+ - | Lint | 2 | | - +---------------------+-----------+---------------------------------------------------------------+ + +--------------------------------+-----------+---------------------------------------------------------------+ + | **"Found By"** | **Count** | **Note** | + +================================+===========+===============================================================+ + | RISC-V ISA Formal Verification | 30 | All related to features enabled by ``COREV_PULP`` or ``FPU``. | + +--------------------------------+-----------+---------------------------------------------------------------+ + | Simulation | 20 | Details below | + +--------------------------------+-----------+---------------------------------------------------------------+ + | Lint/RTL Code review | 4 | | + +--------------------------------+-----------+---------------------------------------------------------------+ -A classification of the Formal Verification issues by type and their description are listed in the following tables: +A classification of the RISC-V ISA Formal Verification issues by type and their description are listed in the following tables: -.. table:: Breakdown of Issues found by Formal Verification in v2.0.0 - :name: Breakdown of Issues found by Formal Verification in v2.0.0 +.. table:: Breakdown of Issues found by RISC-V ISA Formal Verification in v2.0.0 + :name: Breakdown of Issues found by RISC-V ISA Formal Verification in v2.0.0 :widths: 27 9 64 :class: no-scrollbar-table @@ -222,11 +226,11 @@ A classification of the Formal Verification issues by type and their description +==============================+===========+========================================================================================+ | User Manual | 12 | Instructions description leading to mis-interpretation | +------------------------------+-----------+----------------------------------------------------------------------------------------+ - | RTL bugs | 18 | See classification below | + | RTL bugs | 18 | Details below | +------------------------------+-----------+----------------------------------------------------------------------------------------+ -.. table:: Formal Verification Issues Classification in v2.0.0 - :name: Formal Verification Issues Classification in v2.0.0 +.. table:: RISC-V ISA Formal Verification Issues Classification in v2.0.0 + :name: RISC-V ISA Formal Verification Issues Classification in v2.0.0 :widths: 27 9 64 :class: no-scrollbar-table @@ -257,7 +261,7 @@ A classification of the Simulation issues by type and their description are list +------------------------------+-----------+----------------------------------------------------------------------------------------+ | **Type** | **Count** | **Note** | +==============================+===========+========================================================================================+ - | RTL bugs | 10 | See classification below | + | RTL bugs | 20 | See classification below | +------------------------------+-----------+----------------------------------------------------------------------------------------+ .. table:: Simulation Issues Classification in v2.0.0 @@ -265,22 +269,36 @@ A classification of the Simulation issues by type and their description are list :widths: 38 9 53 :class: no-scrollbar-table - +--------------------------------+-----------+---------------------------------------------------------------------------------------+ - | **Issue Type** | **Count** | **Note** | - +================================+===========+=======================================================================================+ - | Multi-cycle F instructions | 5 | Data forward violation between XPULP instructions and muticycle F instructions. | - +--------------------------------+-----------+---------------------------------------------------------------------------------------+ - | Hardware Loops | 3 | Incorrect behavior when count programmed with 0 value. | - | | | | - | | | lpendX CSR updated by a cancelled instruction. | - | | | | - | | | lpcountX not updated after a pipeline flush due to a CSR access. | - +--------------------------------+-----------+---------------------------------------------------------------------------------------+ - | Deadlock | 1 | Bug resolution for multicycle F instructions created a deadlock when conflicting | - | | | Register File write between ALU and FPU. | - +--------------------------------+-----------+---------------------------------------------------------------------------------------+ - | MSTATUS.FS incorrect value | 1 | FS was not updated following any Floating Point Load instruction. | - +--------------------------------+-----------+---------------------------------------------------------------------------------------+ + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | **Issue Type** | **Count** | **Note** | + +==========================================+===========+=======================================================================================+ + | Multi-cycle F instructions | 5 | Data forward violation between XPULP instructions and muticycle F instructions. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Hardware Loops | 4 | Conflict between CSR write and cv.lp* instructions. | + | | | | + | | | Incorrect behavior when count programmed with 0 value. | + | | | | + | | | lpcountX not decremented to 0 at the end of HWloop execution. | + | | | | + | | | lpcountX not updated after a pipeline flush due to a CSR access. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Illegal instructions exception | 3 | Illegal immediates values | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Incorrect Register file control | 1 | ZFINX = 1 case | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | MIMPID incorrect value | 1 | Value depending of FPU, COREV_PULP and COREV_CLUSTER paremeters. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Deadlock | 1 | Bug resolution for multicycle F instructions created a deadlock when conflicting | + | | | Register File write between ALU and FPU. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | MSTATUS.FS incorrect value | 1 | FS was not updated following any Floating Point Load instruction. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Unnecessary multiple Register File write | 1 | Removed redundant Register File writes. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | Missing or unreacheable case defaults | 2 | Found with RTL Code coverage holes analysis. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ + | FPU unnecessary clock enable | 1 | Finer grain clock gating generation. | + +------------------------------------------+-----------+---------------------------------------------------------------------------------------+ Tracer ------ From cc0d4204ec166117125bfc75382fd07f24f8af05 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Thu, 30 May 2024 17:06:23 +0200 Subject: [PATCH 64/69] RISC-V ISA Formal Verification files for SiemensEDA OneSpin tool. Signed-off-by: Pascal Gouedo --- scripts/riscv_isa_formal/Makefile | 59 + scripts/riscv_isa_formal/README.md | 55 + .../riscv_isa_formal/common/basics.tcl.obf | 2 + .../riscv_isa_formal/common/constraints.sv | 119 ++ .../riscv_isa_formal/common/core_checker.sv | 1108 +++++++++++++++++ scripts/riscv_isa_formal/common/io.sv | 72 ++ .../riscv_isa_formal/common/other_bindings.sv | 72 ++ scripts/riscv_isa_formal/common/setup.tcl | 564 +++++++++ scripts/riscv_isa_formal/common/setup_mv.tcl | 8 + scripts/riscv_isa_formal/common/t.sh | 12 + .../riscv_isa_formal/common/vips/obi_dmem.sv | 60 + .../riscv_isa_formal/common/vips/obi_imem.sv | 59 + .../riscv_isa_formal/launch_command example | 58 + 13 files changed, 2248 insertions(+) create mode 100755 scripts/riscv_isa_formal/Makefile create mode 100755 scripts/riscv_isa_formal/README.md create mode 100755 scripts/riscv_isa_formal/common/basics.tcl.obf create mode 100755 scripts/riscv_isa_formal/common/constraints.sv create mode 100755 scripts/riscv_isa_formal/common/core_checker.sv create mode 100755 scripts/riscv_isa_formal/common/io.sv create mode 100755 scripts/riscv_isa_formal/common/other_bindings.sv create mode 100755 scripts/riscv_isa_formal/common/setup.tcl create mode 100755 scripts/riscv_isa_formal/common/setup_mv.tcl create mode 100755 scripts/riscv_isa_formal/common/t.sh create mode 100755 scripts/riscv_isa_formal/common/vips/obi_dmem.sv create mode 100755 scripts/riscv_isa_formal/common/vips/obi_imem.sv create mode 100755 scripts/riscv_isa_formal/launch_command example diff --git a/scripts/riscv_isa_formal/Makefile b/scripts/riscv_isa_formal/Makefile new file mode 100755 index 000000000..f344b819b --- /dev/null +++ b/scripts/riscv_isa_formal/Makefile @@ -0,0 +1,59 @@ +commonPath=../../common +PREPARE?=0 +RTL?=../../cv32e40p/ +GUI?=0 +NAME?=noname + +ifeq ($(APP),) + $(error APP is empty) +endif +ifeq ($(CONF),) + $(error CONF is empty) +endif +ifeq ($(MODE),) + $(error MODE is empty) +endif + +$(info APP=$(APP)) +$(info CONF=$(CONF)) +$(info MODE=$(MODE)) + +ifeq ($(GUI), 1) + flag="-i" +else + flag= +endif + +dirname=$(NAME) + +ifeq ($(PREPARE), 1) + script_name=ones_prepare_run +else + script_name=ones_run +endif + +define ones_prepare_run + @echo "====================================================" + @echo "Preparing working area $(dirname)" + @echo "====================================================" + \mkdir -p cfgs/$(dirname)/logs + \cd cfgs/$(dirname) && \cp -pf $(commonPath)/{other_bindings.sv,core_checker.sv,io.sv,setup.tcl,setup_mv.tcl,*.json,constraints.sv,t.sh,basics.tcl.obf} . && \cp -prfL $(commonPath)/vips . && \cp -prfL $(RTL) . + @echo "====================================================" + @echo "Running mode $(MODE) on configuration $(CONF) in $(dirname)" + @echo "====================================================" + \cd cfgs/$(dirname) && onespin -Q -l logs/$(APP)-cfg_$(CONF)-mode_$(MODE).log $(flag) setup.tcl $(CONF) $(MODE) $(APP) +endef + +define ones_run + @echo "====================================================" + @echo "Running mode $(MODE) on configuration $(CONF) in $(dirname)" + @echo "====================================================" + \cd cfgs/$(dirname) && onespin -Q -l logs/$(APP)-cfg_$(CONF)-mode_$(MODE).log $(flag) setup.tcl $(CONF) $(MODE) $(APP) +endef + +all: + $(call $(script_name)) + +clean: + rm -rf cfgs/$(dirname) + diff --git a/scripts/riscv_isa_formal/README.md b/scripts/riscv_isa_formal/README.md new file mode 100755 index 000000000..3786eebef --- /dev/null +++ b/scripts/riscv_isa_formal/README.md @@ -0,0 +1,55 @@ +# RISC-V ISA Formal Verification + +RISC-V ISA Formal Verification methodology has been used with Siemens EDA Onespin tool and its RISC-V ISA Processor Verification app. + +## Configurations + + +--------------------+-----------------------------------------------------------------------------+ + | | **Verified Configurations** | + +====================+========+==========+==========+==========+===========+===========+===========+ + | **Top Parameters** | **XP** | **XPF0** | **XPF1** | **XPF2** | **XPZF0** | **XPZF1** | **XPZF2** | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + | COREV_PULP | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + | COREV_CLUSTER | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + | FPU | 0 | 1 | 1 | 1 | 1 | 1 | 1 | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + | ZFINX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + | FPU_ADDMUL_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + | FPU_OTHERS_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | + +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + +## Tool apps + +- PRC : Property Checking +- QTF : Quantify +- VCI : Verification Coverage Integration + +## Prove modes + +- DEF : Control path verification of all instructions and datapath verification of all instructions except multiplication, division or floating point ones +- DPM : Data path verification of multiplication/ division instructions +- DPF : Data path verification of floating-point instructions + +## Directory Structure of this Repo + +- Makefile +- launch_command_example + +### common +Contains all files to create assertions and to launch different tool apps on different configurations and using different modes. + +## How to launch a run + +- Locally clone cv32e40p github repository or make a symbolic link to an existing repo. +- launch following command: make GUI=1 APP=PRC CONF=XP MODE=DEF NAME=v1_8_0 VERBOSE=1 PREPARE=1 all >&! run_gui-PRC-cfg_XP-mode_DEF-v1_8_0.log & +- or use launch_command_example to launch different runs in parallel. + +## Commands to launch for each configuration + +- XP : PRC app with DEF and DPM modes +- XPF[0,1,2] and XPZF[0,1,2] : PRC app with DEF, DPM and DPF modes + diff --git a/scripts/riscv_isa_formal/common/basics.tcl.obf b/scripts/riscv_isa_formal/common/basics.tcl.obf new file mode 100755 index 000000000..b97ac2b1e --- /dev/null +++ b/scripts/riscv_isa_formal/common/basics.tcl.obf @@ -0,0 +1,2 @@ +OneSpin obfuscated tcl file v1.2 +{"crypted_data_base64":"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","crypted_key_base64":"ae4swfzavOkxqDsJudKbX9pzOUkmtH3lghKeUgBvRwMQ/v/ohDNTomF29+UP/D6xla54T0a5\r\ncO//7aAvERGzzXcMK5Lhs20jZ9PPJz5RfppXjpquoW8adKhcEsUttU/J/k5dZxldwqtoLocp\r\nOQmJOzSoJ1nTQhaDmnQ99UvI6rej5wXUXerN6jcAyJYAfVacZMtzyVf5WZY8MANcZ+cTuJ40\r\nT6aFkpIO+s4epEyjAPPRY3aqvRqtRZd6iJRwtAYxGTyAz9Xc8yDxgvdJG7z5nfmJZ57ZUDCS\r\nqIL/WTIjg/9q9T2fxAUsnA0vBEaSQ1tZYTcelgzRQTgsVXuPcl6CkA==","crypted_sign_version_base64":"KL+4hMqJXz+2qrBnOcBWqQQhV9A4FAyyoIxcvRMJbhqDZVuNlrI6eN4y0+pWeBowxW91avwn\r\nCxpUnfO2fJpnUSDiMaEbfz5kCFuBxEMK1HYk8A6SQe+62B3Sb3ArmOTrfnZbTTVuNYFveKIC\r\n7k1PcwrD3z7NxiwyDEOuhVh3/+rD2PFrxtHtzu0Mars00hW/NZCAI6N1kC87lFgzMRwWpVCU\r\n19WIag8AEyzAy6g9WnL/sLVlj8CxiJh1C6uLPxHa6L4e/8GSu92fZgwO0363P/8Pf5fR+8O/\r\nSUxSEiMJdq6+05Pq8UtHLSTkBvgjXlVKD9DXV+USkL5twuwNUHMxKw==","crypted_signature_base64":"OGcBm7GN/6ibKuLWSdXzp2uBayu3UKZPDSMYDKOrPfJe8J/QPP3YiS0fWlAKgIp7LDsMZeiu\r\n+d0m8R2Y8jfff+sxMsApauBQ1e453cwbcZeN8BFyBoxYzkXF/NTYzFTe+U2nWuxHT9E8m572\r\nipH+Y38KVQ0UOAkPE2oZHxn9C3cnJ5VGKAwRK+PYxVyTkc0c7/EIbcE5VEObwUiGD8AJWWpF\r\n2TgDFi+AtCqoAlsGWjr+cN0w5NoaNXOav7LMQJNq20JGxN83fbywGEgjBHvr+3OBtp/7QNuZ\r\n20Lnyqer83j3uEGwUCQJ1fAiG5H3F/p3DHiQhvz2L+LTTvdS/j5tYg==","key_name":"onespin_002","key_vendor":"OneSpin","method":"aes-256-cbc"} \ No newline at end of file diff --git a/scripts/riscv_isa_formal/common/constraints.sv b/scripts/riscv_isa_formal/common/constraints.sv new file mode 100755 index 000000000..02bf694d0 --- /dev/null +++ b/scripts/riscv_isa_formal/common/constraints.sv @@ -0,0 +1,119 @@ +/*********************/ +// CONSTRAINTS +/*********************/ + +// MAIN CONSTRAINTS // + +const_addrs_c : assume property (##1 $stable({boot_addr,`core.dm_halt_addr_i,`core.dm_exception_addr_i,`core.mtvec_addr_i,`core.hart_id_i})); +const_dm_addr_c : assume property (`core.dm_halt_addr_i==32'h800 && `core.dm_exception_addr_i==32'h808); // **I** To meet app expectations + +`ifdef CFG_XP +`ifdef CV_LOOP + // raising of hwloop illegal currently not modeled + no_hwloop_illegal_c : assume property (!id_stage_i.controller_i.is_hwlp_illegal); + + // hwloop must contain 3+ instructions + hwloop_min_size_c : assume property (!(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]>0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[0]-id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0] inside {32'h0,32'h4,32'h8}) && !(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]>0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]-id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1] inside {32'h0,32'h4,32'h8})); + + // hwloop must be word-aligned + hwloop_aligned_c : assume property (id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0][1:0]==0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[0][1:0]==0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1][1:0]==0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1][1:0]==0); + + // we must not create loop 0 in the middle of itself (setting count to non-zero at a PC location that would qualify as inside the loop). Also, setting up the registers and then jumping to a location inside loop 0 will likely not work + loop0_setup_c : assume property (id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]==0 ##1 id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]!=0 |-> id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0]==$past(pc_id)+32'd4); + + // we must not create loop 1 in the middle of itself (setting count to non-zero at a PC location that would qualify as inside the loop). Also, setting up the registers and then jumping to a location inside loop 1 will likely not work + loop1_setup_c : assume property (id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]==0 ##1 id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]!=0 |-> id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1]==$past(pc_id)+32'd4); + + // let's not wrap + lopp_no_wrap_c : assume property (!(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]>0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[0]0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]0 && pc_id>=id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0] && pc_id0 && pc_id>=id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1] && pc_id0 && id_stage_i.hwlp_regid==1 && id_stage_i.hwlp_we)); + + // end addresses 8 apart + loop_end_min_sitance_c : assume property (!(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]>0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]>0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_we_i[1] && !id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_regid_i &&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]0|->`core.data_rvalid_i); +`else + no_hwloop_c : assume property (!id_stage_i.controller_i.is_hwlp_body); +`endif +`endif + +`ifdef CFG_XC + clk_en_c: assume property (`core.pulp_clock_en_i); +`endif + +// MEMORY INTERFACE CONSTRAINTS // + +// +// The following set of constraints could be used to constrain memory interfaces in case bus protocols implemented are not tool supported. +// **W** Use only in case bus protocols implemented are not tool supported +// + +`ifdef CUSTOM_MEM_INTERFACES + `include "mem_constraints.sv" + localparam MAX_WAIT=DMEM_MAX_WAIT; +`else + localparam MAX_WAIT=obi_dmem_checker.MAX_WAIT; +`endif + +// PERFORMANCE ENHANCEMENT CONSTRAINTS // + +// +// The following set of constraints could be used to enhance properties' runtime. +// **W** If ever used, these constraints have to be removed totally afterwards to achieve full verification. +// + +// +// "restrict_regs" restricts instruction source and destination indices to a subset of registers. +// By default, the following register indices are chosen: 0 to 3, and 8 to 9 in presence of compressed extensions. +// +function automatic restrict_regs(input dec_t dec); + restrict_regs=1'b1; + foreach (dec.RS[i]) + if (dec.RS[i].valid) +// restrict_regs&=dec.RS[i].idx<4 || (MISA.C|Zca) && dec.RS[i].idx inside {5'd8,5'd9}; + restrict_regs&=dec.RS[i].idx inside {5'd0, 5'd1, 5'd2, 5'd4, 5'd8, 5'd12, 5'd16}; + foreach (dec.RD[i]) + if (dec.RD[i].valid) +// restrict_regs&=dec.RD[i].idx<4 || (MISA.C|Zca) && dec.RD[i].idx inside {5'd8,5'd9}; + restrict_regs&=dec.RD[i].idx inside {5'd0, 5'd1, 5'd2, 5'd4, 5'd8, 5'd12, 5'd16}; +endfunction + +`ifdef RESTRICT_REGS + // Restrict instruction decoding & register file verification to a subset of registers + restrict_regs_c: assume property (disable iff (~rst_n) + restrict_regs(execute.dec) + `ifndef COMPLETENESS + `ifndef RESTRICT_REGISTER_INDEX +// && (reg_idx<4 || (MISA.C|Zca) && reg_idx inside {5'd8,5'd9}) + && (reg_idx inside {5'd0, 5'd1, 5'd2, 5'd4, 5'd8, 5'd12, 5'd16}) + `endif + `endif + ); +`endif + +// GRADUAL VERIFICATION CONSTRAINTS // + +// +// The following set of constraints could be used for a gradual setup of a new core. +// **W** If ever used, these constraints have to be removed totally afterwards to achieve full verification. +// + +`ifdef LIMIT_TOTAL_INSTR_COUNT + // Limit total number of instructions allowed in the pipeline + limit_total_instr_count_c : assume property (disable iff (~rst_n) full[0] -> id_instr_cnt<`LIMIT_TOTAL_INSTR_COUNT); +`endif diff --git a/scripts/riscv_isa_formal/common/core_checker.sv b/scripts/riscv_isa_formal/common/core_checker.sv new file mode 100755 index 000000000..4cbd14507 --- /dev/null +++ b/scripts/riscv_isa_formal/common/core_checker.sv @@ -0,0 +1,1108 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// RISC-V Checker // +// // +// This material contains trade secrets or otherwise confidential // +// information owned by Siemens Industry Software Inc. or its affiliates // +// (collectively, "SISW"), or its licensors. Access to and use of this // +// information is strictly limited as set forth in the Customer's applicable // +// agreements with SISW. // +// // +// This material may not be copied, distributed, or otherwise disclosed // +// outside of the Customer's facilities without the express written // +// permission of SISW, and may not be used in any way not expressly // +// authorized by SISW. // +// // +/////////////////////////////////////////////////////////////////////////////// + +`include "tidal.sv" +`include "RISCV_ISA.sv" +import RISCV_ISA::*; + +/*********************/ +// DEBUG GROUPS +/*********************/ + +(* ONESPIN_APP = "Processor" *) +(* ONESPIN_VIP_NAME = "RISC-V" *) +(* ONESPIN_VIP_TYPE = "cpu" *) +(* ONESPIN_VIP_TRANSACTION= "instr" *) +(* ONESPIN_VIP_GROUP_1 = "{{IF} if_valid}" *) +(* ONESPIN_VIP_GROUP_1_X = "/instr_addr_o /instr_req_o /instr_gnt_i /instr_rvalid_i /instr_rdata_i /pc_if /if_stage_i.fetch_valid /if_stage_i.fetch_rdata /if_stage_i.fetch_ready /if_stage_i.instr_valid /if_stage_i.instr_aligned /if_stage_i.if_ready /halt_if " *) +(* ONESPIN_VIP_GROUP_2 = "{{ID} id_valid}" *) +(* ONESPIN_VIP_GROUP_2_X = "/pc_id /instr_valid_id /instr_rdata_id /is_compressed_id /is_fetch_failed_id /clear_instr_valid /id_stage_i.controller_i.ctrl_fsm_cs /id_stage_i.controller_i.ctrl_fsm_ns /id_stage_i.misaligned_stall /id_stage_i.jr_stall /id_stage_i.load_stall /id_stage_i.apu_stall /id_stage_i.csr_apu_stall /id_stage_i.branch_taken_ex /id_ready /id_stage_i.halt_id" *) +(* ONESPIN_VIP_GROUP_3 = "{{EX} ex_valid}" *) +(* ONESPIN_VIP_GROUP_3_X = "/pc_ex /alu_en_ex /id_stage_i.decoder_i.alu_operator_o /alu_operand_a_ex /alu_operand_b_ex /ex_stage_i.alu_result /ex_stage_i.alu_ready /ex_stage_i.mult_ready mul_op_a mul_op_b mul_op_c mul_result /ex_stage_i.alu_i.div_valid div_result_valid /ex_stage_i.alu_i.result_div div_op_a div_op_b div_result_valid div_result /lsu_ready_ex /ex_ready" *) +(* ONESPIN_VIP_GROUP_4 = "{{MEM} mem_valid}" *) +(* ONESPIN_VIP_GROUP_4_X = "/data_we_o /data_addr_o /data_req_o /data_be_o /data_sign_ext_ex /data_type_ex /data_wdata_o /data_gnt_i /data_rvalid_i /data_rdata_i /lsu_rdata rf_we_lsu rf_waddr_lsu lsu_data_type lsu_data_sign lsu_data_offset" *) +(* ONESPIN_VIP_GROUP_5 = "{{WB} wb_valid}" *) +(* ONESPIN_VIP_GROUP_5_X = "/id_stage_i.register_file_i.we_b_i /id_stage_i.register_file_i.waddr_b_i /id_stage_i.register_file_i.wdata_b_i /id_stage_i.register_file_i.we_b_dec /id_stage_i.register_file_i.we_a_i /id_stage_i.register_file_i.waddr_a_i /id_stage_i.register_file_i.wdata_a_i /id_stage_i.register_file_i.we_a_dec /id_stage_i.register_file_i.mem /lsu_ready_wb /ex_stage_i.wb_ready_i" *) +(* ONESPIN_VIP_GROUP_6 = "CSRs" *) +(* ONESPIN_VIP_GROUP_6_X = "/csr_access_ex /csr_op /csr_addr /csr_wdata /csr_rdata /csr_cause /cs_registers_i.mepc_q /cs_registers_i.mcause_q /cs_registers_i.mstatus_q /cs_registers_i.mie_q /cs_registers_i.mtvec_q /cs_registers_i.fflags_q /cs_registers_i.frm_q" *) +(* ONESPIN_VIP_GROUP_7 = "XCPTs" *) +(* ONESPIN_VIP_GROUP_7_X = "/current_priv_lvl /pc_set /exc_cause /cs_registers_i.exception_pc /if_stage_i.exc_pc /if_stage_i.fetch_failed /instr_err_pmp /data_err_pmp /data_err_ack /id_stage_i.illegal_insn_dec /illegal_c_insn_id /id_stage_i.fencei_insn_dec /id_stage_i.ebrk_insn_dec /id_stage_i.ecall_insn_dec /id_stage_i.mret_insn_dec /id_stage_i.uret_insn_dec /id_stage_i.dret_insn_dec" *) +(* ONESPIN_VIP_GROUP_8 = "INTRs" *) +(* ONESPIN_VIP_GROUP_8_X = "/irq_i /irq_id_o /irq_ack_o" *) +(* ONESPIN_VIP_GROUP_9 = "DBG" *) +(* ONESPIN_VIP_GROUP_9_X = "/debug_mode /debug_req_i /debug_cause /debug_ebreakm /debug_ebreaku /debug_single_step /debug_csr_save /cs_registers_i.dcsr_q /cs_registers_i.depc_q" *) +(* ONESPIN_VIP_GROUP_A = "FPU" *) +(* ONESPIN_VIP_GROUP_A_X = "fpu_op_valid fpu_op_a fpu_op_b fpu_op_c fpu_op_ex fpu_lat_ex fpu_waddr_ex fpu_result_valid fpu_s_cycle fpu_m_cycle ex_stage_i.gen_apu.apu_disp_i.apu_lat fpu_waddr fpu_result fpu_flags" *) + +/*********************/ +// VIP's MODULE +/*********************/ + +module RISCV_checker #( + localparam logic[5:0] ALENX=ALEN ~(fpu_waddr_ex==fpu_waddr && (MISA.F|Zfinx -> fpu_lat_ex==ex_stage_i.gen_apu.apu_disp_i.apu_lat)))) + if (fpu_waddr[5]) + sboard_FR[fpu_waddr[4:0]] <= 1'b0; + else + sboard_XR[fpu_waddr[4:0]] <= 1'b0; + end + +/*********************/ +// DEBUG SIGNALS +/*********************/ + +(* OSS_TCL_VALUE_PRINTER = "PVE_disass" *) logic[32:0] instr; +assign instr = $past({full[0],iword_id}); + +wire if_valid = if_stage_i.if_valid; +wire id_valid = `core.id_valid; +wire ex_valid = `core.ex_valid; +wire mem_valid = `core.data_req_o; +wire wb_valid = `core.wb_valid; + +/*********************/ +// ARCHITECTURE STATE +/*********************/ + +Arch_state_t Arch; +always_comb begin + foreach (Arch.X[i]) + if (i==0) + Arch.X[i] <= '{valid: 1'b1, data: '0}; + else + Arch.X[i] <= '{valid: ~((rf_we_lsu&rf_waddr_lsu==i)|sboard_XR[i]), data: pipe_XR[i]}; + if (MISA.F && ~Zfinx) + foreach (Arch.F[i]) + Arch.F[i] <= '{valid: ~((rf_we_lsu&rf_waddr_lsu==(i+6'd32))|sboard_FR[i]), data: pipe_FR[i]}; + + Arch.CSR <= CSR; +`ifdef CFG_XP + Arch.CSR.lpstart <= $past(CSR.lpstart); + Arch.CSR.lpend <= $past(CSR.lpend); + Arch.CSR.lpcount <= $past(CSR.lpcount); +`endif + Arch.PC <= $past(full[0]?pc_id:pc_if); +end + +/*********************/ +// MODEL +/*********************/ + +prio_interrupt_t prio_interrupt; +assign prio_interrupt = prioritize_interrupt($past(interrupt_in,WB_OFFSET),Arch.CSR); + +execute_t execute; +assign execute = ISA_exe($past(iword_id), + $past(is_sstep,WB_OFFSET), + prio_interrupt, + '{Fetch_Access_Fault:{xcpt_af_instr_2nd,xcpt_af_instr_1st}, + BreakpointF: xcpt_bp_if, + BreakpointL: xcpt_bp_ld, + BreakpointS: xcpt_bp_samo, + DBGBreakpointF: $past(Arch.CSR.tdata1[0].typ==2 && Arch.CSR.tdata1[0].execute,WB_OFFSET) && Arch.PC==CSR.tdata2[0] && $past(~Arch.CSR.curDebug,WB_OFFSET), + DBGBreakpointL: xcpt_dbg_bp_ld, + DBGBreakpointS: xcpt_dbg_bp_samo, + Load_Addr_Align: xcpt_ma_ld, + Load_Access_Fault: {xcpt_af_ld_2nd,xcpt_af_ld_1st}, + SAMO_Addr_Align: xcpt_ma_samo, + SAMO_Access_Fault: {xcpt_af_samo_2nd,xcpt_af_samo_1st}, + Fetch_Page_Fault: {xcpt_pf_instr_2nd,xcpt_pf_instr_1st}, + Load_Page_Fault: {xcpt_pf_ld_2nd,xcpt_pf_ld_1st}, + SAMO_Page_Fault: {xcpt_pf_samo_2nd,xcpt_pf_samo_1st}}, + Arch); + +/*********************/ +// FUNCTIONS +/*********************/ + +function automatic [1:NUM_RS][1:0] compose_selection(logic[1:0] op_a_sl='0, logic[1:0] op_b_sl='0, logic[1:0] op_c_sl='0); + compose_selection = '{1: op_a_sl, 2: op_b_sl, default: op_c_sl}; +endfunction + +function automatic CSR_struct_t CSR_hw_update(input CSR_struct_t cur_CSR, input CSR_struct_t next_CSR, input logic is_retired=1'b0, input fflags_t fflags='{default:'0}); +`ifdef SKIP_CSR_CHECK + CSR_hw_update=next_CSR; +`else + CSR_hw_update=skip_CSR_update(cur_CSR,next_CSR); + if (MISA.F|Zfinx) begin + CSR_hw_update.fflags=next_CSR.fflags; // **I** Skip checking fflags updates + if (MISA.F) + CSR_hw_update.mstatus.FS=next_CSR.mstatus.FS; // **I** Skip checking mstatus.FS updates + end + if (NUM_COUNTERS>0) + CSR_hw_update.mcycle=next_CSR.mcycle; + if (NUM_COUNTERS>2 && is_retired) + CSR_hw_update.minstret={CSR_hw_update.minstret+64'h1}[63:0]; + if (NUM_COUNTERS>3) + CSR_hw_update.mhpmcounter=next_CSR.mhpmcounter; +`ifdef CFG_XP + CSR_hw_update.lpcount=next_CSR.lpcount; // **I** Skip checking lpcount updates +`endif +`endif +endfunction + +function automatic pc_check(input logic[XLEN-1:0] expected_pc); + pc_check=1'b1; +`ifndef SKIP_PC_CHECK + pc_check&=expected_pc==Arch.PC; +`endif +endfunction + +function automatic op_check(input execute_t exe, input op_t rtl_op='0, input [1:NUM_RS][1:0] sl='0); + op_check=1'b1; +`ifndef SKIP_RF_CHECK + foreach (rtl_op[i]) + op_check&=(exe.dec.RS[i].valid -> expected_op_data(exe.op[i][XLEN-1:0],sl[i])==rtl_op[i]); +`endif +endfunction + +function logic[1:0] data_size_enc(input logic[1:0] data_size); + case(data_size) + ms_byte: data_size_enc = ms_word; + ms_half: data_size_enc = ms_half; + ms_word: data_size_enc = ms_byte; + default: data_size_enc = ms_double; + endcase +endfunction + +function reg_t expected_op_data(input reg_t op, input logic[1:0] sl='0); + case(sl) + 2'h0: expected_op_data = op; + 2'h1: expected_op_data = {op[XLEN/2-1:0],op[XLEN/2-1:0]}; + 2'h2: expected_op_data = {op[XLEN/4-1:0],op[XLEN/4-1:0],op[XLEN/4-1:0],op[XLEN/4-1:0]}; + 2'h3: expected_op_data = op< check_wdata(exe.mem,dmem_req_data)); +`endif +endsequence + +sequence pipe_dmem_2nd_req(t_req, execute_t exe); +`ifdef SKIP_DMEM_CHECK + t##0 1'b1; +`else + t_req##0 dmem_req_valid==exe.mem.valid and + t_req##0 dmem_req_addr=={encVA({exe.mem.addr[XLEN-1:2],2'b00})+32'd4}[ALENX-1:0] and + t_req##0 dmem_req_we==(exe.mem.cmd inside {mc_store,mc_sc}) and + t_req##0 dmem_req_be==exe.mem.byte_enable[7:4] and + t_req##0 (exe.mem.cmd inside {mc_store,mc_sc} -> check_wdata(exe.mem,dmem_req_data,1'b1)); +`endif +endsequence + +sequence pipe_reset(t_wb, Arch_state_t cur_Arch=Arch); + t_wb##0 all_regs_valid(cur_Arch) && cur_Arch.X[0].data=='0 and + t_wb##0 no_rf_update($past(cur_Arch),cur_Arch) and + t_wb##0 RISCV_CSR_reset_state(cur_Arch.CSR) and + t_wb##0 CSR_hw_update($past(cur_Arch.CSR),cur_Arch.CSR)==cur_Arch.CSR and + t_wb##0 pc_check(boot_addr); +endsequence + +sequence pipe_bubble(t_wb, Arch_state_t cur_Arch, Arch_state_t next_Arch=Arch); + t_wb##1 no_rf_update(cur_Arch,next_Arch) and + t_wb##1 CSR_hw_update(cur_Arch.CSR,next_Arch.CSR)==next_Arch.CSR and + t_wb##1 pc_check(cur_Arch.PC); +endsequence + +sequence pipe_ret(t_wb, Arch_state_t cur_Arch, execute_t exe, Arch_state_t next_Arch=Arch); + t_wb##1 no_rf_update(cur_Arch,next_Arch) and + t_wb##1 CSR_hw_update(exe.next_CSR,next_Arch.CSR,~exe.csr.count_inhibit.IR)==next_Arch.CSR and + t_wb##1 pc_check(exe.next_pc.ret_PC); +endsequence + +sequence pipe_xcpt(t_wb, Arch_state_t cur_Arch, xcpt_t xcpt, Arch_state_t next_Arch=Arch); + t_wb##1 no_rf_update(cur_Arch,next_Arch) and + t_wb##1 CSR_hw_update(CSR_xcpt_update(cur_Arch.CSR,xcpt),next_Arch.CSR)==next_Arch.CSR and + t_wb##1 pc_check(CSR_xcpt_pc(cur_Arch.CSR,xcpt)); +endsequence + +sequence pipe_instr(t_wb, Arch_state_t cur_Arch, execute_t exe, result_t result='0, logic[1:NUM_RD] check_result='1, Arch_state_t next_Arch=Arch); + t_wb##1 (~exe.mem.valid & ~exe.fpu.valid) -> no_pending_results_used(exe.dec,cur_Arch) and // **I** don't check registers validity for memory or FPU instructions + t_wb##1 pipe_rf_check(exe.dec.RD,result,cur_Arch,check_result,next_Arch) and + t_wb##1 CSR_hw_update(CSR_instr_update(exe.csr,exe.next_CSR,CSR),next_Arch.CSR,~exe.csr.count_inhibit.IR,result.flags)==next_Arch.CSR and + t_wb##1 pc_check(exe.next_pc.PC); +endsequence + +sequence pipe_result(t_ex, execute_t exe, result_t result='0, logic[XLEN-1:0] rtl_result='0); + t_ex##0 ~((exe.dec.RD[1].idx==0) & (exe.fpu.valid -> Zfinx)) -> result.data[1]==rtl_result and + t_ex##0 (exe.fpu.valid & exe.fpu.flags_update) -> result.flags==fpu_flags; +endsequence + +sequence pipe_operands(t_ex, execute_t exe, op_t rtl_op='0, logic[1:NUM_RS][1:0] select_op_data='0); + t_ex##0 op_check(exe,rtl_op,select_op_data) and + t_ex##0 exe.fpu.valid -> exe.fpu.frm==fpu_rm; +endsequence + +property pipe_env(t_wb, logic env_cond='1, logic[PIPE_STAGES-1:0] prevent_stage_flush='0, logic[PIPE_STAGES-1:0] prevent_stage_stall='0); + t_id##0 (prevent_stage_flush[0] -> ~flush[0]) && (prevent_stage_stall[0] -> ~stall[0]) and + t_wb##0 (prevent_stage_flush[1] -> ~flush[1]) && (prevent_stage_stall[1] -> ~stall[1]) and + during(t_id,t_wb,env_cond); +endproperty + +/*********************/ +// CONCEPTUAL STATE +/*********************/ + +sequence Ready2Execute; + ~stall[1] && ~id_stage_i.misaligned_stall && id_stage_i.controller_i.ctrl_fsm_cs inside {DECODE,DECODE_HWLOOP} && ~id_stage_i.branch_taken_ex +`ifndef SKIP_PC_CHECK + && (id_stage_i.controller_i.jump_done_q -> (full[0] & id_stage_i.controller_i.jump_in_dec & (id_stage_i.controller_i.pc_mux_o==PC_JUMP) & ~$past(fpu_result_valid) & (~fpu_m_cycle) -> (~id_stage_i.controller_i.jr_stall_o & (pc_if==if_stage_i.aligner_i.branch_addr_i)))) + && ((full[0] & ~id_stage_i.controller_i.jump_done_q & ~id_stage_i.controller_i.is_hwlp_body & id_stage_i.controller_i.ctrl_fsm_cs==DECODE) -> (pc_if=={pc_id+(iword_id[1:0]==2'b11 ?3'd4: 3'd2)}[31:0])) +`endif +; +endsequence + +/*********************/ +// TIMEPOINTS +/*********************/ + +// RESET PROPERTY TIMEPOINTS // + +sequence t_if_rst; nxt(t,2); endsequence; +sequence t_id_rst; nxt(t_if_rst,2); endsequence; + +// PIPELINE STAGE TIMEPOINTS // + +sequence t_id; t; endsequence; +sequence t_ex; nxt(t_id,1); endsequence; +sequence t_wb; t_ex; endsequence; +sequence t_ex_ready; await(t_ex,~stall[1]&&id_stage_i.controller_i.ctrl_fsm_cs inside {DECODE,DECODE_HWLOOP,ELW_EXE},MAX_WAIT+4); endsequence; +sequence t_wb_ready; t_ex_ready; endsequence; + +// MEMORY PROPERTY TIMEPOINTS // + +sequence t_dmem_req; t_ex; endsequence; +sequence t_dmem_gnt; await(t_dmem_req,dmem_req_ready,MAX_WAIT); endsequence; +sequence t_dmem_2nd_req; await(nxt(t_dmem_gnt,1),obi_dmem_checker.new_req_allowed,MAX_WAIT); endsequence; +sequence t_dmem_2nd_gnt; await(t_dmem_2nd_req,dmem_req_ready,MAX_WAIT); endsequence; +sequence t_wb_ready_mem; t_wb_ready; endsequence; +sequence t_ex_ready_mem_ma; await(t_dmem_2nd_req,~stall[1],MAX_WAIT); endsequence; +sequence t_wb_ready_mem_ma; t_ex_ready_mem_ma; endsequence; + +// OTHER PROPERTY TIMEPOINTS // + +sequence t_ex_ready_branch; await(nxt(t_ex_ready,1),~stall[1],MAX_WAIT); endsequence; +sequence t_ex_ready_wfi; await(t_ex,~stall[1]&&id_stage_i.controller_i.ctrl_fsm_cs==DECODE,MAX_WAIT+6); endsequence; +sequence t_ex_ready_div; await(nxt(t_ex,2),~stall[1]&&id_stage_i.controller_i.ctrl_fsm_cs inside {DECODE},32); endsequence; +sequence t_wb_ready_branch; t_ex_ready_branch; endsequence; +sequence t_wb_ready_wfi; t_ex_ready_wfi; endsequence; +sequence t_wb_ready_div; t_ex_ready_div; endsequence; + +// MODEL CAPTURING TIMEPOINTS // + +sequence t_model; t_wb; endsequence; +sequence t_arch; t_wb; endsequence; + +// ARCHITECTURE UPDATE TIMEPOINTS // + +sequence t_arch_update; t_wb_ready; endsequence; +sequence t_arch_update_mem; t_wb_ready_mem; endsequence; +sequence t_arch_update_mem_ma; t_wb_ready_mem_ma; endsequence; +sequence t_arch_update_branch; t_wb_ready_branch; endsequence; +sequence t_arch_update_wfi; t_wb_ready_wfi; endsequence; +sequence t_arch_update_div; t_wb_ready_div; endsequence; +sequence t_arch_update_fpu; await(nxt(t_ex_ready,FPU_LATENCY),fpu_result_valid,MAX_WAIT); endsequence; + +// CONCEPTUAL STATE TIMEPOINTS // + +sequence t_rd2ex_rst; t_id_rst; endsequence; +sequence t_rd2ex; t_ex_ready; endsequence; +sequence t_rd2ex_mem_ma; t_ex_ready_mem_ma; endsequence; +sequence t_rd2ex_branch; t_ex_ready_branch; endsequence; +sequence t_rd2ex_wfi; t_ex_ready_wfi; endsequence; +sequence t_rd2ex_div; t_ex_ready_div; endsequence; + +/*********************/ +// PROPERTIES +/*********************/ + +// RESET PROPERTY // + +property RESET_p; +reset_sequence |=> + t##0 `core.fetch_enable_i and + during(t,nxt(t_id_rst,WB_OFFSET-1),~interrupt_in.DBGI) and + during(t,nxt(t_id_rst,WB_OFFSET),rst_n) // [t##0 --> first WB] +implies + t_rd2ex_rst##0 Ready2Execute and // first ID + pipe_fetch_req(t,t_if_rst) and // [t##0 --> first IF] + pipe_reset(nxt(t_id_rst,WB_OFFSET)) and // first WB + pipe_dmem_no_req(t,t_id_rst) and // [t##0 --> first ID] + t_rd2ex_rst##0 right_hook; +endproperty + +// BUBBLE & PIPELINE SPECIFIC PROPERTIES // + +property BUBBLE_p; + Arch_state_t cur_Arch; + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 Ready2Execute and + t_id##0 ~full[0] | stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) +implies + t_rd2ex##0 Ready2Execute and + pipe_bubble(t_arch_update,cur_Arch) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +// I, E, C, X PROPERTIES // + +property RV_INSTR(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] && (exe.next_pc.conditional -> ~exe.next_pc.non_linear) and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and + during(nxt(t_wb,1),nxt(t_wb_ready,1),pc_check(exe.next_pc.PC)) and + pipe_instr(t_arch_update,cur_Arch,exe,exe.result) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_Branch(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] && (exe.next_pc.conditional -> exe.next_pc.non_linear) and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready_branch,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex_branch##0 Ready2Execute and + pipe_instr(t_arch_update_branch,cur_Arch,exe,exe.result) and + pipe_dmem_no_req(t_ex,t_ex_ready_branch) and + t_rd2ex_branch##0 right_hook; +endproperty + +property RV_INSTR_MEM(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable<=4'hf and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready_mem,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and + pipe_instr(t_arch_update_mem,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and + pipe_dmem_1st_req(t_dmem_gnt,exe) and + during_excl(nxt(t_dmem_gnt,1),t_wb_ready_mem,~dmem_req_valid) and + t_arch_update_mem##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and + t_arch_update_mem##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_MEM_MA(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable>4'hf and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready_mem_ma,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex_mem_ma##0 Ready2Execute and + pipe_instr(t_arch_update_mem_ma,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and + pipe_dmem_1st_req(t_dmem_gnt,exe) and + pipe_dmem_2nd_req(t_dmem_2nd_gnt,exe) and + during_excl(nxt(t_dmem_gnt,1),t_dmem_2nd_req,~dmem_req_valid) and + t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and + t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and + t_rd2ex_mem_ma##0 right_hook; +endproperty + +// SYSTEM PROPERTIES // + +property FENCE_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and + pipe_instr(t_arch_update,cur_Arch,exe) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property WFI_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready_wfi,~(is_interrupt|is_debug)) and + during(nxt(t_ex,3),nxt(t_ex,6), id_stage_i.controller_i.ctrl_fsm_cs==SLEEP -> `core.wake_from_sleep) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex_wfi##0 Ready2Execute and + pipe_instr(t_arch_update_wfi,cur_Arch,exe) and + pipe_dmem_no_req(t_ex,t_ex_ready_wfi) and + t_rd2ex_wfi##0 right_hook; +endproperty + +property xRET_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] & ((exe.dec.instr==DRET) | ~cur_Arch.CSR.curDebug) and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and + pipe_ret(t_arch_update,cur_Arch,exe) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property ECALL_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + during(t_id,t_wb_ready,~is_interrupt&~is_debug) and + t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.xcpt_code inside {xcpt_UEnvCall,xcpt_SEnvCall,xcpt_MEnvCall} & ~cur_Arch.CSR.curDebug +implies + t_rd2ex##0 Ready2Execute and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property EBREAK_BreakPoint_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & ~exe.xcpt.dbg & exe.xcpt.xcpt_code==xcpt_Breakpoint & exe.xcpt.brk inside {brk_instr} & ~cur_Arch.CSR.curDebug +implies + t_rd2ex##0 Ready2Execute and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property EBREAK_HaltReq_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.xcpt_code==xcpt_Breakpoint & exe.xcpt.brk inside {brk_instr} & cur_Arch.CSR.curDebug +implies + t_rd2ex##0 Ready2Execute and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property EBREAK_ForcedEntry_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt)) and + t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.dbg & exe.xcpt.xcpt_code==xcpt_Breakpoint & exe.xcpt.brk inside {brk_instr} & ~cur_Arch.CSR.curDebug +implies + t_rd2ex##0 Ready2Execute and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +// Zicsr PROPERTIES // + +property CSRx_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_ex##0 set_freeze(result,compose_result(csr_rdata)) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and +`ifndef ISSUE_32_FIXED + t_wb_ready##0 `core.COREV_PULP -> (~id_stage_i.controller_i.hwlp_end1_eq_pc & ~id_stage_i.controller_i.hwlp_end0_eq_pc) and // **Potential ISSUE_32** In case the hwlp end pc is same as next pc expected (pc+4) the next pc is set to a different value than expected +`endif + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and + pipe_instr(t_arch_update,cur_Arch,exe,result) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_ex##0 exe.csr.addr==csr_addr and + t_ex##0 ~((exe.dec.RD[1].idx==0)|(`core.COREV_PULP?(exe.csr.csr inside {csr_lpcount0, csr_lpcount1}):'0)) -> CSR_read(csr_rdata,exe.csr,cur_Arch.CSR,$past(interrupt_in,1)) and // **I** Skip checking lpcount read + t_rd2ex##0 right_hook; +endproperty + +// Zifencei PROPERTIES // + +property FENCE_I_p(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and + pipe_instr(t_arch_update,cur_Arch,exe) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +// M PROPERTIES // + +property RV_INSTR_MUL(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and +`ifdef PVE_M_SUPPORT + t_ex_ready##0 set_freeze(result,exe.result) and + t_ex_ready##0 restrict_ops(compose_operands(exe.op[1],exe.op[2]),'{default:'h1}) and +`else + t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and +`endif + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and +`ifdef PVE_M_SUPPORT + pipe_result(t_ex_ready,exe,result,mul_result) and +`else + pipe_instr(t_arch_update,cur_Arch,exe,result) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + pipe_operands(t_ex_ready,exe,compose_operands(mul_op_a,mul_op_b,mul_op_c)) and +`endif + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_DIV(insn_set insns, cycles); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and +`ifdef PVE_M_SUPPORT + t_ex##0 set_freeze(result,exe.result) and + t_ex##0 restrict_ops(exe.op,'{default:'h1}) and +`else + t_ex##cycles set_freeze(result,compose_result(div_result)) and +`endif + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready_div,~(is_interrupt|is_debug)) and + during_excl(nxt(t_ex,2),nxt(t_ex,cycles),~div_result_valid) and + t_ex##cycles div_result_valid and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex_div##0 Ready2Execute and +`ifdef PVE_M_SUPPORT + pipe_result(t_ex_ready_div,exe,result,div_result) and +`else + pipe_instr(t_arch_update_div,cur_Arch,exe,result) and + pipe_dmem_no_req(t_ex,t_ex_ready_div) and + pipe_operands(t_ex_ready_div,exe,compose_operands(div_op_a,div_op_b),compose_selection('h0,'h3)) and +`endif + t_rd2ex_div##0 right_hook; +endproperty + +// F, D PROPERTIES // + +property RV_INSTR_F(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and +`ifdef PVE_FPU_SUPPORT + t_ex_ready##FPU_LATENCY set_freeze(result,exe.result) and + t_ex_ready##FPU_LATENCY exe.dec.instr inside {FMUL_S,FMADD_S,FNMADD_S,FMSUB_S,FNMSUB_S} -> restrict_fpu_ops(compose_operands(exe.op[1],exe.op[2])) and +`else + t_ex_ready##FPU_LATENCY set_freeze(result,compose_result(fpu_result,fpu_flags)) and +`endif + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_arch_update_fpu,~(is_interrupt|is_debug)) and + t_arch_update_fpu##0 (FPU_LATENCY>0) -> fpu_result_valid and // **I** Otherwise we wait forever in case FPU_LATENCY==2 + t_ex_ready##0 ~stall[1] and // **I** No preceding FDIV/ FSQRT instruction, could use instead t_id##0 ~(fpu_lat_ex=='h3 && (fpu_op_ex=='h4 || fpu_op_ex=='h5)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and +`ifdef PVE_FPU_SUPPORT + pipe_result(nxt(t_ex_ready,FPU_LATENCY),exe,result,fpu_result) and +`else + pipe_instr(t_arch_update,cur_Arch,exe,result,(FPU_LATENCY>0)?'0:'1) and + pipe_dmem_no_req(t_ex,t_ex_ready) and +`ifdef CFG_F + t_arch_update_fpu##1 (FPU_LATENCY>0) -> (exe.dec.RD[1].RF==rf_X?((exe.dec.RD[1].idx!=0 -> result.data[1]==Arch.X[exe.dec.RD[1].idx].data)):(result.data[1]==Arch.F[exe.dec.RD[1].idx].data)) and +`else + t_arch_update_fpu##1 (FPU_LATENCY>0) -> (exe.dec.RD[1].idx!=0 -> result.data[1]==Arch.X[exe.dec.RD[1].idx].data) and +`endif + t_arch_update_fpu##1 (FPU_LATENCY>0) -> (Arch.CSR.fflags==($past(Arch.CSR.fflags)|result.flags)) and +`endif + t_rd2ex##0 right_hook; +endproperty + +// X PROPERTIES // + +property RV_INSTR_DOT(insn_set insns, select); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and +`ifdef PVE_M_SUPPORT + t_ex_ready##0 set_freeze(result,exe.result) and + t_ex_ready##0 restrict_ops(compose_operands(exe.op[1],exe.op[2]),'{default:select}) and +`else + t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and +`endif + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and +`ifdef PVE_M_SUPPORT + pipe_result(t_ex_ready,exe,result,mul_result) and +`else + pipe_instr(t_arch_update,cur_Arch,exe,result) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + pipe_operands(t_ex_ready,exe,compose_operands(dot_mul_op_a,dot_mul_op_b,dot_mul_op_c)) and +`endif + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_DOT_SC(insn_set insns, select); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and +`ifdef PVE_M_SUPPORT + t_ex_ready##0 set_freeze(result,exe.result) and + t_ex_ready##0 restrict_ops(compose_operands(exe.op[1],exe.op[2]),'{default:select}) and +`else + t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and +`endif + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and +`ifdef PVE_M_SUPPORT + pipe_result(t_ex_ready,exe,result,mul_result) and +`else + pipe_instr(t_arch_update,cur_Arch,exe,result) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + pipe_operands(t_ex_ready,exe,compose_operands(dot_mul_op_a,dot_mul_op_b,dot_mul_op_c),compose_selection('h0,select)) and +`endif + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_DOT_SCI(insn_set insns, select); + execute_t exe; + Arch_state_t cur_Arch; + result_t result; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and +`ifdef PVE_M_SUPPORT + t_ex##0 set_freeze(result,exe.result) and + t_ex##0 restrict_ops(compose_operands(exe.op[1],dot_mul_op_b),'{default:select}) and +`else + t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and +`endif + t_id##0 insns[exe.dec.instr] and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies + t_rd2ex##0 Ready2Execute and +`ifdef PVE_M_SUPPORT + pipe_result(t_ex_ready,exe,result,mul_result) and +`else + pipe_instr(t_arch_update,cur_Arch,exe,result) and + pipe_dmem_no_req(t_ex,t_ex_ready) and +// pipe_operands(t_ex_ready,exe,compose_operands(dot_mul_op_a,dot_mul_op_b,dot_mul_op_c),compose_selection('h0,select)) and // operand b manipulation is based on the immediate value +`endif + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_MEM_ELW(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable<=4'hf and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(nxt(t_wb_ready_mem,2),~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies +// t_rd2ex##0 Ready2Execute and + pipe_instr(t_arch_update_mem,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and + pipe_dmem_1st_req(t_dmem_gnt,exe) and + during_excl(nxt(t_dmem_gnt,1),t_wb_ready_mem,~dmem_req_valid) and + t_arch_update_mem##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and + t_arch_update_mem##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and + t_rd2ex##0 right_hook; +endproperty + +property RV_INSTR_MEM_MA_ELW(insn_set insns); + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable>4'hf and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(nxt(t_wb_ready_mem_ma,2),~(is_interrupt|is_debug)) and + t_id##0 ~exe.xcpt.valid +implies +// t_rd2ex_mem_ma##0 Ready2Execute and + pipe_instr(t_arch_update_mem_ma,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and + pipe_dmem_1st_req(t_dmem_gnt,exe) and + pipe_dmem_2nd_req(t_dmem_2nd_req,exe) and + during_excl(nxt(t_dmem_gnt,1),t_dmem_2nd_req,~dmem_req_valid) and + t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and + t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and + t_rd2ex_mem_ma##0 right_hook; +endproperty + +// EXCEPTION PROPERTIES // + +property XCPT_IF_ID_p; + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + pipe_env(t_wb_ready,~(is_interrupt|(is_debug & exe.xcpt.xcpt_code inside {xcpt_Illegal_Instr}))) and + t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.xcpt_code inside {xcpt_Breakpoint,xcpt_Fetch_Page_Fault,xcpt_Fetch_Access_Fault,xcpt_Illegal_Instr,xcpt_Fetch_Addr_Align} & exe.xcpt.brk inside {brk_none,brk_fetch} +implies + t_rd2ex##0 Ready2Execute and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +property XCPT_WB_p; + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & (exe.xcpt.xcpt_code inside {xcpt_Breakpoint,xcpt_SAMO_Addr_Align,xcpt_Load_Addr_Align,xcpt_SAMO_Page_Fault,xcpt_Load_Page_Fault,xcpt_SAMO_Access_Fault,xcpt_Load_Access_Fault}) & exe.xcpt.brk inside {brk_none,brk_dmem} +implies + t_rd2ex##0 Ready2Execute and + t_wb_ready##0 no_pending_results_used(exe.dec) and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +// INTERRUPT HANDLING PROPERTIES // + +property INTR_Handle_p; + execute_t exe; + Arch_state_t cur_Arch; + t_model##0 set_freeze(exe,execute) and + t_arch##0 set_freeze(cur_Arch,Arch) and + t_id##0 Ready2Execute and + t_id##0 full[0] && ~stall[0] and + t_id##0 exe.xcpt.valid & exe.xcpt.interrupt +implies + t_rd2ex##0 Ready2Execute and + pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and + pipe_dmem_no_req(t_ex,t_ex_ready) and + t_rd2ex##0 right_hook; +endproperty + +/*********************/ +// NON-TIDAL ASSERTIONs +/*********************/ + +// COUNTERS // + +property mcycle_increment_p; + Ready2Execute ##1 ~execute.csr.count_inhibit.CY&~execute.xcpt.interrupt |=> + Arch.CSR.mcycle==$past(Arch.CSR.mcycle+64'h1); +endproperty +mcycle_increment_a : assert property (disable iff(~rst_n) mcycle_increment_p); + +property mcycle_no_increment_p; + Ready2Execute ##1 execute.csr.count_inhibit.CY&Arch.CSR.mcountinhibit.CY&((execute.csr.cmd == cc_none)|(execute.csr.cmd == cc_r)) |=> + Arch.CSR.mcycle==$past(Arch.CSR.mcycle); +endproperty +mcycle_no_increment_a : assert property (disable iff(~rst_n) mcycle_no_increment_p); + +property mhpmcounter3_increment_p; + Ready2Execute ##1 ~execute.csr.count_inhibit.HPM[3]&~execute.xcpt.interrupt |=> + Arch.CSR.mhpmcounter[3]==$past(|(Arch.CSR.mhpmevent[3][15:0]&cs_registers_i.hpm_events) ? Arch.CSR.mhpmcounter[3]+64'h1 : Arch.CSR.mhpmcounter[3]); +endproperty +mhpmcounter3_increment_a : assert property (disable iff(~rst_n) mhpmcounter3_increment_p); + +property mhpmcounter3_no_increment_p; + Ready2Execute ##1 execute.csr.count_inhibit.HPM[3]&Arch.CSR.mcountinhibit.HPM[3]&((execute.csr.cmd == cc_none)|(execute.csr.cmd == cc_r)) |=> + Arch.CSR.mhpmcounter[3]==$past(Arch.CSR.mhpmcounter[3]); +endproperty +mhpmcounter3_no_increment_a : assert property (disable iff(~rst_n) mhpmcounter3_no_increment_p); + +// LSU // + +property stable_lsu_signals_p; + rf_we_lsu&~obi_dmem_checker.rvalid |=> $stable({rf_we_lsu,rf_waddr_lsu,lsu_data_type,lsu_data_offset,lsu_data_sign}); +endproperty +stable_lsu_signals_a : assert property (disable iff(~rst_n) stable_lsu_signals_p); + +property lsu_write_p; + ~rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid && + ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0]) && // A write on ALU port by next F instruction to same RD overtake LSU port write + ~((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || // lw + (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) // lh + |=> + (obi_dmem_checker.cnt!=$past(obi_dmem_checker.cnt) && rf_waddr_lsu!=$past(rf_waddr_lsu) -> Arch.X[$past(rf_waddr_lsu[4:0])].valid) && + ($past(rf_waddr_lsu[4:0])!='0 -> Arch.X[$past(rf_waddr_lsu[4:0])].data== + $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), + addr: $past({30'h0,lsu_data_offset}), default: '0},{32'h0,$past(dmem_resp_data)}))); +endproperty +lsu_write_a : assert property (disable iff(~rst_n) lsu_write_p); + +property lsu_ma_write_p; + ~rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid&&id_stage_i.register_file_i.we_a_i && + ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0])&& + ((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) + |=> +// Arch.X[$past(rf_waddr_lsu[4:0])].valid && + $past(rf_waddr_lsu[4:0])!='0 -> Arch.X[$past(rf_waddr_lsu[4:0])].data== + $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), + addr: $past({30'h0,lsu_data_offset}), default: '0},{$past(dmem_resp_data),$past(load_store_unit_i.rdata_q)})); +endproperty +lsu_ma_write_a : assert property (disable iff(~rst_n) lsu_ma_write_p); + +property lsu_ma_rdata_q_p; + rf_we_lsu&&obi_dmem_checker.rvalid&&cv32e40p_core.data_misaligned_ex&& + ((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) + |=> + load_store_unit_i.rdata_q==$past(dmem_resp_data); +endproperty +lsu_ma_rdata_q_a : assert property (disable iff(~rst_n) lsu_ma_rdata_q_p); + +`ifdef CFG_F +property lsu_write_f_p; + rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid && + ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0])&& + ~((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) + |=> + (obi_dmem_checker.cnt!=$past(obi_dmem_checker.cnt) && rf_waddr_lsu!=$past(rf_waddr_lsu) -> Arch.F[$past(rf_waddr_lsu[4:0])].valid) && + (Arch.F[$past(rf_waddr_lsu[4:0])].data== + $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), + addr: $past({30'h0,lsu_data_offset}), default: '0},{32'h0,$past(dmem_resp_data)}))); +endproperty +lsu_write_f_a : assert property (disable iff(~rst_n) lsu_write_f_p); + +property lsu_ma_write_f_p; + rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid&&id_stage_i.register_file_i.we_a_i && + ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0])&& + ((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) + |=> +// Arch.F[$past(rf_waddr_lsu[4:0])].valid && + Arch.F[$past(rf_waddr_lsu[4:0])].data== + $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), + addr: $past({30'h0,lsu_data_offset}), default: '0},{$past(dmem_resp_data),$past(load_store_unit_i.rdata_q)})); +endproperty +lsu_ma_write_f_a : assert property (disable iff(~rst_n) lsu_ma_write_f_p); +`endif + +`include `GENERATED_ASSERTIONS_FILE +`include "constraints.sv" + +endmodule diff --git a/scripts/riscv_isa_formal/common/io.sv b/scripts/riscv_isa_formal/common/io.sv new file mode 100755 index 000000000..cb7c9c1e2 --- /dev/null +++ b/scripts/riscv_isa_formal/common/io.sv @@ -0,0 +1,72 @@ + // Data memory interface + input dmem_req_we ='0, // Data memory request type + input[3:0] dmem_req_be ='0, // Data memory request byte enable + input[1:0] dmem_req_size ='0, // Data memory request size + input dmem_req_sign ='0, // Data memory request sign + + // Exceptions & Debug + input is_sstep ='0, // Single stepping of debug mode + input xcpt_bp_if ='0, // Instruction address breakpoint exception + input xcpt_bp_ld ='0, // Load address breakpoint exception + input xcpt_bp_samo ='0, // Store/ AMO address breakpoint exception + input xcpt_dbg_bp_if ='0, // Debug instruction address breakpoint exception + input xcpt_dbg_bp_ld ='0, // Debug load address breakpoint exception + input xcpt_dbg_bp_samo ='0, // Debug Store/ AMO address breakpoint exception + input xcpt_af_instr_1st ='0, // Instruction access fault exception + input xcpt_af_instr_2nd ='0, // Instruction second access fault exception + input xcpt_af_ld_1st ='0, // Load access fault exception + input xcpt_af_ld_2nd ='0, // Load second access fault exception + input xcpt_af_samo_1st ='0, // Store/ AMO access fault exception + input xcpt_af_samo_2nd ='0, // Store/ AMO second access fault exception + input xcpt_pf_instr_1st ='0, // Instruction page fault exception + input xcpt_pf_instr_2nd ='0, // Instruction second access page fault exception + input xcpt_pf_ld_1st ='0, // Load page fault exception + input xcpt_pf_ld_2nd ='0, // Load second access page fault exception + input xcpt_pf_samo_1st ='0, // Store/ AMO page fault exception + input xcpt_pf_samo_2nd ='0, // Store/ AMO second access page fault exception + input xcpt_ma_ld ='0, // Load address misaligned exception + input xcpt_ma_samo ='0, // Store/AMO address misaligned exception + + // Multiplication & Division + input mul_op_valid ='0, // Multiplication operation validity + input[XLEN-1:0] mul_op_a ='0, // Multiplication first source operand + input[XLEN-1:0] mul_op_b ='0, // Multiplication second source operand + input[XLEN-1:0] mul_op_c ='0, // Multiplication third source operand + input[XLEN-1:0] mul_result ='0, // Multiplication operation result + input mul_result_valid ='0, // Multiplication operation result validity + input div_op_valid ='0, // Division operation validity + input[XLEN-1:0] div_op_a ='0, // Division first source operand + input[XLEN-1:0] div_op_b ='0, // Division second source operand + input[$clog2(XLEN):0] div_op_b_shift ='0, // Division second source operand shift amount + input[XLEN-1:0] div_result ='0, // Division operation result + input div_result_valid ='0, // Division operation result validity + + // Floating point + input fpu_op_valid ='0, // FPU operation validity + input[XLEN-1:0] fpu_op_a ='0, // FPU first source operand + input[XLEN-1:0] fpu_op_b ='0, // FPU second source operand + input[XLEN-1:0] fpu_op_c ='0, // FPU third source operand + input Frm fpu_rm ='0, // FPU rounding mode + input Fflags fpu_flags ='0, // FPU flags + input[XLEN-1:0] fpu_result ='0, // FPU operation result + input fpu_result_valid ='0, // FPU operation result validity + + // Design specific + input is_debug ='0, // Core is about to enter debug mode + input is_interrupt ='0, // Core is about to encounter an interrupt + input[XLEN-1:0] boot_addr ='0, // Boot address + + input rf_we_lsu ='0, + input[5:0] rf_waddr_lsu ='0, + input[1:0] lsu_data_type ='0, + input[1:0] lsu_data_sign ='0, + input[1:0] lsu_data_offset ='0, + input fpu_s_cycle ='0, + input fpu_m_cycle ='0, + input[5:0] fpu_waddr ='0, + input[5:0] fpu_waddr_ex ='0, + input[1:0] fpu_lat_ex ='0, + input[5:0] fpu_op_ex ='0, + input[XLEN-1:0] dot_mul_op_a ='0, + input[XLEN-1:0] dot_mul_op_b ='0, + input[XLEN-1:0] dot_mul_op_c ='0 diff --git a/scripts/riscv_isa_formal/common/other_bindings.sv b/scripts/riscv_isa_formal/common/other_bindings.sv new file mode 100755 index 000000000..41c929d20 --- /dev/null +++ b/scripts/riscv_isa_formal/common/other_bindings.sv @@ -0,0 +1,72 @@ + // Data memory interface + .dmem_req_we (data_we_o), + .dmem_req_be (data_be_o), + .dmem_req_size (), + .dmem_req_sign (), + + // Exceptions & Debug + .is_sstep (debug_single_step), + .xcpt_bp_if (), + .xcpt_bp_ld (), + .xcpt_bp_samo (), + .xcpt_dbg_bp_if (), + .xcpt_dbg_bp_ld (), + .xcpt_dbg_bp_samo (), + .xcpt_af_instr_1st (), + .xcpt_af_instr_2nd (), + .xcpt_af_ld_1st (), + .xcpt_af_ld_2nd (), + .xcpt_af_samo_1st (), + .xcpt_af_samo_2nd (), + .xcpt_pf_instr_1st (), + .xcpt_pf_instr_2nd (), + .xcpt_pf_ld_1st (), + .xcpt_pf_ld_2nd (), + .xcpt_pf_samo_1st (), + .xcpt_pf_samo_2nd (), + .xcpt_ma_ld (), + .xcpt_ma_samo (), + + // Multiplication & Division + .mul_op_valid (), + .mul_op_a (ex_stage_i.mult_i.op_a_i), + .mul_op_b (ex_stage_i.mult_i.op_b_i), + .mul_op_c (ex_stage_i.mult_i.op_c_i), + .mul_result (ex_stage_i.mult_i.result_o), + .mul_result_valid (), + .div_op_valid (), + .div_op_a (ex_stage_i.alu_i.alu_div_i.OpA_DI), + .div_op_b (ex_stage_i.alu_i.alu_div_i.OpB_DI), + .div_op_b_shift (ex_stage_i.alu_i.alu_div_i.OpBShift_DI), + .div_result (ex_stage_i.alu_i.alu_div_i.Res_DO), + .div_result_valid (ex_stage_i.alu_i.div_ready), + + // Floating point + .fpu_op_valid (ex_stage_i.apu_req), + .fpu_op_a (ex_stage_i.apu_operands_o[0]), + .fpu_op_b (ex_stage_i.apu_operands_o[1]), + .fpu_op_c (ex_stage_i.apu_operands_o[2]), + .fpu_rm (), + .fpu_flags (ex_stage_i.fpu_fflags_o), + .fpu_result (ex_stage_i.apu_result), + .fpu_result_valid (ex_stage_i.apu_valid), + + // Design specific + .is_debug (id_stage_i.controller_i.ctrl_fsm_cs inside {DBG_TAKEN_ID,DBG_TAKEN_IF,DBG_FLUSH}), + .is_interrupt (id_stage_i.int_controller_i.irq_req_ctrl_o), + .boot_addr ({boot_addr_i[31:2],2'b00}), + + .rf_we_lsu (ex_stage_i.regfile_we_lsu), + .rf_waddr_lsu (ex_stage_i.regfile_waddr_lsu), + .lsu_data_type (load_store_unit_i.data_type_q), + .lsu_data_sign (load_store_unit_i.data_sign_ext_q), + .lsu_data_offset (load_store_unit_i.rdata_offset_q), + .fpu_s_cycle (ex_stage_i.apu_singlecycle), + .fpu_m_cycle (ex_stage_i.apu_multicycle), + .fpu_waddr (ex_stage_i.apu_waddr), + .fpu_waddr_ex (apu_waddr_ex), + .fpu_lat_ex (apu_lat_ex), + .fpu_op_ex (apu_op_ex), + .dot_mul_op_a (ex_stage_i.mult_dot_op_a_i), + .dot_mul_op_b (ex_stage_i.mult_dot_op_b_i), + .dot_mul_op_c (ex_stage_i.mult_dot_op_c_i) diff --git a/scripts/riscv_isa_formal/common/setup.tcl b/scripts/riscv_isa_formal/common/setup.tcl new file mode 100755 index 000000000..0bcce5472 --- /dev/null +++ b/scripts/riscv_isa_formal/common/setup.tcl @@ -0,0 +1,564 @@ +proc duration {int_time} { + set timeList [list] + if {$int_time == 0} { + return "0 Sec" + } else { + foreach div {86400 3600 60 1} mod {0 24 60 60} name {Day Hour Min Sec} { + set n [expr {$int_time / $div}] + if {$mod > 0} {set n [expr {$n % $mod}]} + if {$n > 1} { + lappend timeList "$n ${name}s" + } elseif {$n == 1} { + lappend timeList "$n $name" + } + } + return [join $timeList] + } +} + +proc quantify_run {{cmd_limit 0} {run 0} {no_cuts {}} {limit_scale 2.0} {effort 4} {skip_effort_level 0} {html_dir {}} {result_file {}} {checks {}} {prev_run_result {}} {skip_files {}}} { + + puts "\n-INFO- Start of Quantify Run ($run)::\n\nChecks Included::\n\n$checks" + + set_limit -command_real_time $cmd_limit + set run_start_t [clock seconds] + puts "\n-INFO- Launching Quantify Command::\n\nquantify -assume_hold -additional_args \[list $no_cuts -limit_scale $limit_scale -use_single_prover\] -effort $effort -skip_effort_level $skip_effort_level -html $html_dir -save $result_file -checks $checks -incremental $prev_run_result -skip_files $skip_files\n" + catch {quantify -assume_hold -additional_args [list $no_cuts -limit_scale $limit_scale -use_single_prover] -effort $effort -skip_effort_level $skip_effort_level -html $html_dir -save $result_file -checks $checks -incremental $prev_run_result -skip_files $skip_files} + set run_end_t [expr [clock seconds] - $run_start_t] + set_limit -default + + puts "\n-INFO- End of Quantify Run ($run) | Time spent:: [duration $run_end_t]\n" +} + +## 0. DESIGN SETUP ## + +### SETTING UP THE DESIRED CONFIGURATION, RUN & APP ### +## source the setup.inc as the following: [onespin -i setup.inc ] +## arg1: what configuration to set . +## arg2: what processor verification mode to set . +## arg3: what app to launch on top of the processor app. +## ------------------------------------------------------------------------------------------------------------------ + +set configs [dict create \ + "DEF" [dict create \ + description "RV32IMCZicsr_Zifencei" \ + elab "-verilog_parameter {}" \ + define "" \ + json "" \ + ] \ + "F0" [dict create \ + description "RV32IMFCZicsr_Zifencei with FPU latency params set to 0" \ + elab "-verilog_parameter {FPU=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ + define "CFG_F" \ + json "" \ + ] \ + "ZF0" [dict create \ + description "RV32IMCZicsr_Zifencei_Zfinx with FPU latency params set to 0" \ + elab "-verilog_parameter {FPU=1 ZFINX=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ + define "CFG_ZFINX" \ + json "" \ + ] \ + "XP" [dict create \ + description "RV32IMCZicsr_Zifencei_Xpulp" \ + elab "-verilog_parameter {COREV_PULP=1}" \ + define "CFG_XP" \ + json "Xpulp.json Zfinx.json" \ + ] \ + "XPF0" [dict create \ + description "RV32IMFCZicsr_Zifencei_Xpulp with FPU latency params set to 0" \ + elab "-verilog_parameter {FPU=1 COREV_PULP=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ + define "CFG_XP CFG_F" \ + json "Xpulp.json" \ + ] \ + "XPF1" [dict create \ + description "RV32IMFCZicsr_Zifencei_Xpulp with FPU latency params set to 1" \ + elab "-verilog_parameter {FPU=1 COREV_PULP=1 FPU_ADDMUL_LAT=1 FPU_OTHERS_LAT=1}" \ + define "CFG_XP CFG_F" \ + json "Xpulp.json" \ + ] \ + "XPF2" [dict create \ + description "RV32IMFCZicsr_Zifencei_Xpulp with FPU latency params set to 2" \ + elab "-verilog_parameter {FPU=1 COREV_PULP=1 FPU_ADDMUL_LAT=2 FPU_OTHERS_LAT=2}" \ + define "CFG_XP CFG_F" \ + json "Xpulp.json" \ + ] \ + "XPZF0" [dict create \ + description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp with FPU latency params set to 0" \ + elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ + define "CFG_XP CFG_ZFINX" \ + json "Xpulp.json Zfinx.json" \ + ] \ + "XPZF1" [dict create \ + description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp with FPU latency params set to 1" \ + elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 FPU_ADDMUL_LAT=1 FPU_OTHERS_LAT=1}" \ + define "CFG_XP CFG_ZFINX" \ + json "Xpulp.json Zfinx.json" \ + ] \ + "XPZF2" [dict create \ + description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp with FPU latency params set to 2" \ + elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 FPU_ADDMUL_LAT=2 FPU_OTHERS_LAT=2}" \ + define "CFG_XP CFG_ZFINX" \ + json "Xpulp.json Zfinx.json" \ + ] \ + "XPXC" [dict create \ + description "RV32IMCZicsr_Zifencei_Xpulp_Xcluster" \ + elab "-verilog_parameter {COREV_PULP=1 COREV_CLUSTER=1}" \ + define "CFG_XP CFG_XC" \ + json "Xpulp.json Xcluster.json Zfinx.json" \ + ] \ + "XPXCZF2" [dict create \ + description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp_Xcluster with FPU latency params set to 2" \ + elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 COREV_CLUSTER=1 FPU_ADDMUL_LAT=2 FPU_OTHERS_LAT=2}" \ + define "CFG_XP CFG_XC CFG_ZFINX" \ + json "Xpulp.json Xcluster.json Zfinx.json" \ + ] \ +] + +set pve_modes [dict create \ + "DEF" [dict create \ + description "DEF: Control path verification of all instructions and datapath verification of all instructions except multiplication, division or floating point ones" \ + define "" \ + ] \ + "DPM" [dict create \ + description "DPM: Data path verification of multiplication/ division instructions" \ + define "PVE_M_SUPPORT RESTRICT_MUL_OPS_FREE_BITS=1" \ + ] \ + "DPF" [dict create \ + description "DPF: Data path verification of floating-point instructions" \ + define "PVE_FPU_SUPPORT RESTRICT_MUL_OPS_FREE_BITS=1" \ + ] \ +] + +set apps [dict create \ + "PRC" [dict create \ + description "PRC: Property Checking" \ + compile "-dontcare_handling any -signal_domain {{scan_cg_en_i} 0}" \ + ] \ + "QTF" [dict create \ + description "QTF: Quantify" \ + compile "-dontcare_handling any -signal_domain {{scan_cg_en_i} 0} -constant [list [list core_i.id_stage_i.register_file_i.rst_n 1] ]" \ + ] \ + "VCI" [dict create \ + description "VCI: Verification Coverage Integration" \ + compile "-dontcare_handling any -signal_domain {{scan_cg_en_i} 0}" \ + ] \ +] + +if {$::argc>0} { + lassign $::argv cfg pve_mode app + if {$cfg ni [dict keys $configs]} { + onespin::message -error "Only configurations [join [dict keys $configs] ,] are supported!" + return -code error + } + if {$pve_mode ni [dict keys $pve_modes]} { + onespin::message -error "Only processor verification modes [join [dict keys $pve_modes] ,] are supported!" + return -code error + } elseif {$pve_mode eq "DPF" && $cfg in {"DEF" "XP" "XPXC"} } { + onespin::message -error "Floating-point configuration must be selected in order to perform data path verification!" + return -code error + } + if {$app ni [dict keys $apps]} { + onespin::message -error "Only apps [join [dict keys $apps] ,] are supported!" + return -code error + } +} else { + if {[get_tool_info -gui]} { + set cfg [string index [onespin::ask_user -default 0 -alternatives [lmap {k d} $configs {string cat "$k - " [dict get $d description]}] "Select which RISC-V configuration to set up:"] 0] + set pve_mode [string index [onespin::ask_user -default "DEF" -alternatives [lmap {k d} $pve_modes {string cat "$k - " [dict get $d description]}] "Select which processor verification mode to set:"] 0] + set app [string index [onespin::ask_user -default "PRC" -alternatives [lmap {k d} $apps {string cat "$k - " [dict get $d description]}] "Select which app to launch:"] 0] + } else { + set cfg "DEF" + set pve_mode "DEF" + set app "PRC" + } +} +set target cv32e40p_top +set core_inst core_i +set prefix ${core_inst}. +## + +### ADJUST TO READ-IN THE NEW DESIGN ### +onespin::set_parameter disable_intermediate_arithmetic_signals 1 +set cwd [pwd] +set_session_option -naming_style sv +set_compile_option {*}[dict get $apps $app compile] +set_elaborate_option {*}[dict get $configs $cfg elab] -top $target +cd cv32e40p +source $cwd/setup_mv.tcl +set_reset_sequence -low rst_ni +cd $cwd + +set cfg_dir $cwd/$cfg +set pve_mode_dir $cwd/$cfg/$pve_mode +set app_dir $cwd/$cfg/$pve_mode/$app +file mkdir $cfg_dir +file mkdir $pve_mode_dir +file mkdir $app_dir +## + +### PROCESSOR APP FLOW ### + +## --------------------------------------------------------------------------------------------------------------------------------- +## 1 > 2 > 3 > 4 > 5 > 6 > 7 +## --------------------------------------------------------------------------------------------------------------------------------- +## PRE-ANALYSIS | DESIGN | POST-ANALYSIS | ASSERTION | ASSERTION | PERFORMANCE | ASSERTION +## CONFIGURATION | ANALYSIS | CONFIGURATION | GENERATION | READING & RETUNING | ENHANCEMENT | RUNNING & DEBUGGING +## --------------------------------------------------------------------------------------------------------------------------------- + +## --------------------------------------------------------------------------------------------------------------------------------- +## processor_integrity:: | DESCRIPTION +## --------------------------------------------------------------------------------------------------------------------------------- +## extract_ISA | Extract ISA from a RISC-V based processor core and store data in a processor database. +## -core_instance <> | Specify instance name of the core in the DUV to instantiate the VIP on. +## -csr_addr <> | Specify CSR address signal that might be used to assist extraction. +## -csr_rdata <> | Specify CSR read data signal that might be used to assist extraction. +## merge_data | Merge JSON data into the database. +## -file <> | Specify JSON file to be merged. +## -configuration <> | Specify predefined JSON configuration to be merged. +## generate_assertions | Generate assertions for verifying the RISC-V core based on the database. +## -create_individual_checks <> | Specify extensions for which assertions are generated per instruction. +## -exclude_extensions <> | Specify extensions for which assertions generation is supressed. +## -include_extensions <> | Specify extensions only for which assertions are generated. +## generate_IVA | Perform initial value abstraction of architecture state. +## -candidates <> | Specify architecture register fields to be abstracted. +## analyze_trace | Perform detailed trace analysis of run assertions. +## save_data | Write the processor database, or part of it, to a JSON file. +## clear_data | Clear JSON data from the processor database. +## --------------------------------------------------------------------------------------------------------------------------------- +## For full app documentation run "help *processor_integrity::*" or refer to Chapter 14. of the User Manual. +## --------------------------------------------------------------------------------------------------------------------------------- + +## 0. APP SETUP ## + +package require processor_integrity + +### APPEND THE FOLLOWING SET OF DEFINES (ONLY IF NECESSARY) ### +## --------------------------------------------------------------------------------------------------------------------------------- +## DEFINE | USE CASE IF SET +## --------------------------------------------------------------------------------------------------------------------------------- +## GRADUAL VERIFICATION ## +## SKIP_PC_CHECK | Skip checking PC register updates. +## SKIP_RF_CHECK | Skip checking register file updates. +## SKIP_CSR_CHECK | Skip checking CSR updates and reads. +## SKIP_DMEM_CHECK | Skip checking data memory requests. +## LIMIT_TOTAL_INSTR_COUNT | Limit total # of instructions allowed in the pipeline. +## PERFORMANCE ENHANCEMENT ## +## RESTRICT_REGS | Restrict instruction decoding & register file verification to a subset of registers. +## RESTRICT_REGISTER_INDEX | Restrict register file verification to one register only, instruction decoding is not affected. +## RESTRICT_CHECK_DATA_SLICE | Restrict register file data and memory write data verification to a slice or even a bit. +## RESTRICT_MUL_OPS_FREE_BITS | Restrict # of operand bits allowed to toggle checking multiplication/ division instruction datapath. +## RESTRICT_DMEM_STALL_CYCLES | Restrict data memory stall cycles to specific number. Has an effect w/ protocol VIPs' usage. +## TAILORED VERIFICATION ## +## PVE_M_SUPPORT | Enable checking M extension data path. By default, only the control path is checked. +## PVE_FPU_SUPPORT | Enable checking F extension data path. By default, only the control path is checked. +## CHECK_ACCESS_FAULTS | Enable checking all access faults fully according to the privileged specification or Smepmp. +## CUSTOM_MEM_INTERFACES | Constrain memory interfaces. Use only in case bus protocols implemented are not tool supported. +## --------------------------------------------------------------------------------------------------------------------------------- +lappend defines {*}[dict get $configs $cfg define] {*}[dict get $pve_modes $pve_mode define] RESTRICT_REGS RESTRICT_DMEM_STALL_CYCLES=2 +## + +### RE-SET THE FOLLOWING SET OF VARIABLES (ONLY IF NECESSARY) ### +lappend pre_analysis_json_files_to_merge spec.json {*}[dict get $configs $cfg json] +set csr_addr_to_assist_analysis {} +set csr_rdata_to_assist_analysis {} +set core_instance_to_instantiate_vip_on ${core_inst} +lappend post_analysis_json_files_to_merge spec.json {*}[dict get $configs $cfg json] core.json +lappend extensions_to_generate_individual_checks_for F Zfinx +set extensions_to_exclude_assertion_generation_for {} +if {"CV_LOOP" in $defines} { + lappend pre_analysis_json_files_to_merge Xpulp_hwlp.json + lappend post_analysis_json_files_to_merge Xpulp_hwlp.json +} +## + +### EXTEND THE FOLLOWING LISTS BY THE RESPECTIVE RTL SIGNALS (ONLY IF NECESSARY) ### +lappend mul_signals_to_cut ${prefix}ex_stage_i.mult_i.result_o ${prefix}ex_stage_i.alu_i.alu_div_i.Res_DO ${prefix}ex_stage_i.alu_i.alu_div_i.Cnt_DP +lappend fpu_signals_to_cut ${prefix}apu_result_i ${prefix}apu_flags_i +lappend rtl_signals_to_cut +lappend rtl_signals_to_disassemble ${prefix}instr_rdata_i ${prefix}instr_rdata_id ${prefix}if_stage_i.instr_aligned +## + +if {![info exists reuse_files] || !$reuse_files} { + +## 1. PRE-ANALYSIS CONFIGURATION ## + + foreach i ${pre_analysis_json_files_to_merge} { + processor_integrity::merge_data -file ${i} + } + +## 2. DESIGN ANALYSIS ## + + processor_integrity::extract_ISA -csr_addr $csr_addr_to_assist_analysis -csr_rdata $csr_rdata_to_assist_analysis -core_instance $core_instance_to_instantiate_vip_on + +## 3. POST-ANALYSIS CONFIGURATION ## + + foreach i ${post_analysis_json_files_to_merge} { + processor_integrity::merge_data -file ${i} + } + + if {"CFG_ZFINX" in $defines} { + onespin::data::set ISA/Z/Zfinx true + } + + if {$pve_mode ne "DEF"} { + onespin::data::set PVE/checker_instance "RV_chk_DP" + } + +## 4. ASSERTION GENERATION ## + + cd $pve_mode_dir + processor_integrity::generate_assertions -create_individual_checks $extensions_to_generate_individual_checks_for -exclude_extensions $extensions_to_exclude_assertion_generation_for -force + cd $cwd +} else { + puts "-W- Re-using previously generated files! Make sure to re-generate all files on adopting a new tool version or changing the JSON configuration!" + source $pve_mode_dir/RISCV_disass.tcl + source RISCV_disass.tcl +} + +## 5. ASSERTION READING & RETUNING ## + +### USE TO CONSTRAIN MEMORY INTERFACES (ONLY IF BUS PROTOCOLS IMPLEMENTED ARE TOOL SUPPORTED) ### +## Instantiate the respective bus protocol VIP for each of the fetch and data memory interfaces +## The VIPs in this case are used to check and more importantly constrain memory interfaces +## Read in the instantiated VIPs, my_{}.sv, using the read_sva command below +#instantiate_vip -addr_sig instr_addr_o -generated_instance_name obi_imem_checker -filename obi_imem.sv obi +#instantiate_vip -addr_sig data_addr_o -generated_instance_name obi_dmem_checker -filename obi_dmem.sv obi +## + +read_sva -define $defines -include_path $pve_mode_dir {core_checker.sv $pve_mode_dir/bind.sv vips/obi_?mem.sv} + +## 7.1 ASSERTION RUNNING & DEBUGGING ## + +### USE TO RUN INITIAL SET OF ASSERTIONS ### +set_check_option -prover_exec_order { { approver1 approver4 prover2:0 prover2:8 prover2:11 disprover1 disprover3 } } -disprover1_steps 40 -disprover3_steps 40 +check [get_checks -filter name=~"*invariant_a"||name=~"*legal_CSR_reset_state_a"||name=~"*RESET_a"] +## + +## 6. PERFORMANCE ENHANCEMENT ## + +### USE TO COMPUTE INVARIANTS (IF NECESSARY) ### +compute_invariants +## + +if {$app eq "PRC"} { + ### USE TO PERFORM AUTOMATIC INITIAL VALUE ABSTRACTION (IVA) OF ARCHITECTURE STATE (IF NECESSARY) ### + lappend candidates X F frm + if {"CFG_XP" in $defines} { + lappend candidates lpstart0 lpstart1 lpend0 lpend1 + } + processor_integrity::generate_IVA -candidates $candidates + ## +} + +### USE TO CUT DESIGN COMPLEX SIGNALS (IF NECESSARY) ### +if {$pve_mode ne "DPM"} { + lappend rtl_signals_to_cut {*}$mul_signals_to_cut +} +if {($pve_mode ne "DPF") && ("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { + lappend rtl_signals_to_cut {*}$fpu_signals_to_cut +} +add_cut_signals $rtl_signals_to_cut +cut_signals +## + +## 7.2 ASSERTION RUNNING & DEBUGGING ## + +### USE TO EASE DEBUGGING BY DISASSEMBLING VALUES OF RTL SIGNALS HOLDING INSTRUCTION WORDS & RUN THE OTHER ASSERTIONS ### +foreach i ${rtl_signals_to_disassemble} { + use_value_printer ${i} PVE_disass +} +## + +#set nb_processes 2 +#set nb_processes 3 +#set nb_processes 4 +#set nb_processes 5 +#set nb_processes 6 +#set nb_processes 8 +#set nb_processes 12 +set nb_processes 16 +#set nb_processes 24 +#set nb_processes 32 + +set_check_option -verbose +set_check_option -local_processes $nb_processes +set_check_option -engine_licensing unlimited + +puts "\n-INFO- Launching $app app in $pve_mode mode with $nb_processes parallel processes.\n" + +#set_check_option -prover_exec_order { { approver1 approver4 prover2:0 prover2:8 prover2:11 disprover1 disprover3 } } +set_check_option -prover_exec_order { { approver1 prover2:0 prover2:8 prover2:11 } } +#set_check_option -disprover1_steps 40 -disprover3_steps 40 + +check_consistency -category model_building -effort maximum +exclude_check [get_checks -filter name=~"*hdl*"||name=~"*FSQRT_S_a*"||name=~"**FDIV_S_a*"] + +set DEF_checks [lsort -dictionary [get_checks -filter excluded==false&&(type==property||type==assertion)]] +set DPM_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32M.*"||name=~"*RV32X.CV_XDOT*"||name=~"*RV32X.CV_MUL*"||name=~"*RV32X.CV_MAC*"||name=~"*RV32X.CV_CPLXMUL*")]] +set DPF_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32F.*"||name=~"*RV32Zfinx.*")]] + +set group_1_checks [lsort -dictionary [concat core_i.RV_chk.ops.RESET_a [get_checks -filter excluded==false&&type==assertion]]] +set group_2_checks [lsort -dictionary [list core_i.RV_chk.ops.XCPT_IF_ID_a core_i.RV_chk.RV32C.ARITH_a core_i.RV_chk.RV32C.BRANCH_Taken_a core_i.RV_chk.RV32C.BRANCH_a core_i.RV_chk.RV32C.JUMP_a core_i.RV_chk.RV32I.EBREAK_BreakPoint_a core_i.RV_chk.RV32I.MEM_MultiAccess_a core_i.RV_chk.RV32I.xRET_a core_i.RV_chk.RV32X.CV_ADD_X_a core_i.RV_chk.RV32X.CV_BITMAN_OTHER_a core_i.RV_chk.RV32X.CV_EXTRACTX_X_a core_i.RV_chk.RV32X.CV_INSERTX_a core_i.RV_chk.RV32X.CV_PACKXX_X_a core_i.RV_chk.RV32X.CV_SETUPX_a core_i.RV_chk.RV32X.CV_SHUFFLE2_X_a core_i.RV_chk.RV32Zicsr.CSRx_a]] +set group_3_checks [lsort -dictionary [list core_i.RV_chk.ops.BUBBLE_a core_i.RV_chk.RV32I.ARITH_a core_i.RV_chk.RV32I.EBREAK_HaltReq_a core_i.RV_chk.RV32I.ECALL_a core_i.RV_chk.RV32I.FENCE_a core_i.RV_chk.RV32I.WFI_a core_i.RV_chk.RV32X.CV_ABS_X_a core_i.RV_chk.RV32X.CV_CLIPXX_a core_i.RV_chk.RV32X.CV_CMPEQ_X_a core_i.RV_chk.RV32X.CV_EXTRACTXX_a core_i.RV_chk.RV32X.CV_EXTXX_a core_i.RV_chk.RV32X.CV_INSERT_X_a core_i.RV_chk.RV32X.CV_SX_I_a core_i.RV_chk.RV32X.CV_SX_RI_a core_i.RV_chk.RV32X.CV_ADDXXNR_a core_i.RV_chk.RV32X.CV_SHUFFLEIX_SCI_B_a core_i.RV_chk.RV32X.CV_BSETX_a core_i.RV_chk.RV32X.CV_BXXIMM_Taken_a core_i.RV_chk.RV32X.CV_ENDX_a core_i.RV_chk.RV32X.CV_LXX_I_a core_i.RV_chk.RV32X.CV_LXX_RI_a core_i.RV_chk.RV32X.CV_SLL_X_a core_i.RV_chk.RV32X.CV_STARTX_a core_i.RV_chk.RV32X.CV_ADD_DIVX_a core_i.RV_chk.RV32X.CV_ADDXXN_a core_i.RV_chk.RV32X.CV_AVGU_X_a core_i.RV_chk.RV32X.CV_BCLRX_a core_i.RV_chk.RV32X.CV_SUB_DIVX_a core_i.RV_chk.RV32X.CV_SUBROTMJ_X_a core_i.RV_chk.RV32X.CV_SUBXXN_a core_i.RV_chk.RV32X.CV_SUBXXNR_a core_i.RV_chk.RV32X.CV_MAXU_X_a]] +set group_4_checks [lsort -dictionary [concat [get_checks -filter excluded==false&&name=~"*RV32X.CV_ELW*"] core_i.RV_chk.RV32I.EBREAK_ForcedEntry_a core_i.RV_chk.RV32X.CV_COUNTX_a core_i.RV_chk.RV32X.CV_LXX_R_a core_i.RV_chk.RV32X.CV_MAXX_a core_i.RV_chk.RV32X.CV_SX_R_a core_i.RV_chk.RV32C.MEM_a core_i.RV_chk.RV32C.MEM_MultiAccess_a core_i.RV_chk.RV32I.BRANCH_a core_i.RV_chk.RV32I.BRANCH_Taken_a core_i.RV_chk.RV32I.JUMP_a core_i.RV_chk.RV32I.MEM_a core_i.RV_chk.RV32X.CV_ABS_a core_i.RV_chk.RV32X.CV_AND_X_a core_i.RV_chk.RV32X.CV_AVG_X_a core_i.RV_chk.RV32X.CV_BXXIMM_a core_i.RV_chk.RV32X.CV_CMPGE_X_a core_i.RV_chk.RV32X.CV_CMPGEU_X_a core_i.RV_chk.RV32X.CV_CMPGT_X_a core_i.RV_chk.RV32X.CV_CMPGTU_X_a core_i.RV_chk.RV32X.CV_CMPLE_X_a core_i.RV_chk.RV32X.CV_CMPLEU_X_a core_i.RV_chk.RV32X.CV_CMPLT_X_a core_i.RV_chk.RV32X.CV_CMPLTU_X_a core_i.RV_chk.RV32X.CV_CMPNE_X_a core_i.RV_chk.RV32X.CV_CPLXCONJ_a core_i.RV_chk.RV32X.CV_LXX_I_MultiAccess_a core_i.RV_chk.RV32X.CV_LXX_R_MultiAccess_a core_i.RV_chk.RV32X.CV_LXX_RI_MultiAccess_a core_i.RV_chk.RV32X.CV_MAX_X_a core_i.RV_chk.RV32X.CV_MIN_X_a core_i.RV_chk.RV32X.CV_MINU_X_a core_i.RV_chk.RV32X.CV_MINX_a core_i.RV_chk.RV32X.CV_OR_X_a core_i.RV_chk.RV32X.CV_SHUFFLE_X_a core_i.RV_chk.RV32X.CV_SLEX_a core_i.RV_chk.RV32X.CV_SRA_X_a core_i.RV_chk.RV32X.CV_SRL_X_a core_i.RV_chk.RV32X.CV_SUB_X_a core_i.RV_chk.RV32X.CV_SX_I_MultiAccess_a core_i.RV_chk.RV32X.CV_SX_R_MultiAccess_a core_i.RV_chk.RV32X.CV_SX_RI_MultiAccess_a core_i.RV_chk.RV32X.CV_XOR_X_a core_i.RV_chk.RV32Zifencei.FENCE_I_a]] +set group_5_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32M.DIV16_a*"||name=~"*RV32M.DIV32_a*"||name=~"*RV32M.MUL_a*"||name=~"*RV32X.CV_XDOT*"||name=~"*RV32X.CV_MUL*"||name=~"*RV32X.CV_MAC*"||name=~"*RV32X.CV_CPLXMUL*")]] +set group_6_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32F.*"||name=~"*RV32Zfinx.*")]] + +set skipped_files "*/fpnew_* {} */gated_clk_cell* {} */lzc* {} */pa_fdsu_* {} */pa_fpu_* {} */rr_arb_tree* {}" + +puts "\n-INFO- Compile options::\n\n\t[dict get $apps $app compile]\n" +puts "\n-INFO- Elaborate options::\n\n\t[dict get $configs $cfg elab]\n" +puts "\n-INFO- Defines::\n\n\t$defines\n" +puts "\n-INFO- Cut signals::\n\n\t$rtl_signals_to_cut\n" + +if {$app eq "PRC"} { + +# set_check_option -prover_exec_order { { approver1 approver4 prover2:0 prover2:8 prover2:11 disprover1 disprover3 } } + set_check_option -prover_exec_order { { approver1 prover2:0 prover2:8 prover2:11 } } +# set_check_option -prover_exec_order { { disprover1 disprover3 } } -disprover1_steps 20 -disprover3_steps 20 + + set all_checks [set ${pve_mode}_checks] + set checks_nb [llength $all_checks] + set nb_round [expr $checks_nb / $nb_processes] + set nb_remain [expr $checks_nb % $nb_processes] + puts "nb_round = $nb_round, nb_remain = $nb_remain" + for {set i 0} {$i < $nb_round} {incr i} { + set checks [lrange $all_checks [expr $i * $nb_processes] [expr ((($i + 1) * $nb_processes) - 1)]] + puts "[expr $i * $nb_processes] [expr ((($i + 1) * $nb_processes) - 1)]" + puts "\n-INFO- Launching Check Command::\n\ncheck $checks\n" + check $checks + report_result -details + cd $app_dir + save_database -force round_[expr $i + 1] + cd $cwd + } + if {$nb_remain > 0} { + set checks [lrange $all_checks [expr $nb_round * $nb_processes] [expr (($nb_round * $nb_processes) + $nb_remain - 1)]] + puts "[expr $nb_round * $nb_processes] [expr (($nb_round * $nb_processes) + $nb_remain - 1)]" + puts "\n-INFO- Launching Check Command::\n\ncheck $checks\n" + check $checks + report_result -details + cd $app_dir + save_database -force round_[expr $nb_round + 1] + cd $cwd + } + + report_result -signoff -details + +# set_check_option -prover_exec_order { { disprover1 disprover3 } } +# puts "\n-INFO- Launching Check Command::\n\ncheck RV32M.DIV16_a\n" +# check [get_checks -filter name=~"*RV32M.DIV16_a*"] +# cd $app_dir +# save_database -force +# cd $cwd + +} + +if {$app eq "QTF"} { + + source basics.tcl.obf + + set_check_option -prover_exec_order { { disprover1 disprover3 } } -disprover1_steps 20 -disprover3_steps 20 + + set html "${app_dir}/html_results_${cfg}_${pve_mode}" + set results "${app_dir}/qtf_results_${cfg}_${pve_mode}_R" + set log "${app_dir}/${app}_${cfg}_${pve_mode}_R" + + if {$pve_mode eq "DEF"} { + + for {set i 1} {$i < 7} {incr i} { + puts "\nGroup (${i}) checks:\n\nTotal number of checks is: [llength [set group_${i}_checks]] \n" + foreach j [set group_${i}_checks] { + puts "$j" + } + } + + for {set i 1} {$i < 7} {incr i} { + puts "Group (${i}) checks: Total number of checks is: [llength [set group_${i}_checks]]" + } + +# for {set i 1} {$i < 7} {incr i} { + + set i 5 + + start_message_log ${log}${i}.log + if {$i == 1} { + quantify_run 0 $i {-no_cuts} 1.0 2 1 ${html}_L2_S1_R${i} ${results}${i} $group_1_checks {} {} + } elseif {$i == 2} { + quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_2_checks ${results}[expr $i-1] $skipped_files + } elseif {$i == 3} { + quantify_run 0 $i {-no_cuts} 2.0 4 3 ${html}_L4_S2_R${i} ${results}${i} $group_3_checks ${results}[expr $i-1] $skipped_files + } elseif {$i == 4} { + quantify_run 0 $i {-no_cuts} 2.0 4 3 ${html}_L4_S2_R${i} ${results}${i} $group_4_checks ${results}[expr $i-1] $skipped_files + } elseif {$i == 5} { +# quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${results}[expr $i-1] $skipped_files + quantify_run 0 $i {} 6.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${results}[expr $i-1] $skipped_files + } elseif {($i == 6) && ("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { + quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_6_checks ${results}[expr $i-1] {} + } + stop_message_log +# } + + } elseif {$pve_mode eq "DPM"} { + + if {("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { + set i 7 + } else { + set i 6 + } + + start_message_log ${log}${i}.log +# quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks {} $skipped_files +# file copy -force ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1]-Xr +# fileutil::updateInPlace ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] [list string map [list " Xr" " U0"]] +# quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] $skipped_files + quantify_run 0 $i {} 6.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] $skipped_files + stop_message_log + + } elseif {$pve_mode eq "DPF"} { + + set i 8 + + start_message_log ${log}${i}.log +# quantify_run 0 $i -no_cuts 2.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_6_checks {} {} +# file copy -force ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1] ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1]-Xr +# fileutil::updateInPlace ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1] [list string map [list " Xr" " U0"]] + quantify_run 0 $i -no_cuts 2.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_6_checks ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1] {} + stop_message_log + + } + +} + +if {$app eq "VCI"} { + + set_check_option -prover_exec_order { { disprover1 disprover3 } } -disprover1_steps 20 -disprover3_steps 20 + + set output_dir "${app_dir}/qtf_coverage_${cfg}_${pve_mode}" + set checks "[set ${pve_mode}_checks]" + set results "${cfg_dir}/${pve_mode}/QTF/qtf_results_${cfg}_${pve_mode}_R" + set log "${app_dir}/${app}_${cfg}_${pve_mode}" + + if {$pve_mode eq "DEF"} { + if {("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { + set i 6 + } else { + set i 5 + } + } elseif {$pve_mode eq "DPM"} { + if {("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { + set i 7 + } else { + set i 6 + } + } elseif {$pve_mode eq "DPF"} { + set i 8 + } + + start_message_log ${log}.log + puts "\n-INFO- Launching VCI Command::\nexport_quantify_coverage -call_script t.sh -generate_flist -output_dir $output_dir -checks $checks ${results}${i}\n" + export_quantify_coverage -call_script t.sh -generate_flist -output_dir $output_dir -checks $checks ${results}${i} + stop_message_log +# report_quantify_result -quantify_result qtf_results_run_${run} -html html_results_run_${run} + +} diff --git a/scripts/riscv_isa_formal/common/setup_mv.tcl b/scripts/riscv_isa_formal/common/setup_mv.tcl new file mode 100755 index 000000000..84eb4523c --- /dev/null +++ b/scripts/riscv_isa_formal/common/setup_mv.tcl @@ -0,0 +1,8 @@ +if {![info exists ::env(DESIGN_RTL_DIR)]} { + set ::env(DESIGN_RTL_DIR) [pwd]/rtl +} +set_read_hdl_option -verilog_version sv2012 -pragma_ignore {translate_} +vlog -sv -f cv32e40p_fpu_manifest.flist +elaborate +compile +set_mode mv diff --git a/scripts/riscv_isa_formal/common/t.sh b/scripts/riscv_isa_formal/common/t.sh new file mode 100755 index 000000000..eca98e09f --- /dev/null +++ b/scripts/riscv_isa_formal/common/t.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# +# This script is a template representing a customization to integrate OneSpin 360 with VCS simulator +# +# onespin calls the script as follows: +# template_vcs_flow.sh +# +# In this script you need to set up the environment for the simulator, +# +ARG1=$1 + +vsim -64 -c -do "source ${ARG1}; quit -f" diff --git a/scripts/riscv_isa_formal/common/vips/obi_dmem.sv b/scripts/riscv_isa_formal/common/vips/obi_dmem.sv new file mode 100755 index 000000000..7ca5866e2 --- /dev/null +++ b/scripts/riscv_isa_formal/common/vips/obi_dmem.sv @@ -0,0 +1,60 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// General remarks: // +// // +// Just replace below with the name of the module you want to connect the VIP to // +// and add the appropriate parameter values and DUT signals in braces. // +// // +// Leave unused signals (and parameters that just have the default value) simply unconnected // +// because optional signals are pulled up/down appropriately in the checker file. // +// // +// The VIP uses an active LOW reset. // +// If your DUT reset signal, called "rst", is active high, use "!rst" in the instantiation // +// // +// For external interfaces (bus signals are primary inputs/outputs), set parameter ASSUME=1. // +// In that case, make sure MASTER=1 in case the DUT is the bus master (driving the address signal output), // +// or MASTER=0 in case the DUT is the bus slave (address signal is input). // +// // +// In case you instantiate the VIP several times for different interfaces in the DUT, // +// make sure to pick individual instance names (line with comment "non-ambiguous instance name" below) // +// // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bind cv32e40p_core obi_checker #( + .ADDR_WIDTH (), // (default 32) number of bits in addr + .DATA_WIDTH (), // (default 32) number of bits in wdata, rdata + .ASSUME (1), // (default 0) switch to create assumes + .MASTER (1), // (default 0) switch to select master/slave side (when switched off, i.e., slave side, important in case of ASSUME) + .ASSERT_ON (), // (default 1) switch to generate assertions, + // useful to switch off (ASSERT_ON=0) together with ASSUME=1 just to constrain a block for Inspect + .COVER_ON (), // (default 1) switch to additionally generate cover statements + .X_CHECKING_ON(), // (default 0) switch to create no-X assertions (to be used in conjunction with x_checking_setup) + .LIVENESS_ON (), // (default 0) switch to create liveness assertions + .MAX_WAIT (`RESTRICT_DMEM_STALL_CYCLES), // (default $) number of cycles for waiting period checks (for creating liveness checks in case LIVENESS_ON=1) + .AUSER_WIDTH (), // (default 32) number of bits in auser (if used) + .WUSER_WIDTH (), // (default 32) number of bits in wuser (if used) + .RUSER_WIDTH (), // (default 32) number of bits in ruser (if used) + .ID_WIDTH (), // (default 32) number of bits in aid, rid (if used) + .MAX_OUTSTANDING_TRANSACTIONS(), // (default 2) maximum number of outstanding transactions in the system + .RESPONSE_PREDICTOR(1) // (default 0) switch to introduce a signal to predict the response at the beginning of the data phase +) obi_dmem_checker ( // non-ambiguous instance name + .clk (clk_i), // required + .reset_n(rst_ni), // required +// Address channel + .req (data_req_o), // required + .gnt (data_gnt_i), // required + .addr (data_addr_o), // required /*ADDRESS*/ + .we (data_we_o), // optional, default is 1'b0 + .be (data_be_o), // optional, default is '1 + .wdata (data_wdata_o), // required /*DATA*/ + .auser (), // optional, default is '0 + .wuser (), // optional, default is '0 + .aid (), // optional, default is '0 +// Response channel + .rvalid (data_rvalid_i), // required + .rready (), // optional, default is 1'b1 + .rdata (data_rdata_i), // required /*DATA*/ + .err (), // optional, default is 1'b0 + .ruser (), // optional, default is '0 + .rid () // optional, default is '0 +); diff --git a/scripts/riscv_isa_formal/common/vips/obi_imem.sv b/scripts/riscv_isa_formal/common/vips/obi_imem.sv new file mode 100755 index 000000000..126152246 --- /dev/null +++ b/scripts/riscv_isa_formal/common/vips/obi_imem.sv @@ -0,0 +1,59 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// General remarks: // +// // +// Just replace below with the name of the module you want to connect the VIP to // +// and add the appropriate parameter values and DUT signals in braces. // +// // +// Leave unused signals (and parameters that just have the default value) simply unconnected // +// because optional signals are pulled up/down appropriately in the checker file. // +// // +// The VIP uses an active LOW reset. // +// If your DUT reset signal, called "rst", is active high, use "!rst" in the instantiation // +// // +// For external interfaces (bus signals are primary inputs/outputs), set parameter ASSUME=1. // +// In that case, make sure MASTER=1 in case the DUT is the bus master (driving the address signal output), // +// or MASTER=0 in case the DUT is the bus slave (address signal is input). // +// // +// In case you instantiate the VIP several times for different interfaces in the DUT, // +// make sure to pick individual instance names (line with comment "non-ambiguous instance name" below) // +// // +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bind cv32e40p_core obi_checker #( + .ADDR_WIDTH (), // (default 32) number of bits in addr + .DATA_WIDTH (), // (default 32) number of bits in wdata, rdata + .ASSUME (1), // (default 0) switch to create assumes + .MASTER (1), // (default 0) switch to select master/slave side (when switched off, i.e., slave side, important in case of ASSUME) + .ASSERT_ON (), // (default 1) switch to generate assertions, + // useful to switch off (ASSERT_ON=0) together with ASSUME=1 just to constrain a block for Inspect + .COVER_ON (), // (default 1) switch to additionally generate cover statements + .X_CHECKING_ON(), // (default 0) switch to create no-X assertions (to be used in conjunction with x_checking_setup) + .LIVENESS_ON (), // (default 0) switch to create liveness assertions + .MAX_WAIT (), // (default $) number of cycles for waiting period checks (for creating liveness checks in case LIVENESS_ON=1) + .AUSER_WIDTH (), // (default 32) number of bits in auser (if used) + .WUSER_WIDTH (), // (default 32) number of bits in wuser (if used) + .RUSER_WIDTH (), // (default 32) number of bits in ruser (if used) + .ID_WIDTH (), // (default 32) number of bits in aid, rid (if used) + .MAX_OUTSTANDING_TRANSACTIONS() // (default 2) maximum number of outstanding transactions in the system +) obi_imem_checker ( // non-ambiguous instance name + .clk (clk_i), // required + .reset_n(rst_ni), // required +// Address channel + .req (instr_req_o), // required + .gnt (instr_gnt_i), // required + .addr (instr_addr_o), // required /*ADDRESS*/ + .we (), // optional, default is 1'b0 + .be (), // optional, default is '1 + .wdata ('0), // required /*DATA*/ + .auser (), // optional, default is '0 + .wuser (), // optional, default is '0 + .aid (), // optional, default is '0 +// Response channel + .rvalid (instr_rvalid_i), // required + .rready (), // optional, default is 1'b1 + .rdata (instr_rdata_i), // required /*DATA*/ + .err (), // optional, default is 1'b0 + .ruser (), // optional, default is '0 + .rid () // optional, default is '0 +); diff --git a/scripts/riscv_isa_formal/launch_command example b/scripts/riscv_isa_formal/launch_command example new file mode 100755 index 000000000..6b7f3a0a3 --- /dev/null +++ b/scripts/riscv_isa_formal/launch_command example @@ -0,0 +1,58 @@ +# Setup tool and licenses +#source SourceMe + +set instructions="v1_8_0"; set name_cmd="NAME=${instructions} ; + +set config=XP ; set config_cmd="CONF=${config}" +set config=XPF0 ; set config_cmd="CONF=${config}" +set config=XPF1 ; set config_cmd="CONF=${config}" +set config=XPF2 ; set config_cmd="CONF=${config}" +set config=XPZF0 ; set config_cmd="CONF=${config}" +set config=XPZF1 ; set config_cmd="CONF=${config}" +set config=XPZF2 ; set config_cmd="CONF=${config}" + +set app=PRC ; set app_cmd="APP=${app}" +set app=QTF ; set app_cmd="APP=${app}" +set app=VCI ; set app_cmd="APP=${app}" + +set mode=DEF ; set mode_cmd="MODE=${mode}" +set mode=DPM ; set mode_cmd="MODE=${mode}" +set mode=DPF ; set mode_cmd="MODE=${mode}" + +# Prepare the working directory (common files and design copy) or reuse existing one (no copy) +set prepare="" +set prepare="PREPARE=1" + +set verbose="" +set verbose="VERBOSE=1" + +set timeout="" +set timeout="DBG=1800" + +# Interactive or batch run on local server +set gui="gui" ; set gui_cmd="GUI=1" +set gui="batch" ; set gui_cmd="" + +set my_time = `date '+%Y-%m-%d-%Hh%Mm%Ss'` ; set logname=run_${gui}-${app}-cfg_${config}-mode_${mode}-${instructions}-${my_time}.log ; echo "\n vi ${logname}\n" ; \ +echo "make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all\n" > ${logname} && echo "" >>& ${logname} ; \ +/usr/bin/time make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all >> & ! ${logname} & + +# Interactive or batch run on compute farm server using LSF +set gui="lsf" ; set gui_cmd="" ; set queue="long" +set gui="lsf_gui" ; set gui_cmd="GUI=1" ; set queue="gui -XF" +set gui="lsf_gui" ; set gui_cmd="GUI=1" ; set queue="gui -XF -Is -tty" + +set nb_cpus="1" +set nb_cpus="2" +set nb_cpus="4" +set nb_cpus="8" +set nb_cpus="12" +set nb_cpus="16" +set nb_cpus="24" +set nb_cpus="32" +set nb_cpus="36" +set nb_cpus="48" + +set my_time = `date '+%Y-%m-%d-%Hh%Mm%Ss'` ; set logname=run_${gui}-${app}-cfg_${config}-mode_${mode}-${instructions}-${my_time}.log ; echo "\n vi ${logname}\n" ; \ +echo "make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all\n" > ${logname} && echo "" >>& ${logname} ; \ +bsub -J ${app}-cfg_${config}-mode_${mode}-${instructions} -P cv32e40p -q ${queue} -oo ${logname} -n ${nb_cpus} -R "select[cpuf>=15.0] span[hosts=1] rusage[mem=64G]" make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all From f6bd677ca1523387e00762e02b26ec7589ec4135 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Fri, 31 May 2024 16:41:28 +0800 Subject: [PATCH 65/69] Uploading formal work related to code coverage analysis --- scripts/formal/Makefile | 54 ++++++ scripts/formal/README.md | 24 +++ scripts/formal/cv32e40p_formal.flist | 33 ++++ scripts/formal/formal.do | 37 ++++ scripts/formal/src/cv32e40p_EX_assert.sv | 74 ++++++++ scripts/formal/src/cv32e40p_ID_assert.sv | 46 +++++ scripts/formal/src/cv32e40p_assert.sv | 124 +++++++++++++ scripts/formal/src/cv32e40p_bind.sv | 117 +++++++++++++ scripts/formal/src/cv32e40p_formal_top.sv | 93 ++++++++++ scripts/formal/src/data_assert.sv | 74 ++++++++ scripts/formal/src/debug_assert.sv | 46 +++++ .../formal/src/fpnew_divsqrt_th_32_assert.sv | 42 +++++ scripts/formal/src/insn_assert.sv | 165 ++++++++++++++++++ scripts/formal/src/interrupt_assert.sv | 46 +++++ 14 files changed, 975 insertions(+) create mode 100644 scripts/formal/Makefile create mode 100644 scripts/formal/README.md create mode 100644 scripts/formal/cv32e40p_formal.flist create mode 100644 scripts/formal/formal.do create mode 100644 scripts/formal/src/cv32e40p_EX_assert.sv create mode 100644 scripts/formal/src/cv32e40p_ID_assert.sv create mode 100644 scripts/formal/src/cv32e40p_assert.sv create mode 100644 scripts/formal/src/cv32e40p_bind.sv create mode 100644 scripts/formal/src/cv32e40p_formal_top.sv create mode 100644 scripts/formal/src/data_assert.sv create mode 100644 scripts/formal/src/debug_assert.sv create mode 100644 scripts/formal/src/fpnew_divsqrt_th_32_assert.sv create mode 100644 scripts/formal/src/insn_assert.sv create mode 100644 scripts/formal/src/interrupt_assert.sv diff --git a/scripts/formal/Makefile b/scripts/formal/Makefile new file mode 100644 index 000000000..bff46da6f --- /dev/null +++ b/scripts/formal/Makefile @@ -0,0 +1,54 @@ +# Copyright 2024 Dolphin Design +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# +# Licensed under the Solderpad Hardware License v 2.1 (the "License"); +# you may not use this file except in compliance with the License, or, +# at your option, the Apache License version 2.0. +# You may obtain a copy of the License at +# +# https://solderpad.org/licenses/SHL-2.1/ +# +# Unless required by applicable law or agreed to in writing, any work +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +################################################################################## +# # +# Contributors: Yoann Pruvost, Dolphin Design # +# # +# Description: Makefile for CV32E40P Formal code analysis # +# # +################################################################################## + +export DESIGN_RTL_DIR = ../../rtl + +create_lib: + rm -rf work + vlib work + +compile_design: create_lib + vlog -sv -f ../../cv32e40p_fpu_manifest.flist + vlog -sv -mfcu -cuname cv32e40p_bind -f cv32e40p_formal.flist + +compile_design_pulp: create_lib + vlog -sv +define+PULP -f ../../cv32e40p_fpu_manifest.flist + vlog -sv +define+PULP -mfcu -cuname cv32e40p_bind -f cv32e40p_formal.flist + +compile_design_pulp_f0: create_lib + vlog -sv +define+PULP_F0 -f ../../cv32e40p_fpu_manifest.flist + vlog -sv +define+PULP_F0 -mfcu -cuname cv32e40p_bind -f cv32e40p_formal.flist + +run: compile_design + qverify -c -do formal.do + +run_pulp: compile_design_pulp + qverify -c -do formal.do + +run_pulp_F0: compile_design_pulp_f0 + qverify -c -do formal.do + +clean: + qverify_clean + rm -rf work \ No newline at end of file diff --git a/scripts/formal/README.md b/scripts/formal/README.md new file mode 100644 index 000000000..aa91fab6a --- /dev/null +++ b/scripts/formal/README.md @@ -0,0 +1,24 @@ +## CV32E40P Formal + + This folder contains the source and scripts used in the effort to justify waived code coverage holes using formal tools. + + Disclaimer: This has been developped and tested with Siemens Questa formal and the Makefile only support this tool. Porting to other tools should be straightforward as all source files are standard sva. + +### Introduction + To assist code coverage analysis we formally proved that some code was in our case unreachable. Each assertion correspond to one coverage holes. We tried to keep the constraints as minimal as possible. The only constraints we are using are: + - OBI protocol constraints on both instructions and data interfaces + - Disabling scan + + +### How to use + +Inside this folder, with ```vlog``` and ```qverify``` available in your PATH, run one of the following command. + +| Command | Description | +|-----------------|-----------------------------------------------| +|make run | Run default config (no corev_pulp, no FPU) | +|make run_pulp | Run config corev_pulp withou FPU | +|make run_pulp_F0 | Run config corev_pulp with FPU with latency 0 | +|make clean | Remove all temporary file | + +All runs are in batch. At the end of the run, use ```qverify ``` to open the results in GUI. \ No newline at end of file diff --git a/scripts/formal/cv32e40p_formal.flist b/scripts/formal/cv32e40p_formal.flist new file mode 100644 index 000000000..e3c5f1f2a --- /dev/null +++ b/scripts/formal/cv32e40p_formal.flist @@ -0,0 +1,33 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Filelist for CV32E40P formal code analysis // +// // +//////////////////////////////////////////////////////////////////////////////////// + ++incdir+./src +src/insn_assert.sv +src/data_assert.sv +src/cv32e40p_assert.sv +src/cv32e40p_ID_assert.sv +src/cv32e40p_EX_assert.sv +src/fpnew_divsqrt_th_32_assert.sv +src/cv32e40p_formal_top.sv +src/cv32e40p_bind.sv \ No newline at end of file diff --git a/scripts/formal/formal.do b/scripts/formal/formal.do new file mode 100644 index 000000000..8e0be6031 --- /dev/null +++ b/scripts/formal/formal.do @@ -0,0 +1,37 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Formal script for CV32E40P // +// // +//////////////////////////////////////////////////////////////////////////////////// + +set top cv32e40p_formal_top + +#netlist clock clk_i -period 50 + +#netlist constraint rst_ni -value 1'b1 -after_init + +#netlist port domain i_lint_grnt -clock i_clk + +formal compile -d cv32e40p_formal_top -cuname cv32e40p_bind + +formal verify -timeout 100m -jobs 4 -sanity_waveforms + +#exit diff --git a/scripts/formal/src/cv32e40p_EX_assert.sv b/scripts/formal/src/cv32e40p_EX_assert.sv new file mode 100644 index 000000000..6a04b7629 --- /dev/null +++ b/scripts/formal/src/cv32e40p_EX_assert.sv @@ -0,0 +1,74 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Assertion for unreachable code in CV32E40P EX stage // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module cv32e40p_EX_assert import cv32e40p_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input logic apu_valid , + input logic apu_singlecycle , + input logic apu_multicycle , + input logic regfile_alu_we_i, + input logic apu_en_i , + input logic regfile_we_lsu , + input logic apu_rvalid_i , + input logic apu_rvalid_q , + + input logic data_misaligned_i , + input logic data_misaligned_ex_i , + input logic data_req_i , + input logic data_rvalid_i , + input logic mulh_active , + input mul_opcode_e mult_operator_i , + input logic [ 1:0] ctrl_transfer_insn_in_dec_i, + input logic apu_read_dep_for_jalr_o +); + + property unreachable_ex_211; + @(posedge clk_i) disable iff(!rst_ni) + (apu_valid & (apu_singlecycle | apu_multicycle)) |-> !(apu_en_i & regfile_alu_we_i); + endproperty + + property unreachable_ex_237; + @(posedge clk_i) disable iff(!rst_ni) + regfile_we_lsu |-> !(~apu_valid & (!apu_singlecycle & !apu_multicycle)); + endproperty + + property unreachable_ex_387; + @(posedge clk_i) disable iff(!rst_ni) + ((apu_rvalid_i && apu_multicycle) && ~(((ctrl_transfer_insn_in_dec_i == 2) && regfile_alu_we_i) && ~apu_read_dep_for_jalr_o) && ~((data_misaligned_i || data_misaligned_ex_i) || ((data_req_i || data_rvalid_i) && regfile_alu_we_i)) && mulh_active)|-> mult_operator_i == MUL_H; + endproperty + + property unreachable_ex_396; + @(posedge clk_i) disable iff(!rst_ni) + (apu_rvalid_q && ~(( ~apu_read_dep_for_jalr_o && (ctrl_transfer_insn_in_dec_i==2)) && regfile_alu_we_i) && ~((data_misaligned_i || data_misaligned_ex_i) || ((data_req_i || data_rvalid_i) && regfile_alu_we_i)) && mulh_active) |-> mult_operator_i == MUL_H; + endproperty + + assert_unreachable_ex_211: assert property(unreachable_ex_211); + assert_unreachable_ex_237: assert property(unreachable_ex_237); + assert_unreachable_ex_387: assert property(unreachable_ex_387); + assert_unreachable_ex_396: assert property(unreachable_ex_396); + +endmodule \ No newline at end of file diff --git a/scripts/formal/src/cv32e40p_ID_assert.sv b/scripts/formal/src/cv32e40p_ID_assert.sv new file mode 100644 index 000000000..1a6b58cf3 --- /dev/null +++ b/scripts/formal/src/cv32e40p_ID_assert.sv @@ -0,0 +1,46 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Assertion for unreachable code in CV32E40P ID stage // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module cv32e40p_ID_assert import cv32e40p_pkg::*; +( + input logic clk_i, + input logic rst_ni, + + input logic [31:0] instr_rdata_i, + input logic is_compressed_id_i, + + input logic [ 2:0] alu_op_a_mux_sel, + input logic [ 2:0] alu_op_b_mux_sel, + input logic [ 1:0] alu_op_c_mux_sel, + input logic alu_bmask_b_mux_sel, + input logic [ 1:0] ctrl_transfer_target_mux_sel +); + + property unreachable_id_872; + @(posedge clk_i) disable iff(!rst_ni) + (alu_op_c_mux_sel == OP_C_REGC_OR_FWD) && (~(alu_op_b_mux_sel == OP_B_BMASK) && ((alu_op_a_mux_sel != OP_A_REGC_OR_FWD) && (ctrl_transfer_target_mux_sel != JT_JALR)) && ~alu_bmask_b_mux_sel) |-> alu_op_b_mux_sel == OP_B_IMM; + endproperty + + assert_unreachable_id_872: assert property(unreachable_id_872); +endmodule \ No newline at end of file diff --git a/scripts/formal/src/cv32e40p_assert.sv b/scripts/formal/src/cv32e40p_assert.sv new file mode 100644 index 000000000..610ad3940 --- /dev/null +++ b/scripts/formal/src/cv32e40p_assert.sv @@ -0,0 +1,124 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// Pascal Gouedo, Dolphin Design // +// // +// Description: GLobal assume and assert for CV32E40P formal code analysis // +// // +//////////////////////////////////////////////////////////////////////////////////// + + +module cv32e40p_assert import cv32e40p_pkg::*; +( + input logic clk_i, + input logic rst_ni, + input logic scan_cg_en_i, + + input logic [31:0] boot_addr_i, + input logic [31:0] mtvec_addr_i, + input logic [31:0] hart_id_i, + input logic [31:0] dm_halt_addr_i, + input logic [31:0] dm_exception_addr_i, + + input logic [1:0] data_type_ex_i, + + input logic [31:0] pc_id_i, + + // Taken from controller + input ctrl_state_e ctrl_fsm_cs, + input logic is_hwlp_body, + input logic hwlp_end0_eq_pc, + input logic hwlp_counter0_gt_1, + input logic hwlp_end1_eq_pc, + input logic hwlp_counter1_gt_1, + input logic jump_done_q +); + import cv32e40p_tracer_pkg::*; + + /********** + * Assume * + **********/ + property no_scan; + @(posedge clk_i) disable iff(!rst_ni) + scan_cg_en_i == '0; + endproperty + + property hart_id_0; + @(posedge clk_i) disable iff(!rst_ni) + hart_id_i == '0; + endproperty + + property aligned_boot_address; + @(posedge clk_i) disable iff(!rst_ni) + boot_addr_i == 32'h1000_0000; + endproperty + + property aligned_mtvec_address; + @(posedge clk_i) disable iff(!rst_ni) + mtvec_addr_i == 32'h2000_0000; + endproperty + + property aligned_halt_address; + @(posedge clk_i) disable iff(!rst_ni) + dm_halt_addr_i == 32'h3000_0000; + endproperty + + property aligned_exception_address; + @(posedge clk_i) disable iff(!rst_ni) + dm_exception_addr_i == 32'h4000_0000; + endproperty + + /********** + * Assert * + **********/ + property data_type_ex_never_11; + @(posedge clk_i) disable iff(!rst_ni) + data_type_ex_i != 2'b11; + endproperty + + property never_jump_done_q_when_hwlp_body_and_hwlp_end0_eq_pc_and_hwlp_counter0_gt_1; + @(posedge clk_i) disable iff(!rst_ni) + (ctrl_fsm_cs == DECODE) & is_hwlp_body & hwlp_end0_eq_pc & hwlp_counter0_gt_1 |-> ~jump_done_q; + endproperty + + property never_ret_from_int_ecall_ebreak_exceptions_on_HWLoop1_last_inst_with_HWLoop1_counter_not_gt1; + @(posedge clk_i) disable iff(!rst_ni) + (ctrl_fsm_cs == DECODE) & is_hwlp_body |-> ~(hwlp_end1_eq_pc & hwlp_counter1_gt_1); + endproperty + + property pc_id_aligned; + @(posedge clk_i) disable iff(!rst_ni) + pc_id_i[2:0] != 2'b00; + endproperty + + + + assume_no_scan: assume property(no_scan); + // assume_hart_id_0: assume property(hart_id_0); + // assume_aligned_boot_address: assume property(aligned_boot_address); + // asuume_aligned_mtvec_address: assume property(aligned_mtvec_address); + // assume_aligned_halt_address: assume property(aligned_halt_address); + // assume_aligned_exception_address: assume property(aligned_exception_address); + + assert_data_type_ex_never_11: assert property(data_type_ex_never_11); + // assert_never_jump_done_q_when_hwlp_body_and_hwlp_end0_eq_pc_and_hwlp_counter0_gt_1: assert property(never_jump_done_q_when_hwlp_body_and_hwlp_end0_eq_pc_and_hwlp_counter0_gt_1); + // assert_never_ret_from_int_ecall_ebreak_exceptions_on_HWLoop1_last_inst_with_HWLoop1_counter_not_gt1: assert property(never_ret_from_int_ecall_ebreak_exceptions_on_HWLoop1_last_inst_with_HWLoop1_counter_not_gt1); + // assert_pc_id_aligned: assert property(pc_id_aligned); + +endmodule \ No newline at end of file diff --git a/scripts/formal/src/cv32e40p_bind.sv b/scripts/formal/src/cv32e40p_bind.sv new file mode 100644 index 000000000..38d51941a --- /dev/null +++ b/scripts/formal/src/cv32e40p_bind.sv @@ -0,0 +1,117 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// Pascal Gouedo, Dolphin Design // +// // +// Description: CV32E40P binding for formal code analysis // +// // +//////////////////////////////////////////////////////////////////////////////////// + +bind cv32e40p_formal_top insn_assert u_insn_assert ( + .clk_i(clk_i), + .rst_ni(rst_ni), + + .instr_req_o (instr_req_o), + .instr_gnt_i (instr_gnt_i), + .instr_rvalid_i(instr_rvalid_i), + .instr_addr_o (instr_addr_o), + .instr_rdata_i (instr_rdata_i) +); + +bind cv32e40p_formal_top data_assert u_data_assert ( + .clk_i(clk_i), + .rst_ni(rst_ni), + + .data_req_o (data_req_o ), + .data_gnt_i (data_gnt_i ), + .data_rvalid_i(data_rvalid_i), + .data_we_o (data_we_o ), + .data_be_o (data_be_o ), + .data_addr_o (data_addr_o ), + .data_wdata_o (data_wdata_o ), + .data_rdata_i (data_rdata_i ) +); + +bind cv32e40p_formal_top cv32e40p_assert u_cv32e40p_assert ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .scan_cg_en_i(scan_cg_en_i), + + .boot_addr_i (boot_addr_i ), + .mtvec_addr_i (mtvec_addr_i ), + .hart_id_i (hart_id_i ), + .dm_halt_addr_i (dm_halt_addr_i ), + .dm_exception_addr_i(dm_exception_addr_i), + + .data_type_ex_i(u_cv32e40p_top.core_i.data_type_ex), + + .pc_id_i(u_cv32e40p_top.core_i.pc_id), + + //From controller + .ctrl_fsm_cs (u_cv32e40p_top.core_i.id_stage_i.controller_i.ctrl_fsm_cs ), + .is_hwlp_body (u_cv32e40p_top.core_i.id_stage_i.controller_i.is_hwlp_body ), + .hwlp_end0_eq_pc (u_cv32e40p_top.core_i.id_stage_i.controller_i.hwlp_end0_eq_pc ), + .hwlp_counter0_gt_1(u_cv32e40p_top.core_i.id_stage_i.controller_i.hwlp_counter0_gt_1), + .hwlp_end1_eq_pc (u_cv32e40p_top.core_i.id_stage_i.controller_i.hwlp_end1_eq_pc ), + .hwlp_counter1_gt_1(u_cv32e40p_top.core_i.id_stage_i.controller_i.hwlp_counter1_gt_1), + .jump_done_q (u_cv32e40p_top.core_i.id_stage_i.controller_i.jump_done_q ) +); + +bind cv32e40p_id_stage cv32e40p_ID_assert u_cv32e40p_ID_assert ( + .clk_i(clk), + .rst_ni(rst_n), + + .alu_op_a_mux_sel (alu_op_a_mux_sel ), + .alu_op_b_mux_sel (alu_op_b_mux_sel ), + .alu_op_c_mux_sel (alu_op_c_mux_sel ), + .alu_bmask_b_mux_sel (alu_bmask_b_mux_sel ), + .ctrl_transfer_target_mux_sel(ctrl_transfer_target_mux_sel) +); + +bind cv32e40p_ex_stage cv32e40p_EX_assert u_cv32e40p_EX_assert ( + .clk_i(clk), + .rst_ni(rst_n), + + .apu_valid (apu_valid ), + .apu_singlecycle (apu_singlecycle ), + .apu_multicycle (apu_multicycle ), + .regfile_alu_we_i(regfile_alu_we_i), + .apu_en_i (apu_en_i ), + .regfile_we_lsu (regfile_we_lsu ), + .apu_rvalid_i (apu_rvalid_i ), + .apu_rvalid_q (apu_rvalid_q ), + .data_misaligned_i (data_misaligned_i ), + .data_misaligned_ex_i (data_misaligned_ex_i ), + .data_req_i (data_req_i ), + .data_rvalid_i (data_rvalid_i ), + .mulh_active (mulh_active ), + .mult_operator_i (mult_operator_i ), + .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec_i), + .apu_read_dep_for_jalr_o (apu_read_dep_for_jalr_o ) +); + +bind fpnew_divsqrt_th_32 fpnew_divsqrt_th_32_assert u_fpnew_divsqrt_th_32_assert ( + .clk_i (clk_i), + .rst_ni(rst_ni), + + .op_starting (op_starting ), + .unit_ready_q (unit_ready_q ), + .ex2_inst_wb (ex2_inst_wb ), + .ex2_inst_wb_vld_q(ex2_inst_wb_vld_q) +); diff --git a/scripts/formal/src/cv32e40p_formal_top.sv b/scripts/formal/src/cv32e40p_formal_top.sv new file mode 100644 index 000000000..5148cd76d --- /dev/null +++ b/scripts/formal/src/cv32e40p_formal_top.sv @@ -0,0 +1,93 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Formal testbench for CV32E40P // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module cv32e40p_formal_top ( + // Clock and Reset + input logic clk_i, + input logic rst_ni, + + input logic pulp_clock_en_i, // PULP clock enable (only used if COREV_CLUSTER = 1) + input logic scan_cg_en_i, // Enable all clock gates for testing + + // Core ID, Cluster ID, debug mode halt address and boot address are considered more or less static + input logic [31:0] boot_addr_i, + input logic [31:0] mtvec_addr_i, + input logic [31:0] dm_halt_addr_i, + input logic [31:0] hart_id_i, + input logic [31:0] dm_exception_addr_i, + + // Instruction memory interface + output logic instr_req_o, + input logic instr_gnt_i, + input logic instr_rvalid_i, + output logic [31:0] instr_addr_o, + input logic [31:0] instr_rdata_i, + + // Data memory interface + output logic data_req_o, + input logic data_gnt_i, + input logic data_rvalid_i, + output logic data_we_o, + output logic [ 3:0] data_be_o, + output logic [31:0] data_addr_o, + output logic [31:0] data_wdata_o, + input logic [31:0] data_rdata_i, + + // Interrupt inputs + input logic [31:0] irq_i, // CLINT interrupts + CLINT extension interrupts + output logic irq_ack_o, + output logic [ 4:0] irq_id_o, + + // Debug Interface + input logic debug_req_i, + output logic debug_havereset_o, + output logic debug_running_o, + output logic debug_halted_o, + + // CPU Control Signals + input logic fetch_enable_i, + output logic core_sleep_o +); + + `ifdef PULP_F0 + parameter COREV_PULP = 1; + parameter FPU = 1; + `elsif PULP + parameter COREV_PULP = 1; + parameter FPU = 0; + `else + parameter COREV_PULP = 0; + parameter FPU = 0; + `endif + + cv32e40p_top #( + .COREV_PULP(COREV_PULP), + .FPU(FPU) + + ) u_cv32e40p_top ( + .* + ); + + +endmodule \ No newline at end of file diff --git a/scripts/formal/src/data_assert.sv b/scripts/formal/src/data_assert.sv new file mode 100644 index 000000000..1b70b660b --- /dev/null +++ b/scripts/formal/src/data_assert.sv @@ -0,0 +1,74 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// Pascal Gouedo, Dolphin Design // +// // +// Description: OBI protocol emulation for CV32E40P data interface // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module data_assert ( + input logic clk_i, + input logic rst_ni, + + // Data memory interface + input logic data_req_o, + input logic data_gnt_i, + input logic data_rvalid_i, + input logic data_we_o, + input logic [ 3:0] data_be_o, + input logic [31:0] data_addr_o, + input logic [31:0] data_wdata_o, + input logic [31:0] data_rdata_i +); + + /***************** + * Helpers logic * + *****************/ + int s_outstanding_cnt; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if(!rst_ni) begin + s_outstanding_cnt <= 0; + end else if (data_req_o & data_gnt_i & data_rvalid_i) begin + s_outstanding_cnt <= s_outstanding_cnt; + end else if (data_req_o & data_gnt_i) begin + s_outstanding_cnt <= s_outstanding_cnt + 1; + end else if (data_rvalid_i) begin + s_outstanding_cnt <= s_outstanding_cnt - 1; + end + end + + /********** + * Assume * + **********/ + // Concerning lint_grnt + property no_grnt_when_no_req; + @(posedge clk_i) disable iff(!rst_ni) + !data_req_o |-> !data_gnt_i; + endproperty + + property no_rvalid_if_no_pending_req; + @(posedge clk_i) disable iff(!rst_ni) + s_outstanding_cnt < 1 |-> !data_rvalid_i; + endproperty + + assume_no_grnt_when_no_req: assume property(no_grnt_when_no_req); + assume_no_rvalid_if_no_pending_req: assume property(no_rvalid_if_no_pending_req); +endmodule diff --git a/scripts/formal/src/debug_assert.sv b/scripts/formal/src/debug_assert.sv new file mode 100644 index 000000000..0c6c6bd8c --- /dev/null +++ b/scripts/formal/src/debug_assert.sv @@ -0,0 +1,46 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Debug interface constraints // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module debug_assert ( + input logic clk_i, + input logic rst_ni, + // Debug Interface + input logic debug_req_i, + input logic debug_havereset_o, + input logic debug_running_o, + input logic debug_halted_o +); + + /********** + * Assume * + **********/ + property no_debug; + @(posedge clk_i) disable iff(!rst_ni) + debug_req_i == '0; + endproperty + + // Uncomment this line to disable debug interface + // assume_no_debug: assume property(no_debug); + +endmodule \ No newline at end of file diff --git a/scripts/formal/src/fpnew_divsqrt_th_32_assert.sv b/scripts/formal/src/fpnew_divsqrt_th_32_assert.sv new file mode 100644 index 000000000..d66e15df6 --- /dev/null +++ b/scripts/formal/src/fpnew_divsqrt_th_32_assert.sv @@ -0,0 +1,42 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Assertion for unreachable code in CV32E40P div sqrt unit // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module fpnew_divsqrt_th_32_assert ( + input logic clk_i, + input logic rst_ni, + + input logic op_starting , + input logic unit_ready_q , + input logic ex2_inst_wb , + input logic ex2_inst_wb_vld_q +); + + property unreachable_divsqrt_th_288; + @(posedge clk_i) disable iff(!rst_ni) + (op_starting && unit_ready_q) |-> !(ex2_inst_wb && ex2_inst_wb_vld_q); + endproperty + + assert_unreachable_divsqrt_th_288: assert property(unreachable_divsqrt_th_288); + +endmodule \ No newline at end of file diff --git a/scripts/formal/src/insn_assert.sv b/scripts/formal/src/insn_assert.sv new file mode 100644 index 000000000..ca3acdc5f --- /dev/null +++ b/scripts/formal/src/insn_assert.sv @@ -0,0 +1,165 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: OBI protocol emulation for CV32E40P instruction interface // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module insn_assert ( + input logic clk_i, + input logic rst_ni, + // Instruction memory interface + input logic instr_req_o, + input logic instr_gnt_i, + input logic instr_rvalid_i, + input logic [31:0] instr_addr_o, + input logic [31:0] instr_rdata_i +); + + import cv32e40p_pkg::*; + import cv32e40p_tracer_pkg::*; + + /***************** + * Helpers logic * + *****************/ + int s_outstanding_cnt; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if(!rst_ni) begin + s_outstanding_cnt <= 0; + end else if (instr_req_o & instr_gnt_i & instr_rvalid_i) begin + s_outstanding_cnt <= s_outstanding_cnt; + end else if (instr_req_o & instr_gnt_i) begin + s_outstanding_cnt <= s_outstanding_cnt + 1; + end else if (instr_rvalid_i) begin + s_outstanding_cnt <= s_outstanding_cnt - 1; + end + end + + logic [31:0] s_prev_insn; + always_ff @(posedge clk_i or negedge rst_ni) begin + if(!rst_ni) begin + s_prev_insn <= '0; + end else if (instr_rvalid_i) begin + s_prev_insn <= instr_rdata_i; + end + end + + /********** + * Assume * + **********/ + // Concerning lint_grnt + property no_grnt_when_no_req; + @(posedge clk_i) disable iff(!rst_ni) + !instr_req_o |-> !instr_gnt_i; + endproperty + + property no_rvalid_if_no_pending_req; + @(posedge clk_i) disable iff(!rst_ni) + s_outstanding_cnt < 1 |-> !instr_rvalid_i; + endproperty + + property no_compressed; + @(posedge clk_i) disable iff(!rst_ni) + instr_rdata_i[1:0] == 2'b11; + endproperty + + property no_jump; + @(posedge clk_i) disable iff(!rst_ni) + (instr_rdata_i[6:0] != OPCODE_JAL) & (instr_rdata_i[6:0] != OPCODE_JALR); + endproperty + + property no_branch; + @(posedge clk_i) disable iff(!rst_ni) + instr_rdata_i[6:0] != OPCODE_BRANCH; + endproperty + + property no_custom0; + @(posedge clk_i) disable iff(!rst_ni) + instr_rdata_i[6:0] != OPCODE_CUSTOM_0; + endproperty + + property cvend0_only_after_cvstart0; + @(posedge clk_i) disable iff(!rst_ni) + (s_prev_insn != INSTR_CVSTARTI0) & (s_prev_insn != INSTR_CVSTARTI0) |-> (instr_rdata_i != INSTR_CVSENDI0) & (instr_rdata_i != INSTR_CVEND0); + endproperty + + property cvcount0_only_after_cvend0; + @(posedge clk_i) disable iff(!rst_ni) + (s_prev_insn != INSTR_CVSENDI0) & (s_prev_insn != INSTR_CVEND0) |-> (instr_rdata_i != INSTR_CVCOUNTI0) & (instr_rdata_i != INSTR_CVCOUNT0); + endproperty + + property no_cvsetup0; + @(posedge clk_i) disable iff(!rst_ni) + (instr_rdata_i != INSTR_CVSETUPI0) & (instr_rdata_i != INSTR_CVSETUP0); + endproperty + + property no_cvstart0; + @(posedge clk_i) disable iff(!rst_ni) + (instr_rdata_i != INSTR_CVSTARTI0) & (instr_rdata_i != INSTR_CVSTART0); + endproperty + + property cvend1_only_after_cvstart1; + @(posedge clk_i) disable iff(!rst_ni) + (s_prev_insn != INSTR_CVSTARTI1) & (s_prev_insn != INSTR_CVSTARTI1) |-> (instr_rdata_i != INSTR_CVSENDI1) & (instr_rdata_i != INSTR_CVEND1); + endproperty + + property cvcount1_only_after_cvend1; + @(posedge clk_i) disable iff(!rst_ni) + (s_prev_insn != INSTR_CVSENDI1) & (s_prev_insn != INSTR_CVEND1) |-> (instr_rdata_i != INSTR_CVCOUNTI1) & (instr_rdata_i != INSTR_CVCOUNT1); + endproperty + + property no_cvsetup1; + @(posedge clk_i) disable iff(!rst_ni) + (instr_rdata_i != INSTR_CVSETUPI1) & (instr_rdata_i != INSTR_CVSETUP1); + endproperty + + property no_cvstart1; + @(posedge clk_i) disable iff(!rst_ni) + (instr_rdata_i != INSTR_CVSTARTI1) & (instr_rdata_i != INSTR_CVSTART1); + endproperty + + property no_csr_write_to_hwloop; + @(posedge clk_i) disable iff(!rst_ni) + instr_rdata_i[6:0] == OPCODE_SYSTEM |-> (instr_rdata_i[31:20] != 12'hCC0) & (instr_rdata_i[31:20] != 12'hCC1) & (instr_rdata_i[31:20] != 12'hCC2) & (instr_rdata_i[31:20] != 12'hCC4) & (instr_rdata_i[31:20] != 12'hCC5) & (instr_rdata_i[31:20] != 12'hCC6); + endproperty + + assume_no_grnt_when_no_req: assume property(no_grnt_when_no_req); + assume_no_rvalid_if_no_pending_req: assume property(no_rvalid_if_no_pending_req); + // assume_no_compressed: assume property(no_compressed); + // assume_no_jump: assume property(no_jump); + // assume_no_branch: assume property(no_branch); + + // assume_no_custom0: assume property(no_custom0); + + //hwloop 0 constraints + // assume_cvend0_only_after_cvstart0: assume property(cvend0_only_after_cvstart0); + // assume_cvcount0_only_after_cvend0: assume property(cvcount0_only_after_cvend0); + // assume_no_cvsetup0: assume property(no_cvsetup0); + // assume_no_cvstart0: assume property(no_cvstart0); //This one disables all hwloop0 + //hwloop 1 constraints + // assume_cvend1_only_after_cvstart1: assume property(cvend1_only_after_cvstart1); + // assume_cvcount1_only_after_cvend1: assume property(cvcount1_only_after_cvend1); + // assume_no_cvsetup1: assume property(no_cvsetup1); + // assume_no_cvstart1: assume property(no_cvstart1); //This one disables all hwloop1 + + assume_no_csr_write_to_hwloop: assume property(no_csr_write_to_hwloop); + +endmodule \ No newline at end of file diff --git a/scripts/formal/src/interrupt_assert.sv b/scripts/formal/src/interrupt_assert.sv new file mode 100644 index 000000000..0f0e67492 --- /dev/null +++ b/scripts/formal/src/interrupt_assert.sv @@ -0,0 +1,46 @@ +// Copyright 2024 Dolphin Design +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); +// you may not use this file except in compliance with the License, or, +// at your option, the Apache License version 2.0. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//////////////////////////////////////////////////////////////////////////////////// +// // +// Contributors: Yoann Pruvost, Dolphin Design // +// // +// Description: Debug interface constraints // +// // +//////////////////////////////////////////////////////////////////////////////////// + +module interrput_assert ( + input logic clk_i, + input logic rst_ni, + // Interrupt inputs + input logic [31:0] irq_i, + input logic irq_ack_o, + input logic [ 4:0] irq_id_o +); + + /********** + * Assume * + **********/ + property no_interrupt; + @(posedge clk_i) disable iff(!rst_ni) + irq_i == '0; + endproperty + + // Uncomment to disable interrupt interface + // assume_no_interrupt: assume property(no_interrupt); + + +endmodule \ No newline at end of file From 1dbddd882e33df3012f80f56a215e74a3a5adbee Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 3 Jun 2024 16:58:22 +0200 Subject: [PATCH 66/69] Table update for markdown rendering Signed-off-by: Pascal Gouedo --- scripts/riscv_isa_formal/README.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/scripts/riscv_isa_formal/README.md b/scripts/riscv_isa_formal/README.md index 3786eebef..b9cc77557 100755 --- a/scripts/riscv_isa_formal/README.md +++ b/scripts/riscv_isa_formal/README.md @@ -4,23 +4,14 @@ RISC-V ISA Formal Verification methodology has been used with Siemens EDA Onespi ## Configurations - +--------------------+-----------------------------------------------------------------------------+ - | | **Verified Configurations** | - +====================+========+==========+==========+==========+===========+===========+===========+ | **Top Parameters** | **XP** | **XPF0** | **XPF1** | **XPF2** | **XPZF0** | **XPZF1** | **XPZF2** | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ + |--------------------|-----------------------------------------------------------------------------| | COREV_PULP | 1 | 1 | 1 | 1 | 1 | 1 | 1 | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ | COREV_CLUSTER | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ | FPU | 0 | 1 | 1 | 1 | 1 | 1 | 1 | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ | ZFINX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ | FPU_ADDMUL_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ | FPU_OTHERS_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | - +--------------------+--------+----------+----------+----------+-----------+-----------+-----------+ ## Tool apps From cf658a074f67b566fdd1038c7cf4658a44ce08f6 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 3 Jun 2024 17:03:37 +0200 Subject: [PATCH 67/69] Table rendering Signed-off-by: Pascal Gouedo --- scripts/riscv_isa_formal/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/riscv_isa_formal/README.md b/scripts/riscv_isa_formal/README.md index b9cc77557..5fa41a7aa 100755 --- a/scripts/riscv_isa_formal/README.md +++ b/scripts/riscv_isa_formal/README.md @@ -4,8 +4,8 @@ RISC-V ISA Formal Verification methodology has been used with Siemens EDA Onespi ## Configurations - | **Top Parameters** | **XP** | **XPF0** | **XPF1** | **XPF2** | **XPZF0** | **XPZF1** | **XPZF2** | - |--------------------|-----------------------------------------------------------------------------| + | Top Parameters | XP | XPF0 | XPF1 | XPF2 | XPZF0 | XPZF1 | XPZF2 | + | :----------------- | :----: |:-------: | :------: | :------: | :-------: | :-------: | :-------: | | COREV_PULP | 1 | 1 | 1 | 1 | 1 | 1 | 1 | | COREV_CLUSTER | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | FPU | 0 | 1 | 1 | 1 | 1 | 1 | 1 | From 86c0ed676b3ea631ce4b973e1a79996a07eaa8c7 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 3 Jun 2024 17:05:49 +0200 Subject: [PATCH 68/69] Cleanup Signed-off-by: Pascal Gouedo --- scripts/riscv_isa_formal/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/riscv_isa_formal/README.md b/scripts/riscv_isa_formal/README.md index 5fa41a7aa..3cb124dce 100755 --- a/scripts/riscv_isa_formal/README.md +++ b/scripts/riscv_isa_formal/README.md @@ -36,7 +36,8 @@ Contains all files to create assertions and to launch different tool apps on dif ## How to launch a run - Locally clone cv32e40p github repository or make a symbolic link to an existing repo. -- launch following command: make GUI=1 APP=PRC CONF=XP MODE=DEF NAME=v1_8_0 VERBOSE=1 PREPARE=1 all >&! run_gui-PRC-cfg_XP-mode_DEF-v1_8_0.log & +- launch following command: + make GUI=1 APP=PRC CONF=XP MODE=DEF NAME=v1_8_0 VERBOSE=1 PREPARE=1 all >&! run_gui-PRC-cfg_XP-mode_DEF-v1_8_0.log & - or use launch_command_example to launch different runs in parallel. ## Commands to launch for each configuration From 0a9df7266b205be743a67354ba671317dfc1ce93 Mon Sep 17 00:00:00 2001 From: Pascal Gouedo Date: Mon, 3 Jun 2024 17:32:19 +0200 Subject: [PATCH 69/69] Reverted PR #993. --- scripts/riscv_isa_formal/Makefile | 59 - scripts/riscv_isa_formal/README.md | 47 - .../riscv_isa_formal/common/basics.tcl.obf | 2 - .../riscv_isa_formal/common/constraints.sv | 119 -- .../riscv_isa_formal/common/core_checker.sv | 1108 ----------------- scripts/riscv_isa_formal/common/io.sv | 72 -- .../riscv_isa_formal/common/other_bindings.sv | 72 -- scripts/riscv_isa_formal/common/setup.tcl | 564 --------- scripts/riscv_isa_formal/common/setup_mv.tcl | 8 - scripts/riscv_isa_formal/common/t.sh | 12 - .../riscv_isa_formal/common/vips/obi_dmem.sv | 60 - .../riscv_isa_formal/common/vips/obi_imem.sv | 59 - .../riscv_isa_formal/launch_command example | 58 - 13 files changed, 2240 deletions(-) delete mode 100755 scripts/riscv_isa_formal/Makefile delete mode 100755 scripts/riscv_isa_formal/README.md delete mode 100755 scripts/riscv_isa_formal/common/basics.tcl.obf delete mode 100755 scripts/riscv_isa_formal/common/constraints.sv delete mode 100755 scripts/riscv_isa_formal/common/core_checker.sv delete mode 100755 scripts/riscv_isa_formal/common/io.sv delete mode 100755 scripts/riscv_isa_formal/common/other_bindings.sv delete mode 100755 scripts/riscv_isa_formal/common/setup.tcl delete mode 100755 scripts/riscv_isa_formal/common/setup_mv.tcl delete mode 100755 scripts/riscv_isa_formal/common/t.sh delete mode 100755 scripts/riscv_isa_formal/common/vips/obi_dmem.sv delete mode 100755 scripts/riscv_isa_formal/common/vips/obi_imem.sv delete mode 100755 scripts/riscv_isa_formal/launch_command example diff --git a/scripts/riscv_isa_formal/Makefile b/scripts/riscv_isa_formal/Makefile deleted file mode 100755 index f344b819b..000000000 --- a/scripts/riscv_isa_formal/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -commonPath=../../common -PREPARE?=0 -RTL?=../../cv32e40p/ -GUI?=0 -NAME?=noname - -ifeq ($(APP),) - $(error APP is empty) -endif -ifeq ($(CONF),) - $(error CONF is empty) -endif -ifeq ($(MODE),) - $(error MODE is empty) -endif - -$(info APP=$(APP)) -$(info CONF=$(CONF)) -$(info MODE=$(MODE)) - -ifeq ($(GUI), 1) - flag="-i" -else - flag= -endif - -dirname=$(NAME) - -ifeq ($(PREPARE), 1) - script_name=ones_prepare_run -else - script_name=ones_run -endif - -define ones_prepare_run - @echo "====================================================" - @echo "Preparing working area $(dirname)" - @echo "====================================================" - \mkdir -p cfgs/$(dirname)/logs - \cd cfgs/$(dirname) && \cp -pf $(commonPath)/{other_bindings.sv,core_checker.sv,io.sv,setup.tcl,setup_mv.tcl,*.json,constraints.sv,t.sh,basics.tcl.obf} . && \cp -prfL $(commonPath)/vips . && \cp -prfL $(RTL) . - @echo "====================================================" - @echo "Running mode $(MODE) on configuration $(CONF) in $(dirname)" - @echo "====================================================" - \cd cfgs/$(dirname) && onespin -Q -l logs/$(APP)-cfg_$(CONF)-mode_$(MODE).log $(flag) setup.tcl $(CONF) $(MODE) $(APP) -endef - -define ones_run - @echo "====================================================" - @echo "Running mode $(MODE) on configuration $(CONF) in $(dirname)" - @echo "====================================================" - \cd cfgs/$(dirname) && onespin -Q -l logs/$(APP)-cfg_$(CONF)-mode_$(MODE).log $(flag) setup.tcl $(CONF) $(MODE) $(APP) -endef - -all: - $(call $(script_name)) - -clean: - rm -rf cfgs/$(dirname) - diff --git a/scripts/riscv_isa_formal/README.md b/scripts/riscv_isa_formal/README.md deleted file mode 100755 index 3cb124dce..000000000 --- a/scripts/riscv_isa_formal/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# RISC-V ISA Formal Verification - -RISC-V ISA Formal Verification methodology has been used with Siemens EDA Onespin tool and its RISC-V ISA Processor Verification app. - -## Configurations - - | Top Parameters | XP | XPF0 | XPF1 | XPF2 | XPZF0 | XPZF1 | XPZF2 | - | :----------------- | :----: |:-------: | :------: | :------: | :-------: | :-------: | :-------: | - | COREV_PULP | 1 | 1 | 1 | 1 | 1 | 1 | 1 | - | COREV_CLUSTER | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - | FPU | 0 | 1 | 1 | 1 | 1 | 1 | 1 | - | ZFINX | 0 | 0 | 0 | 0 | 1 | 1 | 1 | - | FPU_ADDMUL_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | - | FPU_OTHERS_LAT | 0 | 0 | 1 | 2 | 0 | 1 | 2 | - -## Tool apps - -- PRC : Property Checking -- QTF : Quantify -- VCI : Verification Coverage Integration - -## Prove modes - -- DEF : Control path verification of all instructions and datapath verification of all instructions except multiplication, division or floating point ones -- DPM : Data path verification of multiplication/ division instructions -- DPF : Data path verification of floating-point instructions - -## Directory Structure of this Repo - -- Makefile -- launch_command_example - -### common -Contains all files to create assertions and to launch different tool apps on different configurations and using different modes. - -## How to launch a run - -- Locally clone cv32e40p github repository or make a symbolic link to an existing repo. -- launch following command: - make GUI=1 APP=PRC CONF=XP MODE=DEF NAME=v1_8_0 VERBOSE=1 PREPARE=1 all >&! run_gui-PRC-cfg_XP-mode_DEF-v1_8_0.log & -- or use launch_command_example to launch different runs in parallel. - -## Commands to launch for each configuration - -- XP : PRC app with DEF and DPM modes -- XPF[0,1,2] and XPZF[0,1,2] : PRC app with DEF, DPM and DPF modes - diff --git a/scripts/riscv_isa_formal/common/basics.tcl.obf b/scripts/riscv_isa_formal/common/basics.tcl.obf deleted file mode 100755 index b97ac2b1e..000000000 --- a/scripts/riscv_isa_formal/common/basics.tcl.obf +++ /dev/null @@ -1,2 +0,0 @@ -OneSpin obfuscated tcl file v1.2 -{"crypted_data_base64":"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","crypted_key_base64":"ae4swfzavOkxqDsJudKbX9pzOUkmtH3lghKeUgBvRwMQ/v/ohDNTomF29+UP/D6xla54T0a5\r\ncO//7aAvERGzzXcMK5Lhs20jZ9PPJz5RfppXjpquoW8adKhcEsUttU/J/k5dZxldwqtoLocp\r\nOQmJOzSoJ1nTQhaDmnQ99UvI6rej5wXUXerN6jcAyJYAfVacZMtzyVf5WZY8MANcZ+cTuJ40\r\nT6aFkpIO+s4epEyjAPPRY3aqvRqtRZd6iJRwtAYxGTyAz9Xc8yDxgvdJG7z5nfmJZ57ZUDCS\r\nqIL/WTIjg/9q9T2fxAUsnA0vBEaSQ1tZYTcelgzRQTgsVXuPcl6CkA==","crypted_sign_version_base64":"KL+4hMqJXz+2qrBnOcBWqQQhV9A4FAyyoIxcvRMJbhqDZVuNlrI6eN4y0+pWeBowxW91avwn\r\nCxpUnfO2fJpnUSDiMaEbfz5kCFuBxEMK1HYk8A6SQe+62B3Sb3ArmOTrfnZbTTVuNYFveKIC\r\n7k1PcwrD3z7NxiwyDEOuhVh3/+rD2PFrxtHtzu0Mars00hW/NZCAI6N1kC87lFgzMRwWpVCU\r\n19WIag8AEyzAy6g9WnL/sLVlj8CxiJh1C6uLPxHa6L4e/8GSu92fZgwO0363P/8Pf5fR+8O/\r\nSUxSEiMJdq6+05Pq8UtHLSTkBvgjXlVKD9DXV+USkL5twuwNUHMxKw==","crypted_signature_base64":"OGcBm7GN/6ibKuLWSdXzp2uBayu3UKZPDSMYDKOrPfJe8J/QPP3YiS0fWlAKgIp7LDsMZeiu\r\n+d0m8R2Y8jfff+sxMsApauBQ1e453cwbcZeN8BFyBoxYzkXF/NTYzFTe+U2nWuxHT9E8m572\r\nipH+Y38KVQ0UOAkPE2oZHxn9C3cnJ5VGKAwRK+PYxVyTkc0c7/EIbcE5VEObwUiGD8AJWWpF\r\n2TgDFi+AtCqoAlsGWjr+cN0w5NoaNXOav7LMQJNq20JGxN83fbywGEgjBHvr+3OBtp/7QNuZ\r\n20Lnyqer83j3uEGwUCQJ1fAiG5H3F/p3DHiQhvz2L+LTTvdS/j5tYg==","key_name":"onespin_002","key_vendor":"OneSpin","method":"aes-256-cbc"} \ No newline at end of file diff --git a/scripts/riscv_isa_formal/common/constraints.sv b/scripts/riscv_isa_formal/common/constraints.sv deleted file mode 100755 index 02bf694d0..000000000 --- a/scripts/riscv_isa_formal/common/constraints.sv +++ /dev/null @@ -1,119 +0,0 @@ -/*********************/ -// CONSTRAINTS -/*********************/ - -// MAIN CONSTRAINTS // - -const_addrs_c : assume property (##1 $stable({boot_addr,`core.dm_halt_addr_i,`core.dm_exception_addr_i,`core.mtvec_addr_i,`core.hart_id_i})); -const_dm_addr_c : assume property (`core.dm_halt_addr_i==32'h800 && `core.dm_exception_addr_i==32'h808); // **I** To meet app expectations - -`ifdef CFG_XP -`ifdef CV_LOOP - // raising of hwloop illegal currently not modeled - no_hwloop_illegal_c : assume property (!id_stage_i.controller_i.is_hwlp_illegal); - - // hwloop must contain 3+ instructions - hwloop_min_size_c : assume property (!(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]>0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[0]-id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0] inside {32'h0,32'h4,32'h8}) && !(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]>0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]-id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1] inside {32'h0,32'h4,32'h8})); - - // hwloop must be word-aligned - hwloop_aligned_c : assume property (id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0][1:0]==0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[0][1:0]==0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1][1:0]==0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1][1:0]==0); - - // we must not create loop 0 in the middle of itself (setting count to non-zero at a PC location that would qualify as inside the loop). Also, setting up the registers and then jumping to a location inside loop 0 will likely not work - loop0_setup_c : assume property (id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]==0 ##1 id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]!=0 |-> id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0]==$past(pc_id)+32'd4); - - // we must not create loop 1 in the middle of itself (setting count to non-zero at a PC location that would qualify as inside the loop). Also, setting up the registers and then jumping to a location inside loop 1 will likely not work - loop1_setup_c : assume property (id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]==0 ##1 id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]!=0 |-> id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1]==$past(pc_id)+32'd4); - - // let's not wrap - lopp_no_wrap_c : assume property (!(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]>0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[0]0&&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]0 && pc_id>=id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[0] && pc_id0 && pc_id>=id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_start_q[1] && pc_id0 && id_stage_i.hwlp_regid==1 && id_stage_i.hwlp_we)); - - // end addresses 8 apart - loop_end_min_sitance_c : assume property (!(id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[0]>0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_counter_q[1]>0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]0 && id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_we_i[1] && !id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_regid_i &&id_stage_i.gen_hwloop_regs.hwloop_regs_i.hwlp_end_q[1]0|->`core.data_rvalid_i); -`else - no_hwloop_c : assume property (!id_stage_i.controller_i.is_hwlp_body); -`endif -`endif - -`ifdef CFG_XC - clk_en_c: assume property (`core.pulp_clock_en_i); -`endif - -// MEMORY INTERFACE CONSTRAINTS // - -// -// The following set of constraints could be used to constrain memory interfaces in case bus protocols implemented are not tool supported. -// **W** Use only in case bus protocols implemented are not tool supported -// - -`ifdef CUSTOM_MEM_INTERFACES - `include "mem_constraints.sv" - localparam MAX_WAIT=DMEM_MAX_WAIT; -`else - localparam MAX_WAIT=obi_dmem_checker.MAX_WAIT; -`endif - -// PERFORMANCE ENHANCEMENT CONSTRAINTS // - -// -// The following set of constraints could be used to enhance properties' runtime. -// **W** If ever used, these constraints have to be removed totally afterwards to achieve full verification. -// - -// -// "restrict_regs" restricts instruction source and destination indices to a subset of registers. -// By default, the following register indices are chosen: 0 to 3, and 8 to 9 in presence of compressed extensions. -// -function automatic restrict_regs(input dec_t dec); - restrict_regs=1'b1; - foreach (dec.RS[i]) - if (dec.RS[i].valid) -// restrict_regs&=dec.RS[i].idx<4 || (MISA.C|Zca) && dec.RS[i].idx inside {5'd8,5'd9}; - restrict_regs&=dec.RS[i].idx inside {5'd0, 5'd1, 5'd2, 5'd4, 5'd8, 5'd12, 5'd16}; - foreach (dec.RD[i]) - if (dec.RD[i].valid) -// restrict_regs&=dec.RD[i].idx<4 || (MISA.C|Zca) && dec.RD[i].idx inside {5'd8,5'd9}; - restrict_regs&=dec.RD[i].idx inside {5'd0, 5'd1, 5'd2, 5'd4, 5'd8, 5'd12, 5'd16}; -endfunction - -`ifdef RESTRICT_REGS - // Restrict instruction decoding & register file verification to a subset of registers - restrict_regs_c: assume property (disable iff (~rst_n) - restrict_regs(execute.dec) - `ifndef COMPLETENESS - `ifndef RESTRICT_REGISTER_INDEX -// && (reg_idx<4 || (MISA.C|Zca) && reg_idx inside {5'd8,5'd9}) - && (reg_idx inside {5'd0, 5'd1, 5'd2, 5'd4, 5'd8, 5'd12, 5'd16}) - `endif - `endif - ); -`endif - -// GRADUAL VERIFICATION CONSTRAINTS // - -// -// The following set of constraints could be used for a gradual setup of a new core. -// **W** If ever used, these constraints have to be removed totally afterwards to achieve full verification. -// - -`ifdef LIMIT_TOTAL_INSTR_COUNT - // Limit total number of instructions allowed in the pipeline - limit_total_instr_count_c : assume property (disable iff (~rst_n) full[0] -> id_instr_cnt<`LIMIT_TOTAL_INSTR_COUNT); -`endif diff --git a/scripts/riscv_isa_formal/common/core_checker.sv b/scripts/riscv_isa_formal/common/core_checker.sv deleted file mode 100755 index 4cbd14507..000000000 --- a/scripts/riscv_isa_formal/common/core_checker.sv +++ /dev/null @@ -1,1108 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// // -// RISC-V Checker // -// // -// This material contains trade secrets or otherwise confidential // -// information owned by Siemens Industry Software Inc. or its affiliates // -// (collectively, "SISW"), or its licensors. Access to and use of this // -// information is strictly limited as set forth in the Customer's applicable // -// agreements with SISW. // -// // -// This material may not be copied, distributed, or otherwise disclosed // -// outside of the Customer's facilities without the express written // -// permission of SISW, and may not be used in any way not expressly // -// authorized by SISW. // -// // -/////////////////////////////////////////////////////////////////////////////// - -`include "tidal.sv" -`include "RISCV_ISA.sv" -import RISCV_ISA::*; - -/*********************/ -// DEBUG GROUPS -/*********************/ - -(* ONESPIN_APP = "Processor" *) -(* ONESPIN_VIP_NAME = "RISC-V" *) -(* ONESPIN_VIP_TYPE = "cpu" *) -(* ONESPIN_VIP_TRANSACTION= "instr" *) -(* ONESPIN_VIP_GROUP_1 = "{{IF} if_valid}" *) -(* ONESPIN_VIP_GROUP_1_X = "/instr_addr_o /instr_req_o /instr_gnt_i /instr_rvalid_i /instr_rdata_i /pc_if /if_stage_i.fetch_valid /if_stage_i.fetch_rdata /if_stage_i.fetch_ready /if_stage_i.instr_valid /if_stage_i.instr_aligned /if_stage_i.if_ready /halt_if " *) -(* ONESPIN_VIP_GROUP_2 = "{{ID} id_valid}" *) -(* ONESPIN_VIP_GROUP_2_X = "/pc_id /instr_valid_id /instr_rdata_id /is_compressed_id /is_fetch_failed_id /clear_instr_valid /id_stage_i.controller_i.ctrl_fsm_cs /id_stage_i.controller_i.ctrl_fsm_ns /id_stage_i.misaligned_stall /id_stage_i.jr_stall /id_stage_i.load_stall /id_stage_i.apu_stall /id_stage_i.csr_apu_stall /id_stage_i.branch_taken_ex /id_ready /id_stage_i.halt_id" *) -(* ONESPIN_VIP_GROUP_3 = "{{EX} ex_valid}" *) -(* ONESPIN_VIP_GROUP_3_X = "/pc_ex /alu_en_ex /id_stage_i.decoder_i.alu_operator_o /alu_operand_a_ex /alu_operand_b_ex /ex_stage_i.alu_result /ex_stage_i.alu_ready /ex_stage_i.mult_ready mul_op_a mul_op_b mul_op_c mul_result /ex_stage_i.alu_i.div_valid div_result_valid /ex_stage_i.alu_i.result_div div_op_a div_op_b div_result_valid div_result /lsu_ready_ex /ex_ready" *) -(* ONESPIN_VIP_GROUP_4 = "{{MEM} mem_valid}" *) -(* ONESPIN_VIP_GROUP_4_X = "/data_we_o /data_addr_o /data_req_o /data_be_o /data_sign_ext_ex /data_type_ex /data_wdata_o /data_gnt_i /data_rvalid_i /data_rdata_i /lsu_rdata rf_we_lsu rf_waddr_lsu lsu_data_type lsu_data_sign lsu_data_offset" *) -(* ONESPIN_VIP_GROUP_5 = "{{WB} wb_valid}" *) -(* ONESPIN_VIP_GROUP_5_X = "/id_stage_i.register_file_i.we_b_i /id_stage_i.register_file_i.waddr_b_i /id_stage_i.register_file_i.wdata_b_i /id_stage_i.register_file_i.we_b_dec /id_stage_i.register_file_i.we_a_i /id_stage_i.register_file_i.waddr_a_i /id_stage_i.register_file_i.wdata_a_i /id_stage_i.register_file_i.we_a_dec /id_stage_i.register_file_i.mem /lsu_ready_wb /ex_stage_i.wb_ready_i" *) -(* ONESPIN_VIP_GROUP_6 = "CSRs" *) -(* ONESPIN_VIP_GROUP_6_X = "/csr_access_ex /csr_op /csr_addr /csr_wdata /csr_rdata /csr_cause /cs_registers_i.mepc_q /cs_registers_i.mcause_q /cs_registers_i.mstatus_q /cs_registers_i.mie_q /cs_registers_i.mtvec_q /cs_registers_i.fflags_q /cs_registers_i.frm_q" *) -(* ONESPIN_VIP_GROUP_7 = "XCPTs" *) -(* ONESPIN_VIP_GROUP_7_X = "/current_priv_lvl /pc_set /exc_cause /cs_registers_i.exception_pc /if_stage_i.exc_pc /if_stage_i.fetch_failed /instr_err_pmp /data_err_pmp /data_err_ack /id_stage_i.illegal_insn_dec /illegal_c_insn_id /id_stage_i.fencei_insn_dec /id_stage_i.ebrk_insn_dec /id_stage_i.ecall_insn_dec /id_stage_i.mret_insn_dec /id_stage_i.uret_insn_dec /id_stage_i.dret_insn_dec" *) -(* ONESPIN_VIP_GROUP_8 = "INTRs" *) -(* ONESPIN_VIP_GROUP_8_X = "/irq_i /irq_id_o /irq_ack_o" *) -(* ONESPIN_VIP_GROUP_9 = "DBG" *) -(* ONESPIN_VIP_GROUP_9_X = "/debug_mode /debug_req_i /debug_cause /debug_ebreakm /debug_ebreaku /debug_single_step /debug_csr_save /cs_registers_i.dcsr_q /cs_registers_i.depc_q" *) -(* ONESPIN_VIP_GROUP_A = "FPU" *) -(* ONESPIN_VIP_GROUP_A_X = "fpu_op_valid fpu_op_a fpu_op_b fpu_op_c fpu_op_ex fpu_lat_ex fpu_waddr_ex fpu_result_valid fpu_s_cycle fpu_m_cycle ex_stage_i.gen_apu.apu_disp_i.apu_lat fpu_waddr fpu_result fpu_flags" *) - -/*********************/ -// VIP's MODULE -/*********************/ - -module RISCV_checker #( - localparam logic[5:0] ALENX=ALEN ~(fpu_waddr_ex==fpu_waddr && (MISA.F|Zfinx -> fpu_lat_ex==ex_stage_i.gen_apu.apu_disp_i.apu_lat)))) - if (fpu_waddr[5]) - sboard_FR[fpu_waddr[4:0]] <= 1'b0; - else - sboard_XR[fpu_waddr[4:0]] <= 1'b0; - end - -/*********************/ -// DEBUG SIGNALS -/*********************/ - -(* OSS_TCL_VALUE_PRINTER = "PVE_disass" *) logic[32:0] instr; -assign instr = $past({full[0],iword_id}); - -wire if_valid = if_stage_i.if_valid; -wire id_valid = `core.id_valid; -wire ex_valid = `core.ex_valid; -wire mem_valid = `core.data_req_o; -wire wb_valid = `core.wb_valid; - -/*********************/ -// ARCHITECTURE STATE -/*********************/ - -Arch_state_t Arch; -always_comb begin - foreach (Arch.X[i]) - if (i==0) - Arch.X[i] <= '{valid: 1'b1, data: '0}; - else - Arch.X[i] <= '{valid: ~((rf_we_lsu&rf_waddr_lsu==i)|sboard_XR[i]), data: pipe_XR[i]}; - if (MISA.F && ~Zfinx) - foreach (Arch.F[i]) - Arch.F[i] <= '{valid: ~((rf_we_lsu&rf_waddr_lsu==(i+6'd32))|sboard_FR[i]), data: pipe_FR[i]}; - - Arch.CSR <= CSR; -`ifdef CFG_XP - Arch.CSR.lpstart <= $past(CSR.lpstart); - Arch.CSR.lpend <= $past(CSR.lpend); - Arch.CSR.lpcount <= $past(CSR.lpcount); -`endif - Arch.PC <= $past(full[0]?pc_id:pc_if); -end - -/*********************/ -// MODEL -/*********************/ - -prio_interrupt_t prio_interrupt; -assign prio_interrupt = prioritize_interrupt($past(interrupt_in,WB_OFFSET),Arch.CSR); - -execute_t execute; -assign execute = ISA_exe($past(iword_id), - $past(is_sstep,WB_OFFSET), - prio_interrupt, - '{Fetch_Access_Fault:{xcpt_af_instr_2nd,xcpt_af_instr_1st}, - BreakpointF: xcpt_bp_if, - BreakpointL: xcpt_bp_ld, - BreakpointS: xcpt_bp_samo, - DBGBreakpointF: $past(Arch.CSR.tdata1[0].typ==2 && Arch.CSR.tdata1[0].execute,WB_OFFSET) && Arch.PC==CSR.tdata2[0] && $past(~Arch.CSR.curDebug,WB_OFFSET), - DBGBreakpointL: xcpt_dbg_bp_ld, - DBGBreakpointS: xcpt_dbg_bp_samo, - Load_Addr_Align: xcpt_ma_ld, - Load_Access_Fault: {xcpt_af_ld_2nd,xcpt_af_ld_1st}, - SAMO_Addr_Align: xcpt_ma_samo, - SAMO_Access_Fault: {xcpt_af_samo_2nd,xcpt_af_samo_1st}, - Fetch_Page_Fault: {xcpt_pf_instr_2nd,xcpt_pf_instr_1st}, - Load_Page_Fault: {xcpt_pf_ld_2nd,xcpt_pf_ld_1st}, - SAMO_Page_Fault: {xcpt_pf_samo_2nd,xcpt_pf_samo_1st}}, - Arch); - -/*********************/ -// FUNCTIONS -/*********************/ - -function automatic [1:NUM_RS][1:0] compose_selection(logic[1:0] op_a_sl='0, logic[1:0] op_b_sl='0, logic[1:0] op_c_sl='0); - compose_selection = '{1: op_a_sl, 2: op_b_sl, default: op_c_sl}; -endfunction - -function automatic CSR_struct_t CSR_hw_update(input CSR_struct_t cur_CSR, input CSR_struct_t next_CSR, input logic is_retired=1'b0, input fflags_t fflags='{default:'0}); -`ifdef SKIP_CSR_CHECK - CSR_hw_update=next_CSR; -`else - CSR_hw_update=skip_CSR_update(cur_CSR,next_CSR); - if (MISA.F|Zfinx) begin - CSR_hw_update.fflags=next_CSR.fflags; // **I** Skip checking fflags updates - if (MISA.F) - CSR_hw_update.mstatus.FS=next_CSR.mstatus.FS; // **I** Skip checking mstatus.FS updates - end - if (NUM_COUNTERS>0) - CSR_hw_update.mcycle=next_CSR.mcycle; - if (NUM_COUNTERS>2 && is_retired) - CSR_hw_update.minstret={CSR_hw_update.minstret+64'h1}[63:0]; - if (NUM_COUNTERS>3) - CSR_hw_update.mhpmcounter=next_CSR.mhpmcounter; -`ifdef CFG_XP - CSR_hw_update.lpcount=next_CSR.lpcount; // **I** Skip checking lpcount updates -`endif -`endif -endfunction - -function automatic pc_check(input logic[XLEN-1:0] expected_pc); - pc_check=1'b1; -`ifndef SKIP_PC_CHECK - pc_check&=expected_pc==Arch.PC; -`endif -endfunction - -function automatic op_check(input execute_t exe, input op_t rtl_op='0, input [1:NUM_RS][1:0] sl='0); - op_check=1'b1; -`ifndef SKIP_RF_CHECK - foreach (rtl_op[i]) - op_check&=(exe.dec.RS[i].valid -> expected_op_data(exe.op[i][XLEN-1:0],sl[i])==rtl_op[i]); -`endif -endfunction - -function logic[1:0] data_size_enc(input logic[1:0] data_size); - case(data_size) - ms_byte: data_size_enc = ms_word; - ms_half: data_size_enc = ms_half; - ms_word: data_size_enc = ms_byte; - default: data_size_enc = ms_double; - endcase -endfunction - -function reg_t expected_op_data(input reg_t op, input logic[1:0] sl='0); - case(sl) - 2'h0: expected_op_data = op; - 2'h1: expected_op_data = {op[XLEN/2-1:0],op[XLEN/2-1:0]}; - 2'h2: expected_op_data = {op[XLEN/4-1:0],op[XLEN/4-1:0],op[XLEN/4-1:0],op[XLEN/4-1:0]}; - 2'h3: expected_op_data = op< check_wdata(exe.mem,dmem_req_data)); -`endif -endsequence - -sequence pipe_dmem_2nd_req(t_req, execute_t exe); -`ifdef SKIP_DMEM_CHECK - t##0 1'b1; -`else - t_req##0 dmem_req_valid==exe.mem.valid and - t_req##0 dmem_req_addr=={encVA({exe.mem.addr[XLEN-1:2],2'b00})+32'd4}[ALENX-1:0] and - t_req##0 dmem_req_we==(exe.mem.cmd inside {mc_store,mc_sc}) and - t_req##0 dmem_req_be==exe.mem.byte_enable[7:4] and - t_req##0 (exe.mem.cmd inside {mc_store,mc_sc} -> check_wdata(exe.mem,dmem_req_data,1'b1)); -`endif -endsequence - -sequence pipe_reset(t_wb, Arch_state_t cur_Arch=Arch); - t_wb##0 all_regs_valid(cur_Arch) && cur_Arch.X[0].data=='0 and - t_wb##0 no_rf_update($past(cur_Arch),cur_Arch) and - t_wb##0 RISCV_CSR_reset_state(cur_Arch.CSR) and - t_wb##0 CSR_hw_update($past(cur_Arch.CSR),cur_Arch.CSR)==cur_Arch.CSR and - t_wb##0 pc_check(boot_addr); -endsequence - -sequence pipe_bubble(t_wb, Arch_state_t cur_Arch, Arch_state_t next_Arch=Arch); - t_wb##1 no_rf_update(cur_Arch,next_Arch) and - t_wb##1 CSR_hw_update(cur_Arch.CSR,next_Arch.CSR)==next_Arch.CSR and - t_wb##1 pc_check(cur_Arch.PC); -endsequence - -sequence pipe_ret(t_wb, Arch_state_t cur_Arch, execute_t exe, Arch_state_t next_Arch=Arch); - t_wb##1 no_rf_update(cur_Arch,next_Arch) and - t_wb##1 CSR_hw_update(exe.next_CSR,next_Arch.CSR,~exe.csr.count_inhibit.IR)==next_Arch.CSR and - t_wb##1 pc_check(exe.next_pc.ret_PC); -endsequence - -sequence pipe_xcpt(t_wb, Arch_state_t cur_Arch, xcpt_t xcpt, Arch_state_t next_Arch=Arch); - t_wb##1 no_rf_update(cur_Arch,next_Arch) and - t_wb##1 CSR_hw_update(CSR_xcpt_update(cur_Arch.CSR,xcpt),next_Arch.CSR)==next_Arch.CSR and - t_wb##1 pc_check(CSR_xcpt_pc(cur_Arch.CSR,xcpt)); -endsequence - -sequence pipe_instr(t_wb, Arch_state_t cur_Arch, execute_t exe, result_t result='0, logic[1:NUM_RD] check_result='1, Arch_state_t next_Arch=Arch); - t_wb##1 (~exe.mem.valid & ~exe.fpu.valid) -> no_pending_results_used(exe.dec,cur_Arch) and // **I** don't check registers validity for memory or FPU instructions - t_wb##1 pipe_rf_check(exe.dec.RD,result,cur_Arch,check_result,next_Arch) and - t_wb##1 CSR_hw_update(CSR_instr_update(exe.csr,exe.next_CSR,CSR),next_Arch.CSR,~exe.csr.count_inhibit.IR,result.flags)==next_Arch.CSR and - t_wb##1 pc_check(exe.next_pc.PC); -endsequence - -sequence pipe_result(t_ex, execute_t exe, result_t result='0, logic[XLEN-1:0] rtl_result='0); - t_ex##0 ~((exe.dec.RD[1].idx==0) & (exe.fpu.valid -> Zfinx)) -> result.data[1]==rtl_result and - t_ex##0 (exe.fpu.valid & exe.fpu.flags_update) -> result.flags==fpu_flags; -endsequence - -sequence pipe_operands(t_ex, execute_t exe, op_t rtl_op='0, logic[1:NUM_RS][1:0] select_op_data='0); - t_ex##0 op_check(exe,rtl_op,select_op_data) and - t_ex##0 exe.fpu.valid -> exe.fpu.frm==fpu_rm; -endsequence - -property pipe_env(t_wb, logic env_cond='1, logic[PIPE_STAGES-1:0] prevent_stage_flush='0, logic[PIPE_STAGES-1:0] prevent_stage_stall='0); - t_id##0 (prevent_stage_flush[0] -> ~flush[0]) && (prevent_stage_stall[0] -> ~stall[0]) and - t_wb##0 (prevent_stage_flush[1] -> ~flush[1]) && (prevent_stage_stall[1] -> ~stall[1]) and - during(t_id,t_wb,env_cond); -endproperty - -/*********************/ -// CONCEPTUAL STATE -/*********************/ - -sequence Ready2Execute; - ~stall[1] && ~id_stage_i.misaligned_stall && id_stage_i.controller_i.ctrl_fsm_cs inside {DECODE,DECODE_HWLOOP} && ~id_stage_i.branch_taken_ex -`ifndef SKIP_PC_CHECK - && (id_stage_i.controller_i.jump_done_q -> (full[0] & id_stage_i.controller_i.jump_in_dec & (id_stage_i.controller_i.pc_mux_o==PC_JUMP) & ~$past(fpu_result_valid) & (~fpu_m_cycle) -> (~id_stage_i.controller_i.jr_stall_o & (pc_if==if_stage_i.aligner_i.branch_addr_i)))) - && ((full[0] & ~id_stage_i.controller_i.jump_done_q & ~id_stage_i.controller_i.is_hwlp_body & id_stage_i.controller_i.ctrl_fsm_cs==DECODE) -> (pc_if=={pc_id+(iword_id[1:0]==2'b11 ?3'd4: 3'd2)}[31:0])) -`endif -; -endsequence - -/*********************/ -// TIMEPOINTS -/*********************/ - -// RESET PROPERTY TIMEPOINTS // - -sequence t_if_rst; nxt(t,2); endsequence; -sequence t_id_rst; nxt(t_if_rst,2); endsequence; - -// PIPELINE STAGE TIMEPOINTS // - -sequence t_id; t; endsequence; -sequence t_ex; nxt(t_id,1); endsequence; -sequence t_wb; t_ex; endsequence; -sequence t_ex_ready; await(t_ex,~stall[1]&&id_stage_i.controller_i.ctrl_fsm_cs inside {DECODE,DECODE_HWLOOP,ELW_EXE},MAX_WAIT+4); endsequence; -sequence t_wb_ready; t_ex_ready; endsequence; - -// MEMORY PROPERTY TIMEPOINTS // - -sequence t_dmem_req; t_ex; endsequence; -sequence t_dmem_gnt; await(t_dmem_req,dmem_req_ready,MAX_WAIT); endsequence; -sequence t_dmem_2nd_req; await(nxt(t_dmem_gnt,1),obi_dmem_checker.new_req_allowed,MAX_WAIT); endsequence; -sequence t_dmem_2nd_gnt; await(t_dmem_2nd_req,dmem_req_ready,MAX_WAIT); endsequence; -sequence t_wb_ready_mem; t_wb_ready; endsequence; -sequence t_ex_ready_mem_ma; await(t_dmem_2nd_req,~stall[1],MAX_WAIT); endsequence; -sequence t_wb_ready_mem_ma; t_ex_ready_mem_ma; endsequence; - -// OTHER PROPERTY TIMEPOINTS // - -sequence t_ex_ready_branch; await(nxt(t_ex_ready,1),~stall[1],MAX_WAIT); endsequence; -sequence t_ex_ready_wfi; await(t_ex,~stall[1]&&id_stage_i.controller_i.ctrl_fsm_cs==DECODE,MAX_WAIT+6); endsequence; -sequence t_ex_ready_div; await(nxt(t_ex,2),~stall[1]&&id_stage_i.controller_i.ctrl_fsm_cs inside {DECODE},32); endsequence; -sequence t_wb_ready_branch; t_ex_ready_branch; endsequence; -sequence t_wb_ready_wfi; t_ex_ready_wfi; endsequence; -sequence t_wb_ready_div; t_ex_ready_div; endsequence; - -// MODEL CAPTURING TIMEPOINTS // - -sequence t_model; t_wb; endsequence; -sequence t_arch; t_wb; endsequence; - -// ARCHITECTURE UPDATE TIMEPOINTS // - -sequence t_arch_update; t_wb_ready; endsequence; -sequence t_arch_update_mem; t_wb_ready_mem; endsequence; -sequence t_arch_update_mem_ma; t_wb_ready_mem_ma; endsequence; -sequence t_arch_update_branch; t_wb_ready_branch; endsequence; -sequence t_arch_update_wfi; t_wb_ready_wfi; endsequence; -sequence t_arch_update_div; t_wb_ready_div; endsequence; -sequence t_arch_update_fpu; await(nxt(t_ex_ready,FPU_LATENCY),fpu_result_valid,MAX_WAIT); endsequence; - -// CONCEPTUAL STATE TIMEPOINTS // - -sequence t_rd2ex_rst; t_id_rst; endsequence; -sequence t_rd2ex; t_ex_ready; endsequence; -sequence t_rd2ex_mem_ma; t_ex_ready_mem_ma; endsequence; -sequence t_rd2ex_branch; t_ex_ready_branch; endsequence; -sequence t_rd2ex_wfi; t_ex_ready_wfi; endsequence; -sequence t_rd2ex_div; t_ex_ready_div; endsequence; - -/*********************/ -// PROPERTIES -/*********************/ - -// RESET PROPERTY // - -property RESET_p; -reset_sequence |=> - t##0 `core.fetch_enable_i and - during(t,nxt(t_id_rst,WB_OFFSET-1),~interrupt_in.DBGI) and - during(t,nxt(t_id_rst,WB_OFFSET),rst_n) // [t##0 --> first WB] -implies - t_rd2ex_rst##0 Ready2Execute and // first ID - pipe_fetch_req(t,t_if_rst) and // [t##0 --> first IF] - pipe_reset(nxt(t_id_rst,WB_OFFSET)) and // first WB - pipe_dmem_no_req(t,t_id_rst) and // [t##0 --> first ID] - t_rd2ex_rst##0 right_hook; -endproperty - -// BUBBLE & PIPELINE SPECIFIC PROPERTIES // - -property BUBBLE_p; - Arch_state_t cur_Arch; - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 Ready2Execute and - t_id##0 ~full[0] | stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) -implies - t_rd2ex##0 Ready2Execute and - pipe_bubble(t_arch_update,cur_Arch) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -// I, E, C, X PROPERTIES // - -property RV_INSTR(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] && (exe.next_pc.conditional -> ~exe.next_pc.non_linear) and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and - during(nxt(t_wb,1),nxt(t_wb_ready,1),pc_check(exe.next_pc.PC)) and - pipe_instr(t_arch_update,cur_Arch,exe,exe.result) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_Branch(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] && (exe.next_pc.conditional -> exe.next_pc.non_linear) and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready_branch,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex_branch##0 Ready2Execute and - pipe_instr(t_arch_update_branch,cur_Arch,exe,exe.result) and - pipe_dmem_no_req(t_ex,t_ex_ready_branch) and - t_rd2ex_branch##0 right_hook; -endproperty - -property RV_INSTR_MEM(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable<=4'hf and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready_mem,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and - pipe_instr(t_arch_update_mem,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and - pipe_dmem_1st_req(t_dmem_gnt,exe) and - during_excl(nxt(t_dmem_gnt,1),t_wb_ready_mem,~dmem_req_valid) and - t_arch_update_mem##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and - t_arch_update_mem##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_MEM_MA(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable>4'hf and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready_mem_ma,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex_mem_ma##0 Ready2Execute and - pipe_instr(t_arch_update_mem_ma,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and - pipe_dmem_1st_req(t_dmem_gnt,exe) and - pipe_dmem_2nd_req(t_dmem_2nd_gnt,exe) and - during_excl(nxt(t_dmem_gnt,1),t_dmem_2nd_req,~dmem_req_valid) and - t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and - t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and - t_rd2ex_mem_ma##0 right_hook; -endproperty - -// SYSTEM PROPERTIES // - -property FENCE_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and - pipe_instr(t_arch_update,cur_Arch,exe) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property WFI_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready_wfi,~(is_interrupt|is_debug)) and - during(nxt(t_ex,3),nxt(t_ex,6), id_stage_i.controller_i.ctrl_fsm_cs==SLEEP -> `core.wake_from_sleep) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex_wfi##0 Ready2Execute and - pipe_instr(t_arch_update_wfi,cur_Arch,exe) and - pipe_dmem_no_req(t_ex,t_ex_ready_wfi) and - t_rd2ex_wfi##0 right_hook; -endproperty - -property xRET_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] & ((exe.dec.instr==DRET) | ~cur_Arch.CSR.curDebug) and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and - pipe_ret(t_arch_update,cur_Arch,exe) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property ECALL_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - during(t_id,t_wb_ready,~is_interrupt&~is_debug) and - t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.xcpt_code inside {xcpt_UEnvCall,xcpt_SEnvCall,xcpt_MEnvCall} & ~cur_Arch.CSR.curDebug -implies - t_rd2ex##0 Ready2Execute and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property EBREAK_BreakPoint_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & ~exe.xcpt.dbg & exe.xcpt.xcpt_code==xcpt_Breakpoint & exe.xcpt.brk inside {brk_instr} & ~cur_Arch.CSR.curDebug -implies - t_rd2ex##0 Ready2Execute and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property EBREAK_HaltReq_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.xcpt_code==xcpt_Breakpoint & exe.xcpt.brk inside {brk_instr} & cur_Arch.CSR.curDebug -implies - t_rd2ex##0 Ready2Execute and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property EBREAK_ForcedEntry_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt)) and - t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.dbg & exe.xcpt.xcpt_code==xcpt_Breakpoint & exe.xcpt.brk inside {brk_instr} & ~cur_Arch.CSR.curDebug -implies - t_rd2ex##0 Ready2Execute and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -// Zicsr PROPERTIES // - -property CSRx_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_ex##0 set_freeze(result,compose_result(csr_rdata)) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and -`ifndef ISSUE_32_FIXED - t_wb_ready##0 `core.COREV_PULP -> (~id_stage_i.controller_i.hwlp_end1_eq_pc & ~id_stage_i.controller_i.hwlp_end0_eq_pc) and // **Potential ISSUE_32** In case the hwlp end pc is same as next pc expected (pc+4) the next pc is set to a different value than expected -`endif - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and - pipe_instr(t_arch_update,cur_Arch,exe,result) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_ex##0 exe.csr.addr==csr_addr and - t_ex##0 ~((exe.dec.RD[1].idx==0)|(`core.COREV_PULP?(exe.csr.csr inside {csr_lpcount0, csr_lpcount1}):'0)) -> CSR_read(csr_rdata,exe.csr,cur_Arch.CSR,$past(interrupt_in,1)) and // **I** Skip checking lpcount read - t_rd2ex##0 right_hook; -endproperty - -// Zifencei PROPERTIES // - -property FENCE_I_p(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and - pipe_instr(t_arch_update,cur_Arch,exe) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -// M PROPERTIES // - -property RV_INSTR_MUL(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and -`ifdef PVE_M_SUPPORT - t_ex_ready##0 set_freeze(result,exe.result) and - t_ex_ready##0 restrict_ops(compose_operands(exe.op[1],exe.op[2]),'{default:'h1}) and -`else - t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and -`endif - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and -`ifdef PVE_M_SUPPORT - pipe_result(t_ex_ready,exe,result,mul_result) and -`else - pipe_instr(t_arch_update,cur_Arch,exe,result) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - pipe_operands(t_ex_ready,exe,compose_operands(mul_op_a,mul_op_b,mul_op_c)) and -`endif - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_DIV(insn_set insns, cycles); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and -`ifdef PVE_M_SUPPORT - t_ex##0 set_freeze(result,exe.result) and - t_ex##0 restrict_ops(exe.op,'{default:'h1}) and -`else - t_ex##cycles set_freeze(result,compose_result(div_result)) and -`endif - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready_div,~(is_interrupt|is_debug)) and - during_excl(nxt(t_ex,2),nxt(t_ex,cycles),~div_result_valid) and - t_ex##cycles div_result_valid and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex_div##0 Ready2Execute and -`ifdef PVE_M_SUPPORT - pipe_result(t_ex_ready_div,exe,result,div_result) and -`else - pipe_instr(t_arch_update_div,cur_Arch,exe,result) and - pipe_dmem_no_req(t_ex,t_ex_ready_div) and - pipe_operands(t_ex_ready_div,exe,compose_operands(div_op_a,div_op_b),compose_selection('h0,'h3)) and -`endif - t_rd2ex_div##0 right_hook; -endproperty - -// F, D PROPERTIES // - -property RV_INSTR_F(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and -`ifdef PVE_FPU_SUPPORT - t_ex_ready##FPU_LATENCY set_freeze(result,exe.result) and - t_ex_ready##FPU_LATENCY exe.dec.instr inside {FMUL_S,FMADD_S,FNMADD_S,FMSUB_S,FNMSUB_S} -> restrict_fpu_ops(compose_operands(exe.op[1],exe.op[2])) and -`else - t_ex_ready##FPU_LATENCY set_freeze(result,compose_result(fpu_result,fpu_flags)) and -`endif - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_arch_update_fpu,~(is_interrupt|is_debug)) and - t_arch_update_fpu##0 (FPU_LATENCY>0) -> fpu_result_valid and // **I** Otherwise we wait forever in case FPU_LATENCY==2 - t_ex_ready##0 ~stall[1] and // **I** No preceding FDIV/ FSQRT instruction, could use instead t_id##0 ~(fpu_lat_ex=='h3 && (fpu_op_ex=='h4 || fpu_op_ex=='h5)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and -`ifdef PVE_FPU_SUPPORT - pipe_result(nxt(t_ex_ready,FPU_LATENCY),exe,result,fpu_result) and -`else - pipe_instr(t_arch_update,cur_Arch,exe,result,(FPU_LATENCY>0)?'0:'1) and - pipe_dmem_no_req(t_ex,t_ex_ready) and -`ifdef CFG_F - t_arch_update_fpu##1 (FPU_LATENCY>0) -> (exe.dec.RD[1].RF==rf_X?((exe.dec.RD[1].idx!=0 -> result.data[1]==Arch.X[exe.dec.RD[1].idx].data)):(result.data[1]==Arch.F[exe.dec.RD[1].idx].data)) and -`else - t_arch_update_fpu##1 (FPU_LATENCY>0) -> (exe.dec.RD[1].idx!=0 -> result.data[1]==Arch.X[exe.dec.RD[1].idx].data) and -`endif - t_arch_update_fpu##1 (FPU_LATENCY>0) -> (Arch.CSR.fflags==($past(Arch.CSR.fflags)|result.flags)) and -`endif - t_rd2ex##0 right_hook; -endproperty - -// X PROPERTIES // - -property RV_INSTR_DOT(insn_set insns, select); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and -`ifdef PVE_M_SUPPORT - t_ex_ready##0 set_freeze(result,exe.result) and - t_ex_ready##0 restrict_ops(compose_operands(exe.op[1],exe.op[2]),'{default:select}) and -`else - t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and -`endif - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and -`ifdef PVE_M_SUPPORT - pipe_result(t_ex_ready,exe,result,mul_result) and -`else - pipe_instr(t_arch_update,cur_Arch,exe,result) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - pipe_operands(t_ex_ready,exe,compose_operands(dot_mul_op_a,dot_mul_op_b,dot_mul_op_c)) and -`endif - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_DOT_SC(insn_set insns, select); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and -`ifdef PVE_M_SUPPORT - t_ex_ready##0 set_freeze(result,exe.result) and - t_ex_ready##0 restrict_ops(compose_operands(exe.op[1],exe.op[2]),'{default:select}) and -`else - t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and -`endif - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and -`ifdef PVE_M_SUPPORT - pipe_result(t_ex_ready,exe,result,mul_result) and -`else - pipe_instr(t_arch_update,cur_Arch,exe,result) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - pipe_operands(t_ex_ready,exe,compose_operands(dot_mul_op_a,dot_mul_op_b,dot_mul_op_c),compose_selection('h0,select)) and -`endif - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_DOT_SCI(insn_set insns, select); - execute_t exe; - Arch_state_t cur_Arch; - result_t result; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and -`ifdef PVE_M_SUPPORT - t_ex##0 set_freeze(result,exe.result) and - t_ex##0 restrict_ops(compose_operands(exe.op[1],dot_mul_op_b),'{default:select}) and -`else - t_ex_ready##0 set_freeze(result,compose_result(mul_result)) and -`endif - t_id##0 insns[exe.dec.instr] and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies - t_rd2ex##0 Ready2Execute and -`ifdef PVE_M_SUPPORT - pipe_result(t_ex_ready,exe,result,mul_result) and -`else - pipe_instr(t_arch_update,cur_Arch,exe,result) and - pipe_dmem_no_req(t_ex,t_ex_ready) and -// pipe_operands(t_ex_ready,exe,compose_operands(dot_mul_op_a,dot_mul_op_b,dot_mul_op_c),compose_selection('h0,select)) and // operand b manipulation is based on the immediate value -`endif - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_MEM_ELW(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable<=4'hf and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(nxt(t_wb_ready_mem,2),~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies -// t_rd2ex##0 Ready2Execute and - pipe_instr(t_arch_update_mem,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and - pipe_dmem_1st_req(t_dmem_gnt,exe) and - during_excl(nxt(t_dmem_gnt,1),t_wb_ready_mem,~dmem_req_valid) and - t_arch_update_mem##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and - t_arch_update_mem##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and - t_rd2ex##0 right_hook; -endproperty - -property RV_INSTR_MEM_MA_ELW(insn_set insns); - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 insns[exe.dec.instr] && exe.mem.byte_enable>4'hf and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(nxt(t_wb_ready_mem_ma,2),~(is_interrupt|is_debug)) and - t_id##0 ~exe.xcpt.valid -implies -// t_rd2ex_mem_ma##0 Ready2Execute and - pipe_instr(t_arch_update_mem_ma,cur_Arch,exe,exe.result,NUM_RD==2?2'b01:1'b0) and - pipe_dmem_1st_req(t_dmem_gnt,exe) and - pipe_dmem_2nd_req(t_dmem_2nd_req,exe) and - during_excl(nxt(t_dmem_gnt,1),t_dmem_2nd_req,~dmem_req_valid) and - t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> rf_we_lsu && rf_waddr_lsu=={(exe.dec.RD[1].RF==rf_F)?1'b1:1'b0,exe.dec.RD[1].idx} and - t_arch_update_mem_ma##1 exe.mem.cmd==mc_load -> lsu_data_type==data_size_enc(exe.mem.size) && lsu_data_sign[0]==((exe.dec.RD[1].RF==rf_X)&exe.mem.signed_data) && lsu_data_offset==exe.mem.addr[1:0] and - t_rd2ex_mem_ma##0 right_hook; -endproperty - -// EXCEPTION PROPERTIES // - -property XCPT_IF_ID_p; - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - pipe_env(t_wb_ready,~(is_interrupt|(is_debug & exe.xcpt.xcpt_code inside {xcpt_Illegal_Instr}))) and - t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & exe.xcpt.xcpt_code inside {xcpt_Breakpoint,xcpt_Fetch_Page_Fault,xcpt_Fetch_Access_Fault,xcpt_Illegal_Instr,xcpt_Fetch_Addr_Align} & exe.xcpt.brk inside {brk_none,brk_fetch} -implies - t_rd2ex##0 Ready2Execute and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -property XCPT_WB_p; - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - t_id##0 exe.xcpt.valid & ~exe.xcpt.interrupt & (exe.xcpt.xcpt_code inside {xcpt_Breakpoint,xcpt_SAMO_Addr_Align,xcpt_Load_Addr_Align,xcpt_SAMO_Page_Fault,xcpt_Load_Page_Fault,xcpt_SAMO_Access_Fault,xcpt_Load_Access_Fault}) & exe.xcpt.brk inside {brk_none,brk_dmem} -implies - t_rd2ex##0 Ready2Execute and - t_wb_ready##0 no_pending_results_used(exe.dec) and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -// INTERRUPT HANDLING PROPERTIES // - -property INTR_Handle_p; - execute_t exe; - Arch_state_t cur_Arch; - t_model##0 set_freeze(exe,execute) and - t_arch##0 set_freeze(cur_Arch,Arch) and - t_id##0 Ready2Execute and - t_id##0 full[0] && ~stall[0] and - t_id##0 exe.xcpt.valid & exe.xcpt.interrupt -implies - t_rd2ex##0 Ready2Execute and - pipe_xcpt(t_arch_update,cur_Arch,exe.xcpt) and - pipe_dmem_no_req(t_ex,t_ex_ready) and - t_rd2ex##0 right_hook; -endproperty - -/*********************/ -// NON-TIDAL ASSERTIONs -/*********************/ - -// COUNTERS // - -property mcycle_increment_p; - Ready2Execute ##1 ~execute.csr.count_inhibit.CY&~execute.xcpt.interrupt |=> - Arch.CSR.mcycle==$past(Arch.CSR.mcycle+64'h1); -endproperty -mcycle_increment_a : assert property (disable iff(~rst_n) mcycle_increment_p); - -property mcycle_no_increment_p; - Ready2Execute ##1 execute.csr.count_inhibit.CY&Arch.CSR.mcountinhibit.CY&((execute.csr.cmd == cc_none)|(execute.csr.cmd == cc_r)) |=> - Arch.CSR.mcycle==$past(Arch.CSR.mcycle); -endproperty -mcycle_no_increment_a : assert property (disable iff(~rst_n) mcycle_no_increment_p); - -property mhpmcounter3_increment_p; - Ready2Execute ##1 ~execute.csr.count_inhibit.HPM[3]&~execute.xcpt.interrupt |=> - Arch.CSR.mhpmcounter[3]==$past(|(Arch.CSR.mhpmevent[3][15:0]&cs_registers_i.hpm_events) ? Arch.CSR.mhpmcounter[3]+64'h1 : Arch.CSR.mhpmcounter[3]); -endproperty -mhpmcounter3_increment_a : assert property (disable iff(~rst_n) mhpmcounter3_increment_p); - -property mhpmcounter3_no_increment_p; - Ready2Execute ##1 execute.csr.count_inhibit.HPM[3]&Arch.CSR.mcountinhibit.HPM[3]&((execute.csr.cmd == cc_none)|(execute.csr.cmd == cc_r)) |=> - Arch.CSR.mhpmcounter[3]==$past(Arch.CSR.mhpmcounter[3]); -endproperty -mhpmcounter3_no_increment_a : assert property (disable iff(~rst_n) mhpmcounter3_no_increment_p); - -// LSU // - -property stable_lsu_signals_p; - rf_we_lsu&~obi_dmem_checker.rvalid |=> $stable({rf_we_lsu,rf_waddr_lsu,lsu_data_type,lsu_data_offset,lsu_data_sign}); -endproperty -stable_lsu_signals_a : assert property (disable iff(~rst_n) stable_lsu_signals_p); - -property lsu_write_p; - ~rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid && - ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0]) && // A write on ALU port by next F instruction to same RD overtake LSU port write - ~((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || // lw - (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) // lh - |=> - (obi_dmem_checker.cnt!=$past(obi_dmem_checker.cnt) && rf_waddr_lsu!=$past(rf_waddr_lsu) -> Arch.X[$past(rf_waddr_lsu[4:0])].valid) && - ($past(rf_waddr_lsu[4:0])!='0 -> Arch.X[$past(rf_waddr_lsu[4:0])].data== - $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), - addr: $past({30'h0,lsu_data_offset}), default: '0},{32'h0,$past(dmem_resp_data)}))); -endproperty -lsu_write_a : assert property (disable iff(~rst_n) lsu_write_p); - -property lsu_ma_write_p; - ~rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid&&id_stage_i.register_file_i.we_a_i && - ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0])&& - ((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) - |=> -// Arch.X[$past(rf_waddr_lsu[4:0])].valid && - $past(rf_waddr_lsu[4:0])!='0 -> Arch.X[$past(rf_waddr_lsu[4:0])].data== - $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), - addr: $past({30'h0,lsu_data_offset}), default: '0},{$past(dmem_resp_data),$past(load_store_unit_i.rdata_q)})); -endproperty -lsu_ma_write_a : assert property (disable iff(~rst_n) lsu_ma_write_p); - -property lsu_ma_rdata_q_p; - rf_we_lsu&&obi_dmem_checker.rvalid&&cv32e40p_core.data_misaligned_ex&& - ((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) - |=> - load_store_unit_i.rdata_q==$past(dmem_resp_data); -endproperty -lsu_ma_rdata_q_a : assert property (disable iff(~rst_n) lsu_ma_rdata_q_p); - -`ifdef CFG_F -property lsu_write_f_p; - rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid && - ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0])&& - ~((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) - |=> - (obi_dmem_checker.cnt!=$past(obi_dmem_checker.cnt) && rf_waddr_lsu!=$past(rf_waddr_lsu) -> Arch.F[$past(rf_waddr_lsu[4:0])].valid) && - (Arch.F[$past(rf_waddr_lsu[4:0])].data== - $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), - addr: $past({30'h0,lsu_data_offset}), default: '0},{32'h0,$past(dmem_resp_data)}))); -endproperty -lsu_write_f_a : assert property (disable iff(~rst_n) lsu_write_f_p); - -property lsu_ma_write_f_p; - rf_waddr_lsu[5]&&rf_we_lsu&&obi_dmem_checker.rvalid&&id_stage_i.register_file_i.we_a_i && - ~(fpu_result_valid && fpu_waddr[4:0]==rf_waddr_lsu[4:0])&& - ((data_size_enc(lsu_data_type)==2'h2&&lsu_data_offset>0) || (data_size_enc(lsu_data_type)==2'h1&&lsu_data_offset==2'h3)) - |=> -// Arch.F[$past(rf_waddr_lsu[4:0])].valid && - Arch.F[$past(rf_waddr_lsu[4:0])].data== - $unsigned(align_rdata('{size: data_size_enc($past(lsu_data_type)), signed_data: $past(lsu_data_sign[0]), - addr: $past({30'h0,lsu_data_offset}), default: '0},{$past(dmem_resp_data),$past(load_store_unit_i.rdata_q)})); -endproperty -lsu_ma_write_f_a : assert property (disable iff(~rst_n) lsu_ma_write_f_p); -`endif - -`include `GENERATED_ASSERTIONS_FILE -`include "constraints.sv" - -endmodule diff --git a/scripts/riscv_isa_formal/common/io.sv b/scripts/riscv_isa_formal/common/io.sv deleted file mode 100755 index cb7c9c1e2..000000000 --- a/scripts/riscv_isa_formal/common/io.sv +++ /dev/null @@ -1,72 +0,0 @@ - // Data memory interface - input dmem_req_we ='0, // Data memory request type - input[3:0] dmem_req_be ='0, // Data memory request byte enable - input[1:0] dmem_req_size ='0, // Data memory request size - input dmem_req_sign ='0, // Data memory request sign - - // Exceptions & Debug - input is_sstep ='0, // Single stepping of debug mode - input xcpt_bp_if ='0, // Instruction address breakpoint exception - input xcpt_bp_ld ='0, // Load address breakpoint exception - input xcpt_bp_samo ='0, // Store/ AMO address breakpoint exception - input xcpt_dbg_bp_if ='0, // Debug instruction address breakpoint exception - input xcpt_dbg_bp_ld ='0, // Debug load address breakpoint exception - input xcpt_dbg_bp_samo ='0, // Debug Store/ AMO address breakpoint exception - input xcpt_af_instr_1st ='0, // Instruction access fault exception - input xcpt_af_instr_2nd ='0, // Instruction second access fault exception - input xcpt_af_ld_1st ='0, // Load access fault exception - input xcpt_af_ld_2nd ='0, // Load second access fault exception - input xcpt_af_samo_1st ='0, // Store/ AMO access fault exception - input xcpt_af_samo_2nd ='0, // Store/ AMO second access fault exception - input xcpt_pf_instr_1st ='0, // Instruction page fault exception - input xcpt_pf_instr_2nd ='0, // Instruction second access page fault exception - input xcpt_pf_ld_1st ='0, // Load page fault exception - input xcpt_pf_ld_2nd ='0, // Load second access page fault exception - input xcpt_pf_samo_1st ='0, // Store/ AMO page fault exception - input xcpt_pf_samo_2nd ='0, // Store/ AMO second access page fault exception - input xcpt_ma_ld ='0, // Load address misaligned exception - input xcpt_ma_samo ='0, // Store/AMO address misaligned exception - - // Multiplication & Division - input mul_op_valid ='0, // Multiplication operation validity - input[XLEN-1:0] mul_op_a ='0, // Multiplication first source operand - input[XLEN-1:0] mul_op_b ='0, // Multiplication second source operand - input[XLEN-1:0] mul_op_c ='0, // Multiplication third source operand - input[XLEN-1:0] mul_result ='0, // Multiplication operation result - input mul_result_valid ='0, // Multiplication operation result validity - input div_op_valid ='0, // Division operation validity - input[XLEN-1:0] div_op_a ='0, // Division first source operand - input[XLEN-1:0] div_op_b ='0, // Division second source operand - input[$clog2(XLEN):0] div_op_b_shift ='0, // Division second source operand shift amount - input[XLEN-1:0] div_result ='0, // Division operation result - input div_result_valid ='0, // Division operation result validity - - // Floating point - input fpu_op_valid ='0, // FPU operation validity - input[XLEN-1:0] fpu_op_a ='0, // FPU first source operand - input[XLEN-1:0] fpu_op_b ='0, // FPU second source operand - input[XLEN-1:0] fpu_op_c ='0, // FPU third source operand - input Frm fpu_rm ='0, // FPU rounding mode - input Fflags fpu_flags ='0, // FPU flags - input[XLEN-1:0] fpu_result ='0, // FPU operation result - input fpu_result_valid ='0, // FPU operation result validity - - // Design specific - input is_debug ='0, // Core is about to enter debug mode - input is_interrupt ='0, // Core is about to encounter an interrupt - input[XLEN-1:0] boot_addr ='0, // Boot address - - input rf_we_lsu ='0, - input[5:0] rf_waddr_lsu ='0, - input[1:0] lsu_data_type ='0, - input[1:0] lsu_data_sign ='0, - input[1:0] lsu_data_offset ='0, - input fpu_s_cycle ='0, - input fpu_m_cycle ='0, - input[5:0] fpu_waddr ='0, - input[5:0] fpu_waddr_ex ='0, - input[1:0] fpu_lat_ex ='0, - input[5:0] fpu_op_ex ='0, - input[XLEN-1:0] dot_mul_op_a ='0, - input[XLEN-1:0] dot_mul_op_b ='0, - input[XLEN-1:0] dot_mul_op_c ='0 diff --git a/scripts/riscv_isa_formal/common/other_bindings.sv b/scripts/riscv_isa_formal/common/other_bindings.sv deleted file mode 100755 index 41c929d20..000000000 --- a/scripts/riscv_isa_formal/common/other_bindings.sv +++ /dev/null @@ -1,72 +0,0 @@ - // Data memory interface - .dmem_req_we (data_we_o), - .dmem_req_be (data_be_o), - .dmem_req_size (), - .dmem_req_sign (), - - // Exceptions & Debug - .is_sstep (debug_single_step), - .xcpt_bp_if (), - .xcpt_bp_ld (), - .xcpt_bp_samo (), - .xcpt_dbg_bp_if (), - .xcpt_dbg_bp_ld (), - .xcpt_dbg_bp_samo (), - .xcpt_af_instr_1st (), - .xcpt_af_instr_2nd (), - .xcpt_af_ld_1st (), - .xcpt_af_ld_2nd (), - .xcpt_af_samo_1st (), - .xcpt_af_samo_2nd (), - .xcpt_pf_instr_1st (), - .xcpt_pf_instr_2nd (), - .xcpt_pf_ld_1st (), - .xcpt_pf_ld_2nd (), - .xcpt_pf_samo_1st (), - .xcpt_pf_samo_2nd (), - .xcpt_ma_ld (), - .xcpt_ma_samo (), - - // Multiplication & Division - .mul_op_valid (), - .mul_op_a (ex_stage_i.mult_i.op_a_i), - .mul_op_b (ex_stage_i.mult_i.op_b_i), - .mul_op_c (ex_stage_i.mult_i.op_c_i), - .mul_result (ex_stage_i.mult_i.result_o), - .mul_result_valid (), - .div_op_valid (), - .div_op_a (ex_stage_i.alu_i.alu_div_i.OpA_DI), - .div_op_b (ex_stage_i.alu_i.alu_div_i.OpB_DI), - .div_op_b_shift (ex_stage_i.alu_i.alu_div_i.OpBShift_DI), - .div_result (ex_stage_i.alu_i.alu_div_i.Res_DO), - .div_result_valid (ex_stage_i.alu_i.div_ready), - - // Floating point - .fpu_op_valid (ex_stage_i.apu_req), - .fpu_op_a (ex_stage_i.apu_operands_o[0]), - .fpu_op_b (ex_stage_i.apu_operands_o[1]), - .fpu_op_c (ex_stage_i.apu_operands_o[2]), - .fpu_rm (), - .fpu_flags (ex_stage_i.fpu_fflags_o), - .fpu_result (ex_stage_i.apu_result), - .fpu_result_valid (ex_stage_i.apu_valid), - - // Design specific - .is_debug (id_stage_i.controller_i.ctrl_fsm_cs inside {DBG_TAKEN_ID,DBG_TAKEN_IF,DBG_FLUSH}), - .is_interrupt (id_stage_i.int_controller_i.irq_req_ctrl_o), - .boot_addr ({boot_addr_i[31:2],2'b00}), - - .rf_we_lsu (ex_stage_i.regfile_we_lsu), - .rf_waddr_lsu (ex_stage_i.regfile_waddr_lsu), - .lsu_data_type (load_store_unit_i.data_type_q), - .lsu_data_sign (load_store_unit_i.data_sign_ext_q), - .lsu_data_offset (load_store_unit_i.rdata_offset_q), - .fpu_s_cycle (ex_stage_i.apu_singlecycle), - .fpu_m_cycle (ex_stage_i.apu_multicycle), - .fpu_waddr (ex_stage_i.apu_waddr), - .fpu_waddr_ex (apu_waddr_ex), - .fpu_lat_ex (apu_lat_ex), - .fpu_op_ex (apu_op_ex), - .dot_mul_op_a (ex_stage_i.mult_dot_op_a_i), - .dot_mul_op_b (ex_stage_i.mult_dot_op_b_i), - .dot_mul_op_c (ex_stage_i.mult_dot_op_c_i) diff --git a/scripts/riscv_isa_formal/common/setup.tcl b/scripts/riscv_isa_formal/common/setup.tcl deleted file mode 100755 index 0bcce5472..000000000 --- a/scripts/riscv_isa_formal/common/setup.tcl +++ /dev/null @@ -1,564 +0,0 @@ -proc duration {int_time} { - set timeList [list] - if {$int_time == 0} { - return "0 Sec" - } else { - foreach div {86400 3600 60 1} mod {0 24 60 60} name {Day Hour Min Sec} { - set n [expr {$int_time / $div}] - if {$mod > 0} {set n [expr {$n % $mod}]} - if {$n > 1} { - lappend timeList "$n ${name}s" - } elseif {$n == 1} { - lappend timeList "$n $name" - } - } - return [join $timeList] - } -} - -proc quantify_run {{cmd_limit 0} {run 0} {no_cuts {}} {limit_scale 2.0} {effort 4} {skip_effort_level 0} {html_dir {}} {result_file {}} {checks {}} {prev_run_result {}} {skip_files {}}} { - - puts "\n-INFO- Start of Quantify Run ($run)::\n\nChecks Included::\n\n$checks" - - set_limit -command_real_time $cmd_limit - set run_start_t [clock seconds] - puts "\n-INFO- Launching Quantify Command::\n\nquantify -assume_hold -additional_args \[list $no_cuts -limit_scale $limit_scale -use_single_prover\] -effort $effort -skip_effort_level $skip_effort_level -html $html_dir -save $result_file -checks $checks -incremental $prev_run_result -skip_files $skip_files\n" - catch {quantify -assume_hold -additional_args [list $no_cuts -limit_scale $limit_scale -use_single_prover] -effort $effort -skip_effort_level $skip_effort_level -html $html_dir -save $result_file -checks $checks -incremental $prev_run_result -skip_files $skip_files} - set run_end_t [expr [clock seconds] - $run_start_t] - set_limit -default - - puts "\n-INFO- End of Quantify Run ($run) | Time spent:: [duration $run_end_t]\n" -} - -## 0. DESIGN SETUP ## - -### SETTING UP THE DESIRED CONFIGURATION, RUN & APP ### -## source the setup.inc as the following: [onespin -i setup.inc ] -## arg1: what configuration to set . -## arg2: what processor verification mode to set . -## arg3: what app to launch on top of the processor app. -## ------------------------------------------------------------------------------------------------------------------ - -set configs [dict create \ - "DEF" [dict create \ - description "RV32IMCZicsr_Zifencei" \ - elab "-verilog_parameter {}" \ - define "" \ - json "" \ - ] \ - "F0" [dict create \ - description "RV32IMFCZicsr_Zifencei with FPU latency params set to 0" \ - elab "-verilog_parameter {FPU=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ - define "CFG_F" \ - json "" \ - ] \ - "ZF0" [dict create \ - description "RV32IMCZicsr_Zifencei_Zfinx with FPU latency params set to 0" \ - elab "-verilog_parameter {FPU=1 ZFINX=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ - define "CFG_ZFINX" \ - json "" \ - ] \ - "XP" [dict create \ - description "RV32IMCZicsr_Zifencei_Xpulp" \ - elab "-verilog_parameter {COREV_PULP=1}" \ - define "CFG_XP" \ - json "Xpulp.json Zfinx.json" \ - ] \ - "XPF0" [dict create \ - description "RV32IMFCZicsr_Zifencei_Xpulp with FPU latency params set to 0" \ - elab "-verilog_parameter {FPU=1 COREV_PULP=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ - define "CFG_XP CFG_F" \ - json "Xpulp.json" \ - ] \ - "XPF1" [dict create \ - description "RV32IMFCZicsr_Zifencei_Xpulp with FPU latency params set to 1" \ - elab "-verilog_parameter {FPU=1 COREV_PULP=1 FPU_ADDMUL_LAT=1 FPU_OTHERS_LAT=1}" \ - define "CFG_XP CFG_F" \ - json "Xpulp.json" \ - ] \ - "XPF2" [dict create \ - description "RV32IMFCZicsr_Zifencei_Xpulp with FPU latency params set to 2" \ - elab "-verilog_parameter {FPU=1 COREV_PULP=1 FPU_ADDMUL_LAT=2 FPU_OTHERS_LAT=2}" \ - define "CFG_XP CFG_F" \ - json "Xpulp.json" \ - ] \ - "XPZF0" [dict create \ - description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp with FPU latency params set to 0" \ - elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 FPU_ADDMUL_LAT=0 FPU_OTHERS_LAT=0}" \ - define "CFG_XP CFG_ZFINX" \ - json "Xpulp.json Zfinx.json" \ - ] \ - "XPZF1" [dict create \ - description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp with FPU latency params set to 1" \ - elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 FPU_ADDMUL_LAT=1 FPU_OTHERS_LAT=1}" \ - define "CFG_XP CFG_ZFINX" \ - json "Xpulp.json Zfinx.json" \ - ] \ - "XPZF2" [dict create \ - description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp with FPU latency params set to 2" \ - elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 FPU_ADDMUL_LAT=2 FPU_OTHERS_LAT=2}" \ - define "CFG_XP CFG_ZFINX" \ - json "Xpulp.json Zfinx.json" \ - ] \ - "XPXC" [dict create \ - description "RV32IMCZicsr_Zifencei_Xpulp_Xcluster" \ - elab "-verilog_parameter {COREV_PULP=1 COREV_CLUSTER=1}" \ - define "CFG_XP CFG_XC" \ - json "Xpulp.json Xcluster.json Zfinx.json" \ - ] \ - "XPXCZF2" [dict create \ - description "RV32IMCZicsr_Zifencei_Zfinx_Xpulp_Xcluster with FPU latency params set to 2" \ - elab "-verilog_parameter {FPU=1 ZFINX=1 COREV_PULP=1 COREV_CLUSTER=1 FPU_ADDMUL_LAT=2 FPU_OTHERS_LAT=2}" \ - define "CFG_XP CFG_XC CFG_ZFINX" \ - json "Xpulp.json Xcluster.json Zfinx.json" \ - ] \ -] - -set pve_modes [dict create \ - "DEF" [dict create \ - description "DEF: Control path verification of all instructions and datapath verification of all instructions except multiplication, division or floating point ones" \ - define "" \ - ] \ - "DPM" [dict create \ - description "DPM: Data path verification of multiplication/ division instructions" \ - define "PVE_M_SUPPORT RESTRICT_MUL_OPS_FREE_BITS=1" \ - ] \ - "DPF" [dict create \ - description "DPF: Data path verification of floating-point instructions" \ - define "PVE_FPU_SUPPORT RESTRICT_MUL_OPS_FREE_BITS=1" \ - ] \ -] - -set apps [dict create \ - "PRC" [dict create \ - description "PRC: Property Checking" \ - compile "-dontcare_handling any -signal_domain {{scan_cg_en_i} 0}" \ - ] \ - "QTF" [dict create \ - description "QTF: Quantify" \ - compile "-dontcare_handling any -signal_domain {{scan_cg_en_i} 0} -constant [list [list core_i.id_stage_i.register_file_i.rst_n 1] ]" \ - ] \ - "VCI" [dict create \ - description "VCI: Verification Coverage Integration" \ - compile "-dontcare_handling any -signal_domain {{scan_cg_en_i} 0}" \ - ] \ -] - -if {$::argc>0} { - lassign $::argv cfg pve_mode app - if {$cfg ni [dict keys $configs]} { - onespin::message -error "Only configurations [join [dict keys $configs] ,] are supported!" - return -code error - } - if {$pve_mode ni [dict keys $pve_modes]} { - onespin::message -error "Only processor verification modes [join [dict keys $pve_modes] ,] are supported!" - return -code error - } elseif {$pve_mode eq "DPF" && $cfg in {"DEF" "XP" "XPXC"} } { - onespin::message -error "Floating-point configuration must be selected in order to perform data path verification!" - return -code error - } - if {$app ni [dict keys $apps]} { - onespin::message -error "Only apps [join [dict keys $apps] ,] are supported!" - return -code error - } -} else { - if {[get_tool_info -gui]} { - set cfg [string index [onespin::ask_user -default 0 -alternatives [lmap {k d} $configs {string cat "$k - " [dict get $d description]}] "Select which RISC-V configuration to set up:"] 0] - set pve_mode [string index [onespin::ask_user -default "DEF" -alternatives [lmap {k d} $pve_modes {string cat "$k - " [dict get $d description]}] "Select which processor verification mode to set:"] 0] - set app [string index [onespin::ask_user -default "PRC" -alternatives [lmap {k d} $apps {string cat "$k - " [dict get $d description]}] "Select which app to launch:"] 0] - } else { - set cfg "DEF" - set pve_mode "DEF" - set app "PRC" - } -} -set target cv32e40p_top -set core_inst core_i -set prefix ${core_inst}. -## - -### ADJUST TO READ-IN THE NEW DESIGN ### -onespin::set_parameter disable_intermediate_arithmetic_signals 1 -set cwd [pwd] -set_session_option -naming_style sv -set_compile_option {*}[dict get $apps $app compile] -set_elaborate_option {*}[dict get $configs $cfg elab] -top $target -cd cv32e40p -source $cwd/setup_mv.tcl -set_reset_sequence -low rst_ni -cd $cwd - -set cfg_dir $cwd/$cfg -set pve_mode_dir $cwd/$cfg/$pve_mode -set app_dir $cwd/$cfg/$pve_mode/$app -file mkdir $cfg_dir -file mkdir $pve_mode_dir -file mkdir $app_dir -## - -### PROCESSOR APP FLOW ### - -## --------------------------------------------------------------------------------------------------------------------------------- -## 1 > 2 > 3 > 4 > 5 > 6 > 7 -## --------------------------------------------------------------------------------------------------------------------------------- -## PRE-ANALYSIS | DESIGN | POST-ANALYSIS | ASSERTION | ASSERTION | PERFORMANCE | ASSERTION -## CONFIGURATION | ANALYSIS | CONFIGURATION | GENERATION | READING & RETUNING | ENHANCEMENT | RUNNING & DEBUGGING -## --------------------------------------------------------------------------------------------------------------------------------- - -## --------------------------------------------------------------------------------------------------------------------------------- -## processor_integrity:: | DESCRIPTION -## --------------------------------------------------------------------------------------------------------------------------------- -## extract_ISA | Extract ISA from a RISC-V based processor core and store data in a processor database. -## -core_instance <> | Specify instance name of the core in the DUV to instantiate the VIP on. -## -csr_addr <> | Specify CSR address signal that might be used to assist extraction. -## -csr_rdata <> | Specify CSR read data signal that might be used to assist extraction. -## merge_data | Merge JSON data into the database. -## -file <> | Specify JSON file to be merged. -## -configuration <> | Specify predefined JSON configuration to be merged. -## generate_assertions | Generate assertions for verifying the RISC-V core based on the database. -## -create_individual_checks <> | Specify extensions for which assertions are generated per instruction. -## -exclude_extensions <> | Specify extensions for which assertions generation is supressed. -## -include_extensions <> | Specify extensions only for which assertions are generated. -## generate_IVA | Perform initial value abstraction of architecture state. -## -candidates <> | Specify architecture register fields to be abstracted. -## analyze_trace | Perform detailed trace analysis of run assertions. -## save_data | Write the processor database, or part of it, to a JSON file. -## clear_data | Clear JSON data from the processor database. -## --------------------------------------------------------------------------------------------------------------------------------- -## For full app documentation run "help *processor_integrity::*" or refer to Chapter 14. of the User Manual. -## --------------------------------------------------------------------------------------------------------------------------------- - -## 0. APP SETUP ## - -package require processor_integrity - -### APPEND THE FOLLOWING SET OF DEFINES (ONLY IF NECESSARY) ### -## --------------------------------------------------------------------------------------------------------------------------------- -## DEFINE | USE CASE IF SET -## --------------------------------------------------------------------------------------------------------------------------------- -## GRADUAL VERIFICATION ## -## SKIP_PC_CHECK | Skip checking PC register updates. -## SKIP_RF_CHECK | Skip checking register file updates. -## SKIP_CSR_CHECK | Skip checking CSR updates and reads. -## SKIP_DMEM_CHECK | Skip checking data memory requests. -## LIMIT_TOTAL_INSTR_COUNT | Limit total # of instructions allowed in the pipeline. -## PERFORMANCE ENHANCEMENT ## -## RESTRICT_REGS | Restrict instruction decoding & register file verification to a subset of registers. -## RESTRICT_REGISTER_INDEX | Restrict register file verification to one register only, instruction decoding is not affected. -## RESTRICT_CHECK_DATA_SLICE | Restrict register file data and memory write data verification to a slice or even a bit. -## RESTRICT_MUL_OPS_FREE_BITS | Restrict # of operand bits allowed to toggle checking multiplication/ division instruction datapath. -## RESTRICT_DMEM_STALL_CYCLES | Restrict data memory stall cycles to specific number. Has an effect w/ protocol VIPs' usage. -## TAILORED VERIFICATION ## -## PVE_M_SUPPORT | Enable checking M extension data path. By default, only the control path is checked. -## PVE_FPU_SUPPORT | Enable checking F extension data path. By default, only the control path is checked. -## CHECK_ACCESS_FAULTS | Enable checking all access faults fully according to the privileged specification or Smepmp. -## CUSTOM_MEM_INTERFACES | Constrain memory interfaces. Use only in case bus protocols implemented are not tool supported. -## --------------------------------------------------------------------------------------------------------------------------------- -lappend defines {*}[dict get $configs $cfg define] {*}[dict get $pve_modes $pve_mode define] RESTRICT_REGS RESTRICT_DMEM_STALL_CYCLES=2 -## - -### RE-SET THE FOLLOWING SET OF VARIABLES (ONLY IF NECESSARY) ### -lappend pre_analysis_json_files_to_merge spec.json {*}[dict get $configs $cfg json] -set csr_addr_to_assist_analysis {} -set csr_rdata_to_assist_analysis {} -set core_instance_to_instantiate_vip_on ${core_inst} -lappend post_analysis_json_files_to_merge spec.json {*}[dict get $configs $cfg json] core.json -lappend extensions_to_generate_individual_checks_for F Zfinx -set extensions_to_exclude_assertion_generation_for {} -if {"CV_LOOP" in $defines} { - lappend pre_analysis_json_files_to_merge Xpulp_hwlp.json - lappend post_analysis_json_files_to_merge Xpulp_hwlp.json -} -## - -### EXTEND THE FOLLOWING LISTS BY THE RESPECTIVE RTL SIGNALS (ONLY IF NECESSARY) ### -lappend mul_signals_to_cut ${prefix}ex_stage_i.mult_i.result_o ${prefix}ex_stage_i.alu_i.alu_div_i.Res_DO ${prefix}ex_stage_i.alu_i.alu_div_i.Cnt_DP -lappend fpu_signals_to_cut ${prefix}apu_result_i ${prefix}apu_flags_i -lappend rtl_signals_to_cut -lappend rtl_signals_to_disassemble ${prefix}instr_rdata_i ${prefix}instr_rdata_id ${prefix}if_stage_i.instr_aligned -## - -if {![info exists reuse_files] || !$reuse_files} { - -## 1. PRE-ANALYSIS CONFIGURATION ## - - foreach i ${pre_analysis_json_files_to_merge} { - processor_integrity::merge_data -file ${i} - } - -## 2. DESIGN ANALYSIS ## - - processor_integrity::extract_ISA -csr_addr $csr_addr_to_assist_analysis -csr_rdata $csr_rdata_to_assist_analysis -core_instance $core_instance_to_instantiate_vip_on - -## 3. POST-ANALYSIS CONFIGURATION ## - - foreach i ${post_analysis_json_files_to_merge} { - processor_integrity::merge_data -file ${i} - } - - if {"CFG_ZFINX" in $defines} { - onespin::data::set ISA/Z/Zfinx true - } - - if {$pve_mode ne "DEF"} { - onespin::data::set PVE/checker_instance "RV_chk_DP" - } - -## 4. ASSERTION GENERATION ## - - cd $pve_mode_dir - processor_integrity::generate_assertions -create_individual_checks $extensions_to_generate_individual_checks_for -exclude_extensions $extensions_to_exclude_assertion_generation_for -force - cd $cwd -} else { - puts "-W- Re-using previously generated files! Make sure to re-generate all files on adopting a new tool version or changing the JSON configuration!" - source $pve_mode_dir/RISCV_disass.tcl - source RISCV_disass.tcl -} - -## 5. ASSERTION READING & RETUNING ## - -### USE TO CONSTRAIN MEMORY INTERFACES (ONLY IF BUS PROTOCOLS IMPLEMENTED ARE TOOL SUPPORTED) ### -## Instantiate the respective bus protocol VIP for each of the fetch and data memory interfaces -## The VIPs in this case are used to check and more importantly constrain memory interfaces -## Read in the instantiated VIPs, my_{}.sv, using the read_sva command below -#instantiate_vip -addr_sig instr_addr_o -generated_instance_name obi_imem_checker -filename obi_imem.sv obi -#instantiate_vip -addr_sig data_addr_o -generated_instance_name obi_dmem_checker -filename obi_dmem.sv obi -## - -read_sva -define $defines -include_path $pve_mode_dir {core_checker.sv $pve_mode_dir/bind.sv vips/obi_?mem.sv} - -## 7.1 ASSERTION RUNNING & DEBUGGING ## - -### USE TO RUN INITIAL SET OF ASSERTIONS ### -set_check_option -prover_exec_order { { approver1 approver4 prover2:0 prover2:8 prover2:11 disprover1 disprover3 } } -disprover1_steps 40 -disprover3_steps 40 -check [get_checks -filter name=~"*invariant_a"||name=~"*legal_CSR_reset_state_a"||name=~"*RESET_a"] -## - -## 6. PERFORMANCE ENHANCEMENT ## - -### USE TO COMPUTE INVARIANTS (IF NECESSARY) ### -compute_invariants -## - -if {$app eq "PRC"} { - ### USE TO PERFORM AUTOMATIC INITIAL VALUE ABSTRACTION (IVA) OF ARCHITECTURE STATE (IF NECESSARY) ### - lappend candidates X F frm - if {"CFG_XP" in $defines} { - lappend candidates lpstart0 lpstart1 lpend0 lpend1 - } - processor_integrity::generate_IVA -candidates $candidates - ## -} - -### USE TO CUT DESIGN COMPLEX SIGNALS (IF NECESSARY) ### -if {$pve_mode ne "DPM"} { - lappend rtl_signals_to_cut {*}$mul_signals_to_cut -} -if {($pve_mode ne "DPF") && ("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { - lappend rtl_signals_to_cut {*}$fpu_signals_to_cut -} -add_cut_signals $rtl_signals_to_cut -cut_signals -## - -## 7.2 ASSERTION RUNNING & DEBUGGING ## - -### USE TO EASE DEBUGGING BY DISASSEMBLING VALUES OF RTL SIGNALS HOLDING INSTRUCTION WORDS & RUN THE OTHER ASSERTIONS ### -foreach i ${rtl_signals_to_disassemble} { - use_value_printer ${i} PVE_disass -} -## - -#set nb_processes 2 -#set nb_processes 3 -#set nb_processes 4 -#set nb_processes 5 -#set nb_processes 6 -#set nb_processes 8 -#set nb_processes 12 -set nb_processes 16 -#set nb_processes 24 -#set nb_processes 32 - -set_check_option -verbose -set_check_option -local_processes $nb_processes -set_check_option -engine_licensing unlimited - -puts "\n-INFO- Launching $app app in $pve_mode mode with $nb_processes parallel processes.\n" - -#set_check_option -prover_exec_order { { approver1 approver4 prover2:0 prover2:8 prover2:11 disprover1 disprover3 } } -set_check_option -prover_exec_order { { approver1 prover2:0 prover2:8 prover2:11 } } -#set_check_option -disprover1_steps 40 -disprover3_steps 40 - -check_consistency -category model_building -effort maximum -exclude_check [get_checks -filter name=~"*hdl*"||name=~"*FSQRT_S_a*"||name=~"**FDIV_S_a*"] - -set DEF_checks [lsort -dictionary [get_checks -filter excluded==false&&(type==property||type==assertion)]] -set DPM_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32M.*"||name=~"*RV32X.CV_XDOT*"||name=~"*RV32X.CV_MUL*"||name=~"*RV32X.CV_MAC*"||name=~"*RV32X.CV_CPLXMUL*")]] -set DPF_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32F.*"||name=~"*RV32Zfinx.*")]] - -set group_1_checks [lsort -dictionary [concat core_i.RV_chk.ops.RESET_a [get_checks -filter excluded==false&&type==assertion]]] -set group_2_checks [lsort -dictionary [list core_i.RV_chk.ops.XCPT_IF_ID_a core_i.RV_chk.RV32C.ARITH_a core_i.RV_chk.RV32C.BRANCH_Taken_a core_i.RV_chk.RV32C.BRANCH_a core_i.RV_chk.RV32C.JUMP_a core_i.RV_chk.RV32I.EBREAK_BreakPoint_a core_i.RV_chk.RV32I.MEM_MultiAccess_a core_i.RV_chk.RV32I.xRET_a core_i.RV_chk.RV32X.CV_ADD_X_a core_i.RV_chk.RV32X.CV_BITMAN_OTHER_a core_i.RV_chk.RV32X.CV_EXTRACTX_X_a core_i.RV_chk.RV32X.CV_INSERTX_a core_i.RV_chk.RV32X.CV_PACKXX_X_a core_i.RV_chk.RV32X.CV_SETUPX_a core_i.RV_chk.RV32X.CV_SHUFFLE2_X_a core_i.RV_chk.RV32Zicsr.CSRx_a]] -set group_3_checks [lsort -dictionary [list core_i.RV_chk.ops.BUBBLE_a core_i.RV_chk.RV32I.ARITH_a core_i.RV_chk.RV32I.EBREAK_HaltReq_a core_i.RV_chk.RV32I.ECALL_a core_i.RV_chk.RV32I.FENCE_a core_i.RV_chk.RV32I.WFI_a core_i.RV_chk.RV32X.CV_ABS_X_a core_i.RV_chk.RV32X.CV_CLIPXX_a core_i.RV_chk.RV32X.CV_CMPEQ_X_a core_i.RV_chk.RV32X.CV_EXTRACTXX_a core_i.RV_chk.RV32X.CV_EXTXX_a core_i.RV_chk.RV32X.CV_INSERT_X_a core_i.RV_chk.RV32X.CV_SX_I_a core_i.RV_chk.RV32X.CV_SX_RI_a core_i.RV_chk.RV32X.CV_ADDXXNR_a core_i.RV_chk.RV32X.CV_SHUFFLEIX_SCI_B_a core_i.RV_chk.RV32X.CV_BSETX_a core_i.RV_chk.RV32X.CV_BXXIMM_Taken_a core_i.RV_chk.RV32X.CV_ENDX_a core_i.RV_chk.RV32X.CV_LXX_I_a core_i.RV_chk.RV32X.CV_LXX_RI_a core_i.RV_chk.RV32X.CV_SLL_X_a core_i.RV_chk.RV32X.CV_STARTX_a core_i.RV_chk.RV32X.CV_ADD_DIVX_a core_i.RV_chk.RV32X.CV_ADDXXN_a core_i.RV_chk.RV32X.CV_AVGU_X_a core_i.RV_chk.RV32X.CV_BCLRX_a core_i.RV_chk.RV32X.CV_SUB_DIVX_a core_i.RV_chk.RV32X.CV_SUBROTMJ_X_a core_i.RV_chk.RV32X.CV_SUBXXN_a core_i.RV_chk.RV32X.CV_SUBXXNR_a core_i.RV_chk.RV32X.CV_MAXU_X_a]] -set group_4_checks [lsort -dictionary [concat [get_checks -filter excluded==false&&name=~"*RV32X.CV_ELW*"] core_i.RV_chk.RV32I.EBREAK_ForcedEntry_a core_i.RV_chk.RV32X.CV_COUNTX_a core_i.RV_chk.RV32X.CV_LXX_R_a core_i.RV_chk.RV32X.CV_MAXX_a core_i.RV_chk.RV32X.CV_SX_R_a core_i.RV_chk.RV32C.MEM_a core_i.RV_chk.RV32C.MEM_MultiAccess_a core_i.RV_chk.RV32I.BRANCH_a core_i.RV_chk.RV32I.BRANCH_Taken_a core_i.RV_chk.RV32I.JUMP_a core_i.RV_chk.RV32I.MEM_a core_i.RV_chk.RV32X.CV_ABS_a core_i.RV_chk.RV32X.CV_AND_X_a core_i.RV_chk.RV32X.CV_AVG_X_a core_i.RV_chk.RV32X.CV_BXXIMM_a core_i.RV_chk.RV32X.CV_CMPGE_X_a core_i.RV_chk.RV32X.CV_CMPGEU_X_a core_i.RV_chk.RV32X.CV_CMPGT_X_a core_i.RV_chk.RV32X.CV_CMPGTU_X_a core_i.RV_chk.RV32X.CV_CMPLE_X_a core_i.RV_chk.RV32X.CV_CMPLEU_X_a core_i.RV_chk.RV32X.CV_CMPLT_X_a core_i.RV_chk.RV32X.CV_CMPLTU_X_a core_i.RV_chk.RV32X.CV_CMPNE_X_a core_i.RV_chk.RV32X.CV_CPLXCONJ_a core_i.RV_chk.RV32X.CV_LXX_I_MultiAccess_a core_i.RV_chk.RV32X.CV_LXX_R_MultiAccess_a core_i.RV_chk.RV32X.CV_LXX_RI_MultiAccess_a core_i.RV_chk.RV32X.CV_MAX_X_a core_i.RV_chk.RV32X.CV_MIN_X_a core_i.RV_chk.RV32X.CV_MINU_X_a core_i.RV_chk.RV32X.CV_MINX_a core_i.RV_chk.RV32X.CV_OR_X_a core_i.RV_chk.RV32X.CV_SHUFFLE_X_a core_i.RV_chk.RV32X.CV_SLEX_a core_i.RV_chk.RV32X.CV_SRA_X_a core_i.RV_chk.RV32X.CV_SRL_X_a core_i.RV_chk.RV32X.CV_SUB_X_a core_i.RV_chk.RV32X.CV_SX_I_MultiAccess_a core_i.RV_chk.RV32X.CV_SX_R_MultiAccess_a core_i.RV_chk.RV32X.CV_SX_RI_MultiAccess_a core_i.RV_chk.RV32X.CV_XOR_X_a core_i.RV_chk.RV32Zifencei.FENCE_I_a]] -set group_5_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32M.DIV16_a*"||name=~"*RV32M.DIV32_a*"||name=~"*RV32M.MUL_a*"||name=~"*RV32X.CV_XDOT*"||name=~"*RV32X.CV_MUL*"||name=~"*RV32X.CV_MAC*"||name=~"*RV32X.CV_CPLXMUL*")]] -set group_6_checks [lsort -dictionary [get_checks -filter excluded==false&&(name=~"*RV32F.*"||name=~"*RV32Zfinx.*")]] - -set skipped_files "*/fpnew_* {} */gated_clk_cell* {} */lzc* {} */pa_fdsu_* {} */pa_fpu_* {} */rr_arb_tree* {}" - -puts "\n-INFO- Compile options::\n\n\t[dict get $apps $app compile]\n" -puts "\n-INFO- Elaborate options::\n\n\t[dict get $configs $cfg elab]\n" -puts "\n-INFO- Defines::\n\n\t$defines\n" -puts "\n-INFO- Cut signals::\n\n\t$rtl_signals_to_cut\n" - -if {$app eq "PRC"} { - -# set_check_option -prover_exec_order { { approver1 approver4 prover2:0 prover2:8 prover2:11 disprover1 disprover3 } } - set_check_option -prover_exec_order { { approver1 prover2:0 prover2:8 prover2:11 } } -# set_check_option -prover_exec_order { { disprover1 disprover3 } } -disprover1_steps 20 -disprover3_steps 20 - - set all_checks [set ${pve_mode}_checks] - set checks_nb [llength $all_checks] - set nb_round [expr $checks_nb / $nb_processes] - set nb_remain [expr $checks_nb % $nb_processes] - puts "nb_round = $nb_round, nb_remain = $nb_remain" - for {set i 0} {$i < $nb_round} {incr i} { - set checks [lrange $all_checks [expr $i * $nb_processes] [expr ((($i + 1) * $nb_processes) - 1)]] - puts "[expr $i * $nb_processes] [expr ((($i + 1) * $nb_processes) - 1)]" - puts "\n-INFO- Launching Check Command::\n\ncheck $checks\n" - check $checks - report_result -details - cd $app_dir - save_database -force round_[expr $i + 1] - cd $cwd - } - if {$nb_remain > 0} { - set checks [lrange $all_checks [expr $nb_round * $nb_processes] [expr (($nb_round * $nb_processes) + $nb_remain - 1)]] - puts "[expr $nb_round * $nb_processes] [expr (($nb_round * $nb_processes) + $nb_remain - 1)]" - puts "\n-INFO- Launching Check Command::\n\ncheck $checks\n" - check $checks - report_result -details - cd $app_dir - save_database -force round_[expr $nb_round + 1] - cd $cwd - } - - report_result -signoff -details - -# set_check_option -prover_exec_order { { disprover1 disprover3 } } -# puts "\n-INFO- Launching Check Command::\n\ncheck RV32M.DIV16_a\n" -# check [get_checks -filter name=~"*RV32M.DIV16_a*"] -# cd $app_dir -# save_database -force -# cd $cwd - -} - -if {$app eq "QTF"} { - - source basics.tcl.obf - - set_check_option -prover_exec_order { { disprover1 disprover3 } } -disprover1_steps 20 -disprover3_steps 20 - - set html "${app_dir}/html_results_${cfg}_${pve_mode}" - set results "${app_dir}/qtf_results_${cfg}_${pve_mode}_R" - set log "${app_dir}/${app}_${cfg}_${pve_mode}_R" - - if {$pve_mode eq "DEF"} { - - for {set i 1} {$i < 7} {incr i} { - puts "\nGroup (${i}) checks:\n\nTotal number of checks is: [llength [set group_${i}_checks]] \n" - foreach j [set group_${i}_checks] { - puts "$j" - } - } - - for {set i 1} {$i < 7} {incr i} { - puts "Group (${i}) checks: Total number of checks is: [llength [set group_${i}_checks]]" - } - -# for {set i 1} {$i < 7} {incr i} { - - set i 5 - - start_message_log ${log}${i}.log - if {$i == 1} { - quantify_run 0 $i {-no_cuts} 1.0 2 1 ${html}_L2_S1_R${i} ${results}${i} $group_1_checks {} {} - } elseif {$i == 2} { - quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_2_checks ${results}[expr $i-1] $skipped_files - } elseif {$i == 3} { - quantify_run 0 $i {-no_cuts} 2.0 4 3 ${html}_L4_S2_R${i} ${results}${i} $group_3_checks ${results}[expr $i-1] $skipped_files - } elseif {$i == 4} { - quantify_run 0 $i {-no_cuts} 2.0 4 3 ${html}_L4_S2_R${i} ${results}${i} $group_4_checks ${results}[expr $i-1] $skipped_files - } elseif {$i == 5} { -# quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${results}[expr $i-1] $skipped_files - quantify_run 0 $i {} 6.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${results}[expr $i-1] $skipped_files - } elseif {($i == 6) && ("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { - quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_6_checks ${results}[expr $i-1] {} - } - stop_message_log -# } - - } elseif {$pve_mode eq "DPM"} { - - if {("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { - set i 7 - } else { - set i 6 - } - - start_message_log ${log}${i}.log -# quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks {} $skipped_files -# file copy -force ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1]-Xr -# fileutil::updateInPlace ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] [list string map [list " Xr" " U0"]] -# quantify_run 0 $i {-no_cuts} 4.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] $skipped_files - quantify_run 0 $i {} 6.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_5_checks ${cfg_dir}/DEF/QTF/qtf_results_${cfg}_DEF_R[expr $i-1] $skipped_files - stop_message_log - - } elseif {$pve_mode eq "DPF"} { - - set i 8 - - start_message_log ${log}${i}.log -# quantify_run 0 $i -no_cuts 2.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_6_checks {} {} -# file copy -force ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1] ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1]-Xr -# fileutil::updateInPlace ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1] [list string map [list " Xr" " U0"]] - quantify_run 0 $i -no_cuts 2.0 4 3 ${html}_L4_S4_R${i} ${results}${i} $group_6_checks ${cfg_dir}/DPM/QTF/qtf_results_${cfg}_DPM_R[expr $i-1] {} - stop_message_log - - } - -} - -if {$app eq "VCI"} { - - set_check_option -prover_exec_order { { disprover1 disprover3 } } -disprover1_steps 20 -disprover3_steps 20 - - set output_dir "${app_dir}/qtf_coverage_${cfg}_${pve_mode}" - set checks "[set ${pve_mode}_checks]" - set results "${cfg_dir}/${pve_mode}/QTF/qtf_results_${cfg}_${pve_mode}_R" - set log "${app_dir}/${app}_${cfg}_${pve_mode}" - - if {$pve_mode eq "DEF"} { - if {("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { - set i 6 - } else { - set i 5 - } - } elseif {$pve_mode eq "DPM"} { - if {("CFG_F" in $defines || "CFG_ZFINX" in $defines)} { - set i 7 - } else { - set i 6 - } - } elseif {$pve_mode eq "DPF"} { - set i 8 - } - - start_message_log ${log}.log - puts "\n-INFO- Launching VCI Command::\nexport_quantify_coverage -call_script t.sh -generate_flist -output_dir $output_dir -checks $checks ${results}${i}\n" - export_quantify_coverage -call_script t.sh -generate_flist -output_dir $output_dir -checks $checks ${results}${i} - stop_message_log -# report_quantify_result -quantify_result qtf_results_run_${run} -html html_results_run_${run} - -} diff --git a/scripts/riscv_isa_formal/common/setup_mv.tcl b/scripts/riscv_isa_formal/common/setup_mv.tcl deleted file mode 100755 index 84eb4523c..000000000 --- a/scripts/riscv_isa_formal/common/setup_mv.tcl +++ /dev/null @@ -1,8 +0,0 @@ -if {![info exists ::env(DESIGN_RTL_DIR)]} { - set ::env(DESIGN_RTL_DIR) [pwd]/rtl -} -set_read_hdl_option -verilog_version sv2012 -pragma_ignore {translate_} -vlog -sv -f cv32e40p_fpu_manifest.flist -elaborate -compile -set_mode mv diff --git a/scripts/riscv_isa_formal/common/t.sh b/scripts/riscv_isa_formal/common/t.sh deleted file mode 100755 index eca98e09f..000000000 --- a/scripts/riscv_isa_formal/common/t.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# -# This script is a template representing a customization to integrate OneSpin 360 with VCS simulator -# -# onespin calls the script as follows: -# template_vcs_flow.sh -# -# In this script you need to set up the environment for the simulator, -# -ARG1=$1 - -vsim -64 -c -do "source ${ARG1}; quit -f" diff --git a/scripts/riscv_isa_formal/common/vips/obi_dmem.sv b/scripts/riscv_isa_formal/common/vips/obi_dmem.sv deleted file mode 100755 index 7ca5866e2..000000000 --- a/scripts/riscv_isa_formal/common/vips/obi_dmem.sv +++ /dev/null @@ -1,60 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// // -// General remarks: // -// // -// Just replace below with the name of the module you want to connect the VIP to // -// and add the appropriate parameter values and DUT signals in braces. // -// // -// Leave unused signals (and parameters that just have the default value) simply unconnected // -// because optional signals are pulled up/down appropriately in the checker file. // -// // -// The VIP uses an active LOW reset. // -// If your DUT reset signal, called "rst", is active high, use "!rst" in the instantiation // -// // -// For external interfaces (bus signals are primary inputs/outputs), set parameter ASSUME=1. // -// In that case, make sure MASTER=1 in case the DUT is the bus master (driving the address signal output), // -// or MASTER=0 in case the DUT is the bus slave (address signal is input). // -// // -// In case you instantiate the VIP several times for different interfaces in the DUT, // -// make sure to pick individual instance names (line with comment "non-ambiguous instance name" below) // -// // -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bind cv32e40p_core obi_checker #( - .ADDR_WIDTH (), // (default 32) number of bits in addr - .DATA_WIDTH (), // (default 32) number of bits in wdata, rdata - .ASSUME (1), // (default 0) switch to create assumes - .MASTER (1), // (default 0) switch to select master/slave side (when switched off, i.e., slave side, important in case of ASSUME) - .ASSERT_ON (), // (default 1) switch to generate assertions, - // useful to switch off (ASSERT_ON=0) together with ASSUME=1 just to constrain a block for Inspect - .COVER_ON (), // (default 1) switch to additionally generate cover statements - .X_CHECKING_ON(), // (default 0) switch to create no-X assertions (to be used in conjunction with x_checking_setup) - .LIVENESS_ON (), // (default 0) switch to create liveness assertions - .MAX_WAIT (`RESTRICT_DMEM_STALL_CYCLES), // (default $) number of cycles for waiting period checks (for creating liveness checks in case LIVENESS_ON=1) - .AUSER_WIDTH (), // (default 32) number of bits in auser (if used) - .WUSER_WIDTH (), // (default 32) number of bits in wuser (if used) - .RUSER_WIDTH (), // (default 32) number of bits in ruser (if used) - .ID_WIDTH (), // (default 32) number of bits in aid, rid (if used) - .MAX_OUTSTANDING_TRANSACTIONS(), // (default 2) maximum number of outstanding transactions in the system - .RESPONSE_PREDICTOR(1) // (default 0) switch to introduce a signal to predict the response at the beginning of the data phase -) obi_dmem_checker ( // non-ambiguous instance name - .clk (clk_i), // required - .reset_n(rst_ni), // required -// Address channel - .req (data_req_o), // required - .gnt (data_gnt_i), // required - .addr (data_addr_o), // required /*ADDRESS*/ - .we (data_we_o), // optional, default is 1'b0 - .be (data_be_o), // optional, default is '1 - .wdata (data_wdata_o), // required /*DATA*/ - .auser (), // optional, default is '0 - .wuser (), // optional, default is '0 - .aid (), // optional, default is '0 -// Response channel - .rvalid (data_rvalid_i), // required - .rready (), // optional, default is 1'b1 - .rdata (data_rdata_i), // required /*DATA*/ - .err (), // optional, default is 1'b0 - .ruser (), // optional, default is '0 - .rid () // optional, default is '0 -); diff --git a/scripts/riscv_isa_formal/common/vips/obi_imem.sv b/scripts/riscv_isa_formal/common/vips/obi_imem.sv deleted file mode 100755 index 126152246..000000000 --- a/scripts/riscv_isa_formal/common/vips/obi_imem.sv +++ /dev/null @@ -1,59 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// // -// General remarks: // -// // -// Just replace below with the name of the module you want to connect the VIP to // -// and add the appropriate parameter values and DUT signals in braces. // -// // -// Leave unused signals (and parameters that just have the default value) simply unconnected // -// because optional signals are pulled up/down appropriately in the checker file. // -// // -// The VIP uses an active LOW reset. // -// If your DUT reset signal, called "rst", is active high, use "!rst" in the instantiation // -// // -// For external interfaces (bus signals are primary inputs/outputs), set parameter ASSUME=1. // -// In that case, make sure MASTER=1 in case the DUT is the bus master (driving the address signal output), // -// or MASTER=0 in case the DUT is the bus slave (address signal is input). // -// // -// In case you instantiate the VIP several times for different interfaces in the DUT, // -// make sure to pick individual instance names (line with comment "non-ambiguous instance name" below) // -// // -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bind cv32e40p_core obi_checker #( - .ADDR_WIDTH (), // (default 32) number of bits in addr - .DATA_WIDTH (), // (default 32) number of bits in wdata, rdata - .ASSUME (1), // (default 0) switch to create assumes - .MASTER (1), // (default 0) switch to select master/slave side (when switched off, i.e., slave side, important in case of ASSUME) - .ASSERT_ON (), // (default 1) switch to generate assertions, - // useful to switch off (ASSERT_ON=0) together with ASSUME=1 just to constrain a block for Inspect - .COVER_ON (), // (default 1) switch to additionally generate cover statements - .X_CHECKING_ON(), // (default 0) switch to create no-X assertions (to be used in conjunction with x_checking_setup) - .LIVENESS_ON (), // (default 0) switch to create liveness assertions - .MAX_WAIT (), // (default $) number of cycles for waiting period checks (for creating liveness checks in case LIVENESS_ON=1) - .AUSER_WIDTH (), // (default 32) number of bits in auser (if used) - .WUSER_WIDTH (), // (default 32) number of bits in wuser (if used) - .RUSER_WIDTH (), // (default 32) number of bits in ruser (if used) - .ID_WIDTH (), // (default 32) number of bits in aid, rid (if used) - .MAX_OUTSTANDING_TRANSACTIONS() // (default 2) maximum number of outstanding transactions in the system -) obi_imem_checker ( // non-ambiguous instance name - .clk (clk_i), // required - .reset_n(rst_ni), // required -// Address channel - .req (instr_req_o), // required - .gnt (instr_gnt_i), // required - .addr (instr_addr_o), // required /*ADDRESS*/ - .we (), // optional, default is 1'b0 - .be (), // optional, default is '1 - .wdata ('0), // required /*DATA*/ - .auser (), // optional, default is '0 - .wuser (), // optional, default is '0 - .aid (), // optional, default is '0 -// Response channel - .rvalid (instr_rvalid_i), // required - .rready (), // optional, default is 1'b1 - .rdata (instr_rdata_i), // required /*DATA*/ - .err (), // optional, default is 1'b0 - .ruser (), // optional, default is '0 - .rid () // optional, default is '0 -); diff --git a/scripts/riscv_isa_formal/launch_command example b/scripts/riscv_isa_formal/launch_command example deleted file mode 100755 index 6b7f3a0a3..000000000 --- a/scripts/riscv_isa_formal/launch_command example +++ /dev/null @@ -1,58 +0,0 @@ -# Setup tool and licenses -#source SourceMe - -set instructions="v1_8_0"; set name_cmd="NAME=${instructions} ; - -set config=XP ; set config_cmd="CONF=${config}" -set config=XPF0 ; set config_cmd="CONF=${config}" -set config=XPF1 ; set config_cmd="CONF=${config}" -set config=XPF2 ; set config_cmd="CONF=${config}" -set config=XPZF0 ; set config_cmd="CONF=${config}" -set config=XPZF1 ; set config_cmd="CONF=${config}" -set config=XPZF2 ; set config_cmd="CONF=${config}" - -set app=PRC ; set app_cmd="APP=${app}" -set app=QTF ; set app_cmd="APP=${app}" -set app=VCI ; set app_cmd="APP=${app}" - -set mode=DEF ; set mode_cmd="MODE=${mode}" -set mode=DPM ; set mode_cmd="MODE=${mode}" -set mode=DPF ; set mode_cmd="MODE=${mode}" - -# Prepare the working directory (common files and design copy) or reuse existing one (no copy) -set prepare="" -set prepare="PREPARE=1" - -set verbose="" -set verbose="VERBOSE=1" - -set timeout="" -set timeout="DBG=1800" - -# Interactive or batch run on local server -set gui="gui" ; set gui_cmd="GUI=1" -set gui="batch" ; set gui_cmd="" - -set my_time = `date '+%Y-%m-%d-%Hh%Mm%Ss'` ; set logname=run_${gui}-${app}-cfg_${config}-mode_${mode}-${instructions}-${my_time}.log ; echo "\n vi ${logname}\n" ; \ -echo "make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all\n" > ${logname} && echo "" >>& ${logname} ; \ -/usr/bin/time make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all >> & ! ${logname} & - -# Interactive or batch run on compute farm server using LSF -set gui="lsf" ; set gui_cmd="" ; set queue="long" -set gui="lsf_gui" ; set gui_cmd="GUI=1" ; set queue="gui -XF" -set gui="lsf_gui" ; set gui_cmd="GUI=1" ; set queue="gui -XF -Is -tty" - -set nb_cpus="1" -set nb_cpus="2" -set nb_cpus="4" -set nb_cpus="8" -set nb_cpus="12" -set nb_cpus="16" -set nb_cpus="24" -set nb_cpus="32" -set nb_cpus="36" -set nb_cpus="48" - -set my_time = `date '+%Y-%m-%d-%Hh%Mm%Ss'` ; set logname=run_${gui}-${app}-cfg_${config}-mode_${mode}-${instructions}-${my_time}.log ; echo "\n vi ${logname}\n" ; \ -echo "make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all\n" > ${logname} && echo "" >>& ${logname} ; \ -bsub -J ${app}-cfg_${config}-mode_${mode}-${instructions} -P cv32e40p -q ${queue} -oo ${logname} -n ${nb_cpus} -R "select[cpuf>=15.0] span[hosts=1] rusage[mem=64G]" make ${gui_cmd} ${app_cmd} ${config_cmd} ${mode_cmd} ${name_cmd} ${verbose} ${prepare} ${timeout} all