From 912f9dee4dabe2815c476a82c98af05f650a1202 Mon Sep 17 00:00:00 2001 From: rohan Date: Fri, 23 Feb 2024 17:32:57 +0500 Subject: [PATCH 01/15] Added ZCMP support --- core/Flist.cva6 | 1 + core/commit_stage.sv | 9 + core/compressed_decoder.sv | 11 + core/cva6.sv | 6 +- core/decoder.sv | 51 +- core/id_stage.sv | 61 +- core/include/config_pkg.sv | 2 + core/include/cv32a60x_config_pkg.sv | 2 + core/include/cv64a6_imafdc_sv39_config_pkg.sv | 2 + .../cv64a6_imafdc_sv39_hpdcache_config_pkg.sv | 2 + .../cv64a6_imafdc_sv39_wb_config_pkg.sv | 2 + .../include/cv64a6_imafdcv_sv39_config_pkg.sv | 2 + core/scoreboard.sv | 13 +- core/zcmp_decoder.sv | 731 ++++++++++++++++++ 14 files changed, 862 insertions(+), 33 deletions(-) create mode 100644 core/zcmp_decoder.sv diff --git a/core/Flist.cva6 b/core/Flist.cva6 index a51ef965f6..8d72f42514 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/alu.sv ${CVA6_REPO_DIR}/core/fpu_wrap.sv ${CVA6_REPO_DIR}/core/branch_unit.sv ${CVA6_REPO_DIR}/core/compressed_decoder.sv +${CVA6_REPO_DIR}/core/zcmp_decoder.sv ${CVA6_REPO_DIR}/core/controller.sv ${CVA6_REPO_DIR}/core/csr_buffer.sv ${CVA6_REPO_DIR}/core/csr_regfile.sv diff --git a/core/commit_stage.sv b/core/commit_stage.sv index a3a8b4ba06..3975c8fe8b 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -38,6 +38,8 @@ module commit_stage input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i, // Acknowledge that we are indeed committing - ISSUE_STAGE output logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_o, + // Acknowledge that we are indeed committing - CSR_REGFILE + output logic [CVA6Cfg.NrCommitPorts-1:0] commit_zcmp_ack_o, // Register file write address - ISSUE_STAGE output logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_o, // Register file write data - ISSUE_STAGE @@ -116,6 +118,7 @@ module commit_stage assign commit_tran_id_o = commit_instr_i[0].trans_id; logic instr_0_is_amo; + logic [CVA6Cfg.NrCommitPorts-1:0] commit_zcmp_ack; assign instr_0_is_amo = is_amo(commit_instr_i[0].op); // ------------------- // Commit Instruction @@ -124,6 +127,7 @@ module commit_stage always_comb begin : commit // default assignments commit_ack_o[0] = 1'b0; + commit_zcmp_ack[0] = 1'b0; amo_valid_commit_o = 1'b0; @@ -141,6 +145,10 @@ module commit_stage csr_write_fflags_o = 1'b0; flush_commit_o = 1'b0; + if (commit_instr_i[0].valid && !commit_instr_i[0].ex.valid && !halt_i && (commit_instr_i[0].is_zcmp_instr && commit_instr_i[0].is_last_zcmp_instr)) + commit_zcmp_ack[0] = 1'b1; + else commit_zcmp_ack[0] = 1'b0; + // we will not commit the instruction if we took an exception // and we do not commit the instruction if we requested a halt if (commit_instr_i[0].valid && !commit_instr_i[0].ex.valid && !halt_i) begin @@ -281,6 +289,7 @@ module commit_stage end end end + commit_zcmp_ack_o = (commit_instr_i[0].is_zcmp_instr) ? commit_zcmp_ack : commit_ack_o; end // ----------------------------- diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index 2c0a527172..1c989df00e 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -28,6 +28,8 @@ module compressed_decoder #( output logic [31:0] instr_o, // Input instruction is illegal - decoder output logic illegal_instr_o, + // Output instruction is zcmp - decoder + output logic is_zcmp_instr_o, // Output instruction is compressed - decoder output logic is_compressed_o ); @@ -40,6 +42,7 @@ module compressed_decoder #( instr_o = '0; is_compressed_o = 1'b1; instr_o = instr_i; + is_zcmp_instr_o = 0; // I: | imm[11:0] | rs1 | funct3 | rd | opcode | // S: | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | @@ -865,6 +868,13 @@ module compressed_decoder #( 3'b000, riscv::OpcodeStoreFp }; + end else if (CVA6Cfg.RVZCMP) begin + if (instr_i[12:10] == 3'b110 || instr_i[12:10] == 3'b111 || instr_i[12:10] == 3'b011) begin //is a push/pop instruction + is_zcmp_instr_o = 1; + instr_o = instr_i; + end else begin + illegal_instr_o = 1'b1; + end end else begin illegal_instr_o = 1'b1; end @@ -937,3 +947,4 @@ module compressed_decoder #( end end endmodule + diff --git a/core/cva6.sv b/core/cva6.sv index 70512a8735..0ab191b3fc 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -302,6 +302,7 @@ module cva6 logic [ riscv::VLEN-1:0] pc_commit; logic eret; logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; + logic [CVA6Cfg.NrCommitPorts-1:0] commit_zcmp_ack; localparam NumPorts = 4; cvxif_pkg::cvxif_req_t cvxif_req; @@ -884,6 +885,7 @@ module cva6 .single_step_i (single_step_csr_commit || single_step_acc_commit), .commit_instr_i (commit_instr_id_commit), .commit_ack_o (commit_ack), + .commit_zcmp_ack_o (commit_zcmp_ack), .no_st_pending_i (no_st_pending_commit), .waddr_o (waddr_commit_id), .wdata_o (wdata_commit_id), @@ -923,7 +925,7 @@ module cva6 .flush_o (flush_csr_ctrl), .halt_csr_o (halt_csr_ctrl), .commit_instr_i (commit_instr_id_commit), - .commit_ack_i (commit_ack), + .commit_ack_i (commit_zcmp_ack), .boot_addr_i (boot_addr_i[riscv::VLEN-1:0]), .hart_id_i (hart_id_i[riscv::XLEN-1:0]), .ex_i (ex_commit), @@ -1548,7 +1550,7 @@ module cva6 .lsu_ctrl_i (rvfi_lsu_ctrl), .wbdata_i (wbdata_ex_id), - .commit_ack_i(commit_ack), + .commit_ack_i(commit_zcmp_ack), .mem_paddr_i (rvfi_mem_paddr), .debug_mode_i(debug_mode), .wdata_i (wdata_commit_id), diff --git a/core/decoder.sv b/core/decoder.sv index 2b8381e814..f3ca47e0df 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -40,6 +40,12 @@ module decoder input logic is_illegal_i, // Instruction from fetch stage - FRONTEND input logic [31:0] instruction_i, + // Is a zcmp instruction - zcmp_decoder + input logic is_zcmp_instr_i, + // Is a last zcmp instruction - zcmp_decoder + input logic is_last_zcmp_instr_i, + // Is mvsa01/mva01s zcmp instruction - zcmp_decoder + input logic is_mv_zcmp_instr_i, // Is a branch predict instruction - FRONTEND input branchpredict_sbe_t branch_predict_i, // If an exception occured in fetch stage - FRONTEND @@ -128,27 +134,30 @@ module decoder always_comb begin : decoder - imm_select = NOIMM; - is_control_flow_instr_o = 1'b0; - illegal_instr = 1'b0; - illegal_instr_non_bm = 1'b0; - illegal_instr_bm = 1'b0; - illegal_instr_zic = 1'b0; - instruction_o.pc = pc_i; - instruction_o.trans_id = '0; - instruction_o.fu = NONE; - instruction_o.op = ariane_pkg::ADD; - instruction_o.rs1 = '0; - instruction_o.rs2 = '0; - instruction_o.rd = '0; - instruction_o.use_pc = 1'b0; - instruction_o.is_compressed = is_compressed_i; - instruction_o.use_zimm = 1'b0; - instruction_o.bp = branch_predict_i; - instruction_o.vfp = 1'b0; - ecall = 1'b0; - ebreak = 1'b0; - check_fprm = 1'b0; + imm_select = NOIMM; + is_control_flow_instr_o = 1'b0; + illegal_instr = 1'b0; + illegal_instr_non_bm = 1'b0; + illegal_instr_bm = 1'b0; + illegal_instr_zic = 1'b0; + instruction_o.pc = pc_i; + instruction_o.trans_id = '0; + instruction_o.fu = NONE; + instruction_o.op = ariane_pkg::ADD; + instruction_o.rs1 = '0; + instruction_o.rs2 = '0; + instruction_o.rd = '0; + instruction_o.use_pc = 1'b0; + instruction_o.is_compressed = is_compressed_i; + instruction_o.is_zcmp_instr = is_zcmp_instr_i; + instruction_o.is_last_zcmp_instr = is_last_zcmp_instr_i; + instruction_o.is_mv_zcmp_instr = is_mv_zcmp_instr_i; + instruction_o.use_zimm = 1'b0; + instruction_o.bp = branch_predict_i; + instruction_o.vfp = 1'b0; + ecall = 1'b0; + ebreak = 1'b0; + check_fprm = 1'b0; if (~ex_i.valid) begin case (instr.rtype.opcode) diff --git a/core/id_stage.sv b/core/id_stage.sv index d892b82eb4..79883c8452 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -82,8 +82,15 @@ module id_stage #( logic [31:0] orig_instr; logic is_illegal; + logic is_illegal_cmp; logic [31:0] instruction; + logic [31:0] compressed_instr; logic is_compressed; + logic is_compressed_cmp; + logic is_zcmp_instr_i; + logic stall_instr_fetch; + logic is_last_zcmp_instr_o; + logic is_mv_zcmp_instr_o; if (CVA6Cfg.RVC) begin // --------------------------------------------------------- @@ -93,17 +100,47 @@ module id_stage #( .CVA6Cfg(CVA6Cfg) ) compressed_decoder_i ( .instr_i (fetch_entry_i.instruction), - .instr_o (instruction), + .instr_o (compressed_instr), .illegal_instr_o(is_illegal), - .is_compressed_o(is_compressed) + .is_compressed_o(is_compressed), + .is_zcmp_instr_o(is_zcmp_instr_i) ); + if (CVA6Cfg.RVZCMP) begin + //sequencial decoder + zcmp_decoder #( + .CVA6Cfg(CVA6Cfg) + ) zcmp_decoder_i ( + .instr_i (compressed_instr), + .is_zcmp_instr_i (is_zcmp_instr_i), + .clk_i (clk_i), + .rst_ni (rst_ni), + .instr_o (instruction), + .illegal_instr_i (is_illegal), + .is_compressed_i (is_compressed), + .issue_ack_i (issue_instr_ack_i), + .illegal_instr_o (is_illegal_cmp), + .is_compressed_o (is_compressed_cmp), + .fetch_stall_o (stall_instr_fetch), + .is_last_zcmp_instr_o(is_last_zcmp_instr_o), + .is_mv_zcmp_instr_o (is_mv_zcmp_instr_o) + ); + end else begin + assign instruction = compressed_instr; + assign is_illegal_cmp = is_illegal; + assign is_compressed_cmp = is_compressed; + assign is_last_zcmp_instr_o = '0; + assign is_mv_zcmp_instr_o = '0; + end end else begin assign instruction = fetch_entry_i.instruction; - assign is_illegal = '0; - assign is_compressed = '0; + assign is_illegal_cmp = '0; + assign is_compressed_cmp = '0; + assign is_zcmp_instr_i = '0; + assign is_last_zcmp_instr_o = '0; + assign is_mv_zcmp_instr_o = '0; end - assign rvfi_is_compressed_o = is_compressed; + assign rvfi_is_compressed_o = is_compressed_cmp; // --------------------------------------------------------- // 2. Decode and emit instruction to issue stage // --------------------------------------------------------- @@ -118,8 +155,11 @@ module id_stage #( .irq_ctrl_i, .irq_i, .pc_i (fetch_entry_i.address), - .is_compressed_i (is_compressed), - .is_illegal_i (is_illegal), + .is_compressed_i (is_compressed_cmp), + .is_zcmp_instr_i (is_zcmp_instr_i), + .is_last_zcmp_instr_i (is_last_zcmp_instr_o), + .is_mv_zcmp_instr_i (is_mv_zcmp_instr_o), + .is_illegal_i (is_illegal_cmp), .instruction_i (instruction), .compressed_instr_i (fetch_entry_i.instruction[15:0]), .branch_predict_i (fetch_entry_i.branch_predict), @@ -156,7 +196,11 @@ module id_stage #( // or the issue stage is currently acknowledging an instruction, which means that we will have space // for a new instruction if ((!issue_q.valid || issue_instr_ack_i) && fetch_entry_valid_i) begin - fetch_entry_ready_o = 1'b1; + if (stall_instr_fetch) begin + fetch_entry_ready_o = 1'b0; + end else begin + fetch_entry_ready_o = 1'b1; + end issue_n = '{1'b1, decoded_instruction, orig_instr, is_control_flow_instr}; end @@ -174,3 +218,4 @@ module id_stage #( end end endmodule + diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 14f6b9f0df..4a3c0b05a6 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -68,6 +68,8 @@ package config_pkg; bit RVC; // Zcb RISC-V extension bit RVZCB; + // Zcmp RISC-V extension + bit RVZCMP; // Non standard Vector Floating Point bit XFVec; // CV-X-IF coprocessor interface is supported diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index cbb0afb888..9a467b7ded 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 1; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; + localparam CVA6ConfigZcmpExtEn = 1; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index e09501aa78..33696e1c3a 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 1; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv index c3d557b638..ab62c714fe 100644 --- a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv @@ -28,6 +28,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 1; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -98,6 +99,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv index 302e6cdca4..e3582147b4 100644 --- a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 1; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index 8e26632dc2..f39dbd4549 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 1; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/scoreboard.sv b/core/scoreboard.sv index c6bd62a8e9..a8d5a0c666 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -185,7 +185,16 @@ module scoreboard #( // check if this instruction was issued (e.g.: it could happen after a flush that there is still // something in the pipeline e.g. an incomplete memory operation) if (wt_valid_i[i] && mem_q[trans_id_i[i]].issued) begin - mem_n[trans_id_i[i]].sbe.valid = 1'b1; + if (mem_q[trans_id_i[i]].sbe.is_mv_zcmp_instr && mem_q[trans_id_i[i]].sbe.is_zcmp_instr) begin + if (mem_q[trans_id_i[i]].sbe.is_last_zcmp_instr) begin + mem_n[trans_id_i[i]].sbe.valid = 1'b1; + mem_n[trans_id_i[i-1]].sbe.valid = 1'b1; + end else begin + mem_n[trans_id_i[i]].sbe.valid = 1'b0; + end + end else begin + mem_n[trans_id_i[i]].sbe.valid = 1'b1; + end mem_n[trans_id_i[i]].sbe.result = wbdata_i[i]; // save the target address of a branch (needed for debug in commit stage) if (CVA6Cfg.DebugEn) begin @@ -486,4 +495,4 @@ module scoreboard #( end end //pragma translate_on -endmodule +endmodule \ No newline at end of file diff --git a/core/zcmp_decoder.sv b/core/zcmp_decoder.sv new file mode 100644 index 0000000000..3f339f842b --- /dev/null +++ b/core/zcmp_decoder.sv @@ -0,0 +1,731 @@ +// 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. +// +// Author: Rohan Arshid, 10xEngineers +// Date: 22.01.2024 +// Description: Contains the logic for decoding cm.push, cm.pop, cm.popret, +// cm.popretz, cm.mvsa01, and cm.mva01s instructions of the +// Zcmp Extension + +module zcmp_decoder #( + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty +) ( + input logic [31:0] instr_i, + input logic clk_i, // Clock + input logic rst_ni, // Synchronous reset + input logic is_zcmp_instr_i, // Intruction is of zcmp extension + input logic illegal_instr_i, // From compressed decoder + input logic is_compressed_i, + input logic issue_ack_i, // Check if the intruction is acknowledged + output logic [31:0] instr_o, + output logic illegal_instr_o, + output logic is_compressed_o, + output logic fetch_stall_o, //Wait while push/pop/move instructions expand + output logic is_last_zcmp_instr_o, + output logic is_mv_zcmp_instr_o +); + + // FSM States + enum logic [2:0] { + IDLE, + INIT, + PUSH_ADDI, + POPRETZ_1, + MOVE, + PUSH_POP_INSTR_2 + } + state_d, state_q; + + // Instruction Types + enum logic [2:0] { + PUSH, + POP, + POPRETZ, + POPRET, + MVA01S, + MVSA01 + } zcmp_instr_type; + + // Temporary registers + logic [3:0] reg_numbers, reg_numbers_q, reg_numbers_d; + logic [8:0] stack_adj; + logic [4:0] xreg1, xreg2, store_reg, store_reg_q, store_reg_d; + logic [1:0] popretz_inst_q, popretz_inst_d; + logic [11:0] offset_reg, offset_q, offset_d; + logic [31:0] instr_o_reg; + + riscv::itype_t itype_inst; + assign instr_o = instr_o_reg; + always_comb begin + illegal_instr_o = 1'b0; + fetch_stall_o = 1'b0; + is_last_zcmp_instr_o = 1'b0; + is_mv_zcmp_instr_o = 1'b0; + is_compressed_o = is_zcmp_instr_i ? 1'b1 : is_compressed_i; + reg_numbers = '0; + stack_adj = '0; + state_d = state_q; + offset_d = offset_q; + reg_numbers_d = reg_numbers_q; + store_reg_d = store_reg_q; + popretz_inst_d = popretz_inst_q; + + if (is_zcmp_instr_i) begin + + unique case (instr_i[12:10]) + // push or pop + 3'b110: begin + unique case (instr_i[9:8]) + 2'b00: begin + zcmp_instr_type = PUSH; + end + 2'b10: begin + zcmp_instr_type = POP; + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + end + // popret or popretz + 3'b111: begin + unique case (instr_i[9:8]) + 2'b00: begin + zcmp_instr_type = POPRETZ; + end + 2'b10: begin + zcmp_instr_type = POPRET; + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + end + // mvq01s or mvsa01 + 3'b011: begin + unique case (instr_i[6:5]) + 2'b01: begin + zcmp_instr_type = MVSA01; + end + 2'b11: begin + zcmp_instr_type = MVA01S; + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + + // Calculate xreg1 & xreg2 for move instructions + if (zcmp_instr_type == MVSA01 || zcmp_instr_type == MVA01S) begin + if (instr_i[9:7] != instr_i[4:2]) begin + xreg1 = {instr_i[9:8] > 0, instr_i[9:8] == 0, instr_i[9:7]}; + xreg2 = {instr_i[4:3] > 0, instr_i[4:3] == 0, instr_i[4:2]}; + end else begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + end else begin + xreg1 = '0; + xreg2 = '0; + end + + // push/pop/popret/popretz instructions + unique case (instr_i[7:4]) + 4'b0100: reg_numbers = 4'b0001; // 4 + 4'b0101: reg_numbers = 4'b0010; // 5 + 4'b0110: reg_numbers = 4'b0011; // 6 + 4'b0111: reg_numbers = 4'b0100; // 7 + 4'b1000: reg_numbers = 4'b0101; // 8 + 4'b1001: reg_numbers = 4'b0110; // 9 + 4'b1010: reg_numbers = 4'b0111; // 10 + 4'b1011: reg_numbers = 4'b1000; // 11 + 4'b1100: reg_numbers = 4'b1001; // 12 + 4'b1101: reg_numbers = 4'b1010; // 13 + 4'b1110: reg_numbers = 4'b1011; // 14 + 4'b1111: reg_numbers = 4'b1100; // 15 + default: reg_numbers = '0; + endcase + + if (riscv::XLEN == 32) begin + unique case (instr_i[7:4]) + 4'b0100, 4'b0101, 4'b0110, 4'b0111: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 16; + 2'b01: stack_adj = 32; + 2'b10: stack_adj = 48; + 2'b11: stack_adj = 64; + endcase + end + 4'b1000, 4'b1001, 4'b1010, 4'b1011: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 32; + 2'b01: stack_adj = 48; + 2'b10: stack_adj = 64; + 2'b11: stack_adj = 80; + endcase + end + 4'b1100, 4'b1101, 4'b1110: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 48; + 2'b01: stack_adj = 64; + 2'b10: stack_adj = 80; + 2'b11: stack_adj = 96; + endcase + end + 4'b1111: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 64; + 2'b01: stack_adj = 80; + 2'b10: stack_adj = 96; + 2'b11: stack_adj = 112; + endcase + end + default: ; + endcase + end else begin + unique case (instr_i[7:4]) + 4'b0100, 4'b0101: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 16; + 2'b01: stack_adj = 32; + 2'b10: stack_adj = 48; + 2'b11: stack_adj = 64; + endcase + end + 4'b0110, 4'b0111: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 32; + 2'b01: stack_adj = 48; + 2'b10: stack_adj = 64; + 2'b11: stack_adj = 80; + endcase + end + 4'b1000, 4'b1001: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 48; + 2'b01: stack_adj = 64; + 2'b10: stack_adj = 80; + 2'b11: stack_adj = 96; + endcase + end + 4'b1010, 4'b1011: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 64; + 2'b01: stack_adj = 80; + 2'b10: stack_adj = 96; + 2'b11: stack_adj = 112; + endcase + end + 4'b1100, 4'b1101: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 80; + 2'b01: stack_adj = 96; + 2'b10: stack_adj = 112; + 2'b11: stack_adj = 128; + endcase + end + 4'b1110: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 96; + 2'b01: stack_adj = 112; + 2'b10: stack_adj = 128; + 2'b11: stack_adj = 144; + endcase + end + 4'b1111: begin + unique case (instr_i[3:2]) + 2'b00: stack_adj = 112; + 2'b01: stack_adj = 128; + 2'b10: stack_adj = 144; + 2'b11: stack_adj = 160; + endcase + end + endcase + end + + //Take 2's compliment in case of PUSH instruction + if (zcmp_instr_type == PUSH) begin + itype_inst.imm = ~stack_adj + 1'b1; + end else begin + itype_inst.imm = stack_adj - 3'b100; + end + end else begin + illegal_instr_o = illegal_instr_i; + instr_o_reg = instr_i; + end + + unique case (state_q) + IDLE: begin + if (is_zcmp_instr_i && issue_ack_i) begin + reg_numbers_d = reg_numbers - 1'b1; + state_d = INIT; + case (zcmp_instr_type) + PUSH: begin + offset_d = 12'hFFC + 12'hFFC; + end + POP, POPRETZ, POPRET: begin + offset_d = itype_inst.imm + 12'hFFC; + offset_reg = itype_inst.imm; + case (zcmp_instr_type) + POPRETZ: begin + popretz_inst_d = 2'b11; + end + POPRET: begin + popretz_inst_d = 2'b01; + end + default: begin + popretz_inst_d = 'b0; + end + endcase + end + default: ; + endcase + // when rlist is 4, max reg is x18 i.e. 14(const) + 4 + // when rlist is 12, max reg is x27 i.e. 15(const) + 12 + if (reg_numbers == 4'b1100) begin + store_reg_d = 4'b1110 + reg_numbers; + store_reg = 4'b1111 + reg_numbers; + end else begin + store_reg_d = 4'b1101 + reg_numbers; + store_reg = 4'b1110 + reg_numbers; + end + + if (zcmp_instr_type == MVSA01) begin + fetch_stall_o = 1; + is_mv_zcmp_instr_o = 1; + // addi xreg1, a0, 0 + instr_o_reg = {12'h0, 5'hA, 3'h0, xreg1, riscv::OpcodeOpImm}; + state_d = MOVE; + end + + if (zcmp_instr_type == MVA01S) begin + fetch_stall_o = 1; + is_mv_zcmp_instr_o = 1; + // addi a0, xreg1, 0 + instr_o_reg = {12'h0, xreg1, 3'h0, 5'hA, riscv::OpcodeOpImm}; + state_d = MOVE; + end + + if (zcmp_instr_type == PUSH) begin + + fetch_stall_o = 1'b1; // stall inst fetch + + if (reg_numbers == 4'b0001) begin + if (riscv::XLEN == 64) begin + instr_o_reg = { + 7'b1111111, 5'h1, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore + }; // sd store_reg, -4(sp) + end else begin + instr_o_reg = { + 7'b1111111, 5'h1, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore + }; // sw store_reg, -4(sp) + end + state_d = PUSH_ADDI; + end + + if (reg_numbers == 4'b0010) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {7'b1111111, 5'h8, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore}; + end else begin + instr_o_reg = {7'b1111111, 5'h8, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore}; + end + end + + if (reg_numbers == 4'b0011) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {7'b1111111, 5'h9, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore}; + end else begin + instr_o_reg = {7'b1111111, 5'h9, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore}; + end + + end + + if (reg_numbers >= 4 && reg_numbers <= 12) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {7'b1111111, store_reg, 5'h2, 3'h3, 5'b11000, riscv::OpcodeStore}; + end else begin + instr_o_reg = {7'b1111111, store_reg, 5'h2, 3'h2, 5'b11100, riscv::OpcodeStore}; + end + + if (reg_numbers == 12) begin + state_d = PUSH_POP_INSTR_2; + end + end + end + + if ((zcmp_instr_type == POP || zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + fetch_stall_o = 1; // stall inst fetch + if (reg_numbers == 1) begin + if (riscv::XLEN == 64) begin + instr_o_reg = { + offset_reg - 4, 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad + }; // ld store_reg, Imm(sp) + end else begin + instr_o_reg = { + offset_reg, 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad + }; // lw store_reg, Imm(sp) + end + unique case (zcmp_instr_type) + PUSH, POP, POPRET: begin + state_d = PUSH_ADDI; + end + POPRETZ: begin + state_d = POPRETZ_1; + end + default: ; + endcase + end + + if (reg_numbers == 2) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_reg - 4, 5'h2, 3'h3, 5'h8, riscv::OpcodeLoad}; + end else begin + instr_o_reg = {offset_reg, 5'h2, 3'h2, 5'h8, riscv::OpcodeLoad}; + end + end + + if (reg_numbers == 3) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_reg - 4, 5'h2, 3'h3, 5'h9, riscv::OpcodeLoad}; + end else begin + instr_o_reg = {offset_reg, 5'h2, 3'h2, 5'h9, riscv::OpcodeLoad}; + end + end + + if (reg_numbers >= 4 && reg_numbers <= 12) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_reg - 4, 5'h2, 3'h3, store_reg, riscv::OpcodeLoad}; + end else begin + instr_o_reg = {offset_reg, 5'h2, 3'h2, store_reg, riscv::OpcodeLoad}; + end + + if (reg_numbers == 12) begin + state_d = PUSH_POP_INSTR_2; + end + end + end + end + end + INIT: begin + fetch_stall_o = 1'b1; // stall inst fetch + if (issue_ack_i && is_zcmp_instr_i && zcmp_instr_type == PUSH) begin + if (reg_numbers_q == 4'b0001) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_d[11:5], 5'h1, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; + end else begin + instr_o_reg = {offset_d[11:5], 5'h1, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore}; + end + state_d = PUSH_ADDI; + end + + if (reg_numbers_q == 4'b0010) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_d[11:5], 5'h8, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; + end else begin + instr_o_reg = {offset_d[11:5], 5'h8, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore}; + end + reg_numbers_d = reg_numbers_q - 1; + offset_d = offset_q + 12'hFFC; // decrement offset by -4 i.e. add 2's compilment of 4 + end + + if (reg_numbers_q == 4'b0011) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_d[11:5], 5'h9, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; + end else begin + instr_o_reg = {offset_d[11:5], 5'h9, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore}; + end + reg_numbers_d = reg_numbers_q - 1; + offset_d = offset_q + 12'hFFC; + end + + if (reg_numbers_q >= 4 && reg_numbers_q <= 12) begin + if (riscv::XLEN == 64) begin + instr_o_reg = { + offset_d[11:5], store_reg_q, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore + }; + end else begin + instr_o_reg = { + offset_d[11:5], store_reg_q, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore + }; + end + reg_numbers_d = reg_numbers_q - 1; + store_reg_d = store_reg_q - 1; + offset_d = offset_q + 12'hFFC; + if (reg_numbers_q == 12) begin + state_d = PUSH_POP_INSTR_2; + end + end + end + + if (issue_ack_i && is_zcmp_instr_i && (zcmp_instr_type == POP || zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + + if (reg_numbers_q == 1) begin + if (riscv::XLEN == 64) begin + instr_o_reg = {offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad}; + end else begin + instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad}; + end + unique case (zcmp_instr_type) + PUSH, POP, POPRET: begin + state_d = PUSH_ADDI; + end + POPRETZ: begin + state_d = POPRETZ_1; + end + default: ; + endcase + end + + if (reg_numbers_q == 2) begin + if (riscv::XLEN == 64) begin + instr_o_reg = { + offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h8, riscv::OpcodeLoad + }; + end else begin + instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h8, riscv::OpcodeLoad}; + end + reg_numbers_d = reg_numbers_q - 1; + offset_d = offset_q + 12'hFFC; // decrement offset by -4 i.e. add 2's compilment of 4 + end + + if (reg_numbers_q == 3) begin + if (riscv::XLEN == 64) begin + instr_o_reg = { + offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h9, riscv::OpcodeLoad + }; + end else begin + instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h9, riscv::OpcodeLoad}; + end + reg_numbers_d = reg_numbers_q - 1; + offset_d = offset_q + 12'hFFC; + end + + if (reg_numbers_q >= 4 && reg_numbers_q <= 12) begin + if (riscv::XLEN == 64) begin + instr_o_reg = { + offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, store_reg_q, riscv::OpcodeLoad + }; + end else begin + instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, store_reg_q, riscv::OpcodeLoad}; + end + reg_numbers_d = reg_numbers_q - 1; + store_reg_d = store_reg_q - 1; + offset_d = offset_q + 12'hFFC; + if (reg_numbers_q == 12) begin + state_d = PUSH_POP_INSTR_2; + end + end + end + end + + MOVE: begin + case (zcmp_instr_type) + MVSA01: begin + if (issue_ack_i) begin + // addi xreg2, a1, 0 + instr_o_reg = {12'h0, 5'hB, 3'h0, xreg2, riscv::OpcodeOpImm}; + fetch_stall_o = 0; + is_last_zcmp_instr_o = 1; + is_mv_zcmp_instr_o = 1; + state_d = IDLE; + end + end + MVA01S: begin + if (issue_ack_i) begin + // addi a1, xreg2, 0 + instr_o_reg = {12'h0, xreg2, 3'h0, 5'hB, riscv::OpcodeOpImm}; + fetch_stall_o = 0; + is_last_zcmp_instr_o = 1; + is_mv_zcmp_instr_o = 1; + state_d = IDLE; + end + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + fetch_stall_o = 1; + end + + PUSH_ADDI: begin + if (riscv::XLEN == 64) begin + if (issue_ack_i && is_zcmp_instr_i && zcmp_instr_type == PUSH) begin + // addi sp, sp, stack_adj + instr_o_reg = {itype_inst.imm - 4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; + end else begin + if (issue_ack_i) begin + instr_o_reg = {stack_adj - 4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; + end + end + if (issue_ack_i && is_zcmp_instr_i && (zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + state_d = POPRETZ_1; + fetch_stall_o = 1; + end else begin + if (issue_ack_i) begin + state_d = IDLE; + fetch_stall_o = 0; + is_last_zcmp_instr_o = 1; + end else begin + fetch_stall_o = 1; + end + end + end else begin + if (issue_ack_i && is_zcmp_instr_i && zcmp_instr_type == PUSH) begin + // addi sp, sp, stack_adj + instr_o_reg = {itype_inst.imm, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; + end else begin + if (issue_ack_i) begin + instr_o_reg = {stack_adj, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; + end + end + if (issue_ack_i && is_zcmp_instr_i && (zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + state_d = POPRETZ_1; + fetch_stall_o = 1; + end else begin + if (issue_ack_i) begin + state_d = IDLE; + fetch_stall_o = 0; + is_last_zcmp_instr_o = 1; + end else begin + fetch_stall_o = 1; + end + end + end + end + + PUSH_POP_INSTR_2: begin + if (riscv::XLEN == 64) begin + case (zcmp_instr_type) + PUSH: begin + if (issue_ack_i) begin + instr_o_reg = { + offset_d[11:5], + store_reg_q, + 5'h2, + 3'h3, + offset_d[4:3], + 1'b0, + offset_d[1:0], + riscv::OpcodeStore + }; + offset_d = offset_q + 12'hFFC; + store_reg_d = store_reg_q - 1; + state_d = INIT; + end + end + POP, POPRETZ, POPRET: begin + if (issue_ack_i) begin + instr_o_reg = { + offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, store_reg_q, riscv::OpcodeLoad + }; + offset_d = offset_q + 12'hFFC; + store_reg_d = store_reg_q - 1; + state_d = INIT; + end + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + end else begin + case (zcmp_instr_type) + PUSH: begin + if (issue_ack_i) begin + instr_o_reg = { + offset_d[11:5], store_reg_q, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore + }; + offset_d = offset_q + 12'hFFC; + store_reg_d = store_reg_q - 1; + state_d = INIT; + end + end + POP, POPRETZ, POPRET: begin + if (issue_ack_i) begin + instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, store_reg_q, riscv::OpcodeLoad}; + offset_d = offset_q + 12'hFFC; + store_reg_d = store_reg_q - 1; + state_d = INIT; + end + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + end + fetch_stall_o = 1; + end + + POPRETZ_1: begin + unique case (popretz_inst_q) + 2'b11: begin + if (issue_ack_i) begin + instr_o_reg = {20'h0, 5'hA, riscv::OpcodeLui}; //lui a0, 0x0 + popretz_inst_d = popretz_inst_q - 1; + end + fetch_stall_o = 1; + end + 2'b10: begin + if (issue_ack_i) begin + instr_o_reg = {12'h0, 5'hA, 3'h0, 5'hA, riscv::OpcodeOpImm}; //addi a0, a0, 0x0 + popretz_inst_d = popretz_inst_q - 1; + state_d = PUSH_ADDI; + end + fetch_stall_o = 1; + end + 2'b01: begin + if (issue_ack_i) begin + instr_o_reg = {12'h0, 5'h1, 3'h0, 5'h0, riscv::OpcodeJalr}; //ret - jalr x0, x1, 0 + state_d = IDLE; + fetch_stall_o = 0; + is_last_zcmp_instr_o = 1; + popretz_inst_d = popretz_inst_q - 1; + end + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + endcase + end + default: begin + state_d = IDLE; + end + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + state_q <= IDLE; + offset_q <= '0; + popretz_inst_q <= '0; + reg_numbers_q <= '0; + store_reg_q <= '0; + end else begin + state_q <= state_d; + offset_q <= offset_d; + reg_numbers_q <= reg_numbers_d; + store_reg_q <= store_reg_d; + popretz_inst_q <= popretz_inst_d; + end + end +endmodule + From 2cccfa52f1235365c2b007c6bed34a432cf25392 Mon Sep 17 00:00:00 2001 From: rohan Date: Fri, 23 Feb 2024 17:33:20 +0500 Subject: [PATCH 02/15] added tesst for zcmp instructions --- verif/tests/custom/Zcmp/cm_mva01s_test.S | 32 ++ verif/tests/custom/Zcmp/cm_mvsa01_test.S | 32 ++ verif/tests/custom/Zcmp/cm_popret_test.S | 58 +++ verif/tests/custom/Zcmp/cm_popretz_test.S | 57 +++ verif/tests/custom/Zcmp/cm_push_pop_test.S | 59 +++ verif/tests/custom/Zcmp/link.ld | 66 +++ verif/tests/custom/Zcmp/readme.txt | 2 + verif/tests/custom/Zcmp/riscv_test.h | 269 +++++++++++ verif/tests/custom/Zcmp/syscalls.c | 521 +++++++++++++++++++++ verif/tests/custom/Zcmp/util.h | 92 ++++ 10 files changed, 1188 insertions(+) create mode 100644 verif/tests/custom/Zcmp/cm_mva01s_test.S create mode 100644 verif/tests/custom/Zcmp/cm_mvsa01_test.S create mode 100644 verif/tests/custom/Zcmp/cm_popret_test.S create mode 100644 verif/tests/custom/Zcmp/cm_popretz_test.S create mode 100644 verif/tests/custom/Zcmp/cm_push_pop_test.S create mode 100644 verif/tests/custom/Zcmp/link.ld create mode 100644 verif/tests/custom/Zcmp/readme.txt create mode 100644 verif/tests/custom/Zcmp/riscv_test.h create mode 100644 verif/tests/custom/Zcmp/syscalls.c create mode 100644 verif/tests/custom/Zcmp/util.h diff --git a/verif/tests/custom/Zcmp/cm_mva01s_test.S b/verif/tests/custom/Zcmp/cm_mva01s_test.S new file mode 100644 index 0000000000..3c6b38a8f6 --- /dev/null +++ b/verif/tests/custom/Zcmp/cm_mva01s_test.S @@ -0,0 +1,32 @@ +#include "riscv_test.h" + +RVTEST_RV32U +RVTEST_CODE_BEGIN + + li s1, 5 + li s2, 7 + cm.mva01s s1, s2 + + bne a0, s1, failure + beq a1, s2, success +failure: + li x1, 1 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop_2: j self_loop_2 + +success: + li x1, 0 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop: j self_loop + +RVTEST_CODE_END + +.data + +RVTEST_DATA_BEGIN + +RVTEST_DATA_END diff --git a/verif/tests/custom/Zcmp/cm_mvsa01_test.S b/verif/tests/custom/Zcmp/cm_mvsa01_test.S new file mode 100644 index 0000000000..6c99794bd7 --- /dev/null +++ b/verif/tests/custom/Zcmp/cm_mvsa01_test.S @@ -0,0 +1,32 @@ +#include "riscv_test.h" + +RVTEST_RV32U +RVTEST_CODE_BEGIN + + li a0, 5 + li a1, 7 + cm.mvsa01 s1, s2 + + bne a0, s1, failure + beq a1, s2, success +failure: + li x1, 1 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop_2: j self_loop_2 + +success: + li x1, 0 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop: j self_loop + +RVTEST_CODE_END + +.data + +RVTEST_DATA_BEGIN + +RVTEST_DATA_END diff --git a/verif/tests/custom/Zcmp/cm_popret_test.S b/verif/tests/custom/Zcmp/cm_popret_test.S new file mode 100644 index 0000000000..55669c22bd --- /dev/null +++ b/verif/tests/custom/Zcmp/cm_popret_test.S @@ -0,0 +1,58 @@ +#include "riscv_test.h" + +RVTEST_RV32U +RVTEST_CODE_BEGIN + //Initialize the stack + la sp, stack + + // Load the first number into register a0 + lw s0, num1 + + // Load the second number into register a1 + lw s1, num2 + + //Load the result into register a2 + lw a2, result + + //Two consecutive move instructions replaced by the compressed move instruction + //mv s0, a0 + //mv s1, a1 + + //Push the registers to stack + jal push_pop + + // Add the numbers and store the result in register t2 + add t2, s0, s1 + + // Store the result in the memory location reserved for it + beq t2, a2, success +failure: + li x1, 1 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop_2: j self_loop_2 + +success: + li x1, 0 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop: j self_loop + +push_pop: + cm.push {ra, s0-s1}, -16 + nop + cm.popret {ra, s0-s1}, 16 + +RVTEST_CODE_END + +.data + num1: .word 5 // First number + num2: .word 7 // Second number + result: .word 12 // Result + stack: .space 100 + +RVTEST_DATA_BEGIN + +RVTEST_DATA_END diff --git a/verif/tests/custom/Zcmp/cm_popretz_test.S b/verif/tests/custom/Zcmp/cm_popretz_test.S new file mode 100644 index 0000000000..4a5f4eb07b --- /dev/null +++ b/verif/tests/custom/Zcmp/cm_popretz_test.S @@ -0,0 +1,57 @@ +#include "riscv_test.h" + +RVTEST_RV32U +RVTEST_CODE_BEGIN + //Initialize the stack + la sp, stack + + // Load the first number into register a0 + lw s0, num1 + + // Load the second number into register a1 + lw s1, num2 + + //Load the result into register a2 + lw a2, result + + //Two consecutive move instructions replaced by the compressed move instruction + //mv s0, a0 + //mv s1, a1 + + //Push the registers to stack + jal push_pop + + // Add the numbers and store the result in register t2 + add t2, s0, s1 + + // Store the result in the memory location reserved for it + beq t2, a2, success +failure: + li x1, 1 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop_2: j self_loop_2 + +success: + li x1, 0 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop: j self_loop + +push_pop: + cm.push {ra, s0-s1}, -16 + nop + cm.popretz {ra, s0-s1}, 16 +RVTEST_CODE_END + +.data + num1: .word 5 // First number + num2: .word 7 // Second number + result: .word 12 // Result + stack: .space 100 + +RVTEST_DATA_BEGIN + +RVTEST_DATA_END diff --git a/verif/tests/custom/Zcmp/cm_push_pop_test.S b/verif/tests/custom/Zcmp/cm_push_pop_test.S new file mode 100644 index 0000000000..28a0af8f08 --- /dev/null +++ b/verif/tests/custom/Zcmp/cm_push_pop_test.S @@ -0,0 +1,59 @@ +#include "riscv_test.h" + +RVTEST_RV32U +RVTEST_CODE_BEGIN + //Initialize the stack + la sp, stack + + // Load the first number into register a0 + lw s0, num1 + + // Load the second number into register a1 + lw s1, num2 + + //Load the result into register a2 + lw a2, result + + //Two consecutive move instructions replaced by the compressed move instruction + //mv s0, a0 + //mv s1, a1 + + //Push the registers to stack + jal push_pop + + // Add the numbers and store the result in register t2 + add t2, s0, s1 + + // Store the result in the memory location reserved for it + beq t2, a2, success +failure: + li x1, 1 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop_2: j self_loop_2 + +success: + li x1, 0 + slli x1, x1, 1 + addi x1, x1, 1 + sw x1, tohost, t5 + self_loop: j self_loop + +push_pop: + cm.push {ra, s0-s1}, -16 + nop + cm.pop {ra, s0-s1}, 16 + jr ra + +RVTEST_CODE_END + +.data + num1: .word 5 // First number + num2: .word 7 // Second number + result: .word 12 // Result + stack: .space 100 + +RVTEST_DATA_BEGIN + +RVTEST_DATA_END diff --git a/verif/tests/custom/Zcmp/link.ld b/verif/tests/custom/Zcmp/link.ld new file mode 100644 index 0000000000..6135e79df0 --- /dev/null +++ b/verif/tests/custom/Zcmp/link.ld @@ -0,0 +1,66 @@ +/*======================================================================*/ +/* Proxy kernel linker script */ +/*======================================================================*/ +/* This is the linker script used when building the proxy kernel. */ + +/*----------------------------------------------------------------------*/ +/* Setup */ +/*----------------------------------------------------------------------*/ + +/* The OUTPUT_ARCH command specifies the machine architecture where the + argument is one of the names used in the BFD library. More + specifically one of the entires in bfd/cpu-mips.c */ + +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + +/*----------------------------------------------------------------------*/ +/* Sections */ +/*----------------------------------------------------------------------*/ + +SECTIONS +{ + + /* text: test code section */ + . = 0x80000000; + .text.init : { *(.text.init) } + + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + + . = ALIGN(0x1000); + .text : { *(.text) } + + /* data segment */ + .data : { *(.data) } + + .sdata : { + __global_pointer$ = . + 0x800; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : { *(.bss) } + + /* thread-local data segment */ + .tdata : + { + _tdata_begin = .; + *(.tdata) + _tdata_end = .; + } + .tbss : + { + *(.tbss) + _tbss_end = .; + } + + /* End of uninitalized data segement */ + _end = .; +} + diff --git a/verif/tests/custom/Zcmp/readme.txt b/verif/tests/custom/Zcmp/readme.txt new file mode 100644 index 0000000000..fe08325bca --- /dev/null +++ b/verif/tests/custom/Zcmp/readme.txt @@ -0,0 +1,2 @@ +Use the following command to build the test binaries (example for cm_push_pop_test.S): + riscv32-corev-elf-gcc -static -mcmodel=medany -fvisibility=hidden -nostdlib -g syscalls.c -lgcc -Tlink.ld -march=rv32gc_zcmp -o cm_push_pop_test.elf cm_push_pop_test.S diff --git a/verif/tests/custom/Zcmp/riscv_test.h b/verif/tests/custom/Zcmp/riscv_test.h new file mode 100644 index 0000000000..91a2e2b785 --- /dev/null +++ b/verif/tests/custom/Zcmp/riscv_test.h @@ -0,0 +1,269 @@ +// See LICENSE for license details. + +#ifndef _ENV_PHYSICAL_SINGLE_CORE_H +#define _ENV_PHYSICAL_SINGLE_CORE_H + +#include "encoding.h" + +//----------------------------------------------------------------------- +// Begin Macro +//----------------------------------------------------------------------- + +#define RVTEST_RV64U \ + .macro init; \ + .endm + +#define RVTEST_RV64UF \ + .macro init; \ + RVTEST_FP_ENABLE; \ + .endm + +#define RVTEST_RV64UV \ + .macro init; \ + RVTEST_VECTOR_ENABLE; \ + .endm + +#define RVTEST_RV32U \ + .macro init; \ + .endm + +#define RVTEST_RV32UF \ + .macro init; \ + RVTEST_FP_ENABLE; \ + .endm + +#define RVTEST_RV32UV \ + .macro init; \ + RVTEST_VECTOR_ENABLE; \ + .endm + +#define RVTEST_RV64M \ + .macro init; \ + RVTEST_ENABLE_MACHINE; \ + .endm + +#define RVTEST_RV64S \ + .macro init; \ + RVTEST_ENABLE_SUPERVISOR; \ + .endm + +#define RVTEST_RV32M \ + .macro init; \ + RVTEST_ENABLE_MACHINE; \ + .endm + +#define RVTEST_RV32S \ + .macro init; \ + RVTEST_ENABLE_SUPERVISOR; \ + .endm + +#if __riscv_xlen == 64 +# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1: +#else +# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1: +#endif + +#define INIT_XREG \ + li x1, 0; \ + li x2, 0; \ + li x3, 0; \ + li x4, 0; \ + li x5, 0; \ + li x6, 0; \ + li x7, 0; \ + li x8, 0; \ + li x9, 0; \ + li x10, 0; \ + li x11, 0; \ + li x12, 0; \ + li x13, 0; \ + li x14, 0; \ + li x15, 0; \ + li x16, 0; \ + li x17, 0; \ + li x18, 0; \ + li x19, 0; \ + li x20, 0; \ + li x21, 0; \ + li x22, 0; \ + li x23, 0; \ + li x24, 0; \ + li x25, 0; \ + li x26, 0; \ + li x27, 0; \ + li x28, 0; \ + li x29, 0; \ + li x30, 0; \ + li x31, 0; + +#define INIT_PMP \ + la t0, 1f; \ + csrw mtvec, t0; \ + /* Set up a PMP to permit all accesses */ \ + li t0, (1 << (31 + (__riscv_xlen / 64) * (53 - 31))) - 1; \ + csrw pmpaddr0, t0; \ + li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \ + csrw pmpcfg0, t0; \ + .align 2; \ +1: + +#define INIT_SATP \ + la t0, 1f; \ + csrw mtvec, t0; \ + csrwi sptbr, 0; \ + .align 2; \ +1: + +#define DELEGATE_NO_TRAPS \ + la t0, 1f; \ + csrw mtvec, t0; \ + csrwi medeleg, 0; \ + csrwi mideleg, 0; \ + csrwi mie, 0; \ + .align 2; \ +1: + +#define RVTEST_ENABLE_SUPERVISOR \ + li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \ + csrs mstatus, a0; \ + li a0, SIP_SSIP | SIP_STIP; \ + csrs mideleg, a0; \ + +#define RVTEST_ENABLE_MACHINE \ + li a0, MSTATUS_MPP; \ + csrs mstatus, a0; \ + +#define RVTEST_FP_ENABLE \ + li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \ + csrs mstatus, a0; \ + csrwi fcsr, 0 + +#define RVTEST_VECTOR_ENABLE \ + li a0, (MSTATUS_VS & (MSTATUS_VS >> 1)) | \ + (MSTATUS_FS & (MSTATUS_FS >> 1)); \ + csrs mstatus, a0; \ + csrwi fcsr, 0; \ + csrwi vcsr, 0; + +#define RISCV_MULTICORE_DISABLE \ + csrr a0, mhartid; \ + 1: bnez a0, 1b + +#define EXTRA_TVEC_USER +#define EXTRA_TVEC_MACHINE +#define EXTRA_INIT +#define EXTRA_INIT_TIMER + +#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */ + +#define RVTEST_CODE_BEGIN \ + .section .text.init; \ + .align 6; \ + .weak stvec_handler; \ + .weak mtvec_handler; \ + .globl _start; \ +_start: \ + /* reset vector */ \ + j reset_vector; \ + .align 2; \ +trap_vector: \ + /* test whether the test came from pass/fail */ \ + csrr t5, mcause; \ + li t6, CAUSE_USER_ECALL; \ + beq t5, t6, write_tohost; \ + li t6, CAUSE_SUPERVISOR_ECALL; \ + beq t5, t6, write_tohost; \ + li t6, CAUSE_MACHINE_ECALL; \ + beq t5, t6, write_tohost; \ + /* if an mtvec_handler is defined, jump to it */ \ + la t5, mtvec_handler; \ + beqz t5, 1f; \ + jr t5; \ + /* was it an interrupt or an exception? */ \ + 1: csrr t5, mcause; \ + bgez t5, handle_exception; \ + INTERRUPT_HANDLER; \ +handle_exception: \ + /* we don't know how to handle whatever the exception was */ \ + other_exception: \ + /* some unhandlable exception occurred */ \ + 1: ori TESTNUM, TESTNUM, 1337; \ + write_tohost: \ + sw TESTNUM, tohost, t5; \ + j write_tohost; \ +reset_vector: \ + INIT_XREG; \ + RISCV_MULTICORE_DISABLE; \ + INIT_SATP; \ + INIT_PMP; \ + DELEGATE_NO_TRAPS; \ + li TESTNUM, 0; \ + la t0, trap_vector; \ + csrw mtvec, t0; \ + CHECK_XLEN; \ + /* if an stvec_handler is defined, delegate exceptions to it */ \ + la t0, stvec_handler; \ + beqz t0, 1f; \ + csrw stvec, t0; \ + li t0, (1 << CAUSE_LOAD_PAGE_FAULT) | \ + (1 << CAUSE_STORE_PAGE_FAULT) | \ + (1 << CAUSE_FETCH_PAGE_FAULT) | \ + (1 << CAUSE_MISALIGNED_FETCH) | \ + (1 << CAUSE_USER_ECALL) | \ + (1 << CAUSE_BREAKPOINT); \ + csrw medeleg, t0; \ +1: csrwi mstatus, 0; \ + init; \ + EXTRA_INIT; \ + EXTRA_INIT_TIMER; \ + la t0, 1f; \ + csrw mepc, t0; \ + csrr a0, mhartid; \ + mret; \ +1: + +//----------------------------------------------------------------------- +// End Macro +//----------------------------------------------------------------------- + +#define RVTEST_CODE_END \ + unimp + +//----------------------------------------------------------------------- +// Pass/Fail Macro +//----------------------------------------------------------------------- + +#define RVTEST_PASS \ + fence; \ + li TESTNUM, 1; \ + li a7, 93; \ + li a0, 0; \ + ecall + +#define TESTNUM gp +#define RVTEST_FAIL \ + fence; \ +1: beqz TESTNUM, 1b; \ + sll TESTNUM, TESTNUM, 1; \ + or TESTNUM, TESTNUM, 1; \ + li a7, 93; \ + addi a0, TESTNUM, 0; \ + ecall + +//----------------------------------------------------------------------- +// Data Section Macro +//----------------------------------------------------------------------- + +#define EXTRA_DATA + +#define RVTEST_DATA_BEGIN \ + EXTRA_DATA \ + .pushsection .tohost,"aw",@progbits; \ + .align 6; .global tohost; tohost: .dword 0; \ + .align 6; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 4; .global begin_signature; begin_signature: + +#define RVTEST_DATA_END .align 4; .global end_signature; end_signature: + +#endif diff --git a/verif/tests/custom/Zcmp/syscalls.c b/verif/tests/custom/Zcmp/syscalls.c new file mode 100644 index 0000000000..ebb9a87275 --- /dev/null +++ b/verif/tests/custom/Zcmp/syscalls.c @@ -0,0 +1,521 @@ +// See LICENSE for license details. + +#include +#include +#include +#include +#include +#include +#include "util.h" + +#define SYS_write 64 + +#undef strcmp + +extern volatile uint64_t tohost; +extern volatile uint64_t fromhost; + +// tohost is 64 bits wide, irrespective of XLEN. The structure expected in Spike is: +// - tohost[63:56] == device (syscall: 0) +// - tohost[55:48] == command (syscall: 0) +// - tohost[47:0] == payload (syscall: address of magic_mem) +// +// magic_mem for a syscall contains the following elements (XLEN bits each) +// - syscall index (93 dec for syscall_exit, cf. Spike values in +// riscv-isa-sim/fesvr/syscall.cc:140 and ff.) +// - syscall args in the declaration order of the given syscall + +static uintptr_t syscall(uintptr_t which, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2) +{ + // Arguments in magic_mem have XLEN bits each. + volatile uintptr_t magic_mem[8] __attribute__((aligned(64))); + magic_mem[0] = which; + magic_mem[1] = arg0; + magic_mem[2] = arg1; + magic_mem[3] = arg2; +#ifdef __riscv_atomic // __sync_synchronize requires A extension + __sync_synchronize(); +#endif + + // A WRITE_MEM transaction writing non-zero value to TOHOST triggers + // the environment (Spike or RTL harness). + // - here tohost is guaranteed non-NULL because magic_mem is a valid RISC-V + // pointer. + // - the environment acknowledges the env request by writing 0 into tohost. + // - the completion of the request is signalled by the environment through + // a write of a non-zero value into fromhost. + tohost = (((uint64_t) ((unsigned long int) magic_mem)) << 16) >> 16; // clear the DEV and CMD bytes, clip payload. + while (fromhost == 0) + ; + fromhost = 0; + +#ifdef __riscv_atomic // __sync_synchronize requires A extension + __sync_synchronize(); +#endif + return magic_mem[0]; +} + +#define NUM_COUNTERS 2 +static uintptr_t counters[NUM_COUNTERS]; +static char* counter_names[NUM_COUNTERS]; + +void setStats(int enable) +{ + int i = 0; +#define READ_CTR(name) do { \ + while (i >= NUM_COUNTERS) ; \ + uintptr_t csr = read_csr(name); \ + if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \ + counters[i++] = csr; \ + } while (0) + + READ_CTR(mcycle); + READ_CTR(minstret); + +#undef READ_CTR +} + +uintptr_t getStats(int counterid) +{ + return counters[counterid]; +} + +void __attribute__((noreturn)) tohost_exit(uintptr_t code) +{ + // Simply write PASS/FAIL result into 'tohost'. + // Left shift 'code' by 1 and set bit 0 to 1, but leave the 16 uppermost bits clear + // so that the syscall is properly recognized even if 'code' value is very large. + tohost = ((((uint64_t) code) << 17) >> 16) | 1; + + // Do not care about the value returned by host. + // Leave 1 cycle of slack (one NOP instruction) to help debugging + // the termination mechanism if needed. + __asm__("nop\n\t"); + + // Go into an endless loop if the write into 'tohost' did not terminate the simulation. + while (1); +} + +uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) +{ + tohost_exit(1337); +} + +void exit(int code) +{ + tohost_exit(code); +} + +void abort() +{ + exit(128 + SIGABRT); +} + +void printstr(const char* s) +{ +#if !NOPRINT + syscall(SYS_write, 1, (uintptr_t)s, strlen(s)); +#endif +} + +void __attribute__((weak)) thread_entry(int cid, int nc) +{ + // multi-threaded programs override this function. + // for the case of single-threaded programs, only let core 0 proceed. + while (cid != 0); +} + +int __attribute__((weak)) main(int argc, char** argv) +{ + // single-threaded programs override this function. + printstr("Implement main(), foo!\n"); + return -1; +} + +static void init_tls() +{ + register void* thread_pointer asm("tp"); + extern char _tdata_begin, _tdata_end, _tbss_end; + size_t tdata_size = &_tdata_end - &_tdata_begin; + memcpy(thread_pointer, &_tdata_begin, tdata_size); + size_t tbss_size = &_tbss_end - &_tdata_end; + memset(thread_pointer + tdata_size, 0, tbss_size); +} + +void _init(int cid, int nc) +{ + init_tls(); + thread_entry(cid, nc); + + // only single-threaded programs should ever get here. + int ret = main(0, 0); + + char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); + char* pbuf = buf; + for (int i = 0; i < NUM_COUNTERS; i++) + if (counters[i]) + pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); + if (pbuf != buf) + printstr(buf); + + exit(ret); +} + +int puts(const char *s) +{ + const char *p = s; + + while (*p) + putchar(*p++); + + putchar('\n'); + return 0; +} + +#undef putchar +int putchar(int ch) +{ +#if !NOPRINT + static __thread char buf[64] __attribute__((aligned(64))); + static __thread int buflen = 0; + + buf[buflen++] = ch; + + if (ch == '\n' || buflen == sizeof(buf)) + { + syscall(SYS_write, 1, (uintptr_t)buf, buflen); + buflen = 0; + } +#endif + + return 0; +} + +void printhex(uint64_t x) +{ + char str[17]; + int i; + for (i = 0; i < 16; i++) + { + str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10); + x >>= 4; + } + str[16] = 0; + + printstr(str); +} + +static inline void printnum(void (*putch)(int, void**), void **putdat, + unsigned long long num, unsigned base, int width, int padc) +{ + unsigned digs[sizeof(num)*CHAR_BIT]; + int pos = 0; + + while (1) + { + digs[pos++] = num % base; + if (num < base) + break; + num /= base; + } + + while (width-- > pos) + putch(padc, putdat); + + while (pos-- > 0) + putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); +} + +static unsigned long long getuint(va_list *ap, int lflag) +{ + if (lflag >= 2) + return va_arg(*ap, unsigned long long); + else if (lflag) + return va_arg(*ap, unsigned long); + else + return va_arg(*ap, unsigned int); +} + +static long long getint(va_list *ap, int lflag) +{ + if (lflag >= 2) + return va_arg(*ap, long long); + else if (lflag) + return va_arg(*ap, long); + else + return va_arg(*ap, int); +} + +static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap) +{ + register const char* p; + const char* last_fmt; + register int ch, err; + unsigned long long num; + int base, lflag, width, precision, altflag; + char padc; + + while (1) { + while ((ch = *(unsigned char *) fmt) != '%') { + if (ch == '\0') + return; + fmt++; + putch(ch, putdat); + } + fmt++; + + // Process a %-escape sequence + last_fmt = fmt; + padc = ' '; + width = -1; + precision = -1; + lflag = 0; + altflag = 0; + reswitch: + switch (ch = *(unsigned char *) fmt++) { + + // flag to pad on the right + case '-': + padc = '-'; + goto reswitch; + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + goto reswitch; + + // width field + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + for (precision = 0; ; ++fmt) { + precision = precision * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + goto process_precision; + + case '.': + if (width < 0) + width = 0; + goto reswitch; + + case '#': + altflag = 1; + goto reswitch; + + process_precision: + if (width < 0) + width = precision, precision = -1; + goto reswitch; + + // long flag (doubled for long long) + case 'l': + lflag++; + goto reswitch; + + // character + case 'c': + putch(va_arg(ap, int), putdat); + break; + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) + p = "(null)"; + if (width > 0 && padc != '-') + for (width -= strnlen(p, precision); width > 0; width--) + putch(padc, putdat); + for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { + putch(ch, putdat); + p++; + } + for (; width > 0; width--) + putch(' ', putdat); + break; + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + if ((long long) num < 0) { + putch('-', putdat); + num = -(long long) num; + } + base = 10; + goto signed_number; + + // unsigned decimal + case 'u': + base = 10; + goto unsigned_number; + + // (unsigned) octal + case 'o': + // should do something with padding so it's always 3 octits + base = 8; + goto unsigned_number; + + // pointer + case 'p': + static_assert(sizeof(long) == sizeof(void*)); + lflag = 1; + putch('0', putdat); + putch('x', putdat); + /* fall through to 'x' */ + + // (unsigned) hexadecimal + case 'x': + base = 16; + unsigned_number: + num = getuint(&ap, lflag); + signed_number: + printnum(putch, putdat, num, base, width, padc); + break; + + // escaped '%' character + case '%': + putch(ch, putdat); + break; + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + fmt = last_fmt; + break; + } + } +} + +int printf(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + vprintfmt((void*)putchar, 0, fmt, ap); + + va_end(ap); + return 0; // incorrect return value, but who cares, anyway? +} + +int sprintf(char* str, const char* fmt, ...) +{ + va_list ap; + char* str0 = str; + va_start(ap, fmt); + + void sprintf_putch(int ch, void** data) + { + char** pstr = (char**)data; + **pstr = ch; + (*pstr)++; + } + + vprintfmt(sprintf_putch, (void**)&str, fmt, ap); + *str = 0; + + va_end(ap); + return str - str0; +} + +void* memcpy(void* dest, const void* src, size_t len) +{ + if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) { + const uintptr_t* s = src; + uintptr_t *d = dest; + while (d < (uintptr_t*)(dest + len)) + *d++ = *s++; + } else { + const char* s = src; + char *d = dest; + while (d < (char*)(dest + len)) + *d++ = *s++; + } + return dest; +} + +void* memset(void* dest, int byte, size_t len) +{ + if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) { + uintptr_t word = byte & 0xFF; + word |= word << 8; + word |= word << 16; + word |= word << 16 << 16; + + uintptr_t *d = dest; + while (d < (uintptr_t*)(dest + len)) + *d++ = word; + } else { + char *d = dest; + while (d < (char*)(dest + len)) + *d++ = byte; + } + return dest; +} + +size_t strlen(const char *s) +{ + const char *p = s; + while (*p) + p++; + return p - s; +} + +size_t strnlen(const char *s, size_t n) +{ + const char *p = s; + while (n-- && *p) + p++; + return p - s; +} + +int strcmp(const char* s1, const char* s2) +{ + unsigned char c1, c2; + + do { + c1 = *s1++; + c2 = *s2++; + } while (c1 != 0 && c1 == c2); + + return c1 - c2; +} + +char* strcpy(char* dest, const char* src) +{ + char* d = dest; + while ((*d++ = *src++)) + ; + return dest; +} + +long atol(const char* str) +{ + long res = 0; + int sign = 0; + + while (*str == ' ') + str++; + + if (*str == '-' || *str == '+') { + sign = *str == '-'; + str++; + } + + while (*str) { + res *= 10; + res += *str++ - '0'; + } + + return sign ? -res : res; +} diff --git a/verif/tests/custom/Zcmp/util.h b/verif/tests/custom/Zcmp/util.h new file mode 100644 index 0000000000..78fa62401a --- /dev/null +++ b/verif/tests/custom/Zcmp/util.h @@ -0,0 +1,92 @@ +// See LICENSE for license details. + +#ifndef __UTIL_H +#define __UTIL_H + +extern void setStats(int enable); + +#include + +#define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; } + +static int verify(int n, const volatile int* test, const int* verify) +{ + int i; + // Unrolled for faster verification + for (i = 0; i < n/2*2; i+=2) + { + int t0 = test[i], t1 = test[i+1]; + int v0 = verify[i], v1 = verify[i+1]; + if (t0 != v0) return i+1; + if (t1 != v1) return i+2; + } + if (n % 2 != 0 && test[n-1] != verify[n-1]) + return n; + return 0; +} + +static int verifyDouble(int n, const volatile double* test, const double* verify) +{ + int i; + // Unrolled for faster verification + for (i = 0; i < n/2*2; i+=2) + { + double t0 = test[i], t1 = test[i+1]; + double v0 = verify[i], v1 = verify[i+1]; + int eq1 = t0 == v0, eq2 = t1 == v1; + if (!(eq1 & eq2)) return i+1+eq1; + } + if (n % 2 != 0 && test[n-1] != verify[n-1]) + return n; + return 0; +} + +static void __attribute__((noinline)) barrier(int ncores) +{ +#ifdef __riscv_atomic // __sync_* builtins require A extension + static volatile int sense; + static volatile int count; + static __thread int threadsense; + + __sync_synchronize(); + + threadsense = !threadsense; + if (__sync_fetch_and_add(&count, 1) == ncores-1) + { + count = 0; + sense = threadsense; + } + else while(sense != threadsense) + ; + + __sync_synchronize(); +#endif // __riscv_atomic +} + +static uint64_t lfsr(uint64_t x) +{ + uint64_t bit = (x ^ (x >> 1)) & 1; + return (x >> 1) | (bit << 62); +} + +static uintptr_t insn_len(uintptr_t pc) +{ + return (*(unsigned short*)pc & 3) ? 4 : 2; +} + +#ifdef __riscv +#include "encoding.h" +#endif + +#define stringify_1(s) #s +#define stringify(s) stringify_1(s) +#define stats(code, iter) do { \ + unsigned long _c = -read_csr(mcycle), _i = -read_csr(minstret); \ + code; \ + _c += read_csr(mcycle), _i += read_csr(minstret); \ + if (cid == 0) \ + printf("\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \ + stringify(code), _c, _c/iter, 10*_c/iter%10, _c/_i, 10*_c/_i%10); \ + } while(0) + +#endif //__UTIL_H From 9f7fb9770b36e83ae1d6109bce00e9138b82953a Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 26 Feb 2024 18:11:27 +0500 Subject: [PATCH 03/15] Fixed some issues in Zcmp modifications --- core/commit_stage.sv | 13 ++++++++----- core/scoreboard.sv | 6 +++++- core/zcmp_decoder.sv | 1 - 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/core/commit_stage.sv b/core/commit_stage.sv index 3975c8fe8b..815c22bc9f 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -145,13 +145,12 @@ module commit_stage csr_write_fflags_o = 1'b0; flush_commit_o = 1'b0; - if (commit_instr_i[0].valid && !commit_instr_i[0].ex.valid && !halt_i && (commit_instr_i[0].is_zcmp_instr && commit_instr_i[0].is_last_zcmp_instr)) - commit_zcmp_ack[0] = 1'b1; - else commit_zcmp_ack[0] = 1'b0; - // we will not commit the instruction if we took an exception // and we do not commit the instruction if we requested a halt if (commit_instr_i[0].valid && !commit_instr_i[0].ex.valid && !halt_i) begin + if (commit_instr_i[0].is_zcmp_instr && commit_instr_i[0].is_last_zcmp_instr) + commit_zcmp_ack[0] = 1'b1; + else commit_zcmp_ack[0] = 1'b0; // we can definitely write the register file // if the instruction is not committing anything the destination commit_ack_o[0] = 1'b1; @@ -272,6 +271,10 @@ module commit_stage if (CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr(commit_instr_i[1].op)) we_fpr_o[1] = 1'b1; else we_gpr_o[1] = 1'b1; + if (commit_instr_i[1].is_zcmp_instr && commit_instr_i[1].is_last_zcmp_instr) + commit_zcmp_ack[1] = 1'b1; + else commit_zcmp_ack[1] = 1'b0; + commit_ack_o[1] = 1'b1; // additionally check if we are retiring an FPU instruction because we need to make sure that we write all @@ -289,7 +292,7 @@ module commit_stage end end end - commit_zcmp_ack_o = (commit_instr_i[0].is_zcmp_instr) ? commit_zcmp_ack : commit_ack_o; + commit_zcmp_ack_o = (commit_instr_i[0].is_zcmp_instr || commit_instr_i[1].is_zcmp_instr) ? commit_zcmp_ack : commit_ack_o; end // ----------------------------- diff --git a/core/scoreboard.sv b/core/scoreboard.sv index a8d5a0c666..83ba913ff3 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -111,6 +111,8 @@ module scoreboard #( } sb_mem_t; sb_mem_t [ariane_pkg::NR_SB_ENTRIES-1:0] mem_q, mem_n; + logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] prev_trans_id; // transaction ID for the first decoded mvsa01/mva01s instr + int unsigned prev_i; // WbPort number for the first decoded mvsa01/mva01s instr logic issue_full, issue_en; logic [ariane_pkg::TRANS_ID_BITS:0] issue_cnt_n, issue_cnt_q; logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer_n, issue_pointer_q; @@ -188,9 +190,11 @@ module scoreboard #( if (mem_q[trans_id_i[i]].sbe.is_mv_zcmp_instr && mem_q[trans_id_i[i]].sbe.is_zcmp_instr) begin if (mem_q[trans_id_i[i]].sbe.is_last_zcmp_instr) begin mem_n[trans_id_i[i]].sbe.valid = 1'b1; - mem_n[trans_id_i[i-1]].sbe.valid = 1'b1; + mem_n[prev_trans_id[prev_i]].sbe.valid = 1'b1; end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b0; + prev_trans_id[i] = trans_id_i[i]; + prev_i = i; end end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b1; diff --git a/core/zcmp_decoder.sv b/core/zcmp_decoder.sv index 3f339f842b..73d90ba83a 100644 --- a/core/zcmp_decoder.sv +++ b/core/zcmp_decoder.sv @@ -561,7 +561,6 @@ module zcmp_decoder #( instr_o_reg = instr_i; end endcase - fetch_stall_o = 1; end PUSH_ADDI: begin From b1f6a8f70449cf5cfed7321045248ae3a62febf4 Mon Sep 17 00:00:00 2001 From: rohan Date: Fri, 8 Mar 2024 20:55:21 +0500 Subject: [PATCH 04/15] Updated config pkg files in core/include --- core/include/cv32a65x_config_pkg.sv | 2 ++ core/include/cv32a6_embedded_config_pkg.sv | 2 ++ core/include/cv32a6_ima_sv32_fpga_config_pkg.sv | 2 ++ core/include/cv32a6_imac_sv0_config_pkg.sv | 2 ++ core/include/cv32a6_imac_sv32_config_pkg.sv | 2 ++ core/include/cv32a6_imafc_sv32_config_pkg.sv | 2 ++ core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv | 2 ++ core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv | 2 ++ 8 files changed, 16 insertions(+) diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index 1bc8c8ba27..badc9ce01d 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -20,6 +20,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 1; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 0; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -90,6 +91,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv32a6_embedded_config_pkg.sv b/core/include/cv32a6_embedded_config_pkg.sv index 09fc3daadd..99ed450cf3 100644 --- a/core/include/cv32a6_embedded_config_pkg.sv +++ b/core/include/cv32a6_embedded_config_pkg.sv @@ -20,6 +20,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 1; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 0; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -90,6 +91,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index fa4e4af07a..84a342a5dd 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 0; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index 4443a9e3a1..49f2f78a9e 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index 3dcce61aec..7c3968757f 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index 484611d3da..80139cc8fe 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv index 4d0e3ab5da..481a6b6686 100644 --- a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv +++ b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 1; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 8ce332d9fa..64cb7ce694 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCvxifEn = 0; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; + localparam CVA6ConfigZcmpExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigVExtEn = 0; @@ -91,6 +92,7 @@ package cva6_config_pkg; RVV: bit'(CVA6ConfigVExtEn), RVC: bit'(CVA6ConfigCExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn), From e8e32fc4213d3dc1fc8d82ea1ca855e6823c8c9e Mon Sep 17 00:00:00 2001 From: rohan Date: Fri, 8 Mar 2024 22:25:45 +0500 Subject: [PATCH 05/15] variable format, RVZCMP bit addition in fpga config --- core/decoder.sv | 4 ++-- core/scoreboard.sv | 4 ++-- corev_apu/fpga/src/ariane_xilinx.sv | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/decoder.sv b/core/decoder.sv index f3ca47e0df..4b5db2265d 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -41,11 +41,11 @@ module decoder // Instruction from fetch stage - FRONTEND input logic [31:0] instruction_i, // Is a zcmp instruction - zcmp_decoder - input logic is_zcmp_instr_i, + input logic is_zcmp_instr_i, // Is a last zcmp instruction - zcmp_decoder input logic is_last_zcmp_instr_i, // Is mvsa01/mva01s zcmp instruction - zcmp_decoder - input logic is_mv_zcmp_instr_i, + input logic is_mv_zcmp_instr_i, // Is a branch predict instruction - FRONTEND input branchpredict_sbe_t branch_predict_i, // If an exception occured in fetch stage - FRONTEND diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 83ba913ff3..86e622ead7 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -112,7 +112,7 @@ module scoreboard #( sb_mem_t [ariane_pkg::NR_SB_ENTRIES-1:0] mem_q, mem_n; logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] prev_trans_id; // transaction ID for the first decoded mvsa01/mva01s instr - int unsigned prev_i; // WbPort number for the first decoded mvsa01/mva01s instr + int unsigned prev_i; // WbPort number for the first decoded mvsa01/mva01s instr logic issue_full, issue_en; logic [ariane_pkg::TRANS_ID_BITS:0] issue_cnt_n, issue_cnt_q; logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer_n, issue_pointer_q; @@ -189,7 +189,7 @@ module scoreboard #( if (wt_valid_i[i] && mem_q[trans_id_i[i]].issued) begin if (mem_q[trans_id_i[i]].sbe.is_mv_zcmp_instr && mem_q[trans_id_i[i]].sbe.is_zcmp_instr) begin if (mem_q[trans_id_i[i]].sbe.is_last_zcmp_instr) begin - mem_n[trans_id_i[i]].sbe.valid = 1'b1; + mem_n[trans_id_i[i]].sbe.valid = 1'b1; mem_n[prev_trans_id[prev_i]].sbe.valid = 1'b1; end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b0; diff --git a/corev_apu/fpga/src/ariane_xilinx.sv b/corev_apu/fpga/src/ariane_xilinx.sv index f658dc8c89..7b80c353e8 100644 --- a/corev_apu/fpga/src/ariane_xilinx.sv +++ b/corev_apu/fpga/src/ariane_xilinx.sv @@ -175,6 +175,7 @@ localparam config_pkg::cva6_user_cfg_t CVA6UserCfg = '{ RVV: bit'(cva6_config_pkg::CVA6ConfigVExtEn), RVC: bit'(cva6_config_pkg::CVA6ConfigCExtEn), RVZCB: bit'(cva6_config_pkg::CVA6ConfigZcbExtEn), + RVZCMP: bit'(cva6_config_pkg::CVA6ConfigZcmpExtEn), XFVec: bit'(cva6_config_pkg::CVA6ConfigFVecEn), CvxifEn: bit'(cva6_config_pkg::CVA6ConfigCvxifEn), ZiCondExtEn: bit'(0), From 53249d3ad7178f246405675827c39bf5a80eaff6 Mon Sep 17 00:00:00 2001 From: rohan Date: Fri, 8 Mar 2024 22:56:35 +0500 Subject: [PATCH 06/15] Updated config pkg --- core/include/config_pkg.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index 4a3c0b05a6..da1972d058 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -152,6 +152,7 @@ package config_pkg; bit RVV; bit RVC; bit RVZCB; + bit RVZCMP; bit XFVec; bit CvxifEn; bit ZiCondExtEn; From 42fa283b2d90dce9275498031cbd4745e6b01ab2 Mon Sep 17 00:00:00 2001 From: rohan Date: Fri, 8 Mar 2024 23:35:13 +0500 Subject: [PATCH 07/15] updated build_config_pkg --- core/include/build_config_pkg.sv | 1 + 1 file changed, 1 insertion(+) diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index 96610de7ff..aafcf783d4 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -39,6 +39,7 @@ package build_config_pkg; cfg.RVV = CVA6Cfg.RVV; cfg.RVC = CVA6Cfg.RVC; cfg.RVZCB = CVA6Cfg.RVZCB; + cfg.RVZCMP = CVA6Cfg.RVZCMP; cfg.XFVec = CVA6Cfg.XFVec; cfg.CvxifEn = CVA6Cfg.CvxifEn; cfg.ZiCondExtEn = CVA6Cfg.ZiCondExtEn; From c361b315eb9d89a31c1c829f97cb2f1b2e8241db Mon Sep 17 00:00:00 2001 From: rohan Date: Sat, 9 Mar 2024 18:11:22 +0500 Subject: [PATCH 08/15] Updated scoreboard entry dtype --- core/cva6.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/cva6.sv b/core/cva6.sv index 0ab191b3fc..2d8dbf07ec 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -105,6 +105,9 @@ module cva6 branchpredict_sbe_t bp; // branch predict scoreboard data structure logic is_compressed; // signals a compressed instructions, we need this information at the commit stage if // we want jump accordingly e.g.: +4, +2 + logic is_zcmp_instr; // instruction is of Zcmp Extension + logic is_last_zcmp_instr; // is last decoded 32bit instruction of Zcmp Extension + logic is_mv_zcmp_instr; // is double move decoded 32bit instruction of Zcmp Extension logic vfp; // is this a vector floating-point instruction? }, From bd1aaee647bde6120480c687b9d26b5cc9bb9e74 Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 11 Mar 2024 16:50:06 +0500 Subject: [PATCH 09/15] renamed zcmp --> macro --- core/Flist.cva6 | 2 +- core/commit_stage.sv | 20 ++--- core/compressed_decoder.sv | 8 +- core/cva6.sv | 14 ++-- core/decoder.sv | 18 ++--- core/id_stage.sv | 34 ++++----- core/{zcmp_decoder.sv => macro_decoder.sv} | 88 +++++++++++----------- core/rename | 3 + core/scoreboard.sv | 4 +- 9 files changed, 97 insertions(+), 94 deletions(-) rename core/{zcmp_decoder.sv => macro_decoder.sv} (90%) create mode 100644 core/rename diff --git a/core/Flist.cva6 b/core/Flist.cva6 index 8d72f42514..83d2479309 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -105,7 +105,7 @@ ${CVA6_REPO_DIR}/core/alu.sv ${CVA6_REPO_DIR}/core/fpu_wrap.sv ${CVA6_REPO_DIR}/core/branch_unit.sv ${CVA6_REPO_DIR}/core/compressed_decoder.sv -${CVA6_REPO_DIR}/core/zcmp_decoder.sv +${CVA6_REPO_DIR}/core/macro_decoder.sv ${CVA6_REPO_DIR}/core/controller.sv ${CVA6_REPO_DIR}/core/csr_buffer.sv ${CVA6_REPO_DIR}/core/csr_regfile.sv diff --git a/core/commit_stage.sv b/core/commit_stage.sv index 815c22bc9f..79800088f6 100644 --- a/core/commit_stage.sv +++ b/core/commit_stage.sv @@ -39,7 +39,7 @@ module commit_stage // Acknowledge that we are indeed committing - ISSUE_STAGE output logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_o, // Acknowledge that we are indeed committing - CSR_REGFILE - output logic [CVA6Cfg.NrCommitPorts-1:0] commit_zcmp_ack_o, + output logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack_o, // Register file write address - ISSUE_STAGE output logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_o, // Register file write data - ISSUE_STAGE @@ -118,7 +118,7 @@ module commit_stage assign commit_tran_id_o = commit_instr_i[0].trans_id; logic instr_0_is_amo; - logic [CVA6Cfg.NrCommitPorts-1:0] commit_zcmp_ack; + logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack; assign instr_0_is_amo = is_amo(commit_instr_i[0].op); // ------------------- // Commit Instruction @@ -127,7 +127,7 @@ module commit_stage always_comb begin : commit // default assignments commit_ack_o[0] = 1'b0; - commit_zcmp_ack[0] = 1'b0; + commit_macro_ack[0] = 1'b0; amo_valid_commit_o = 1'b0; @@ -148,9 +148,9 @@ module commit_stage // we will not commit the instruction if we took an exception // and we do not commit the instruction if we requested a halt if (commit_instr_i[0].valid && !commit_instr_i[0].ex.valid && !halt_i) begin - if (commit_instr_i[0].is_zcmp_instr && commit_instr_i[0].is_last_zcmp_instr) - commit_zcmp_ack[0] = 1'b1; - else commit_zcmp_ack[0] = 1'b0; + if (commit_instr_i[0].is_macro_instr && commit_instr_i[0].is_last_macro_instr) + commit_macro_ack[0] = 1'b1; + else commit_macro_ack[0] = 1'b0; // we can definitely write the register file // if the instruction is not committing anything the destination commit_ack_o[0] = 1'b1; @@ -271,9 +271,9 @@ module commit_stage if (CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr(commit_instr_i[1].op)) we_fpr_o[1] = 1'b1; else we_gpr_o[1] = 1'b1; - if (commit_instr_i[1].is_zcmp_instr && commit_instr_i[1].is_last_zcmp_instr) - commit_zcmp_ack[1] = 1'b1; - else commit_zcmp_ack[1] = 1'b0; + if (commit_instr_i[1].is_macro_instr && commit_instr_i[1].is_last_macro_instr) + commit_macro_ack[1] = 1'b1; + else commit_macro_ack[1] = 1'b0; commit_ack_o[1] = 1'b1; @@ -292,7 +292,7 @@ module commit_stage end end end - commit_zcmp_ack_o = (commit_instr_i[0].is_zcmp_instr || commit_instr_i[1].is_zcmp_instr) ? commit_zcmp_ack : commit_ack_o; + commit_macro_ack_o = (commit_instr_i[0].is_macro_instr || commit_instr_i[1].is_macro_instr) ? commit_macro_ack : commit_ack_o; end // ----------------------------- diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index 1c989df00e..8ae7abe923 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -28,8 +28,8 @@ module compressed_decoder #( output logic [31:0] instr_o, // Input instruction is illegal - decoder output logic illegal_instr_o, - // Output instruction is zcmp - decoder - output logic is_zcmp_instr_o, + // Output instruction is macro - decoder + output logic is_macro_instr_o, // Output instruction is compressed - decoder output logic is_compressed_o ); @@ -42,7 +42,7 @@ module compressed_decoder #( instr_o = '0; is_compressed_o = 1'b1; instr_o = instr_i; - is_zcmp_instr_o = 0; + is_macro_instr_o = 0; // I: | imm[11:0] | rs1 | funct3 | rd | opcode | // S: | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | @@ -870,7 +870,7 @@ module compressed_decoder #( }; end else if (CVA6Cfg.RVZCMP) begin if (instr_i[12:10] == 3'b110 || instr_i[12:10] == 3'b111 || instr_i[12:10] == 3'b011) begin //is a push/pop instruction - is_zcmp_instr_o = 1; + is_macro_instr_o = 1; instr_o = instr_i; end else begin illegal_instr_o = 1'b1; diff --git a/core/cva6.sv b/core/cva6.sv index 2d8dbf07ec..ceda86b085 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -105,9 +105,9 @@ module cva6 branchpredict_sbe_t bp; // branch predict scoreboard data structure logic is_compressed; // signals a compressed instructions, we need this information at the commit stage if // we want jump accordingly e.g.: +4, +2 - logic is_zcmp_instr; // instruction is of Zcmp Extension - logic is_last_zcmp_instr; // is last decoded 32bit instruction of Zcmp Extension - logic is_mv_zcmp_instr; // is double move decoded 32bit instruction of Zcmp Extension + logic is_macro_instr; // instruction is of Zcmp Extension + logic is_last_macro_instr; // is last decoded 32bit instruction of Zcmp Extension + logic is_mv_macro_instr; // is double move decoded 32bit instruction of Zcmp Extension logic vfp; // is this a vector floating-point instruction? }, @@ -305,7 +305,7 @@ module cva6 logic [ riscv::VLEN-1:0] pc_commit; logic eret; logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack; - logic [CVA6Cfg.NrCommitPorts-1:0] commit_zcmp_ack; + logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack; localparam NumPorts = 4; cvxif_pkg::cvxif_req_t cvxif_req; @@ -888,7 +888,7 @@ module cva6 .single_step_i (single_step_csr_commit || single_step_acc_commit), .commit_instr_i (commit_instr_id_commit), .commit_ack_o (commit_ack), - .commit_zcmp_ack_o (commit_zcmp_ack), + .commit_macro_ack_o (commit_macro_ack), .no_st_pending_i (no_st_pending_commit), .waddr_o (waddr_commit_id), .wdata_o (wdata_commit_id), @@ -928,7 +928,7 @@ module cva6 .flush_o (flush_csr_ctrl), .halt_csr_o (halt_csr_ctrl), .commit_instr_i (commit_instr_id_commit), - .commit_ack_i (commit_zcmp_ack), + .commit_ack_i (commit_macro_ack), .boot_addr_i (boot_addr_i[riscv::VLEN-1:0]), .hart_id_i (hart_id_i[riscv::XLEN-1:0]), .ex_i (ex_commit), @@ -1553,7 +1553,7 @@ module cva6 .lsu_ctrl_i (rvfi_lsu_ctrl), .wbdata_i (wbdata_ex_id), - .commit_ack_i(commit_zcmp_ack), + .commit_ack_i(commit_macro_ack), .mem_paddr_i (rvfi_mem_paddr), .debug_mode_i(debug_mode), .wdata_i (wdata_commit_id), diff --git a/core/decoder.sv b/core/decoder.sv index 4b5db2265d..4af9927c4e 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -40,12 +40,12 @@ module decoder input logic is_illegal_i, // Instruction from fetch stage - FRONTEND input logic [31:0] instruction_i, - // Is a zcmp instruction - zcmp_decoder - input logic is_zcmp_instr_i, - // Is a last zcmp instruction - zcmp_decoder - input logic is_last_zcmp_instr_i, - // Is mvsa01/mva01s zcmp instruction - zcmp_decoder - input logic is_mv_zcmp_instr_i, + // Is a macro instruction - macro_decoder + input logic is_macro_instr_i, + // Is a last macro instruction - macro_decoder + input logic is_last_macro_instr_i, + // Is mvsa01/mva01s macro instruction - macro_decoder + input logic is_mv_macro_instr_i, // Is a branch predict instruction - FRONTEND input branchpredict_sbe_t branch_predict_i, // If an exception occured in fetch stage - FRONTEND @@ -149,9 +149,9 @@ module decoder instruction_o.rd = '0; instruction_o.use_pc = 1'b0; instruction_o.is_compressed = is_compressed_i; - instruction_o.is_zcmp_instr = is_zcmp_instr_i; - instruction_o.is_last_zcmp_instr = is_last_zcmp_instr_i; - instruction_o.is_mv_zcmp_instr = is_mv_zcmp_instr_i; + instruction_o.is_macro_instr = is_macro_instr_i; + instruction_o.is_last_macro_instr = is_last_macro_instr_i; + instruction_o.is_mv_macro_instr = is_mv_macro_instr_i; instruction_o.use_zimm = 1'b0; instruction_o.bp = branch_predict_i; instruction_o.vfp = 1'b0; diff --git a/core/id_stage.sv b/core/id_stage.sv index 79883c8452..b7ca6734a9 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -87,10 +87,10 @@ module id_stage #( logic [31:0] compressed_instr; logic is_compressed; logic is_compressed_cmp; - logic is_zcmp_instr_i; + logic is_macro_instr_i; logic stall_instr_fetch; - logic is_last_zcmp_instr_o; - logic is_mv_zcmp_instr_o; + logic is_last_macro_instr_o; + logic is_mv_macro_instr_o; if (CVA6Cfg.RVC) begin // --------------------------------------------------------- @@ -103,15 +103,15 @@ module id_stage #( .instr_o (compressed_instr), .illegal_instr_o(is_illegal), .is_compressed_o(is_compressed), - .is_zcmp_instr_o(is_zcmp_instr_i) + .is_macro_instr_o(is_macro_instr_i) ); if (CVA6Cfg.RVZCMP) begin //sequencial decoder - zcmp_decoder #( + macro_decoder #( .CVA6Cfg(CVA6Cfg) - ) zcmp_decoder_i ( + ) macro_decoder_i ( .instr_i (compressed_instr), - .is_zcmp_instr_i (is_zcmp_instr_i), + .is_macro_instr_i (is_macro_instr_i), .clk_i (clk_i), .rst_ni (rst_ni), .instr_o (instruction), @@ -121,23 +121,23 @@ module id_stage #( .illegal_instr_o (is_illegal_cmp), .is_compressed_o (is_compressed_cmp), .fetch_stall_o (stall_instr_fetch), - .is_last_zcmp_instr_o(is_last_zcmp_instr_o), - .is_mv_zcmp_instr_o (is_mv_zcmp_instr_o) + .is_last_macro_instr_o(is_last_macro_instr_o), + .is_mv_macro_instr_o (is_mv_macro_instr_o) ); end else begin assign instruction = compressed_instr; assign is_illegal_cmp = is_illegal; assign is_compressed_cmp = is_compressed; - assign is_last_zcmp_instr_o = '0; - assign is_mv_zcmp_instr_o = '0; + assign is_last_macro_instr_o = '0; + assign is_mv_macro_instr_o = '0; end end else begin assign instruction = fetch_entry_i.instruction; assign is_illegal_cmp = '0; assign is_compressed_cmp = '0; - assign is_zcmp_instr_i = '0; - assign is_last_zcmp_instr_o = '0; - assign is_mv_zcmp_instr_o = '0; + assign is_macro_instr_i = '0; + assign is_last_macro_instr_o = '0; + assign is_mv_macro_instr_o = '0; end assign rvfi_is_compressed_o = is_compressed_cmp; @@ -156,9 +156,9 @@ module id_stage #( .irq_i, .pc_i (fetch_entry_i.address), .is_compressed_i (is_compressed_cmp), - .is_zcmp_instr_i (is_zcmp_instr_i), - .is_last_zcmp_instr_i (is_last_zcmp_instr_o), - .is_mv_zcmp_instr_i (is_mv_zcmp_instr_o), + .is_macro_instr_i (is_macro_instr_i), + .is_last_macro_instr_i (is_last_macro_instr_o), + .is_mv_macro_instr_i (is_mv_macro_instr_o), .is_illegal_i (is_illegal_cmp), .instruction_i (instruction), .compressed_instr_i (fetch_entry_i.instruction[15:0]), diff --git a/core/zcmp_decoder.sv b/core/macro_decoder.sv similarity index 90% rename from core/zcmp_decoder.sv rename to core/macro_decoder.sv index 73d90ba83a..8555a1eba2 100644 --- a/core/zcmp_decoder.sv +++ b/core/macro_decoder.sv @@ -14,13 +14,13 @@ // cm.popretz, cm.mvsa01, and cm.mva01s instructions of the // Zcmp Extension -module zcmp_decoder #( +module macro_decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic [31:0] instr_i, input logic clk_i, // Clock input logic rst_ni, // Synchronous reset - input logic is_zcmp_instr_i, // Intruction is of zcmp extension + input logic is_macro_instr_i, // Intruction is of macro extension input logic illegal_instr_i, // From compressed decoder input logic is_compressed_i, input logic issue_ack_i, // Check if the intruction is acknowledged @@ -28,8 +28,8 @@ module zcmp_decoder #( output logic illegal_instr_o, output logic is_compressed_o, output logic fetch_stall_o, //Wait while push/pop/move instructions expand - output logic is_last_zcmp_instr_o, - output logic is_mv_zcmp_instr_o + output logic is_last_macro_instr_o, + output logic is_mv_macro_instr_o ); // FSM States @@ -51,7 +51,7 @@ module zcmp_decoder #( POPRET, MVA01S, MVSA01 - } zcmp_instr_type; + } macro_instr_type; // Temporary registers logic [3:0] reg_numbers, reg_numbers_q, reg_numbers_d; @@ -66,9 +66,9 @@ module zcmp_decoder #( always_comb begin illegal_instr_o = 1'b0; fetch_stall_o = 1'b0; - is_last_zcmp_instr_o = 1'b0; - is_mv_zcmp_instr_o = 1'b0; - is_compressed_o = is_zcmp_instr_i ? 1'b1 : is_compressed_i; + is_last_macro_instr_o = 1'b0; + is_mv_macro_instr_o = 1'b0; + is_compressed_o = is_macro_instr_i ? 1'b1 : is_compressed_i; reg_numbers = '0; stack_adj = '0; state_d = state_q; @@ -77,17 +77,17 @@ module zcmp_decoder #( store_reg_d = store_reg_q; popretz_inst_d = popretz_inst_q; - if (is_zcmp_instr_i) begin + if (is_macro_instr_i) begin unique case (instr_i[12:10]) // push or pop 3'b110: begin unique case (instr_i[9:8]) 2'b00: begin - zcmp_instr_type = PUSH; + macro_instr_type = PUSH; end 2'b10: begin - zcmp_instr_type = POP; + macro_instr_type = POP; end default: begin illegal_instr_o = 1'b1; @@ -99,10 +99,10 @@ module zcmp_decoder #( 3'b111: begin unique case (instr_i[9:8]) 2'b00: begin - zcmp_instr_type = POPRETZ; + macro_instr_type = POPRETZ; end 2'b10: begin - zcmp_instr_type = POPRET; + macro_instr_type = POPRET; end default: begin illegal_instr_o = 1'b1; @@ -114,10 +114,10 @@ module zcmp_decoder #( 3'b011: begin unique case (instr_i[6:5]) 2'b01: begin - zcmp_instr_type = MVSA01; + macro_instr_type = MVSA01; end 2'b11: begin - zcmp_instr_type = MVA01S; + macro_instr_type = MVA01S; end default: begin illegal_instr_o = 1'b1; @@ -132,7 +132,7 @@ module zcmp_decoder #( endcase // Calculate xreg1 & xreg2 for move instructions - if (zcmp_instr_type == MVSA01 || zcmp_instr_type == MVA01S) begin + if (macro_instr_type == MVSA01 || macro_instr_type == MVA01S) begin if (instr_i[9:7] != instr_i[4:2]) begin xreg1 = {instr_i[9:8] > 0, instr_i[9:8] == 0, instr_i[9:7]}; xreg2 = {instr_i[4:3] > 0, instr_i[4:3] == 0, instr_i[4:2]}; @@ -260,7 +260,7 @@ module zcmp_decoder #( end //Take 2's compliment in case of PUSH instruction - if (zcmp_instr_type == PUSH) begin + if (macro_instr_type == PUSH) begin itype_inst.imm = ~stack_adj + 1'b1; end else begin itype_inst.imm = stack_adj - 3'b100; @@ -272,17 +272,17 @@ module zcmp_decoder #( unique case (state_q) IDLE: begin - if (is_zcmp_instr_i && issue_ack_i) begin + if (is_macro_instr_i && issue_ack_i) begin reg_numbers_d = reg_numbers - 1'b1; state_d = INIT; - case (zcmp_instr_type) + case (macro_instr_type) PUSH: begin offset_d = 12'hFFC + 12'hFFC; end POP, POPRETZ, POPRET: begin offset_d = itype_inst.imm + 12'hFFC; offset_reg = itype_inst.imm; - case (zcmp_instr_type) + case (macro_instr_type) POPRETZ: begin popretz_inst_d = 2'b11; end @@ -306,23 +306,23 @@ module zcmp_decoder #( store_reg = 4'b1110 + reg_numbers; end - if (zcmp_instr_type == MVSA01) begin + if (macro_instr_type == MVSA01) begin fetch_stall_o = 1; - is_mv_zcmp_instr_o = 1; + is_mv_macro_instr_o = 1; // addi xreg1, a0, 0 instr_o_reg = {12'h0, 5'hA, 3'h0, xreg1, riscv::OpcodeOpImm}; state_d = MOVE; end - if (zcmp_instr_type == MVA01S) begin + if (macro_instr_type == MVA01S) begin fetch_stall_o = 1; - is_mv_zcmp_instr_o = 1; + is_mv_macro_instr_o = 1; // addi a0, xreg1, 0 instr_o_reg = {12'h0, xreg1, 3'h0, 5'hA, riscv::OpcodeOpImm}; state_d = MOVE; end - if (zcmp_instr_type == PUSH) begin + if (macro_instr_type == PUSH) begin fetch_stall_o = 1'b1; // stall inst fetch @@ -369,7 +369,7 @@ module zcmp_decoder #( end end - if ((zcmp_instr_type == POP || zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + if ((macro_instr_type == POP || macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin fetch_stall_o = 1; // stall inst fetch if (reg_numbers == 1) begin if (riscv::XLEN == 64) begin @@ -381,7 +381,7 @@ module zcmp_decoder #( offset_reg, 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad }; // lw store_reg, Imm(sp) end - unique case (zcmp_instr_type) + unique case (macro_instr_type) PUSH, POP, POPRET: begin state_d = PUSH_ADDI; end @@ -424,7 +424,7 @@ module zcmp_decoder #( end INIT: begin fetch_stall_o = 1'b1; // stall inst fetch - if (issue_ack_i && is_zcmp_instr_i && zcmp_instr_type == PUSH) begin + if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin if (reg_numbers_q == 4'b0001) begin if (riscv::XLEN == 64) begin instr_o_reg = {offset_d[11:5], 5'h1, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; @@ -473,7 +473,7 @@ module zcmp_decoder #( end end - if (issue_ack_i && is_zcmp_instr_i && (zcmp_instr_type == POP || zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POP || macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin if (reg_numbers_q == 1) begin if (riscv::XLEN == 64) begin @@ -481,7 +481,7 @@ module zcmp_decoder #( end else begin instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad}; end - unique case (zcmp_instr_type) + unique case (macro_instr_type) PUSH, POP, POPRET: begin state_d = PUSH_ADDI; end @@ -535,14 +535,14 @@ module zcmp_decoder #( end MOVE: begin - case (zcmp_instr_type) + case (macro_instr_type) MVSA01: begin if (issue_ack_i) begin // addi xreg2, a1, 0 instr_o_reg = {12'h0, 5'hB, 3'h0, xreg2, riscv::OpcodeOpImm}; fetch_stall_o = 0; - is_last_zcmp_instr_o = 1; - is_mv_zcmp_instr_o = 1; + is_last_macro_instr_o = 1; + is_mv_macro_instr_o = 1; state_d = IDLE; end end @@ -551,8 +551,8 @@ module zcmp_decoder #( // addi a1, xreg2, 0 instr_o_reg = {12'h0, xreg2, 3'h0, 5'hB, riscv::OpcodeOpImm}; fetch_stall_o = 0; - is_last_zcmp_instr_o = 1; - is_mv_zcmp_instr_o = 1; + is_last_macro_instr_o = 1; + is_mv_macro_instr_o = 1; state_d = IDLE; end end @@ -565,7 +565,7 @@ module zcmp_decoder #( PUSH_ADDI: begin if (riscv::XLEN == 64) begin - if (issue_ack_i && is_zcmp_instr_i && zcmp_instr_type == PUSH) begin + if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin // addi sp, sp, stack_adj instr_o_reg = {itype_inst.imm - 4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; end else begin @@ -573,20 +573,20 @@ module zcmp_decoder #( instr_o_reg = {stack_adj - 4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; end end - if (issue_ack_i && is_zcmp_instr_i && (zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin state_d = POPRETZ_1; fetch_stall_o = 1; end else begin if (issue_ack_i) begin state_d = IDLE; fetch_stall_o = 0; - is_last_zcmp_instr_o = 1; + is_last_macro_instr_o = 1; end else begin fetch_stall_o = 1; end end end else begin - if (issue_ack_i && is_zcmp_instr_i && zcmp_instr_type == PUSH) begin + if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin // addi sp, sp, stack_adj instr_o_reg = {itype_inst.imm, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; end else begin @@ -594,14 +594,14 @@ module zcmp_decoder #( instr_o_reg = {stack_adj, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; end end - if (issue_ack_i && is_zcmp_instr_i && (zcmp_instr_type == POPRETZ || zcmp_instr_type == POPRET)) begin + if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin state_d = POPRETZ_1; fetch_stall_o = 1; end else begin if (issue_ack_i) begin state_d = IDLE; fetch_stall_o = 0; - is_last_zcmp_instr_o = 1; + is_last_macro_instr_o = 1; end else begin fetch_stall_o = 1; end @@ -611,7 +611,7 @@ module zcmp_decoder #( PUSH_POP_INSTR_2: begin if (riscv::XLEN == 64) begin - case (zcmp_instr_type) + case (macro_instr_type) PUSH: begin if (issue_ack_i) begin instr_o_reg = { @@ -645,7 +645,7 @@ module zcmp_decoder #( end endcase end else begin - case (zcmp_instr_type) + case (macro_instr_type) PUSH: begin if (issue_ack_i) begin instr_o_reg = { @@ -695,7 +695,7 @@ module zcmp_decoder #( instr_o_reg = {12'h0, 5'h1, 3'h0, 5'h0, riscv::OpcodeJalr}; //ret - jalr x0, x1, 0 state_d = IDLE; fetch_stall_o = 0; - is_last_zcmp_instr_o = 1; + is_last_macro_instr_o = 1; popretz_inst_d = popretz_inst_q - 1; end end diff --git a/core/rename b/core/rename new file mode 100644 index 0000000000..e7d590db59 --- /dev/null +++ b/core/rename @@ -0,0 +1,3 @@ +find /home/rohan/cva6/core/ -type f -exec sed -i.bak 's/macro/macro/g' {} \; + + diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 86e622ead7..c73b8bd230 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -187,8 +187,8 @@ module scoreboard #( // check if this instruction was issued (e.g.: it could happen after a flush that there is still // something in the pipeline e.g. an incomplete memory operation) if (wt_valid_i[i] && mem_q[trans_id_i[i]].issued) begin - if (mem_q[trans_id_i[i]].sbe.is_mv_zcmp_instr && mem_q[trans_id_i[i]].sbe.is_zcmp_instr) begin - if (mem_q[trans_id_i[i]].sbe.is_last_zcmp_instr) begin + if (mem_q[trans_id_i[i]].sbe.is_mv_macro_instr && mem_q[trans_id_i[i]].sbe.is_macro_instr) begin + if (mem_q[trans_id_i[i]].sbe.is_last_macro_instr) begin mem_n[trans_id_i[i]].sbe.valid = 1'b1; mem_n[prev_trans_id[prev_i]].sbe.valid = 1'b1; end else begin From dd7d0da010878cb7e5cb6b1bb9ff94537f21f8d7 Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 11 Mar 2024 18:17:28 +0500 Subject: [PATCH 10/15] verible format files --- core/cva6.sv | 4 +-- core/decoder.sv | 44 +++++++++++------------ core/id_stage.sv | 37 ++++++++++--------- core/macro_decoder.sv | 83 ++++++++++++++++++++++++++++++------------- 4 files changed, 101 insertions(+), 67 deletions(-) diff --git a/core/cva6.sv b/core/cva6.sv index ceda86b085..28c885acfb 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -888,7 +888,7 @@ module cva6 .single_step_i (single_step_csr_commit || single_step_acc_commit), .commit_instr_i (commit_instr_id_commit), .commit_ack_o (commit_ack), - .commit_macro_ack_o (commit_macro_ack), + .commit_macro_ack_o(commit_macro_ack), .no_st_pending_i (no_st_pending_commit), .waddr_o (waddr_commit_id), .wdata_o (wdata_commit_id), @@ -1565,4 +1565,4 @@ module cva6 ); -endmodule // ariane +endmodule // ariane \ No newline at end of file diff --git a/core/decoder.sv b/core/decoder.sv index 4af9927c4e..e6983fd51e 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -134,30 +134,30 @@ module decoder always_comb begin : decoder - imm_select = NOIMM; - is_control_flow_instr_o = 1'b0; - illegal_instr = 1'b0; - illegal_instr_non_bm = 1'b0; - illegal_instr_bm = 1'b0; - illegal_instr_zic = 1'b0; - instruction_o.pc = pc_i; - instruction_o.trans_id = '0; - instruction_o.fu = NONE; - instruction_o.op = ariane_pkg::ADD; - instruction_o.rs1 = '0; - instruction_o.rs2 = '0; - instruction_o.rd = '0; - instruction_o.use_pc = 1'b0; - instruction_o.is_compressed = is_compressed_i; + imm_select = NOIMM; + is_control_flow_instr_o = 1'b0; + illegal_instr = 1'b0; + illegal_instr_non_bm = 1'b0; + illegal_instr_bm = 1'b0; + illegal_instr_zic = 1'b0; + instruction_o.pc = pc_i; + instruction_o.trans_id = '0; + instruction_o.fu = NONE; + instruction_o.op = ariane_pkg::ADD; + instruction_o.rs1 = '0; + instruction_o.rs2 = '0; + instruction_o.rd = '0; + instruction_o.use_pc = 1'b0; + instruction_o.is_compressed = is_compressed_i; instruction_o.is_macro_instr = is_macro_instr_i; instruction_o.is_last_macro_instr = is_last_macro_instr_i; instruction_o.is_mv_macro_instr = is_mv_macro_instr_i; - instruction_o.use_zimm = 1'b0; - instruction_o.bp = branch_predict_i; - instruction_o.vfp = 1'b0; - ecall = 1'b0; - ebreak = 1'b0; - check_fprm = 1'b0; + instruction_o.use_zimm = 1'b0; + instruction_o.bp = branch_predict_i; + instruction_o.vfp = 1'b0; + ecall = 1'b0; + ebreak = 1'b0; + check_fprm = 1'b0; if (~ex_i.valid) begin case (instr.rtype.opcode) @@ -1436,4 +1436,4 @@ module decoder instruction_o.ex.cause = riscv::DEBUG_REQUEST; end end -endmodule +endmodule \ No newline at end of file diff --git a/core/id_stage.sv b/core/id_stage.sv index b7ca6734a9..302ff13933 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -99,10 +99,10 @@ module id_stage #( compressed_decoder #( .CVA6Cfg(CVA6Cfg) ) compressed_decoder_i ( - .instr_i (fetch_entry_i.instruction), - .instr_o (compressed_instr), - .illegal_instr_o(is_illegal), - .is_compressed_o(is_compressed), + .instr_i (fetch_entry_i.instruction), + .instr_o (compressed_instr), + .illegal_instr_o (is_illegal), + .is_compressed_o (is_compressed), .is_macro_instr_o(is_macro_instr_i) ); if (CVA6Cfg.RVZCMP) begin @@ -110,17 +110,17 @@ module id_stage #( macro_decoder #( .CVA6Cfg(CVA6Cfg) ) macro_decoder_i ( - .instr_i (compressed_instr), + .instr_i (compressed_instr), .is_macro_instr_i (is_macro_instr_i), - .clk_i (clk_i), - .rst_ni (rst_ni), - .instr_o (instruction), - .illegal_instr_i (is_illegal), - .is_compressed_i (is_compressed), - .issue_ack_i (issue_instr_ack_i), - .illegal_instr_o (is_illegal_cmp), - .is_compressed_o (is_compressed_cmp), - .fetch_stall_o (stall_instr_fetch), + .clk_i (clk_i), + .rst_ni (rst_ni), + .instr_o (instruction), + .illegal_instr_i (is_illegal), + .is_compressed_i (is_compressed), + .issue_ack_i (issue_instr_ack_i), + .illegal_instr_o (is_illegal_cmp), + .is_compressed_o (is_compressed_cmp), + .fetch_stall_o (stall_instr_fetch), .is_last_macro_instr_o(is_last_macro_instr_o), .is_mv_macro_instr_o (is_mv_macro_instr_o) ); @@ -156,9 +156,9 @@ module id_stage #( .irq_i, .pc_i (fetch_entry_i.address), .is_compressed_i (is_compressed_cmp), - .is_macro_instr_i (is_macro_instr_i), - .is_last_macro_instr_i (is_last_macro_instr_o), - .is_mv_macro_instr_i (is_mv_macro_instr_o), + .is_macro_instr_i (is_macro_instr_i), + .is_last_macro_instr_i (is_last_macro_instr_o), + .is_mv_macro_instr_i (is_mv_macro_instr_o), .is_illegal_i (is_illegal_cmp), .instruction_i (instruction), .compressed_instr_i (fetch_entry_i.instruction[15:0]), @@ -217,5 +217,4 @@ module id_stage #( issue_q <= issue_n; end end -endmodule - +endmodule \ No newline at end of file diff --git a/core/macro_decoder.sv b/core/macro_decoder.sv index 8555a1eba2..73bccc09fc 100644 --- a/core/macro_decoder.sv +++ b/core/macro_decoder.sv @@ -18,16 +18,16 @@ module macro_decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic [31:0] instr_i, - input logic clk_i, // Clock - input logic rst_ni, // Synchronous reset - input logic is_macro_instr_i, // Intruction is of macro extension - input logic illegal_instr_i, // From compressed decoder + input logic clk_i, // Clock + input logic rst_ni, // Synchronous reset + input logic is_macro_instr_i, // Intruction is of macro extension + input logic illegal_instr_i, // From compressed decoder input logic is_compressed_i, - input logic issue_ack_i, // Check if the intruction is acknowledged + input logic issue_ack_i, // Check if the intruction is acknowledged output logic [31:0] instr_o, output logic illegal_instr_o, output logic is_compressed_o, - output logic fetch_stall_o, //Wait while push/pop/move instructions expand + output logic fetch_stall_o, //Wait while push/pop/move instructions expand output logic is_last_macro_instr_o, output logic is_mv_macro_instr_o ); @@ -64,18 +64,18 @@ module macro_decoder #( riscv::itype_t itype_inst; assign instr_o = instr_o_reg; always_comb begin - illegal_instr_o = 1'b0; - fetch_stall_o = 1'b0; + illegal_instr_o = 1'b0; + fetch_stall_o = 1'b0; is_last_macro_instr_o = 1'b0; - is_mv_macro_instr_o = 1'b0; - is_compressed_o = is_macro_instr_i ? 1'b1 : is_compressed_i; - reg_numbers = '0; - stack_adj = '0; - state_d = state_q; - offset_d = offset_q; - reg_numbers_d = reg_numbers_q; - store_reg_d = store_reg_q; - popretz_inst_d = popretz_inst_q; + is_mv_macro_instr_o = 1'b0; + is_compressed_o = is_macro_instr_i ? 1'b1 : is_compressed_i; + reg_numbers = '0; + stack_adj = '0; + state_d = state_q; + offset_d = offset_q; + reg_numbers_d = reg_numbers_q; + store_reg_d = store_reg_q; + popretz_inst_d = popretz_inst_q; if (is_macro_instr_i) begin @@ -427,7 +427,16 @@ module macro_decoder #( if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin if (reg_numbers_q == 4'b0001) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_d[11:5], 5'h1, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; + instr_o_reg = { + offset_d[11:5], + 5'h1, + 5'h2, + 3'h3, + offset_d[4:3], + 1'b0, + offset_d[1:0], + riscv::OpcodeStore + }; end else begin instr_o_reg = {offset_d[11:5], 5'h1, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore}; end @@ -436,7 +445,16 @@ module macro_decoder #( if (reg_numbers_q == 4'b0010) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_d[11:5], 5'h8, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; + instr_o_reg = { + offset_d[11:5], + 5'h8, + 5'h2, + 3'h3, + offset_d[4:3], + 1'b0, + offset_d[1:0], + riscv::OpcodeStore + }; end else begin instr_o_reg = {offset_d[11:5], 5'h8, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore}; end @@ -446,7 +464,16 @@ module macro_decoder #( if (reg_numbers_q == 4'b0011) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_d[11:5], 5'h9, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore}; + instr_o_reg = { + offset_d[11:5], + 5'h9, + 5'h2, + 3'h3, + offset_d[4:3], + 1'b0, + offset_d[1:0], + riscv::OpcodeStore + }; end else begin instr_o_reg = {offset_d[11:5], 5'h9, 5'h2, 3'h2, offset_d[4:0], riscv::OpcodeStore}; end @@ -457,7 +484,14 @@ module macro_decoder #( if (reg_numbers_q >= 4 && reg_numbers_q <= 12) begin if (riscv::XLEN == 64) begin instr_o_reg = { - offset_d[11:5], store_reg_q, 5'h2, 3'h3, offset_d[4:3], 1'b0, offset_d[1:0], riscv::OpcodeStore + offset_d[11:5], + store_reg_q, + 5'h2, + 3'h3, + offset_d[4:3], + 1'b0, + offset_d[1:0], + riscv::OpcodeStore }; end else begin instr_o_reg = { @@ -477,7 +511,9 @@ module macro_decoder #( if (reg_numbers_q == 1) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad}; + instr_o_reg = { + offset_d[11:3], 1'b0, offset_d[1:0], 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad + }; end else begin instr_o_reg = {offset_d[11:0], 5'h2, 3'h2, 5'h1, riscv::OpcodeLoad}; end @@ -726,5 +762,4 @@ module macro_decoder #( popretz_inst_q <= popretz_inst_d; end end -endmodule - +endmodule \ No newline at end of file From c566d56c307169e9be323287d71a9ea31ec3a3d2 Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 11 Mar 2024 18:27:35 +0500 Subject: [PATCH 11/15] verible format files -- added newlines --- core/cva6.sv | 2 +- core/decoder.sv | 2 +- core/id_stage.sv | 2 +- core/macro_decoder.sv | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/cva6.sv b/core/cva6.sv index 28c885acfb..0c200c7830 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1565,4 +1565,4 @@ module cva6 ); -endmodule // ariane \ No newline at end of file +endmodule // ariane diff --git a/core/decoder.sv b/core/decoder.sv index e6983fd51e..e131708c55 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -1436,4 +1436,4 @@ module decoder instruction_o.ex.cause = riscv::DEBUG_REQUEST; end end -endmodule \ No newline at end of file +endmodule diff --git a/core/id_stage.sv b/core/id_stage.sv index 302ff13933..19b8cda210 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -217,4 +217,4 @@ module id_stage #( issue_q <= issue_n; end end -endmodule \ No newline at end of file +endmodule diff --git a/core/macro_decoder.sv b/core/macro_decoder.sv index 73bccc09fc..65eb4b1d81 100644 --- a/core/macro_decoder.sv +++ b/core/macro_decoder.sv @@ -762,4 +762,4 @@ module macro_decoder #( popretz_inst_q <= popretz_inst_d; end end -endmodule \ No newline at end of file +endmodule From 60cc92e5174cf8770a39976f6b65f50577926ce9 Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 11 Mar 2024 21:40:11 +0500 Subject: [PATCH 12/15] renamed mv_macro occurrances with double_rd_macro --- core/cva6.sv | 2 +- core/decoder.sv | 50 +++++++++++++++++----------------- core/id_stage.sv | 62 +++++++++++++++++++++---------------------- core/macro_decoder.sv | 46 ++++++++++++++++---------------- core/rename | 3 --- core/scoreboard.sv | 10 +++---- 6 files changed, 85 insertions(+), 88 deletions(-) delete mode 100644 core/rename diff --git a/core/cva6.sv b/core/cva6.sv index 0c200c7830..94136acdd2 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -107,7 +107,7 @@ module cva6 // we want jump accordingly e.g.: +4, +2 logic is_macro_instr; // instruction is of Zcmp Extension logic is_last_macro_instr; // is last decoded 32bit instruction of Zcmp Extension - logic is_mv_macro_instr; // is double move decoded 32bit instruction of Zcmp Extension + logic is_double_rd_macro_instr; // is double move decoded 32bit instruction of Zcmp Extension logic vfp; // is this a vector floating-point instruction? }, diff --git a/core/decoder.sv b/core/decoder.sv index e131708c55..70b399da12 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -45,7 +45,7 @@ module decoder // Is a last macro instruction - macro_decoder input logic is_last_macro_instr_i, // Is mvsa01/mva01s macro instruction - macro_decoder - input logic is_mv_macro_instr_i, + input logic is_double_rd_macro_instr_i, // Is a branch predict instruction - FRONTEND input branchpredict_sbe_t branch_predict_i, // If an exception occured in fetch stage - FRONTEND @@ -134,30 +134,30 @@ module decoder always_comb begin : decoder - imm_select = NOIMM; - is_control_flow_instr_o = 1'b0; - illegal_instr = 1'b0; - illegal_instr_non_bm = 1'b0; - illegal_instr_bm = 1'b0; - illegal_instr_zic = 1'b0; - instruction_o.pc = pc_i; - instruction_o.trans_id = '0; - instruction_o.fu = NONE; - instruction_o.op = ariane_pkg::ADD; - instruction_o.rs1 = '0; - instruction_o.rs2 = '0; - instruction_o.rd = '0; - instruction_o.use_pc = 1'b0; - instruction_o.is_compressed = is_compressed_i; - instruction_o.is_macro_instr = is_macro_instr_i; - instruction_o.is_last_macro_instr = is_last_macro_instr_i; - instruction_o.is_mv_macro_instr = is_mv_macro_instr_i; - instruction_o.use_zimm = 1'b0; - instruction_o.bp = branch_predict_i; - instruction_o.vfp = 1'b0; - ecall = 1'b0; - ebreak = 1'b0; - check_fprm = 1'b0; + imm_select = NOIMM; + is_control_flow_instr_o = 1'b0; + illegal_instr = 1'b0; + illegal_instr_non_bm = 1'b0; + illegal_instr_bm = 1'b0; + illegal_instr_zic = 1'b0; + instruction_o.pc = pc_i; + instruction_o.trans_id = '0; + instruction_o.fu = NONE; + instruction_o.op = ariane_pkg::ADD; + instruction_o.rs1 = '0; + instruction_o.rs2 = '0; + instruction_o.rd = '0; + instruction_o.use_pc = 1'b0; + instruction_o.is_compressed = is_compressed_i; + instruction_o.is_macro_instr = is_macro_instr_i; + instruction_o.is_last_macro_instr = is_last_macro_instr_i; + instruction_o.is_double_rd_macro_instr = is_double_rd_macro_instr_i; + instruction_o.use_zimm = 1'b0; + instruction_o.bp = branch_predict_i; + instruction_o.vfp = 1'b0; + ecall = 1'b0; + ebreak = 1'b0; + check_fprm = 1'b0; if (~ex_i.valid) begin case (instr.rtype.opcode) diff --git a/core/id_stage.sv b/core/id_stage.sv index 19b8cda210..1ce879ba20 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -90,7 +90,7 @@ module id_stage #( logic is_macro_instr_i; logic stall_instr_fetch; logic is_last_macro_instr_o; - logic is_mv_macro_instr_o; + logic is_double_rd_macro_instr_o; if (CVA6Cfg.RVC) begin // --------------------------------------------------------- @@ -110,26 +110,26 @@ module id_stage #( macro_decoder #( .CVA6Cfg(CVA6Cfg) ) macro_decoder_i ( - .instr_i (compressed_instr), - .is_macro_instr_i (is_macro_instr_i), - .clk_i (clk_i), - .rst_ni (rst_ni), - .instr_o (instruction), - .illegal_instr_i (is_illegal), - .is_compressed_i (is_compressed), - .issue_ack_i (issue_instr_ack_i), - .illegal_instr_o (is_illegal_cmp), - .is_compressed_o (is_compressed_cmp), - .fetch_stall_o (stall_instr_fetch), - .is_last_macro_instr_o(is_last_macro_instr_o), - .is_mv_macro_instr_o (is_mv_macro_instr_o) + .instr_i (compressed_instr), + .is_macro_instr_i (is_macro_instr_i), + .clk_i (clk_i), + .rst_ni (rst_ni), + .instr_o (instruction), + .illegal_instr_i (is_illegal), + .is_compressed_i (is_compressed), + .issue_ack_i (issue_instr_ack_i), + .illegal_instr_o (is_illegal_cmp), + .is_compressed_o (is_compressed_cmp), + .fetch_stall_o (stall_instr_fetch), + .is_last_macro_instr_o (is_last_macro_instr_o), + .is_double_rd_macro_instr_o(is_double_rd_macro_instr_o) ); end else begin assign instruction = compressed_instr; assign is_illegal_cmp = is_illegal; assign is_compressed_cmp = is_compressed; assign is_last_macro_instr_o = '0; - assign is_mv_macro_instr_o = '0; + assign is_double_rd_macro_instr_o = '0; end end else begin assign instruction = fetch_entry_i.instruction; @@ -137,7 +137,7 @@ module id_stage #( assign is_compressed_cmp = '0; assign is_macro_instr_i = '0; assign is_last_macro_instr_o = '0; - assign is_mv_macro_instr_o = '0; + assign is_double_rd_macro_instr_o = '0; end assign rvfi_is_compressed_o = is_compressed_cmp; @@ -154,27 +154,27 @@ module id_stage #( .debug_req_i, .irq_ctrl_i, .irq_i, - .pc_i (fetch_entry_i.address), - .is_compressed_i (is_compressed_cmp), - .is_macro_instr_i (is_macro_instr_i), - .is_last_macro_instr_i (is_last_macro_instr_o), - .is_mv_macro_instr_i (is_mv_macro_instr_o), - .is_illegal_i (is_illegal_cmp), - .instruction_i (instruction), - .compressed_instr_i (fetch_entry_i.instruction[15:0]), - .branch_predict_i (fetch_entry_i.branch_predict), - .ex_i (fetch_entry_i.ex), - .priv_lvl_i (priv_lvl_i), - .debug_mode_i (debug_mode_i), + .pc_i (fetch_entry_i.address), + .is_compressed_i (is_compressed_cmp), + .is_macro_instr_i (is_macro_instr_i), + .is_last_macro_instr_i (is_last_macro_instr_o), + .is_double_rd_macro_instr_i(is_double_rd_macro_instr_o), + .is_illegal_i (is_illegal_cmp), + .instruction_i (instruction), + .compressed_instr_i (fetch_entry_i.instruction[15:0]), + .branch_predict_i (fetch_entry_i.branch_predict), + .ex_i (fetch_entry_i.ex), + .priv_lvl_i (priv_lvl_i), + .debug_mode_i (debug_mode_i), .fs_i, .frm_i, .vs_i, .tvm_i, .tw_i, .tsr_i, - .instruction_o (decoded_instruction), - .orig_instr_o (orig_instr), - .is_control_flow_instr_o(is_control_flow_instr) + .instruction_o (decoded_instruction), + .orig_instr_o (orig_instr), + .is_control_flow_instr_o (is_control_flow_instr) ); // ------------------ diff --git a/core/macro_decoder.sv b/core/macro_decoder.sv index 65eb4b1d81..43f2a0e64a 100644 --- a/core/macro_decoder.sv +++ b/core/macro_decoder.sv @@ -18,18 +18,18 @@ module macro_decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty ) ( input logic [31:0] instr_i, - input logic clk_i, // Clock - input logic rst_ni, // Synchronous reset - input logic is_macro_instr_i, // Intruction is of macro extension - input logic illegal_instr_i, // From compressed decoder + input logic clk_i, // Clock + input logic rst_ni, // Synchronous reset + input logic is_macro_instr_i, // Intruction is of macro extension + input logic illegal_instr_i, // From compressed decoder input logic is_compressed_i, - input logic issue_ack_i, // Check if the intruction is acknowledged + input logic issue_ack_i, // Check if the intruction is acknowledged output logic [31:0] instr_o, output logic illegal_instr_o, output logic is_compressed_o, - output logic fetch_stall_o, //Wait while push/pop/move instructions expand + output logic fetch_stall_o, //Wait while push/pop/move instructions expand output logic is_last_macro_instr_o, - output logic is_mv_macro_instr_o + output logic is_double_rd_macro_instr_o ); // FSM States @@ -64,18 +64,18 @@ module macro_decoder #( riscv::itype_t itype_inst; assign instr_o = instr_o_reg; always_comb begin - illegal_instr_o = 1'b0; - fetch_stall_o = 1'b0; - is_last_macro_instr_o = 1'b0; - is_mv_macro_instr_o = 1'b0; - is_compressed_o = is_macro_instr_i ? 1'b1 : is_compressed_i; - reg_numbers = '0; - stack_adj = '0; - state_d = state_q; - offset_d = offset_q; - reg_numbers_d = reg_numbers_q; - store_reg_d = store_reg_q; - popretz_inst_d = popretz_inst_q; + illegal_instr_o = 1'b0; + fetch_stall_o = 1'b0; + is_last_macro_instr_o = 1'b0; + is_double_rd_macro_instr_o = 1'b0; + is_compressed_o = is_macro_instr_i ? 1'b1 : is_compressed_i; + reg_numbers = '0; + stack_adj = '0; + state_d = state_q; + offset_d = offset_q; + reg_numbers_d = reg_numbers_q; + store_reg_d = store_reg_q; + popretz_inst_d = popretz_inst_q; if (is_macro_instr_i) begin @@ -308,7 +308,7 @@ module macro_decoder #( if (macro_instr_type == MVSA01) begin fetch_stall_o = 1; - is_mv_macro_instr_o = 1; + is_double_rd_macro_instr_o = 1; // addi xreg1, a0, 0 instr_o_reg = {12'h0, 5'hA, 3'h0, xreg1, riscv::OpcodeOpImm}; state_d = MOVE; @@ -316,7 +316,7 @@ module macro_decoder #( if (macro_instr_type == MVA01S) begin fetch_stall_o = 1; - is_mv_macro_instr_o = 1; + is_double_rd_macro_instr_o = 1; // addi a0, xreg1, 0 instr_o_reg = {12'h0, xreg1, 3'h0, 5'hA, riscv::OpcodeOpImm}; state_d = MOVE; @@ -578,7 +578,7 @@ module macro_decoder #( instr_o_reg = {12'h0, 5'hB, 3'h0, xreg2, riscv::OpcodeOpImm}; fetch_stall_o = 0; is_last_macro_instr_o = 1; - is_mv_macro_instr_o = 1; + is_double_rd_macro_instr_o = 1; state_d = IDLE; end end @@ -588,7 +588,7 @@ module macro_decoder #( instr_o_reg = {12'h0, xreg2, 3'h0, 5'hB, riscv::OpcodeOpImm}; fetch_stall_o = 0; is_last_macro_instr_o = 1; - is_mv_macro_instr_o = 1; + is_double_rd_macro_instr_o = 1; state_d = IDLE; end end diff --git a/core/rename b/core/rename deleted file mode 100644 index e7d590db59..0000000000 --- a/core/rename +++ /dev/null @@ -1,3 +0,0 @@ -find /home/rohan/cva6/core/ -type f -exec sed -i.bak 's/macro/macro/g' {} \; - - diff --git a/core/scoreboard.sv b/core/scoreboard.sv index c73b8bd230..01c29238e0 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -187,17 +187,17 @@ module scoreboard #( // check if this instruction was issued (e.g.: it could happen after a flush that there is still // something in the pipeline e.g. an incomplete memory operation) if (wt_valid_i[i] && mem_q[trans_id_i[i]].issued) begin - if (mem_q[trans_id_i[i]].sbe.is_mv_macro_instr && mem_q[trans_id_i[i]].sbe.is_macro_instr) begin + if (mem_q[trans_id_i[i]].sbe.is_double_rd_macro_instr && mem_q[trans_id_i[i]].sbe.is_macro_instr) begin if (mem_q[trans_id_i[i]].sbe.is_last_macro_instr) begin mem_n[trans_id_i[i]].sbe.valid = 1'b1; mem_n[prev_trans_id[prev_i]].sbe.valid = 1'b1; end else begin - mem_n[trans_id_i[i]].sbe.valid = 1'b0; + mem_n[trans_id_i[i]].sbe.valid = 1'b0; prev_trans_id[i] = trans_id_i[i]; prev_i = i; end - end else begin - mem_n[trans_id_i[i]].sbe.valid = 1'b1; + end else begin + mem_n[trans_id_i[i]].sbe.valid = 1'b1; end mem_n[trans_id_i[i]].sbe.result = wbdata_i[i]; // save the target address of a branch (needed for debug in commit stage) @@ -499,4 +499,4 @@ module scoreboard #( end end //pragma translate_on -endmodule \ No newline at end of file +endmodule From f58d945f0107bc7d4ae6562873dfd4136efac9ca Mon Sep 17 00:00:00 2001 From: rohan Date: Tue, 12 Mar 2024 10:56:49 +0500 Subject: [PATCH 13/15] Generalized comments, fixed alignment --- core/cva6.sv | 6 +++--- core/scoreboard.sv | 8 ++------ corev_apu/fpga/src/ariane_xilinx.sv | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/core/cva6.sv b/core/cva6.sv index 94136acdd2..c13bccc22e 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -105,9 +105,9 @@ module cva6 branchpredict_sbe_t bp; // branch predict scoreboard data structure logic is_compressed; // signals a compressed instructions, we need this information at the commit stage if // we want jump accordingly e.g.: +4, +2 - logic is_macro_instr; // instruction is of Zcmp Extension - logic is_last_macro_instr; // is last decoded 32bit instruction of Zcmp Extension - logic is_double_rd_macro_instr; // is double move decoded 32bit instruction of Zcmp Extension + logic is_macro_instr; // is an instruction executed as predefined sequence of instructions called macro definition + logic is_last_macro_instr; // is last decoded 32bit instruction of macro definition + logic is_double_rd_macro_instr; // is double move decoded 32bit instruction of macro definition logic vfp; // is this a vector floating-point instruction? }, diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 01c29238e0..b98fd4e302 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -111,8 +111,6 @@ module scoreboard #( } sb_mem_t; sb_mem_t [ariane_pkg::NR_SB_ENTRIES-1:0] mem_q, mem_n; - logic [CVA6Cfg.NrWbPorts-1:0][ariane_pkg::TRANS_ID_BITS-1:0] prev_trans_id; // transaction ID for the first decoded mvsa01/mva01s instr - int unsigned prev_i; // WbPort number for the first decoded mvsa01/mva01s instr logic issue_full, issue_en; logic [ariane_pkg::TRANS_ID_BITS:0] issue_cnt_n, issue_cnt_q; logic [ariane_pkg::TRANS_ID_BITS-1:0] issue_pointer_n, issue_pointer_q; @@ -189,12 +187,10 @@ module scoreboard #( if (wt_valid_i[i] && mem_q[trans_id_i[i]].issued) begin if (mem_q[trans_id_i[i]].sbe.is_double_rd_macro_instr && mem_q[trans_id_i[i]].sbe.is_macro_instr) begin if (mem_q[trans_id_i[i]].sbe.is_last_macro_instr) begin - mem_n[trans_id_i[i]].sbe.valid = 1'b1; - mem_n[prev_trans_id[prev_i]].sbe.valid = 1'b1; + mem_n[trans_id_i[i]].sbe.valid = 1'b1; + mem_n[trans_id_i[i]-1].sbe.valid = 1'b1; end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b0; - prev_trans_id[i] = trans_id_i[i]; - prev_i = i; end end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b1; diff --git a/corev_apu/fpga/src/ariane_xilinx.sv b/corev_apu/fpga/src/ariane_xilinx.sv index 7b80c353e8..9202711dd4 100644 --- a/corev_apu/fpga/src/ariane_xilinx.sv +++ b/corev_apu/fpga/src/ariane_xilinx.sv @@ -175,7 +175,7 @@ localparam config_pkg::cva6_user_cfg_t CVA6UserCfg = '{ RVV: bit'(cva6_config_pkg::CVA6ConfigVExtEn), RVC: bit'(cva6_config_pkg::CVA6ConfigCExtEn), RVZCB: bit'(cva6_config_pkg::CVA6ConfigZcbExtEn), - RVZCMP: bit'(cva6_config_pkg::CVA6ConfigZcmpExtEn), + RVZCMP: bit'(cva6_config_pkg::CVA6ConfigZcmpExtEn), XFVec: bit'(cva6_config_pkg::CVA6ConfigFVecEn), CvxifEn: bit'(cva6_config_pkg::CVA6ConfigCvxifEn), ZiCondExtEn: bit'(0), From 1535f3c525666672c70fab3eb2e094c48c888c40 Mon Sep 17 00:00:00 2001 From: rohan Date: Tue, 12 Mar 2024 15:41:20 +0500 Subject: [PATCH 14/15] verible format, removed lint warnings --- core/compressed_decoder.sv | 8 ++++---- core/macro_decoder.sv | 14 +++++++------- core/scoreboard.sv | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index 8ae7abe923..902f31ded6 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -38,10 +38,10 @@ module compressed_decoder #( // Compressed Decoder // ------------------- always_comb begin - illegal_instr_o = 1'b0; - instr_o = '0; - is_compressed_o = 1'b1; - instr_o = instr_i; + illegal_instr_o = 1'b0; + instr_o = '0; + is_compressed_o = 1'b1; + instr_o = instr_i; is_macro_instr_o = 0; // I: | imm[11:0] | rs1 | funct3 | rd | opcode | diff --git a/core/macro_decoder.sv b/core/macro_decoder.sv index 43f2a0e64a..0fa2f0f4c8 100644 --- a/core/macro_decoder.sv +++ b/core/macro_decoder.sv @@ -55,7 +55,7 @@ module macro_decoder #( // Temporary registers logic [3:0] reg_numbers, reg_numbers_q, reg_numbers_d; - logic [8:0] stack_adj; + logic [11:0] stack_adj; logic [4:0] xreg1, xreg2, store_reg, store_reg_q, store_reg_d; logic [1:0] popretz_inst_q, popretz_inst_d; logic [11:0] offset_reg, offset_q, offset_d; @@ -374,7 +374,7 @@ module macro_decoder #( if (reg_numbers == 1) begin if (riscv::XLEN == 64) begin instr_o_reg = { - offset_reg - 4, 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad + offset_reg - 12'h4, 5'h2, 3'h3, 5'h1, riscv::OpcodeLoad }; // ld store_reg, Imm(sp) end else begin instr_o_reg = { @@ -394,7 +394,7 @@ module macro_decoder #( if (reg_numbers == 2) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_reg - 4, 5'h2, 3'h3, 5'h8, riscv::OpcodeLoad}; + instr_o_reg = {offset_reg - 12'h4, 5'h2, 3'h3, 5'h8, riscv::OpcodeLoad}; end else begin instr_o_reg = {offset_reg, 5'h2, 3'h2, 5'h8, riscv::OpcodeLoad}; end @@ -402,7 +402,7 @@ module macro_decoder #( if (reg_numbers == 3) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_reg - 4, 5'h2, 3'h3, 5'h9, riscv::OpcodeLoad}; + instr_o_reg = {offset_reg - 12'h4, 5'h2, 3'h3, 5'h9, riscv::OpcodeLoad}; end else begin instr_o_reg = {offset_reg, 5'h2, 3'h2, 5'h9, riscv::OpcodeLoad}; end @@ -410,7 +410,7 @@ module macro_decoder #( if (reg_numbers >= 4 && reg_numbers <= 12) begin if (riscv::XLEN == 64) begin - instr_o_reg = {offset_reg - 4, 5'h2, 3'h3, store_reg, riscv::OpcodeLoad}; + instr_o_reg = {offset_reg - 12'h4, 5'h2, 3'h3, store_reg, riscv::OpcodeLoad}; end else begin instr_o_reg = {offset_reg, 5'h2, 3'h2, store_reg, riscv::OpcodeLoad}; end @@ -603,10 +603,10 @@ module macro_decoder #( if (riscv::XLEN == 64) begin if (issue_ack_i && is_macro_instr_i && macro_instr_type == PUSH) begin // addi sp, sp, stack_adj - instr_o_reg = {itype_inst.imm - 4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; + instr_o_reg = {itype_inst.imm - 12'h4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; end else begin if (issue_ack_i) begin - instr_o_reg = {stack_adj - 4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; + instr_o_reg = {stack_adj - 12'h4, 5'h2, 3'h0, 5'h2, riscv::OpcodeOpImm}; end end if (issue_ack_i && is_macro_instr_i && (macro_instr_type == POPRETZ || macro_instr_type == POPRET)) begin diff --git a/core/scoreboard.sv b/core/scoreboard.sv index b98fd4e302..4b0fd6f3b9 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -187,8 +187,8 @@ module scoreboard #( if (wt_valid_i[i] && mem_q[trans_id_i[i]].issued) begin if (mem_q[trans_id_i[i]].sbe.is_double_rd_macro_instr && mem_q[trans_id_i[i]].sbe.is_macro_instr) begin if (mem_q[trans_id_i[i]].sbe.is_last_macro_instr) begin - mem_n[trans_id_i[i]].sbe.valid = 1'b1; - mem_n[trans_id_i[i]-1].sbe.valid = 1'b1; + mem_n[trans_id_i[i]].sbe.valid = 1'b1; + mem_n[trans_id_i[i]-2'b1].sbe.valid = 1'b1; end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b0; end From 599253bcbd9be86d4fa73fd42c1c5607de81e3d0 Mon Sep 17 00:00:00 2001 From: rohan Date: Wed, 13 Mar 2024 11:56:01 +0500 Subject: [PATCH 15/15] Fixed additional lint warnings --- core/macro_decoder.sv | 2 +- core/scoreboard.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/macro_decoder.sv b/core/macro_decoder.sv index 0fa2f0f4c8..224e8eb649 100644 --- a/core/macro_decoder.sv +++ b/core/macro_decoder.sv @@ -263,7 +263,7 @@ module macro_decoder #( if (macro_instr_type == PUSH) begin itype_inst.imm = ~stack_adj + 1'b1; end else begin - itype_inst.imm = stack_adj - 3'b100; + itype_inst.imm = stack_adj - 12'h4; end end else begin illegal_instr_o = illegal_instr_i; diff --git a/core/scoreboard.sv b/core/scoreboard.sv index 4b0fd6f3b9..73bead147e 100644 --- a/core/scoreboard.sv +++ b/core/scoreboard.sv @@ -188,7 +188,7 @@ module scoreboard #( if (mem_q[trans_id_i[i]].sbe.is_double_rd_macro_instr && mem_q[trans_id_i[i]].sbe.is_macro_instr) begin if (mem_q[trans_id_i[i]].sbe.is_last_macro_instr) begin mem_n[trans_id_i[i]].sbe.valid = 1'b1; - mem_n[trans_id_i[i]-2'b1].sbe.valid = 1'b1; + mem_n[8'(trans_id_i[i])-1].sbe.valid = 1'b1; end else begin mem_n[trans_id_i[i]].sbe.valid = 1'b0; end