From 16ab2638579bd2613b8306d9c059635e4709590c Mon Sep 17 00:00:00 2001 From: Moritz Imfeld <73966745+moimfeld@users.noreply.github.com> Date: Sat, 9 Mar 2024 09:59:19 +0100 Subject: [PATCH 01/11] Fix my author email address (#4) * Fix my author email address Signed-off-by: Moritz Imfeld * Fix wording Signed-off-by: Moritz Imfeld --------- Signed-off-by: Moritz Imfeld --- rtl/cv32e40px_x_disp.sv | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rtl/cv32e40px_x_disp.sv b/rtl/cv32e40px_x_disp.sv index fe1471241..5edae101b 100644 --- a/rtl/cv32e40px_x_disp.sv +++ b/rtl/cv32e40px_x_disp.sv @@ -8,16 +8,16 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -//////////////////////////////////////////////////////////////////////////////// -// Engineer: Moritz Imfeld - moimfeld@student.ethz.ch // -// // -// Design Name: x-interface dispatcher // -// Project Name: cv32e40px // -// Language: SystemVerilog // -// // -// Description: Dispatcher for sending instructions to the x-interface. // -// // -//////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Engineer: Moritz Imfeld - moimfeld@ee.ethz.ch // +// // +// Design Name: x-interface dispatcher // +// Project Name: cv32e40px // +// Language: SystemVerilog // +// // +// Description: Dispatcher for sending instructions to the x-interface. // +// // +///////////////////////////////////////////////////////////////////////////// module cv32e40px_x_disp import cv32e40px_core_v_xif_pkg::*; @@ -243,7 +243,7 @@ module cv32e40px_x_disp end end - // illegal instruction assertion + // illegal instruction assignment always_comb begin x_illegal_insn_o = 1'b0; if (x_issue_valid_o & x_issue_ready_i & ~x_issue_resp_accept_i) begin From 131e506d6c131bcee8e930c429f8638866f96e68 Mon Sep 17 00:00:00 2001 From: Davide Schiavone Date: Fri, 17 May 2024 16:01:49 +0200 Subject: [PATCH 02/11] updates from cv32e40p (#5) --- .github/workflows/check_target_on_pr.yml | 9 +- .gitignore | 8 + CONTRIBUTING.md | 16 + bhv/cv32e40px_instr_trace.svh | 466 ++- bhv/cv32e40px_rvfi.sv | 397 +- bhv/cv32e40px_rvfi_trace.sv | 123 +- bhv/cv32e40px_tb_wrapper.sv | 83 +- bhv/cv32e40px_tracer.sv | 47 +- bhv/include/cv32e40px_rvfi_pkg.sv | 28 +- bhv/include/cv32e40px_tracer_pkg.sv | 30 +- bhv/insn_trace.sv | 111 +- bhv/pipe_freeze_trace.sv | 41 +- .../ImperasDV_diagram_May_2023-reduced.jpg | Bin 0 -> 43870 bytes docs/images/openhw-landscape.png | Bin 0 -> 26149 bytes docs/source/_static/css/custom.css | 6 + docs/source/conf.py | 30 +- docs/source/control_status_registers.rst | 20 +- docs/source/core_versions.rst | 16 +- docs/source/corev_hw_loop.rst | 97 +- 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 | 654 ++-- docs/source/integration.rst | 34 +- docs/source/intro.rst | 20 +- docs/source/load_store_unit.rst | 16 +- docs/source/perf_counters.rst | 16 +- docs/source/pipeline.rst | 19 +- docs/source/preface.rst | 17 + docs/source/register_file.rst | 16 +- docs/source/sleep.rst | 16 +- docs/source/verification.rst | 241 +- rtl/cv32e40px_controller.sv | 42 +- rtl/cv32e40px_core.sv | 18 +- rtl/cv32e40px_cs_registers.sv | 2 +- rtl/cv32e40px_decoder.sv | 86 +- rtl/cv32e40px_ex_stage.sv | 2 +- rtl/cv32e40px_fp_wrapper.sv | 2 +- rtl/cv32e40px_id_stage.sv | 10 +- rtl/cv32e40px_load_store_unit.sv | 32 +- rtl/cv32e40px_register_file_latch.sv | 8 +- rtl/cv32e40px_top.sv | 50 +- .../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 -- scripts/lec/README.md | 51 - scripts/lec/cadence_conformal/check_lec.tcl | 51 - scripts/lec/clone_reference.sh | 22 - scripts/lec/lec.sh | 98 - scripts/lec/synopsys_formality/check_lec.tcl | 22 - 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 | 123 + 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 + scripts/slec/README.md | 79 + scripts/slec/cadence/lec.tcl | 57 + scripts/slec/cadence/sec.tcl | 40 + scripts/slec/run.sh | 245 ++ scripts/slec/siemens/Makefile | 41 + scripts/slec/synopsys/lec.tcl | 61 + 85 files changed, 2832 insertions(+), 6536 deletions(-) create mode 100755 docs/images/ImperasDV_diagram_May_2023-reduced.jpg create mode 100755 docs/images/openhw-landscape.png 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 delete mode 100644 scripts/lec/README.md delete mode 100644 scripts/lec/cadence_conformal/check_lec.tcl delete mode 100755 scripts/lec/clone_reference.sh delete mode 100755 scripts/lec/lec.sh delete mode 100644 scripts/lec/synopsys_formality/check_lec.tcl 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 create mode 100644 scripts/slec/README.md create mode 100644 scripts/slec/cadence/lec.tcl create mode 100644 scripts/slec/cadence/sec.tcl create mode 100755 scripts/slec/run.sh create mode 100755 scripts/slec/siemens/Makefile create mode 100644 scripts/slec/synopsys/lec.tcl diff --git a/.github/workflows/check_target_on_pr.yml b/.github/workflows/check_target_on_pr.yml index bbfd3ebc6..b48f31f33 100644 --- a/.github/workflows/check_target_on_pr.yml +++ b/.github/workflows/check_target_on_pr.yml @@ -1,12 +1,11 @@ name: check_target -on: - pull_request: - types: [opened, reopened, edited] +on: [push, pull_request] + jobs: check_target: runs-on: ubuntu-latest steps: - - if: ${{ (github.event.pull_request.head.ref == 'dev' && github.event.pull_request.base.ref == 'master') || github.event.pull_request.base.ref == 'dev' }} + - if: ${{ (github.event.pull_request.head.ref == 'dev' && github.event.pull_request.base.ref == 'master') || github.event.pull_request.base.ref == 'dev' || github.event.push.ref != 'refs/heads/master'}} run: exit 0 - - if: ${{ github.event.pull_request.base.ref != 'dev' }} + - if: ${{ github.event.pull_request.base.ref != 'dev' || github.event.push.ref == 'refs/heads/master'}} run: exit 1 diff --git a/.gitignore b/.gitignore index ef351b194..6c2cd7917 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,11 @@ TAGS /build /Bender.lock /Bender.local +golden_reference_design +ref_design +golden.src +revised.src +cadence_conformal +synopsys_formality +questa_autocheck +reports diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d15fef3e..60aa591d2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,22 @@ The [OpenHW Work Flow](https://github.com/openhwgroup/core-v-docs/blob/master/ve is required reading. You will find information about the implementation and usage of the CORE-V verification environments in the [Verification Strategy](https://github.com/openhwgroup/core-v-docs/blob/master/verif/Common/OpenHWGroup_CORE-V_Verif_Strategy.pdf). +## Updating Copyright +The files in this repository are open-source artifacts licensed under the terms of the Solderpad license, see [LICENSE](LICENSE). +If you modify a file, a new copyright _may_ be added, but the existing copyright and license header _must not_ be removed or modified. +If your contribution uses a newer version of the existing license, you are encouraged to declare that with a one-liner SPDX header. + +In the example below, a new copyright and updated license are added to an existing copyright and license: +``` +// Copyright 2024 OpenHW Group and +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// 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. +// ...remainder of original license header from ETHZ and UniBo. +``` + ## The Mechanics 1. From GitHub: [fork](https://help.github.com/articles/fork-a-repo/) the [cv32e40p](https://github.com/openhwgroup/cv32e40p) repository 2. Clone repository: `git clone https://github.com/[your_github_username]/cv32e40p` diff --git a/bhv/cv32e40px_instr_trace.svh b/bhv/cv32e40px_instr_trace.svh index a89ed4e45..355bc7382 100644 --- a/bhv/cv32e40px_instr_trace.svh +++ b/bhv/cv32e40px_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; @@ -35,9 +49,13 @@ 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; + string ctx; //Used to add context in the trace log file (Canceled, debug, interrput,....) bit compressed; bit wb_bypass; bit misaligned; @@ -56,10 +74,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 +331,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 %-3s %-36s", simtime, cycles, pc, instr, ctx, str); + end else if (simtime < 1us) begin + 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 %-3s %-36s", simtime, cycles, pc, instr, ctx, str); + end else if (simtime < 100us) begin + 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 %-3s %-36s", simtime, cycles, pc, instr, ctx, str); + end else if (simtime < 10ms) begin + 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 %-3s %-36s", simtime, cycles, pc, instr, ctx, str); + end else begin + insn_str = $sformatf("%t %15d %h %h %-3s %-36s", simtime, cycles, pc, instr, ctx, str); + end foreach (regs_write[i]) begin if (regs_write[i].addr != 0) @@ -330,6 +369,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 @@ -489,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 @@ -587,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}); @@ -637,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 @@ -645,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}); @@ -757,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; diff --git a/bhv/cv32e40px_rvfi.sv b/bhv/cv32e40px_rvfi.sv index 4effb2b86..3675a950d 100644 --- a/bhv/cv32e40px_rvfi.sv +++ b/bhv/cv32e40px_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 "cv32e40px_rvfi_pkg.sv" @@ -27,7 +31,8 @@ module cv32e40px_rvfi import cv32e40px_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 +295,7 @@ module cv32e40px_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, @@ -327,6 +332,10 @@ module cv32e40px_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, @@ -346,6 +355,7 @@ module cv32e40px_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, @@ -366,8 +376,8 @@ module cv32e40px_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, @@ -618,6 +628,13 @@ module cv32e40px_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; @@ -626,6 +643,9 @@ module cv32e40px_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}; + 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" @@ -747,6 +767,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; @@ -801,6 +825,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]; @@ -905,15 +930,50 @@ 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]; + + 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; + 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,36 +1019,134 @@ 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]; - 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; + 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 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]; - 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; + 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 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; + 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 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 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; + endfunction + + 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 + 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_trace(m_trace); + 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_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 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; + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[2]) begin + 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_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); + 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); + 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(idx); + end + if(r_pipe_freeze_trace.csr.mhpmcounter_write_upper[idx]) begin + 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 + + 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(); @@ -1083,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 @@ -1155,7 +1311,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; e_dev_commit_rf_to_ex_3, e_dev_commit_rf_to_ex_4, e_dev_commit_rf_to_ex_5; - event e_if_2_id_1, e_if_2_id_2, e_if_2_id_3; + event e_if_2_id_1, e_if_2_id_2, e_if_2_id_3, e_if_2_id_4; event e_ex_to_wb_1, e_ex_to_wb_2; event e_id_to_ex_1, e_id_to_ex_2; event e_commit_dpc; @@ -1257,6 +1413,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 @@ -1272,35 +1431,47 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_id_done; function void if_to_id(); if (trace_id.m_valid) begin - minstret_to_id(); `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 trace_id.init(trace_if); trace_id.m_trap = ~r_pipe_freeze_trace.minstret; - trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; + trace_id.m_is_illegal = trace_id.m_is_illegal | r_pipe_freeze_trace.is_illegal; + `CSR_FROM_PIPE(id, dpc) s_is_pc_set = 1'b0; s_is_irq_start = 1'b0; trace_if.m_valid = 1'b0; s_id_done = 1'b0; - `CSR_FROM_PIPE(id, dpc) endfunction 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; 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; @@ -1320,6 +1491,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_ex_reg_we_adjusted; //ex_reg_we bit s_rf_we_wb_adjusted; // + bit s_dont_override_mstatus_fs_id; + trace_if = new(); trace_id = new(); trace_ex = new(); @@ -1352,6 +1525,8 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_ex_reg_we_adjusted = 1'b0; s_rf_we_wb_adjusted = 1'b0; + s_dont_override_mstatus_fs_id = 1'b0; + forever begin wait(e_pipe_monitor_ok.triggered); // event triggered #1; @@ -1368,23 +1543,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end if (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID && r_pipe_freeze_trace.ebrk_insn_dec) begin - if (trace_wb.m_valid) begin - send_rvfi(trace_wb); - trace_wb.m_valid = 1'b0; - ->e_send_rvfi_trace_wb_1; - end - if (trace_ex.m_valid) begin - send_rvfi(trace_ex); - trace_ex.m_valid = 1'b0; - ->e_send_rvfi_trace_ex_1; - end if (trace_id.m_valid) begin - - minstret_to_id(); `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 @@ -1418,7 +1581,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 - minstret_to_ex(); + sample_perf_counter_to_trace(trace_ex); trace_ex.m_csr.got_minstret = '1; end @@ -1494,14 +1657,15 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end if (trace_ex.m_valid) begin - - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); + if(trace_ex.m_instret_smaple_trigger == 1) begin //time to sample instret + sample_perf_counter_to_trace(trace_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; @@ -1524,29 +1688,20 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_2; end else begin - if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end 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) begin + 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; if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we trace_ex.m_csr.mstatus_fs_wdata = FS_DIRTY; + end else begin + trace_id.m_csr.mstatus_fs_rdata = trace_ex.m_csr.mstatus_fs_wdata; + s_dont_override_mstatus_fs_id = 1'b1; end ->e_fregs_dirty_3; end @@ -1559,9 +1714,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; ->e_ex_to_wb_1; trace_wb.move_down_pipe(trace_ex); end else begin - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end send_rvfi(trace_ex); ->e_send_rvfi_trace_ex_6; end @@ -1570,31 +1722,41 @@ 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 // If mret, we need to keep the instruction in Id during flush_ex because mstatus update happens at that time - s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || ((r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) && !r_pipe_freeze_trace.mret_insn_dec)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); + s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || ((r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) && !r_pipe_freeze_trace.mret_insn_dec)); //EX_STAGE + 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); + 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; if(trace_id.m_sample_csr_write_in_ex && !csr_is_irq && !s_is_irq_start) begin //First cycle after id_ready, csr write is asserted in this cycle `CSR_FROM_PIPE(id, mstatus) - `CSR_FROM_PIPE(id, mstatus_fs) + if(!s_dont_override_mstatus_fs_id) begin + `CSR_FROM_PIPE(id, mstatus_fs) + end `CSR_FROM_PIPE(id, mepc) `CSR_FROM_PIPE(id, mcause) `CSR_FROM_PIPE(id, dscratch0) `CSR_FROM_PIPE(id, dscratch1) + 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) + + perf_counter_to_trace(trace_id); ->e_csr_in_ex; end @@ -1614,10 +1776,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(id, frm) `CSR_FROM_PIPE(id, fcsr) - if (r_pipe_freeze_trace.csr.we) begin - `CSR_FROM_PIPE(id, dpc) - end - if (r_pipe_freeze_trace.csr.dcsr_we) begin dcsr_to_id(); end @@ -1638,6 +1796,15 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_csr.frm_wmask = '0; trace_ex.m_csr.fcsr_wmask = '0; + if(r_pipe_freeze_trace.ctrl_fsm_cs == XRET_JUMP) begin //xret exit pipeline + tinfo_to_trace(trace_id); + `CSR_FROM_PIPE(id, tdata1) + `CSR_FROM_PIPE(id, tdata2) + send_rvfi(trace_id); + trace_id.m_valid = 1'b0; + s_dont_override_mstatus_fs_id = 1'b0; + end + if (r_pipe_freeze_trace.apu_req && r_pipe_freeze_trace.apu_gnt) begin trace_id.m_is_apu = 1'b1; trace_id.m_apu_req_id = cnt_apu_req; @@ -1647,6 +1814,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_apu_req.set_to_apu(); apu_trace_q.push_back(trace_apu_req); trace_id.m_valid = 1'b0; + s_dont_override_mstatus_fs_id = 1'b0; if(r_pipe_freeze_trace.apu_rvalid && (cnt_apu_req == cnt_apu_resp)) begin//APU return in the same cycle apu_resp(); @@ -1702,6 +1870,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; hwloop_to_id(); trace_ex.move_down_pipe(trace_id); // The instruction moves forward from ID to EX trace_id.m_valid = 1'b0; + s_dont_override_mstatus_fs_id = 1'b0; ->e_id_to_ex_1; end else if (r_pipe_freeze_trace.ex_reg_we && r_pipe_freeze_trace.rf_alu_we_ex) begin @@ -1725,9 +1894,6 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; if (s_new_valid_insn) begin // There is a new valid instruction if (trace_id.m_valid) begin if (trace_ex.m_valid) begin - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end if (trace_wb.m_valid) begin send_rvfi(trace_ex); ->e_send_rvfi_trace_ex_4; @@ -1769,6 +1935,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; hwloop_to_id(); trace_ex.move_down_pipe(trace_id); trace_id.m_valid = 1'b0; + s_dont_override_mstatus_fs_id = 1'b0; ->e_id_to_ex_2; end if_to_id(); @@ -1786,18 +1953,24 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end //IF_STAGE - if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready) begin + if(trace_if.m_valid) begin + if(r_pipe_freeze_trace.is_illegal && r_pipe_freeze_trace.is_decoding) begin + trace_if.m_is_illegal = 1'b1; + end + end + + if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready && r_pipe_freeze_trace.instr_valid_if) begin if (trace_if.m_valid) begin if (r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin if_to_id(); trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; ->e_if_2_id_2; - end else if (r_pipe_freeze_trace.is_illegal) begin + end else if (trace_if.m_is_illegal) begin if_to_id(); - trace_id.m_is_illegal = 1'b1; ->e_if_2_id_3; end else if (r_pipe_freeze_trace.ecall_insn_dec) begin if_to_id(); + ->e_if_2_id_4; end end diff --git a/bhv/cv32e40px_rvfi_trace.sv b/bhv/cv32e40px_rvfi_trace.sv index bfb025796..bdbe6127d 100644 --- a/bhv/cv32e40px_rvfi_trace.sv +++ b/bhv/cv32e40px_rvfi_trace.sv @@ -1,26 +1,31 @@ -// 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 cv32e40px_rvfi_trace import cv32e40px_pkg::*; + import cv32e40px_rvfi_pkg::*; #( parameter FPU = 0, parameter ZFINX = 0 @@ -32,9 +37,14 @@ module cv32e40px_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 rvfi_trap_t rvfi_trap, input logic [ 4:0] rvfi_rd_addr [1:0], input logic [31:0] rvfi_rd_wdata[1:0], @@ -42,6 +52,7 @@ module cv32e40px_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 +72,8 @@ module cv32e40px_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 +85,7 @@ module cv32e40px_rvfi_trace integer f; //file pointer string fn; - integer cycles; + // integer cycles; string info_tag; logic is_compressed; @@ -125,7 +136,13 @@ module cv32e40px_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 +151,69 @@ module cv32e40px_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; - cv32e40px_compressed_decoder #( - .FPU(FPU) - ) rvfi_trace_decompress_i ( - .instr_i(rvfi_insn), - .instr_o(decomp_insn), - .is_compressed_o(is_compressed) - ); - `include "cv32e40px_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.ctx = (rvfi_trap.trap) ? "(C)" : ""; + 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 +231,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 +241,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 +253,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 Ctx Decoded instruction Register and memory contents Stop cycle Stop time\n"); end diff --git a/bhv/cv32e40px_tb_wrapper.sv b/bhv/cv32e40px_tb_wrapper.sv index d4aa94dcd..c14b131ba 100644 --- a/bhv/cv32e40px_tb_wrapper.sv +++ b/bhv/cv32e40px_tb_wrapper.sv @@ -1,45 +1,49 @@ -// 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 cv32e40px, containing cv32e40px_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 cv32e40px_top, tracer and and rvfi_tracer // +// // +//////////////////////////////////////////////////////////////////////////////////// -`ifdef CV32E40P_ASSERT_ON +`ifdef CV32E40PX_ASSERT_ON `include "cv32e40px_prefetch_controller_sva.sv" `endif -`ifdef CV32E40P_CORE_LOG +`ifdef CV32E40PX_CORE_LOG `include "cv32e40px_core_log.sv" `endif -`ifdef CV32E40P_APU_TRACE +`ifdef CV32E40PX_APU_TRACE `include "cv32e40px_apu_tracer.sv" `endif -`ifdef CV32E40P_TRACE_EXECUTION +`ifdef CV32E40PX_TRACE_EXECUTION `include "cv32e40px_tracer.sv" `endif -`ifdef CV32E40P_RVFI +`ifdef CV32E40PX_RVFI `include "cv32e40px_rvfi.sv" `endif -`ifdef CV32E40P_RVFI_TRACE_EXECUTION +`ifdef CV32E40PX_RVFI_TRACE_EXECUTION `include "cv32e40px_rvfi_trace.sv" `endif @@ -101,7 +105,7 @@ module cv32e40px_tb_wrapper output logic core_sleep_o ); -`ifdef CV32E40P_ASSERT_ON +`ifdef CV32E40PX_ASSERT_ON // RTL Assertions bind cv32e40px_prefetch_controller: @@ -114,9 +118,9 @@ module cv32e40px_tb_wrapper .FIFO_ADDR_DEPTH(FIFO_ADDR_DEPTH) ) prefetch_controller_sva (.*); -`endif // CV32E40P_ASSERT_ON +`endif // CV32E40PX_ASSERT_ON -`ifdef CV32E40P_CORE_LOG +`ifdef CV32E40PX_CORE_LOG cv32e40px_core_log #( .COREV_PULP (COREV_PULP), .COREV_CLUSTER (COREV_CLUSTER), @@ -130,9 +134,9 @@ module cv32e40px_tb_wrapper .hart_id_i (cv32e40px_top_i.core_i.hart_id_i), .pc_id_i (cv32e40px_top_i.core_i.pc_id) ); -`endif // CV32E40P_CORE_LOG +`endif // CV32E40PX_CORE_LOG -`ifdef CV32E40P_APU_TRACE +`ifdef CV32E40PX_APU_TRACE cv32e40px_apu_tracer apu_tracer_i ( .clk_i (cv32e40px_top_i.core_i.rst_ni), .rst_n (cv32e40px_top_i.core_i.clk_i), @@ -143,7 +147,7 @@ module cv32e40px_tb_wrapper ); `endif -`ifdef CV32E40P_TRACE_EXECUTION +`ifdef CV32E40PX_TRACE_EXECUTION cv32e40px_tracer #( .FPU (FPU), .ZFINX(ZFINX) @@ -210,11 +214,11 @@ module cv32e40px_tb_wrapper .apu_en_i (cv32e40px_top_i.apu_req), .apu_singlecycle_i(cv32e40px_top_i.core_i.ex_stage_i.apu_singlecycle), .apu_multicycle_i (cv32e40px_top_i.core_i.ex_stage_i.apu_multicycle), - .apu_rvalid_i (cv32e40px_top_i.apu_rvalid) + .apu_rvalid_i (cv32e40px_top_i.core_i.ex_stage_i.apu_valid) ); `endif -`ifdef CV32E40P_RVFI +`ifdef CV32E40PX_RVFI logic [1:0][31:0] hwlp_start_q; logic [1:0][31:0] hwlp_end_q; logic [1:0][31:0] hwlp_counter_q; @@ -234,8 +238,9 @@ module cv32e40px_tb_wrapper endgenerate cv32e40px_rvfi #( - .FPU (FPU), - .ZFINX(ZFINX) + .FPU(FPU), + .ZFINX(ZFINX), + .NUM_MHPMCOUNTERS(NUM_MHPMCOUNTERS) ) rvfi_i ( .clk_i (cv32e40px_top_i.core_i.clk_i), .rst_ni(cv32e40px_top_i.core_i.rst_ni), @@ -399,6 +404,9 @@ module cv32e40px_tb_wrapper .csr_mcountinhibit_n_i (cv32e40px_top_i.core_i.cs_registers_i.mcountinhibit_n), .csr_mcountinhibit_we_i(cv32e40px_top_i.core_i.cs_registers_i.mcountinhibit_we), + .csr_mhpmevent_n_i(cv32e40px_top_i.core_i.cs_registers_i.mhpmevent_n), + .csr_mhpmevent_q_i(cv32e40px_top_i.core_i.cs_registers_i.mhpmevent_q), + .csr_mhpmevent_we_i(cv32e40px_top_i.core_i.cs_registers_i.mhpmevent_we), .csr_mscratch_q_i(cv32e40px_top_i.core_i.cs_registers_i.mscratch_q), .csr_mscratch_n_i(cv32e40px_top_i.core_i.cs_registers_i.mscratch_n), .csr_mepc_q_i(cv32e40px_top_i.core_i.cs_registers_i.mepc_q), @@ -441,8 +449,7 @@ module cv32e40px_tb_wrapper ); `endif - -`ifdef CV32E40P_RVFI_TRACE_EXECUTION +`ifdef CV32E40PX_RVFI_TRACE_EXECUTION bind cv32e40px_rvfi: rvfi_i cv32e40px_rvfi_trace #( .FPU (FPU), .ZFINX(ZFINX) @@ -455,22 +462,38 @@ module cv32e40px_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_trap(rvfi_trap), .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), .rvfi_rs1_rdata(rvfi_rs1_rdata), .rvfi_rs2_rdata(rvfi_rs2_rdata), + .rvfi_rs3_rdata(rvfi_rs3_rdata), .rvfi_frs1_addr(rvfi_frs1_addr), .rvfi_frs2_addr(rvfi_frs2_addr), + .rvfi_frs3_addr(rvfi_frs3_addr), .rvfi_frs1_rvalid(rvfi_frs1_rvalid), .rvfi_frs2_rvalid(rvfi_frs2_rvalid), + .rvfi_frs3_rvalid(rvfi_frs3_rvalid), .rvfi_frs1_rdata(rvfi_frs1_rdata), - .rvfi_frs2_rdata(rvfi_frs2_rdata) + .rvfi_frs2_rdata(rvfi_frs2_rdata), + .rvfi_frs3_rdata(rvfi_frs3_rdata), + .rvfi_mem_addr(rvfi_mem_addr), + .rvfi_mem_rmask(rvfi_mem_rmask), + .rvfi_mem_wmask(rvfi_mem_wmask), + .rvfi_mem_rdata(rvfi_mem_rdata), + .rvfi_mem_wdata(rvfi_mem_wdata) ); `endif // Instantiate the Core and the optinal FPU diff --git a/bhv/cv32e40px_tracer.sv b/bhv/cv32e40px_tracer.sv index c0c13315b..9254cceac 100644 --- a/bhv/cv32e40px_tracer.sv +++ b/bhv/cv32e40px_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 @@ -183,7 +185,8 @@ module cv32e40px_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 Ctx Decoded instruction Register and memory contents\n"); end //initial begin diff --git a/bhv/include/cv32e40px_rvfi_pkg.sv b/bhv/include/cv32e40px_rvfi_pkg.sv index 9a131a68b..5a43daf64 100644 --- a/bhv/include/cv32e40px_rvfi_pkg.sv +++ b/bhv/include/cv32e40px_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 cv32e40px_rvfi_pkg; import cv32e40px_pkg::*; diff --git a/bhv/include/cv32e40px_tracer_pkg.sv b/bhv/include/cv32e40px_tracer_pkg.sv index 90ee5be9d..2046dd740 100644 --- a/bhv/include/cv32e40px_tracer_pkg.sv +++ b/bhv/include/cv32e40px_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 cv32e40px_tracer_pkg; import cv32e40px_pkg::*; diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index 3fe7c1848..8cdc06d9e 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; \ @@ -23,6 +44,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; @@ -65,14 +90,15 @@ bit m_move_down_pipe; int m_instret_cnt; + int m_instret_smaple_trigger; //We need to sample minstret from csr 2 cycle after id is doen bit m_sample_csr_write_in_ex; 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; @@ -102,9 +128,28 @@ `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; + + 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 @@ -148,6 +193,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; @@ -173,6 +222,7 @@ this.m_frm_we_non_apu = 1'b0; this.m_fcsr_we_non_apu = 1'b0; this.m_instret_cnt = 0; + this.m_instret_smaple_trigger = 0; this.m_sample_csr_write_in_ex = 1'b1; endfunction @@ -613,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"; @@ -847,7 +897,18 @@ `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; + this.m_csr.mhpmevent_we = '0; + this.m_csr.mhpmevent_wmask = '0; `INIT_CSR(mip) `INIT_CSR(tdata1) `INIT_CSR(tdata2) @@ -875,6 +936,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 @@ -896,6 +961,7 @@ this.m_got_regs_write = 1'b0; this.m_move_down_pipe = 1'b0; this.m_instret_cnt = 0; + this.m_instret_smaple_trigger = 0; this.m_sample_csr_write_in_ex = 1'b1; this.m_rd_addr[0] = '0; this.m_rd_addr[1] = '0; @@ -951,6 +1017,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; @@ -970,6 +1040,7 @@ this.m_is_illegal = m_source.m_is_illegal; this.m_is_irq = m_source.m_is_irq; this.m_instret_cnt = m_source.m_instret_cnt; + this.m_instret_smaple_trigger = m_source.m_instret_smaple_trigger; this.m_sample_csr_write_in_ex = m_source.m_sample_csr_write_in_ex; this.m_rs1_addr = m_source.m_rs1_addr; this.m_rs2_addr = m_source.m_rs2_addr; @@ -1000,8 +1071,26 @@ `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; + 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 88d65d0b0..39a16fa62 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; @@ -349,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) @@ -366,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; @@ -376,6 +382,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 /* @@ -573,7 +583,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; 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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 literal 0 HcmV?d00001 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 +} diff --git a/docs/source/conf.py b/docs/source/conf.py index dbb7b0203..3e24854b3 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 # ############################################################################### # @@ -38,13 +38,13 @@ # -- 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 version = u'' # The full version, including alpha/beta/rc tags -release = u'' +release = u'v1.8.0' # -- General configuration --------------------------------------------------- @@ -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 ------------------------------------------------- @@ -111,8 +114,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, @@ -143,6 +148,8 @@ # -- Options for LaTeX output ------------------------------------------------ +latex_logo = '../images/openhw-landscape.png' + latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # @@ -159,6 +166,7 @@ # Latex figure (float) alignment # # 'figure_align': 'htbp', + 'figure_align': 'H', } # Grouping the document tree into LaTeX files. List of tuples 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 6d0cbf64d..6653ce1f5 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: @@ -51,21 +51,24 @@ 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. - End Address must be strictly greater than Start Address. +- HWLoop #0 (resp. #1) start and end addresses **must not be modified** if HWLoop #0 (resp. #1) count is different than 0. + - End address of an HWLoop must point to the instruction just after the last one of the HWLoop body. - 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. - Remark: To avoid to add 2 NOPs in case nothing can be put there by the compiler, lpcount setting of the the inner loop could be moved after it - without forgetting to add the same in the preamble before the outer loop start address. +- 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). @@ -103,58 +106,60 @@ Below an assembly code example of a nested HWLoop that computes a matrix additio asm volatile ( "add %[i],x0, x0;" "add %[j],x0, x0;" - "cv.count 1, %[N];" ".balign 4;" - "cv.endi 1, endO;" - "cv.starti 1, startO;" + "cv.starti 1, start1;" + "cv.endi 1, end1;" + "cv.count 1, %[N];" "any instructions here" ".balign 4;" - "cv.endi 0, endZ;" - "cv.starti 0, startZ;" - "cv.count 0, %[N];" + "cv.starti 0, start0;" + "cv.endi 0, end0;" "any instructions here" ".balign 4;" ".option norvc;" - "startO:;" - " startZ:;" + "start1:;" + " cv.count 0, %[N];" + " start0:;" " addi %[i], %[i], 1;" " addi %[i], %[i], 1;" " addi %[i], %[i], 1;" - " endZ:;" - " cv.count 0, %[N];" + " end0:;" + " addi %[j], %[j], 2;" " addi %[j], %[j], 2;" - "endO:;" + "end1:;" : [i] "+r" (i), [j] "+r" (j) : [N] "r" (10) ); +As HWLoop feature is enabled as soon as lpcountX > 0, lpstartX and lpendX **must** be programmed **before** lpcountX to avoid unexpected behavior. +For HWLoop where body contains up to 30 instructions, it is always better to use cv.setup* instructions which are updating all 3 HWLoop CSRs in the same cycle. At the beginning of the HWLoop, the registers %[i] and %[j] are 0. -The innermost loop, from startZ to (endZ - 4), adds to %[i] three times 1 and -it is executed 10x10 times. Whereas the outermost loop, from startO to (endO - 4), -executes 10 times the innermost loop and adds 2 to the register %[j]. -At the end of the loop, the register %[i] contains 300 and the register %[j] contains 20. +The innermost loop, from start0 to (end0 - 4), adds to %[i] three times 1 and +it is executed 10x10 times. Whereas the outermost loop, from start1 to (end1 - 4), +executes 10 times the innermost loop and adds two times 2 to the register %[j]. +At the end of the loop, the register %[i] contains 300 and the register %[j] contains 40. .. _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: -1. if MEPC = lpend0 - 4 and lpcount0 > 1 then MPEC should be set to lpstart0 and lpcount0 should be decremented by 1, -2. else if MEPC = lpend0 - 4 and lpcount0 = 1 then MPEC should be incremented by 4 and lpcount0 should be decremented by 1, -3. else if MEPC = lpend1 - 4 and lpcount1 > 1 then MPEC should be set to lpstart1 and lpcount1 should be decremented by 1, -4. else if MEPC = lpend1 - 4 and lpcount1 = 1 then MPEC should be incremented by 4 and lpcount1 should be decremented by 1, -5. else if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4) then MPEC should be incremented by 4, -6. else if instruction at MEPC location is either ecall or ebreak then MPEC should be incremented by 4, -7. else if instruction at MEPC location location is c.ebreak then MPEC should be incremented by 2. +1. if MEPC = lpend0 - 4 and lpcount0 > 1 then MEPC should be set to lpstart0 and lpcount0 should be decremented by 1, +2. else if MEPC = lpend0 - 4 and lpcount0 = 1 then MEPC should be incremented by 4 and lpcount0 should be decremented by 1, +3. else if MEPC = lpend1 - 4 and lpcount1 > 1 then MEPC should be set to lpstart1 and lpcount1 should be decremented by 1, +4. else if MEPC = lpend1 - 4 and lpcount1 = 1 then MEPC should be incremented by 4 and lpcount1 should be decremented by 1, +5. else if (lpstart0 <= MEPC < lpend0 - 4) or (lpstart1 <= MEPC < lpend1 - 4) then MEPC should be incremented by 4, +6. else if instruction at MEPC location is either ecall or ebreak then MEPC should be incremented by 4, +7. else if instruction at MEPC location location is c.ebreak then MEPC should be incremented by 2. The 2 last cases are the standard ones when ebreak/ecall are not inside an HWLopp. @@ -162,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 ------------------------------------- @@ -174,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. 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 c7becb7f3..03dca5191 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: @@ -783,15 +783,19 @@ 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 if rs1 >=rs2', rD = rs2', | | | | | | else rD = rs1 | +-------------------------------------------+------------------------------------------------------------------------+ - | **cv.clipur rD, rs1, rs2** | if rs1 <= 0, rD = 0, | + | **cv.clipur rD, rs1, rs2** | rs2' = rs2 & 0x7FFFFFFF | + | | | + | | if rs1 <= 0, rD = 0, | | | | - | | else if rs1 >= rs2, rD = rs2, | + | | else if rs1 >= rs2', rD = rs2', | | | | | | else rD = rs1 | +-------------------------------------------+------------------------------------------------------------------------+ @@ -1015,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 @@ -1042,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 @@ -1095,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 @@ -1123,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 @@ -1175,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 @@ -1191,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 @@ -1218,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 @@ -1245,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 @@ -1380,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] | | | | @@ -1389,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] | | | | @@ -1398,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] | +------------------------------------------------------------+------------------------------------------------------------------+ @@ -1421,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 @@ -1527,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] | | | | @@ -1606,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 diff --git a/docs/source/integration.rst b/docs/source/integration.rst index d2fa3eac8..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: @@ -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\*"]]”. 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 971a0a9e1..8b5501e37 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: @@ -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) @@ -150,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 | | | 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: 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. diff --git a/rtl/cv32e40px_controller.sv b/rtl/cv32e40px_controller.sv index a3e3bac9c..e9807a381 100644 --- a/rtl/cv32e40px_controller.sv +++ b/rtl/cv32e40px_controller.sv @@ -597,7 +597,17 @@ module cv32e40px_controller import cv32e40px_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 cv32e40px_controller import cv32e40px_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 cv32e40px_controller import cv32e40px_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 cv32e40px_controller import cv32e40px_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 @@ -1561,7 +1575,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); diff --git a/rtl/cv32e40px_core.sv b/rtl/cv32e40px_core.sv index 25aa6cc98..91c4eb8d5 100644 --- a/rtl/cv32e40px_core.sv +++ b/rtl/cv32e40px_core.sv @@ -72,7 +72,8 @@ module cv32e40px_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, @@ -199,7 +200,6 @@ module cv32e40px_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 @@ -445,7 +445,7 @@ module cv32e40px_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), @@ -690,7 +690,7 @@ module cv32e40px_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), // CORE-V-XIF // Compressed Interface @@ -909,9 +909,9 @@ module cv32e40px_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), @@ -1160,9 +1160,9 @@ module cv32e40px_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/cv32e40px_cs_registers.sv b/rtl/cv32e40px_cs_registers.sv index f24b3bf9b..530057250 100644 --- a/rtl/cv32e40px_cs_registers.sv +++ b/rtl/cv32e40px_cs_registers.sv @@ -509,7 +509,7 @@ module cv32e40px_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/cv32e40px_decoder.sv b/rtl/cv32e40px_decoder.sv index 3d55fdbc8..c8e11cc3b 100644 --- a/rtl/cv32e40px_decoder.sv +++ b/rtl/cv32e40px_decoder.sv @@ -1057,7 +1057,6 @@ module cv32e40px_decoder 5'b00000: begin fpu_op = cv32e40px_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 cv32e40px_decoder fpu_op = cv32e40px_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 cv32e40px_decoder regb_used_o = 1'b0; fpu_op = cv32e40px_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 cv32e40px_decoder fpu_op = cv32e40px_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 cv32e40px_decoder fpu_op = cv32e40px_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 @@ -1323,20 +1318,20 @@ module cv32e40px_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 != cv32e40px_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; @@ -1364,6 +1359,7 @@ module cv32e40px_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 @@ -1425,25 +1421,21 @@ module cv32e40px_decoder unique case (instr_rdata_i[6:0]) // fmadd.fmt - FP Fused multiply-add OPCODE_OP_FMADD : begin - fpu_op = cv32e40px_fpu_pkg::FMADD; - apu_op_o = 2'b00; + fpu_op = cv32e40px_fpu_pkg::FMADD; end // fmsub.fmt - FP Fused multiply-subtract OPCODE_OP_FMSUB : begin - fpu_op = cv32e40px_fpu_pkg::FMADD; - fpu_op_mod = 1'b1; - apu_op_o = 2'b01; + fpu_op = cv32e40px_fpu_pkg::FMADD; + fpu_op_mod = 1'b1; end // fnmsub.fmt - FP Negated fused multiply-subtract OPCODE_OP_FNMSUB : begin - fpu_op = cv32e40px_fpu_pkg::FNMSUB; - apu_op_o = 2'b10; + fpu_op = cv32e40px_fpu_pkg::FNMSUB; end // fnmadd.fmt - FP Negated fused multiply-add OPCODE_OP_FNMADD : begin - fpu_op = cv32e40px_fpu_pkg::FNMSUB; - fpu_op_mod = 1'b1; - apu_op_o = 2'b11; + fpu_op = cv32e40px_fpu_pkg::FNMSUB; + fpu_op_mod = 1'b1; end default : ; endcase @@ -1459,19 +1451,19 @@ module cv32e40px_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 != cv32e40px_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 @@ -1493,6 +1485,7 @@ module cv32e40px_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; @@ -1900,15 +1893,14 @@ module cv32e40px_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 +2077,6 @@ module cv32e40px_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 +2084,12 @@ module cv32e40px_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 +2117,6 @@ module cv32e40px_decoder mult_operator_o = MUL_I; end end - default: illegal_insn_o = 1'b1; endcase end else begin illegal_insn_o = 1'b1; @@ -2267,6 +2257,11 @@ module cv32e40px_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; @@ -2278,6 +2273,11 @@ module cv32e40px_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; @@ -2289,6 +2289,11 @@ module cv32e40px_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; @@ -2425,6 +2430,11 @@ module cv32e40px_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; @@ -2439,6 +2449,10 @@ module cv32e40px_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, diff --git a/rtl/cv32e40px_ex_stage.sv b/rtl/cv32e40px_ex_stage.sv index 3beaf0227..028761083 100644 --- a/rtl/cv32e40px_ex_stage.sv +++ b/rtl/cv32e40px_ex_stage.sv @@ -266,7 +266,7 @@ module cv32e40px_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 diff --git a/rtl/cv32e40px_fp_wrapper.sv b/rtl/cv32e40px_fp_wrapper.sv index 54add99df..126a1f449 100644 --- a/rtl/cv32e40px_fp_wrapper.sv +++ b/rtl/cv32e40px_fp_wrapper.sv @@ -14,7 +14,7 @@ module cv32e40px_fp_wrapper import cv32e40px_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/cv32e40px_id_stage.sv b/rtl/cv32e40px_id_stage.sv index 6e996c32f..9f1f668b5 100644 --- a/rtl/cv32e40px_id_stage.sv +++ b/rtl/cv32e40px_id_stage.sv @@ -1772,9 +1772,13 @@ module cv32e40px_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_operand_b_ex_o <= alu_operand_b; + 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 + 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; diff --git a/rtl/cv32e40px_load_store_unit.sv b/rtl/cv32e40px_load_store_unit.sv index 674da6647..92194ccdd 100644 --- a/rtl/cv32e40px_load_store_unit.sv +++ b/rtl/cv32e40px_load_store_unit.sv @@ -121,18 +121,18 @@ module cv32e40px_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 cv32e40px_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 cv32e40px_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 diff --git a/rtl/cv32e40px_register_file_latch.sv b/rtl/cv32e40px_register_file_latch.sv index 217150c04..63a23228c 100644 --- a/rtl/cv32e40px_register_file_latch.sv +++ b/rtl/cv32e40px_register_file_latch.sv @@ -203,8 +203,8 @@ module cv32e40px_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 @@ -213,9 +213,9 @@ module cv32e40px_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 diff --git a/rtl/cv32e40px_top.sv b/rtl/cv32e40px_top.sv index ad3dc9868..03b996266 100644 --- a/rtl/cv32e40px_top.sv +++ b/rtl/cv32e40px_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 cv32e40px_top import cv32e40px_core_v_xif_pkg::*; @@ -105,7 +117,7 @@ module cv32e40px_top import cv32e40px_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; @@ -117,6 +129,8 @@ module cv32e40px_top logic [ 31:0] apu_rdata; logic [APU_NUSFLAGS_CPU-1:0] apu_rflags; + logic apu_clk_en, apu_clk; + // Instantiate the Core cv32e40px_core #( .COREV_X_IF (COREV_X_IF), @@ -155,6 +169,7 @@ module cv32e40px_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), @@ -211,12 +226,15 @@ module cv32e40px_top generate if (FPU) begin : fpu_gen + + assign apu_clk_en = apu_req | apu_busy; + // FPU clock gate cv32e40px_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 @@ -224,7 +242,7 @@ module cv32e40px_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), 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 diff --git a/scripts/lec/README.md b/scripts/lec/README.md deleted file mode 100644 index 51befbc2f..000000000 --- a/scripts/lec/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Logic Equivalence Checking (LEC) - -This folder contains a LEC script that runs on both -Synopsys Formality and Cadence Design Systems Conformal. - -This script allows to catch non-logical equivalent changes on the RTL which are forbidden -on the verified paramter set. - -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. - -### Running the script - -From a bash shell, please execute: - -``` -./lec.sh synopsys -``` - or - -``` -./lec.sh cadence -``` - -to use one of the tools. synopsys is used by default if no tool is specified,. - -Use `sh ./les.sh {synopsys, cadence}` if you run it from a tcsh shell. - -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. - -``` -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. - -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/lec/cadence_conformal/check_lec.tcl b/scripts/lec/cadence_conformal/check_lec.tcl deleted file mode 100644 index 2ff64380c..000000000 --- a/scripts/lec/cadence_conformal/check_lec.tcl +++ /dev/null @@ -1,51 +0,0 @@ -// 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. - -read_design -SV -replace -noelaborate -golden -File ../golden.src - -elaborate_design -golden - -read_design -SV -replace -noelaborate -revised -File ../revised.src - -elaborate_design -revised - -report_design_data > ./reports/report_design.log - -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 - -// core_v_xif signals -add ignored outputs x_compressed_valid_o -Both -add ignored outputs x_compressed_req_o* -Both -add ignored outputs x_issue_valid_o -Both -add ignored outputs x_issue_req_o* -Both -add ignored outputs x_commit_valid_o -Both -add ignored outputs x_commit_o* -Both -add ignored outputs x_mem_ready_o -Both -add ignored outputs x_mem_resp_o* -Both -add ignored outputs x_mem_result_valid_o -Both -add ignored outputs x_mem_result_o* -Both -add ignored outputs x_result_ready_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 - -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 - -exit 0 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/lec.sh b/scripts/lec/lec.sh deleted file mode 100755 index 5e9f7387f..000000000 --- a/scripts/lec/lec.sh +++ /dev/null @@ -1,98 +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 [[ -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" -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 - fi -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 -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" - 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" - fi - cd ../ -fi - -if [[ $NonLec == "0" ]]; then - echo "The DESIGN IS LOGICALLY EQUIVALENT" -else - NonLec="-1" - echo "The DESIGN IS NOT LOGICALLY EQUIVALENT" -fi - -echo "$0 returns $NonLec" - -exit $NonLec diff --git a/scripts/lec/synopsys_formality/check_lec.tcl b/scripts/lec/synopsys_formality/check_lec.tcl deleted file mode 100644 index 612aba257..000000000 --- a/scripts/lec/synopsys_formality/check_lec.tcl +++ /dev/null @@ -1,22 +0,0 @@ -set synopsys_auto_setup true - -read_sverilog -container r -libname WORK -12 -f ../golden.src -set_top r:/WORK/cv32e40p_core - -read_sverilog -container i -libname WORK -12 -f ../revised.src -set_top i:/WORK/cv32e40p_core - -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* - -verify > ./reports/verify.rpt - -report_aborted_points > ./reports/aborted_points.rpt -report_failing_points > ./reports/failing_points.rpt -analyze_points -failing > ./reports/analyze.rpt - -exit 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..135ee4fa9 --- /dev/null +++ b/scripts/lint/cv32e40p_wrapper.sv @@ -0,0 +1,123 @@ +// 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. +// 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.1 + +// 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, + input logic scan_cg_en_i, + + 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, + 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 diff --git a/scripts/slec/README.md b/scripts/slec/README.md new file mode 100644 index 000000000..6249563cc --- /dev/null +++ b/scripts/slec/README.md @@ -0,0 +1,79 @@ +# Sequential Logic Equivalence Checking (SLEC) + +This folder contains a SLEC script that runs: + +- 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` , +Cadence Design Systems Conformal `20.20` and Siemens SLEC App `2023.4`. + +### Running the script + +From a bash shell using LEC, please execute: + +``` +./run.sh -t synopsys -p lec +``` + or + + ``` + ./run.sh -t cadence -p lec + ``` + + From a bash shell to use SEC, please execute: + ``` + ./run.sh -t siemens -p sec + ``` + + 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. + + 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 + + ``` + 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 new file mode 100644 index 000000000..e62046b73 --- /dev/null +++ b/scripts/slec/cadence/lec.tcl @@ -0,0 +1,57 @@ +// 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) +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 -parameter FPU_ADDMUL_LAT $latency_cfg -parameter FPU_OTHERS_LAT $latency_cfg" +} + +read_design -SV09 -replace -noelaborate -golden -File ./golden.src + +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 -parameter FPU_ADDMUL_LAT $latency_cfg -parameter FPU_OTHERS_LAT $latency_cfg + +report_design_data + +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 + add_ignored_outputs apu_busy_o -Revised +} + +write_hier_compare_dofile hier_compare_r2r.do -constraint -replace + +run_hier_compare hier_compare_r2r.do -ROOT_module $top_module $top_module + +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 new file mode 100755 index 000000000..01bb1b126 --- /dev/null +++ b/scripts/slec/run.sh @@ -0,0 +1,245 @@ +#!/bin/bash + +# 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. + +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}] [-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. + usage + exit 1 +} + +not_implemented() { + echo "$1 does not have yet $2 implemented" + exit 1 +} + +print_log() { + echo "[LOG] $1" +} + +VERSION=v1 +PULP_CFG=0 +FPU_CFG=0 +ZFINX_CFG=0 +LATENCY_CFG=0 + +while getopts "t:p:v:x:f:z:l:" flag +do + case "${flag}" in + t) + target_tool=${OPTARG} + ;; + p) + target_process=${OPTARG} + ;; + v) + VERSION=${OPTARG} + ;; + x) + PULP_CFG=${OPTARG} + ;; + f) + FPU_CFG=${OPTARG} + ;; + z) + ZFINX_CFG=${OPTARG} + ;; + l) + LATENCY_CFG=${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 [[ "${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 [[ ("${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 +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} +export latency_cfg=${LATENCY_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 + 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 ../..) + +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" + 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." + \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" +fi + +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 !~ "tb_wrapper" && $0 !~ "cv32e40p_wrapper") print $0 }' ${GOLDEN_DIR}/$FLIST | sed 's|${DESIGN_RTL_DIR}|'"${GOLDEN_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} +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/${target_tool}/$(date +%Y-%m-%d-%Hh%Mm%Ss) + +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 + +elif [[ "${target_tool}" == "synopsys" ]]; then + + if [[ "${target_process}" == "lec" ]]; then + 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} + 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 + +fi + +if [[ ! -f ${output_log} || ! -f ${summary_log} ]]; then + print_log "Something went wrong during the process" + exit 1 +fi + +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 ${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 new file mode 100644 index 000000000..7d17722c0 --- /dev/null +++ b/scripts/slec/synopsys/lec.tcl @@ -0,0 +1,61 @@ +# 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 latency_cfg $::env(latency_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, FPU_ADDMUL_LAT = $latency_cfg, FPU_OTHERS_LAT = $latency_cfg" + set core_ref_name $core_impl_name +} + +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, FPU_ADDMUL_LAT = $latency_cfg, FPU_OTHERS_LAT = $latency_cfg" + +match > $summary_log.match.rpt + +if {"$top_module" == "cv32e40p_core"} { + 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* + set_dont_verify_point -type port i:/WORK/$core_impl_name/apu_busy_o +} + +verify > $summary_log + +report_aborted_points > $summary_log.aborted_points.rpt +report_failing_points > $summary_log.failing_points.rpt + +exit From 15b9dd6077513342cf44e6853a5fc33098f2e73b Mon Sep 17 00:00:00 2001 From: Davide Schiavone Date: Mon, 27 May 2024 15:22:14 +0200 Subject: [PATCH 03/11] fix combinatorial loop in x illegal (#6) --- rtl/cv32e40px_x_disp.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtl/cv32e40px_x_disp.sv b/rtl/cv32e40px_x_disp.sv index 5edae101b..dc8907979 100644 --- a/rtl/cv32e40px_x_disp.sv +++ b/rtl/cv32e40px_x_disp.sv @@ -107,6 +107,7 @@ module cv32e40px_x_disp logic x_if_not_ready; logic x_if_memory_instr; logic illegal_forwarding_prevention; + logic x_issue_illegal; // issue interface assign x_issue_valid_o = x_illegal_insn_dec_i & ~branch_or_jump_i & ~instr_offloaded_q & instr_valid_i & ~illegal_forwarding_prevention; @@ -244,9 +245,10 @@ module cv32e40px_x_disp end // illegal instruction assignment + assign x_issue_illegal = x_illegal_insn_dec_i & ~instr_offloaded_q & instr_valid_i; always_comb begin x_illegal_insn_o = 1'b0; - if (x_issue_valid_o & x_issue_ready_i & ~x_issue_resp_accept_i) begin + if (x_issue_illegal & x_issue_ready_i & ~x_issue_resp_accept_i) begin x_illegal_insn_o = 1'b1; end end From fe137ea2124f6609f3a36e6ca21675048f431662 Mon Sep 17 00:00:00 2001 From: Davide Schiavone Date: Wed, 12 Jun 2024 12:06:09 +0200 Subject: [PATCH 04/11] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 669fae31b..31d7a6ad7 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,18 +1,18 @@ blank_issues_enabled: false contact_links: - name: Bug - url: https://github.com/openhwgroup/cv32e40p/issues/new?template=bug.md + url: https://github.com/openhwgroup/cv32e40px/issues/new?template=bug.md about: For bugs in the RTL, Documentation, Verification environment or Tool and Build system. labels: "Type:Bug" - name: Task - url: https://github.com/openhwgroup/cv32e40p/issues/new?template=task.md + url: https://github.com/openhwgroup/cv32e40px/issues/new?template=task.md about: For any task except bug fixes. labels: "Type:Task" - name: Question - url: https://github.com/openhwgroup/cv32e40p/issues/new?template=question.md + url: https://github.com/openhwgroup/cv32e40px/issues/new?template=question.md about: For general questions. labels: "Type:Question" - name: Enhancement - url: https://github.com/openhwgroup/cv32e40p/issues/new?template=enhancement.md + url: https://github.com/openhwgroup/cv32e40px/issues/new?template=enhancement.md about: For feature requests and enhancements. labels: "Type:Enhancement" From 3791c099307a6a78fbb29758ce081a3b1815c3e8 Mon Sep 17 00:00:00 2001 From: Davide Schiavone Date: Wed, 12 Jun 2024 12:07:31 +0200 Subject: [PATCH 05/11] fix config.yml --- .github/ISSUE_TEMPLATE/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 31d7a6ad7..14d320fec 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,18 +1,18 @@ blank_issues_enabled: false contact_links: - name: Bug - url: https://github.com/openhwgroup/cv32e40px/issues/new?template=bug.md + url: https://github.com/esl-epfl/cv32e40px/issues/new?template=bug.md about: For bugs in the RTL, Documentation, Verification environment or Tool and Build system. labels: "Type:Bug" - name: Task - url: https://github.com/openhwgroup/cv32e40px/issues/new?template=task.md + url: https://github.com/esl-epfl/cv32e40px/issues/new?template=task.md about: For any task except bug fixes. labels: "Type:Task" - name: Question - url: https://github.com/openhwgroup/cv32e40px/issues/new?template=question.md + url: https://github.com/esl-epfl/cv32e40px/issues/new?template=question.md about: For general questions. labels: "Type:Question" - name: Enhancement - url: https://github.com/openhwgroup/cv32e40px/issues/new?template=enhancement.md + url: https://github.com/esl-epfl/cv32e40px/issues/new?template=enhancement.md about: For feature requests and enhancements. labels: "Type:Enhancement" From 10b08065c50d44b5355c1535cb8f740e68e4f106 Mon Sep 17 00:00:00 2001 From: Davide Schiavone Date: Wed, 25 Sep 2024 17:10:33 +0200 Subject: [PATCH 06/11] fix comb loop (#8) --- README.md | 14 +++++++------- rtl/cv32e40px_controller.sv | 25 +++++++++++++++++++++---- rtl/cv32e40px_id_stage.sv | 23 ++++++++++++++--------- rtl/cv32e40px_x_disp.sv | 17 +++++++++++++---- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 0b23f8412..2272b6807 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ [![Build Status](https://travis-ci.com/pulp-platform/riscv.svg?branch=master)](https://travis-ci.com/pulp-platform/riscv) -# OpenHW Group CORE-V CV32E40P RISC-V IP +# OpenHW Group CORE-V CV32E40PX RISC-V IP -CV32E40P is a small and efficient, 32-bit, in-order RISC-V core with a 4-stage pipeline that implements +CV32E40PX is a small and efficient, 32-bit, in-order RISC-V core with a 4-stage pipeline that implements the RV32IM\[F|Zfinx\]C instruction set architecture, and the PULP custom extensions for achieving higher code density, performance, and energy efficiency \[[1](https://doi.org/10.1109/TVLSI.2017.2654506)\], \[[2](https://doi.org/10.1109/PATMOS.2017.8106976)\]. It started its life as a fork of the OR10N CPU core that is based on the OpenRISC ISA. @@ -14,12 +14,12 @@ when it has been contributed to [OpenHW Group](https://www.openhwgroup.org/). ## Documentation -The CV32E40P user manual can be found in the _docs_ folder and it is +The CV32E40PX user manual can be found in the _docs_ folder and it is captured in reStructuredText, rendered to html using [Sphinx](https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html). These documents are viewable using readthedocs and can be viewed [here](https://docs.openhwgroup.org/projects/cv32e40p-user-manual/). ## Verification -The verification environment for the CV32E40P is _not_ in this Repository. There is a small, simple testbench here which is +The verification environment for the CV32E40PX is _not_ in this Repository. There is a small, simple testbench here which is useful for experimentation only and should not be used to validate any changes to the RTL prior to pushing to the master branch of this repo. @@ -31,7 +31,7 @@ The Makefiles supported in the **core-v-verif** project automatically clone the ## Changelog A changelog is generated automatically in the documentation from the individual pull requests. -In order to enable automatic changelog generation within the CV32E40P documentation, the committer is required to label each pull request +In order to enable automatic changelog generation within the CV32E40PX documentation, the committer is required to label each pull request that touches any file in 'rtl' (or any of its subdirectories) with *Component:RTL* and label each pull request that touches any file in 'docs' (or any of its subdirectories) with *Component:Doc*. Pull requests that are not labeled or labeled with *ignore-for-release* are ignored for the changelog generation. @@ -40,7 +40,7 @@ Only the person who actually performs the merge can add these labels (you need c 1 label is applied and therefore pull requests that touches both RTL and documentation files in the same pull request are not allowed. ## Constraints -Example synthesis constraints for the CV32E40P are provided. +Example synthesis constraints for the CV32E40PX are provided. ## Contributing @@ -71,7 +71,7 @@ Run `./util/format-verible` to format all the files. ## Issues and Troubleshooting -If you find any problems or issues with CV32E40P or the documentation, please check out the [issue +If you find any problems or issues with CV32E40PX or the documentation, please check out the [issue tracker](https://github.com/openhwgroup/cv32e40p/issues) and create a new issue if your problem is not yet tracked. diff --git a/rtl/cv32e40px_controller.sv b/rtl/cv32e40px_controller.sv index e9807a381..19e210670 100644 --- a/rtl/cv32e40px_controller.sv +++ b/rtl/cv32e40px_controller.sv @@ -110,6 +110,10 @@ module cv32e40px_controller import cv32e40px_pkg::*; output logic apu_stall_o, + // X-IF signals + output logic x_branch_or_async_taken_o, + output logic x_control_illegal_reset_o, + // jump/branch signals input logic branch_taken_ex_i, // branch taken signal from EX ALU input logic [1:0] ctrl_transfer_insn_in_id_i, // jump is being calculated in ALU @@ -240,7 +244,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; logic debug_req_q; logic debug_req_pending; - // qualify wfi vs nosleep locally + // qualify wfi vs nosleep locally logic wfi_active; @@ -327,6 +331,9 @@ module cv32e40px_controller import cv32e40px_pkg::*; // ensures that the target is kept constant even if pc_id is no more HWLP_END hwlp_targ_addr_o = ((hwlp_start1_leq_pc && hwlp_end1_geq_pc) && !(hwlp_start0_leq_pc && hwlp_end0_geq_pc)) ? hwlp_start_addr_i[1] : hwlp_start_addr_i[0]; + x_branch_or_async_taken_o = 1'b0; + x_control_illegal_reset_o = 1'b0; + unique case (ctrl_fsm_cs) // We were just reset, wait for fetch_enable RESET: @@ -438,6 +445,8 @@ module cv32e40px_controller import cv32e40px_pkg::*; pc_mux_o = PC_BRANCH; pc_set_o = 1'b1; + x_branch_or_async_taken_o = 1'b1; + // if we want to debug, flush the pipeline // the current_pc_if will take the value of the next instruction to // be executed (NPC) @@ -496,6 +505,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; halt_id_o = 1'b1; ctrl_fsm_ns = DBG_FLUSH; debug_req_entry_n = 1'b1; + x_branch_or_async_taken_o = 1'b1; end else if (irq_req_ctrl_i && ~debug_mode_q) begin @@ -511,6 +521,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; exc_pc_mux_o = EXC_PC_IRQ; exc_cause_o = irq_id_ctrl_i; csr_irq_sec_o = irq_sec_ctrl_i; + x_branch_or_async_taken_o = 1'b1; // IRQ interface irq_ack_o = 1'b1; @@ -534,6 +545,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; halt_id_o = 1'b0; ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE; illegal_insn_n = 1'b1; + x_control_illegal_reset_o = 1'b1; end else begin @@ -679,6 +691,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; illegal_insn_i | ecall_insn_i: begin ctrl_fsm_ns = FLUSH_EX; + x_control_illegal_reset_o = illegal_insn_i; end (~ebrk_force_debug_mode & ebrk_insn_i): @@ -728,6 +741,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; halt_id_o = 1'b1; ctrl_fsm_ns = DBG_FLUSH; debug_req_entry_n = 1'b1; + x_branch_or_async_taken_o = 1'b1; end else if (irq_req_ctrl_i && ~debug_mode_q) begin @@ -743,6 +757,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; exc_pc_mux_o = EXC_PC_IRQ; exc_cause_o = irq_id_ctrl_i; csr_irq_sec_o = irq_sec_ctrl_i; + x_branch_or_async_taken_o = 1'b1; // IRQ interface irq_ack_o = 1'b1; @@ -768,6 +783,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; halt_id_o = 1'b1; ctrl_fsm_ns = FLUSH_EX; illegal_insn_n = 1'b1; + x_control_illegal_reset_o = 1'b1; end else begin @@ -865,6 +881,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; illegal_insn_i | ecall_insn_i: begin ctrl_fsm_ns = FLUSH_EX; + x_control_illegal_reset_o = illegal_insn_i; end (~ebrk_force_debug_mode & ebrk_insn_i): @@ -1207,7 +1224,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; exc_pc_mux_o = EXC_PC_DBD; csr_save_cause_o = 1'b1; debug_csr_save_o = 1'b1; - if (debug_force_wakeup_q) + if (debug_force_wakeup_q) debug_cause_o = DBG_CAUSE_HALTREQ; else if (debug_single_step_i) debug_cause_o = DBG_CAUSE_STEP; // pri 0 @@ -1479,7 +1496,7 @@ endgenerate assign debug_wfi_no_sleep_o = debug_mode_q || debug_req_pending || debug_single_step_i || trigger_match_i || COREV_CLUSTER; - // Gate off wfi + // Gate off wfi assign wfi_active = wfi_i & ~debug_wfi_no_sleep_o; // sticky version of debug_req (must be on clk_ungated_i such that incoming pulse before core is enabled is not missed) @@ -1600,7 +1617,7 @@ endgenerate // Ensure DBG_TAKEN_IF can only be enterred if in single step mode or woken // up from sleep by debug_req_i - + a_single_step_dbg_taken_if : assert property (@(posedge clk) disable iff (!rst_n) (ctrl_fsm_ns==DBG_TAKEN_IF) |-> ((~debug_mode_q && debug_single_step_i) || debug_force_wakeup_n)); // Ensure DBG_FLUSH state is only one cycle. This implies that cause is either trigger, debug_req_entry, or ebreak diff --git a/rtl/cv32e40px_id_stage.sv b/rtl/cv32e40px_id_stage.sv index 9f1f668b5..883b5ff1c 100644 --- a/rtl/cv32e40px_id_stage.sv +++ b/rtl/cv32e40px_id_stage.sv @@ -436,6 +436,8 @@ module cv32e40px_id_stage // X-Interface logic illegal_insn; logic x_illegal_insn; + logic x_branch_or_async_taken; + logic x_control_illegal_reset; logic [4:0] waddr_id; logic [4:0] waddr_ex; logic [4:0] waddr_wb; @@ -1124,7 +1126,7 @@ module cv32e40px_id_stage .mem_instr_waddr_ex_i(regfile_waddr_ex_o[4:0]), .mem_instr_we_ex_i (regfile_we_ex_o), .regs_used_i (regs_used), - .branch_or_jump_i (pc_set_o), + .branch_or_jump_i (x_branch_or_async_taken), .instr_valid_i (instr_valid_i), .x_rs_addr_i (x_rs_addr), .x_ex_fwd_o (x_ex_fwd), @@ -1136,14 +1138,15 @@ module cv32e40px_id_stage .wb_ready_i (wb_ready_i), // additional status signals - .x_stall_o (x_stall), - .x_illegal_insn_o (x_illegal_insn), - .x_illegal_insn_dec_i(illegal_insn_dec), - .id_ready_i (id_ready_o), - .ex_valid_i (ex_valid_i), - .ex_ready_i (ex_ready_i), - .current_priv_lvl_i (current_priv_lvl_i), - .data_req_dec_i (data_req_id) + .x_stall_o (x_stall), + .x_illegal_insn_o (x_illegal_insn), + .x_illegal_insn_dec_i (illegal_insn_dec), + .x_control_illegal_reset_i(x_control_illegal_reset), + .id_ready_i (id_ready_o), + .ex_valid_i (ex_valid_i), + .ex_ready_i (ex_ready_i), + .current_priv_lvl_i (current_priv_lvl_i), + .data_req_dec_i (data_req_id) ); @@ -1445,6 +1448,8 @@ module cv32e40px_id_stage .apu_write_dep_i (apu_write_dep_i), .apu_stall_o(apu_stall), + .x_branch_or_async_taken_o(x_branch_or_async_taken), + .x_control_illegal_reset_o(x_control_illegal_reset), // jump/branch control .branch_taken_ex_i (branch_taken_ex), diff --git a/rtl/cv32e40px_x_disp.sv b/rtl/cv32e40px_x_disp.sv index dc8907979..f326b3f90 100644 --- a/rtl/cv32e40px_x_disp.sv +++ b/rtl/cv32e40px_x_disp.sv @@ -90,6 +90,7 @@ module cv32e40px_x_disp output logic x_stall_o, output logic x_illegal_insn_o, input logic x_illegal_insn_dec_i, + input logic x_control_illegal_reset_i, input logic id_ready_i, input logic ex_valid_i, input logic ex_ready_i, @@ -108,6 +109,7 @@ module cv32e40px_x_disp logic x_if_memory_instr; logic illegal_forwarding_prevention; logic x_issue_illegal; + logic x_illegal_insn_q, x_illegal_insn_n; // issue interface assign x_issue_valid_o = x_illegal_insn_dec_i & ~branch_or_jump_i & ~instr_offloaded_q & instr_valid_i & ~illegal_forwarding_prevention; @@ -182,7 +184,7 @@ module cv32e40px_x_disp assign x_wb_fwd_o[3] = (x_rs_addr_i[0] | 5'b00001) == waddr_wb_i & we_wb_i & ex_valid_i & x_issue_resp_dualread_i[0]; assign x_wb_fwd_o[4] = (x_rs_addr_i[1] | 5'b00001) == waddr_wb_i & we_wb_i & ex_valid_i & x_issue_resp_dualread_i[1]; assign x_wb_fwd_o[5] = (x_rs_addr_i[2] | 5'b00001) == waddr_wb_i & we_wb_i & ex_valid_i & x_issue_resp_dualread_i[2]; - assign dep = ~x_illegal_insn_o & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) + assign dep = ~x_illegal_insn_n & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) | (regs_used_i[1] & scoreboard_q[x_rs_addr_i[1]] & (x_result_rd_i != x_rs_addr_i[1])) | (regs_used_i[2] & scoreboard_q[x_rs_addr_i[2]] & (x_result_rd_i != x_rs_addr_i[2])) | (((regs_used_i[0] & x_issue_resp_dualread_i[0]) & scoreboard_q[x_rs_addr_i[0] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[0] | 5'b00001))) & x_issue_resp_dualread_i[0]) @@ -195,7 +197,7 @@ module cv32e40px_x_disp assign x_wb_fwd_o[0] = x_rs_addr_i[0] == waddr_wb_i & we_wb_i & ex_valid_i; assign x_wb_fwd_o[1] = x_rs_addr_i[1] == waddr_wb_i & we_wb_i & ex_valid_i; assign x_wb_fwd_o[2] = x_rs_addr_i[2] == waddr_wb_i & we_wb_i & ex_valid_i; - assign dep = ~x_illegal_insn_o & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) + assign dep = ~x_illegal_insn_n & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) | (regs_used_i[1] & scoreboard_q[x_rs_addr_i[1]] & (x_result_rd_i != x_rs_addr_i[1])) | (regs_used_i[2] & scoreboard_q[x_rs_addr_i[2]] & (x_result_rd_i != x_rs_addr_i[2]))); end @@ -247,11 +249,12 @@ module cv32e40px_x_disp // illegal instruction assignment assign x_issue_illegal = x_illegal_insn_dec_i & ~instr_offloaded_q & instr_valid_i; always_comb begin - x_illegal_insn_o = 1'b0; + x_illegal_insn_n = 1'b0; if (x_issue_illegal & x_issue_ready_i & ~x_issue_resp_accept_i) begin - x_illegal_insn_o = 1'b1; + x_illegal_insn_n = 1'b1; end end + assign x_illegal_insn_o = x_illegal_insn_q; // scoreboard and status signal register always_ff @(posedge clk_i or negedge rst_ni) begin @@ -260,11 +263,17 @@ module cv32e40px_x_disp instr_offloaded_q <= 1'b0; id_q <= '0; mem_counter_q <= '0; + x_illegal_insn_q <= 1'b0; end else begin scoreboard_q <= scoreboard_d; instr_offloaded_q <= instr_offloaded_d; id_q <= id_d; mem_counter_q <= mem_counter_d; + if (x_control_illegal_reset_i) begin + x_illegal_insn_q <= 1'b0; + end else begin + x_illegal_insn_q <= x_illegal_insn_n; + end end end From 329f622b908ba9ccdfd940ce757242f6674c60ad Mon Sep 17 00:00:00 2001 From: Michele Caon Date: Mon, 6 Oct 2025 18:13:00 +0200 Subject: [PATCH 07/11] Add missing generate label --- rtl/cv32e40px_id_stage.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/cv32e40px_id_stage.sv b/rtl/cv32e40px_id_stage.sv index 883b5ff1c..44cb5bdf2 100644 --- a/rtl/cv32e40px_id_stage.sv +++ b/rtl/cv32e40px_id_stage.sv @@ -867,9 +867,9 @@ module cv32e40px_id_stage end generate - if (!COREV_PULP) begin + if (!COREV_PULP) begin : gen_no_corev_pulp assign imm_vec_ext_id = imm_vu_type[1:0]; - end else begin + end else begin : gen_corev_pulp assign imm_vec_ext_id = (alu_vec) ? imm_vu_type[1:0] : 2'b0; end endgenerate From d80affae31f3e36a3e92dd2f84acd28a85a977bd Mon Sep 17 00:00:00 2001 From: Michele Caon Date: Mon, 6 Oct 2025 18:19:47 +0200 Subject: [PATCH 08/11] Add other missing generate labels --- rtl/cv32e40px_id_stage.sv | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rtl/cv32e40px_id_stage.sv b/rtl/cv32e40px_id_stage.sv index 44cb5bdf2..d7293c5b7 100644 --- a/rtl/cv32e40px_id_stage.sv +++ b/rtl/cv32e40px_id_stage.sv @@ -888,9 +888,15 @@ module cv32e40px_id_stage generate if (APU == 1) begin : gen_apu - if (APU_NARGS_CPU >= 1) assign apu_operands[0] = alu_operand_a; - if (APU_NARGS_CPU >= 2) assign apu_operands[1] = alu_operand_b; - if (APU_NARGS_CPU >= 3) assign apu_operands[2] = alu_operand_c; + if (APU_NARGS_CPU >= 1) begin : gen_apu_nargs_1 + assign apu_operands[0] = alu_operand_a; + end + if (APU_NARGS_CPU >= 2) begin : gen_apu_nargs_2 + assign apu_operands[1] = alu_operand_b; + end + if (APU_NARGS_CPU >= 3) begin : gen_apu_nargs_3 + assign apu_operands[2] = alu_operand_c; + end // write reg assign apu_waddr = regfile_alu_waddr_id; From 8ffdcc50674e19bc1f2cdf70308b5c3763a2e646 Mon Sep 17 00:00:00 2001 From: Michele Caon Date: Mon, 6 Oct 2025 18:22:44 +0200 Subject: [PATCH 09/11] Keep fixing lint warnings --- rtl/cv32e40px_if_stage.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtl/cv32e40px_if_stage.sv b/rtl/cv32e40px_if_stage.sv index 2b02e0a79..39b5911f4 100644 --- a/rtl/cv32e40px_if_stage.sv +++ b/rtl/cv32e40px_if_stage.sv @@ -291,7 +291,7 @@ module cv32e40px_if_stage #( generate - if (COREV_X_IF != 0) begin + if (COREV_X_IF != 0) begin : gen_core_v_x_if assign x_compressed_valid_o = illegal_c_insn_dec; assign x_compressed_req_o.instr = instr_aligned[15:0]; assign x_compressed_req_o.mode = 2'b00; // Machine Mode @@ -308,7 +308,7 @@ module cv32e40px_if_stage #( illegal_c_insn = 1'b1; end end - end else begin + end else begin : gen_no_core_v_x_if assign instr_decompressed = instr_decompressed_dec; assign illegal_c_insn = illegal_c_insn_dec; assign x_compressed_valid_o = '0; From bc322cdef052fa8fda0ddad46628ea47f0797881 Mon Sep 17 00:00:00 2001 From: Michele Caon Date: Mon, 6 Oct 2025 18:26:48 +0200 Subject: [PATCH 10/11] Keep fixing lint warnings --- rtl/cv32e40px_register_file_ff.sv | 8 ++++---- rtl/cv32e40px_x_disp.sv | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rtl/cv32e40px_register_file_ff.sv b/rtl/cv32e40px_register_file_ff.sv index d0aad5838..7164b3756 100644 --- a/rtl/cv32e40px_register_file_ff.sv +++ b/rtl/cv32e40px_register_file_ff.sv @@ -91,8 +91,8 @@ module cv32e40px_register_file #( //-- READ : Read address decoder RAD //----------------------------------------------------------------------------- generate - if (COREV_X_IF != 0) begin - if (X_DUALREAD) begin + if (COREV_X_IF != 0) begin : gen_corev_x_if + if (X_DUALREAD) begin : gen_corev_x_if_dualread always_comb begin rdata_a_o[0] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; rdata_b_o[0] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; @@ -119,12 +119,12 @@ module cv32e40px_register_file #( }]); else rdata_c_o[1] = '0; end - end else begin + end else begin : gen_corev_x_if_no_dualread assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; end - end else begin + end else begin : gen_no_corev_x_if assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; diff --git a/rtl/cv32e40px_x_disp.sv b/rtl/cv32e40px_x_disp.sv index f326b3f90..e5c07094d 100644 --- a/rtl/cv32e40px_x_disp.sv +++ b/rtl/cv32e40px_x_disp.sv @@ -115,7 +115,7 @@ module cv32e40px_x_disp assign x_issue_valid_o = x_illegal_insn_dec_i & ~branch_or_jump_i & ~instr_offloaded_q & instr_valid_i & ~illegal_forwarding_prevention; assign x_issue_req_id_o = id_q; generate - if (X_DUALREAD != 0) begin + if (X_DUALREAD != 0) begin : gen_rs_dualread assign x_issue_req_rs_valid_o[0] = (~scoreboard_q[x_rs_addr_i[0]] | x_ex_fwd_o[0] | x_wb_fwd_o[0]) & ~(x_rs_addr_i[0] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[0] == waddr_wb_i & ~ex_valid_i); assign x_issue_req_rs_valid_o[1] = (~scoreboard_q[x_rs_addr_i[1]] | x_ex_fwd_o[1] | x_wb_fwd_o[1]) @@ -129,7 +129,7 @@ module cv32e40px_x_disp assign x_issue_req_rs_valid_o[5] = (~scoreboard_q[x_rs_addr_i[2] | 5'b00001] | x_ex_fwd_o[5] | x_wb_fwd_o[5]) & ~((x_rs_addr_i[2] | 5'b00001) == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~((x_rs_addr_i[2] | 5'b00001) == waddr_wb_i & ~ex_valid_i); assign x_issue_req_ecs_valid = 1'b1; // extension context status is not implemented in cv32e40px - end else begin + end else begin : gen_rs_no_dualread assign x_issue_req_rs_valid_o[0] = (~scoreboard_q[x_rs_addr_i[0]] | x_ex_fwd_o[0] | x_wb_fwd_o[0]) & ~(x_rs_addr_i[0] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[0] == waddr_wb_i & ~ex_valid_i); assign x_issue_req_rs_valid_o[1] = (~scoreboard_q[x_rs_addr_i[1]] | x_ex_fwd_o[1] | x_wb_fwd_o[1]) @@ -171,7 +171,7 @@ module cv32e40px_x_disp // forwarding generate - if (X_DUALREAD != 0) begin + if (X_DUALREAD != 0) begin : gen_fwd_dualread assign x_ex_fwd_o[0] = x_rs_addr_i[0] == waddr_ex_i & we_ex_i & ex_valid_i; assign x_ex_fwd_o[1] = x_rs_addr_i[1] == waddr_ex_i & we_ex_i & ex_valid_i; assign x_ex_fwd_o[2] = x_rs_addr_i[2] == waddr_ex_i & we_ex_i & ex_valid_i; @@ -190,7 +190,7 @@ module cv32e40px_x_disp | (((regs_used_i[0] & x_issue_resp_dualread_i[0]) & scoreboard_q[x_rs_addr_i[0] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[0] | 5'b00001))) & x_issue_resp_dualread_i[0]) | (((regs_used_i[1] & x_issue_resp_dualread_i[1]) & scoreboard_q[x_rs_addr_i[1] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[1] | 5'b00001))) & x_issue_resp_dualread_i[1]) | (((regs_used_i[2] & x_issue_resp_dualread_i[2]) & scoreboard_q[x_rs_addr_i[2] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[2] | 5'b00001))) & x_issue_resp_dualread_i[2])); - end else begin + end else begin : gen_fwd_no_dualread assign x_ex_fwd_o[0] = x_rs_addr_i[0] == waddr_ex_i & we_ex_i & ex_valid_i; assign x_ex_fwd_o[1] = x_rs_addr_i[1] == waddr_ex_i & we_ex_i & ex_valid_i; assign x_ex_fwd_o[2] = x_rs_addr_i[2] == waddr_ex_i & we_ex_i & ex_valid_i; From ee1f281d7a41f74ac89c0f70515c391e3af05fbf Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Tue, 7 Oct 2025 12:50:08 +0200 Subject: [PATCH 11/11] remove check target pr --- .github/workflows/check_target_on_pr.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .github/workflows/check_target_on_pr.yml diff --git a/.github/workflows/check_target_on_pr.yml b/.github/workflows/check_target_on_pr.yml deleted file mode 100644 index b48f31f33..000000000 --- a/.github/workflows/check_target_on_pr.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: check_target -on: [push, pull_request] - -jobs: - check_target: - runs-on: ubuntu-latest - steps: - - if: ${{ (github.event.pull_request.head.ref == 'dev' && github.event.pull_request.base.ref == 'master') || github.event.pull_request.base.ref == 'dev' || github.event.push.ref != 'refs/heads/master'}} - run: exit 0 - - if: ${{ github.event.pull_request.base.ref != 'dev' || github.event.push.ref == 'refs/heads/master'}} - run: exit 1