⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i80386.vhd

📁 Intel微处理器80386的vhdl模拟
💻 VHD
📖 第 1 页 / 共 4 页
字号:
    -- 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 + -