📄 i80386.vhd
字号:
WAIT FOR 1; END IF; More := FALSE; Flush := FALSE; InstAddrPointer := InstAddrPointer + 2; InstQueueRd_Addr := InstQueueRd_Addr + 2; ELSE Flush := FALSE; More := TRUE; END IF; WHEN IN_al => IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN IF Debug OR Inst THEN put("DEBUG: Executing IN-al"); END IF; rEIP <= extendum(InstQueue(InstQueueRd_Addr+1),32); WAIT FOR 1; IF Debug OR Inst THEN put(" from:");Dummy := tohex(integer(rEIP),4); END IF; RequestPending <= Pending; ReadRequest <= Pending; MemoryFetch <= NotPending; CodeFetch <= NotPending; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL pfalling(CLK); EAX(7 downto 0) <= Data(7 downto 0); WAIT FOR 1; IF Debug OR Inst THEN put(" Data=");Dummy := tohex(integer(EAX(7 downto 0)),1);putline(""); END IF; InstAddrPointer := InstAddrPointer + 2; InstQueueRd_Addr := InstQueueRd_Addr + 2; Flush := FALSE; More := FALSE; ELSE Flush := FALSE; More := TRUE; IF Debug THEN putline("DEBUG: Executing IN-al but ..."); putline("DEBUG: the immediate Address is not in queue."); END IF; END IF; WHEN OUT_al => IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN IF Debug OR Inst THEN put("DEBUG: Executing OUT-al"); END IF; rEIP <= extendum(InstQueue(InstQueueRd_Addr+1),32); WAIT FOR 1; IF Debug OR Inst THEN put(" to:");Dummy := tohex(integer(rEIP),4); END IF; RequestPending <= Pending; ReadRequest <= NotPending; MemoryFetch <= NotPending; CodeFetch <= NotPending; IF Debug OR Inst THEN put(" Data=");Dummy := tohex(integer(EAX(7 downto 0)),1);putline(""); END IF; WAIT UNTIL (integer(State) = StateT1 OR integer(State) = StateT1P); WAIT UNTIL prising(CLK); fWord := X"ZZZZZZ" & EAX(7 downto 0); Data <= fWord after 480; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL prising(CLK); Data <= X"ZZZZZZZZ" after 480; WAIT FOR 1; InstAddrPointer := InstAddrPointer + 2; InstQueueRd_Addr := InstQueueRd_Addr + 2; Flush := FALSE; More := FALSE; ELSE Flush := FALSE; More := TRUE; IF Debug THEN putline("DEBUG: Executing OUT-al but ..."); putline("DEBUG: the immediate Address is not in queue."); END IF; END IF; WHEN ADD_al_b =>-- To be Implemented (mad/8-23-1988) IF Debug OR Inst THEN putline("DEBUG: {TBD} Executing ADD-al to byte:"); END IF; InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; WHEN ADD_ax_w =>-- To be Implemented (mad/8-23-1988) IF Debug OR Inst THEN putline("DEBUG: {TBD} Executing ADD-ax to word:"); END IF; InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; WHEN ROL_al_1 =>-- To be Implemented (mad/8-23-1988) IF Debug OR Inst THEN putline("DEBUG: {TBD} Executing ROL-al left one bit"); END IF; InstAddrPointer := InstAddrPointer + 2; InstQueueRd_Addr := InstQueueRd_Addr + 2; Flush := FALSE; More := FALSE; WHEN ROL_al_n =>-- To be Implemented (mad/8-23-1988) IF Debug OR Inst THEN putline("DEBUG: {TBD} Executing ROL-al by:"); END IF; InstAddrPointer := InstAddrPointer + 2; InstQueueRd_Addr := InstQueueRd_Addr + 2; Flush := FALSE; More := FALSE; WHEN INC_eax => EAX <= vlbit_vector(integer(EAX) + 1); WAIT FOR 1; IF Debug OR Inst THEN put("DEBUG: Executing INC-eax by 1 to:");Dummy := tohex(integer(EAX),4);putline(""); END IF; InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; WHEN INC_ebx => EBX <= vlbit_vector(integer(EBX) + 1); WAIT FOR 1; IF Debug OR Inst THEN put("DEBUG: Executing INC-ebx by 1 to:");Dummy := tohex(integer(EBX),4);putline(""); END IF; InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; WHEN OTHERS => put("ERROR: Invalid Instruction=");Dummy := tohex(integer(InstQueue(InstQueueRd_Addr)),1);putline(""); InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; END CASE; EXIT WHEN ((InstQueueLimit - InstQueueRd_Addr) < 4) OR Flush OR More; END LOOP Decode; IF Flush THEN InstQueueRd_Addr := 1; InstQueueWr_Addr := 1; fWord := vlbit_vector(InstAddrPointer); IF fWord(0) = '1' THEN InstQueueRd_Addr := InstQueueRd_Addr + integer(extendum(fWord(1 downto 0),32)); END IF; IF Debug THEN putline("DEBUG: Flushing Instruction Queue"); END IF; END IF; IF (InstQueueLimit - InstQueueRd_Addr) < 3 THEN -- The queue is about to be bounded. -- This section implements the circular queue. IF Debug THEN putline("DEBUG: Instruction Queue Length Execeeded"); putline("DEBUG: Implementing Circular Queue"); END IF; InstQueueWr_Addr := 1; Circular: WHILE InstQueueRd_Addr <= InstQueueLimit LOOP InstQueue(InstQueueWr_Addr) := InstQueue(InstQueueRd_Addr); InstQueueRd_Addr := InstQueueRd_Addr + 1; InstQueueWr_Addr := InstQueueWr_Addr + 1; END LOOP Circular; InstQueueRd_Addr := 1; END IF; IF Debug THEN putline("DEBUG: Request Pending, filling Queue at:",InstQueueWr_Addr); END IF; rEIP <= vlbit_vector(PhyAddrPointer); WAIT UNTIL prising(CLK); end PROCESS InstDecode; -- Instruction Pre-Fetch, Decode and Execution Unit Begin -- ByteEnables Begin GenByteEnables: PROCESS (rEIP) BEGIN CASE integer(DataWidth) is WHEN WidthByte => CASE integer(rEIP(1 downto 0)) is -- A[1:0] WHEN 0 => ByteEnable <= B"1110"; WHEN 1 => ByteEnable <= B"1101"; WHEN 2 => ByteEnable <= B"1011"; WHEN 3 => ByteEnable <= B"0111"; WHEN OTHERS => NULL; END CASE; WHEN WidthWord => CASE integer(rEIP(1 downto 0)) is -- A[1:0] WHEN 0 => ByteEnable <= B"1100"; NonAligned <= NotPending; WHEN 1 => ByteEnable <= B"1001"; NonAligned <= NotPending; WHEN 2 => ByteEnable <= B"0011"; NonAligned <= NotPending; WHEN 3 => IF Debug THEN putline("DEBUG: Non-Aligned Word"); END IF; ByteEnable <= B"0111"; NonAligned <= Pending; WHEN OTHERS => NULL; END CASE; WHEN WidthDword => CASE integer(rEIP(1 downto 0)) is -- A[1:0] WHEN 0 => ByteEnable <= B"0000"; NonAligned <= NotPending; WHEN 1 => IF Debug THEN putline("DEBUG: Non-Aligned Dword"); END IF; ByteEnable <= B"0001"; NonAligned <= Pending; WHEN 2 => IF Debug THEN putline("DEBUG: Non-Aligned Dword"); END IF; NonAligned <= Pending; ByteEnable <= B"0011"; WHEN 3 => IF Debug THEN putline("DEBUG: Non-Aligned Dword"); END IF; NonAligned <= Pending; ByteEnable <= B"0111"; WHEN OTHERS => NULL; END CASE; WHEN OTHERS => putline("MODEL ERROR: Data Path Width Fault: DataWidth"); putline("MODEL ERROR: Width Selected was:",integer(DataWidth)); END CASE; end PROCESS GenByteEnables; -- ByteEnables End -- Bus Interface Unit Begin GenBusIntf: PROCESS (State) BEGIN CASE integer(State) is WHEN StateT1 | StateT2P => Address <= rEIP(31 downto 2) after 40ns; IF Debug THEN-- putline("DEBUG: Next Address=",rEIP); END IF; BE_n <= ByteEnable after 30ns; M_IO_n <= MemoryFetch; IF ReadRequest = Pending THEN W_R_n <= '0' after 30ns; ELSE W_R_n <= '1' after 30ns; END IF; IF CodeFetch = Pending THEN D_C_n <= '0' after 30ns; ELSE D_C_n <= '1' after 30ns; END IF; WHEN OTHERS => NULL; END CASE; CASE integer(State) is WHEN StateT1 => ADS_n <= '0' after 25ns; WHEN StateT2 => ADS_n <= '1' after 25ns; WHEN StateT1P => ADS_n <= '1' after 25ns; WHEN StateT2P => ADS_n <= '0' after 25ns; WHEN OTHERS => NULL; END CASE; end PROCESS GenBusIntf; BS16: PROCESS BEGIN WAIT UNTIL integer(State) = StateT2 OR integer(State) = StateT1P; WHILE integer(State) = StateT2 OR integer(State) = StateT1P LOOP WAIT UNTIL prising(CLK); StateBS16 <= BS16_n; IF BS16_n = '0' THEN DataWidth <= vlbit_vector(Widthword); -- WidthByte, WidthWord, WidthDword ELSE DataWidth <= vlbit_vector(WidthDword); END IF; END LOOP; end PROCESS BS16; NA: PROCESS BEGIN WAIT UNTIL integer(State) = StateT2 OR integer(State) = StateT1P; WAIT UNTIL prising(CLK); StateNA <= NA_n; end PROCESS NA; -- Bus Interface Unit End-- End Behavioral Blocksend behavior;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -