Now able to run multiple ISA tests in a single simulation run connected to remote debugger DSharp, using either hart_reset or ndm_reset between tests to bring the system back into reset state. All Debug Module commands working: - dm_reset, hart_reset, ndm_reset - break (set breakpoint) - step - continue (until breakpoint of 'halt' command) - halt - read/write GPR, FPR, CSR, memory - elf_load
290 lines
7.8 KiB
Plaintext
290 lines
7.8 KiB
Plaintext
// Copyright (c) 2019 Bluespec, Inc. All Rights Reserved
|
|
|
|
package Unit_Test_Deburster;
|
|
|
|
// ================================================================
|
|
// Standalone unit tester for AXI4_Deburster.bsv
|
|
|
|
// ================================================================
|
|
// Bluespec library imports
|
|
|
|
import FIFOF :: *;
|
|
import Connectable :: *;
|
|
|
|
// ----------------
|
|
// BSV additional libs
|
|
|
|
import Cur_Cycle :: *;
|
|
|
|
// ================================================================
|
|
// Project imports
|
|
|
|
import Semi_FIFOF :: *;
|
|
import AXI4_Types :: *;
|
|
import AXI4_Deburster :: *;
|
|
|
|
// ================================================================
|
|
// Synthesized instance of Deburster
|
|
|
|
typedef 4 Wd_Id;
|
|
typedef 32 Wd_Addr;
|
|
typedef 64 Wd_Data;
|
|
typedef 10 Wd_User;
|
|
|
|
typedef AXI4_Deburster_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) AXI4_Deburster_IFC_Inst;
|
|
|
|
(* synthesize *)
|
|
module mkAXI4_Deburster_Inst (AXI4_Deburster_IFC_Inst);
|
|
let m <- mkAXI4_Deburster;
|
|
return m;
|
|
endmodule
|
|
|
|
// ================================================================
|
|
|
|
(* synthesize *)
|
|
module mkUnit_Test_Deburster (Empty);
|
|
AXI4_Deburster_IFC_Inst deburster <- mkAXI4_Deburster_Inst;
|
|
|
|
AXI4_Master_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master <- mkAXI4_Master_Xactor;
|
|
AXI4_Slave_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) slave <- mkAXI4_Slave_Xactor;
|
|
|
|
mkConnection (master.axi_side, deburster.from_master);
|
|
mkConnection (deburster.to_slave, slave.axi_side);
|
|
|
|
Reg #(Bit #(32)) rg_test <- mkReg (20); // Chooses which test to run
|
|
|
|
FIFOF #(Bit #(8)) f_len <- mkFIFOF;
|
|
Reg #(Bit #(8)) rg_beat <- mkReg (0);
|
|
Reg #(Bit #(32)) rg_idle_count <- mkReg (0);
|
|
|
|
// ================================================================
|
|
// Help function to create AXI4 channel payloads
|
|
|
|
function AXI4_Wr_Addr #(Wd_Id, Wd_Addr, Wd_User)
|
|
fv_mk_wr_addr (Bit #(Wd_Id) id,
|
|
Bit #(Wd_Addr) addr,
|
|
Bit #(8) len,
|
|
Bit #(2) burst,
|
|
Bit #(Wd_User) user);
|
|
return AXI4_Wr_Addr {awid: id,
|
|
awaddr: addr,
|
|
awlen: len,
|
|
awsize: axsize_8,
|
|
awburst: burst,
|
|
awlock: 0,
|
|
awcache: 0,
|
|
awprot: 0,
|
|
awqos: 0,
|
|
awregion: 0,
|
|
awuser: user};
|
|
endfunction
|
|
|
|
function AXI4_Wr_Data #(Wd_Data, Wd_User)
|
|
fv_mk_wr_data (Bit #(Wd_Data) data,
|
|
Bit #(Wd_User) user);
|
|
Bool last = (rg_beat == f_len.first - 1);
|
|
return AXI4_Wr_Data {wdata: data,
|
|
wstrb: 'hFF,
|
|
wlast: last,
|
|
wuser: user};
|
|
endfunction
|
|
|
|
function AXI4_Wr_Resp #(Wd_Id, Wd_User)
|
|
fv_mk_wr_resp (AXI4_Wr_Addr #(Wd_Id, Wd_Addr, Wd_User) wa);
|
|
return AXI4_Wr_Resp {bid: wa.awid,
|
|
bresp: axi4_resp_okay,
|
|
buser: wa.awuser};
|
|
endfunction
|
|
|
|
function AXI4_Rd_Addr #(Wd_Id, Wd_Addr, Wd_User)
|
|
fv_mk_rd_addr (Bit #(Wd_Id) id,
|
|
Bit #(Wd_Addr) addr,
|
|
Bit #(8) len,
|
|
Bit #(2) burst,
|
|
Bit #(Wd_User) user);
|
|
return AXI4_Rd_Addr {arid: id,
|
|
araddr: addr,
|
|
arlen: len,
|
|
arsize: axsize_8,
|
|
arburst: burst,
|
|
arlock: 0,
|
|
arcache: 0,
|
|
arprot: 0,
|
|
arqos: 0,
|
|
arregion: 0,
|
|
aruser: user};
|
|
endfunction
|
|
|
|
function AXI4_Rd_Data #(Wd_Id, Wd_Data, Wd_User)
|
|
fv_mk_rd_data (AXI4_Rd_Addr #(Wd_Id, Wd_Addr, Wd_User) ar);
|
|
return AXI4_Rd_Data {rid: ar.arid,
|
|
rdata: zeroExtend (ar.araddr + 'h10_000),
|
|
rresp: axi4_resp_okay,
|
|
rlast: True,
|
|
ruser: ar.aruser};
|
|
endfunction
|
|
|
|
// ================================================================
|
|
// STIMULUS
|
|
|
|
Bit #(Wd_Id) id1 = 1;
|
|
Bit #(Wd_User) user1 = 1;
|
|
|
|
// ----------------
|
|
// Write tests
|
|
|
|
rule rl_wr_single (rg_test == 0);
|
|
Bit #(8) len = 1;
|
|
let wa = fv_mk_wr_addr (id1, 'h1000, (len - 1), axburst_fixed, user1);
|
|
master.i_wr_addr.enq (wa);
|
|
|
|
f_len.enq (len);
|
|
rg_idle_count <= 0;
|
|
rg_test <= 100;
|
|
|
|
$display ("%0d: master.rl_wr_single: ", cur_cycle);
|
|
$display (" ", fshow (wa));
|
|
endrule
|
|
|
|
rule rl_wr_burst_addr_0 (rg_test == 10);
|
|
Bit #(8) len = 2;
|
|
let wa = fv_mk_wr_addr (id1, 'h1000, (len - 1), axburst_incr, user1);
|
|
master.i_wr_addr.enq (wa);
|
|
|
|
f_len.enq (len);
|
|
rg_idle_count <= 0;
|
|
rg_test <= 11;
|
|
|
|
$display ("%0d: master.rl_wr_burst_addr_0: ", cur_cycle);
|
|
$display (" ", fshow (wa));
|
|
endrule
|
|
|
|
rule rl_wr_burst_addr_1 (rg_test == 11);
|
|
Bit #(8) len = 4;
|
|
let wa = fv_mk_wr_addr (id1, 'h2000, (len - 1), axburst_incr, user1);
|
|
master.i_wr_addr.enq (wa);
|
|
|
|
f_len.enq (len);
|
|
rg_idle_count <= 0;
|
|
rg_test <= 100;
|
|
|
|
$display ("%0d: master.rl_wr_burst_addr_1: ", cur_cycle);
|
|
$display (" ", fshow (wa));
|
|
endrule
|
|
|
|
rule rl_wr_data;
|
|
let data = 'h1_0000 + zeroExtend (rg_beat);
|
|
let wd = fv_mk_wr_data (data, user1);
|
|
master.i_wr_data.enq (wd);
|
|
rg_idle_count <= 0;
|
|
|
|
if (rg_beat < f_len.first - 1)
|
|
rg_beat <= rg_beat + 1;
|
|
else begin
|
|
rg_beat <= 0;
|
|
f_len.deq;
|
|
|
|
rg_test <= '1;
|
|
end
|
|
|
|
$display ("%0d: master.rl_wr_data: ", cur_cycle);
|
|
$display (" ", fshow (wd));
|
|
endrule
|
|
|
|
// ----------------
|
|
// Read tests
|
|
|
|
rule rl_rd_single (rg_test == 2);
|
|
let ra = fv_mk_rd_addr (id1, 'h1000, 1, axburst_fixed, user1);
|
|
master.i_rd_addr.enq (ra);
|
|
rg_idle_count <= 0;
|
|
rg_test <= '1;
|
|
|
|
$display ("%0d: master.rd_single: ", cur_cycle);
|
|
$display (" ", fshow (ra));
|
|
endrule
|
|
|
|
rule rl_rd_burst_addr_0 (rg_test == 20);
|
|
Bit #(8) len = 2;
|
|
let ra = fv_mk_rd_addr (id1, 'h1000, (len - 1), axburst_incr, user1);
|
|
master.i_rd_addr.enq (ra);
|
|
|
|
rg_idle_count <= 0;
|
|
rg_test <= 21;
|
|
|
|
$display ("%0d: master.rl_rd_burst_addr_0: ", cur_cycle);
|
|
$display (" ", fshow (ra));
|
|
endrule
|
|
|
|
rule rl_rd_burst_addr_1 (rg_test == 21);
|
|
Bit #(8) len = 4;
|
|
let ra = fv_mk_rd_addr (id1, 'h2000, (len - 1), axburst_incr, user1);
|
|
master.i_rd_addr.enq (ra);
|
|
|
|
rg_idle_count <= 0;
|
|
rg_test <= 100;
|
|
|
|
$display ("%0d: master.rl_rd_burst_addr_1: ", cur_cycle);
|
|
$display (" ", fshow (ra));
|
|
endrule
|
|
|
|
// ================================================================
|
|
// Drain and display responses received by master
|
|
|
|
rule rl_wr_resps;
|
|
let wr_resp <- pop_o (master.o_wr_resp);
|
|
$display ("%0d: master: ", cur_cycle);
|
|
$display (" ", fshow (wr_resp));
|
|
rg_idle_count <= 0;
|
|
endrule
|
|
|
|
rule rl_rd_resps;
|
|
let rd_resp <- pop_o (master.o_rd_data);
|
|
$display ("%0d: master: ", cur_cycle);
|
|
$display (" ", fshow (rd_resp));
|
|
rg_idle_count <= 0;
|
|
endrule
|
|
|
|
// ================================================================
|
|
// Slave: return functional responses
|
|
// Note: we should not be receiving any bursts, since we're fronted by the Deburster.
|
|
|
|
rule rl_slave_IP_model_writes;
|
|
$display ("%0d: %m.rl_slave_IP_model_writes: ", cur_cycle);
|
|
|
|
let wa <- pop_o (slave.o_wr_addr);
|
|
let wd <- pop_o (slave.o_wr_data);
|
|
|
|
let wr = fv_mk_wr_resp (wa);
|
|
slave.i_wr_resp.enq (wr);
|
|
$display (" ", fshow (wa));
|
|
$display (" ", fshow (wd));
|
|
$display (" ", fshow (wr));
|
|
endrule
|
|
|
|
rule rl_slave_IP_model_rd_addr;
|
|
let ra <- pop_o (slave.o_rd_addr);
|
|
slave.i_rd_data.enq (fv_mk_rd_data (ra));
|
|
|
|
$display ("%0d: slave: ", cur_cycle);
|
|
$display (" ", fshow (ra));
|
|
endrule
|
|
|
|
// ================================================================
|
|
|
|
rule rl_idle_quit;
|
|
if (rg_idle_count == 100) begin
|
|
$display ("%0d: UnitTest_Deburster: idle; quit", cur_cycle);
|
|
$finish (0);
|
|
end
|
|
else begin
|
|
rg_idle_count <= rg_idle_count + 1;
|
|
end
|
|
endrule
|
|
|
|
endmodule
|
|
|
|
// ================================================================
|
|
|
|
endpackage
|