ISACOV : Create decoder for some Compressed instructions

This commit is contained in:
Ayoub Jalali 2023-05-11 12:19:25 +02:00
parent b623e14a8f
commit bb89a319d0
2 changed files with 42 additions and 13 deletions

View file

@ -48,10 +48,13 @@ class uvma_isacov_instr_c#(int ILEN=DEFAULT_ILEN,
bit rs2_valid;
bit rd_valid;
// rx for compressed instruction (5-bit encoding)
bit [4:0] c_rdrs1;
bit [2:0] c_rs1s;
bit [2:0] c_rs2s;
bit [2:0] c_rdp;
// rx for compressed instruction (3-bit encoding)
bit [2:0] c_rs1;
bit [2:0] c_rs2;
bit [2:0] c_rd;
bit[XLEN-1:0] rs1_value;
instr_value_t rs1_value_type;
@ -93,6 +96,11 @@ class uvma_isacov_instr_c#(int ILEN=DEFAULT_ILEN,
`uvm_field_int(rd_valid, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_enum(instr_value_t, rd_value_type, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rdrs1, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rs1, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rs2, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rd, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(immi, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_enum(instr_value_t, immi_value_type, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(imms, UVM_ALL_ON | UVM_NOPRINT);
@ -126,6 +134,10 @@ class uvma_isacov_instr_c#(int ILEN=DEFAULT_ILEN,
extern function int get_addr_rs1();
extern function int get_addr_rs2();
extern function int get_data_imm();
extern function int decode_rd_c(bit[ILEN-1:0] instr);
extern function int decode_rs1_c(bit[ILEN-1:0] instr);
extern function int decode_rs2_c(bit[ILEN-1:0] instr);
endclass : uvma_isacov_instr_c
@ -174,19 +186,19 @@ function string uvma_isacov_instr_c::convert2string();
instr_str = $sformatf("x%0d, %0d(x2)", this.get_addr_rs2(), this.get_data_imm());
end
if (itype == CIW_TYPE) begin
instr_str = $sformatf("x%0d, x2, %0d", this.get_addr_rd(), this.get_data_imm());
instr_str = $sformatf("x%0d, x2, %0d", this.decode_rd_c($signed(this.rvfi.insn)), this.get_data_imm());
end
if (itype == CL_TYPE) begin
instr_str = $sformatf("x%0d, x%0d, %0d", this.get_addr_rd(), this.get_addr_rs1(), get_data_imm());
instr_str = $sformatf("x%0d, x%0d, %0d", this.decode_rd_c($signed(this.rvfi.insn)), this.decode_rs1_c($signed(this.rvfi.insn)), get_data_imm());
end
if (itype == CS_TYPE) begin
instr_str = $sformatf("x%0d, %0d(x%0d)", this.get_addr_rs2, this.get_data_imm(), this.get_addr_rs1);
instr_str = $sformatf("x%0d, %0d(x%0d)", this.decode_rs2_c($signed(this.rvfi.insn)), this.get_data_imm(), this.decode_rs1_c($signed(this.rvfi.insn)));
end
if (itype == CA_TYPE) begin
instr_str = $sformatf("x%0d, x%0d", this.get_addr_rd(), this.get_addr_rs2());
instr_str = $sformatf("x%0d, x%0d", this.decode_rs1_c($signed(this.rvfi.insn)), this.decode_rs2_c($signed(this.rvfi.insn)));
end
if (itype == CB_TYPE) begin
instr_str = $sformatf("x%0d, %0x", this.get_addr_rs1(), ($signed(rvfi.pc_rdata) + this.get_data_imm()));
instr_str = $sformatf("x%0d, %0x", this.decode_rs1_c($signed(this.rvfi.insn)), ($signed(rvfi.pc_rdata) + this.get_data_imm()));
end
if (itype == CJ_TYPE) begin
instr_str = $sformatf("%0x", ($signed(rvfi.pc_rdata) + this.get_data_imm()));
@ -211,10 +223,10 @@ function string uvma_isacov_instr_c::convert2string();
instr_str = $sformatf("x%0d, 0x%0x", this.get_addr_rd(), this.get_data_imm());
end
if (name inside {C_SRAI, C_SRLI}) begin
instr_str = $sformatf("x%0d, 0x%0x", this.get_addr_rs1(), this.get_data_imm());
instr_str = $sformatf("x%0d, 0x%0x", this.decode_rs1_c($signed(this.rvfi.insn)), this.get_data_imm());
end
if (name == C_ANDI) begin
instr_str = $sformatf("x%0d, %0d", this.get_addr_rd(), $signed(this.get_data_imm()));
instr_str = $sformatf("x%0d, %0d", this.decode_rs1_c($signed(this.rvfi.insn)), $signed(this.get_data_imm()));
end
if (name == FENCE) begin
instr_str = "iorw, iorw"; // Note: If later found necessary, add support for `fence` arguments other than "iorw"
@ -497,6 +509,23 @@ function int uvma_isacov_instr_c::get_data_imm();
endfunction : get_data_imm
function int uvma_isacov_instr_c::decode_rd_c(bit[ILEN-1:0] instr); //function to extract the rd' (3 bits) address from a compressed instruction
return instr[4:2] + 8;
endfunction : decode_rd_c
function int uvma_isacov_instr_c::decode_rs1_c(bit[ILEN-1:0] instr); //function to extract the rs1' (3 bits) address from a compressed instruction
return instr[9:7] + 8;
endfunction : decode_rs1_c
function int uvma_isacov_instr_c::decode_rs2_c(bit[ILEN-1:0] instr); //function to extract the rs2' (3 bits) address from a compressed instruction
return instr[4:2] + 8;
endfunction : decode_rs2_c
function bit uvma_isacov_instr_c::is_conditional_branch();

View file

@ -167,9 +167,9 @@ function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(IL
mon_trn.instr.rs2 = dasm_rvc_rs2(instr);
mon_trn.instr.rd = dasm_rvc_rd(instr);
mon_trn.instr.c_rdrs1 = dasm_rvc_rd(instr);
mon_trn.instr.c_rdp = dasm_rvc_rs1s(instr);
mon_trn.instr.c_rs1s = dasm_rvc_rs1s(instr);
mon_trn.instr.c_rs2s = dasm_rvc_rs2s(instr);
mon_trn.instr.c_rd = mon_trn.instr.decode_rd_c(instr);
mon_trn.instr.c_rs1 = mon_trn.instr.decode_rs1_c(instr);
mon_trn.instr.c_rs2 = mon_trn.instr.decode_rs2_c(instr);
end
else begin
mon_trn.instr.rs1 = dasm_rs1(instr);