Skip to content

maram-daas/logisim-interrupt-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

Overview

This project implements a complete hierarchical interrupt system with a Daisy-Chain recognition circuit, a phase-driven sequencer, and a detailed ROM built with transistor, fully designed and simulated in Logisim (classic/legacy version). The .circ file must be opened with the original Logisim (not Logisim Evolution or any fork), or else it won't behave I guess.


File

  • Format: .circ (Logisim classic, version 2.7.1)

Circuit List

The file contains 8 subcircuits:

  1. A-1 int system 4-level hierarchical interrupt system with mask and cause registers

  2. A-2 extension Same as A-1, extended with a hardware priority encoder to identify the highest active interrupt level as a 2-bit number

  3. B-1 single cell Single Daisy-Chain cell: given an interrupt signal and an incoming acknowledgment, it decides whether to claim the interrupt or pass the acknowledgment to the next cell

  4. B-1 full circuit — Four B-1 cells wired in series, where the first cell has highest priority; together they identify which of the 4 devices triggered the interrupt and output its 2-bit number

  5. B-2 Full interrupt system integrating the Daisy-Chain on Level 1, and the hardware extension from A-2.

  6. C-1 4-phase distributor generating non-overlapping phases and short pulses

  7. C-2 ROM ROM storing the 4 ISR addresses, built using only transistors, pull resistors, and basic gates, no memory components used

  8. C-5 complete circuit Full integration of all components into one top-level circuit


Here's the Detailed Explanation and Working Logic Behind Each One


A-1 int system: Hierarchical Interrupt System

Level Priority Sources Description
0 Highest 1 (source 0) Power failure alert
1 High 4 (disk 0–3) Disk management
2 Medium 6 (R0 – R5) Room alarm system
3 Lowest 4 (cause 0–3) Reserved sources

The room alarm interrupt for room 4 and 5 is disabled, and the causes 0 to 3 are also disabled, for customization reasons, unable them by changing the constants controlling them.

Each source goes through the same 3-stage pipeline:

Source input
    → Cause register (D flip-flop, latches the signal)
        → AND gate with mask bit (enables/disables this source)
            → OR gate (fires if any unmasked source is active)
                → Level register (D flip-flop, stores the level state)

All mask bits are initialized to 1 at startup (all interrupts enabled). Level 2 has 6 inputs but only 4 are active — R 4 and R 5 exist in the circuit with their mask bits fixed at 0, representing the two rooms not yet wired.

The 4 level register outputs are ORed and gated through a validity flip-flop (initialized to 1) to produce the global interrupt request signal, which drives an LED (BI):

Level 0 reg ─┐
Level 1 reg ─┤
             ├─ OR ── AND ── D flip-flop ── LED
Level 2 reg ─┤          ↑
Level 3 reg ─┘      Validity FF (=1)

In all circuits other than A-1, mask register inputs are replaced with a hardwired constant 1 to simplify testing without needing to set the mask manually each time.


A-2 extension: Hardware Priority Recognition

Identical to A-1, with one addition: after the level registers, a Priority Encoder takes the 4 level outputs and produces a 2-bit code representing the highest active level. This goes through a NOT gate, is ANDed with the validity flip-flop output, latched into a D flip-flop, and exported as the "running level" 2-bit output:

Level regs → Priority Encoder → NOT → AND → D flip-flop → "running level" (2-bit out)
                                              ↑
                                          Validity FF

This lets the sequencer instantly know which level is active in hardware, with no software polling needed.


B-1 single cell: Daisy-Chain Cell

The fundamental building block. Each cell is connected to one interrupt controller and sits in a chain where acknowledgment flows from left (highest priority) to right (lowest priority).

Inputs: int request, ack-inOutputs: ENABLE, ack-out

Scenario Condition Result
1 int request = 1 AND ack-in = 1 This cell is the highest priority requester — ENABLE = 1, ack-out = 0
2 int request = 1 AND ack-in = 0 A higher priority cell already claimed it — nothing happens, ack-out = 0
3 int request = 0 No interrupt from this cell — ack-out = ack-in (passed through unchanged)

Internal logic:

int request ──────────────── NOT ──┐
                │                  AND ── ack-out
ack-in ─────────┼─────────────────┘
                │
                └──── AND ── ENABLE
ack-in ──────────────┘
  • ENABLE = int request AND ack-in
  • ack-out = NOT(int request) AND ack-in

Three gates total per cell. When ENABLE goes high, the external circuit uses it to place the device number on the data bus.


B-1 full circuit: Complete 4-Cell Daisy-Chain

Four B-1 single cell instances cascaded in a chain. Cell 0 has the highest priority, Cell 3 the lowest. The CPU's acknowledgment signal enters at Cell 0 and ripples right:

CPU ack ──► [Cell 0] ──► [Cell 1] ──► [Cell 2] ──► [Cell 3] ──► ack-out
             int 0         int 1         int 2         int 3
              │             │             │             │
           ENABLE 0      ENABLE 1      ENABLE 2      ENABLE 3
                \            \            \            \
                 └────────────┴────────────┴────────────┴──► Priority Encoder
                                                                    │
                                                               devnum (2-bit)

The 4 ENABLE signals feed a Priority Encoder which outputs the 2-bit number of the highest priority active cell. This device number is split and exported as devnum0 and devnum1, along with INT REQ OUTPUT and output ack.


