I followed the steps to create RAL but it fails when debugging

I am a student learning to create uvm frameworks and I have a problem when I create a RAL and add it to my existing UVM framework (which was working fine before). I have been double checking for three days but still have no clue and I hope someone can help me. My current dut is a cpu featch part
The main problem is that I feel that the RAL has been built, but whenever I try to use the read command, it reports an error
I googled it and it says it’s a signal connection error but I can’t really find it, hope you can help me
Maybe this is a really stupid question

** Fatal: (SIGSEGV) Bad handle or reference.

Time: 0 ns Iteration: 49 Process: /uvm_pkg::uvm_task_phase::execute/fork#137(#ublk#215181159#137)_7fefed9ae04 File: /software/mentor/questa10.7c/questasim/linux_x86_64/../verilog_src/uvm-1.1d/src/base/uvm_component.svh

Fatal error in Task stage1_tb_top_sv_unit/stage1_scoreboard::run at /home/SOCV-1/Desktop/stage1/uvm/stage1_scoreboard.sv line 51

HDL call sequence:

Stopped at /home/SOCV-1/Desktop/stage1/uvm/stage1_scoreboard.sv 51 Task stage1_tb_top_sv_unit/stage1_scoreboard::run

called from /software/mentor/questa10.7c/questasim/linux_x86_64/../verilog_src/uvm-1.1d/src/base/uvm_component.svh 2288 Task uvm_pkg/uvm_component::run_phase

called from /software/mentor/questa10.7c/questasim/linux_x86_64/../verilog_src/uvm-1.1d/src/base/uvm_common_phases.svh 245 Task uvm_pkg/uvm_run_phase::exec_task

called from /software/mentor/questa10.7c/questasim/linux_x86_64/../verilog_src/uvm-1.1d/src/base/uvm_task_phase.svh 150 Function uvm_pkg/uvm_task_phase::execute

here is code

`include "uvm_macros.svh"
import uvm_pkg::*;
`include "stage1_sequencer.sv"

class reg_iram extends uvm_mem;

	uvm_reg_field	reg_data;
	
	`uvm_object_utils(reg_iram)

	function new(input string name="reg_iram");

		super.new(name, 48, 32);

	endfunction
endclass
//----------------------------------------------------------------------
class reg_model extends uvm_reg_block;

	reg_iram	iram;
	
	virtual function void build();
	
		default_map = create_map("default_map", 0, 4, UVM_BIG_ENDIAN);
		iram = reg_iram::type_id::create("iram", , get_full_name());
		iram.configure(this, "");
		//iram.build();
		default_map.add_mem(iram, 'h0);
	
	endfunction

	`uvm_object_utils(reg_model)
	
	function new(input string name="reg_model");
		
		super.new(name, UVM_NO_COVERAGE);

	endfunction

endclass
//---------------------------------------------------------------------
class my_adapter extends uvm_reg_adapter;

	string tID = get_type_name();

	`uvm_object_utils(my_adapter)
	
	function new(string name="my_adapter");
		
		super.new(name);
	
	endfunction

	function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
	
		stage1_transaction st1_tr;
		st1_tr = new("st1_tr");
		st1_tr.M_PCIN = rw.addr;
		//st1_tr.bus_op = (rw.kind == UVM_READ) BUS_RD: BUS_WR;
		
		//if(st1_tr.bus_op == BUS_WR)
			st1_tr.IR_reg= rw.data;
		//return bus_tr;
	
	endfunction

	function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
		
		stage1_transaction st1_tr;
		
		//if(!cast(st1_tr, bus_item)) begin

			//`uvm_fatal(tID, "provided stage1_item is not of correct type, expecting stage1_trans action")
		//return;
		//end

		//rw.kind = (st1_tr.bus_op == BUS_RD) UVM_READ : UVM_WRITE;
		rw.addr = st1_tr.M_PCIN;
		//rw.data = (st1_tr.bus_op == BUS_RD) st1_tr.rd_data : st1_tr.rw_data;
		rw.status = UVM_IS_OK;

	endfunction

endclass

Regarding these comments, I want to only read data from my dut, so I have commented out the parts I don’t want as I understand them, if I have any errors please let me know to help me improve
here is interface

//interface 
interface stage1_if;
	logic 			IF_CLK;
	logic 			IF_RST;
	logic			IF_IR_LATCH_EN;
	logic			IF_NPC_LATCH_EN;
	logic			IF_MUXPC;
	logic[31:0]		IF_M_PCIN;
	logic[31:0]		IF_IR;
	logic[31:0]		IF_PC_COUNT;
	logic[31:0]		IF_ID_RA_VAL;
	logic[31:0]		IF_ID_RB_VAL;
	logic[31:0]		IF_IMM;
	logic[4:0]		IF_W_RE_NUM;
	logic[4:0]		IF_RA;
	logic[4:0]		IF_RB;

	modport port(input IF_CLK, IF_RST, IF_IR_LATCH_EN, IF_NPC_LATCH_EN, IF_MUXPC, IF_M_PCIN, output IF_PC_COUNT, IF_IR, IF_ID_RA_VAL, IF_ID_RB_VAL, IF_IMM, IF_W_RE_NUM, IF_RA, IF_RB);
endinterface

here is sequence



`include "uvm_macros.svh"
import uvm_pkg::*;

class stage1_transaction extends uvm_sequence_item;
	
	rand	logic		IR_LATCH_EN;
	rand	logic		NPC_LATCH_EN;
	rand	logic		muxpc;
	rand	logic[31:0]	M_PCIN;
			
			logic[31:0]	IR;	
			logic[31:0]	IR_reg;
			logic[31:0]	PC_count;	
			logic[31:0]	id_ra_val;
			logic[31:0]	id_rb_val;
			logic[31:0]	id_imm;
			logic[4:0]	w_re_num;
			logic[4:0]	ra;
			logic[4:0]	rb;
		
	function new(string name = "stage1_transaction");

		super.new(name);

	endfunction: new

	`uvm_object_utils_begin(stage1_transaction)

		`uvm_field_int(IR_LATCH_EN, UVM_ALL_ON)
		`uvm_field_int(NPC_LATCH_EN, UVM_ALL_ON)
		`uvm_field_int(muxpc, UVM_ALL_ON)
		`uvm_field_int(M_PCIN, UVM_ALL_ON)
		`uvm_field_int(IR, UVM_ALL_ON)
		`uvm_field_int(IR_reg, UVM_ALL_ON)
		`uvm_field_int(PC_count, UVM_ALL_ON)
		`uvm_field_int(id_ra_val, UVM_ALL_ON)
		`uvm_field_int(id_rb_val, UVM_ALL_ON)
		`uvm_field_int(id_imm, UVM_ALL_ON)
		`uvm_field_int(w_re_num, UVM_ALL_ON)
		`uvm_field_int(ra, UVM_ALL_ON)
		`uvm_field_int(rb, UVM_ALL_ON)

	`uvm_object_utils_end

endclass: stage1_transaction	

