In reply to Subhra Bera:
Hi Subhra,
virtual function void write();
//if((!sb_wr_txn.csn_0)||(!sb_wr_txn.csn_1)) begin
fork
if(sb_wr_txn.wen_0)
ram_model[sb_wr_txn.addr_0]=sb_wr_txn.datain_0;
if(sb_wr_txn.wen_1)
ram_model[sb_wr_txn.addr_1]=sb_wr_txn.datain_1;
join
//end
endfunction
I believe you want a join_any, not join. Your fork started 2 processes, and they both must complete before the fork will exit. The only transactions that will complete this fork MUST have wen_0 and wen_1 both logic high.
task run_phase(uvm_phase phase);
forever begin
wr_fifo.get(sb_wr_txn);
write();
rd_fifo.get(sb_rd_txn);
compare();
end
endtask
This component you described is a “dual port RAM model, with a scoreboard”. However, your run_phase looks like code for a dual-port fifo scoreboard. The writing of the RAM should be independent of the reading/comparing. i.e. They should not be in the same thread.
This might be a lot to digest if you are just beginning, but I recommend also using a single transaction type. address, data, either an enum {RAM_WRITE, RAM_READ) or a logic rd_nwr signal. I’d removed the “dual port” information out of the transaction, and use the 2 “imp” ports to represent the two ports of your RAM This will greatly shrink the size of your code, which is too complicated currently. I can help more if you are interested.
result will look something like:
// Macros to create the uvm_analysis_imp ports (just an export + write function)
`uvm_analysis_imp_decl(_port0)
`uvm_analysis_imp_decl(_port1)
// The macros above created these ports
uvm_analysis_imp_exp #(ram_txn,scoreboard) port0_imp;
uvm_analysis_imp_act #(ram_txn,scoreboard) port1_imp;
virtual function void write_port0(ram_txn t, 0);
if (t.rd_nwr) check_ram(t); // READ & VERIFY
else ram_model[t.addr]=t.data; // WRITE
endfunction
virtual function void write_port1(ram_txn t, 1);
if (t.rd_nwr) check_ram(t); // READ & VERIFY
else ram_model[t.addr]=t.data; // WRITE
endfunction
function void check_ram(ram_txn t, int port_num);
if(ram_model[t.addr]==t.data) begin
`uvm_info("compare", {"Test: OK!"}, UVM_HIGH);
end else begin
`uvm_error(get_type_name(), $sformatf("miscompare on port %0d, addr=", port_num, t.addr))
`uvm_info(get_type_name(), $sformatf("ACT data=0x%0h",t.data), UVM_MEDIUM)
`uvm_info(get_type_name(), $sformatf("EXP data=0x%0h",ram_model[t.addr]), UVM_MEDIUM)
end
endfunction
That leaves your run_phase empty, so just delete it for now.
You can build on to this model, if your RAM has write access semaphores etc.
I’m assuming you don’t need an associative array for your RAM either… I’d just use a typically array if you know the size.
bit [31:0] RAM[512]; // e.g.