summaryrefslogtreecommitdiff
path: root/tb
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-09-30 17:44:26 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-01 01:04:19 -0600
commitcf6ab851183870bca61252a56b274342380d0960 (patch)
tree96c08231d60d300788462b17549d5120802e7f32 /tb
parentd1b10aa380578b5af20081dd37f2d36ec111cbd2 (diff)
tb: implement quad-core SMP
Diffstat (limited to '')
-rw-r--r--tb/mem_interconnect.sv152
-rw-r--r--tb/platform.sv318
-rw-r--r--tb/top/conspiracion.cpp198
3 files changed, 420 insertions, 248 deletions
diff --git a/tb/mem_interconnect.sv b/tb/mem_interconnect.sv
new file mode 100644
index 0000000..e947568
--- /dev/null
+++ b/tb/mem_interconnect.sv
@@ -0,0 +1,152 @@
+module mem_interconnect
+(
+ input logic clk,
+ rst_n,
+
+ input logic avl_waitrequest,
+ input logic[127:0] avl_readdata,
+ output logic[31:0] avl_address,
+ output logic avl_read,
+ avl_write,
+ output logic[127:0] avl_writedata,
+ output logic[15:0] avl_byteenable,
+
+ input logic[31:0] mem_0_address,
+ mem_1_address,
+ mem_2_address,
+ mem_3_address,
+ input logic mem_0_read,
+ mem_1_read,
+ mem_2_read,
+ mem_3_read,
+ mem_0_write,
+ mem_1_write,
+ mem_2_write,
+ mem_3_write,
+ input logic[127:0] mem_0_writedata,
+ mem_1_writedata,
+ mem_2_writedata,
+ mem_3_writedata,
+ input logic[15:0] mem_0_byteenable,
+ mem_1_byteenable,
+ mem_2_byteenable,
+ mem_3_byteenable,
+ output logic mem_0_waitrequest,
+ mem_1_waitrequest,
+ mem_2_waitrequest,
+ mem_3_waitrequest,
+ output logic[127:0] mem_0_readdata,
+ mem_1_readdata,
+ mem_2_readdata,
+ mem_3_readdata
+);
+
+ logic last_hold;
+ logic[1:0] last_select, select;
+
+ assign mem_0_readdata = avl_readdata;
+ assign mem_1_readdata = avl_readdata;
+ assign mem_2_readdata = avl_readdata;
+ assign mem_3_readdata = avl_readdata;
+
+ always_comb begin
+ // Arbitraje round-robin
+ unique case (last_select)
+ 2'd0:
+ if (mem_1_read || mem_1_write)
+ select = 2'd1;
+ else if (mem_2_read || mem_2_write)
+ select = 2'd2;
+ else if (mem_3_read || mem_3_write)
+ select = 2'd3;
+ else
+ select = 2'd0;
+
+ 2'd1:
+ if (mem_2_read || mem_2_write)
+ select = 2'd2;
+ else if (mem_3_read || mem_3_write)
+ select = 2'd3;
+ else if (mem_0_read || mem_0_write)
+ select = 2'd0;
+ else
+ select = 2'd1;
+
+ 2'd2:
+ if (mem_3_read || mem_3_write)
+ select = 2'd3;
+ else if (mem_0_read || mem_0_write)
+ select = 2'd0;
+ else if (mem_1_read || mem_1_write)
+ select = 2'd1;
+ else
+ select = 2'd2;
+
+ 2'd3:
+ if (mem_0_read || mem_0_write)
+ select = 2'd0;
+ else if (mem_1_read || mem_1_write)
+ select = 2'd1;
+ else if (mem_2_read || mem_2_write)
+ select = 2'd2;
+ else
+ select = 2'd3;
+ endcase
+
+ if (last_hold)
+ select = last_select;
+
+ mem_0_waitrequest = 1;
+ mem_1_waitrequest = 1;
+ mem_2_waitrequest = 1;
+ mem_3_waitrequest = 1;
+
+ unique case (select)
+ 2'd0: begin
+ avl_read = mem_0_read;
+ avl_write = mem_0_write;
+ avl_address = mem_0_address;
+ avl_writedata = mem_0_writedata;
+ avl_byteenable = mem_0_byteenable;
+ mem_0_waitrequest = avl_waitrequest;
+ end
+
+ 2'd1: begin
+ avl_read = mem_1_read;
+ avl_write = mem_1_write;
+ avl_address = mem_1_address;
+ avl_writedata = mem_1_writedata;
+ avl_byteenable = mem_1_byteenable;
+ mem_1_waitrequest = avl_waitrequest;
+ end
+
+ 2'd2: begin
+ avl_read = mem_2_read;
+ avl_write = mem_2_write;
+ avl_address = mem_2_address;
+ avl_writedata = mem_2_writedata;
+ avl_byteenable = mem_2_byteenable;
+ mem_2_waitrequest = avl_waitrequest;
+ end
+
+ 2'd3: begin
+ avl_read = mem_3_read;
+ avl_write = mem_3_write;
+ avl_address = mem_3_address;
+ avl_writedata = mem_3_writedata;
+ avl_byteenable = mem_3_byteenable;
+ mem_3_waitrequest = avl_waitrequest;
+ end
+ endcase
+ end
+
+ always @(posedge clk or negedge rst_n)
+ if (!rst_n) begin
+ last_hold <= 1;
+ last_select <= 2'd0;
+ end else begin
+ last_hold <= (avl_read || avl_write) && avl_waitrequest;
+ last_select <= select;
+ end
+
+endmodule
diff --git a/tb/platform.sv b/tb/platform.sv
index c729b56..79df2a8 100644
--- a/tb/platform.sv
+++ b/tb/platform.sv
@@ -4,10 +4,6 @@ module platform
(
input wire [7:0] buttons_external_connection_export, // buttons_external_connection.export
input wire clk_clk, // clk.clk
- input wire cpu_0_mp_step, // cpu_0_mp.step
- input wire cpu_0_mp_cpu_halt, // .cpu_halt
- output wire cpu_0_mp_cpu_halted, // .cpu_halted
- output wire cpu_0_mp_breakpoint, // .breakpoint
output wire [12:0] memory_mem_a, // memory.mem_a
output wire [2:0] memory_mem_ba, // .mem_ba
output wire memory_mem_ck, // .mem_ck
@@ -48,6 +44,10 @@ module platform
output wire vram_wire_we_n // .we_n
);
+ logic clk, rst_n;
+ assign clk = clk_clk;
+ assign rst_n = reset_reset_n;
+
logic[31:0] avl_address /*verilator public*/;
logic avl_read /*verilator public*/;
logic avl_write /*verilator public*/;
@@ -57,29 +57,86 @@ module platform
logic avl_waitrequest /*verilator public_flat_rw @(negedge clk_clk)*/;
logic[15:0] avl_byteenable /*verilator public*/;
- logic[31:0] core_avl_address;
- logic core_avl_read;
- logic core_avl_write;
- logic[31:0] core_avl_readdata;
- logic[31:0] core_avl_writedata;
- logic core_avl_waitrequest;
- logic[3:0] core_avl_byteenable;
+ logic[31:0] mem_0_address, mem_1_address, mem_2_address, mem_3_address;
+ logic mem_0_read, mem_1_read, mem_2_read, mem_3_read;
+ logic mem_0_write, mem_1_write, mem_2_write, mem_3_write;
+ logic[127:0] mem_0_readdata, mem_1_readdata, mem_2_readdata, mem_3_readdata;
+ logic[127:0] mem_0_writedata, mem_1_writedata, mem_2_writedata, mem_3_writedata;
+ logic mem_0_waitrequest, mem_1_waitrequest, mem_2_waitrequest, mem_3_waitrequest;
+ logic[15:0] mem_0_byteenable, mem_1_byteenable, mem_2_byteenable, mem_3_byteenable;
+
+ logic[31:0] cpu_0_address, cpu_1_address, cpu_2_address, cpu_3_address;
+ logic cpu_0_read, cpu_1_read, cpu_2_read, cpu_3_read;
+ logic cpu_0_write, cpu_1_write, cpu_2_write, cpu_3_write;
+ logic[31:0] cpu_0_readdata, cpu_1_readdata, cpu_2_readdata, cpu_3_readdata;
+ logic[31:0] cpu_0_writedata, cpu_1_writedata, cpu_2_writedata, cpu_3_writedata;
+ logic cpu_0_waitrequest, cpu_1_waitrequest, cpu_2_waitrequest, cpu_3_waitrequest;
+ logic[3:0] cpu_0_byteenable, cpu_1_byteenable, cpu_2_byteenable, cpu_3_byteenable;
+
+ core cpu_0
+ (
+ .step(step_0),
+ .breakpoint(breakpoint_0),
+ .cpu_halt(halt_0),
+ .cpu_halted(cpu_halted_0),
+ .avl_address(cpu_0_address),
+ .avl_read(cpu_0_read),
+ .avl_write(cpu_0_write),
+ .avl_readdata(cpu_0_readdata),
+ .avl_writedata(cpu_0_writedata),
+ .avl_waitrequest(cpu_0_waitrequest),
+ .avl_byteenable(cpu_0_byteenable),
+ .*
+ );
+
+ core cpu_1
+ (
+ .step(step_1),
+ .breakpoint(breakpoint_1),
+ .cpu_halt(halt_1),
+ .cpu_halted(cpu_halted_1),
+ .avl_address(cpu_1_address),
+ .avl_read(cpu_1_read),
+ .avl_write(cpu_1_write),
+ .avl_readdata(cpu_1_readdata),
+ .avl_writedata(cpu_1_writedata),
+ .avl_waitrequest(cpu_1_waitrequest),
+ .avl_byteenable(cpu_1_byteenable),
+ .avl_irq(0),
+ .*
+ );
+
+ core cpu_2
+ (
+ .step(step_2),
+ .breakpoint(breakpoint_2),
+ .cpu_halt(halt_2),
+ .cpu_halted(cpu_halted_2),
+ .avl_address(cpu_2_address),
+ .avl_read(cpu_2_read),
+ .avl_write(cpu_2_write),
+ .avl_readdata(cpu_2_readdata),
+ .avl_writedata(cpu_2_writedata),
+ .avl_waitrequest(cpu_2_waitrequest),
+ .avl_byteenable(cpu_2_byteenable),
+ .avl_irq(0),
+ .*
+ );
- core cpu0
+ core cpu_3
(
- .clk(clk_clk),
- .rst_n(reset_reset_n),
- .step(cpu_0_mp_step),
- .breakpoint(cpu_0_mp_breakpoint),
- .cpu_halt(cpu_0_mp_cpu_halt),
- .cpu_halted(cpu_0_mp_cpu_halted),
- .avl_address(core_avl_address),
- .avl_read(core_avl_read),
- .avl_write(core_avl_write),
- .avl_readdata(core_avl_readdata),
- .avl_writedata(core_avl_writedata),
- .avl_waitrequest(core_avl_waitrequest),
- .avl_byteenable(core_avl_byteenable),
+ .step(step_3),
+ .breakpoint(breakpoint_3),
+ .cpu_halt(halt_3),
+ .cpu_halted(cpu_halted_3),
+ .avl_address(cpu_3_address),
+ .avl_read(cpu_3_read),
+ .avl_write(cpu_3_write),
+ .avl_readdata(cpu_3_readdata),
+ .avl_writedata(cpu_3_writedata),
+ .avl_waitrequest(cpu_3_waitrequest),
+ .avl_byteenable(cpu_3_byteenable),
+ .avl_irq(0),
.*
);
@@ -95,32 +152,23 @@ module platform
data_ready_0, data_ready_1, data_ready_2, data_ready_3,
token_valid_0, token_valid_1, token_valid_2, token_valid_3;
- cache #(.TOKEN_AT_RESET(0)) cache0
+ cache cache_0
(
- .clk(clk_clk),
- .rst_n(reset_reset_n),
- .core_address(core_avl_address[31:2]),
- .core_read(core_avl_read),
- .core_write(core_avl_write),
- .core_writedata(core_avl_writedata),
- .core_byteenable(core_avl_byteenable),
- .core_waitrequest(core_avl_waitrequest),
- .core_readdata(core_avl_readdata),
-
- //.dbg_address(),
- .dbg_read(0),
- .dbg_write(0),
- .dbg_writedata(),
- .dbg_waitrequest(),
- .dbg_readdata(),
-
- .mem_waitrequest(avl_waitrequest),
- .mem_readdata(avl_readdata),
- .mem_address(avl_address),
- .mem_read(avl_read),
- .mem_write(avl_write),
- .mem_writedata(avl_writedata),
- .mem_byteenable(avl_byteenable),
+ .core_address(cpu_0_address[31:2]),
+ .core_read(cpu_0_read),
+ .core_write(cpu_0_write),
+ .core_writedata(cpu_0_writedata),
+ .core_byteenable(cpu_0_byteenable),
+ .core_waitrequest(cpu_0_waitrequest),
+ .core_readdata(cpu_0_readdata),
+
+ .mem_waitrequest(mem_0_waitrequest),
+ .mem_readdata(mem_0_readdata),
+ .mem_address(mem_0_address),
+ .mem_read(mem_0_read),
+ .mem_write(mem_0_write),
+ .mem_writedata(mem_0_writedata),
+ .mem_byteenable(mem_0_byteenable),
.in_data_valid(data_valid_3),
.in_data(data_3),
@@ -134,35 +182,28 @@ module platform
.in_token_valid(token_valid_3),
.out_token(token_0),
- .out_token_valid(token_valid_0)
+ .out_token_valid(token_valid_0),
+
+ .*
);
- cache #(.TOKEN_AT_RESET(0)) cache1
+ cache cache_1
(
- .clk(clk_clk),
- .rst_n(reset_reset_n),
- .core_address(),
- .core_read(0),
- .core_write(0),
- .core_writedata(),
- .core_byteenable(),
- .core_waitrequest(),
- .core_readdata(),
-
- //.dbg_address(),
- .dbg_read(0),
- .dbg_write(0),
- .dbg_writedata(),
- .dbg_waitrequest(),
- .dbg_readdata(),
-
- .mem_waitrequest(1),
- .mem_readdata(),
- .mem_address(),
- .mem_read(),
- .mem_write(),
- .mem_writedata(),
- .mem_byteenable(),
+ .core_address(cpu_1_address[31:2]),
+ .core_read(cpu_1_read),
+ .core_write(cpu_1_write),
+ .core_writedata(cpu_1_writedata),
+ .core_byteenable(cpu_1_byteenable),
+ .core_waitrequest(cpu_1_waitrequest),
+ .core_readdata(cpu_1_readdata),
+
+ .mem_waitrequest(mem_1_waitrequest),
+ .mem_readdata(mem_1_readdata),
+ .mem_address(mem_1_address),
+ .mem_read(mem_1_read),
+ .mem_write(mem_1_write),
+ .mem_writedata(mem_1_writedata),
+ .mem_byteenable(mem_1_byteenable),
.in_data_valid(data_valid_0),
.in_data(data_0),
@@ -176,35 +217,28 @@ module platform
.in_token_valid(token_valid_0),
.out_token(token_1),
- .out_token_valid(token_valid_1)
+ .out_token_valid(token_valid_1),
+
+ .*
);
- cache #(.TOKEN_AT_RESET(0)) cache2
+ cache cache_2
(
- .clk(clk_clk),
- .rst_n(reset_reset_n),
- .core_address(),
- .core_read(0),
- .core_write(0),
- .core_writedata(),
- .core_byteenable(),
- .core_waitrequest(),
- .core_readdata(),
-
- //.dbg_address(),
- .dbg_read(0),
- .dbg_write(0),
- .dbg_writedata(),
- .dbg_waitrequest(),
- .dbg_readdata(),
-
- .mem_waitrequest(1),
- .mem_readdata(),
- .mem_address(),
- .mem_read(),
- .mem_write(),
- .mem_writedata(),
- .mem_byteenable(),
+ .core_address(cpu_2_address[31:2]),
+ .core_read(cpu_2_read),
+ .core_write(cpu_2_write),
+ .core_writedata(cpu_2_writedata),
+ .core_byteenable(cpu_2_byteenable),
+ .core_waitrequest(cpu_2_waitrequest),
+ .core_readdata(cpu_2_readdata),
+
+ .mem_waitrequest(mem_2_waitrequest),
+ .mem_readdata(mem_2_readdata),
+ .mem_address(mem_2_address),
+ .mem_read(mem_2_read),
+ .mem_write(mem_2_write),
+ .mem_writedata(mem_2_writedata),
+ .mem_byteenable(mem_2_byteenable),
.in_data_valid(data_valid_1),
.in_data(data_1),
@@ -218,35 +252,28 @@ module platform
.in_token_valid(token_valid_1),
.out_token(token_2),
- .out_token_valid(token_valid_2)
+ .out_token_valid(token_valid_2),
+
+ .*
);
- cache #(.TOKEN_AT_RESET(1)) cache3
+ cache #(.TOKEN_AT_RESET(1)) cache_3
(
- .clk(clk_clk),
- .rst_n(reset_reset_n),
- .core_address(),
- .core_read(0),
- .core_write(0),
- .core_writedata(),
- .core_byteenable(),
- .core_waitrequest(),
- .core_readdata(),
-
- //.dbg_address(),
- .dbg_read(0),
- .dbg_write(0),
- .dbg_writedata(),
- .dbg_waitrequest(),
- .dbg_readdata(),
-
- .mem_waitrequest(1),
- .mem_readdata(),
- .mem_address(),
- .mem_read(),
- .mem_write(),
- .mem_writedata(),
- .mem_byteenable(),
+ .core_address(cpu_3_address[31:2]),
+ .core_read(cpu_3_read),
+ .core_write(cpu_3_write),
+ .core_writedata(cpu_3_writedata),
+ .core_byteenable(cpu_3_byteenable),
+ .core_waitrequest(cpu_3_waitrequest),
+ .core_readdata(cpu_3_readdata),
+
+ .mem_waitrequest(mem_3_waitrequest),
+ .mem_readdata(mem_3_readdata),
+ .mem_address(mem_3_address),
+ .mem_read(mem_3_read),
+ .mem_write(mem_3_write),
+ .mem_writedata(mem_3_writedata),
+ .mem_byteenable(mem_3_byteenable),
.in_data_valid(data_valid_2),
.in_data(data_2),
@@ -260,36 +287,29 @@ module platform
.in_token_valid(token_valid_2),
.out_token(token_3),
- .out_token_valid(token_valid_3)
+ .out_token_valid(token_valid_3),
+
+ .*
);
+ logic step_0, step_1, step_2, step_3,
+ halt_0, halt_1, halt_2, halt_3,
+ breakpoint_0, breakpoint_1, breakpoint_2, breakpoint_3,
+ cpu_halted_0, cpu_halted_1, cpu_halted_2, cpu_halted_3;
+
smp_ctrl smp
(
- .clk(),
- .rst_n(),
-
.avl_read(0),
.avl_write(0),
.avl_writedata(),
.avl_readdata(),
- .cpu_halted_0(0),
- .cpu_halted_1(0),
- .cpu_halted_2(0),
- .cpu_halted_3(0),
- .breakpoint_0(0),
- .breakpoint_1(0),
- .breakpoint_2(0),
- .breakpoint_3(0),
-
- .halt_0(),
- .halt_1(),
- .halt_2(),
- .halt_3(),
- .step_0(),
- .step_1(),
- .step_2(),
- .step_3()
+ .*
+ );
+
+ mem_interconnect mem
+ (
+ .*
);
endmodule
diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp
index f12e17a..e28fcfc 100644
--- a/tb/top/conspiracion.cpp
+++ b/tb/top/conspiracion.cpp
@@ -396,11 +396,23 @@ int main(int argc, char **argv)
std::fclose(img_file);
}
- auto &core = *plat.cpu0->cpu;
- for(const auto &init : init_regs)
- {
- core.regs->a->file[init.index] = init.value;
- core.regs->b->file[init.index] = init.value;
+ Vconspiracion_arm810 *const cores[] = {
+ plat.cpu_0->cpu,
+ plat.cpu_1->cpu,
+ plat.cpu_2->cpu,
+ plat.cpu_3->cpu
+ };
+
+ Vconspiracion_cache_sram *const caches[] = {
+ plat.cache_0->sram,
+ plat.cache_1->sram,
+ plat.cache_2->sram,
+ plat.cache_3->sram
+ };
+
+ for (const auto &init : init_regs) {
+ cores[0]->regs->a->file[init.index] = init.value;
+ cores[0]->regs->b->file[init.index] = init.value;
}
int time = 0;
@@ -442,13 +454,17 @@ int main(int argc, char **argv)
tick();
};
- if(!no_tty)
- {
+ if (!no_tty)
ttyJ0.takeover();
+
+ for (auto *core : cores) {
+ // No toman efecto hasta que no se levante VforceEn
+ core->fetch->explicit_branch__VforceVal = 1;
+ core->halt__VforceVal = 1;
+ core->step__VforceVal = 1;
}
- top.step = 0;
- top.halt = start_halted;
+ cores[0]->halt__VforceEn = start_halted;
top.rst_n = 0;
cycle();
top.rst_n = 1;
@@ -457,13 +473,13 @@ int main(int argc, char **argv)
{
std::fputs("=== dump-regs ===\n", ctrl);
+ // TODO: cores[i]
+ const auto &core = *cores[0];
const auto &regfile = core.regs->a->file;
int i = 0;
- for(const auto *name : gp_regs)
- {
+ for (const auto *name : gp_regs)
std::fprintf(ctrl, "%08x %s\n", regfile[i++], name);
- }
std::fprintf(ctrl, "%08x pc\n", core.control->pc << 2);
std::fprintf(ctrl, "%08x cpsr\n", core.psr->cpsr_word);
@@ -484,13 +500,6 @@ int main(int argc, char **argv)
std::fputs("=== end-regs ===\n", ctrl);
};
- Vconspiracion_cache_sram *const caches[] = {
- plat.cache0->sram,
- plat.cache1->sram,
- plat.cache2->sram,
- plat.cache3->sram
- };
-
auto dump_coherent = [&](std::uint32_t addr, std::uint32_t &data)
{
bool ok = avl.dump(addr, data);
@@ -514,10 +523,10 @@ int main(int argc, char **argv)
auto pagewalk = [&](std::uint32_t &addr)
{
- if(!core.mmu->mmu_enable)
- {
+ // TODO: core[i]
+ const auto &core = *cores[0];
+ if (!core.mmu->mmu_enable)
return true;
- }
std::uint32_t ttbr = core.mmu->mmu_ttbr;
@@ -592,73 +601,77 @@ int main(int argc, char **argv)
std::signal(SIGUSR1, async_halt_handler);
- core.fetch->explicit_branch__VforceVal = 1;
-
auto maybe_halt = [&]()
{
- if(top.breakpoint || async_halt)
- {
- top.halt = 1;
+ bool has_halted = false;
+ for (auto *core : cores) {
+ if (core->breakpoint || async_halt)
+ core->halt__VforceEn = 1;
+
+ has_halted = has_halted || core->halt__VforceEn;
}
- return top.halt;
+ return has_halted;
};
auto loop_fast = [&]()
{
- do
- {
- for(unsigned iters = 0; iters < 1024 && !top.breakpoint; ++iters)
- {
+ do {
+ for (unsigned iters = 0; iters < 4096; ++iters) {
top.clk_clk = 0;
top.eval();
avl.tick_falling();
top.clk_clk = 1;
top.eval();
-
- // This is free most of the time
- try
- {
- avl.tick_rising();
- } catch(const avl_bus_error&)
- {
- failed = true;
- break;
- }
+ avl.tick_rising();
}
- } while(!maybe_halt());
+ } while (!maybe_halt());
};
unsigned i = 0;
auto loop_accurate = [&]()
{
- do
- {
+ do {
cycle();
maybe_halt();
- } while(!failed && !top.cpu_halted && (*cycles == 0 || ++i < *cycles));
+
+ for (const auto *core : cores)
+ if (core->halted)
+ break;
+ } while (!failed && (*cycles == 0 || ++i < *cycles));
};
const bool slow_path = *cycles > 0 || enable_accurate_video || enable_trace;
- while(true)
- {
- if(slow_path || top.halt || top.step)
- {
- loop_accurate();
- } else
- {
- loop_fast();
+ while (true) {
+ bool needs_accurate = false;
+ for (const auto *core : cores)
+ if (core->halt__VforceEn || core->step__VforceEn) {
+ needs_accurate = true;
+ break;
+ }
+
+ try {
+ if (slow_path || needs_accurate)
+ loop_accurate();
+ else
+ loop_fast();
+ } catch (const avl_bus_error&) {
+ failed = true;
+ break;
}
- if(failed || (*cycles > 0 && i >= *cycles))
- {
+ if (failed || (*cycles > 0 && i >= *cycles))
break;
+
+ for (auto *core : cores) {
+ core->fetch->target__VforceVal = core->control->pc;
+ core->step__VforceEn = 0;
}
- top.step = 0;
- core.fetch->target__VforceVal = core.control->pc;
+ // TODO: cores[i]
+ auto *current_core = cores[0];
do_reg_dump();
std::fprintf(ctrl, "=== %s ===\n", failed ? "fault" : "halted");
@@ -666,13 +679,10 @@ int main(int argc, char **argv)
char *line = nullptr;
std::size_t buf_size = 0;
- while(true)
- {
+ while (true) {
ssize_t read = getline(&line, &buf_size, ctrl);
- if(read == -1)
- {
- if(!std::feof(ctrl))
- {
+ if (read == -1) {
+ if (!std::feof(ctrl)) {
std::perror("getline()");
failed = true;
}
@@ -680,35 +690,28 @@ int main(int argc, char **argv)
break;
}
- if(read > 0 && line[read - 1] == '\n')
- {
+ if (read > 0 && line[read - 1] == '\n')
line[read - 1] = '\0';
- }
const char *cmd = std::strtok(line, " ");
- if(!std::strcmp(cmd, "continue"))
- {
+ if (!std::strcmp(cmd, "continue"))
break;
- } else if(!std::strcmp(cmd, "step"))
- {
- top.step = 1;
+ else if(!std::strcmp(cmd, "step")) {
+ current_core->step__VforceEn = 1;
break;
- } else if(!std::strcmp(cmd, "dump-mem"))
- {
+ } else if (!std::strcmp(cmd, "dump-mem")) {
mem_region dump = {};
std::sscanf(std::strtok(nullptr, " "), "%zu", &dump.start);
std::sscanf(std::strtok(nullptr, " "), "%zu", &dump.length);
do_mem_dump(&dump, 1);
- } else if(!std::strcmp(cmd, "patch-mem"))
- {
+ } else if (!std::strcmp(cmd, "patch-mem")) {
std::uint32_t addr;
std::sscanf(std::strtok(nullptr, " "), "%u", &addr);
const char *data = std::strtok(nullptr, " ");
std::size_t length = std::strlen(data);
- while(data && length >= 8)
- {
+ while (data && length >= 8) {
std::uint32_t word;
std::sscanf(data, "%08x", &word);
@@ -721,31 +724,24 @@ int main(int argc, char **argv)
| ((word >> 24) & 0xff);
std::uint32_t phys = addr++;
- if(!pagewalk(phys))
- {
+ if (!pagewalk(phys))
break;
- }
avl.patch(phys, word);
}
- } else if(!std::strcmp(cmd, "patch-reg"))
- {
+ } else if (!std::strcmp(cmd, "patch-reg")) {
std::uint32_t value;
std::sscanf(std::strtok(nullptr, " "), "%u", &value);
const char *name = std::strtok(nullptr, " ");
- if(!std::strcmp(name, "pc"))
- {
- core.fetch->target__VforceVal = value >> 2;
- } else
- {
+ if (!std::strcmp(name, "pc"))
+ current_core->fetch->target__VforceVal = value >> 2;
+ else {
std::size_t index = 0;
- for(const char *reg : gp_regs)
- {
- if(!strcmp(name, reg))
- {
- core.regs->a->file[index] = value;
- core.regs->b->file[index] = value;
+ for (const char *reg : gp_regs) {
+ if (!strcmp(name, reg)) {
+ current_core->regs->a->file[index] = value;
+ current_core->regs->b->file[index] = value;
break;
}
@@ -758,14 +754,18 @@ int main(int argc, char **argv)
std::free(line);
async_halt = 0;
- core.fetch->target__VforceEn = 0xffff'ffff;
- core.fetch->explicit_branch__VforceEn = 1;
+ for (auto *core : cores) {
+ core->fetch->target__VforceEn = 0xffff'ffff;
+ core->fetch->explicit_branch__VforceEn = 1;
+ }
cycle();
- top.halt = 0;
- core.fetch->target__VforceEn = 0;
- core.fetch->explicit_branch__VforceEn = 0;
+ for (auto *core : cores) {
+ core->fetch->target__VforceEn = 0;
+ core->fetch->explicit_branch__VforceEn = 0;
+ core->halt__VforceEn = 0;
+ }
}
if (!no_tty)