class stage1_sequence extends uvm_sequence#(stage1_transaction);

	`uvm_object_utils(stage1_sequence)

   	function new(string name = "stage1_sequence");

      	super.new(name);

   	endfunction: new

   	task body();

      	stage1_transaction st1_tx;

      	forever begin

	 		st1_tx = stage1_transaction::type_id::create("st1_tx");
	 		start_item(st1_tx);
	 		assert(st1_tx.randomize());
	 		finish_item(st1_tx);

      	end
   	endtask: body
endclass // stage1_sequence

typedef uvm_sequencer#(stage1_transaction) stage1_sequencer;

here is driver

`include "reg_iram.sv"
`include "uvm_macros.svh"
import uvm_pkg::*;

class stage1_driver extends uvm_driver#(stage1_transaction);

   `uvm_component_utils(stage1_driver)

   virtual stage1_if vif;

   event   begin_record, end_record;
   

	function new(string name = "stage1_driver",uvm_component parent);

      	super.new(name, parent);

	endfunction: new

	function void build_phase(uvm_phase phase);

      	super.build_phase(phase);
      	void'(uvm_resource_db#(virtual stage1_if)::read_by_name
	    (.scope("ifs"), .name("stage1_if"), .val(vif)));

	endfunction: build_phase

	task run_phase(uvm_phase phase);

		super.run_phase(phase);

      	fork

	 		reset_signals();
	 		get_and_drive(phase);
	 		record();

      	join
       
   	endtask: run_phase

   	virtual task reset_signals();

      	wait(vif.IF_RST == 1);

      	begin

	 		vif.IF_IR_LATCH_EN  <= 0;
			vif.IF_NPC_LATCH_EN  <= 0;
			vif.IF_MUXPC  <= 0;
			vif.IF_M_PCIN  <= 0;
	 		@(posedge vif.IF_RST);

      	end

   	endtask // reset_signals

   	virtual task get_and_drive(uvm_phase phase);

      	wait(vif.IF_RST == 0);
      	@(negedge vif.IF_CLK);

      	forever begin

	 		seq_item_port.get(req);
			`uvm_info("process hints","driver begin record",UVM_NONE);
	 		->begin_record;
	 		driver_transfer(req);

      	end

   endtask // get_and_drive

	virtual task driver_transfer(stage1_transaction tr);

      	@(posedge vif.IF_CLK);
		`uvm_info("process hints","begin driver transfer",UVM_NONE);
      	vif.IF_IR_LATCH_EN = tr.IR_LATCH_EN;
      	vif.IF_NPC_LATCH_EN = tr.NPC_LATCH_EN;
		vif.IF_MUXPC = tr.muxpc;
		vif.IF_M_PCIN = tr.M_PCIN;

     	@(posedge vif.IF_CLK);
		`uvm_info("process hints","driver end record",UVM_NONE);
      	->end_record;
      	@(posedge vif.IF_CLK);

	endtask // driver_transfer

	virtual task record_tr();

		forever begin

	 		@(begin_record);
	 		begin_tr(req, "stage1_driver");
	 		@(end_record);
	 		end_tr(req);

      	end

   endtask // record_tr

endclass // stage1_driver

here is monitor

`include "uvm_macros.svh"
import uvm_pkg::*;
`include "stage1_driver.sv"


class stage1_monitor_before extends uvm_monitor;

	`uvm_component_utils(stage1_monitor_before)
	
	uvm_analysis_port#(stage1_transaction) item_collected_port_before;

	virtual stage1_if 	vif;
	stage1_transaction 	tr;

	event	begin_record, end_record;

   	function new(string name = "stage1_monitor_before", uvm_component parent);

     	super.new(name, parent);
   
	endfunction // new
   

   	function void build_phase(uvm_phase phase);
		
      	super.build_phase(phase);

      	void'(uvm_resource_db#(virtual stage1_if)::read_by_name
	    (.scope("ifs"), .name("stage1_if"), .val(vif)));

      	item_collected_port_before = new(.name("item_collected_port_before"), .parent(this));
		tr = stage1_transaction::type_id::create("tr", this);

   	endfunction // build_phase

   	task run_phase(uvm_phase phase);

      	super.run_phase(phase);

      	fork

	 		collect_transaction(phase);
	 		record_tr();

      	join

   	endtask // run_phase

  	virtual task collect_transaction(uvm_phase phase);
		wait (vif.IF_RST == 1);

      	forever begin

			#20ns
	 		->begin_record;
				@(posedge vif.IF_CLK);
	 			tr.PC_count = vif.IF_PC_COUNT;
	 			tr.id_ra_val = vif.IF_ID_RA_VAL;
	 			tr.id_rb_val = vif.IF_ID_RB_VAL;
	 			tr.id_imm = vif.IF_IMM;
	 			tr.w_re_num = vif.IF_W_RE_NUM;
	 			tr.ra = vif.IF_RA;
	 			tr.rb = vif.IF_RB;
	 			item_collected_port_before.write(tr);
	 		->end_record;

      	end

   	endtask // collect_transaction

   	virtual task record_tr();

      	forever begin

	 		@(begin_record);
	 		begin_tr(tr, "stage1_monitor_before");
	 		@(end_record);
	 		end_tr(tr);

      	end
   	endtask // record_tr

endclass // p4adder_monitor_before





//------------------------------------------------------------
class stage1_monitor_after extends uvm_monitor;

	`uvm_component_utils(stage1_monitor_after)
   	uvm_analysis_port#(stage1_transaction) item_collected_port_after;
//------------------------------------
	uvm_analysis_port#(stage1_transaction) reg_port;

   	virtual stage1_if vif;
//---------------------------reg_model----------------
	//reg_model			p_rm;
//----------------------------------------------------
  	event	begin_record, end_record;
	
	stage1_transaction tr;

						

   	function new(string name = "stage1_monitor_before", uvm_component parent);

		super.new(name, parent);

   	endfunction // new

   	function void build_phase(uvm_phase phase);

      	super.build_phase(phase);

      	void'(uvm_resource_db#(virtual stage1_if)::read_by_name
	    (.scope("ifs"), .name("stage1_if"), .val(vif)));

      	item_collected_port_after = new(.name("item_collected_port_after"), .parent(this));
//---------------------------------
		reg_port = new(.name("reg_port"), .parent(this));		

		tr = stage1_transaction::type_id::create("tr", this);
		

   	endfunction // build_phase
   
   	task run_phase(uvm_phase phase);	
	

      	super.run_phase(phase);


      	fork
			
	 		collect_transaction(phase);
	 		record_tr();

      	join

   	endtask // run_phase	 

 	virtual task collect_transaction(uvm_phase phase);
		
		forever begin

			->begin_record;
			item_collected_port_after.write(tr);
	 		->end_record;

      	end

 	endtask // collect_transaction


   	virtual task record_tr();

      	forever begin

			@(begin_record);
	 		begin_tr(tr, "stage1_monitor_after");
	 		@end_record;
	 		end_tr(tr);

      	end

   	endtask // record_tr

endclass // stage1_monitor_after

here is agent

`include "uvm_macros.svh"
import uvm_pkg::*;
`include "stage1_monitor.sv"

class stage1_agent extends uvm_agent;

   	`uvm_component_utils(stage1_agent)

   	uvm_analysis_port#(stage1_transaction) agent_collected_port_before;
  	uvm_analysis_port#(stage1_transaction) agent_collected_port_after;

//----------------------------------------------------------
	uvm_analysis_port#(stage1_transaction) agent_reg_port;

   	stage1_sequencer  sqr;
   	stage1_driver     drv;
   	stage1_monitor_before mon_before;
   	stage1_monitor_after  mon_after;

   	function new(string name = "stage1_agent", uvm_component parent);

      	super.new(name, parent);

   	endfunction // new

   	function void build_phase(uvm_phase phase);

      	super.build_phase(phase);

      	agent_collected_port_before = new(.name("agent_collected_port_before"), .parent(this));
      	agent_collected_port_after = new(.name("agent_collected_port_after"), .parent(this));
//---------------------------
		agent_reg_port = new(.name("agent_reg_port"), .parent(this));

      	mon_before = stage1_monitor_before::type_id::create("mon_before", this);
      	sqr = stage1_sequencer::type_id::create("sqr", this);
      	drv = stage1_driver::type_id::create("drv", this);
      	mon_after = stage1_monitor_after::type_id::create("mon_after", this);

   	endfunction // build_phase

   	virtual function void connect_phase(uvm_phase phase);

      	super.connect_phase(phase);

      	mon_before.item_collected_port_before.connect(agent_collected_port_before);
      	mon_after.item_collected_port_after.connect(agent_collected_port_after);
//--------------------------------------------------
		mon_after.reg_port.connect(agent_reg_port);

      	drv.seq_item_port.connect(sqr.seq_item_export);

   	endfunction // connect_phase

endclass // p4adder_agent

here is scoreboard

`include "uvm_macros.svh"
import uvm_pkg::*;
`include "stage1_agent.sv"

class stage1_scoreboard extends uvm_scoreboard;
   `uvm_component_utils(stage1_scoreboard)

   	uvm_analysis_export #(stage1_transaction) sb_export_before;
   	uvm_analysis_export #(stage1_transaction) sb_export_after;

   	uvm_tlm_analysis_fifo #(stage1_transaction) before_fifo;
   	uvm_tlm_analysis_fifo #(stage1_transaction) after_fifo;

   	stage1_transaction transaction_before;
   	stage1_transaction transaction_after;
//-------------------------
	reg_model rm;

   	function new(string name = "stage1_scoreboard", uvm_component parent);

      	super.new(name, parent);

     	transaction_before	= new("transaction_before");
      	transaction_after	= new("transaction_after");

  	 endfunction // new

   	function void build_phase(uvm_phase phase);
       	super.build_phase(phase);

      	sb_export_before	= new("sb_export_before", this);
      	sb_export_after		= new("sb_export_after", this);

      	before_fifo		= new("before_fifo", this);
      	after_fifo		= new("after_fifo", this);

   	endfunction // build_phase

   	function void connect_phase(uvm_phase phase);

		super.connect_phase(phase);
      	sb_export_before.connect(before_fifo.analysis_export);
      	sb_export_after.connect(after_fifo.analysis_export);

   	endfunction // connect_phase

   	task run();
		uvm_status_e status;
		uvm_reg_data_t value[];
      	forever begin
			rm.iram.burst_read(.status(status), .value(value), .offset(0));
	 		before_fifo.get(transaction_before);
	 		after_fifo.get(transaction_after);
			compare();
			end
   	endtask // run
   

   	virtual function void compare();
      		`uvm_info("HTNTS",{"START COMPARE"},UVM_NONE);

	endfunction // compare
   
endclass // stage1_scoreboard

here is env


