Skip to content

Commit

Permalink
User-defined boot of PULP Cluster from host core sw + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sermazz committed Jan 30, 2025
1 parent 6a36ca5 commit 319ee8b
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 29 deletions.
26 changes: 4 additions & 22 deletions hw/chimera_cluster.sv
Original file line number Diff line number Diff line change
Expand Up @@ -313,24 +313,6 @@ module chimera_cluster
.wide_mem_bypass_mode_i(widemem_bypass_i)
);

logic boot_en_q, boot_en_d;
logic fetch_en_q, fetch_en_d;

always_ff @(posedge clu_clk_i or negedge rst_ni) begin
boot_en_q <= 1'b0;
fetch_en_q <= 1'b0;
if (rst_ni && boot_en_d == 1 && fetch_en_d == 1) begin
boot_en_q <= 1'b1;
fetch_en_q <= 1'b1;
end
end

task automatic boot_cluster();
boot_en_d = 1;
#1;
fetch_en_d = 1;
endtask

////////////////////////////////////////////////////////////////////////

pulp_cluster #(
Expand All @@ -349,8 +331,8 @@ module chimera_cluster
.SHARED_ICACHE ( "ENABLED" ),
.DIRECT_MAPPED_FEATURE ( "DISABLED" ),
.L2_SIZE ( MemIslRegionEnd - MemIslRegionStart ),
.ROM_BOOT_ADDR ( 32'h48000180 ), //TODO: WIP to test offload
.BOOT_ADDR ( 32'h48000180 ), //TODO: WIP to test offload (not used if en_sa_boot_i is always 1)
.ROM_BOOT_ADDR ( 32'hAAAAAAAA ), //TODO: WIP to test offload
.BOOT_ADDR ( 32'hAAAAAAAA ), //TODO: WIP to test offload
.INSTR_RDATA_WIDTH ( 32 ),
.CLUST_FPU ( 1 ),
.CLUST_FP_DIVSQRT ( 1 ),
Expand Down Expand Up @@ -396,9 +378,9 @@ module chimera_cluster
.async_cluster_events_rptr_o ( ), // ???
.async_cluster_events_data_i ( '0 ), // ???

.en_sa_boot_i ( boot_en_q ), //TODO: WIP to test offload
.en_sa_boot_i ( 1'b0 ), //TODO: WIP to test offload

Check warning on line 381 in hw/chimera_cluster.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/chimera_cluster.sv#L381

Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]
Raw output
message:"Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]"  location:{path:"hw/chimera_cluster.sv"  range:{start:{line:381  column:101}}}  severity:WARNING  source:{name:"verible-verilog-lint"  url:"https://github.com/chipsalliance/verible"}
.test_mode_i ( 1'b0 ),
.fetch_en_i ( fetch_en_q ), //TODO: WIP to test offload
.fetch_en_i ( 1'b0 ), //TODO: WIP to test offload

Check warning on line 383 in hw/chimera_cluster.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/chimera_cluster.sv#L383

Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]
Raw output
message:"Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]"  location:{path:"hw/chimera_cluster.sv"  range:{start:{line:383  column:101}}}  severity:WARNING  source:{name:"verible-verilog-lint"  url:"https://github.com/chipsalliance/verible"}
.eoc_o ( ), //TODO: WIP to test offload

Check warning on line 384 in hw/chimera_cluster.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/chimera_cluster.sv#L384

Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]
Raw output
message:"Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]"  location:{path:"hw/chimera_cluster.sv"  range:{start:{line:384  column:101}}}  severity:WARNING  source:{name:"verible-verilog-lint"  url:"https://github.com/chipsalliance/verible"}
.busy_o ( ), //TODO: WIP to test offload

Check warning on line 385 in hw/chimera_cluster.sv

View workflow job for this annotation

GitHub Actions / verible-verilog-lint

[verible-verilog-lint] hw/chimera_cluster.sv#L385

Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]
Raw output
message:"Line length exceeds max: 100; is: 104 [Style: line-length] [line-length]"  location:{path:"hw/chimera_cluster.sv"  range:{start:{line:385  column:101}}}  severity:WARNING  source:{name:"verible-verilog-lint"  url:"https://github.com/chipsalliance/verible"}
.cluster_id_i ( ClusterId ),
Expand Down
99 changes: 99 additions & 0 deletions sw/tests/testClusterOffload_pulp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2024 ETH Zurich and University of Bologna.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Sergio Mazzola <[email protected]>

// Simple offload test. Set the trap handler first, offload a function, retrieve
// return value from cluster. Does not currently take care of stack
// initialization and bss initialization on cluster.

#include "offload.h"
#include "soc_addr_map.h"
#include <regs/soc_ctrl.h>
#include <stdint.h>

#define TESTVAL_CLUSTER 0xdeadbeef

#define PERIPH_OFFSET 0x00200000

#define FETCH_EN_OFFSET (PERIPH_OFFSET + 0x008)

#define BOOT_ADDR_CORE_0_OFFSET (PERIPH_OFFSET + 0x040)
#define BOOT_ADDR_CORE_1_OFFSET (PERIPH_OFFSET + 0x044)
#define BOOT_ADDR_CORE_2_OFFSET (PERIPH_OFFSET + 0x048)
#define BOOT_ADDR_CORE_3_OFFSET (PERIPH_OFFSET + 0x04C)
#define BOOT_ADDR_CORE_4_OFFSET (PERIPH_OFFSET + 0x050)
#define BOOT_ADDR_CORE_5_OFFSET (PERIPH_OFFSET + 0x054)
#define BOOT_ADDR_CORE_6_OFFSET (PERIPH_OFFSET + 0x058)
#define BOOT_ADDR_CORE_7_OFFSET (PERIPH_OFFSET + 0x05C)
#define BOOT_ADDR_CORE_8_OFFSET (PERIPH_OFFSET + 0x060)
#define BOOT_ADDR_CORE_9_OFFSET (PERIPH_OFFSET + 0x064)
#define BOOT_ADDR_CORE_10_OFFSET (PERIPH_OFFSET + 0x068)
#define BOOT_ADDR_CORE_11_OFFSET (PERIPH_OFFSET + 0x06C)
#define BOOT_ADDR_CORE_12_OFFSET (PERIPH_OFFSET + 0x070)
#define BOOT_ADDR_CORE_13_OFFSET (PERIPH_OFFSET + 0x074)
#define BOOT_ADDR_CORE_14_OFFSET (PERIPH_OFFSET + 0x078)
#define BOOT_ADDR_CORE_15_OFFSET (PERIPH_OFFSET + 0x07C)

int32_t test_cluster() {
int32_t result;
int32_t hart_id;

asm volatile ("csrr %0, mhartid" : "=r"(hart_id)::);

asm volatile (
"li t0, %1\n" // Load immediate value into t0
"mv a0, t0\n" // Move t0 into a0 (x10)
"mv %0, a0\n" // Move a0 into the output variable
: "=r"(result) // Output operand
: "i"(TESTVAL_CLUSTER) // Input operand: immediate value
: "t0", "a0" // Clobbered registers
);

result = result + hart_id;

return result;
}

int main() {
int32_t hart_id;
asm volatile ("csrr %0, mhartid" : "=r"(hart_id)::);

// set boot address of all cores in cluster 0
uint8_t *boot_addr_core_0_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_0_OFFSET;
uint8_t *boot_addr_core_1_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_1_OFFSET;
uint8_t *boot_addr_core_2_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_2_OFFSET;
uint8_t *boot_addr_core_3_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_3_OFFSET;
uint8_t *boot_addr_core_4_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_4_OFFSET;
uint8_t *boot_addr_core_5_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_5_OFFSET;
uint8_t *boot_addr_core_6_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_6_OFFSET;
uint8_t *boot_addr_core_7_cluster_0 = CLUSTER_0_BASE + BOOT_ADDR_CORE_7_OFFSET;

*((uint32_t*)boot_addr_core_0_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_1_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_2_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_3_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_4_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_5_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_6_cluster_0) = test_cluster;
*((uint32_t*)boot_addr_core_7_cluster_0) = test_cluster;

// enable fetch for all cores in cluster 0
uint8_t *fetch_en_cluster_0 = CLUSTER_0_BASE + FETCH_EN_OFFSET;

*((uint32_t*)fetch_en_cluster_0) = 0x00FF;

// only the host hart executes this
volatile int count = 10000;
if (hart_id == 0) {
// delay loop
asm volatile (
"1: nop\n"
"addi %0, %0, -1\n"
"bnez %0, 1b\n"
: "+r"(count) // Input and output operand
);
}
return count;
}
35 changes: 35 additions & 0 deletions sw/tests/testClusterWriteTCDM.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 ETH Zurich and University of Bologna.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Sergio Mazzola <[email protected]>

// Simple offload test. Set the trap handler first, offload a function, retrieve
// return value from cluster. Does not currently take care of stack
// initialization and bss initialization on cluster.

#include "offload.h"
#include "soc_addr_map.h"
#include <regs/soc_ctrl.h>
#include <stdint.h>

#define TESTVAL_CLUSTER 0xdeadbeef

int main() {
uint8_t *base_addr_tcdm_cluster_0 = CLUSTER_0_BASE;

*((uint32_t*)base_addr_tcdm_cluster_0) = TESTVAL_CLUSTER;

asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");

uint32_t result = *((uint32_t*)base_addr_tcdm_cluster_0);
if (result == TESTVAL_CLUSTER) {
return 0;
} else {
return 1;
}
}
7 changes: 0 additions & 7 deletions target/sim/src/tb_chimera_soc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,6 @@ module tb_chimera_soc
fast_elf_preload(preload_elf);
// Unhalt the core
fix.vip.jtag_resume_hart();

fix.dut.i_cluster_domain.gen_clusters[0].i_chimera_cluster.boot_cluster();
fix.dut.i_cluster_domain.gen_clusters[1].i_chimera_cluster.boot_cluster();
fix.dut.i_cluster_domain.gen_clusters[2].i_chimera_cluster.boot_cluster();
fix.dut.i_cluster_domain.gen_clusters[3].i_chimera_cluster.boot_cluster();
fix.dut.i_cluster_domain.gen_clusters[4].i_chimera_cluster.boot_cluster();

// Wait for the end of computation
fix.vip.jtag_wait_for_eoc(exit_code);
end
Expand Down

0 comments on commit 319ee8b

Please sign in to comment.