Skip to content

Commit

Permalink
tb: Add SL, JTAG and fast preload for pulpd
Browse files Browse the repository at this point in the history
  • Loading branch information
alex96295 committed Oct 14, 2023
1 parent f26c0eb commit e8a5aeb
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 14 deletions.
14 changes: 12 additions & 2 deletions carfield.mk
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ SPATZD_BENDER_DIR ?= $(shell which $(BENDER))
# Default variable values for RTL simulation
TBENCH ?= tb_carfield_soc

# Defines for hyperram model preload at time 0
HYP_USER_PRELOAD ?= 0
HYP0_PRELOAD_MEM_FILE ?= ""
HYP1_PRELOAD_MEM_FILE ?= ""

RUNTIME_DEFINES := +define+HYP_USER_PRELOAD=$(HYP_USER_PRELOAD)
RUNTIME_DEFINES += +define+HYP0_PRELOAD_MEM_FILE=$(HYP0_PRELOAD_MEM_FILE)
RUNTIME_DEFINES += +define+HYP1_PRELOAD_MEM_FILE=$(HYP1_PRELOAD_MEM_FILE)

# Include bender targets and defines for common usage and synth verification
# (the following includes are mandatory)
include $(CAR_ROOT)/bender-common.mk
Expand Down Expand Up @@ -174,7 +183,7 @@ $(CAR_ROOT)/tb/hyp_vip:

.PHONY: scripts/carfield_compile.tcl
scripts/carfield_compile.tcl:
$(BENDER) script vsim $(common_targs) $(sim_targs) $(common_defs) $(safed_defs) --vlog-arg="$(VLOG_ARGS)" --compilation-mode separate > $@
$(BENDER) script vsim $(common_targs) $(sim_targs) $(common_defs) $(safed_defs) --vlog-arg="$(VLOG_ARGS) $(RUNTIME_DEFINES)" --compilation-mode separate > $@
echo 'vlog "$(CHS_ROOT)/target/sim/src/elfloader.cpp" -ccflags "-std=c++11"' >> $@
echo 'vopt $(VOPT_FLAGS) $(TBENCH) -o $(TBENCH)_opt' >> $@

Expand All @@ -197,7 +206,8 @@ car-hw-build: car-sim-init
## @param VSIM_FLAGS the flags for the vsim invocation
car-hw-sim:
$(QUESTA) vsim $(VSIM_FLAGS) -do \
"set SECURE_BOOT $(SECURE_BOOT); \
"set HYP_USER_PRELOAD $(HYP_USER_PRELOAD); \
set SECURE_BOOT $(SECURE_BOOT); \
set CHS_BOOTMODE $(CHS_BOOTMODE); \
set CHS_PRELMODE $(CHS_PRELMODE); \
set CHS_BINARY $(CHS_BINARY); \
Expand Down
1 change: 1 addition & 0 deletions scripts/start_carfield.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set flags ""
if {[info exists VSIM_FLAGS]} { append flags "${VSIM_FLAGS}" }

set pargs ""
if {[info exists HYP_USER_PRELOAD]} { append pargs "+HYP_USER_PRELOAD=${HYP_USER_PRELOAD} " }
if {[info exists SECURE_BOOT]} { append pargs "+SECURE_BOOT=${SECURE_BOOT} " }
if {[info exists CHS_BOOTMODE]} { append pargs "+CHS_BOOTMODE=${CHS_BOOTMODE} " }
if {[info exists CHS_PRELMODE]} { append pargs "+CHS_PRELMODE=${CHS_PRELMODE} " }
Expand Down
12 changes: 9 additions & 3 deletions tb/carfield_fix.sv
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,14 @@ module carfield_soc_fixture;

