1
+ // ------------------
2
+ // Interrupt Control
3
+
4
+ // This stuff looks complicated, because of old-school style #NMI edge-detection
5
+ // (edge detection is based on cross-coupled RS flip/flops)
6
+
7
+ module latch_suspicious (data_out, in, clk);
8
+ input in, clk;
9
+ output data_out;
10
+ reg data_out;
11
+
12
+ always @ (posedge clk)
13
+ data_out <= in;
14
+ endmodule
15
+
16
+ module InterruptControl (
17
+ // Outputs
18
+ Z_ADL0 , Z_ADL1 , Z_ADL2 , DORES , RESP , BRK6E , B_OUT ,
19
+ // Inputs
20
+ PHI0 , _NMI, _IRQ, _RES, _I_OUT, BR2 , T0 , BRK5 , _ready
21
+ );
22
+
23
+ input PHI0 , _NMI, _IRQ, _RES, _I_OUT, BR2 , T0 , BRK5 , _ready;
24
+ output Z_ADL0 , Z_ADL1 , Z_ADL2 , DORES , RESP , BRK6E , B_OUT ;
25
+
26
+ wire Z_ADL0 , Z_ADL1 , Z_ADL2 ;
27
+ wire DORES , RESP , BRK6E , B_OUT ;
28
+
29
+ // Clocks
30
+ wire PHI1 , PHI2 ;
31
+ assign PHI1 = ~ PHI0 ;
32
+ assign PHI2 = PHI0 ;
33
+
34
+ // Input pads flip/flops.
35
+ reg NMIP_FF , IRQP_FF , RESP_FF ;
36
+ wire _NMIP, _IRQP; // internal wires.
37
+ assign _NMIP = NMIP_FF ;
38
+ latch_suspicious IRQP_Latch (_IRQP, IRQP_FF , PHI1 );
39
+ latch_suspicious RESP_Latch (RESP , ~ RESP_FF , PHI1 );
40
+
41
+ // Interrupt cycle 6-7.
42
+ wire BRK7 ; // internal
43
+ wire Latch1_Out, Latch2_Out;
44
+ latch_suspicious Latch1 (Latch1_Out, BRK5 & ~ _ready, PHI2 );
45
+ latch_suspicious Latch2 (Latch2_Out, ~ (BRK5 & Latch2_Out) & ~ Latch1_Out, PHI1 );
46
+ latch_suspicious Latch3 (BRK6E , Latch2_Out, PHI2 );
47
+ assign BRK7 = ~ (Latch2_Out | BRK5 );
48
+
49
+ // Reset FLIP/FLOP
50
+ wire Latch4_Out, Latch5_Out;
51
+ latch_suspicious Latch4 (Latch4_Out, RESP , PHI2 );
52
+ latch_suspicious Latch5 (
53
+ Latch5_Out,
54
+ ~ (BRK6E | ~ (~ Latch4_Out | ~ Latch5_Out) ), PHI1 );
55
+ assign DORES = (~ Latch4_Out | ~ Latch5_Out); // DO Reset
56
+
57
+ // NMI Edge Detection
58
+ // CHECK : Does this stuff actually work at all after synthesize?
59
+ wire _DONMI; // internal
60
+ wire Latch6_Out, Latch7_Out, Latch8_Out, Latch9_Out;
61
+ wire Latch10_Out, Latch11_Out, Latch12_Out, LastLatch_Out;
62
+ wire temp;
63
+ latch_suspicious Latch6 (Latch6_Out, _NMIP, PHI1 );
64
+ latch_suspicious Latch7 (Latch7_Out, BRK7 , PHI2 );
65
+ latch_suspicious Latch8 (Latch8_Out, _DONMI, PHI2 );
66
+ latch_suspicious Latch9 (Latch9_Out, BRK6E & ~ _ready, PHI1 );
67
+ latch_suspicious Latch10 (Latch10_Out, _DONMI, PHI2 );
68
+ latch_suspicious Latch11 (Latch11_Out, ~ Latch10_Out, PHI1 );
69
+ assign temp = ~ ( Latch6_Out | (~ ( Latch11_Out | Latch12_Out)) );
70
+ latch_suspicious Latch12 (Latch12_Out, temp, PHI2 );
71
+ latch_suspicious LastLatch ( LastLatch_Out, ~ (~ Latch7_Out | _NMIP | temp), PHI1 );
72
+ assign _DONMI = ~ ( LastLatch_Out | ~ (Latch8_Out | Latch9_Out) ); // DO NMI after all
73
+
74
+ // Interrupt Check
75
+ wire IntCheck; // internal
76
+ assign IntCheck =
77
+ ( (~ ( ( ~ ( ~ (_I_OUT & ~ BRK6E ) | _IRQP) ) | ~ _DONMI )) | ~ (BR2 | T0 ));
78
+
79
+ // B-Flag
80
+ wire BLatch1_Out, BLatch2_Out;
81
+ latch_suspicious BLatch1 (BLatch1_Out, ~ (BRK6E | BLatch2_Out), PHI1 );
82
+ latch_suspicious BLatch2 (BLatch2_Out, IntCheck & ~ BLatch1_Out, PHI2 );
83
+ assign B_OUT = ~ ( (~ (BRK6E | BLatch2_Out)) | DORES ); // no need to do additional checks for RESET
84
+
85
+ // Interrupt Vector address lines controls.
86
+ // 0xFFFA NMI (ADL[2:0] = 3'b010)
87
+ // 0xFFFC RESET (ADL[2:0] = 3'b100)
88
+ // 0xFFFE IRQ (ADL[2:0] = 3'b110)
89
+ wire ADL0_Latch_Out, ADL1_Latch_Out, ADL2_Latch_Out;
90
+ latch_suspicious ADL0_Latch ( ADL0_Latch_Out, BRK5 , PHI2 );
91
+ latch_suspicious ADL1_Latch ( ADL1_Latch_Out, (BRK7 | ~ DORES ), PHI2 );
92
+ latch_suspicious ADL2_Latch ( ADL2_Latch_Out, ~ (BRK7 | _DONMI | DORES ), PHI2 );
93
+ assign Z_ADL0 = ~ ADL0_Latch_Out;
94
+ assign Z_ADL1 = ~ ADL1_Latch_Out;
95
+ assign Z_ADL2 = ADL2_Latch_Out; // watch this carefully
96
+
97
+ always # 1 @ (PHI2 ) begin // Lock pads on input FFs
98
+ NMIP_FF <= _NMI;
99
+ IRQP_FF <= _IRQ;
100
+ RESP_FF <= _RES;
101
+ end
102
+
103
+ endmodule // InterruptControl
0 commit comments