Merge branch 'master' into JeanRochCoulon-patch-1
Some checks failed
bender-up-to-date / bender-up-to-date (push) Has been cancelled
ci / build-riscv-tests (push) Has been cancelled
ci / execute-riscv64-tests (push) Has been cancelled
ci / execute-riscv32-tests (push) Has been cancelled

This commit is contained in:
JeanRochCoulon 2024-12-12 08:37:11 +01:00 committed by GitHub
commit 8caafb65b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 446 additions and 195 deletions

@ -1 +1 @@
Subproject commit 9601c80f4cbdeda5527ea7f88f9015d3a554da4a
Subproject commit 6c1e999a97f61b4b805603ba142a1347f785fff2

View file

@ -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");
return ("CUS_DOUBLE_RS2");
end
if (func7 == 7'b0000110) begin
return ("CUS_S_ADD");
if (func7 == 7'b0000001) begin
return ("CUS_DOUBLE_RS1");
end
if (func7 == 7'b0000000 && rd == 0 && rs1 == 0 && rs2 == 0) begin
return ("CUS_NOP");
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

View file

@ -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();
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);
//Decode the instruction received
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);
// generate response based on observed request, e.g:
if (instr == "") begin
do_default();
end
if (req_item.compressed_valid) begin
if (compressed_instr == "") do_default();
else begin
if (req_item.issue_valid && req_item.issue_ready) begin
//issue_resp
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_resp
//result response
do_result_resp();
//send resp to sqr
end
end
if (resp_item.issue_valid || resp_item.compressed_valid) begin
//send response to the sequencer
send_resp(resp_item);
end
end
@ -93,185 +118,307 @@ 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;
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
resp_item.issue_resp.writeback = 1;
resp_item.issue_resp.accept = 1;
end
end
"CUS_ADD_RS3" : begin
if (req_item.issue_req.rs_valid == 3'b111) begin
resp_item.issue_resp.writeback = 1;
resp_item.issue_resp.accept = 1;
end
else begin
resp_item.issue_resp.writeback = 0;
resp_item.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
end
end
resp_item.issue_resp.accept = 0;
resp_item.issue_resp.register_read = 0;
case (instr) inside
"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_EXC" : begin
resp_item.issue_resp.writeback = 0;
resp_item.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
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" : 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.issue_resp.writeback = 0;
resp_item.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
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_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.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
resp_item.delay_resp = 1;
end
end
"ILLEGAL" : begin
resp_item.issue_resp.writeback = 0;
"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_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_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_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.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.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_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.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.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
default : begin
resp_item.issue_resp.writeback = 0;
resp_item.issue_resp.accept = 0;
resp_item.issue_resp.register_read = 0;
resp_item.issue_ready = 1;
end
endcase
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
`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_result_resp();
//result_resp
if (!req_item.commit_req.commit_kill && req_item.commit_valid) begin
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.rd = req_item.issue_req.instr[11:7];
resp_item.result.hartid = req_item.commit_req.hartid;
resp_item.result.we = resp_item.issue_resp.writeback;
resp_item.result.data = 0;
resp_item.result_ready = req_item.result_ready;
`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
"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;
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);
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
"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);
"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
"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);
"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_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);
"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);
resp_item.result.data = '0;
resp_item.result.rd = '0;
end
endcase

View file

@ -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,14 +154,22 @@ 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 {
if (enabled) {
clknrst_cfg.enabled == 1;
@ -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;

View file

@ -35,6 +35,7 @@ class uvme_cva6_cntxt_c extends uvm_object;
uvma_cva6_core_cntrl_cntxt_c core_cntrl_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)
@ -80,6 +82,7 @@ function uvme_cva6_cntxt_c::new(string name="uvme_cva6_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");
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");

View file

@ -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,6 +269,7 @@ 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
@ -278,6 +282,7 @@ function void uvme_cva6_env_c::create_agents();
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
@ -367,6 +372,7 @@ 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.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

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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
);
@ -115,15 +116,6 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
.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 ),

View file

@ -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

View file

@ -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

View file

@ -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));