Skip to content

Commit

Permalink
Merge pull request #57 from pulp-platform/prasadar/fast_debug
Browse files Browse the repository at this point in the history
[TB] Fast Preload of binary for fast debug
  • Loading branch information
arpansur authored Dec 12, 2024
2 parents ba901e9 + 8f40e77 commit 68f54dc
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
82 changes: 80 additions & 2 deletions target/sim/src/tb_chimera_soc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
// Nicole Narr <narrn@student.ethz.ch>
// Christopher Reinwardt <creinwar@student.ethz.ch>

module tb_chimera_soc #(
module tb_chimera_soc
import cheshire_pkg::*;
#(
/// The selected simulation configuration from the `tb_chimera_pkg`.
parameter int unsigned SelectedCfg = 32'd0
);
Expand All @@ -17,11 +19,75 @@ module tb_chimera_soc #(
logic [ 1:0] boot_mode;
logic [ 1:0] preload_mode;
bit [31:0] exit_code;
import "DPI-C" function byte read_elf(input string filename);
import "DPI-C" function byte get_entry(output longint entry);
import "DPI-C" function byte get_section(
output longint address,
output longint len
);
import "DPI-C" context function byte read_section(
input longint address,
inout byte buffer [],
input longint len
);

// Load a binary
task automatic force_write(doub_bt addr, doub_bt data);
static doub_bt write_addr;
static doub_bt write_data;
write_addr = addr;
write_data = data;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_addr_i[1] = write_addr;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_req_i[1] = 1'b1;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_we_i[1] = 1'b1;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_wdata_i[1] = write_data;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_strb_i[1] = 4'hf;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_gnt_o[1] = 1'b0;
force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_rvalid_o[1] = 1'b0;
endtask


task automatic fast_elf_preload(input string binary);
longint sec_addr, sec_len;
$display("[FAST PRELOAD] Preloading ELF binary: %s", binary);
if (read_elf(binary)) $fatal(1, "[JTAG] Failed to load ELF!");
while (get_section(
sec_addr, sec_len
)) begin
byte bf[] = new[sec_len];
$display("[FAST PRELOAD] Preloading section at 0x%h (%0d bytes)", sec_addr, sec_len);
if (read_section(sec_addr, bf, sec_len))
$fatal(1, "[FAST PRELOAD] Failed to read ELF section!");
@(posedge fix.vip.soc_clk); //
for (longint i = 0; i <= sec_len; i += riscv::XLEN / 8) begin
bit checkpoint = (i != 0 && i % 512 == 0);
if (checkpoint)
$display(
"[FAST PRELOAD] - %0d/%0d bytes (%0d%%)",
i,
sec_len,
i * 100 / (sec_len > 1 ? sec_len - 1 : 1)
);
@(posedge fix.vip.soc_clk);
force_write((sec_addr + i), {bf[i+3], bf[i+2], bf[i+1], bf[i]});
end
end
@(posedge fix.vip.soc_clk);
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_addr_i[1];
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_req_i[1];
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_we_i[1];
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_wdata_i[1];
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_strb_i[1];
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_gnt_o[1];
release fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_rvalid_o[1];
// a few cycles safety margin after the end of transactions
repeat (3) @(posedge fix.vip.soc_clk);
endtask

initial begin
// Fetch plusargs or use safe (fail-fast) defaults
if (!$value$plusargs("BOOTMODE=%d", boot_mode)) boot_mode = 0;
if (!$value$plusargs("PRELMODE=%d", preload_mode)) preload_mode = 0;
if (!$value$plusargs("PRELMODE=%d", preload_mode)) preload_mode = 3;
if (!$value$plusargs("BINARY=%s", preload_elf)) preload_elf = "";
if (!$value$plusargs("IMAGE=%s", boot_hex)) boot_hex = "";

Expand All @@ -45,6 +111,18 @@ module tb_chimera_soc #(
2: begin // UART
fix.vip.uart_debug_elf_run_and_wait(preload_elf, exit_code);
end
3: begin // FAST DEBUG
// Initialize JTAG
fix.vip.jtag_init();
// Halt the core
fix.vip.jtag_halt_hart();
// Preload the binary through FAST PRELOAD
fast_elf_preload(preload_elf);
// Unhalt the core
fix.vip.jtag_resume_hart();
// Wait for the end of computation
fix.vip.jtag_wait_for_eoc(exit_code);
end
default: begin
$fatal(1, "Unsupported preload mode %d (reserved)!", boot_mode);
end
Expand Down
28 changes: 28 additions & 0 deletions target/sim/src/vip_chimera_soc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,34 @@ module vip_chimera_soc
jtag_elf_preload(binary, entry);
endtask

// Halt the core
task automatic jtag_halt_hart();
dm::dmstatus_t status;
// Halt hart 0
jtag_write(dm::DMControl, dm::dmcontrol_t'{haltreq: 1, dmactive: 1, default: '0});
do jtag_dbg.read_dmi_exp_backoff(dm::DMStatus, status); while (~status.allhalted);
repeat (2) @(posedge jtag_tck);
$display("[JTAG] Halted hart 0");
endtask

// Unhalt the core
task automatic jtag_resume_hart();
doub_bt entry;
repeat (2) @(posedge jtag_tck);
void'(get_entry(entry));
// Repoint execution
jtag_write(dm::Data1, entry[63:32]);
jtag_write(dm::Data0, entry[31:0]);
if (riscv::XLEN == 64) begin
jtag_write(dm::Command, 32'h0033_07b1, 0, 1);
end else begin
jtag_write(dm::Command, 32'h0023_07b1, 0, 1);
end
// Resume hart 0
jtag_write(dm::DMControl, dm::dmcontrol_t'{resumereq: 1, dmactive: 1, default: '0});
$display("[JTAG] Resumed hart 0 from 0x%h", entry);
endtask

// Run a binary
task automatic jtag_elf_run(input string binary);
doub_bt entry;
Expand Down

0 comments on commit 68f54dc

Please sign in to comment.