Skip to content

Commit

Permalink
Merge pull request openhwgroup#2059 from silabs-inhaahje/isacov_disas…
Browse files Browse the repository at this point in the history
…sembler

Made it possible to use the Risc-v disassembler with isacov
  • Loading branch information
silabs-robin authored Jul 19, 2023
2 parents 0ee49d0 + e041fb9 commit 5b10a1a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 43 deletions.
3 changes: 3 additions & 0 deletions cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c;
isacov_cfg.seq_instr_x2_enabled == 1;
isacov_cfg.reg_crosses_enabled == 0;
isacov_cfg.reg_hazards_enabled == 1;
isacov_cfg.decoder == ISA_SUPPORT;


rvfi_cfg.nret == RVFI_NRET;
rvfi_cfg.nmi_load_fault_enabled == 1;
Expand Down Expand Up @@ -418,6 +420,7 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg");
clic_irq_clear_on_ack.rand_mode(0);
end


isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg");
clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg");
interrupt_cfg = uvma_interrupt_cfg_c::type_id::create("interrupt_cfg");
Expand Down
7 changes: 7 additions & 0 deletions lib/uvm_agents/uvma_isacov/uvma_isacov_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class uvma_isacov_cfg_c extends uvm_object;
rand bit reg_crosses_enabled;
rand bit reg_hazards_enabled;

rand decoder_e decoder;

// Core configuration object to filter extensions, csrs, modes, supported
uvma_core_cntrl_cfg_c core_cfg;

Expand All @@ -48,8 +50,13 @@ class uvma_isacov_cfg_c extends uvm_object;
`uvm_field_int(seq_instr_x2_enabled, UVM_DEFAULT);
`uvm_field_int(reg_crosses_enabled, UVM_DEFAULT);
`uvm_field_int(reg_hazards_enabled, UVM_DEFAULT);

`uvm_field_enum(decoder_e, decoder, UVM_DEFAULT);
`uvm_object_utils_end;

constraint defaults_cons {
soft decoder == SPIKE;
}
extern function new(string name = "uvma_isacov_cfg");

endclass : uvma_isacov_cfg_c
Expand Down
129 changes: 87 additions & 42 deletions lib/uvm_agents/uvma_isacov/uvma_isacov_mon.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ class uvma_isacov_mon_c#(int ILEN=DEFAULT_ILEN,
uvma_isacov_cfg_c cfg;
uvm_analysis_port#(uvma_isacov_mon_trn_c) ap;
instr_name_t instr_name_lookup[string];
asm_t instr_asm;

// Analysis export to receive instructions from RVFI
uvm_analysis_imp_rvfi_instr#(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN), uvma_isacov_mon_c) rvfi_instr_imp;

extern function new(string name = "uvma_isacov_mon", uvm_component parent = null);

extern virtual function void build_phase(uvm_phase phase);

/**
Expand All @@ -43,6 +45,8 @@ class uvma_isacov_mon_c#(int ILEN=DEFAULT_ILEN,
*/
extern virtual function void write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN) rvfi_instr);



endclass : uvma_isacov_mon_c


Expand Down Expand Up @@ -75,13 +79,16 @@ function void uvma_isacov_mon_c::build_phase(uvm_phase phase);
dasm_set_config(32, "rv32imc", 0);

// Use the enumerations in <instr_name_t> to setup the instr_name_lookup
// convert the enums to lower-case and substitute underscore with . to match
// Spike disassembler
in = in.first;
repeat(in.num) begin
string instr_name_key = convert_instr_to_spike_name(in.name());
string instr_name_key = in.name();
if(cfg.decoder == SPIKE) begin
// convert the enums to lower-case and substitute underscore with . to match
// Spike disassembler
instr_name_key = convert_instr_to_spike_name(in.name());
`uvm_info("ISACOV", $sformatf("Converting: %s to %s", in.name(), instr_name_key), UVM_HIGH);
end

