better PI IO activity monitoring

This commit is contained in:
Mateusz Faderewski 2024-08-15 21:02:15 +02:00
parent 5e07406eb4
commit 8fb22543c9
6 changed files with 143 additions and 74 deletions

View File

@ -371,6 +371,8 @@ module mcu_top (
logic dd_bm_ack; logic dd_bm_ack;
logic [31:0] debug_buffer;
logic cic_invalid_region; logic cic_invalid_region;
logic aux_pending; logic aux_pending;
@ -649,15 +651,18 @@ module mcu_top (
end end
REG_DEBUG_0: begin REG_DEBUG_0: begin
reg_rdata <= n64_scb.pi_debug[31:0]; reg_rdata <= n64_scb.pi_debug_address;
debug_buffer <= {
6'd0,
n64_scb.pi_debug_direction,
n64_scb.pi_debug_rw_count,
n64_scb.cic_debug_step,
n64_scb.pi_debug_fifo_flags
};
end end
REG_DEBUG_1: begin REG_DEBUG_1: begin
reg_rdata <= { reg_rdata <= debug_buffer;
24'd0,
n64_scb.cic_debug,
n64_scb.pi_debug[35:32]
};
end end
REG_CIC_0: begin REG_CIC_0: begin

View File

@ -192,7 +192,7 @@ module n64_cic (
end end
2'b11: begin 2'b11: begin
n64_scb.cic_debug <= dbus_wdata[3:0]; n64_scb.cic_debug_step <= dbus_wdata[3:0];
end end
endcase endcase
end end
@ -200,7 +200,7 @@ module n64_cic (
end end
if (reset) begin if (reset) begin
n64_scb.cic_debug <= 3'd0; n64_scb.cic_debug_step <= 3'd0;
end end
if (reset || !cic_reset) begin if (reset || !cic_reset) begin
@ -236,7 +236,7 @@ module n64_cic (
cic_dq cic_dq
}; };
2'b11: dbus_rdata = {28'd0, n64_scb.cic_debug}; 2'b11: dbus_rdata = {28'd0, n64_scb.cic_debug_step};
endcase endcase
end end
endcase endcase

View File

@ -127,12 +127,21 @@ module n64_pi (
// Debug: last accessed PI address // Debug: last accessed PI address
logic [15:0] pi_debug_address_buffer;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (aleh_op) begin if (aleh_op) begin
n64_scb.pi_debug[31:16] <= n64_pi_dq_in; pi_debug_address_buffer <= n64_pi_dq_in;
end end
if (alel_op) begin if (alel_op) begin
n64_scb.pi_debug[15:0] <= n64_pi_dq_in; n64_scb.pi_debug_address <= {pi_debug_address_buffer, n64_pi_dq_in};
n64_scb.pi_debug_rw_count <= 17'd0;
end
if (pi_reset && (pi_mode == PI_MODE_VALID)) begin
if ((last_read && !pi_read) || (last_write && !pi_write)) begin
n64_scb.pi_debug_rw_count <= n64_scb.pi_debug_rw_count + 1'd1;
n64_scb.pi_debug_direction <= !pi_write;
end
end end
end end
@ -296,11 +305,11 @@ module n64_pi (
.reset(reset), .reset(reset),
.flush(reset || !pi_reset || alel_op), .flush(reset || !pi_reset || alel_op),
.full(read_fifo_full), .full(read_fifo_full),
.write(read_fifo_write), .write(read_fifo_write),
.wdata(read_fifo_wdata), .wdata(read_fifo_wdata),
.empty(read_fifo_empty), .empty(read_fifo_empty),
.read(read_fifo_read), .read(read_fifo_read),
.rdata(read_fifo_rdata) .rdata(read_fifo_rdata)
@ -310,7 +319,7 @@ module n64_pi (
read_fifo_read <= 1'b0; read_fifo_read <= 1'b0;
if (!pi_reset) begin if (!pi_reset) begin
n64_scb.pi_debug[33:32] <= 2'b00; n64_scb.pi_debug_fifo_flags[1:0] <= 2'b00;
end end
if (reset || !pi_reset || alel_op) begin if (reset || !pi_reset || alel_op) begin
@ -321,9 +330,9 @@ module n64_pi (
if (read_op) begin if (read_op) begin
if (read_fifo_empty) begin if (read_fifo_empty) begin
read_fifo_wait <= 1'b1; read_fifo_wait <= 1'b1;
n64_scb.pi_debug[32] <= 1'b1; n64_scb.pi_debug_fifo_flags[0] <= 1'b1;
if (read_fifo_wait) begin if (read_fifo_wait) begin
n64_scb.pi_debug[33] <= 1'b1; n64_scb.pi_debug_fifo_flags[1] <= 1'b1;
end end
end else begin end else begin
read_fifo_read <= 1'b1; read_fifo_read <= 1'b1;
@ -377,7 +386,7 @@ module n64_pi (
write_fifo_write <= 1'b0; write_fifo_write <= 1'b0;
if (!pi_reset) begin if (!pi_reset) begin
n64_scb.pi_debug[35:34] <= 2'b00; n64_scb.pi_debug_fifo_flags[3:2] <= 2'b00;
end end
if (reset) begin if (reset) begin
@ -388,9 +397,9 @@ module n64_pi (
if (write_op) begin if (write_op) begin
if (write_fifo_full) begin if (write_fifo_full) begin
write_fifo_wait <= 1'b1; write_fifo_wait <= 1'b1;
n64_scb.pi_debug[34] <= 1'b1; n64_scb.pi_debug_fifo_flags[2] <= 1'b1;
if (write_fifo_wait) begin if (write_fifo_wait) begin
n64_scb.pi_debug[35] <= 1'b1; n64_scb.pi_debug_fifo_flags[3] <= 1'b1;
end end
end else begin end else begin
write_fifo_write <= 1'b1; write_fifo_write <= 1'b1;

View File

@ -68,11 +68,14 @@ interface n64_scb ();
logic cic_region; logic cic_region;
logic [7:0] cic_seed; logic [7:0] cic_seed;
logic [47:0] cic_checksum; logic [47:0] cic_checksum;
logic [3:0] cic_debug; logic [3:0] cic_debug_step;
logic pi_sdram_active; logic pi_sdram_active;
logic pi_flash_active; logic pi_flash_active;
logic [35:0] pi_debug; logic [31:0] pi_debug_address;
logic [16:0] pi_debug_rw_count;
logic pi_debug_direction;
logic [3:0] pi_debug_fifo_flags;
modport controller ( modport controller (
input n64_reset, input n64_reset,
@ -126,9 +129,12 @@ interface n64_scb ();
output cic_region, output cic_region,
output cic_seed, output cic_seed,
output cic_checksum, output cic_checksum,
input cic_debug, input cic_debug_step,
input pi_debug input pi_debug_address,
input pi_debug_rw_count,
input pi_debug_direction,
input pi_debug_fifo_flags
); );
modport pi ( modport pi (
@ -153,7 +159,11 @@ interface n64_scb ();
output pi_sdram_active, output pi_sdram_active,
output pi_flash_active, output pi_flash_active,
output pi_debug
output pi_debug_address,
output pi_debug_rw_count,
output pi_debug_direction,
output pi_debug_fifo_flags
); );
modport flashram ( modport flashram (
@ -249,7 +259,7 @@ interface n64_scb ();
input cic_region, input cic_region,
input cic_seed, input cic_seed,
input cic_checksum, input cic_checksum,
output cic_debug output cic_debug_step
); );
modport arbiter ( modport arbiter (

View File

@ -794,10 +794,7 @@ fn handle_info_command(connection: Connection) -> Result<(), sc64::Error> {
println!(" LED blink: {}", state.led_enable); println!(" LED blink: {}", state.led_enable);
println!(" IS-Viewer 64: {}", state.isviewer); println!(" IS-Viewer 64: {}", state.isviewer);
println!("{}", "SummerCart64 diagnostic information:".bold()); println!("{}", "SummerCart64 diagnostic information:".bold());
println!( println!(" PI I/O access: {}", state.fpga_debug_data.pi_io_access);
" Last PI address: 0x{:08X}",
state.fpga_debug_data.last_pi_address
);
println!( println!(
" PI FIFO flags: {}", " PI FIFO flags: {}",
state.fpga_debug_data.pi_fifo_flags state.fpga_debug_data.pi_fifo_flags

View File

@ -833,6 +833,90 @@ impl TryFrom<u32> for UpdateStatus {
} }
} }
pub enum PiIODirection {
Read,
Write,
}
impl Display for PiIODirection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Read => "read",
Self::Write => "written",
})
}
}
pub struct PiIOAccess {
pub address: u32,
pub count: u32,
pub direction: PiIODirection,
}
impl From<&[u8; 8]> for PiIOAccess {
fn from(value: &[u8; 8]) -> Self {
let address = u32::from_be_bytes(value[0..4].try_into().unwrap());
let info = u32::from_be_bytes(value[4..8].try_into().unwrap());
let count = (info >> 8) & 0x1FFFF;
let direction = if (info & (1 << 25)) == 0 {
PiIODirection::Read
} else {
PiIODirection::Write
};
PiIOAccess {
address,
count,
direction,
}
}
}
impl Display for PiIOAccess {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("0x{:08X}", self.address))?;
if self.count > 0 {
f.write_fmt(format_args!(" {} bytes {}", self.count * 2, self.direction))?;
}
Ok(())
}
}
pub struct PiFifoFlags {
pub read_fifo_wait: bool,
pub read_fifo_failure: bool,
pub write_fifo_wait: bool,
pub write_fifo_failure: bool,
}
impl Display for PiFifoFlags {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mapping = vec![
(self.read_fifo_wait, "Read wait"),
(self.read_fifo_failure, "Read failure"),
(self.write_fifo_wait, "Write wait"),
(self.write_fifo_failure, "Write failure"),
];
let filtered: Vec<&str> = mapping.into_iter().filter(|x| x.0).map(|x| x.1).collect();
if filtered.len() > 0 {
f.write_str(filtered.join(", ").as_str())?;
} else {
f.write_str("None")?;
}
Ok(())
}
}
impl From<&[u8; 8]> for PiFifoFlags {
fn from(value: &[u8; 8]) -> Self {
PiFifoFlags {
read_fifo_wait: (value[7] & (1 << 0)) != 0,
read_fifo_failure: (value[7] & (1 << 1)) != 0,
write_fifo_wait: (value[7] & (1 << 2)) != 0,
write_fifo_failure: (value[7] & (1 << 3)) != 0,
}
}
}
pub enum CicStep { pub enum CicStep {
Unavailable, Unavailable,
PowerOff, PowerOff,
@ -875,10 +959,10 @@ impl Display for CicStep {
} }
} }
impl TryFrom<u8> for CicStep { impl From<&[u8; 8]> for CicStep {
type Error = Error; fn from(value: &[u8; 8]) -> Self {
fn try_from(value: u8) -> Result<Self, Self::Error> { let cic_step = (value[7] >> 4) & 0x0F;
Ok(match value { match cic_step {
0 => Self::Unavailable, 0 => Self::Unavailable,
1 => Self::PowerOff, 1 => Self::PowerOff,
2 => Self::ConfigLoad, 2 => Self::ConfigLoad,
@ -895,49 +979,12 @@ impl TryFrom<u8> for CicStep {
13 => Self::DieInvalidRegion, 13 => Self::DieInvalidRegion,
14 => Self::DieCommand, 14 => Self::DieCommand,
_ => Self::Unknown, _ => Self::Unknown,
})
}
}
pub struct PiFifoFlags {
pub read_fifo_wait: bool,
pub read_fifo_failure: bool,
pub write_fifo_wait: bool,
pub write_fifo_failure: bool,
}
impl Display for PiFifoFlags {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mapping = vec![
(self.read_fifo_wait, "Read wait"),
(self.read_fifo_failure, "Read failure"),
(self.write_fifo_wait, "Write wait"),
(self.write_fifo_failure, "Write failure"),
];
let filtered: Vec<&str> = mapping.into_iter().filter(|x| x.0).map(|x| x.1).collect();
if filtered.len() > 0 {
f.write_str(filtered.join(", ").as_str())?;
} else {
f.write_str("None")?;
} }
Ok(())
}
}
impl TryFrom<u8> for PiFifoFlags {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(PiFifoFlags {
read_fifo_wait: (value & (1 << 0)) != 0,
read_fifo_failure: (value & (1 << 1)) != 0,
write_fifo_wait: (value & (1 << 2)) != 0,
write_fifo_failure: (value & (1 << 3)) != 0,
})
} }
} }
pub struct FpgaDebugData { pub struct FpgaDebugData {
pub last_pi_address: u32, pub pi_io_access: PiIOAccess,
pub pi_fifo_flags: PiFifoFlags, pub pi_fifo_flags: PiFifoFlags,
pub cic_step: CicStep, pub cic_step: CicStep,
} }
@ -948,10 +995,11 @@ impl TryFrom<Vec<u8>> for FpgaDebugData {
if value.len() != 8 { if value.len() != 8 {
return Err(Error::new("Invalid data length for FPGA debug data")); return Err(Error::new("Invalid data length for FPGA debug data"));
} }
let data: &[u8; 8] = &value[0..8].try_into().unwrap();
Ok(FpgaDebugData { Ok(FpgaDebugData {
last_pi_address: u32::from_be_bytes(value[0..4].try_into().unwrap()), pi_io_access: data.into(),
pi_fifo_flags: (value[7] & 0x0F).try_into().unwrap(), pi_fifo_flags: data.into(),
cic_step: ((value[7] >> 4) & 0x0F).try_into().unwrap(), cic_step: data.into(),
}) })
} }
} }