📄 i80386.vhd
字号:
-- Internal Control Logic Processes End -- Instruction Pre-Fetch, Decode and Execution Unit Begin InstDecode: PROCESS VARIABLE InstQueue: vlbit_2d(1 to 16,7 downto 0); VARIABLE InstQueueRd_Addr: INTEGER := 1; -- Address used by the decode unit to read the queue. VARIABLE InstQueueWr_Addr: INTEGER := 1; -- Address used by the Pre-fetch unit to fill the queue. VARIABLE InstQueueLimit: INTEGER := 16; -- Maximum length of the Queue. VARIABLE InstAddrPointer: INTEGER := 0; -- Allways points to the current instruction's Address. VARIABLE PhyAddrPointer: INTEGER := 0; -- Allways points to the Systems Physical Address. VARIABLE Extended: BOOLEAN := FALSE; -- True if an extended op-code prefix was detected. VARIABLE More: BOOLEAN := FALSE; -- True if instruction was decoded correctly and -- another read is needed for data. VARIABLE Flush: BOOLEAN := FALSE; -- True if JMP was executed, flush the Queue. VARIABLE First: BOOLEAN := TRUE; -- First time thru. VARIABLE Byte: vlbit_1d(7 downto 0); VARIABLE lWord: vlbit_1d(15 downto 0); VARIABLE uWord: vlbit_1d(15 downto 0); VARIABLE fWord: vlbit_1d(31 downto 0); VARIABLE Dummy: INTEGER; BEGIN IF First THEN PhyAddrPointer := integer(rEIP); InstAddrPointer := PhyAddrPointer; First := FALSE; END IF; RequestPending <= Pending; ReadRequest <= Pending; MemoryFetch <= Pending; CodeFetch <= Pending; IF Debug THEN put("DEBUG: Fetching 1st Word @ Addr=");Dummy := tohex(PhyAddrPointer,4);putline(""); END IF; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL pfalling(CLK); InstQueue(InstQueueWr_Addr) := Data(7 downto 0); InstQueueWr_Addr := InstQueueWr_Addr + 1; InstQueue(InstQueueWr_Addr) := Data(15 downto 8); InstQueueWr_Addr := InstQueueWr_Addr + 1; IF StateBS16 = '1' THEN -- A dWord code fetch InstQueue(InstQueueWr_Addr) := Data(23 downto 16); InstQueueWr_Addr := InstQueueWr_Addr + 1; InstQueue(InstQueueWr_Addr) := Data(31 downto 24); InstQueueWr_Addr := InstQueueWr_Addr + 1; PhyAddrPointer := PhyAddrPointer + 4; -- Point to next dWord since BS16- = 1 ELSE PhyAddrPointer := PhyAddrPointer + 2; -- Point to next word since BS16- = 0 IF Debug THEN put("DEBUG: Fetching 2nd Word @ Addr=");Dummy := tohex(PhyAddrPointer,4);putline(""); END IF; rEIP <= vlbit_vector(PhyAddrPointer); WAIT UNTIL prising(CLK); RequestPending <= Pending; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL pfalling(CLK); InstQueue(InstQueueWr_Addr) := Data(7 downto 0); InstQueueWr_Addr := InstQueueWr_Addr + 1; InstQueue(InstQueueWr_Addr) := Data(15 downto 8); InstQueueWr_Addr := InstQueueWr_Addr + 1; PhyAddrPointer := PhyAddrPointer + 2; -- Point to next word since BS16- = 0 END IF; Decode: WHILE InstQueueRd_Addr < InstQueueWr_Addr LOOP IF DEBUG THEN putline("DEBUG: InstQueueRd_Addr=",InstQueueRd_Addr); putline("DEBUG: InstQueueWr_Addr=",InstQueueWr_Addr); putline("DEBUG: InstQueueLimit=",InstQueueLimit); put("DEBUG: InstAddrPointer=");Dummy := tohex(InstAddrPointer,4);putline(""); put("DEBUG: PhyAddrPointer=");Dummy := tohex(PhyAddrPointer,4);putline(""); putline("DEBUG: Extended=",Extended); putline("DEBUG: Flush=",Flush); putline("DEBUG: More=",More); put("DEBUG: InstQueue( 1)=");Dummy := tohex(integer(InstQueue(1)),1);putline(""); put("DEBUG: InstQueue( 2)=");Dummy := tohex(integer(InstQueue(2)),1);putline(""); put("DEBUG: InstQueue( 3)=");Dummy := tohex(integer(InstQueue(3)),1);putline(""); put("DEBUG: InstQueue( 4)=");Dummy := tohex(integer(InstQueue(4)),1);putline(""); put("DEBUG: InstQueue( 5)=");Dummy := tohex(integer(InstQueue(5)),1);putline(""); put("DEBUG: InstQueue( 6)=");Dummy := tohex(integer(InstQueue(6)),1);putline(""); put("DEBUG: InstQueue( 7)=");Dummy := tohex(integer(InstQueue(7)),1);putline(""); put("DEBUG: InstQueue( 8)=");Dummy := tohex(integer(InstQueue(8)),1);putline(""); put("DEBUG: InstQueue( 9)=");Dummy := tohex(integer(InstQueue(9)),1);putline(""); put("DEBUG: InstQueue(10)=");Dummy := tohex(integer(InstQueue(10)),1);putline(""); put("DEBUG: InstQueue(11)=");Dummy := tohex(integer(InstQueue(11)),1);putline(""); put("DEBUG: InstQueue(12)=");Dummy := tohex(integer(InstQueue(12)),1);putline(""); put("DEBUG: InstQueue(13)=");Dummy := tohex(integer(InstQueue(13)),1);putline(""); put("DEBUG: InstQueue(14)=");Dummy := tohex(integer(InstQueue(14)),1);putline(""); put("DEBUG: InstQueue(15)=");Dummy := tohex(integer(InstQueue(15)),1);putline(""); put("DEBUG: InstQueue(16)=");Dummy := tohex(integer(InstQueue(16)),1);putline(""); END IF; CASE integer(InstQueue(InstQueueRd_Addr)) is WHEN NOP => InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; IF Debug OR Inst THEN putline("DEBUG: Executing NOP"); END IF; WHEN OPsop => InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Extended := TRUE; Flush := FALSE; More := FALSE; IF Debug OR Inst THEN put("DEBUG: Extended Op-Code Read:");Dummy := tohex(OPsop,1);putline(""); END IF; WHEN JMP_rel_short => IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 3 THEN IF Debug OR Inst THEN put("DEBUG: Executing JMP-Rel-Short from:");Dummy := tohex(InstAddrPointer,4); END IF; IF InstQueue(InstQueueRd_Addr+1,7) = '1' THEN -- Negative Offset PhyAddrPointer := InstAddrPointer + 1 - (16#FF# - integer(extendum(InstQueue(InstQueueRd_Addr+1),32))); InstAddrPointer := PhyAddrPointer; IF Debug OR Inst THEN put(" (-)To:");Dummy := tohex(PhyAddrPointer,4);putline(""); END IF; ELSE -- Positive Offset PhyAddrPointer := InstAddrPointer + 2 + integer(extendum(InstQueue(InstQueueRd_Addr+1),32)); InstAddrPointer := PhyAddrPointer; IF Debug OR Inst THEN put(" (+)To:");Dummy := tohex(PhyAddrPointer,4);putline(""); END IF; END IF; Flush := TRUE; More := FALSE; ELSE Flush := FALSE; More := TRUE; END IF; WHEN JMP_rel_near => IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 5 THEN IF Debug OR Inst THEN put("DEBUG: Executing JMP-Rel-Near from:");Dummy := tohex(InstAddrPointer,4); END IF; PhyAddrPointer := InstAddrPointer + 5 + integer(extendum(InstQueue(InstQueueRd_Addr+1),32)); InstAddrPointer := PhyAddrPointer; IF Debug OR Inst THEN put(" To:");Dummy := tohex(PhyAddrPointer,4);putline(""); END IF; Flush := TRUE; More := FALSE; ELSE Flush := FALSE; More := TRUE; END IF; WHEN JMP_intseg_immed =>-- To be Implemented (mad/8-23-1988) IF Debug OR Inst THEN putline("DEBUG: {TBD} Executing JMP-IntSeg-Immed from:",InstAddrPointer); END IF; InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; WHEN MOV_al_b =>-- To be Implemented (mad/8-23-1988) IF Debug OR Inst THEN putline("DEBUG: {TBD} Executing MOV-al<-byte"); END IF; InstAddrPointer := InstAddrPointer + 1; InstQueueRd_Addr := InstQueueRd_Addr + 1; Flush := FALSE; More := FALSE; WHEN MOV_eax_dw => IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 5 THEN IF Debug OR Inst THEN put("DEBUG: Executing MOV-eax<-dw"); END IF; -- Note Word position is swaped EAX <= InstQueue(InstQueueRd_Addr+4) & InstQueue(InstQueueRd_Addr+3) & InstQueue(InstQueueRd_Addr+2) & InstQueue(InstQueueRd_Addr+1); WAIT FOR 1; IF Debug OR Inst THEN put(" of:");Dummy := tohex(integer(EAX),4);putline(""); END IF; More := FALSE; Flush := FALSE; InstAddrPointer := InstAddrPointer + 5; InstQueueRd_Addr := InstQueueRd_Addr + 5; ELSE Flush := FALSE; More := TRUE; IF Debug THEN putline("DEBUG: Executing MOV-eax<-dw but ..."); putline("DEBUG: all of the immediate data is not in queue."); END IF; END IF; WHEN MOV_ebx_dw => IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 5 THEN IF Debug OR Inst THEN put("DEBUG: Executing MOV-ebx<-dw"); END IF; -- Note Word position is swaped EBX <= InstQueue(InstQueueRd_Addr+4) & InstQueue(InstQueueRd_Addr+3) & InstQueue(InstQueueRd_Addr+2) & InstQueue(InstQueueRd_Addr+1); WAIT FOR 1; IF Debug OR Inst THEN put(" of:");Dummy := tohex(integer(EBX),4);putline(""); END IF; More := FALSE; Flush := FALSE; InstAddrPointer := InstAddrPointer + 5; InstQueueRd_Addr := InstQueueRd_Addr + 5; ELSE Flush := FALSE; More := TRUE; IF Debug THEN putline("DEBUG: Executing MOV-ebx<-dw but ..."); putline("DEBUG: all of the immediate data is not in queue."); END IF; END IF; WHEN MOV_eax_ebx => -- Read at [ebx] to eax register IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN IF Debug OR Inst THEN put("DEBUG: Executing MOV-eax,[ebx]"); END IF; IF Debug OR Inst THEN put(" at address:");Dummy := tohex(integer(EBX),4);putline(""); END IF; rEIP <= EBX; RequestPending <= Pending; ReadRequest <= Pending; MemoryFetch <= Pending; CodeFetch <= NotPending; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL pfalling(CLK); uWord := Data(15 downto 0); IF StateBS16 = '1' THEN lWord := Data(31 downto 16); ELSE rEIP <= vlbit_vector(integer(rEIP) + 2); WAIT FOR 1; IF Debug THEN put("DEBUG: Reading Second Word at Addr=");Dummy := tohex(integer(rEIP),4);putline(""); END IF; WAIT UNTIL prising(CLK); RequestPending <= Pending; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL pfalling(CLK); lWord := Data(15 downto 0); END IF; EAX <= uWord & lWord; WAIT FOR 1; IF Debug OR Inst THEN put("DEBUG: Data=");Dummy := tohex(integer(EAX),4);putline(""); END IF; More := FALSE; Flush := FALSE; InstAddrPointer := InstAddrPointer + 2; InstQueueRd_Addr := InstQueueRd_Addr + 2; ELSE Flush := FALSE; More := TRUE; END IF; WHEN MOV_ebx_eax => -- Write at [ebx] from eax register IF (InstQueueWr_Addr - InstQueueRd_Addr) >= 2 THEN IF Debug OR Inst THEN put("DEBUG: Executing MOV-[ebx],eax"); END IF; IF Debug OR Inst THEN put(" at address:");Dummy := tohex(integer(EBX),4);putline(""); END IF; rEIP <= EBX; lWord := EAX(15 downto 0); uWord := EAX(31 downto 16); IF Debug OR Inst THEN put("DEBUG: Data=");Dummy := tohex(integer(EAX),4);putline(""); END IF; RequestPending <= Pending; ReadRequest <= NotPending; MemoryFetch <= Pending; CodeFetch <= NotPending; IF Debug THEN put("DEBUG: Writing First Word at Addr=");Dummy := tohex(integer(EBX),4);putline(""); END IF; WAIT UNTIL (integer(State) = StateT1 OR integer(State) = StateT1P); WAIT UNTIL prising(CLK); Data <= (uWord & lWord) after 480; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL prising(CLK); Data <= X"ZZZZZZZZ" after 480; WAIT FOR 1; IF StateBS16 = '0' THEN IF Debug THEN put("DEBUG: Writing Second Word at Addr=");Dummy := tohex(integer(EBX),4);putline(""); END IF; rEIP <= vlbit_vector(integer(rEIP) + 2); RequestPending <= Pending; ReadRequest <= NotPending; MemoryFetch <= Pending; CodeFetch <= NotPending; WAIT UNTIL (integer(State) = StateT1 OR integer(State) = StateT1P); WAIT UNTIL prising(CLK); Data <= (uWord & lWord) after 480; WAIT UNTIL pfalling(READY_n); RequestPending <= NotPending; WAIT UNTIL prising(CLK); Data <= X"ZZZZZZZZ" after 480;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -