mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 22:27:10 -04:00
Merge pull request #1957 from AyoubJalali/STTEP1
CVXIF : Update the cvxif agent & the core-dv based on new spec #1950
This commit is contained in:
commit
33e7b2ac77
11 changed files with 308 additions and 224 deletions
26
cva6/env/corev-dv/custom/cvxif_custom_instr.sv
vendored
26
cva6/env/corev-dv/custom/cvxif_custom_instr.sv
vendored
|
@ -40,7 +40,7 @@ class cvxif_custom_instr extends riscv_custom_instr;
|
|||
CUS_NOP: asm_str = "cus_nop";
|
||||
/* following instructions are not yet supported by cva6 */
|
||||
//CUS_EXC: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
//CUS_M_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
//CUS_U_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
//CUS_S_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
//CUS_NOP_EXC: asm_str = "cus_nop_exc";
|
||||
//CUS_ISS_EXC: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
|
||||
|
@ -59,15 +59,16 @@ class cvxif_custom_instr extends riscv_custom_instr;
|
|||
function bit [6:0] get_opcode();
|
||||
case (instr_name) inside
|
||||
{CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP} : get_opcode = 7'b1111011;
|
||||
// {CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_EXC, , CUS_NOP_EXC, CUS_ISS_EXC, CUS_M_ADD, CUS_S_ADD} : get_opcode = 7'b1111011;
|
||||
// {CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_EXC, CUS_U_ADD, CUS_S_ADD} : get_opcode = 7'b1111011;
|
||||
default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
virtual function bit [2:0] get_func3();
|
||||
case (instr_name) inside
|
||||
{CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP} : get_func3 = 3'b000;
|
||||
// {CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_EXC, CUS_NOP_EXC, CUS_ISS_EXC, CUS_M_ADD, CUS_S_ADD} : get_func3 = 3'b000;
|
||||
{CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP} : get_func3 = 3'b000;
|
||||
{CUS_ADD} : get_func3 = 3'b001;
|
||||
// {CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_EXC, CUS_U_ADD, CUS_S_ADD} : get_func3 = 3'b000;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
|
@ -79,12 +80,11 @@ class cvxif_custom_instr extends riscv_custom_instr;
|
|||
// CUS_EXC : get_func7 = 7'b1000000;
|
||||
// CUS_M_ADD : get_func7 = 7'b0000010;
|
||||
// CUS_S_ADD : get_func7 = 7'b0000110;
|
||||
// CUS_NOP_EXC : get_func7 = 7'b0100000;
|
||||
// CUS_ISS_EXC : get_func7 = 7'b1100000;
|
||||
// CUS_EXC : get_func7 = 7'b0100000;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
virtual function bit [6:0] get_func2();
|
||||
virtual function bit [1:0] get_func2();
|
||||
case (instr_name)
|
||||
CUS_ADD_RS3 : get_func2 = 2'b01;
|
||||
endcase
|
||||
|
@ -104,18 +104,6 @@ class cvxif_custom_instr extends riscv_custom_instr;
|
|||
rs2.rand_mode(has_rs2);
|
||||
endfunction
|
||||
|
||||
constraint rd_c {
|
||||
// if (instr_name inside {CUS_ADD_MULTI, CUS_ADD, CUS_ADD_RS3, CUS_M_ADD, CUS_S_ADD}) {
|
||||
if (instr_name inside {CUS_ADD_MULTI, CUS_ADD, CUS_ADD_RS3}) {
|
||||
rd!=0;
|
||||
}
|
||||
/* if (instr_name inside { CUS_EXC, CUS_ISS_EXC} ) {
|
||||
rd == 0;
|
||||
rs1 inside {[4:7], 13, 15};
|
||||
rs2 == 0;
|
||||
}*/
|
||||
}
|
||||
|
||||
endclass
|
||||
|
||||
`endif // __CVXIF_CUSTOM_INSTR_SV__
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
# Mappings of custom_* mnemonics to .insn pseudo-op of GAS
|
||||
|
||||
|
||||
# CUS_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x0, rd, rs1, rs2
|
||||
# CUS_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x1, 0x0, rd, rs1, rs2
|
||||
.macro cus_add rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 0x0, 0x0, \rd, \rs1, \rs2
|
||||
.insn r CUSTOM_3, 0x1, 0x0, \rd, \rs1, \rs2
|
||||
.endm
|
||||
|
||||
# CUS_NOP -> .insn r CUSTOM_3, 0x0, 0x0, x0, x0, x0
|
||||
|
@ -22,17 +22,12 @@
|
|||
.insn r CUSTOM_3, 0x0, 0x0, x0, x0, x0
|
||||
.endm
|
||||
|
||||
# CUS_NOP_EXC -> .insn r CUSTOM_3, 0x0, 0x20, x0, x0, x0
|
||||
.macro cus_nop_exc
|
||||
.insn r CUSTOM_3, 0x0, 0x20, x0, x0, x0
|
||||
.endm
|
||||
|
||||
# CUS_ADD_RS3 rd, rs1, rs2, rs3 -> .insn r CUSTOM_3, 0x0, 0x1, rd, rs1, rs2, rs3
|
||||
.macro cus_add_rs3 rd, rs1, rs2, rs3
|
||||
.insn r CUSTOM_3, 0x0, 0x1, \rd, \rs1, \rs2, \rs3
|
||||
.endm
|
||||
|
||||
# CUS_M_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x6, rd, rs1, rs2
|
||||
# CUS_U_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x6, rd, rs1, rs2
|
||||
.macro cus_m_add rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 0x0, 0x6, \rd, \rs1, \rs2
|
||||
.endm
|
||||
|
@ -52,17 +47,4 @@
|
|||
.insn r CUSTOM_3, 0x0, 0x40, \rd, \rs1, \rs2
|
||||
.endm
|
||||
|
||||
# CUS_ISS_EXC rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x60, rd, rs1, rs2
|
||||
.macro cus_iss_exc rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 0x0, 0x60, \rd, \rs1, \rs2
|
||||
.endm
|
||||
|
||||
# CUS_LD rd, rs1, simm12 -> .insn i CUSTOM_3, 0x1, rd, rs1, simm12
|
||||
.macro cus_ld rd, rs1, simm12
|
||||
.insn i CUSTOM_3, 0x1, \rd, \rs1, \simm12
|
||||
.endm
|
||||
|
||||
# CUS_SD rs2, simm12(rs1) -> .insn s CUSTOM_3, 0x2, rs2, simm12(rs1)
|
||||
.macro cus_sd rs2, addr
|
||||
.insn s CUSTOM_3, 0x2, \rs2, \addr
|
||||
.endm
|
||||
|
|
1
cva6/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
1
cva6/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
|
@ -88,6 +88,7 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
|
|||
end
|
||||
|
||||
cvxif_covg = uvme_cvxif_covg_c::type_id::create("cvxif_covg", this);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "cvxif_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "cvxif_covg", "cntxt", cntxt);
|
||||
|
||||
endfunction : build_phase
|
||||
|
|
249
cva6/env/uvme/cov/uvme_cvxif_covg.sv
vendored
249
cva6/env/uvme/cov/uvme_cvxif_covg.sv
vendored
|
@ -16,71 +16,274 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
|
||||
covergroup cg_executed(
|
||||
string name,
|
||||
bit seq_cus_instr_x2_enabled
|
||||
) with function
|
||||
sample(uvma_cvxif_req_item_c req_item,
|
||||
uvma_cvxif_req_item_c prev_req_item);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_instr : coverpoint req_item.issue_req.instr {
|
||||
wildcard bins CUS_ADD = {32'b0000000??????????001?????1111011};
|
||||
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
|
||||
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
|
||||
wildcard bins CUS_U_ADD = {32'b0000100??????????000?????1111011};
|
||||
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
|
||||
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
|
||||
wildcard bins CUS_EXC = {32'b10000000000000000000000001111011};
|
||||
}
|
||||
|
||||
cp_prev_instr : coverpoint prev_req_item.issue_req.instr iff (prev_req_item != null) {
|
||||
ignore_bins IGN_X2_OFF = {[0:$]} iff (!seq_cus_instr_x2_enabled);
|
||||
wildcard bins CUS_ADD = {32'b0000000??????????001?????1111011};
|
||||
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
|
||||
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
|
||||
wildcard bins CUS_U_ADD = {32'b0000100??????????000?????1111011};
|
||||
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
|
||||
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
|
||||
wildcard bins CUS_EXC = {32'b10000000000000000000000001111011};
|
||||
}
|
||||
|
||||
cross_seq_cus_instr_x2 : cross cp_instr, cp_prev_instr;
|
||||
|
||||
endgroup: cg_executed
|
||||
|
||||
covergroup cg_cus_add_instr(
|
||||
string name,
|
||||
bit reg_cus_crosses_enabled,
|
||||
bit rs3_valid
|
||||
) with function sample(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_rd : coverpoint req_item.issue_req.instr[11:7] {
|
||||
bins RD[] = {[1:31]};
|
||||
}
|
||||
|
||||
cp_rs1 : coverpoint req_item.issue_req.instr[19:15] {
|
||||
bins RS1[] = {[0:31]};
|
||||
}
|
||||
|
||||
cp_rs2 : coverpoint req_item.issue_req.instr[24:20] {
|
||||
bins RS2[] = {[0:31]};
|
||||
}
|
||||
|
||||
cp_rs3 : coverpoint req_item.issue_req.instr[31:27] {
|
||||
ignore_bins IGN_RS3[] = {[0:31]} iff (!rs3_valid);
|
||||
bins RS3[] = {[0:31]};
|
||||
}
|
||||
|
||||
cross_rd_rs1 : cross cp_rd, cp_rs1 {
|
||||
ignore_bins IGN_OFF = cross_rd_rs1 iff (!reg_cus_crosses_enabled);
|
||||
}
|
||||
|
||||
cross_rd_rs2 : cross cp_rd, cp_rs2 {
|
||||
ignore_bins IGN_OFF = cross_rd_rs2 iff (!reg_cus_crosses_enabled);
|
||||
}
|
||||
|
||||
cross_rd_rs3 : cross cp_rd, cp_rs3 {
|
||||
ignore_bins IGN_OFF = cross_rd_rs3 iff (!reg_cus_crosses_enabled || !rs3_valid);
|
||||
}
|
||||
|
||||
`CVXIF_CP_BITWISE(cp_rs1_toggle, req_item.issue_req.rs[0], 1)
|
||||
`CVXIF_CP_BITWISE(cp_rs2_toggle, req_item.issue_req.rs[1], 1)
|
||||
`CVXIF_CP_BITWISE(cp_rs3_toggle, req_item.issue_req.rs[2], rs3_valid) //TODO : fix need more filtring
|
||||
|
||||
endgroup: cg_cus_add_instr
|
||||
|
||||
covergroup cg_cus_instr(
|
||||
string name
|
||||
) with function sample(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
`CVXIF_IMM_BITWISE(cp_imm_toggle, req_item.issue_req.instr[12:7], 1)
|
||||
|
||||
endgroup: cg_cus_instr
|
||||
|
||||
class uvme_cvxif_covg_c extends uvm_component;
|
||||
|
||||
/*
|
||||
* Class members
|
||||
*/
|
||||
// Objects
|
||||
uvme_cva6_cfg_c cfg ;
|
||||
uvme_cva6_cntxt_c cntxt ;
|
||||
|
||||
uvma_cvxif_req_item_c req_item ;
|
||||
|
||||
// TLM
|
||||
uvm_tlm_analysis_fifo#(uvma_cvxif_req_item_c ) req_item_fifo;
|
||||
|
||||
`uvm_component_utils_begin(uvme_cvxif_covg_c)
|
||||
`uvm_field_object(cfg , UVM_DEFAULT)
|
||||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
`uvm_component_utils(uvme_cvxif_covg_c);
|
||||
// Covergroups
|
||||
//ADD INSTRUCTIONS
|
||||
cg_cus_add_instr cus_add_cg;
|
||||
cg_cus_add_instr cus_add_rs3_cg;
|
||||
cg_cus_add_instr cus_add_multi_cg;
|
||||
cg_cus_add_instr cus_add_u_cg;
|
||||
cg_cus_add_instr cus_add_s_cg;
|
||||
cg_cus_instr cus_exc_cg;
|
||||
|
||||
//Sequential instruction
|
||||
cg_executed cus_seq_cg;
|
||||
|
||||
extern function new(string name = "cvxif_covg", uvm_component parent = null);
|
||||
extern function void build_phase(uvm_phase phase);
|
||||
extern task run_phase(uvm_phase phase);
|
||||
|
||||
extern task sample_cvxif_req_i(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
/*
|
||||
* Covergroups
|
||||
*/
|
||||
covergroup mode_cg(string name)
|
||||
with function sample(uvma_cvxif_req_item_c req_item);
|
||||
mode_cp: coverpoint (req_item.issue_req.mode)
|
||||
{
|
||||
bins u_mode = {2'b00};
|
||||
bins s_mode = {2'b01};
|
||||
bins r_mode = {2'b10};
|
||||
bins m_mode = {2'b11};
|
||||
}
|
||||
|
||||
endgroup : mode_cg
|
||||
extern task sample_cvxif_req(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
endclass : uvme_cvxif_covg_c
|
||||
|
||||
function uvme_cvxif_covg_c::new(string name = "cvxif_covg", uvm_component parent = null);
|
||||
super.new(name, parent);
|
||||
|
||||
mode_cg = new("mode_cg");
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
function void uvme_cvxif_covg_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
void'(uvm_config_db#(uvme_cva6_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (!cfg) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
|
||||
void'(uvm_config_db#(uvme_cva6_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (!cntxt) begin
|
||||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
cus_add_cg = new("cus_add_cg",
|
||||
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
|
||||
.rs3_valid(0));
|
||||
cus_add_rs3_cg = new("cus_add_rs3_cg",
|
||||
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
|
||||
.rs3_valid(1));
|
||||
cus_add_multi_cg = new("cus_add_multi_cg",
|
||||
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
|
||||
.rs3_valid(0));
|
||||
cus_add_u_cg = new("cus_add_m_cg",
|
||||
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
|
||||
.rs3_valid(0));
|
||||
cus_add_s_cg = new("cus_add_s_cg",
|
||||
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
|
||||
.rs3_valid(0));
|
||||
cus_exc_cg = new("cus_exc_cg");
|
||||
|
||||
cus_seq_cg = new("cus_seq_cg",
|
||||
.seq_cus_instr_x2_enabled(cfg.cvxif_cfg.seq_cus_instr_x2_enabled));
|
||||
|
||||
req_item_fifo = new("req_item_fifo" , this);
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
task uvme_cvxif_covg_c::run_phase(uvm_phase phase);
|
||||
|
||||
super.run_phase(phase);
|
||||
|
||||
`uvm_info("CVXIFCOVG", "The CVXIF coverage model is running", UVM_LOW);
|
||||
forever begin
|
||||
req_item_fifo.get(req_item);
|
||||
sample_cvxif_req_i(req_item);
|
||||
sample_cvxif_req(req_item);
|
||||
end
|
||||
|
||||
endtask : run_phase
|
||||
|
||||
task uvme_cvxif_covg_c::sample_cvxif_req_i(uvma_cvxif_req_item_c req_item);
|
||||
task uvme_cvxif_covg_c::sample_cvxif_req(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
mode_cg.sample(req_item);
|
||||
uvma_cvxif_req_item_c prev_req_item;
|
||||
logic have_sample;
|
||||
bit [6:0] opcode = req_item.issue_req.instr [6:0];
|
||||
bit [6:0] custom3 = 7'b1111011;
|
||||
bit [6:0] func7 = req_item.issue_req.instr [31:25];
|
||||
bit [1:0] func2 = req_item.issue_req.instr [26:25];
|
||||
bit [2:0] func3 = req_item.issue_req.instr [14:12];
|
||||
bit [4:0] rd = req_item.issue_req.instr [11:7];
|
||||
bit [4:0] rs1 = req_item.issue_req.instr [19:15];
|
||||
bit [4:0] rs2 = req_item.issue_req.instr [24:20];
|
||||
|
||||
endtask : sample_cvxif_req_i
|
||||
if (opcode == custom3) begin
|
||||
if (func3 == 3'b000) begin
|
||||
if (func7 == 7'b0000000 && rd != 0) begin
|
||||
cus_add_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
if (func7 == 7'b0001000) begin
|
||||
cus_add_multi_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
if (func2 == 2'b01) begin
|
||||
cus_add_rs3_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
if (func7 == 7'b0000010) begin
|
||||
cus_add_u_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
if (func7 == 7'b0000110) begin
|
||||
cus_add_s_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
if (func7 == 7'b0000000 && rd == 0 && rs1 == 0 && rs2 == 0) begin
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
if (func7 == 7'b1000000 && req_item.issue_req.instr[24:13] == 12'b000000000001) begin
|
||||
cus_exc_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
end
|
||||
if (func3 == 3'b001) begin
|
||||
if (func7 == 7'b0000000) begin
|
||||
cus_add_cg.sample(req_item);
|
||||
cus_seq_cg.sample(req_item,
|
||||
prev_req_item);
|
||||
// Move instructions down the pipeline
|
||||
prev_req_item = req_item;
|
||||
have_sample = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if (!have_sample) `uvm_warning("CVXIF", $sformatf("Could not sample instruction: %b", req_item.issue_req.instr));
|
||||
|
||||
endtask : sample_cvxif_req
|
||||
|
||||
|
|
24
cva6/env/uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv
vendored
24
cva6/env/uvme/cvxif_vseq/uvme_cvxif_base_vseq.sv
vendored
|
@ -53,35 +53,37 @@ function string uvme_cvxif_base_vseq_c::decode(input logic [31:0] instr);
|
|||
bit [6:0] custom3 = 7'b1111011;
|
||||
bit [6:0] func7 = instr [31:25];
|
||||
bit [1:0] func2 = instr [26:25];
|
||||
bit [1:0] func3 = instr [14:12];
|
||||
bit [2:0] func3 = instr [14:12];
|
||||
bit [4:0] rd = instr [11:7];
|
||||
bit [4:0] rs1 = instr [19:15];
|
||||
bit [4:0] rs2 = instr [24:20];
|
||||
|
||||
if (opcode == custom3) begin
|
||||
if (func3 == 0) begin
|
||||
if (func7 == 7'b0000000 && rd != 0) begin
|
||||
return ("CUS_ADD");
|
||||
end
|
||||
if (func7 == 7'b0001000 && rd != 0) begin
|
||||
if (func3 == 3'b000) begin
|
||||
if (func7 == 7'b0001000) begin
|
||||
return ("CUS_ADD_MULTI");
|
||||
end
|
||||
if (func2 == 2'b01 && rd != 0) begin
|
||||
if (func2 == 2'b01) begin
|
||||
return ("CUS_ADD_RS3");
|
||||
end
|
||||
if (func7 == 7'b0000010 && rd != 0) begin
|
||||
return ("CUS_M_ADD");
|
||||
if (func7 == 7'b0000010) begin
|
||||
return ("CUS_U_ADD");
|
||||
end
|
||||
if (func7 == 7'b0000110 && rd != 0) begin
|
||||
if (func7 == 7'b0000110) begin
|
||||
return ("CUS_S_ADD");
|
||||
end
|
||||
if (func7 == 7'b0000000 && rd == 0 && rs1 == 0 && rs2 == 0) begin
|
||||
return ("CUS_NOP");
|
||||
end
|
||||
if (func7 == 7'b1000000 && rd == 0 && rs2[4:1] == 0) begin
|
||||
if (func7 == 7'b1000000 && instr[24:13] == 12'b000000000001) begin
|
||||
return ("CUS_EXC");
|
||||
end
|
||||
end
|
||||
if (func3 == 3'b001) begin
|
||||
if (func7 == 7'b0000000) begin
|
||||
return ("CUS_ADD");
|
||||
end
|
||||
end
|
||||
end
|
||||
return ("ILLEGAL");
|
||||
|
||||
|
|
38
cva6/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv
vendored
38
cva6/env/uvme/cvxif_vseq/uvme_cvxif_vseq.sv
vendored
|
@ -68,7 +68,7 @@ task uvme_cvxif_vseq_c::body();
|
|||
instr = decode(req_item.issue_req.instr);
|
||||
|
||||
// generate response based on observed request, e.g:
|
||||
if (instr == "ILLEGAL" || instr == "") begin
|
||||
if (instr == "") begin
|
||||
do_default();
|
||||
end
|
||||
else begin
|
||||
|
@ -117,15 +117,10 @@ task uvme_cvxif_vseq_c::do_issue_resp();
|
|||
resp_item.issue_resp.exc = 0;
|
||||
case (instr) inside
|
||||
"CUS_ADD", "CUS_ADD_MULTI" : begin
|
||||
if (req_item.issue_req.rs_valid == 2'b11) 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
|
||||
else begin
|
||||
resp_item.issue_resp.writeback = 0;
|
||||
resp_item.issue_resp.accept = 1;
|
||||
resp_item.issue_resp.exc = 1;
|
||||
end
|
||||
end
|
||||
"CUS_ADD_RS3" : begin
|
||||
if (req_item.issue_req.rs_valid == 3'b111) begin
|
||||
|
@ -147,8 +142,8 @@ task uvme_cvxif_vseq_c::do_issue_resp();
|
|||
resp_item.issue_resp.accept = 1;
|
||||
resp_item.issue_resp.exc = 1;
|
||||
end
|
||||
"CUS_M_ADD" : begin
|
||||
if (req_item.issue_req.mode == 2'b11) begin
|
||||
"CUS_U_ADD" : begin
|
||||
if (req_item.issue_req.mode == 2'b00 && 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
|
||||
|
@ -159,7 +154,7 @@ task uvme_cvxif_vseq_c::do_issue_resp();
|
|||
end
|
||||
end
|
||||
"CUS_S_ADD" : begin
|
||||
if (req_item.issue_req.mode == 2'b01) begin
|
||||
if (req_item.issue_req.mode == 2'b01 && 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
|
||||
|
@ -169,6 +164,11 @@ task uvme_cvxif_vseq_c::do_issue_resp();
|
|||
resp_item.issue_resp.exc = 1;
|
||||
end
|
||||
end
|
||||
"ILLEGAL" : begin
|
||||
resp_item.issue_resp.writeback = 0;
|
||||
resp_item.issue_resp.accept = 1;
|
||||
resp_item.issue_resp.exc = 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",
|
||||
|
@ -216,7 +216,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
|
|||
cfg.instr_delayed = 0;
|
||||
case (instr)
|
||||
"CUS_ADD": begin
|
||||
if (req_item.issue_req.rs_valid == 2'b11)
|
||||
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;
|
||||
|
@ -225,7 +225,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
|
|||
end
|
||||
end
|
||||
"CUS_ADD_MULTI": begin
|
||||
if (req_item.issue_req.rs_valid == 2'b11) 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
|
||||
|
@ -237,8 +237,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
|
|||
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] = req_item.issue_req.instr[20];
|
||||
resp_item.result.exccode[5:0] = req_item.issue_req.instr[12:7];
|
||||
`uvm_info(info_tag, $sformatf("EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
|
||||
end
|
||||
"CUS_ADD_RS3": begin
|
||||
|
@ -250,8 +249,8 @@ task uvme_cvxif_vseq_c::do_instr_result();
|
|||
`uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
|
||||
end
|
||||
end
|
||||
"CUS_M_ADD": begin
|
||||
if (req_item.issue_req.mode == 2'b11 && req_item.issue_req.rs_valid == 2'b11)
|
||||
"CUS_U_ADD": begin
|
||||
if (req_item.issue_req.mode == 2'b11 && 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;
|
||||
|
@ -260,7 +259,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
|
|||
end
|
||||
end
|
||||
"CUS_S_ADD": begin
|
||||
if (req_item.issue_req.mode == 2'b01 && req_item.issue_req.rs_valid == 2'b11)
|
||||
if (req_item.issue_req.mode == 2'b01 && 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;
|
||||
|
@ -268,6 +267,11 @@ task uvme_cvxif_vseq_c::do_instr_result();
|
|||
`uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
|
||||
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
|
||||
endcase
|
||||
|
||||
endtask
|
||||
|
|
6
cva6/env/uvme/uvme_cva6_cfg.sv
vendored
6
cva6/env/uvme/uvme_cva6_cfg.sv
vendored
|
@ -74,8 +74,10 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
}
|
||||
|
||||
constraint cvxif_feature { //CVA6 do not support dual read & write also the memory interface
|
||||
soft cvxif_cfg.dual_read_write_support_x == 0;
|
||||
soft cvxif_cfg.load_store_support_x == 0;
|
||||
cvxif_cfg.dual_read_write_support_x == 0;
|
||||
cvxif_cfg.load_store_support_x == 0;
|
||||
cvxif_cfg.seq_cus_instr_x2_enabled == 1;
|
||||
cvxif_cfg.reg_cus_crosses_enabled == 1;
|
||||
}
|
||||
constraint cva6_riscv_cons {
|
||||
xlen == uvma_core_cntrl_pkg::MXL_32;
|
||||
|
|
|
@ -141,7 +141,9 @@ function void uvma_cvxif_agent_c::create_components();
|
|||
monitor = uvma_cvxif_mon_c ::type_id::create("monitor" , this);
|
||||
vsequencer = uvma_cvxif_vsqr_c ::type_id::create("vsequencer", this);
|
||||
driver = uvma_cvxif_drv_c ::type_id::create("driver" , this);
|
||||
cov_model = uvma_cvxif_cov_model_c ::type_id::create("cov_model" , this);
|
||||
if (cfg.cov_model_enabled) begin
|
||||
cov_model = uvma_cvxif_cov_model_c ::type_id::create("cov_model" , this);
|
||||
end
|
||||
|
||||
endfunction : create_components
|
||||
|
||||
|
@ -159,8 +161,10 @@ endfunction : connect_analysis_ports
|
|||
|
||||
function void uvma_cvxif_agent_c::connect_cov_model();
|
||||
|
||||
monitor.req_ap.connect(cov_model.req_item_fifo.analysis_export);
|
||||
monitor.resp_ap.connect(cov_model.resp_item_fifo.analysis_export);
|
||||
if (cfg.cov_model_enabled) begin
|
||||
monitor.req_ap.connect(cov_model.req_item_fifo.analysis_export);
|
||||
monitor.resp_ap.connect(cov_model.resp_item_fifo.analysis_export);
|
||||
end
|
||||
|
||||
endfunction : connect_cov_model
|
||||
|
||||
|
|
|
@ -18,56 +18,6 @@
|
|||
*/
|
||||
//covergroup instances
|
||||
|
||||
covergroup cg_executed(
|
||||
string name
|
||||
) with function sample(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_instr : coverpoint req_item.issue_req.instr {
|
||||
wildcard bins CUS_ADD = {32'b0000000??????????000?????1111011};
|
||||
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
|
||||
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
|
||||
wildcard bins CUS_M_ADD = {32'b0000100??????????000?????1111011};
|
||||
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
|
||||
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
|
||||
wildcard bins CUS_EXC = {32'b10000000000000000000000001111011};
|
||||
}
|
||||
|
||||
endgroup: cg_executed
|
||||
|
||||
covergroup cg_cus_instr(
|
||||
string name,
|
||||
bit rs3_valid
|
||||
) with function sample(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_rd : coverpoint req_item.issue_req.instr[11:7] {
|
||||
bins RD[] = {[1:31]};
|
||||
}
|
||||
|
||||
cp_rs1 : coverpoint req_item.issue_req.instr[19:15] {
|
||||
bins RS1[] = {[0:31]};
|
||||
}
|
||||
|
||||
cp_rs2 : coverpoint req_item.issue_req.instr[24:20] {
|
||||
bins RS2[] = {[0:31]};
|
||||
}
|
||||
|
||||
cp_rs3 : coverpoint req_item.issue_req.instr[31:27] {
|
||||
ignore_bins IGN_RS3[] = {[0:31]} iff (!rs3_valid);
|
||||
bins RS3[] = {[0:31]};
|
||||
}
|
||||
|
||||
`CVXIF_CP_BITWISE(cp_rs1_toggle, req_item.issue_req.rs[0], 1)
|
||||
`CVXIF_CP_BITWISE(cp_rs2_toggle, req_item.issue_req.rs[1], 1)
|
||||
`CVXIF_CP_BITWISE(cp_rs3_toggle, req_item.issue_req.rs[2], rs3_valid) //TODO : fix need more filtring
|
||||
|
||||
endgroup: cg_cus_instr
|
||||
|
||||
covergroup cg_request(
|
||||
string name
|
||||
) with function sample(uvma_cvxif_req_item_c req_item);
|
||||
|
@ -75,16 +25,6 @@ covergroup cg_request(
|
|||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_instr : coverpoint req_item.issue_req.instr {
|
||||
wildcard bins CUS_ADD = {32'b0000000??????????000?????1111011};
|
||||
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
|
||||
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
|
||||
wildcard bins CUS_M_ADD = {32'b0000100??????????000?????1111011};
|
||||
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
|
||||
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
|
||||
wildcard bins CUS_EXC = {32'b10000000000000000000000001111011};
|
||||
}
|
||||
|
||||
cp_valid : coverpoint req_item.issue_valid {
|
||||
bins ISSUE_VALID [] = {[0:$]};
|
||||
}
|
||||
|
@ -117,7 +57,7 @@ covergroup cg_request(
|
|||
bins COMMIT_VALID [] = {[0:$]};
|
||||
}
|
||||
|
||||
cross_req : cross cp_instr, cp_id, cp_rs_valid, cp_mode;
|
||||
cross_req : cross cp_id, cp_rs_valid, cp_mode;
|
||||
cross_valid_ready : cross cp_valid, cp_ready;
|
||||
cross_commit : cross cp_commit_valid, cp_commit_kill, cp_commit_id;
|
||||
|
||||
|
@ -241,8 +181,6 @@ class uvma_cvxif_cov_model_c extends uvm_component;
|
|||
// Objects
|
||||
uvma_cvxif_cfg_c cfg ;
|
||||
uvma_cvxif_cntxt_c cntxt ;
|
||||
uvma_cvxif_req_item_c req_item ;
|
||||
uvma_cvxif_resp_item_c resp_item;
|
||||
|
||||
// TLM
|
||||
uvm_tlm_analysis_fifo#(uvma_cvxif_req_item_c ) req_item_fifo;
|
||||
|
@ -253,16 +191,6 @@ class uvma_cvxif_cov_model_c extends uvm_component;
|
|||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
// Covergroups
|
||||
//ADD INSTRUCTIONS
|
||||
cg_cus_instr cus_add_cg;
|
||||
cg_cus_instr cus_add_rs3_cg;
|
||||
cg_cus_instr cus_add_multi_cg;
|
||||
cg_cus_instr cus_add_m_cg;
|
||||
cg_cus_instr cus_add_s_cg;
|
||||
|
||||
//Sequential instruction
|
||||
cg_executed cus_seq_cg;
|
||||
cg_request request_cg;
|
||||
cg_response response_cg;
|
||||
cg_result result_cg;
|
||||
|
@ -325,18 +253,6 @@ function void uvma_cvxif_cov_model_c::build_phase(uvm_phase phase);
|
|||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
cus_add_cg = new("cus_add_cg",
|
||||
.rs3_valid(0));
|
||||
cus_add_rs3_cg = new("cus_add_rs3_cg",
|
||||
.rs3_valid(1));
|
||||
cus_add_multi_cg = new("cus_add_multi_cg",
|
||||
.rs3_valid(0));
|
||||
cus_add_m_cg = new("cus_add_m_cg",
|
||||
.rs3_valid(0));
|
||||
cus_add_s_cg = new("cus_add_s_cg",
|
||||
.rs3_valid(0));
|
||||
|
||||
cus_seq_cg = new("cus_seq_cg");
|
||||
request_cg = new("request_cg");
|
||||
response_cg = new("response_cg",
|
||||
.dual_read_write_support(cfg.dual_read_write_support_x),
|
||||
|
@ -351,6 +267,10 @@ endfunction : build_phase
|
|||
|
||||
task uvma_cvxif_cov_model_c::run_phase(uvm_phase phase);
|
||||
|
||||
|
||||
uvma_cvxif_req_item_c req_item ;
|
||||
uvma_cvxif_resp_item_c resp_item;
|
||||
|
||||
super.run_phase(phase);
|
||||
if (cfg.enabled && cfg.cov_model_enabled) begin
|
||||
fork
|
||||
|
@ -399,44 +319,6 @@ endfunction : sample_cntxt
|
|||
|
||||
function void uvma_cvxif_cov_model_c::sample_req_item(uvma_cvxif_req_item_c req_item);
|
||||
|
||||
// TODO Implement uvma_cvxif_cov_model_c::sample_req_item();
|
||||
bit [6:0] opcode = req_item.issue_req.instr [6:0];
|
||||
bit [6:0] custom3 = 7'b1111011;
|
||||
bit [6:0] func7 = req_item.issue_req.instr [31:25];
|
||||
bit [1:0] func2 = req_item.issue_req.instr [26:25];
|
||||
bit [1:0] func3 = req_item.issue_req.instr [14:12];
|
||||
bit [4:0] rd = req_item.issue_req.instr [11:7];
|
||||
bit [4:0] rs1 = req_item.issue_req.instr [19:15];
|
||||
bit [4:0] rs2 = req_item.issue_req.instr [24:20];
|
||||
|
||||
if (opcode != custom3 ) begin
|
||||
`uvm_warning("CVXIF", $sformatf("Could not sample instruction: %b", req_item.issue_req.instr));
|
||||
end
|
||||
else begin
|
||||
if (func3 == 0) begin
|
||||
if (rd != 0) begin
|
||||
if (func7 == 0) begin
|
||||
cus_add_cg.sample(req_item);
|
||||
end
|
||||
if (func2 == 2'b01) begin
|
||||
cus_add_rs3_cg.sample(req_item);
|
||||
end
|
||||
if (func7 == 7'b0001000) begin
|
||||
cus_add_multi_cg.sample(req_item);
|
||||
end
|
||||
if (func7 == 7'b0000010) begin
|
||||
cus_add_m_cg.sample(req_item);
|
||||
end
|
||||
if (func7 == 7'b0000110) begin
|
||||
cus_add_s_cg.sample(req_item);
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
`uvm_warning("CVXIF", $sformatf("Could not sample instruction: %b", req_item.issue_req.instr));
|
||||
end
|
||||
end
|
||||
cus_seq_cg.sample(req_item);
|
||||
request_cg.sample(req_item);
|
||||
|
||||
endfunction : sample_req_item
|
||||
|
|
|
@ -28,6 +28,8 @@ class uvma_cvxif_cfg_c extends uvm_object;
|
|||
|
||||
rand bit dual_read_write_support_x;
|
||||
rand bit load_store_support_x;
|
||||
rand bit seq_cus_instr_x2_enabled;
|
||||
rand bit reg_cus_crosses_enabled;
|
||||
|
||||
constraint reasonable_values {
|
||||
soft uvma_cvxif_issue_ready inside {[4:10]};
|
||||
|
@ -40,11 +42,6 @@ class uvma_cvxif_cfg_c extends uvm_object;
|
|||
uvma_cvxif_issue_not_ready!=0 || uvma_cvxif_issue_ready != 0;
|
||||
}
|
||||
|
||||
constraint support_feature { // The dual read & write also load store are enabled default
|
||||
soft dual_read_write_support_x == 1;
|
||||
soft load_store_support_x == 1;
|
||||
}
|
||||
|
||||
constraint defaults_val {
|
||||
soft ready_mode == UVMA_CVXIF_ISSUE_READY_FIX; // issue_ready is not randomized => the agent is always ready by default,
|
||||
// you can randomize it by giving "UVMA_CVXIF_ISSUE_READY_RANDOMIZED" to "ready_mode"
|
||||
|
@ -63,6 +60,9 @@ class uvma_cvxif_cfg_c extends uvm_object;
|
|||
`uvm_field_int ( in_order, UVM_DEFAULT)
|
||||
`uvm_field_int ( cov_model_enabled, UVM_DEFAULT)
|
||||
`uvm_field_int ( enabled, UVM_DEFAULT)
|
||||
`uvm_field_int ( dual_read_write_support_x, UVM_DEFAULT)
|
||||
`uvm_field_int ( load_store_support_x, UVM_DEFAULT)
|
||||
`uvm_field_int ( seq_cus_instr_x2_enabled, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
/**
|
||||
|
|
|
@ -87,4 +87,20 @@
|
|||
wildcard bins BIT31_1 = {32'b1???????????????????????????????}; \
|
||||
}
|
||||
|
||||
`define CVXIF_IMM_BITWISE(name, field, iff_exp) \
|
||||
``name``: coverpoint(``field``) iff (``iff_exp``) { \
|
||||
wildcard bins BIT0_0 = {6'b?????0}; \
|
||||
wildcard bins BIT1_0 = {6'b????0?}; \
|
||||
wildcard bins BIT2_0 = {6'b???0??}; \
|
||||
wildcard bins BIT3_0 = {6'b??0???}; \
|
||||
wildcard bins BIT4_0 = {6'b?0????}; \
|
||||
wildcard bins BIT5_0 = {6'b0?????}; \
|
||||
wildcard bins BIT0_1 = {6'b?????1}; \
|
||||
wildcard bins BIT1_1 = {6'b????1?}; \
|
||||
wildcard bins BIT2_1 = {6'b???1??}; \
|
||||
wildcard bins BIT3_1 = {6'b??1???}; \
|
||||
wildcard bins BIT4_1 = {6'b?1????}; \
|
||||
wildcard bins BIT5_1 = {6'b1?????}; \
|
||||
}
|
||||
|
||||
`endif // __UVMA_CVXIF_MACROS_SV__
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue