mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: update HP Linux configuration validation and adjust simulation time
This commit is contained in:
7 files changed
+286
-84
No files matched your search
@@ -131,7 +131,7 @@ HP_BOOT_BUNDLE_NAME ?= retrosoc_hp_linux
|
||||
HP_BOOT_BUNDLE_BIN := $(SW_BUILD_DIR)/$(HP_BOOT_BUNDLE_NAME).bin
|
||||
HP_BOOT_BUNDLE_HEX := $(SW_BUILD_DIR)/$(HP_BOOT_BUNDLE_NAME).hex
|
||||
HP_BOOT_BUNDLE_MANIFEST := $(SW_BUILD_DIR)/$(HP_BOOT_BUNDLE_NAME).json
|
||||
HP_LINUX_SIM_TIME ?= 7200
|
||||
HP_LINUX_SIM_TIME ?= 0
|
||||
HP_SMOKE_SIM_TIME ?= 300
|
||||
HP_SMOKE_BUILD_DIR := $(VARIANT_ROOT)/hp-smoke
|
||||
HP_SMOKE_STAMP := $(HP_SMOKE_BUILD_DIR)/images/.stamp
|
||||
@@ -731,4 +731,4 @@ regress-nightly:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite nightly
|
||||
|
||||
sim-asm: asm
|
||||
$(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) sim
|
||||
$(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) sim
|
||||
@@ -5,6 +5,10 @@ CONFIG_RISCV_ISA_A=y
|
||||
CONFIG_RISCV_ISA_C=y
|
||||
CONFIG_FPU=y
|
||||
CONFIG_SMP=n
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_TTY=y
|
||||
CONFIG_BINFMT_ELF=y
|
||||
CONFIG_BINFMT_SCRIPT=y
|
||||
CONFIG_HVC_RISCV_SBI=y
|
||||
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
|
||||
CONFIG_SIFIVE_PLIC=y
|
||||
|
||||
@@ -5222,7 +5222,7 @@
|
||||
{
|
||||
"id": "kernel-sbi",
|
||||
"file": "app/ports/linux/linux/retrosoc_hp.config",
|
||||
"text": "CONFIG_SMP=n\nCONFIG_HVC_RISCV_SBI=y\nCONFIG_SERIAL_EARLYCON_RISCV_SBI=y"
|
||||
"text": "CONFIG_SMP=n\nCONFIG_PRINTK=y\nCONFIG_TTY=y\nCONFIG_BINFMT_ELF=y\nCONFIG_BINFMT_SCRIPT=y\nCONFIG_HVC_RISCV_SBI=y\nCONFIG_SERIAL_EARLYCON_RISCV_SBI=y"
|
||||
},
|
||||
{
|
||||
"id": "kernel-ready-support",
|
||||
|
||||
@@ -108,11 +108,11 @@ module axi4_data_crossbar #(
|
||||
logic user;
|
||||
} read_resp_t;
|
||||
|
||||
addr_channel_t m_aw [NumMasters];
|
||||
addr_channel_t m_ar [NumMasters];
|
||||
write_channel_t m_w [NumMasters];
|
||||
write_resp_t m_b [NumMasters];
|
||||
read_resp_t m_r [NumMasters];
|
||||
addr_channel_t m_aw [NumMasters];
|
||||
addr_channel_t m_ar [NumMasters];
|
||||
write_channel_t m_w [NumMasters];
|
||||
write_resp_t m_b [NumMasters];
|
||||
read_resp_t m_r [NumMasters];
|
||||
logic [NumMasters-1:0] m_awvalid;
|
||||
logic [NumMasters-1:0] m_awready;
|
||||
logic [NumMasters-1:0] m_wvalid;
|
||||
@@ -124,11 +124,11 @@ module axi4_data_crossbar #(
|
||||
logic [NumMasters-1:0] m_rvalid;
|
||||
logic [NumMasters-1:0] m_rready;
|
||||
|
||||
addr_channel_t t_aw [NumTargets];
|
||||
addr_channel_t t_ar [NumTargets];
|
||||
write_channel_t t_w [NumTargets];
|
||||
write_resp_t t_b [NumTargets];
|
||||
read_resp_t t_r [NumTargets];
|
||||
addr_channel_t t_aw [NumTargets];
|
||||
addr_channel_t t_ar [NumTargets];
|
||||
write_channel_t t_w [NumTargets];
|
||||
write_resp_t t_b [NumTargets];
|
||||
read_resp_t t_r [NumTargets];
|
||||
logic [NumTargets-1:0] t_awvalid;
|
||||
logic [NumTargets-1:0] t_awready;
|
||||
logic [NumTargets-1:0] t_wvalid;
|
||||
@@ -154,6 +154,7 @@ module axi4_data_crossbar #(
|
||||
logic [NumTargets-1:0] s_write_capture;
|
||||
|
||||
logic [NumMasters-1:0][ NumTargets-1:0] s_read_resp_req;
|
||||
logic [NumMasters-1:0][ NumTargets-1:0] s_read_resp_arb_req;
|
||||
logic [NumMasters-1:0][ NumTargets-1:0] s_write_resp_req;
|
||||
logic [NumMasters-1:0][ NumTargets-1:0] unused_read_resp_grant;
|
||||
logic [NumMasters-1:0][ NumTargets-1:0] unused_write_resp_grant;
|
||||
@@ -163,27 +164,30 @@ module axi4_data_crossbar #(
|
||||
logic [NumMasters-1:0] s_write_resp_valid;
|
||||
logic [NumMasters-1:0] s_read_terminal;
|
||||
logic [NumMasters-1:0] s_write_terminal;
|
||||
logic [NumTargets-1:0] s_invalid_read_response;
|
||||
logic [NumTargets-1:0] s_invalid_write_response;
|
||||
logic [NumTargets-1:0] s_invalid_read_fault_accept;
|
||||
logic [NumTargets-1:0] s_invalid_write_fault_accept;
|
||||
logic s_protocol_fault_pending;
|
||||
logic s_protocol_fault_event;
|
||||
logic s_protocol_recovery_q;
|
||||
logic [NumMasters-1:0] s_read_resp_lock_d, s_read_resp_lock_q;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_read_resp_lock_target_d;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_read_resp_lock_target_q;
|
||||
logic [NumTargets-1:0] s_invalid_read_response;
|
||||
logic [NumTargets-1:0] s_invalid_write_response;
|
||||
logic [NumTargets-1:0] s_invalid_read_fault_accept;
|
||||
logic [NumTargets-1:0] s_invalid_write_fault_accept;
|
||||
logic s_protocol_fault_pending;
|
||||
logic s_protocol_fault_event;
|
||||
logic s_protocol_recovery_q;
|
||||
|
||||
logic [NumTargets-1:0] s_target_write_owner_full;
|
||||
logic [NumTargets-1:0] s_target_write_owner_empty;
|
||||
logic [NumTargets-1:0] s_target_write_owner_push;
|
||||
logic [NumTargets-1:0] s_target_write_owner_pop;
|
||||
logic [NumTargets-1:0][MasterWidth-1:0] s_target_write_owner_data;
|
||||
logic [NumTargets-1:0][ 1:0] unused_target_write_owner_count;
|
||||
logic [NumTargets-1:0] s_target_write_owner_full;
|
||||
logic [NumTargets-1:0] s_target_write_owner_empty;
|
||||
logic [NumTargets-1:0] s_target_write_owner_push;
|
||||
logic [NumTargets-1:0] s_target_write_owner_pop;
|
||||
logic [NumTargets-1:0][MasterWidth-1:0] s_target_write_owner_data;
|
||||
logic [NumTargets-1:0][ 1:0] unused_target_write_owner_count;
|
||||
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_read_decoded_target;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_write_decoded_target;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_read_routed_target;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_write_routed_target;
|
||||
logic [NumMasters-1:0][ 3:0] s_read_fault_reason;
|
||||
logic [NumMasters-1:0][ 3:0] s_write_fault_reason;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_read_decoded_target;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_write_decoded_target;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_read_routed_target;
|
||||
logic [NumMasters-1:0][TargetWidth-1:0] s_write_routed_target;
|
||||
logic [NumMasters-1:0][ 3:0] s_read_fault_reason;
|
||||
logic [NumMasters-1:0][ 3:0] s_write_fault_reason;
|
||||
|
||||
logic [NumMasters-1:0][CountWidth-1:0] s_master_read_count_d, s_master_read_count_q;
|
||||
logic [NumMasters-1:0][CountWidth-1:0] s_master_write_count_d, s_master_write_count_q;
|
||||
@@ -388,7 +392,7 @@ module axi4_data_crossbar #(
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
.advance_i (s_read_terminal[master]),
|
||||
.request_i (s_read_resp_req[master]),
|
||||
.request_i (s_read_resp_arb_req[master]),
|
||||
.grant_o (unused_read_resp_grant[master]),
|
||||
.selected_o(s_read_resp_selected[master]),
|
||||
.valid_o (s_read_resp_valid[master])
|
||||
@@ -406,6 +410,20 @@ module axi4_data_crossbar #(
|
||||
);
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
// Keep all beats of one read burst on its selected target. AXI read
|
||||
// responses may complete out of order by ID, but beats of a burst must
|
||||
// not be interleaved with another target's burst on the same master.
|
||||
s_read_resp_arb_req = s_read_resp_req;
|
||||
for (int master = 0; master < NumMasters; master++) begin
|
||||
if (s_read_resp_lock_q[master]) begin
|
||||
s_read_resp_arb_req[master] = '0;
|
||||
s_read_resp_arb_req[master][s_read_resp_lock_target_q[master]] =
|
||||
s_read_resp_req[master][s_read_resp_lock_target_q[master]];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for (genvar target = 0; target < NumTargets; target++) begin : gen_target_ports
|
||||
assign targets[target].awid = t_aw[target].id;
|
||||
assign targets[target].awaddr = t_aw[target].addr;
|
||||
@@ -846,18 +864,24 @@ module axi4_data_crossbar #(
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
s_master_read_count_d = s_master_read_count_q;
|
||||
s_master_write_count_d = s_master_write_count_q;
|
||||
s_target_read_count_d = s_target_read_count_q;
|
||||
s_target_write_count_d = s_target_write_count_q;
|
||||
s_read_id_busy_d = s_read_id_busy_q;
|
||||
s_write_id_busy_d = s_write_id_busy_q;
|
||||
s_master_read_count_d = s_master_read_count_q;
|
||||
s_master_write_count_d = s_master_write_count_q;
|
||||
s_target_read_count_d = s_target_read_count_q;
|
||||
s_target_write_count_d = s_target_write_count_q;
|
||||
s_read_id_busy_d = s_read_id_busy_q;
|
||||
s_write_id_busy_d = s_write_id_busy_q;
|
||||
s_read_resp_lock_d = s_read_resp_lock_q;
|
||||
s_read_resp_lock_target_d = s_read_resp_lock_target_q;
|
||||
for (int master = 0; master < NumMasters; master++) begin
|
||||
if (s_read_terminal[master]) begin
|
||||
s_master_read_count_d[master] = s_master_read_count_d[master] - 1'b1;
|
||||
s_target_read_count_d[s_read_resp_selected[master]] =
|
||||
s_target_read_count_d[s_read_resp_selected[master]] - 1'b1;
|
||||
s_read_id_busy_d[master][s_read_complete_id[master]] = 1'b0;
|
||||
s_read_resp_lock_d[master] = 1'b0;
|
||||
end else if (!s_read_resp_lock_q[master] && s_read_resp_valid[master]) begin
|
||||
s_read_resp_lock_d[master] = 1'b1;
|
||||
s_read_resp_lock_target_d[master] = s_read_resp_selected[master];
|
||||
end
|
||||
if (s_write_terminal[master]) begin
|
||||
s_master_write_count_d[master] = s_master_write_count_d[master] - 1'b1;
|
||||
@@ -972,53 +996,59 @@ module axi4_data_crossbar #(
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_n_i) begin
|
||||
if (!rst_n_i) begin
|
||||
s_master_read_count_q <= '0;
|
||||
s_master_write_count_q <= '0;
|
||||
s_target_read_count_q <= '0;
|
||||
s_target_write_count_q <= '0;
|
||||
s_read_id_busy_q <= '0;
|
||||
s_write_id_busy_q <= '0;
|
||||
s_write_route_q <= '0;
|
||||
s_route_read_ptr_q <= '0;
|
||||
s_route_write_ptr_q <= '0;
|
||||
s_route_count_q <= '0;
|
||||
s_read_age_q <= '0;
|
||||
s_write_age_q <= '0;
|
||||
s_protocol_recovery_q <= 1'b0;
|
||||
fault_valid_o <= 1'b0;
|
||||
fault_master_o <= '0;
|
||||
fault_target_o <= '0;
|
||||
fault_addr_o <= '0;
|
||||
fault_write_o <= 1'b0;
|
||||
fault_reason_o <= '0;
|
||||
s_master_read_count_q <= '0;
|
||||
s_master_write_count_q <= '0;
|
||||
s_target_read_count_q <= '0;
|
||||
s_target_write_count_q <= '0;
|
||||
s_read_id_busy_q <= '0;
|
||||
s_write_id_busy_q <= '0;
|
||||
s_read_resp_lock_q <= '0;
|
||||
s_read_resp_lock_target_q <= '0;
|
||||
s_write_route_q <= '0;
|
||||
s_route_read_ptr_q <= '0;
|
||||
s_route_write_ptr_q <= '0;
|
||||
s_route_count_q <= '0;
|
||||
s_read_age_q <= '0;
|
||||
s_write_age_q <= '0;
|
||||
s_protocol_recovery_q <= 1'b0;
|
||||
fault_valid_o <= 1'b0;
|
||||
fault_master_o <= '0;
|
||||
fault_target_o <= '0;
|
||||
fault_addr_o <= '0;
|
||||
fault_write_o <= 1'b0;
|
||||
fault_reason_o <= '0;
|
||||
end else begin
|
||||
if (flush_i) begin
|
||||
s_master_read_count_q <= '0;
|
||||
s_master_write_count_q <= '0;
|
||||
s_target_read_count_q <= '0;
|
||||
s_target_write_count_q <= '0;
|
||||
s_read_id_busy_q <= '0;
|
||||
s_write_id_busy_q <= '0;
|
||||
s_write_route_q <= '0;
|
||||
s_route_read_ptr_q <= '0;
|
||||
s_route_write_ptr_q <= '0;
|
||||
s_route_count_q <= '0;
|
||||
s_read_age_q <= '0;
|
||||
s_write_age_q <= '0;
|
||||
s_protocol_recovery_q <= 1'b0;
|
||||
s_master_read_count_q <= '0;
|
||||
s_master_write_count_q <= '0;
|
||||
s_target_read_count_q <= '0;
|
||||
s_target_write_count_q <= '0;
|
||||
s_read_id_busy_q <= '0;
|
||||
s_write_id_busy_q <= '0;
|
||||
s_read_resp_lock_q <= '0;
|
||||
s_read_resp_lock_target_q <= '0;
|
||||
s_write_route_q <= '0;
|
||||
s_route_read_ptr_q <= '0;
|
||||
s_route_write_ptr_q <= '0;
|
||||
s_route_count_q <= '0;
|
||||
s_read_age_q <= '0;
|
||||
s_write_age_q <= '0;
|
||||
s_protocol_recovery_q <= 1'b0;
|
||||
end else begin
|
||||
s_master_read_count_q <= s_master_read_count_d;
|
||||
s_master_write_count_q <= s_master_write_count_d;
|
||||
s_target_read_count_q <= s_target_read_count_d;
|
||||
s_target_write_count_q <= s_target_write_count_d;
|
||||
s_read_id_busy_q <= s_read_id_busy_d;
|
||||
s_write_id_busy_q <= s_write_id_busy_d;
|
||||
s_write_route_q <= s_write_route_d;
|
||||
s_route_read_ptr_q <= s_route_read_ptr_d;
|
||||
s_route_write_ptr_q <= s_route_write_ptr_d;
|
||||
s_route_count_q <= s_route_count_d;
|
||||
s_read_age_q <= s_read_age_d;
|
||||
s_write_age_q <= s_write_age_d;
|
||||
s_master_read_count_q <= s_master_read_count_d;
|
||||
s_master_write_count_q <= s_master_write_count_d;
|
||||
s_target_read_count_q <= s_target_read_count_d;
|
||||
s_target_write_count_q <= s_target_write_count_d;
|
||||
s_read_id_busy_q <= s_read_id_busy_d;
|
||||
s_write_id_busy_q <= s_write_id_busy_d;
|
||||
s_read_resp_lock_q <= s_read_resp_lock_d;
|
||||
s_read_resp_lock_target_q <= s_read_resp_lock_target_d;
|
||||
s_write_route_q <= s_write_route_d;
|
||||
s_route_read_ptr_q <= s_route_read_ptr_d;
|
||||
s_route_write_ptr_q <= s_route_write_ptr_d;
|
||||
s_route_count_q <= s_route_count_d;
|
||||
s_read_age_q <= s_read_age_d;
|
||||
s_write_age_q <= s_write_age_d;
|
||||
if (s_protocol_fault_event) s_protocol_recovery_q <= 1'b1;
|
||||
end
|
||||
if (!fault_valid_o || fault_ready_i) begin
|
||||
|
||||
@@ -19,6 +19,15 @@ LAYOUT = {
|
||||
"rootfs.cpio.gz": (0x39000000, 8 * 1024 * 1024),
|
||||
}
|
||||
|
||||
REQUIRED_LINUX_CONFIG = (
|
||||
"CONFIG_BINFMT_ELF",
|
||||
"CONFIG_BINFMT_SCRIPT",
|
||||
"CONFIG_PRINTK",
|
||||
"CONFIG_TTY",
|
||||
"CONFIG_HVC_RISCV_SBI",
|
||||
"CONFIG_SERIAL_EARLYCON_RISCV_SBI",
|
||||
)
|
||||
|
||||
|
||||
def command(arguments: list[str], cwd: Path) -> None:
|
||||
environment = dict(os.environ)
|
||||
@@ -57,6 +66,27 @@ def find_toolchain(buildroot_output: Path) -> str:
|
||||
return str(matches[0])[: -len("gcc")]
|
||||
|
||||
|
||||
def validate_linux_config(config: Path) -> None:
|
||||
values: dict[str, str] = {}
|
||||
for line in config.read_text(encoding="utf-8").splitlines():
|
||||
if line.startswith("CONFIG_") and "=" in line:
|
||||
symbol, value = line.split("=", 1)
|
||||
values[symbol] = value
|
||||
elif line.startswith("# CONFIG_") and line.endswith(" is not set"):
|
||||
symbol = line[len("# ") : -len(" is not set")]
|
||||
values[symbol] = "n"
|
||||
|
||||
invalid = [
|
||||
f"{symbol}={values.get(symbol, 'missing')}"
|
||||
for symbol in REQUIRED_LINUX_CONFIG
|
||||
if values.get(symbol) != "y"
|
||||
]
|
||||
if invalid:
|
||||
raise RuntimeError(
|
||||
"invalid HP Linux effective configuration: " + ", ".join(invalid)
|
||||
)
|
||||
|
||||
|
||||
def build(args: argparse.Namespace) -> None:
|
||||
root = args.root.resolve()
|
||||
output = args.output.resolve()
|
||||
@@ -94,6 +124,7 @@ def build(args: argparse.Namespace) -> None:
|
||||
["make", f"O={linux_output}", "ARCH=riscv", f"CROSS_COMPILE={cross_compile}", "olddefconfig"],
|
||||
linux,
|
||||
)
|
||||
validate_linux_config(linux_output / ".config")
|
||||
command(
|
||||
["make", f"O={linux_output}", "ARCH=riscv", f"CROSS_COMPILE={cross_compile}",
|
||||
f"-j{args.jobs}", "Image"],
|
||||
|
||||
@@ -98,6 +98,54 @@ module axi4_data_crossbar_tb;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic issue_master1_read_burst(input logic [6:0] id, input logic [31:0] addr);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
masters[1].arid = id;
|
||||
masters[1].araddr = addr;
|
||||
masters[1].arlen = 8'd7;
|
||||
masters[1].arsize = 3'd3;
|
||||
masters[1].arburst = 2'b01;
|
||||
masters[1].arvalid = 1'b1;
|
||||
do @(posedge clk_i); while (!masters[1].arready);
|
||||
@(negedge clk_i);
|
||||
masters[1].arvalid = 1'b0;
|
||||
masters[1].arlen = '0;
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic return_target0_burst(input logic [6:0] id, input logic [63:0] data_base);
|
||||
begin
|
||||
for (int unsigned beat = 0; beat < 8; beat++) begin
|
||||
@(negedge clk_i);
|
||||
targets[0].rid = id;
|
||||
targets[0].rdata = data_base + beat;
|
||||
targets[0].rresp = 2'b00;
|
||||
targets[0].rlast = (beat == 7);
|
||||
targets[0].rvalid = 1'b1;
|
||||
do @(posedge clk_i); while (!targets[0].rready);
|
||||
@(negedge clk_i);
|
||||
targets[0].rvalid = 1'b0;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic return_target1_burst(input logic [6:0] id, input logic [63:0] data_base);
|
||||
begin
|
||||
for (int unsigned beat = 0; beat < 8; beat++) begin
|
||||
@(negedge clk_i);
|
||||
targets[1].rid = id;
|
||||
targets[1].rdata = data_base + beat;
|
||||
targets[1].rresp = 2'b00;
|
||||
targets[1].rlast = (beat == 7);
|
||||
targets[1].rvalid = 1'b1;
|
||||
do @(posedge clk_i); while (!targets[1].rready);
|
||||
@(negedge clk_i);
|
||||
targets[1].rvalid = 1'b0;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
task automatic return_target0_read(input logic [6:0] id, input logic [63:0] data);
|
||||
begin
|
||||
@(negedge clk_i);
|
||||
@@ -405,6 +453,69 @@ module axi4_data_crossbar_tb;
|
||||
$fatal(1, "same-target reads did not drain the crossbar");
|
||||
end
|
||||
|
||||
read_burst_target_lock : begin
|
||||
logic [ 6:0] first_id;
|
||||
logic [ 6:0] second_id;
|
||||
logic [63:0] first_base;
|
||||
logic [63:0] second_base;
|
||||
logic [ 6:0] expected_id;
|
||||
logic [63:0] expected_data;
|
||||
|
||||
issue_master1_read_burst(6'b001_100, 32'h3000_0200);
|
||||
issue_master1_read_burst(6'b001_101, 32'h3800_0200);
|
||||
if (outstanding_read_o != 8'd2) begin
|
||||
$fatal(1, "read bursts were not tracked concurrently");
|
||||
end
|
||||
|
||||
fork
|
||||
return_target0_burst(6'b001_100, 64'hAAAA_0000_0000_0000);
|
||||
return_target1_burst(6'b001_101, 64'hBBBB_0000_0000_0000);
|
||||
begin
|
||||
for (int unsigned beat = 0; beat < 16; beat++) begin
|
||||
do begin
|
||||
@(negedge clk_i);
|
||||
#1;
|
||||
end while (!masters[1].rvalid);
|
||||
|
||||
if (beat == 0) begin
|
||||
first_id = masters[1].rid;
|
||||
if (first_id == 6'b001_100) begin
|
||||
first_base = 64'hAAAA_0000_0000_0000;
|
||||
second_id = 6'b001_101;
|
||||
second_base = 64'hBBBB_0000_0000_0000;
|
||||
end else if (first_id == 6'b001_101) begin
|
||||
first_base = 64'hBBBB_0000_0000_0000;
|
||||
second_id = 6'b001_100;
|
||||
second_base = 64'hAAAA_0000_0000_0000;
|
||||
end else begin
|
||||
$fatal(1, "read burst returned an unexpected ID");
|
||||
end
|
||||
end
|
||||
|
||||
if (beat < 8) begin
|
||||
expected_id = first_id;
|
||||
expected_data = first_base + beat;
|
||||
end else begin
|
||||
expected_id = second_id;
|
||||
expected_data = second_base + (beat - 8);
|
||||
end
|
||||
if ((masters[1].rid != expected_id) || (masters[1].rdata != expected_data) ||
|
||||
(masters[1].rlast != (beat == 7 || beat == 15))) begin
|
||||
$fatal(
|
||||
1,
|
||||
"read response burst was interleaved or malformed at beat %0d rid=%h expected_id=%h data=%h expected_data=%h last=%b expected_last=%b",
|
||||
beat, masters[1].rid, expected_id, masters[1].rdata, expected_data,
|
||||
masters[1].rlast, (beat == 7 || beat == 15));
|
||||
end
|
||||
end
|
||||
end
|
||||
join
|
||||
@(negedge clk_i);
|
||||
if (!idle_o || (outstanding_read_o != 8'd0)) begin
|
||||
$fatal(1, "read burst target lock did not drain the crossbar");
|
||||
end
|
||||
end
|
||||
|
||||
jpeg_master_admission_credit_priority_and_acl : begin
|
||||
// JPEG's normal class is above the LP gateway's class before aging.
|
||||
@(negedge clk_i);
|
||||
|
||||
@@ -7,6 +7,10 @@ import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from scripts import build_hp_linux
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
@@ -50,7 +54,7 @@ def test_hp_linux_simulation_uses_explicit_fast_flash_acceptance() -> None:
|
||||
verilator_makefile = (ROOT / "rtl/mini/mk/verilator.mk").read_text(encoding="utf-8")
|
||||
emulator = (ROOT / "rtl/mini/dv/verilator/csrc/main.cpp").read_text(encoding="utf-8")
|
||||
|
||||
assert "HP_LINUX_SIM_TIME ?= 7200" in makefile
|
||||
assert "HP_LINUX_SIM_TIME ?= 0" in makefile
|
||||
assert "hp-linux-sim: hp-bundle comp" in makefile
|
||||
assert "VERILATOR_SIM_ARGS=--fast-flash sim" in makefile
|
||||
for marker in (
|
||||
@@ -157,6 +161,28 @@ def test_linux_build_uses_external_opensbi_platform_and_actual_initrd_end() -> N
|
||||
assert "aclint_mtimer_cold_init" in platform
|
||||
|
||||
|
||||
def test_hp_linux_effective_config_is_fail_closed(tmp_path: Path) -> None:
|
||||
fragment = (ROOT / "app/ports/linux/linux/retrosoc_hp.config").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
for symbol in build_hp_linux.REQUIRED_LINUX_CONFIG:
|
||||
assert f"{symbol}=y" in fragment
|
||||
|
||||
config = tmp_path / ".config"
|
||||
valid = "".join(f"{symbol}=y\n" for symbol in build_hp_linux.REQUIRED_LINUX_CONFIG)
|
||||
config.write_text(valid, encoding="utf-8")
|
||||
build_hp_linux.validate_linux_config(config)
|
||||
|
||||
config.write_text(valid.replace("CONFIG_BINFMT_ELF=y", "# CONFIG_BINFMT_ELF is not set"),
|
||||
encoding="utf-8")
|
||||
with pytest.raises(RuntimeError, match="CONFIG_BINFMT_ELF=n"):
|
||||
build_hp_linux.validate_linux_config(config)
|
||||
|
||||
config.write_text(valid.replace("CONFIG_TTY=y\n", ""), encoding="utf-8")
|
||||
with pytest.raises(RuntimeError, match="CONFIG_TTY=missing"):
|
||||
build_hp_linux.validate_linux_config(config)
|
||||
|
||||
|
||||
def test_hp_linux_device_tree_compiles_and_can_patch_initrd_end(tmp_path: Path) -> None:
|
||||
dtc = shutil.which("dtc")
|
||||
fdtput = shutil.which("fdtput")
|
||||
|
||||
Reference in new issue
Block a user