`uvm_info("ISACOV", $sformatf("Converting: %s to %s", in.name(), instr_name_key), UVM_HIGH);
instr_name_lookup[instr_name_key] = in;
in = in.next;
end
Expand Down Expand Up @@ -138,12 +145,21 @@ function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(IL
mon_trn = uvma_isacov_mon_trn_c#(.ILEN(ILEN), .XLEN(XLEN))::type_id::create("mon_trn");
mon_trn.instr = uvma_isacov_instr_c#(ILEN,XLEN)::type_id::create("mon_instr");
mon_trn.instr.rvfi = rvfi_instr;

// Mark trapped instructions from RVFI
mon_trn.instr.trap = rvfi_instr.trap;

// Attempt to decode instruction with Spike DASM
instr_name = dasm_name(rvfi_instr.insn);
// Get the config
void'(uvm_config_db#(uvma_isacov_cfg_c)::get(this, "", "cfg", cfg));

if (cfg.decoder == SPIKE) begin
// Attempt to decode instruction with Spike DASM
instr_name = dasm_name(rvfi_instr.insn);
end else if (cfg.decoder == ISA_SUPPORT) begin
// Attempt to decode instruction with isa_support
instr_asm = decode_instr(rvfi_instr.insn);
instr_name = instr_asm.instr.name();
end

if (instr_name_lookup.exists(instr_name)) begin
mon_trn.instr.name = instr_name_lookup[instr_name];
end else begin
Expand All @@ -152,48 +168,79 @@ function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(IL
// from OpenHW core-v-verif perspective so set to UNKNOWN
mon_trn.instr.name = UNKNOWN;
end

`uvm_info("ISACOVMON", $sformatf("rvfi = 0x%08x %s", rvfi_instr.insn, instr_name), UVM_HIGH);

mon_trn.instr.itype = get_instr_type(mon_trn.instr.name);
mon_trn.instr.ext = get_instr_ext(mon_trn.instr.name);
mon_trn.instr.group = get_instr_group(mon_trn.instr.name, rvfi_instr.mem_addr);
mon_trn.instr.itype = get_instr_type(mon_trn.instr.name);

instr = $signed(rvfi_instr.insn);

// Disassemble the instruction using Spike (via DPI)
if (mon_trn.instr.ext == C_EXT) begin
mon_trn.instr.rs1 = dasm_rvc_rs1(instr);
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);
end
else begin
mon_trn.instr.rs1 = dasm_rs1(instr);
mon_trn.instr.rs2 = dasm_rs2(instr);
mon_trn.instr.rd = dasm_rd(instr);
mon_trn.instr.immi = dasm_i_imm(instr);
mon_trn.instr.imms = dasm_s_imm(instr);
mon_trn.instr.immb = dasm_sb_imm(instr) >> 1; // Because dasm gives [12:0], not [12: 1]
mon_trn.instr.immu = dasm_u_imm(instr) >> 12; // Because dasm gives [31:0], not [31:12]
mon_trn.instr.immj = dasm_uj_imm(instr) >> 1; // Because dasm gives [20:0], not [20: 1]
if (cfg.decoder == SPIKE) begin
// Attempt to decode instruction with Spike DASM
instr = $signed(rvfi_instr.insn);

//Disassemble the instruction using Spike (via DPI)
if (mon_trn.instr.ext == C_EXT) begin
mon_trn.instr.rs1 = dasm_rvc_rs1(instr);
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);
end
else begin
mon_trn.instr.rs1 = dasm_rs1(instr);
mon_trn.instr.rs2 = dasm_rs2(instr);
mon_trn.instr.rd = dasm_rd(instr);
mon_trn.instr.immi = dasm_i_imm(instr);
mon_trn.instr.imms = dasm_s_imm(instr);
mon_trn.instr.immb = dasm_sb_imm(instr) >> 1; // Because dasm gives [12:0], not [12: 1]
mon_trn.instr.immu = dasm_u_imm(instr) >> 12; // Because dasm gives [31:0], not [31:12]
mon_trn.instr.immj = dasm_uj_imm(instr) >> 1; // Because dasm gives [20:0], not [20: 1]
end

// Make instructions as illegal,
// 1. If a CSR instruction is not targeted to a valid CSR
if (mon_trn.instr.group == CSR_GROUP) begin
mon_trn.instr.csr_val = dasm_csr(instr);
if (!$cast(mon_trn.instr.csr, mon_trn.instr.csr_val) ||
cfg.core_cfg.unsupported_csr_mask[mon_trn.instr.csr_val]) begin
mon_trn.instr.illegal = 1;
end
end

end else if (cfg.decoder == ISA_SUPPORT) begin
// Attempt to decode instruction with isa_support
mon_trn.instr.c_rdrs1 = instr_asm.rd.gpr;
mon_trn.instr.c_rdp = instr_asm.rd.gpr;
mon_trn.instr.c_rs1s = instr_asm.rs1.gpr;
mon_trn.instr.c_rs2s = instr_asm.rs2.gpr;
mon_trn.instr.rs1 = instr_asm.rs1.gpr;
mon_trn.instr.rs2 = instr_asm.rs2.gpr;
mon_trn.instr.rd = instr_asm.rd.gpr;
mon_trn.instr.immi = instr_asm.imm.imm_raw_sorted;
mon_trn.instr.imms = instr_asm.imm.imm_raw_sorted;
mon_trn.instr.immb = instr_asm.imm.imm_raw_sorted;
mon_trn.instr.immu = instr_asm.imm.imm_raw_sorted;
mon_trn.instr.immj = instr_asm.imm.imm_raw_sorted;

// Make instructions as illegal,
// 1. If a CSR instruction is not targeted to a valid CSR
if (mon_trn.instr.group == CSR_GROUP) begin
mon_trn.instr.csr_val = instr_asm.csr.address;
if (!$cast(mon_trn.instr.csr, mon_trn.instr.csr_val) ||
cfg.core_cfg.unsupported_csr_mask[mon_trn.instr.csr_val]) begin
mon_trn.instr.illegal = 1;
end
end
end

// Make instructions as illegal,
// 1. If UNKNOWN (undecodable)
if (mon_trn.instr.name == UNKNOWN)
// 2. If UNKNOWN (undecodable)
if (mon_trn.instr.name == UNKNOWN) begin
mon_trn.instr.illegal = 1;
// 2. If a CSR instruction is not targeted to a valid CSR
if (mon_trn.instr.group == CSR_GROUP) begin
mon_trn.instr.csr_val = dasm_csr(instr);
if (!$cast(mon_trn.instr.csr, mon_trn.instr.csr_val) ||
cfg.core_cfg.unsupported_csr_mask[mon_trn.instr.csr_val]) begin
mon_trn.instr.illegal = 1;
end
end

// Make instructions as illegal,
// 3. Instruction is in unsupported extension
if ((mon_trn.instr.ext == A_EXT && !cfg.core_cfg.ext_a_supported) ||
(mon_trn.instr.ext == C_EXT && !cfg.core_cfg.ext_c_supported) ||
Expand Down Expand Up @@ -302,5 +349,3 @@ function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(IL
ap.write(mon_trn);

endfunction : write_rvfi_instr


4 changes: 3 additions & 1 deletion lib/uvm_agents/uvma_isacov/uvma_isacov_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ package uvma_isacov_pkg;
import uvma_core_cntrl_pkg::*;
import uvma_rvfi_pkg::*;

import support_pkg::*;

// DPI imports
`include "dpi_dasm_imports.svh"

// Constants / Structs / Enums
// Constants / Structs / Enums
`include "uvma_isacov_constants.sv"
`include "uvma_isacov_tdefs.sv"

Expand Down
5 changes: 5 additions & 0 deletions lib/uvm_agents/uvma_isacov/uvma_isacov_tdefs.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
`ifndef __UVMA_ISACOV_TDEFS_SV__
`define __UVMA_ISACOV_TDEFS_SV__

typedef enum {
SPIKE,
ISA_SUPPORT
} decoder_e;

typedef enum {
A_EXT,
B_EXT,
Expand Down

0 comments on commit 5b10a1a

Please sign in to comment.