/// custom routines defined for the platform // Design parameters, used in the code below and custom to this design! //`define RAM_PATH soc_top.soc_instance.i_sram_subsystem.i_shared_ram //sim:/testbench/dut/uncore/uncore/ram/ram/memory/RAM //`define RAM_PATH testbench.dut.uncore.uncore.ram.ram.memory.RAM //`define RAM_PATH testbench.dut.uncore.uncore.ram.ram.memory `define RAM_PATH testbench.dut.uncoregen.uncore.ram.ram.memory.ram //`define RAM_BASE_ADDR 32'h80000000 `define RAM_BASE_ADDR testbench.P.UNCORE_RAM_BASE // These two routines are specific to a particular design. They are used // to read and write to the "mailbox" locations, to synchronize behaviors // between C code on the processors with activity performed in UVM (and // among activities in UVM). // // Every design will be different. Here we just have a simple Verilog // array that we can read and write. // function automatic void trek_backdoor_read64( input longint unsigned address, output longint unsigned data, input int unsigned debug = 1); //bit [15:0] offset = (address-`RAM_BASE_ADDR) >> 2; bit [31:0] offset = ((address-`RAM_BASE_ADDR)/(testbench.P.XLEN/8)); if (address[1:0] != 2'b00) begin: misaligned $display("%t trek_backdoor_read64: Misaligned address", $time); $finish(); end //data[63:32] = `RAM_PATH[offset + 0]; //data[31: 0] = `RAM_PATH[offset + 1]; data[63:0] = `RAM_PATH.RAM[offset + 0]; if (data != 0) $display("%t trek_backdoor_read64: Read 64'h%016h from address 64'h%016h", $time, data, address); endfunction: trek_backdoor_read64 function automatic void trek_backdoor_write64( input longint unsigned address, input longint unsigned data, input int unsigned debug = 1); //bit [15:0] offset = (address-`RAM_BASE_ADDR) >> 2; bit [31:0] offset = ((address-`RAM_BASE_ADDR)/(testbench.P.XLEN/8)); if (address[1:0] != 2'b00) begin: misaligned $display("%t trek_backdoor_write64: Misaligned address", $time); $finish(); end //`RAM_PATH[offset + 0] = data[63:32]; //`RAM_PATH[offset + 1] = data[31: 0]; `RAM_PATH.RAM[offset + 0] = data[63:0]; //$display("%t trek_backdoor_write64: Wrote 64'h%016h to address 64'h%016h", //$time, data, address); endfunction: trek_backdoor_write64 // For performance, we want to read mailboxes ONLY when they're written to! // (This is very important on emulators!) // // Here we trigger a signal when a memory write happens to the range of // addresses where the mailboxes are. // // A clock later, we go poll all the mailboxes (using the "backdoor_read" // method above. // // Each design will be different, depending on where you are able to snoop // for writes and how long it takes a write to propagate from that point // to the place where the backdoor read will find it. bit trek_c2t_mbox_event; bit trek_is_event_addr; //assign trek_is_event_addr = // ((((`RAM_PATH.ad << 2) + `RAM_BASE_ADDR) >= `TREK_C2T_MBOX_BASE) && // (((`RAM_PATH.ad << 2) + `RAM_BASE_ADDR) < `TREK_C2T_MBOX_LIMIT)); // //always_ff @(posedge `RAM_PATH.clk) begin: trigger_reading_of_mailboxes // trek_c2t_mbox_event <= (trek_is_event_addr && // (`RAM_PATH.n_cs == 1'b0) && // (`RAM_PATH.n_we == 1'b0)); //end // Design specifc: one stage delayed so write has a time to settle //always @(posedge trek_c2t_mbox_event) begin: read_all_mailboxes always @(posedge testbench.clk) begin: read_all_mailboxes trek_poll_mbox(); end