mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 05:59:15 +01:00
better PI IO activity monitoring
This commit is contained in:
parent
5e07406eb4
commit
8fb22543c9
@ -371,6 +371,8 @@ module mcu_top (
|
||||
|
||||
logic dd_bm_ack;
|
||||
|
||||
logic [31:0] debug_buffer;
|
||||
|
||||
logic cic_invalid_region;
|
||||
|
||||
logic aux_pending;
|
||||
@ -649,15 +651,18 @@ module mcu_top (
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
REG_DEBUG_1: begin
|
||||
reg_rdata <= {
|
||||
24'd0,
|
||||
n64_scb.cic_debug,
|
||||
n64_scb.pi_debug[35:32]
|
||||
};
|
||||
reg_rdata <= debug_buffer;
|
||||
end
|
||||
|
||||
REG_CIC_0: begin
|
||||
|
@ -192,7 +192,7 @@ module n64_cic (
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
n64_scb.cic_debug <= dbus_wdata[3:0];
|
||||
n64_scb.cic_debug_step <= dbus_wdata[3:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
@ -200,7 +200,7 @@ module n64_cic (
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
n64_scb.cic_debug <= 3'd0;
|
||||
n64_scb.cic_debug_step <= 3'd0;
|
||||
end
|
||||
|
||||
if (reset || !cic_reset) begin
|
||||
@ -236,7 +236,7 @@ module n64_cic (
|
||||
cic_dq
|
||||
};
|
||||
|
||||
2'b11: dbus_rdata = {28'd0, n64_scb.cic_debug};
|
||||
2'b11: dbus_rdata = {28'd0, n64_scb.cic_debug_step};
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
|
@ -127,12 +127,21 @@ module n64_pi (
|
||||
|
||||
// Debug: last accessed PI address
|
||||
|
||||
logic [15:0] pi_debug_address_buffer;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (aleh_op) begin
|
||||
n64_scb.pi_debug[31:16] <= n64_pi_dq_in;
|
||||
pi_debug_address_buffer <= n64_pi_dq_in;
|
||||
end
|
||||
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
|
||||
|
||||
@ -296,11 +305,11 @@ module n64_pi (
|
||||
.reset(reset),
|
||||
|
||||
.flush(reset || !pi_reset || alel_op),
|
||||
|
||||
|
||||
.full(read_fifo_full),
|
||||
.write(read_fifo_write),
|
||||
.wdata(read_fifo_wdata),
|
||||
|
||||
|
||||
.empty(read_fifo_empty),
|
||||
.read(read_fifo_read),
|
||||
.rdata(read_fifo_rdata)
|
||||
@ -310,7 +319,7 @@ module n64_pi (
|
||||
read_fifo_read <= 1'b0;
|
||||
|
||||
if (!pi_reset) begin
|
||||
n64_scb.pi_debug[33:32] <= 2'b00;
|
||||
n64_scb.pi_debug_fifo_flags[1:0] <= 2'b00;
|
||||
end
|
||||
|
||||
if (reset || !pi_reset || alel_op) begin
|
||||
@ -321,9 +330,9 @@ module n64_pi (
|
||||
if (read_op) begin
|
||||
if (read_fifo_empty) begin
|
||||
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
|
||||
n64_scb.pi_debug[33] <= 1'b1;
|
||||
n64_scb.pi_debug_fifo_flags[1] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
read_fifo_read <= 1'b1;
|
||||
@ -377,7 +386,7 @@ module n64_pi (
|
||||
write_fifo_write <= 1'b0;
|
||||
|
||||
if (!pi_reset) begin
|
||||
n64_scb.pi_debug[35:34] <= 2'b00;
|
||||
n64_scb.pi_debug_fifo_flags[3:2] <= 2'b00;
|
||||
end
|
||||
|
||||
if (reset) begin
|
||||
@ -388,9 +397,9 @@ module n64_pi (
|
||||
if (write_op) begin
|
||||
if (write_fifo_full) begin
|
||||
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
|
||||
n64_scb.pi_debug[35] <= 1'b1;
|
||||
n64_scb.pi_debug_fifo_flags[3] <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
write_fifo_write <= 1'b1;
|
||||
|
@ -68,11 +68,14 @@ interface n64_scb ();
|
||||
logic cic_region;
|
||||
logic [7:0] cic_seed;
|
||||
logic [47:0] cic_checksum;
|
||||
logic [3:0] cic_debug;
|
||||
logic [3:0] cic_debug_step;
|
||||
|
||||
logic pi_sdram_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 (
|
||||
input n64_reset,
|
||||
@ -126,9 +129,12 @@ interface n64_scb ();
|
||||
output cic_region,
|
||||
output cic_seed,
|
||||
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 (
|
||||
@ -153,7 +159,11 @@ interface n64_scb ();
|
||||
|
||||
output pi_sdram_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 (
|
||||
@ -249,7 +259,7 @@ interface n64_scb ();
|
||||
input cic_region,
|
||||
input cic_seed,
|
||||
input cic_checksum,
|
||||
output cic_debug
|
||||
output cic_debug_step
|
||||
);
|
||||
|
||||
modport arbiter (
|
||||
|
@ -794,10 +794,7 @@ fn handle_info_command(connection: Connection) -> Result<(), sc64::Error> {
|
||||
println!(" LED blink: {}", state.led_enable);
|
||||
println!(" IS-Viewer 64: {}", state.isviewer);
|
||||
println!("{}", "SummerCart64 diagnostic information:".bold());
|
||||
println!(
|
||||
" Last PI address: 0x{:08X}",
|
||||
state.fpga_debug_data.last_pi_address
|
||||
);
|
||||
println!(" PI I/O access: {}", state.fpga_debug_data.pi_io_access);
|
||||
println!(
|
||||
" PI FIFO flags: {}",
|
||||
state.fpga_debug_data.pi_fifo_flags
|
||||
|
@ -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 {
|
||||
Unavailable,
|
||||
PowerOff,
|
||||
@ -875,10 +959,10 @@ impl Display for CicStep {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for CicStep {
|
||||
type Error = Error;
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
impl From<&[u8; 8]> for CicStep {
|
||||
fn from(value: &[u8; 8]) -> Self {
|
||||
let cic_step = (value[7] >> 4) & 0x0F;
|
||||
match cic_step {
|
||||
0 => Self::Unavailable,
|
||||
1 => Self::PowerOff,
|
||||
2 => Self::ConfigLoad,
|
||||
@ -895,49 +979,12 @@ impl TryFrom<u8> for CicStep {
|
||||
13 => Self::DieInvalidRegion,
|
||||
14 => Self::DieCommand,
|
||||
_ => 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 last_pi_address: u32,
|
||||
pub pi_io_access: PiIOAccess,
|
||||
pub pi_fifo_flags: PiFifoFlags,
|
||||
pub cic_step: CicStep,
|
||||
}
|
||||
@ -948,10 +995,11 @@ impl TryFrom<Vec<u8>> for FpgaDebugData {
|
||||
if value.len() != 8 {
|
||||
return Err(Error::new("Invalid data length for FPGA debug data"));
|
||||
}
|
||||
let data: &[u8; 8] = &value[0..8].try_into().unwrap();
|
||||
Ok(FpgaDebugData {
|
||||
last_pi_address: u32::from_be_bytes(value[0..4].try_into().unwrap()),
|
||||
pi_fifo_flags: (value[7] & 0x0F).try_into().unwrap(),
|
||||
cic_step: ((value[7] >> 4) & 0x0F).try_into().unwrap(),
|
||||
pi_io_access: data.into(),
|
||||
pi_fifo_flags: data.into(),
|
||||
cic_step: data.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user