├── .gitignore ├── pipe.png ├── interrupt.jpg ├── interrupt_2.png ├── LICENSE.txt ├── README.md ├── controller_pipe.vhd └── controller_interrupt.vhd /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | controller1.0/ 3 | computer_INT/ -------------------------------------------------------------------------------- /pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WadeChiang/CPU-Controller-TEC-8/HEAD/pipe.png -------------------------------------------------------------------------------- /interrupt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WadeChiang/CPU-Controller-TEC-8/HEAD/interrupt.jpg -------------------------------------------------------------------------------- /interrupt_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WadeChiang/CPU-Controller-TEC-8/HEAD/interrupt_2.png -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 Wade Chiang and others 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BUPT Computer Architecture Course Design -- 一款基于 Altera EPM7128 的硬连线控制器 2 | 3 | 小组成员: 4 | 5 | [@weikeduo1](https://github.com/weikeduo1) 6 | 7 | [@Jaskon863](https://github.com/Jaskon863) 8 | 9 | [@Monstry](https://github.com/Monstry) 10 | 11 | @WadeChiang (me) 12 | 13 | ## Feature 14 | 15 | ### Pipeline version 16 | 17 | - [x] 基础功能 18 | - [x] 流水 19 | - [ ] 中断 20 | 21 | ### Interrupt version 22 | 23 | - [x] 基础功能 24 | - [ ] 流水 25 | - [x] 中断 26 | 27 | ## 设计流程图 28 | 29 | ### Pipeline version 30 | 31 | ![pipeline](pipe.png) 32 | 33 | 说明: 34 | 35 | 为什么 ADD, SUB, JC, JZ, LD 要放弃流水,延迟一个机器周期取指? 36 | 37 | 这是 TEC-8 的硬件问题。如果你用全流水的版本测试过本课程的样例程序,你就会发现大多数 TEC-8 实验台会非常神奇地在 SUB 和 LD 这两个指令的取指中按相反的次序触发 LIR 和 PCINC 信号,于是你成功取到了下下条指令。在我们自己的测试程序中 ADD, JC , JZ 出现了相同的问题.尤其是 JC & JZ:把 W2 置为空周期,在 W3 取指就不会反序触发 LIR 和 PCINC ,在 W2 取指,不行,在 W3 取指,行。只能说哇,TEC-8,哇。 38 | 39 | ### Interrupt version 40 | 41 | ![i1](interrupt.jpg) 42 | 43 | ![i2](interrupt_2.png) 44 | 45 | 说明: 46 | 47 | 中断的实现方式: 48 | 49 | 由于 TEC-8 中唯一一个与 PC 有数据通路的中断寄存器 IAR 并没有引脚连接 EPM7128,所以我们无法直接读到 PC 的数据并将其存在 RAM 中。因此,在中断版本中我们牺牲了一个寄存器 R3,令其始终与 PC 的值保持同步,通过在断点保存程序中保存 R3 实现 PC 的存储。 50 | 51 | 我们遇到的另一个困难是, EMP7128 没有任何信号直接连接总线,因此不可能通过控制器控制应该在哪里储存寄存器值,以及哪里是中断服务程序的入口地址。为了完成中断,我们需要三个地址: 52 | 53 | 1. 中断现场的存储地址。我们通过中断服务程序的第一个机器周期,用开关 S7-S0 将其置入 AR 中。 54 | 2. 中断服务程序的入口地址。在向 RAM 中写入程序时预置。假设中断现场的存储首地址为 ADDR0, 中断服务程序的入口地址为 ADDR1,那么 [ADDR0 + 4] = ADDR1。这样断点保存程序就可以获取中断服务程序入口 ADDR1,将其载入 PC 与 R3. 55 | 3. 中断现场的存储地址。中断服务程序结束后,仍需要获得 ADDR0 才能返回断点。若中断服务程序的最后一条指令 IRET(必须是它!)的地址为 ADDR2,那么 [ADDR2 +1] = ADDR0. 这样中断返回程序就能读取到它,并且将所有的寄存器值恢复原样。 56 | 57 | ## 最后 58 | 59 | 再碰 TEC-8 我就是狗。 -------------------------------------------------------------------------------- /controller_pipe.vhd: -------------------------------------------------------------------------------- 1 | ---------THIS FILE CODED IN UTF-8-------- 2 | library ieee; 3 | use ieee.std_logic_1164.all; 4 | use ieee.std_logic_unsigned.all; 5 | entity controller_pipe is --定义实体, 端口 6 | port ( 7 | -------- INPUT SIGNAL-------- 8 | --复位信号,低电平有效 9 | CLR : in STD_LOGIC; 10 | --运行模式:读写寄存器/RAM,执行程序 11 | SWA, SWB, SWC : in STD_LOGIC; 12 | --指令 13 | IR7, IR6, IR5, IR4 : in STD_LOGIC; 14 | --机器周期:W1(始终有效),W2(当SHORT=TRUE时被跳过),W3(LONG=TURE时才进入) 15 | --T3:每个机器周期的最后一个时钟周期 16 | W1, W2, W3, T3 : in STD_LOGIC; 17 | --进位和零标识 18 | C, Z : in STD_LOGIC; 19 | 20 | -------- OUTPUT SIGNAL -------- 21 | --ALU运算模式 22 | S : out STD_LOGIC_VECTOR(3 downto 0); 23 | --SEL3-0,(3,2)为ALU左端口MUX输入,也是 DBUS2REGISTER 的片选信号.(1,0)为ALU右端口MUX输入 24 | SEL_L, SEL_R : out STD_LOGIC_VECTOR(1 downto 0); 25 | --写寄存器使能 26 | DRW : out STD_LOGIC; 27 | --读寄存器使能 28 | MEMW : out STD_LOGIC; 29 | --PCINC:PC自增,PCADD:+offset 30 | PCINC, PCADD : out STD_LOGIC; 31 | --写PC,AR,IR和标志寄存器使能 32 | LPC, LAR, LIR, LDZ, LDC : out STD_LOGIC; 33 | --AR自增 34 | ARINC : out STD_LOGIC; 35 | --停止产生时钟信号 36 | STP : out STD_LOGIC; 37 | --进入控制台模式 38 | SELCTL : out STD_LOGIC; 39 | --74181进位输入信号 40 | CIN : out STD_LOGIC; 41 | --运算模式:M=0为算术运算;M=1为逻辑运算 42 | M : out STD_LOGIC; 43 | --总线使能 44 | ABUS, SBUS, MBUS : out STD_LOGIC; 45 | --控制指令周期中机器周期数量,SHORT=TRUE时W2被跳过,LONG=TURE时才会进入W3 46 | SHORT, LONG : out STD_LOGIC 47 | ); 48 | end controller_pipe; 49 | 50 | architecture struct of controller_pipe is 51 | --定义信号 52 | signal SW : STD_LOGIC_VECTOR(2 downto 0); 53 | signal IR : STD_LOGIC_VECTOR(3 downto 0); 54 | signal ST0, SST0 : STD_LOGIC; 55 | begin 56 | --定义, 组合信号 57 | SW <= SWC & SWB & SWA; 58 | IR <= IR7 & IR6 & IR5 & IR4; 59 | --main process 60 | process (W3, W2, W1, T3, SW, IR, CLR) 61 | begin 62 | --initialization 63 | S <= "0000"; 64 | SEL_L <= "00"; 65 | SEL_R <= "00"; 66 | DRW <= '0'; 67 | MEMW <= '0'; 68 | PCINC <= '0'; 69 | PCADD <= '0'; 70 | LPC <= '0'; 71 | LAR <= '0'; 72 | LIR <= '0'; 73 | LDZ <= '0'; 74 | LDC <= '0'; 75 | ARINC <= '0'; 76 | STP <= '0'; 77 | SELCTL <= '0'; 78 | CIN <= '0'; 79 | M <= '0'; 80 | MEMW <= '0'; 81 | ABUS <= '0'; 82 | SBUS <= '0'; 83 | MBUS <= '0'; 84 | SHORT <= '0'; 85 | LONG <= '0'; 86 | 87 | --CLR=0 -> clear PC & IR & ST0 88 | if CLR = '0' then 89 | ST0 <= '0'; 90 | SST0 <= '0'; 91 | --Assign SST0 2 ST0 at T3 falling edge 92 | elsif falling_edge(T3) then 93 | if SST0 = '1' then 94 | ST0 <= '1'; 95 | end if; 96 | end if; 97 | --SWCBA 98 | case SW is 99 | when "001" => --写存储器 100 | SBUS <= '1'; 101 | STP <= '1'; 102 | SHORT <= '1'; 103 | SELCTL <= '1'; 104 | LAR <= not ST0; 105 | MEMW <= ST0; 106 | ARINC <= ST0; 107 | if ST0 <= '0' then 108 | SST0 <= '1'; 109 | end if; 110 | when "010" => --读存储器 111 | SHORT <= '1'; 112 | STP <= '1'; 113 | SELCTL <= '1'; 114 | SBUS <= not ST0; 115 | LAR <= not ST0; 116 | MBUS <= ST0; 117 | ARINC <= ST0; 118 | if ST0 <= '0' then 119 | SST0 <= '1'; 120 | end if; 121 | when "100" => --写寄存器 122 | SBUS <= '1'; 123 | SEL_L(1) <= ST0; --SEL3 124 | SEL_L(0) <= W2; --SEL2 125 | SEL_R(1) <= (not ST0 and W1) or (ST0 and W2); --SEL1 126 | SEL_R(0) <= W1; --SEL0 127 | if ST0 <= '0' and W2 = '1' then 128 | SST0 <= '1'; 129 | end if; 130 | SELCTL <= '1'; 131 | DRW <= '1'; 132 | STP <= '1'; 133 | when "011" => --读寄存器 134 | SEL_L(1) <= W2; 135 | SEL_L(0) <= '0'; 136 | SEL_R(1) <= W2; 137 | SEL_R(0) <= '1'; 138 | SELCTL <= '1'; 139 | STP <= '1'; 140 | when "000" => --取指 141 | if ST0 = '0' then 142 | LPC <= W1; 143 | SBUS <= W1; 144 | STP <= W1 or W2; 145 | LIR <= W2; 146 | PCINC <= W2; 147 | if ST0 <= '0' and W2 = '1'then 148 | SST0 <= '1'; 149 | end if; 150 | else 151 | case IR is 152 | when "0000" => --NOP 153 | LIR <= W1; 154 | PCINC <= W1; 155 | SHORT <= W1; 156 | when "0001" => --ADD 157 | S <= "1001"; 158 | M <= not W1; 159 | CIN <= W1; 160 | ABUS <= W1; 161 | DRW <= W1; 162 | LDZ <= W1; 163 | LDC <= W1; 164 | LIR <= W2; 165 | PCINC <= W2; 166 | --SHORT <= W1; 167 | when "0010" => --SUB 168 | S <= "0110"; 169 | M <= '0'; 170 | CIN <= '0'; 171 | ABUS <= W1; 172 | DRW <= W1; 173 | LDZ <= W1; 174 | LDC <= W1; 175 | LIR <= W2; 176 | PCINC <= W2; 177 | --SHORT <= W1; 178 | when "0011" => --AND 179 | M <= W1; 180 | S <= "1011"; 181 | ABUS <= W1; 182 | DRW <= W1; 183 | LDZ <= W1; 184 | LIR <= W1; 185 | PCINC <= W1; 186 | SHORT <= W1; 187 | when "0100" => --INC 188 | S <= "0000"; 189 | M <= not W1; 190 | ABUS <= W1; 191 | CIN <= not W1; 192 | DRW <= W1; 193 | LDZ <= W1; 194 | LDC <= W1; 195 | LIR <= W1; 196 | PCINC <= W1; 197 | SHORT <= W1; 198 | when "0101" => --LD 199 | S <= "1010"; 200 | M <= W1; 201 | ABUS <= W1; 202 | LAR <= W1; 203 | MBUS <= W2; 204 | DRW <= W2; 205 | LONG <= '1'; 206 | LIR <= W3; 207 | PCINC <= W3; 208 | when "0110" => --ST 209 | M <= W1 or W2; 210 | if W1 = '1' then 211 | S <= "1111"; 212 | elsif W2 = '1' then 213 | S <= "1010"; 214 | end if; 215 | ABUS <= W1 or W2; 216 | LAR <= W1; 217 | MEMW <= W2; 218 | LIR <= W2; 219 | PCINC <= W2; 220 | when "0111" => --JC 221 | if C = '0' then 222 | LIR <= W1; 223 | PCINC <= W1; 224 | SHORT <= W1; 225 | else 226 | PCADD <= W1; 227 | LIR <= W3; 228 | LONG <= '1'; 229 | PCINC <= W3; 230 | end if; 231 | when "1000" => --JZ 232 | if Z = '0' then 233 | LIR <= W1; 234 | PCINC <= W1; 235 | SHORT <= W1; 236 | else 237 | PCADD <= W1; 238 | LIR <= W3; 239 | LONG <= '1'; 240 | PCINC <= W3; 241 | end if; 242 | when "1001" => --JMP 243 | M <= W1; 244 | S <= "1111"; 245 | ABUS <= W1; 246 | LPC <= W1; 247 | LIR <= W2; 248 | PCINC <= W2; 249 | when "1010" => --MOV 250 | M <= W1; 251 | S <= "1010"; 252 | ABUS <= W1; 253 | DRW <= W1; 254 | LIR <= W1; 255 | PCINC <= W1; 256 | SHORT <= W1; 257 | when "1011" => --CMP 258 | S <= "0110"; 259 | M <= not W1; 260 | CIN <= not W1; 261 | ABUS <= W1; 262 | LDC <= W1; 263 | LDZ <= W1; 264 | LIR <= W1; 265 | PCINC <= W1; 266 | SHORT <= W1; 267 | when "1100" => --OR 268 | M <= W1; 269 | S <= "1110"; 270 | ABUS <= W1; 271 | DRW <= W1; 272 | LDC <= W1; 273 | LIR <= W1; 274 | PCINC <= W1; 275 | SHORT <= W1; 276 | when "1101" => --*****OUT****** 277 | M <= W1; 278 | S <= "1010"; 279 | ABUS <= W1; 280 | LIR <= W1; 281 | PCINC <= W1; 282 | SHORT <= W1; 283 | when "1110" => --STP 284 | STP <= W1; 285 | when "1111" => --NOT 286 | M <= W1; 287 | S <= "0000"; 288 | ABUS <= W1; 289 | DRW <= W1; 290 | LDC <= W1; 291 | LIR <= W1; 292 | PCINC <= W1; 293 | SHORT <= W1; 294 | when others => null; 295 | end case; 296 | --END CASE IR 297 | end if; 298 | --END IF ST0 299 | when others => null; 300 | end case; 301 | --END CASE SW 302 | end process; 303 | end struct; -------------------------------------------------------------------------------- /controller_interrupt.vhd: -------------------------------------------------------------------------------- 1 | ---------THIS FILE CODED IN UTF-8-------- 2 | library ieee; 3 | use ieee.std_logic_1164.all; 4 | use ieee.std_logic_unsigned.all; 5 | entity controller_interrupt is 6 | port ( 7 | -------- INPUT SIGNAL-------- 8 | --复位信号,低电平有效 9 | CLR : in STD_LOGIC; 10 | --运行模式:读写寄存器/RAM,执行程序 11 | SWA, SWB, SWC : in STD_LOGIC; 12 | --指令 13 | IR7, IR6, IR5, IR4 : in STD_LOGIC; 14 | --机器周期:W1(始终有效),W2(当SHORT=TRUE时被跳过),W3(LONG=TURE时才进入) 15 | --T3:每个机器周期的最后一个时钟周期 16 | W1, W2, W3, T3 : in STD_LOGIC; 17 | --进位和零标识 18 | C, Z : in STD_LOGIC; 19 | --中断标识 20 | PULSE : in STD_LOGIC; 21 | -------- OUTPUT SIGNAL -------- 22 | --ALU运算模式 23 | S : out STD_LOGIC_VECTOR(3 downto 0); 24 | --SEL3-0,(3,2)为ALU左端口MUX输入,也是 DBUS2REGISTER 的片选信号.(1,0)为ALU右端口MUX输入 25 | SEL_L, SEL_R : out STD_LOGIC_VECTOR(1 downto 0); 26 | --写寄存器使能 27 | DRW : out STD_LOGIC; 28 | --读寄存器使能 29 | MEMW : out STD_LOGIC; 30 | --PCINC:PC自增,PCADD:+offset 31 | PCINC, PCADD : out STD_LOGIC; 32 | --写PC,AR,IR和标志寄存器使能 33 | LPC, LAR, LIR, LDZ, LDC : out STD_LOGIC; 34 | --AR自增 35 | ARINC : out STD_LOGIC; 36 | --停止产生时钟信号 37 | STP : out STD_LOGIC; 38 | --进入控制台模式 39 | SELCTL : out STD_LOGIC; 40 | --74181进位输入信号 41 | CIN : out STD_LOGIC; 42 | --运算模式:M=0为算术运算;M=1为逻辑运算 43 | M : out STD_LOGIC; 44 | --总线使能 45 | ABUS, SBUS, MBUS : out STD_LOGIC; 46 | --控制指令周期中机器周期数量,SHORT=TRUE时W2被跳过,LONG=TURE时才会进入W3 47 | SHORT, LONG : out STD_LOGIC 48 | ); 49 | end controller_interrupt; 50 | 51 | architecture struct of controller_interrupt is 52 | signal SW : STD_LOGIC_VECTOR(2 downto 0); 53 | signal IR : STD_LOGIC_VECTOR(3 downto 0); 54 | signal ST0, SST0 : STD_LOGIC; 55 | signal EN_INT, IS_INT : STD_LOGIC; --EN_INT: 中断允许标志, IS_INT: 是否在中断中标识 56 | signal INT_FLAG, INT_FFLAG : STD_LOGIC_VECTOR(1 downto 0); --断点保存与断点恢复所在周期标志 57 | signal RUN_SAVE, C_RUN_SAVE : STD_LOGIC; --进入断点保存程序标志 58 | signal RUN_RET, C_RUN_RET : STD_LOGIC; --进入断点恢复程序标志 59 | begin 60 | SW <= SWC & SWB & SWA; 61 | IR <= IR7 & IR6 & IR5 & IR4; 62 | --main process 63 | process (W3, W2, W1, T3, SW, IR, CLR, PULSE) 64 | begin 65 | --Initialization. 66 | S <= "0000"; 67 | SEL_L <= "00"; 68 | SEL_R <= "00"; 69 | DRW <= '0'; 70 | MEMW <= '0'; 71 | PCINC <= '0'; 72 | LPC <= '0'; 73 | LAR <= '0'; 74 | LIR <= '0'; 75 | LDZ <= '0'; 76 | LDC <= '0'; 77 | ARINC <= '0'; 78 | STP <= '0'; 79 | PCADD <= '0'; 80 | SELCTL <= '0'; 81 | CIN <= '0'; 82 | M <= '0'; 83 | MEMW <= '0'; 84 | ABUS <= '0'; 85 | SBUS <= '0'; 86 | MBUS <= '0'; 87 | SHORT <= '0'; 88 | LONG <= '0'; 89 | --CLR=0 -> clear PC & IR & ST0 & EN_INT, INT_FLAGs, RUN_s 90 | if CLR = '0' then 91 | ST0 <= '0'; 92 | SST0 <= '0'; 93 | EN_INT <= '0'; 94 | IS_INT <= '0'; 95 | INT_FLAG <= "00"; 96 | INT_FFLAG <= "00"; 97 | RUN_SAVE <= '0'; 98 | C_RUN_SAVE <= '0'; 99 | RUN_RET <= '0'; 100 | C_RUN_RET <= '0'; 101 | --Assign SST0 2 ST0, INT_FFLAG 2 INT_FLAG, C_RUN_SAVE 2 RUN_SAVE, C_RUN_RET 2 RUN_RET at T3 falling edge 102 | elsif falling_edge(T3) then 103 | ST0 <= SST0; 104 | INT_FLAG <= INT_FFLAG; 105 | RUN_SAVE <= C_RUN_SAVE; 106 | RUN_RET <= C_RUN_RET; 107 | end if; 108 | --If true, set IS_INT to '1',start interrupt. 109 | if PULSE = '1' and EN_INT = '1' then 110 | IS_INT <= '1'; 111 | STP <= '1'; 112 | end if; 113 | --SWCBA 114 | case SW is 115 | when "001" => --写存储器 116 | SBUS <= '1'; 117 | STP <= '1'; 118 | SHORT <= '1'; 119 | SELCTL <= '1'; 120 | LAR <= not ST0; 121 | MEMW <= ST0; 122 | ARINC <= ST0; 123 | if ST0 <= '0' then 124 | SST0 <= '1'; 125 | end if; 126 | when "010" => --读存储器 127 | SHORT <= '1'; 128 | STP <= '1'; 129 | SELCTL <= '1'; 130 | SBUS <= not ST0; 131 | LAR <= not ST0; 132 | MBUS <= ST0; 133 | ARINC <= ST0; 134 | if ST0 <= '0' then 135 | SST0 <= '1'; 136 | end if; 137 | when "100" => --写寄存器 138 | SBUS <= '1'; 139 | SEL_L(1) <= ST0; --SEL3 140 | SEL_L(0) <= W2; --SEL2 141 | SEL_R(1) <= (not ST0 and W1) or (ST0 and W2); --SEL1 142 | SEL_R(0) <= W1; --SEL0 143 | if ST0 <= '0' and W2 = '1' then 144 | SST0 <= '1'; 145 | end if; 146 | SELCTL <= '1'; 147 | DRW <= '1'; 148 | STP <= '1'; 149 | when "011" => --读寄存器 150 | SEL_L(1) <= W2; 151 | SEL_L(0) <= '0'; 152 | SEL_R(1) <= W2; 153 | SEL_R(0) <= '1'; 154 | SELCTL <= '1'; 155 | STP <= '1'; 156 | when "000" => --取指 & 中断 157 | if RUN_SAVE = '1' then --Save break point. 158 | case INT_FLAG is 159 | when "00" => 160 | STP <= '1'; 161 | SBUS <= W1; 162 | LAR <= W1; 163 | M <= W2; 164 | S <= W2 & W2 & W2 & W2; 165 | ABUS <= W2; 166 | MEMW <= W2; 167 | SELCTL <= W2; 168 | SEL_L <= W2 & W2; 169 | ARINC <= W2; 170 | if W2 = '1' then 171 | INT_FFLAG <= "01"; 172 | else 173 | INT_FFLAG <= "00"; 174 | end if; 175 | when "01" => 176 | LONG <= W2; 177 | STP <= '1'; 178 | M <= W1 or W2 or W3; 179 | S <= "1111"; 180 | ABUS <= '1'; 181 | MEMW <= '1'; 182 | SELCTL <= '1'; 183 | SEL_L <= W3 & W2; 184 | ARINC <= '1'; 185 | if W3 = '1' then 186 | INT_FFLAG <= "10"; 187 | end if; 188 | when "10" => 189 | STP <= '1'; 190 | MBUS <= '1'; 191 | DRW <= W1; 192 | SELCTL <= W1; 193 | SEL_L <= W1 & W1; 194 | LPC <= W2; 195 | if W2 = '1' then 196 | INT_FFLAG <= "00"; 197 | IS_INT <= '0'; 198 | C_RUN_SAVE <= '0'; 199 | end if; 200 | when others => null; 201 | end case; 202 | --END CASE INT_FLAG 203 | elsif RUN_RET = '1' then --Return to break point. 204 | case INT_FLAG is 205 | when "00" => 206 | C_RUN_RET <= '1'; 207 | STP <= '1'; 208 | M <= W1; 209 | S <= W1 & W1 & W1 & W1; 210 | ABUS <= W1; 211 | SELCTL <= W1; 212 | SEL_L <= W1 & W1; 213 | LAR <= W1 or W2; 214 | MBUS <= W2; 215 | if W2 = '1' then 216 | INT_FFLAG <= "01"; 217 | else 218 | INT_FFLAG <= "00"; 219 | end if; 220 | when "01" => 221 | C_RUN_RET <= '1'; 222 | STP <= '1'; 223 | MBUS <= W1 or W2; 224 | DRW <= W1; 225 | SELCTL <= W1; 226 | SEL_L <= W1 & W1; 227 | LPC <= W2; 228 | ARINC <= W2; 229 | if W2 = '1' then 230 | INT_FFLAG <= "10"; 231 | else 232 | INT_FFLAG <= "01"; 233 | end if; 234 | when "10" => 235 | C_RUN_RET <= W1 or W2; 236 | STP <= '1'; 237 | MBUS <= '1'; 238 | LONG <= '1'; 239 | DRW <= '1'; 240 | SELCTL <= '1'; 241 | SEL_L <= W3 & W2; 242 | ARINC <= W1 or W2; 243 | LIR <= W3; 244 | PCINC <= W3; 245 | if W3 = '1' then 246 | EN_INT <= '1'; 247 | INT_FFLAG <= "00"; 248 | C_RUN_RET <= '0'; 249 | else 250 | INT_FFLAG <= "10"; 251 | end if; 252 | when others => null; 253 | end case; 254 | --END CASE INT_FLAG 255 | else 256 | if ST0 = '0' then 257 | --Pointer of PC 258 | LPC <= W1; 259 | SBUS <= W1 or W2; 260 | STP <= W1 or W2; 261 | DRW <= W2; 262 | SELCTL <= W2; 263 | SEL_L <= W2 & W2; 264 | if ST0 <= '0' and W2 = '1'then 265 | SST0 <= '1'; 266 | end if; 267 | else 268 | --Public Operation: LIR, PCINC & INC R3 269 | if W1 = '1' then 270 | S <= not W1 & not W1 & not W1 & not W1; 271 | M <= not W1; 272 | CIN <= not W1; 273 | ABUS <= W1; 274 | DRW <= W1; 275 | SELCTL <= W1; 276 | SEL_L <= W1 & W1; 277 | LIR <= W1; 278 | PCINC <= W1; 279 | else 280 | -- Normal instruction. 281 | case IR is 282 | when "0000" => --NOP 283 | if IS_INT = '1' and W2 = '1' then 284 | C_RUN_SAVE <= '1'; 285 | end if; 286 | when "0001" => --ADD 287 | S <= W2 & not W2 & not W2 & W2; 288 | M <= not W2; 289 | CIN <= W2; 290 | ABUS <= W2; 291 | DRW <= W2; 292 | LDZ <= W2; 293 | LDC <= W2; 294 | if IS_INT = '1' and W2 = '1' then 295 | C_RUN_SAVE <= '1'; 296 | end if; 297 | when "0010" => --SUB 298 | S <= not W2 & W2 & W2 & not W2; 299 | M <= W2; 300 | CIN <= W2; 301 | ABUS <= W2; 302 | DRW <= W2; 303 | LDZ <= W2; 304 | LDC <= W2; 305 | if IS_INT = '1' and W2 = '1' then 306 | C_RUN_SAVE <= '1'; 307 | end if; 308 | when "0011" => --AND 309 | M <= W2; 310 | S <= W2 & not W2 & W2 & W2; 311 | ABUS <= W2; 312 | DRW <= W2; 313 | LDZ <= W2; 314 | if IS_INT = '1' and W2 = '1' then 315 | C_RUN_SAVE <= '1'; 316 | end if; 317 | when "0100" => --INC 318 | S <= not W2 & not W2 & not W2 & not W2; 319 | M <= not W2; 320 | ABUS <= W2; 321 | CIN <= not W2; 322 | DRW <= W2; 323 | LDZ <= W2; 324 | LDC <= W2; 325 | if IS_INT = '1' and W2 = '1' then 326 | C_RUN_SAVE <= '1'; 327 | end if; 328 | when "0101" => --LD 329 | LONG <= W2; 330 | S <= W2 & not W2 & W2 & not W2; 331 | M <= W2; 332 | ABUS <= W2; 333 | LAR <= W2; 334 | MBUS <= W3; 335 | DRW <= W3; 336 | if IS_INT = '1' and W3 = '1' then 337 | C_RUN_SAVE <= '1'; 338 | end if; 339 | when "0110" => --ST 340 | LONG <= W2; 341 | M <= W2 or W3; 342 | if W2 = '1' then 343 | S <= "1111"; 344 | elsif W3 = '1' then 345 | S <= "1010"; 346 | end if; 347 | ABUS <= W2 or W3; 348 | LAR <= W2; 349 | MEMW <= W3; 350 | if IS_INT = '1' and W3 = '1' then 351 | C_RUN_SAVE <= '1'; 352 | end if; 353 | when "0111" => --JC 354 | if C = '0' then 355 | if IS_INT = '1' and W2 = '1' then 356 | C_RUN_SAVE <= '1'; 357 | end if; 358 | else 359 | LONG <= W2; 360 | M <= W2 or W3; 361 | if W2 = '1' or W3 = '1' then 362 | S <= "1111"; 363 | end if; 364 | ABUS <= W2; 365 | LPC <= W2; 366 | SELCTL <= W3; 367 | SEL_L <= W3 & W3; 368 | DRW <= W3; 369 | if IS_INT = '1' and W3 = '1' then 370 | C_RUN_SAVE <= '1'; 371 | end if; 372 | end if; 373 | when "1000" => --JZ 374 | if Z = '0' then 375 | if IS_INT = '1' and W2 = '1' then 376 | C_RUN_SAVE <= '1'; 377 | end if; 378 | else 379 | LONG <= W2; 380 | M <= W2 or W3; 381 | if W2 = '1' or W3 = '1' then 382 | S <= "1111"; 383 | end if; 384 | ABUS <= W2; 385 | LPC <= W2; 386 | SELCTL <= W3; 387 | SEL_L <= W3 & W3; 388 | DRW <= W3; 389 | if IS_INT = '1' and W3 = '1' then 390 | C_RUN_SAVE <= '1'; 391 | end if; 392 | end if; 393 | when "1001" => --JMP 394 | LONG <= W2; 395 | M <= W2 or W3; 396 | if w2 = '1' or W3 = '1' then 397 | S <= "1010"; 398 | end if; 399 | ABUS <= W2 or W3; 400 | LPC <= W2; 401 | DRW <= W3; 402 | if IS_INT = '1' and W3 = '1' then 403 | C_RUN_SAVE <= '1'; 404 | end if; 405 | when "1010" => --EI 406 | EN_INT <= '1'; 407 | if IS_INT = '1' and W2 = '1' then 408 | C_RUN_SAVE <= '1'; --Set RUN_SAVE to '1' while falling edge of T3 409 | end if; 410 | when "1011" => --DI 411 | EN_INT <= '0'; 412 | when "1100" => --OR 413 | M <= W2; 414 | S <= W2 & W2 & W2 & not W2; 415 | ABUS <= W2; 416 | DRW <= W2; 417 | LDC <= W2; 418 | if IS_INT = '1' and W2 = '1' then 419 | C_RUN_SAVE <= '1'; 420 | end if; 421 | when "1101" => --OUT 422 | M <= W2; 423 | S <= W2 & not W2 & W2 & not W2; 424 | ABUS <= W2; 425 | SHORT <= W2; 426 | if IS_INT = '1' and W2 = '1' then 427 | C_RUN_SAVE <= '1'; 428 | end if; 429 | when "1110" => --STP 430 | STP <= W2; 431 | when "1111" => --IRET 432 | STP <= W2; 433 | if W2 = '1' then 434 | C_RUN_RET <= '1'; --Set RUN_RET to '1' while falling edge of T3 435 | end if; 436 | when others => null; 437 | end case; 438 | --END CASE IR 439 | end if; 440 | end if; 441 | --END IF ST0 442 | end if; 443 | --END IF RUN_SAVE & ELSIF RUN_RET 444 | when others => null; 445 | end case; 446 | --END CASE SW 447 | end process; 448 | end struct; --------------------------------------------------------------------------------