Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TB] Fast Preload of binary for fast debug #57

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 <[email protected]>
// Christopher Reinwardt <[email protected]>

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_address;
static doub_bt write_data;
write_address = addr;
write_data = data;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be automatic or not decorated instead of static

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using automatic variable leads to compilation error that it is not allowed in the force statement.

force fix.dut.i_memisland_domain.i_memory_island.i_memory_island.narrow_addr_i[1] = write_address;
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_elf_halt();
// Preload the binary through FAST PRELOAD
fast_elf_preload(preload_elf);
// Unhalt the core
fix.vip.jtag_elf_unhalt();
// 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_elf_halt();
arpansur marked this conversation as resolved.
Show resolved Hide resolved
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_elf_unhalt();
arpansur marked this conversation as resolved.
Show resolved Hide resolved
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
Loading