fix: RESET pin active-LOW and clock edge state reset

This commit is contained in:
Jan-Peter von Hunnius 2026-02-26 11:04:25 +01:00
parent 1cf2cd6e2b
commit c9f39aa600
12 changed files with 520 additions and 327 deletions

View file

@ -396,21 +396,22 @@ mod tests {
assert_eq!(d2_pin.lock().unwrap().read(), PinValue::HighZ);
assert_eq!(d3_pin.lock().unwrap().read(), PinValue::HighZ);
// Test reset
// Test reset (RESET is active LOW)
println!("=== Testing Reset ===");
{
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
rom.update();
assert_eq!(rom.get_timing_state(), TimingState::Idle);
assert_eq!(rom.get_io_mode(), IoMode::Input);
// Set reset low
// Release reset (set HIGH for normal operation)
{
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
rom.update();
// Test memory read at address 0x00
println!("=== Memory Access Testing: Address 0x00 ===");
@ -427,7 +428,7 @@ mod tests {
println!("=== Memory Access Testing: Address 0xFF ===");
test_memory_read(
&mut rom, &sync_pin, &cm_pin, &ci_pin, &phi1_pin, &phi2_pin, &d0_pin, &d1_pin, &d2_pin,
&d3_pin, 0xFF, 0x0F, // 4-bit value (low nibble only)
&d3_pin, 0xFF, 0x0F, // 4-bit value (low nibble only)
);
// Test I/O operations
@ -437,19 +438,19 @@ mod tests {
// - CM (chip_select) = HIGH
// - CI (io_select) = HIGH
// - Proper clock edges to trigger the operation
// For this test, we'll verify the direct I/O port access methods work correctly
// since full I/O timing simulation would require more complex test setup.
// Test direct I/O port write (using set_io_port API)
rom.set_io_mode(IoMode::Output);
rom.set_io_port(0, 0x05).unwrap();
assert_eq!(rom.get_io_port(0).unwrap(), 0x05);
// Test I/O port read (using get_io_port API)
rom.set_io_port(0, 0x0A).unwrap();
assert_eq!(rom.get_io_port(0).unwrap(), 0x0A);
// Test that I/O direction is set to Output when we write
assert_eq!(rom.get_io_direction(0).unwrap(), IoDirection::Output);
@ -484,17 +485,17 @@ mod tests {
address: u8,
expected_data: u8,
) {
// Reset to known state first
// Reset to known state first (RESET is active LOW)
{
let reset_pin = rom.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
}
rom.update();
{
let reset_pin = rom.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
}
rom.update();
@ -716,8 +717,18 @@ mod tests {
let test_data = vec![expected_data];
chip.load_rom_data(test_data, addr).unwrap();
test_memory_read(
&mut chip, &sync_pin, &cm_pin, &ci_pin, &phi1_pin, &phi2_pin, &d0_pin, &d1_pin,
&d2_pin, &d3_pin, addr as u8, expected_data,
&mut chip,
&sync_pin,
&cm_pin,
&ci_pin,
&phi1_pin,
&phi2_pin,
&d0_pin,
&d1_pin,
&d2_pin,
&d3_pin,
addr as u8,
expected_data,
);
}
@ -1096,8 +1107,9 @@ mod tests {
expected_data: u8,
) -> u8 {
// Load the expected data into ROM at the specified address
chip.load_rom_data(vec![expected_data], address as usize).unwrap();
chip.load_rom_data(vec![expected_data], address as usize)
.unwrap();
// Reset to known state
chip.perform_reset();
chip.update();
@ -1283,8 +1295,9 @@ mod tests {
.set_settlement_time(Duration::from_nanos(0));
// Test memory read at maximum timing
// Note: Intel 4004 has a 4-bit data bus, so we can only read 4 bits at a time
let address = 0x23;
let expected_data = 0x45;
let expected_data = 0x05; // 4-bit value (low nibble only)
// Set up ROM data
chip.load_rom_data(vec![expected_data], address).unwrap();
@ -1704,17 +1717,17 @@ mod tests {
address: u16,
_expected_data: u8,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -1874,8 +1887,9 @@ mod tests {
.set_settlement_time(Duration::from_nanos(0));
// Test address setup time (minimum 100ns before PHI2 rising edge)
// Note: Intel 4004 has a 4-bit data bus, so we can only read 4 bits at a time
let address = 0x34;
let expected_data = 0x56;
let expected_data = 0x06; // 4-bit value (low nibble only)
// Set up ROM data
chip.load_rom_data(vec![expected_data], address).unwrap();
@ -2167,17 +2181,17 @@ mod tests {
address: u16,
setup_time_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -2287,17 +2301,17 @@ mod tests {
address: u16,
hold_time_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -2408,17 +2422,17 @@ mod tests {
setup_time_ns: u64,
hold_time_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -2531,17 +2545,17 @@ mod tests {
address: u16,
phase: &str,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -2704,17 +2718,17 @@ mod tests {
address: u16,
nibble_delay_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -2824,17 +2838,17 @@ mod tests {
address: u16,
setup_time_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -2951,17 +2965,17 @@ mod tests {
setup_time_ns: u64,
clock_period_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -3127,8 +3141,9 @@ mod tests {
.set_settlement_time(Duration::from_nanos(0));
// Test memory read with focus on clock edge relationships
// Note: Intel 4004 has a 4-bit data bus, so we can only read 4 bits at a time
let address = 0x45;
let expected_data = 0x67;
let expected_data = 0x07; // 4-bit value (low nibble only)
// Set up ROM data
chip.load_rom_data(vec![expected_data], address).unwrap();
@ -3526,17 +3541,17 @@ mod tests {
phi2_pin: &Arc<Mutex<Pin>>,
address: u16,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -3648,17 +3663,17 @@ mod tests {
phi2_pin: &Arc<Mutex<Pin>>,
address: u16,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -3770,17 +3785,17 @@ mod tests {
phi2_pin: &Arc<Mutex<Pin>>,
address: u16,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -3893,17 +3908,17 @@ mod tests {
address: u16,
spacing_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -4010,17 +4025,17 @@ mod tests {
address: u16,
jitter_ns: i64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -4163,17 +4178,17 @@ mod tests {
address: u16,
spacing_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset
}
chip.update();
@ -4280,17 +4295,17 @@ mod tests {
address: u16,
sequence: &str,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
}
chip.update();
@ -4516,17 +4531,17 @@ mod tests {
address: u16,
duty_cycle_percent: u8,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
}
chip.update();
@ -4646,17 +4661,17 @@ mod tests {
address: u16,
frequency_hz: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
}
chip.update();
@ -4766,17 +4781,17 @@ mod tests {
// Helper function for testing access time tolerance
fn test_access_time_tolerance(chip: &mut Intel4001, address: u16, _expected_data: u8) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
}
chip.update();
@ -4891,17 +4906,17 @@ mod tests {
_expected_data: u8,
timing_variation_ns: u64,
) -> u8 {
// Reset to known state
// Reset to known state (RESET is active LOW)
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low); // Assert reset (active LOW)
}
chip.update();
{
let reset_pin = chip.get_pin("RESET").unwrap();
let mut reset_guard = reset_pin.lock().unwrap();
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Release reset (HIGH = normal operation)
}
chip.update();
@ -6120,7 +6135,7 @@ mod tests {
// Test memory read with various timing tolerances
let address = 0x78;
let expected_data = 0x9A;
let expected_data = 0x0A; // 4-bit value (low nibble only)
// Set up ROM data
chip.load_rom_data(vec![expected_data], address).unwrap();