// Verification IPs for carfield
vip_carfield_soc #(
.DutCfg ( DutCfg ),
.DutCfg ( DutCfg ),
// Determine whether we preload the hyperram model or not User preload. If 0, the memory model
// is not preloaded at time 0.
.HypUserPreload ( `HYP_USER_PRELOAD ),
// Mem files for hyperram model. The argument is considered only if HypUserPreload==1 in the
// memory model.
.Hyp0UserPreloadMemFile ( `HYP0_PRELOAD_MEM_FILE ),
.Hyp1UserPreloadMemFile ( `HYP1_PRELOAD_MEM_FILE ),
.ClkPeriodSys ( ClkPeriodSys ),
.ClkPeriodJtag ( ClkPeriodJtag ),
.ClkPeriodRtc ( ClkPeriodRtc),
Expand All @@ -257,8 +264,7 @@ module carfield_soc_fixture;
// We use the clock/reset generated in cheshire VIP
.clk_vip (),
.rst_n_vip (),
// Multiplex incoming AXI req/rsp and convert t
// hrough serial link
// Multiplex incoming AXI req/rsp and convert through serial link
.axi_slvs_req ( ext_to_vip_req ),
.axi_slvs_rsp ( ext_to_vip_rsp ),
.axi_muxed_req ( axi_muxed_req ),
Expand Down
134 changes: 130 additions & 4 deletions tb/carfield_tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,37 @@ module tb_carfield_soc;
// hyperbus
localparam int unsigned HyperbusTburstMax = 32'h20009008;

// FP Spatz Cluster
// spatz cluster
string spatzd_preload_elf;
logic [1:0] spatzd_boot_mode;
bit [31:0] spatzd_exit_code;
bit spatzd_exit_status;
doub_bt spatzd_binary_entry;
doub_bt spatzd_reg_value;

localparam int unsigned SpatzdClkEnRegAddr = 32'h2001007c;
localparam int unsigned SpatzdIsolateRegAddr = 32'h2001004c;
localparam int unsigned SpatzdIsolateStatusRegAddr = 32'h20010064;

// MailBox
// pulp cluster
// Useful register addresses
localparam int unsigned CarL2StartAddr = 32'h7800_0000;
localparam int unsigned CarDramStartAddr = 32'h8000_0000;
localparam int unsigned PulpdNumCores = 4;
localparam int unsigned PulpdBootAddrL2 = CarL2StartAddr + 32'h8080;
localparam int unsigned PulpdBootAddrDram = CarDramStartAddr + 32'h8080;
localparam int unsigned PulpdBootAddr = 32'h50200040;
localparam int unsigned CarSocCtrlPulpdFetchEnAddr = 32'h200100c0;
localparam int unsigned CarSocCtrlPulpdBootEnAddr = 32'h200100dc;
localparam int unsigned CarSocCtrlPulpdBusyAddr = 32'h200100e4;
localparam int unsigned CarSocCtrlPulpdEocAddr = 32'h200100e8;
// sim variables
string pulpd_preload_elf;
logic [1:0] pulpd_boot_mode;
bit [31:0] pulpd_exit_code;
doub_bt pulpd_binary_entry;
doub_bt pulpd_reg_value;

// mailbox unit
parameter logic [31:0] CAR_MBOX_BASE = 32'h40000000;
parameter logic [31:0] CAR_NUM_MAILBOXES = 32'h25;
parameter logic [31:0] MBOX_INT_SND_STAT_OFFSET = 32'h00;
Expand All @@ -81,6 +99,9 @@ module tb_carfield_soc;

logic secure_boot;

// Decide whether to preload hyperram model at time 0
logic hyp_user_preload;

// timing format for $display("...$t..", $realtime)
initial begin : timing_format
$timeformat(-9, 0, "ns", 9);
Expand Down Expand Up @@ -137,6 +158,7 @@ module tb_carfield_soc;
fix.chs_vip.uart_debug_elf_run_and_wait(chs_preload_elf, exit_code);
end 3: begin // Secure boot: Opentitan booting CVA6
fix.chs_vip.slink_elf_preload(chs_preload_elf, unused);
// We check the EOC with the JTAG
fix.chs_vip.jtag_init();
fix.chs_vip.jtag_wait_for_eoc(exit_code);
end default: begin
Expand Down Expand Up @@ -254,7 +276,110 @@ module tb_carfield_soc;
end

// pulp cluster standalone
// TODO
initial begin
// Fetch plusargs or use safe (fail-fast) defaults
if (!$value$plusargs("PULPD_BOOTMODE=%d", pulpd_boot_mode)) pulpd_boot_mode = 0;
if (!$value$plusargs("PULPD_BINARY=%s", pulpd_preload_elf)) pulpd_preload_elf = "";
if (!$value$plusargs("HYP_USER_PRELOAD=%s", hyp_user_preload)) hyp_user_preload = 0;

// Wait for reset
fix.chs_vip.wait_for_reset();

if (pulpd_preload_elf != "") begin
case (pulpd_boot_mode)
0: begin
// JTAG
$display("[JTAG PULPD] Init ");
fix.chs_vip.jtag_init();
$display("[JTAG PULPD] Halt the core and load the binary to L2 ");
fix.chs_vip.jtag_elf_halt_load(pulpd_preload_elf, pulpd_binary_entry );

// boot
// Write bootaddress to each core
$display("[SLINK PULPD] Write PULP cluster boot address for each core");
for (int c = 0; c < PulpdNumCores; c++) begin
fix.chs_vip.jtag_write_reg32(PulpdBootAddrL2, c*32'h4 + PulpdBootAddrDram);
end
// Write boot enable
$display("[SLINK PULPD] Write PULP cluster boot enable");
fix.chs_vip.jtag_write_reg32(CarSocCtrlPulpdBootEnAddr, 32'h1);
// Write fetch enable
$display("[SLINK PULPD] Write PULP cluster fetch enable");
fix.chs_vip.jtag_write_reg32(CarSocCtrlPulpdFetchEnAddr, 32'h1);

// Poll memory address for PULP EOC
fix.chs_vip.jtag_poll_bit0(CarSocCtrlPulpdEocAddr, pulpd_exit_code, 20);
pulpd_exit_code >>= 1;
if (pulpd_exit_code) $error("[JTAG PULP] FAILED: return code %0d", pulpd_exit_code);
else $display("[JTAG PULP] SUCCESS");
end

1: begin
// serial link

// preload
$display("[SLINK PULPD] Preload the binary to L2 ");
fix.chs_vip.slink_elf_preload(pulpd_preload_elf, pulpd_binary_entry);

// boot
// Write bootaddress to each core
$display("[SLINK PULPD] Write PULP cluster boot address for each core");
for (int c = 0; c < PulpdNumCores; c++) begin
fix.chs_vip.slink_write_32(PulpdBootAddrL2, c*32'h4 + PulpdBootAddrDram);
end
// Write boot enable
$display("[SLINK PULPD] Write PULP cluster boot enable");
fix.chs_vip.slink_write_32(CarSocCtrlPulpdBootEnAddr, 32'h1);
// Write fetch enable
$display("[SLINK PULPD] Write PULP cluster fetch enable");
fix.chs_vip.slink_write_32(CarSocCtrlPulpdFetchEnAddr, 32'h1);

// Poll memory address for PULP EOC
fix.chs_vip.slink_poll_bit0(CarSocCtrlPulpdEocAddr, pulpd_exit_code, 20);
pulpd_exit_code >>= 1;
if (pulpd_exit_code) $error("[SLINK PULP] FAILED: return code %0d", pulpd_exit_code);
else $display("[SLINK PULP] SUCCESS");
end
default: begin
$fatal(1, "Unsupported boot mode %d (reserved)!", pulpd_boot_mode);
end
endcase

$finish;
end

// Fast preload of hyperram
if (hyp_user_preload != 0 && pulpd_preload_elf == "") begin
$warning( "[TB] - Instantly preload hyperram0 and hyperrram1 models at time 0. This preload \
mode should be used for simulation only, because it does not check whether we can \
preload the hyperram using physical interfaces, e.g., JTAG or SL. If there is enough \
confidence physical interfaces are working correctly with a gate-level netlist, this \
mode could be used to speed up the simulation, but at your own risk. You were \
warned. \n");
// Hyperrams models are preloaded at time 0. Preferably, this bootflow is used with cluster
// accelerators, but can be extended to other islands as well. We check the EOC with the JTAG

// Write bootaddress to each core
$display("[SLINK PULPD] Write PULP cluster boot address for each core");
for (int c = 0; c < PulpdNumCores; c++) begin
fix.chs_vip.slink_write_32(PulpdBootAddrL2, c*32'h4 + PulpdBootAddrDram);
end
// Write boot enable
$display("[SLINK PULPD] Write PULP cluster boot enable");
fix.chs_vip.slink_write_32(CarSocCtrlPulpdBootEnAddr, 32'h1);
// Write fetch enable
$display("[SLINK PULPD] Write PULP cluster fetch enable");
fix.chs_vip.slink_write_32(CarSocCtrlPulpdFetchEnAddr, 32'h1);

// Poll memory address for PULP EOC
fix.chs_vip.slink_poll_bit0(CarSocCtrlPulpdEocAddr, pulpd_exit_code, 20);
pulpd_exit_code >>= 1;
if (pulpd_exit_code) $error("[SLINK PULP] FAILED: return code %0d", pulpd_exit_code);
else $display("[SLINK PULP] SUCCESS");

$finish;
end
end

// spatz cluster standalone
initial begin
Expand Down Expand Up @@ -352,6 +477,7 @@ module tb_carfield_soc;
$fatal(1, "Unsupported boot mode %d (reserved)!", spatzd_boot_mode);
end
endcase

$finish;
end
end
Expand Down
16 changes: 11 additions & 5 deletions tb/vip_carfield_soc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ module vip_carfield_soc
parameter cheshire_cfg_t DutCfg = carfield_pkg::CarfieldCfgDefault,
parameter type axi_slv_ext_req_t = logic,
parameter type axi_slv_ext_rsp_t = logic,
parameter int unsigned HypNumPhys = 2,
parameter int unsigned HypNumChips = 2,
parameter int unsigned HypNumPhys = 2,
parameter int unsigned HypNumChips = 2,
parameter int unsigned HypUserPreload = 0,
parameter string Hyp0UserPreloadMemFile = "",
parameter string Hyp1UserPreloadMemFile = "",
// Timing
parameter time ClkPeriodSys = 5ns,
parameter time ClkPeriodJtag = 20ns,
Expand Down Expand Up @@ -77,11 +80,14 @@ module vip_carfield_soc
// Hyperbus //
//////////////

localparam string HypUserPreloadMemFiles [HypNumPhys] = '{Hyp0UserPreloadMemFile, Hyp1UserPreloadMemFile};

for (genvar i=0; i<HypNumPhys; i++) begin : hyperrams
for (genvar j=0; j<HypNumChips; j++) begin : chips
s27ks0641 #(
/*.mem_file_name ( "s27ks0641.mem" ),*/
.TimingModel ( "S27KS0641DPBHI020" )
.UserPreload ( HypUserPreload ),
.mem_file_name ( HypUserPreloadMemFiles[i] ),
.TimingModel ( "S27KS0641DPBHI020" )
) dut (
.DQ7 ( pad_hyper_dq[i][7] ),
.DQ6 ( pad_hyper_dq[i][6] ),
Expand All @@ -95,7 +101,7 @@ module vip_carfield_soc
.CSNeg ( pad_hyper_csn[i][j] ),
.CK ( pad_hyper_ck[i] ),
.CKNeg ( pad_hyper_ckn[i] ),
.RESETNeg ( pad_hyper_resetn[i] )
.RESETNeg ( pad_hyper_resetn[i] )
);
end
end
Expand Down

0 comments on commit e8a5aeb

Please sign in to comment.