`include "uvm_macros.svh"
import uvm_pkg::*;
`include "stage1_scoreboard.sv"
class stage1_env extends uvm_env;

   	`uvm_component_utils(stage1_env)

   	stage1_agent 		st1_agent;
   	stage1_scoreboard 	st1_sb;
//----------------------------------------reg_model----------------------
	reg_model 			rm;
	my_adapter			reg_sqr_adapter;
//	my_adapter			reg_mon_adapter;
//	uvm_reg_predictor #(stage1_transaction) reg_predictor;
	



   	function new(string name = "pstage1_env", uvm_component parent);

      	super.new(name, parent);

   	endfunction // new

   	function void build_phase(uvm_phase phase);

      	super.build_phase(phase);
		rm = reg_model::type_id::create(.name("rm"), .parent(this));
		rm.configure(null, "");
		rm.build();
		rm.lock_model();
		rm.reset();
		reg_sqr_adapter = my_adapter::type_id::create("reg_sqr_adapter", this);
		//reg_mon_adapter = my_adapter::type_id::create("reg_mon_adapter", this);
		//reg_predictor = new("reg_predictor", this);

      	st1_agent = stage1_agent::type_id::create(.name("st1_agent"), .parent(this));
      	st1_sb    = stage1_scoreboard::type_id::create(.name("st1_sb"), .parent(this));

   	endfunction // build_phase

   	function void connect_phase(uvm_phase phase);

      	super.connect_phase(phase);

     	st1_agent.agent_collected_port_before.connect(st1_sb.sb_export_before);
      	st1_agent.agent_collected_port_after.connect(st1_sb.sb_export_after);

		rm.default_map.set_sequencer(st1_agent.sqr, reg_sqr_adapter);
		rm.default_map.set_auto_predict(1);

		//reg_predictor.map = rm.default_map;
		//reg_predictor.adapter = reg_mon_adapter;
		//st1_agent.agent_reg_port.connect(reg_predictor.bus_in);

   	endfunction // connect_phase

endclass // p4adder_env

here is test


`include "uvm_macros.svh"
import uvm_pkg::*;
`include "stage1_env.sv"

class stage1_test extends uvm_test;

   	`uvm_component_utils(stage1_test)

   	stage1_env st1_env;

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

      	super.new(name,parent);

   	endfunction // new

   	function void build_phase(uvm_phase phase);

      	super.build_phase(phase);
      	st1_env = stage1_env::type_id::create(.name("st1_env"), .parent(this));

   	endfunction // build_phase

   task run_phase(uvm_phase phase);

      stage1_sequence st1_seq;

      phase.raise_objection(this);
      st1_seq = stage1_sequence::type_id::create(.name("st1_seq"), .contxt(get_full_name()));
      assert(st1_seq.randomize());
      st1_seq.start(st1_env.st1_agent.sqr);
      phase.drop_objection(this);
   endtask // run_phase
endclass // stage1_test

here is top

`include "uvm_macros.svh"
`include "stage1_test.sv"
import uvm_pkg::*;

module stage1_tb_top;

//interface declaration
	stage1_if	vif();

//connect the interface to dut
	stage1  dut(.CLK(vif.IF_CLK),
				.RST(vif.IF_RST),
				.IR_LATCH_EN(vif.IF_IR_LATCH_EN),
				.NPC_LATCH_EN(vif.IF_NPC_LATCH_EN),
				.muxpc(vif.IF_MUXPC),
				.M_PCIN(vif.IF_M_PCIN),
				.PC_count(vif.IF_PC_COUNT),
				.IR(vif.IF_IR),
				.id_ra_val(vif.IF_ID_RA_VAL),
				.id_rb_val(vif.IF_ID_RB_VAL),
				.id_imm(vif.IF_IMM),
				.w_re_num(vif.IF_W_RE_NUM),
				.ra(vif.IF_RA),
				.rb(vif.IF_RB));
initial begin
//registers the interface in the configuration block
//so that other blocks can use it

	uvm_resource_db#(virtual stage1_if)::set(.scope("ifs"), .name("stage1_if"), .val(vif));
//executes the test
	run_test("stage1_test");
end

//variable initialization
initial begin
	vif.IF_CLK = 1'b1;
	vif.IF_RST = 1'b1;
	#5 vif.IF_RST = ~vif.IF_RST;
end

//clock generation
always 
	#5 vif.IF_CLK = ~vif.IF_CLK;
endmodule

In reply to demontop:

You declared a register model variable rm in your scoreboard but never initialize it, so it remains null generating the bad reference error. You constructed the register model in the env and need to pass that handle down to the scoreboard. You can do that in the env::connect_phase().

A couple of other issues with your code.

Normally a scoreboard does not do a time-consuming front-door register read(). You should use get() to access the mirrored value, or do a back-door read().

Do not use the run() task, which is left over from OVM. Use run_phase(uvm_phase phase) instead. Other features of the UVM will need that phase argument (like raising/dropping objections)

Do not use uvm_resource_db directly. Use uvm_config_db instead. One less thing to learn and manage.