From 66ae110a51d27742fe8668daf3a95ddb3b4d9146 Mon Sep 17 00:00:00 2001 From: Jalali <110232072+AyoubJalali@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:29:02 +0000 Subject: [PATCH] CVXIF Verif : Connect CVXIF new agent (#2663) --- verif/core-v-verif | 2 +- .../uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv | 72 ++- verif/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv | 423 ++++++++++++------ verif/env/uvme/uvme_cva6_cfg.sv | 16 +- verif/env/uvme/uvme_cva6_cntxt.sv | 19 +- verif/env/uvme/uvme_cva6_env.sv | 26 +- verif/env/uvme/uvme_cva6_pkg.flist | 1 + verif/env/uvme/uvme_cva6_pkg.sv | 2 + verif/env/uvme/uvme_cva6_vsqr.sv | 1 + verif/sim/Makefile | 1 + verif/tb/uvmt/cva6_tb_wrapper.sv | 35 +- verif/tb/uvmt/uvmt_cva6.flist | 1 + verif/tb/uvmt/uvmt_cva6_dut_wrap.sv | 9 + verif/tb/uvmt/uvmt_cva6_tb.sv | 11 + 14 files changed, 435 insertions(+), 184 deletions(-) diff --git a/verif/core-v-verif b/verif/core-v-verif index 9601c80f4c..6c1e999a97 160000 --- a/verif/core-v-verif +++ b/verif/core-v-verif @@ -1 +1 @@ -Subproject commit 9601c80f4cbdeda5527ea7f88f9015d3a554da4a +Subproject commit 6c1e999a97f61b4b805603ba142a1347f785fff2 diff --git a/verif/env/uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv b/verif/env/uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv index cb47ecc3db..048d76a480 100644 --- a/verif/env/uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv +++ b/verif/env/uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv @@ -28,7 +28,9 @@ class uvme_cvxif_base_vseq_c extends uvm_sequence #(uvma_cvxif_resp_item_c); extern virtual task pre_body(); - extern function string decode(input logic [31:0] instr); + extern virtual function string decode(input logic [31:0] instr); + + extern virtual function string compressed_decode(input logic [15:0] instr); endclass @@ -47,10 +49,30 @@ task uvme_cvxif_base_vseq_c::pre_body(); endtask +function string uvme_cvxif_base_vseq_c::compressed_decode(input logic [15:0] instr); + + bit [2:0] Cfunc3 = instr [15:13]; + bit [1:0] op = instr [1:0]; + + if (instr[1:0] != 2'b11) begin + if (op == 2'b00 && Cfunc3 == 3'b111) begin + if (!instr[12]) return ("CUS_CNOP"); + else return ("CUS_CADD"); + end + end + + return ("ILLEGAL"); + +endfunction + function string uvme_cvxif_base_vseq_c::decode(input logic [31:0] instr); bit [6:0] opcode = instr [6:0]; bit [6:0] custom3 = 7'b1111011; + bit [6:0] MADD = 7'b1000011; + bit [6:0] MSUB = 7'b1000111; + bit [6:0] NMADD = 7'b1001111; + bit [6:0] NMSUB = 7'b1001011; bit [6:0] func7 = instr [31:25]; bit [1:0] func2 = instr [26:25]; bit [2:0] func3 = instr [14:12]; @@ -59,34 +81,50 @@ function string uvme_cvxif_base_vseq_c::decode(input logic [31:0] instr); bit [4:0] rs2 = instr [24:20]; if (opcode == custom3) begin - if (func3 == 3'b000) begin - if (func7 == 7'b0001000) begin + if (func3 == 3'b001) begin + if (func7 == 7'b0000011) begin return ("CUS_ADD_MULTI"); end - if (func2 == 2'b01) begin - return ("CUS_ADD_RS3"); - end if (func7 == 7'b0000010) begin - return ("CUS_U_ADD"); - end - if (func7 == 7'b0000110) begin - return ("CUS_S_ADD"); + return ("CUS_DOUBLE_RS2"); end - if (func7 == 7'b0000000 && rd == 0 && rs1 == 0 && rs2 == 0) begin - return ("CUS_NOP"); + if (func7 == 7'b0000001) begin + return ("CUS_DOUBLE_RS1"); end - end - if (func3 == 3'b001) begin if (func7 == 7'b0000000) begin return ("CUS_ADD"); end end - if (func3 == 3'b010 && rd == 0 && rs2 == 0) begin - if (func7 == 7'b1100000) begin - return ("CUS_EXC"); + if (func3 == 3'b000) begin + if (func7 == 7'b0000000) begin + return ("CUS_NOP"); end end end + else if (opcode == MADD) begin + if (func3 == 3'b000 && func2 == 2'b00) begin + return ("CUS_ADD_RS3_MADD"); + end + if (func3 == 3'b001 && func7 == 7'b0000100) begin + return ("CUS_ADD_RS3_RTYPE"); + end + end + else if (opcode == MSUB) begin + if (func3 == 3'b000 && func2 == 2'b00) begin + return ("CUS_ADD_RS3_MSUB"); + end + end + else if (opcode == NMADD) begin + if (func3 == 3'b000 && func2 == 2'b00) begin + return ("CUS_ADD_RS3_NMADD"); + end + end + else if (opcode == NMSUB) begin + if (func3 == 3'b000 && func2 == 2'b00) begin + return ("CUS_ADD_RS3_NMSUB"); + end + end + return ("ILLEGAL"); endfunction diff --git a/verif/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv b/verif/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv index 3d69e005ad..ddb443c11b 100644 --- a/verif/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv +++ b/verif/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv @@ -18,6 +18,7 @@ class uvme_cvxif_vseq_c extends uvme_cvxif_base_vseq_c; string info_tag = "CVXIF_VSEQ_RESP"; string instr; + string compressed_instr; /** * Default constructor. @@ -38,17 +39,22 @@ class uvme_cvxif_vseq_c extends uvme_cvxif_base_vseq_c; /** * Generate an issue response depending on received request */ - extern task do_issue_resp(); + extern virtual task do_issue_resp(); /** * Generate the result response independent of instruction received */ - extern task do_result_resp(); + extern virtual task do_result_resp(); /** * Generate the result response depending on instruction received */ - extern task do_instr_result(); + extern virtual task do_compressed_resp(); + + /** + * Generate the result response depending on instruction received + */ + extern virtual task do_instr_result(); /** * Main sequence body @@ -59,25 +65,44 @@ endclass task uvme_cvxif_vseq_c::body(); - forever begin - // wait for a transaction request (get is blocking) - `uvm_info(info_tag, $sformatf("Waiting for the transaction request from monitor"), UVM_HIGH); - p_sequencer.mm_req_fifo.get(req_item); - - //Decode the instruction received - instr = decode(req_item.issue_req.instr); - - // generate response based on observed request, e.g: - if (instr == "") begin - do_default(); - end - else begin - if (req_item.issue_valid && req_item.issue_ready) begin - //issue_resp - do_issue_resp(); - //result_resp - do_result_resp(); - //send resp to sqr + if (cfg.enabled_cvxif) begin + + do_default(); + forever begin + // wait for a transaction request (get is blocking) + `uvm_info(info_tag, $sformatf("Waiting for the transaction request from monitor"), UVM_HIGH); + p_sequencer.mm_req_fifo.get(req_item); + resp_item = uvma_cvxif_resp_item_c::type_id::create("resp_item"); + `uvm_info(info_tag, $sformatf("Request: %p ", req_item), UVM_HIGH); + + resp_item.issue_valid = '0; + resp_item.compressed_valid = '0; + + compressed_instr = compressed_decode(req_item.compressed_req.instr); + instr = decode(req_item.issue_req.instr); + `uvm_info(info_tag, $sformatf("Compressed Instr: %s ", compressed_instr), UVM_HIGH); + `uvm_info(info_tag, $sformatf("Uncompressed Instr: %s ", instr), UVM_HIGH); + + if (req_item.compressed_valid) begin + if (compressed_instr == "") do_default(); + else begin + resp_item.compressed_valid = 1; + // compressed response + do_compressed_resp(); + end + end + if (req_item.issue_valid) begin + if (instr == "") do_default(); + else begin + resp_item.issue_valid = 1; + //issue response + do_issue_resp(); + //result response + do_result_resp(); + end + end + if (resp_item.issue_valid || resp_item.compressed_valid) begin + //send response to the sequencer send_resp(resp_item); end end @@ -93,186 +118,308 @@ endfunction : new task uvme_cvxif_vseq_c::do_default(); - resp_item.issue_resp.accept=0; - resp_item.issue_resp.writeback=0; - resp_item.issue_resp.dualwrite=0; - resp_item.issue_resp.dualread=0; - resp_item.issue_resp.exc=0; - resp_item.result_valid=0; - resp_item.result.id=0; - resp_item.result.exc=0; - resp_item.result.data=0; - resp_item.result.rd=0; - resp_item.result.we=0; - resp_item.result.exccode=0; - `uvm_info(info_tag, $sformatf("Sending default sequence response to sqr, accept = %d, result_valid = %d", resp_item.issue_resp.accept, resp_item.result_valid), UVM_HIGH); + resp_item.compressed_ready = 0; + resp_item.compressed_valid = 0; + resp_item.compressed_resp.accept = 0; + resp_item.compressed_resp.instr = 0; + + resp_item.issue_ready = 0; + resp_item.issue_valid = 0; + resp_item.issue_resp.accept = 0; + resp_item.issue_resp.writeback = 0; + resp_item.issue_resp.register_read = 0; + + resp_item.result_valid = 0; + resp_item.result.id = 0; + resp_item.result.hartid = 0; + resp_item.result.data = 0; + resp_item.result.rd = 0; + resp_item.result.we = 0; + + resp_item.delay_resp = 0; + `uvm_info(info_tag, $sformatf("Sending default sequence response to sqr"), UVM_NONE); + send_resp(resp_item); endtask task uvme_cvxif_vseq_c::do_issue_resp(); - resp_item.issue_resp.dualwrite = 0; - resp_item.issue_resp.dualread = 0; - resp_item.issue_resp.exc = 0; + resp_item.issue_resp.writeback = 0; + resp_item.issue_resp.accept = 0; + resp_item.issue_resp.register_read = 0; + case (instr) inside - "CUS_ADD", "CUS_ADD_MULTI" : begin - if (req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin + "CUS_NOP" : begin + resp_item.issue_resp.writeback = 0; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 0; + resp_item.delay_resp = 0; + end + "CUS_ADD" : begin + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 'b011; + resp_item.delay_resp = 0; + end + else begin + resp_item.delay_resp = 1; end end - "CUS_ADD_RS3" : begin - if (req_item.issue_req.rs_valid == 3'b111) begin + "CUS_DOUBLE_RS1" : begin + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 'b001; + resp_item.delay_resp = 0; end else begin - resp_item.issue_resp.writeback = 0; + resp_item.delay_resp = 1; + end + end + "CUS_DOUBLE_RS2" : begin + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin + resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; - resp_item.issue_resp.exc = 1; + resp_item.issue_resp.register_read = 'b010; + resp_item.delay_resp = 0; + end + else begin + resp_item.delay_resp = 1; end end - "CUS_NOP" : begin - resp_item.issue_resp.writeback = 0; - resp_item.issue_resp.accept = 1; + "CUS_ADD_MULTI" : begin + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 'b11; + resp_item.delay_resp = 0; + end + else begin + resp_item.delay_resp = 1; + end end - "CUS_EXC" : begin - resp_item.issue_resp.writeback = 0; - resp_item.issue_resp.accept = 1; - resp_item.issue_resp.exc = 1; + "CUS_ADD_RS3_MADD" : begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 3'b111; + resp_item.delay_resp = 0; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 2'b11; + resp_item.delay_resp = 0; + end + else begin + resp_item.delay_resp = 1; + end end - "CUS_U_ADD" : begin - if (req_item.issue_req.mode == PRIV_LVL_U && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin + "CUS_ADD_RS3_MSUB" : begin + if (req_item.register.rs_valid == 3'b111) begin resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 'b111; + resp_item.delay_resp = 0; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 2'b11; + resp_item.delay_resp = 0; end else begin - resp_item.issue_resp.writeback = 0; + resp_item.delay_resp = 1; + end + end + "CUS_ADD_RS3_NMADD" : begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; - resp_item.issue_resp.exc = 1; + resp_item.issue_resp.register_read = 'b111; + resp_item.delay_resp = 0; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 2'b11; + resp_item.delay_resp = 0; + end + else begin + resp_item.delay_resp = 1; end end - "CUS_S_ADD" : begin - if (req_item.issue_req.mode == PRIV_LVL_S && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin + "CUS_ADD_RS3_NMSUB" : begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 'b111; + resp_item.delay_resp = 0; + end + else if (req_item.register.rs_valid == 2'b11) begin resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 2'b11; + resp_item.delay_resp = 0; end else begin - resp_item.issue_resp.writeback = 0; + resp_item.delay_resp = 1; + end + end + "CUS_ADD_RS3_RTYPE" : begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.issue_resp.writeback = 1; resp_item.issue_resp.accept = 1; - resp_item.issue_resp.exc = 1; + resp_item.issue_resp.register_read = 'b111; + resp_item.delay_resp = 0; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.issue_resp.writeback = 1; + resp_item.issue_resp.accept = 1; + resp_item.issue_resp.register_read = 2'b11; + resp_item.delay_resp = 0; + end + else begin + resp_item.delay_resp = 1; end end - "ILLEGAL" : begin + default : begin resp_item.issue_resp.writeback = 0; - resp_item.issue_resp.accept = 1; - resp_item.issue_resp.exc = 1; + resp_item.issue_resp.accept = 0; + resp_item.issue_resp.register_read = 0; + resp_item.issue_ready = 1; end endcase - `uvm_info(info_tag, $sformatf("instr = %s", instr), UVM_LOW); - `uvm_info(info_tag, $sformatf("Response : accept = %h writeback = %h dualwrite = %h dualread = %h exc = %h", - resp_item.issue_resp.accept, resp_item.issue_resp.writeback, resp_item.issue_resp.dualwrite, resp_item.issue_resp.dualread, resp_item.issue_resp.exc), UVM_LOW); + +endtask + +task uvme_cvxif_vseq_c::do_compressed_resp(); + + case (compressed_instr) inside + "CUS_CNOP" : begin + resp_item.compressed_resp.accept = 1; + resp_item.compressed_resp.instr = 32'b00000000000000000000000001111011; + end + "CUS_CADD" : begin + resp_item.compressed_resp.accept = 1; + resp_item.compressed_resp.instr = 32'b00000000000000000001010101111011; + resp_item.compressed_resp.instr[19:15] = req_item.compressed_req.instr[11:7]; + resp_item.compressed_resp.instr[24:20] = req_item.compressed_req.instr[6:2]; + end + default : begin + resp_item.compressed_resp.accept = 0; + resp_item.compressed_resp.instr = req_item.compressed_req.instr; + end + endcase endtask task uvme_cvxif_vseq_c::do_result_resp(); - //result_resp - if (!req_item.commit_req.commit_kill && req_item.commit_valid) begin - resp_item.result_valid = 1; - resp_item.result.id = req_item.commit_req.id; - resp_item.result.rd = req_item.issue_req.instr[11:7]; - resp_item.result.we = resp_item.issue_resp.writeback; - resp_item.result.data = 0; - resp_item.result_ready = req_item.result_ready; + if (req_item.commit_valid && !req_item.commit_req.commit_kill) begin + resp_item.result_valid = 1; + resp_item.result.id = req_item.commit_req.id; + resp_item.result.hartid = req_item.commit_req.hartid; + resp_item.result.we = resp_item.issue_resp.writeback; + `uvm_info(info_tag, $sformatf("Request ID : %1d", req_item.commit_req.id), UVM_HIGH); do_instr_result(); - if (cfg.instr_delayed) begin - cfg.randomize(rnd_delay); - resp_item.rnd_delay = cfg.rnd_delay; - end - else begin - resp_item.rnd_delay = 0; - end end else begin resp_item.result_valid = 0; resp_item.result.id = 0; - resp_item.result.exc = 0; + resp_item.result.hartid = 0; resp_item.result.data = 0; resp_item.result.rd = 0; resp_item.result.we = 0; - resp_item.result.exccode = 0; - resp_item.rnd_delay = 0; end endtask task uvme_cvxif_vseq_c::do_instr_result(); - //result response depend on instruction - resp_item.result.exc = 0; - resp_item.result.exccode = 0; - cfg.instr_delayed = 0; + resp_item.result.rd = 0; + resp_item.result.data = 0; case (instr) "CUS_ADD": begin - if (req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) - resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1]; - else begin - resp_item.result.exc = 1; - resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction - `uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW); + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; end - end + end + "CUS_DOUBLE_RS1": begin + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[0]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + end + "CUS_DOUBLE_RS2": begin + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin + resp_item.result.data = req_item.register.rs[1] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + end "CUS_ADD_MULTI": begin - if (req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin - resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1]; - cfg.instr_delayed = 1; + if (req_item.register.rs_valid inside {2'b11, 3'b111}) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; end - else begin - resp_item.result.exc = 1; - resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction - `uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW); + end + "CUS_ADD_RS3_MADD": begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1] + req_item.register.rs[2]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; end - end - "CUS_EXC": begin - resp_item.result.exc = 1; - resp_item.result.exccode[4:0] = req_item.issue_req.instr[19:15]; - resp_item.result.exccode[5] = 1'b0; - `uvm_info(info_tag, $sformatf("EXCCODE: %d", resp_item.result.exccode), UVM_LOW); - end - "CUS_ADD_RS3": begin - if (req_item.issue_req.rs_valid == 3'b111) - resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1] + req_item.issue_req.rs[2]; - else begin - resp_item.result.exc = 1; - resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction - `uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW); + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; end - end - "CUS_U_ADD": begin - if (req_item.issue_req.mode == PRIV_LVL_U && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) - resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1]; - else begin - resp_item.result.exc = 1; - resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction - `uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW); - end - end - "CUS_S_ADD": begin - if (req_item.issue_req.mode == PRIV_LVL_S && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) - resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1]; - else begin - resp_item.result.exc = 1; - resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction - `uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW); - end - end + end + "CUS_ADD_RS3_MSUB": begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1] + req_item.register.rs[2]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + end + "CUS_ADD_RS3_NMADD": begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1] + req_item.register.rs[2]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + end + "CUS_ADD_RS3_NMSUB": begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1] + req_item.register.rs[2]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = req_item.issue_req.instr[11:7]; + end + end + "CUS_ADD_RS3_RTYPE": begin + if (req_item.register.rs_valid == 3'b111) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1] + req_item.register.rs[2]; + resp_item.result.rd = 5'h10; + end + else if (req_item.register.rs_valid == 2'b11) begin + resp_item.result.data = req_item.register.rs[0] + req_item.register.rs[1]; + resp_item.result.rd = 5'h10; + end + end "ILLEGAL": begin - resp_item.result.exc = 1; - resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction - `uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW); - end + resp_item.result.data = '0; + resp_item.result.rd = '0; + end endcase endtask diff --git a/verif/env/uvme/uvme_cva6_cfg.sv b/verif/env/uvme/uvme_cva6_cfg.sv index 81f07f45fc..946c63b4b3 100644 --- a/verif/env/uvme/uvme_cva6_cfg.sv +++ b/verif/env/uvme/uvme_cva6_cfg.sv @@ -46,6 +46,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; rand uvma_rvfi_cfg_c#(ILEN,XLEN) rvfi_cfg; rand uvma_isacov_cfg_c isacov_cfg; rand uvma_interrupt_cfg_c interrupt_cfg; + rand uvma_cvxif_cfg_c cvxif_cfg; // Zicond extension rand bit ext_zicond_supported; @@ -92,6 +93,8 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; `uvm_field_object(interrupt_cfg, UVM_DEFAULT) + `uvm_field_object(cvxif_cfg, UVM_DEFAULT) + `uvm_object_utils_end @@ -151,12 +154,20 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c; (!boot_addr_plusarg_valid) -> (boot_addr == 'h8000_0000); } - constraint default_interrupt_cons { + constraint default_cons { if (interrupt_cfg.interrupt_plusarg_valid) { interrupt_cfg.enable_interrupt == 'h1; } - else + else { interrupt_cfg.enable_interrupt == 'h0; + } + + if (cvxif_cfg.cvxif_plusarg_valid) { + cvxif_cfg.enabled_cvxif == 'h1; + } + else { + cvxif_cfg.enabled_cvxif == 'h0; + } } constraint agent_cfg_cons { @@ -243,6 +254,7 @@ function uvme_cva6_cfg_c::new(string name="uvme_cva6_cfg"); rvfi_cfg = uvma_rvfi_cfg_c#(ILEN,XLEN)::type_id::create("rvfi_cfg"); isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg"); interrupt_cfg = uvma_interrupt_cfg_c::type_id::create("interrupt_cfg"); + cvxif_cfg = uvma_cvxif_cfg_c::type_id::create("cvxif_cfg"); isacov_cfg.core_cfg = this; rvfi_cfg.core_cfg = this; diff --git a/verif/env/uvme/uvme_cva6_cntxt.sv b/verif/env/uvme/uvme_cva6_cntxt.sv index 3d07cae042..111278090a 100644 --- a/verif/env/uvme/uvme_cva6_cntxt.sv +++ b/verif/env/uvme/uvme_cva6_cntxt.sv @@ -30,11 +30,12 @@ class uvme_cva6_cntxt_c extends uvm_object; typedef uvml_mem_c#(cva6_config_pkg::CVA6ConfigAxiAddrWidth) uvml_mem_cva6; // Agent context handles - uvma_clknrst_cntxt_c clknrst_cntxt; - uvma_axi_cntxt_c axi_cntxt; + uvma_clknrst_cntxt_c clknrst_cntxt; + uvma_axi_cntxt_c axi_cntxt; uvma_cva6_core_cntrl_cntxt_c core_cntrl_cntxt; - uvma_rvfi_cntxt_c rvfi_cntxt; - uvma_interrupt_cntxt_c interrupt_cntxt; + uvma_rvfi_cntxt_c rvfi_cntxt; + uvma_interrupt_cntxt_c interrupt_cntxt; + uvma_cvxif_cntxt_c cvxif_cntxt; // Memory modelling rand uvml_mem_cva6 mem; @@ -53,6 +54,7 @@ class uvme_cva6_cntxt_c extends uvm_object; `uvm_field_object(core_cntrl_cntxt, UVM_DEFAULT) `uvm_field_object(rvfi_cntxt, UVM_DEFAULT) `uvm_field_object(interrupt_cntxt, UVM_DEFAULT) + `uvm_field_object(cvxif_cntxt, UVM_DEFAULT) `uvm_field_event(sample_cfg_e , UVM_DEFAULT) `uvm_field_event(sample_cntxt_e, UVM_DEFAULT) `uvm_field_object(mem, UVM_DEFAULT) @@ -74,12 +76,13 @@ function uvme_cva6_cntxt_c::new(string name="uvme_cva6_cntxt"); super.new(name); - clknrst_cntxt = uvma_clknrst_cntxt_c::type_id::create("clknrst_cntxt"); + clknrst_cntxt = uvma_clknrst_cntxt_c::type_id::create("clknrst_cntxt"); core_cntrl_cntxt = uvma_cva6_core_cntrl_cntxt_c::type_id::create("core_cntrl_cntxt"); - axi_cntxt = uvma_axi_cntxt_c::type_id::create("axi_cntxt"); + axi_cntxt = uvma_axi_cntxt_c::type_id::create("axi_cntxt"); mem = uvml_mem_cva6::type_id::create("mem"); - rvfi_cntxt = uvma_rvfi_cntxt_c#()::type_id::create("rvfi_cntxt"); - interrupt_cntxt = uvma_interrupt_cntxt_c::type_id::create("interrupt_cntxt"); + rvfi_cntxt = uvma_rvfi_cntxt_c#()::type_id::create("rvfi_cntxt"); + interrupt_cntxt = uvma_interrupt_cntxt_c::type_id::create("interrupt_cntxt"); + cvxif_cntxt = uvma_cvxif_cntxt_c::type_id::create("cvxif_cntxt"); sample_cfg_e = new("sample_cfg_e" ); sample_cntxt_e = new("sample_cntxt_e"); diff --git a/verif/env/uvme/uvme_cva6_env.sv b/verif/env/uvme/uvme_cva6_env.sv index 88af43f8eb..520b89133d 100644 --- a/verif/env/uvme/uvme_cva6_env.sv +++ b/verif/env/uvme/uvme_cva6_env.sv @@ -47,6 +47,7 @@ class uvme_cva6_env_c extends uvm_env; uvma_rvfi_agent_c#(ILEN,XLEN) rvfi_agent; uvma_isacov_agent_c#(ILEN,XLEN) isacov_agent; uvma_interrupt_agent_c interrupt_agent; + uvma_cvxif_agent_c cvxif_agent; // Handle to agent switch interface virtual uvmt_axi_switch_intf axi_switch_vif; @@ -256,6 +257,8 @@ function void uvme_cva6_env_c::assign_cfg(); uvm_config_db#(uvma_interrupt_cfg_c)::set(this, "*interrupt_agent", "cfg", cfg.interrupt_cfg); + uvm_config_db#(uvma_cvxif_cfg_c)::set(this, "*cvxif_agent", "cfg", cfg.cvxif_cfg); + endfunction: assign_cfg @@ -266,18 +269,20 @@ function void uvme_cva6_env_c::assign_cntxt(); uvm_config_db#(uvma_axi_cntxt_c)::set(this, "axi_agent", "cntxt", cntxt.axi_cntxt); uvm_config_db#(uvma_rvfi_cntxt_c)::set(this, "rvfi_agent", "cntxt", cntxt.rvfi_cntxt); uvm_config_db#(uvma_interrupt_cntxt_c)::set(this, "interrupt_agent", "cntxt", cntxt.interrupt_cntxt); + uvm_config_db#(uvma_cvxif_cntxt_c)::set(this, "cvxif_agent", "cntxt", cntxt.cvxif_cntxt); endfunction: assign_cntxt function void uvme_cva6_env_c::create_agents(); - clknrst_agent = uvma_clknrst_agent_c::type_id::create("clknrst_agent", this); - axi_agent = uvma_axi_agent_c::type_id::create("axi_agent", this); + clknrst_agent = uvma_clknrst_agent_c::type_id::create("clknrst_agent", this); + axi_agent = uvma_axi_agent_c::type_id::create("axi_agent", this); core_cntrl_agent = uvma_cva6_core_cntrl_agent_c::type_id::create("core_cntrl_agent", this); - rvfi_agent = uvma_rvfi_agent_c#(ILEN,XLEN)::type_id::create("rvfi_agent", this); - isacov_agent = uvma_isacov_agent_c#(ILEN,XLEN)::type_id::create("isacov_agent", this); + rvfi_agent = uvma_rvfi_agent_c#(ILEN,XLEN)::type_id::create("rvfi_agent", this); + isacov_agent = uvma_isacov_agent_c#(ILEN,XLEN)::type_id::create("isacov_agent", this); interrupt_agent = uvma_interrupt_agent_c::type_id::create("interrupt_agent", this); + cvxif_agent = uvma_cvxif_agent_c::type_id::create("cvxif_agent", this); endfunction: create_agents @@ -364,9 +369,10 @@ endfunction: connect_scoreboard function void uvme_cva6_env_c::assemble_vsequencer(); - vsequencer.clknrst_sequencer = clknrst_agent.sequencer; - vsequencer.axi_vsequencer = axi_agent.vsequencer; - vsequencer.interrupt_sequencer = interrupt_agent.sequencer; + vsequencer.clknrst_sequencer = clknrst_agent.sequencer; + vsequencer.axi_vsequencer = axi_agent.vsequencer; + vsequencer.interrupt_sequencer = interrupt_agent.sequencer; + vsequencer.cvxif_vsequencer = cvxif_agent.vsequencer; endfunction: assemble_vsequencer @@ -390,6 +396,12 @@ task uvme_cva6_env_c::run_phase(uvm_phase phase); interrupt_seq.start(interrupt_agent.sequencer); end end + + begin + uvme_cvxif_vseq_c cvxif_vseq; + cvxif_vseq = uvme_cvxif_vseq_c::type_id::create("cvxif_vseq"); + cvxif_vseq.start(cvxif_agent.vsequencer); + end join_none endtask diff --git a/verif/env/uvme/uvme_cva6_pkg.flist b/verif/env/uvme/uvme_cva6_pkg.flist index a4cb9fe372..4d8cf4274a 100644 --- a/verif/env/uvme/uvme_cva6_pkg.flist +++ b/verif/env/uvme/uvme_cva6_pkg.flist @@ -21,6 +21,7 @@ +incdir+${CVA6_UVME_PATH} +incdir+${CVA6_UVME_PATH}/cov +incdir+${CVA6_UVME_PATH}/vseq ++incdir+${CVA6_UVME_PATH}/cvxif_vseq +incdir+${CVA6_UVME_PATH}/uvma_interrupt // Files diff --git a/verif/env/uvme/uvme_cva6_pkg.sv b/verif/env/uvme/uvme_cva6_pkg.sv index 68b978bac9..b77c5655bd 100644 --- a/verif/env/uvme/uvme_cva6_pkg.sv +++ b/verif/env/uvme/uvme_cva6_pkg.sv @@ -30,6 +30,7 @@ `include "uvml_mem_macros.sv" `include "uvma_axi_macros.sv" `include "uvma_clknrst_macros.sv" +`include "uvma_cvxif_macros.sv" `include "uvma_isacov_macros.sv" `include "uvme_cva6_macros.sv" @@ -53,6 +54,7 @@ package uvme_cva6_pkg; import uvmc_rvfi_reference_model_pkg::*; import uvma_isacov_pkg::*; import uvma_interrupt_pkg::*; + import uvma_cvxif_pkg::*; import config_pkg::*; import "DPI-C" function void read_elf(input string filename); diff --git a/verif/env/uvme/uvme_cva6_vsqr.sv b/verif/env/uvme/uvme_cva6_vsqr.sv index 2b4464dc3e..d28b5073a9 100644 --- a/verif/env/uvme/uvme_cva6_vsqr.sv +++ b/verif/env/uvme/uvme_cva6_vsqr.sv @@ -38,6 +38,7 @@ class uvme_cva6_vsqr_c extends uvm_sequencer#( uvma_clknrst_sqr_c clknrst_sequencer; uvma_axi_vsqr_c axi_vsequencer; uvma_interrupt_sqr_c interrupt_sequencer; + uvma_cvxif_vsqr_c cvxif_vsequencer; `uvm_component_utils_begin(uvme_cva6_vsqr_c) diff --git a/verif/sim/Makefile b/verif/sim/Makefile index c87ef4bcad..01fffe13cc 100644 --- a/verif/sim/Makefile +++ b/verif/sim/Makefile @@ -163,6 +163,7 @@ export DV_UVMA_RVFI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_rvfi export DV_UVMA_ISACOV_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_isacov export DV_UVMA_CLKNRST_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_clknrst export DV_UVMA_AXI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_axi5 +export DV_UVMA_CVXIF_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_cvxif export DV_UVMA_INTERRUPT_PATH = $(DV_UVME_PATH)/uvma_interrupt export DV_UVMA_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug export DV_UVMA_OBI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_obi diff --git a/verif/tb/uvmt/cva6_tb_wrapper.sv b/verif/tb/uvmt/cva6_tb_wrapper.sv index 6a063ef844..fa8250a8e8 100644 --- a/verif/tb/uvmt/cva6_tb_wrapper.sv +++ b/verif/tb/uvmt/cva6_tb_wrapper.sv @@ -75,6 +75,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( input logic [15:0] irq_i, uvma_debug_if debug_if, uvma_axi_intf axi_slave, + uvma_cvxif_intf cvxif_if, uvmt_axi_switch_intf axi_switch_vif, uvmt_default_inputs_intf default_inputs_vif ); @@ -111,19 +112,10 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( .rvfi_probes_o ( rvfi_probes ), .cvxif_req_o ( cvxif_req ), .cvxif_resp_i ( cvxif_resp ), - .noc_req_o ( axi_ariane_req ), - .noc_resp_i ( axi_ariane_resp ) + .noc_req_o ( axi_ariane_req ), + .noc_resp_i ( axi_ariane_resp ) ); - if (CVA6Cfg.CvxifEn) begin : gen_cvxif_default_response - always_comb begin - cvxif_resp = '0; - cvxif_resp.compressed_ready = 1'b1; - cvxif_resp.issue_ready = 1'b1; - cvxif_resp.register_ready = 1'b1; - end - end - //---------------------------------------------------------------------------- // RVFI //---------------------------------------------------------------------------- @@ -242,6 +234,27 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #( assign axi_slave.ar_region = axi_ariane_req.ar.region; assign axi_slave.ar_user = 0; + //CVXIF Response structs + assign cvxif_resp.compressed_ready = cvxif_if.compressed_ready; + assign cvxif_resp.compressed_resp = cvxif_if.compressed_resp; + assign cvxif_resp.issue_ready = cvxif_if.issue_ready; + assign cvxif_resp.issue_resp = cvxif_if.issue_resp; + assign cvxif_resp.register_ready = cvxif_if.register_ready; + assign cvxif_resp.result_valid = cvxif_if.result_valid; + assign cvxif_resp.result = cvxif_if.result; + + // Request structs + assign cvxif_if.compressed_valid = cvxif_req.compressed_valid; + assign cvxif_if.compressed_req = cvxif_req.compressed_req; + assign cvxif_if.issue_valid = cvxif_req.issue_valid; + assign cvxif_if.issue_req = cvxif_req.issue_req; + assign cvxif_if.register_valid = cvxif_req.register_valid; + assign cvxif_if.register = cvxif_req.register; + assign cvxif_if.commit_valid = cvxif_req.commit_valid; + assign cvxif_if.commit_req = cvxif_req.commit; + assign cvxif_if.result_ready = cvxif_req.result_ready; + + AXI_BUS #( .AXI_ADDR_WIDTH ( CVA6Cfg.AxiAddrWidth ), diff --git a/verif/tb/uvmt/uvmt_cva6.flist b/verif/tb/uvmt/uvmt_cva6.flist index d4f7651108..f8a7640a7a 100644 --- a/verif/tb/uvmt/uvmt_cva6.flist +++ b/verif/tb/uvmt/uvmt_cva6.flist @@ -28,6 +28,7 @@ -f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist -f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist -f ${DV_UVMA_ISACOV_PATH}/uvma_isacov_pkg.flist +-f ${DV_UVMA_CVXIF_PATH}/src/uvma_cvxif_pkg.flist -f ${DV_UVMC_RVFI_REFERENCE_MODEL_PATH}/uvmc_rvfi_reference_model_pkg.flist -f ${DV_UVMC_RVFI_SCOREBOARD_PATH}/uvmc_rvfi_scoreboard_pkg.flist -f ${CVA6_UVME_PATH}/uvma_interrupt/uvma_interrupt_pkg.flist diff --git a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv index 500afcf45e..e82e80652a 100644 --- a/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv +++ b/verif/tb/uvmt/uvmt_cva6_dut_wrap.sv @@ -34,6 +34,7 @@ module uvmt_cva6_dut_wrap # ( uvmt_default_inputs_intf default_inputs_vif, uvme_cva6_core_cntrl_if core_cntrl_if, uvma_interrupt_if interrupt_vif, + uvma_cvxif_intf cvxif_vif, uvma_debug_if debug_if, output logic[31:0] tb_exit_o, output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o, @@ -62,6 +63,7 @@ module uvmt_cva6_dut_wrap # ( .irq_i ( interrupt_vif.irq ), .debug_if ( debug_if ), .axi_slave ( axi_if ), + .cvxif_if ( cvxif_vif ), .axi_switch_vif ( axi_switch_vif ), .default_inputs_vif ( default_inputs_vif ), .tb_exit_o ( tb_exit_o ), @@ -69,4 +71,11 @@ module uvmt_cva6_dut_wrap # ( .rvfi_o ( rvfi_o ) ); + assign cvxif_vif.compressed_resp = '0; + assign cvxif_vif.issue_resp = '0; + assign cvxif_vif.result = '0; + assign cvxif_vif.compressed_ready = '0; + assign cvxif_vif.issue_ready = '0; + assign cvxif_vif.register_ready = cvxif_vif.issue_ready; + endmodule diff --git a/verif/tb/uvmt/uvmt_cva6_tb.sv b/verif/tb/uvmt/uvmt_cva6_tb.sv index 5955f53697..0bde61c74a 100644 --- a/verif/tb/uvmt/uvmt_cva6_tb.sv +++ b/verif/tb/uvmt/uvmt_cva6_tb.sv @@ -70,6 +70,11 @@ module uvmt_cva6_tb; .reset_n(clknrst_if.reset_n) ); + uvma_cvxif_intf cvxif_vif( + .clk(clknrst_if.clk), + .reset_n(clknrst_if.reset_n) + ); + uvmt_axi_switch_intf axi_switch_vif(); uvme_cva6_core_cntrl_if core_cntrl_if(); uvma_rvfi_instr_if #( @@ -81,6 +86,10 @@ module uvmt_cva6_tb; uvmt_default_inputs_intf default_inputs_vif(); + //bind assertion module for cvxif interface + bind uvmt_cva6_dut_wrap + uvma_cvxif_assert cvxif_assert(.cvxif_assert(cvxif_vif)); + //bind assertion module for axi interface bind uvmt_cva6_dut_wrap uvmt_axi_assert #(CVA6Cfg.DCacheType) axi_assert(.axi_assert_if(axi_if)); @@ -122,6 +131,7 @@ module uvmt_cva6_tb; .default_inputs_vif (default_inputs_vif), .core_cntrl_if(core_cntrl_if), .interrupt_vif(interrupt_vif), + .cvxif_vif(cvxif_vif), .tb_exit_o(tb_exit_if.tb_exit_o), .rvfi_o(rvfi_if.rvfi_o), .rvfi_csr_o(rvfi_if.rvfi_csr_o) @@ -382,6 +392,7 @@ module uvmt_cva6_tb; uvm_config_db#(virtual uvmt_rvfi_if#( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), .rvfi_csr_t (rvfi_csr_t)))::set(.cntxt(null), .inst_name("*"), .field_name("rvfi_vif"), .value(rvfi_if)); uvm_config_db#(virtual uvme_cva6_core_cntrl_if)::set(.cntxt(null), .inst_name("*"), .field_name("core_cntrl_vif"), .value(core_cntrl_if)); uvm_config_db#(virtual uvma_interrupt_if)::set(.cntxt(null), .inst_name("*"), .field_name("interrupt_vif"), .value(interrupt_vif)); + uvm_config_db#(virtual uvma_cvxif_intf)::set(.cntxt(null), .inst_name("*"), .field_name("vif"), .value(cvxif_vif)); uvm_config_db#(virtual uvmt_tb_exit_if)::set(.cntxt(null), .inst_name("*"), .field_name("tb_exit_vif"), .value(tb_exit_if));