Files
Toooba/src_Testbench/Fabrics/AXI4/Unit_Test/Unit_Test_Deburster.bsv
rsnikhil 83829590dd Fixed up logic for "Non-Debug-Module reset" request/response from the Debug Module
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
2020-02-04 16:02:53 -05:00

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