B-2 Interrupt System with Daisy-Chain on Level 1

The full 4-level interrupt system where Level 1 uses the Daisy-Chain for cause identification. The 4 disk inputs feed both the standard cause registers and the daisy-chain cells in parallel:

disk 0–3 ──┬──► Cause registers ──► Mask ──► OR ──┐
           │                                       AND ── Level 1 interrupt signal
           └──► B-1 Daisy-Chain ──► INT REQ OUT ──┘
                      │
                 devnum (2-bit) ──► "Disk number" output

The active interrupt level is also encoded and exported as the running level (2-bit), using the same Priority Encoder + NOT + validity structure as A-2.


C-1 4-Phase Distributor

A 2-bit Counter (max = 3, falling-edge triggered) increments each clock cycle. Its output feeds a 2-to-4 Decoder, producing 4 non-overlapping phase signals. Each phase is then ANDed with the raw clock to produce a short pulse active only during the clock's high half:

Clock ──► Counter (2-bit, mod-4) ──► Decoder ──► Φ0, Φ1, Φ2, Φ3  (phases)
  │                                                │    │    │    │
  └──────────────────────────────────────────── AND  AND  AND  AND
                                                  │    │    │    │
                                                 Θ0   Θ1   Θ2   Θ3  (pulses)

Clock configured at highDuration = 2, lowDuration = 2.


C-2 ROM Transistor-Level ROM

Stores 4 ISR addresses. Built entirely with transistors no Logisim memory components are used anywhere in this circuit.

Cause (address) ISR address
00 00001111
01 00011100
10 00110000
11 01000110

How it works:

devnum (2-bit)
     │
     ▼
[2-4 decoder] ← built from NOT + AND gates only
  l0  l1  l2  l3   (word lines, one per row)
   │   │   │   │
   ▼   ▼   ▼   ▼
  [bit columns — 8 total]
   │
   Each column: POWER ── Pull Resistor ── bit line
                                              │
                            N-transistor present → pulls to GND = bit 0
                            N-transistor absent  → stays HIGH   = bit 1
   │
   ▼
[Controlled Buffer] ← enabled by Read-req signal
   │
   ▼
[Splitter] → result adr (8-bit output)

The transistor pattern across the 4 rows encodes the 4 addresses. The 2-4 decoder subcircuit inside is also fully gate-level (NOT + AND gates only).


C-3 Sequencer

Integrates the phase distributor, B-1 full circuit, and C-2 ROM into the complete interrupt handling sequence:

Step Phase Action Signal
0 Φ0 Detect active interrupt level phase 0 exported
1 Φ1 Latch device number from Daisy-Chain Φ1 pulse clocks save-devnum0/1 and save-int-req-out
2 Φ2 Address ROM with device number, read ISR address Φ2 triggers Read-req; ROM output latched into OROM register
3 Φ3 Load ISR address into PC TDA gate (int-req-out AND Φ3 pulse) loads IPC register
Φ0: detect level
      │
Φ1: ack-in → Daisy-Chain → ENABLE → devnum latched into save-devnum0/1
      │
Φ2: devnum → ROM address → Read-req → ISR address latched into OROM
      │
Φ3: OROM → TDA gate → PC loaded (IPC)

Named control signals visible in the schematic: OROM (ROM output register), IRAR (interrupt address register), TDA (transfer enable to PC), IPC (load PC).


C-5 complete circuit, Full Integration

All components wired into one top-level circuit. The interrupt system (A-2 style), phase distributor, B-1 full circuit, and C-2 ROM are all present and connected. A Comparator checks if the running level equals 01 (Level 1) to produce the intlvl1 flag. The daisy-chain ack-in is gated as intlvl1 AND phase1. Device number bits are latched by their respective pulses, the ROM is addressed and read in Φ2, and the PC is loaded in Φ3 via the TDA gate. Tunnels (d0–d3) carry phase signals cleanly across the circuit.


Known Timing Issue in C-5, Not Fixed (most likely won't be)

The circuit works correctly but takes extra clock cycles to complete the sequence instead of the ideal 4 phases.

Cause: The intlvl1 signal is the end of a long combinational chain:

Level registers → Priority Encoder → Comparator → intlvl1 → AND → ack-in → Daisy-Chain

In Logisim classic, when a combinational signal crosses a subcircuit boundary, the simulator needs an extra tick to propagate and settle it,

By the time ack-in reaches the daisy-chain, Phase 1 may already be partially elapsed, pushing every subsequent step one cycle late, and the circuit has to repeat itself 2 times to work.

Suggested fix (not implemented yet because I forgot abt it lol) : Add a pipeline register at the end of Φ0 to latch intlvl1 before Φ1 begins. Apply the same principle at every phase boundary, each phase should only consume values latched at the end of the previous phase:

Φ0 ends → latch intlvl1
Φ1 starts → use registered intlvl1 for ack-in → latch devnum at end of Φ1
Φ2 starts → use registered devnum for ROM address → latch ROM output at end of Φ2
Φ3 starts → load registered ROM output into PC

I don't think anyone will read all of this but if you did, THANKS you're really cool I like you ^^ !

made with <3.

About

Gate-level hierarchical interrupt system with Daisy-Chain recognition, transistor-level ROM, Phase Distributor, and Sequencer in Logisim.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors