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

@ -45,6 +45,7 @@ fn test_intel_4001_state_machine_progression() {
}
// Initialize control pins
// Note: RESET is active LOW, so set it to High to ensure component is not in reset
{
let mut sync_guard = sync_pin.lock().unwrap();
let mut cm_guard = cm_pin.lock().unwrap();
@ -53,7 +54,7 @@ fn test_intel_4001_state_machine_progression() {
sync_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
cm_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
ci_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
reset_guard.set_driver(Some("TEST".to_string()), PinValue::High); // Not in reset
}
// Initialize data pins to Low
@ -142,7 +143,8 @@ fn test_intel_4001_state_machine_progression() {
// Wait for pins to settle
thread::sleep(Duration::from_millis(1));
// Trigger Φ1 rising edge again to latch low nibble
// Trigger Φ1 rising edge again - ROM should stay in AddressPhase
// (address nibbles are latched on Φ1 falling edge, not rising)
{
let mut phi1_guard = phi1_pin.lock().unwrap();
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::High);
@ -151,27 +153,40 @@ fn test_intel_4001_state_machine_progression() {
// Update to process Φ1 rising edge
rom.update();
// Should have latched low nibble and transitioned to WaitLatency or DriveData
// With 1ns access time, it might transition directly to DriveData
let state_after_low_nibble = rom.get_timing_state();
assert!(
state_after_low_nibble == TimingState::WaitLatency
|| state_after_low_nibble == TimingState::DriveData
// Should still be in AddressPhase (latching happens on falling edge)
assert_eq!(
rom.get_timing_state(),
TimingState::AddressPhase,
"Should still be in AddressPhase after Φ1 rising - latching happens on falling edge"
);
println!(
"State after Φ1 rising (low nibble): {:?}",
state_after_low_nibble
"State after Φ1 rising (before falling): {:?}",
rom.get_timing_state()
);
// Reset Φ1 to Low
// Reset Φ1 to Low to trigger falling edge - this is when low nibble is latched
{
let mut phi1_guard = phi1_pin.lock().unwrap();
phi1_guard.set_driver(Some("TEST".to_string()), PinValue::Low);
}
// Update to process Φ1 falling edge
// Update to process Φ1 falling edge - low nibble is latched here
rom.update();
// Should have latched low nibble and transitioned to WaitLatency or DriveData
// With 1ns access time, it might transition directly to DriveData
let state_after_low_nibble = rom.get_timing_state();
assert!(
state_after_low_nibble == TimingState::WaitLatency
|| state_after_low_nibble == TimingState::DriveData,
"Expected WaitLatency or DriveData after latching both nibbles, got {:?}",
state_after_low_nibble
);
println!(
"State after Φ1 falling (low nibble latched): {:?}",
state_after_low_nibble
);
// Remove test drivers from data pins to allow ROM to drive bus
{
let mut d0_guard = d0_pin.lock().unwrap();
@ -342,10 +357,10 @@ fn test_intel_4001_state_machine_reset() {
// Should have started memory operation and transitioned to AddressPhase
assert_eq!(rom.get_timing_state(), TimingState::AddressPhase);
// Assert RESET
// Assert RESET (active LOW - set to Low to trigger 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);
}
// Update to process reset