proc_rtl.vhd

来自「Intel微处理器8088的VHDL实现」· VHDL 代码 · 共 950 行 · 第 1/5 页

VHD
950
字号
                            end if;
                                                        
                            -- Load memory into ALUREG                          
                            path_s.alu_operation<= DONTCARE(3 downto 0) & REG_MDBUS &  ALU_REGL; -- selalua(4) & selalub(4) & aluopr(7)                            
                            wrpath_s.wralu  <= '1';                     -- ver 0.69,  write MDBUS to ALUREG
    
                            if (instr.ireg(1)='1') then                             
                                passcnt_s   <= status.cl5;              -- Load CL loop counter
                            end if;                                     -- else passcnt_s=1;

                        else                                            -- second pass, MDBUS contains memory byte
                            
                            -- selalua & selalu are dontcare
                            -- ALU_ROL(6 downto 4) is generic for all shift/rotate                                                                      
                            path_s.alu_operation<= DONTCARE(3 downto 0) & '0'&instr.rm & ALU_ROL(6 downto 4)& instr.ireg(1) & instr.reg; -- selalua(4) & selalub(4) & aluopr(7)

                            wrpath_s.wrcc   <= '1';                     -- Update Status Register after each shift/rot
                                                     
                            --if (passcnt="00001") then                 -- Check if end of shift/rotate
                            if (passcnt="00000") then                   -- ver 0.69, Check if end of shift/rotate
                                second_pass_s <= '0';                   -- clear    
                                wrpath_s.wrip <= '1';                   -- Update IP+nbreq register 
                                next_state <= Swritemem;                -- write result to memory & terminate                   
                            else
                                passcnt_s <= passcnt - '1';
                                second_pass_s <= '1';   
                                wrpath_s.wralu<= '1';                   -- Update ALUREG                    
                                next_state <= Sdecode;                  -- round the loop again                             
                            end if; 
                                                           
                        end if; 

                    end if;

                ---------------------------------------------------------------------------------
                -- Immediate to Register
                ---------------------------------------------------------------------------------
                when MOVI2R0 | MOVI2R1 |MOVI2R2 |MOVI2R3 |MOVI2R4 | MOVI2R5 | MOVI2R6 | MOVI2R7 | 
                     MOVI2R8 | MOVI2R9 |MOVI2R10|MOVI2R11|MOVI2R12| MOVI2R13| MOVI2R14| MOVI2R15  =>

                    second_pass_s <= '0';                    
                    path_s.datareg_input<= DATAIN_IN & instr.ireg(3) & instr.reg; -- dimux & w & seldreg
                    path_s.ea_output    <= NB_CS_IP;                    -- IPREG+NB ADDR=CS:IP

                    wrpath_s.wrd        <= '1';                         -- Write to Data Register
                    wrpath_s.wrip       <= '1';                         -- Update IP+nbreq register
                    
                    next_state  <= Sexecute;

                ---------------------------------------------------------------------------------
                -- Immediate to Register/Memory      0xC6, 0xC7
                -- Data is routed from drmux->dibus->dbusdp_out
                ---------------------------------------------------------------------------------
                when MOVI2RM0 | MOVI2RM1  =>

                    second_pass_s <= '0';
                    path_s.datareg_input<= DATAIN_IN & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg (only dimux, the rest is don't care)    
                                                                        -- change to instr.ireg(0) & instr.reg ???                  
                    path_s.dbus_output  <= DIBUS_OUT;                   --{eabus(0)&} domux setting                     
                    path_s.ea_output    <= NB_DS_EA;                    -- dispmux & eamux & segop  (unless Segment OP flag is set)
                    
                    wrpath_s.wrip       <= '1';                         -- Update IP+nbreq register
                    
                    next_state  <= Swritemem;                           -- start write cycle        

                ---------------------------------------------------------------------------------
                -- Memory to Accu and Accu to Memory AL, AX, not AH!             0xA0..0xA3
                -- Use fake xmod and rm setting
                -- Use instruction but (4..3)=000 as register selector
                ---------------------------------------------------------------------------------
                when MOVM2A0 | MOVM2A1 | MOVA2M0 | MOVA2M1  =>

                    second_pass_s <= '0';
                    path_s.datareg_input<= MDBUS_IN & instr.ireg(0) & instr.reg;    -- dimux & w & seldreg  (don't care for write cycle)
                    
                    path_s.alu_operation<= '0'&instr.reg & DONTCARE(3 downto 0) & ALU_PASSA;  -- selalua & selalub & aluopr  (don't care for read cycle)
                    path_s.dbus_output  <= ALUBUS_OUT;                  --{eabus(0)&} domux setting  (don't care for read cycle)
                    
                    path_s.ea_output    <= NB_DS_EA;                    -- dispmux & eamux & segop  (unless Segment OP flag is set)

                    if instr.ireg(1)='0' then                           -- 0= memory to Accu, Read Cycle                        
                        wrpath_s.wrd        <= '1';                     -- Write Memory to Data Register
                        wrpath_s.wrip       <= '1';                     -- Update IP+nbreq register
                    
                        next_state  <= Sreadmem;                        -- start read cycle     
                    else                                                -- 1=Accu to Memory, Write cycle
                        wrpath_s.wrip       <= '1';                     -- Update IP+nbreq register
                    
                        next_state  <= Swritemem;                       -- start write cycle        
                    end if;

                ---------------------------------------------------------------------------------
                -- Move Register/Memory to/from Register   0x88..0x8B   
                ---------------------------------------------------------------------------------
                when MOVRM2R0 | MOVRM2R1 | MOVRM2R2 | MOVRM2R3 =>

                    second_pass_s <= '0';
                    if instr.xmod="11" then                             -- Register to Register  rm=reg field
                        if instr.ireg(1)='0' then                       -- Check 'd' bit, 0-> SRC=Reg, DEST=rm
                            path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.rm;    -- dimux & w & seldreg
                            path_s.alu_operation<= '0'&instr.reg & DONTCARE(3 downto 0) & ALU_PASSA;  -- selalua & selalub & aluopr                          
                        else                                            -- 'd'=1 SRC=rm, DEST=Reg 
                            path_s.datareg_input<= ALUBUS_IN & instr.ireg(0) & instr.reg;   -- dimux & w & seldreg
                            path_s.alu_operation<= '0'&instr.rm & DONTCARE(3 downto 0) & ALU_PASSA;  -- selalua & selalub & aluopr
                        end if;
                        path_s.ea_output    <= NB_CS_IP;                -- IPREG+NB ADDR=CS:IP
                                                                                            
                        wrpath_s.wrd        <= '1';                     -- Write Data Register to Data Register
                        wrpath_s.wrip       <= '1';                     -- Update IP+nbreq register
                    
                        next_state <= Sexecute;

                    else                                                -- Source is memory
                        if instr.ireg(1)='0' then                       -- Check 'd' bit, 0-> SRC=Reg, DEST=rm, Write Cycle
                            path_s.alu_operation<= '0'&instr.reg & DONTCARE(3 downto 0) & ALU_PASSA;  -- selalua & selalub & aluopr
                            path_s.dbus_output  <= ALUBUS_OUT;          --{eabus(0)&} domux setting 
                            path_s.datareg_input<= DONTCARE(2 downto 0) & instr.ireg(0) & DONTCARE(2 downto 0); -- dimux & w & seldreg 
                                                                                                                -- (only need w, the reset don't care)
                            path_s.ea_output    <= NB_DS_EA;            -- dispmux & eamux & segop  (unless Segment OP flag is set)

                            wrpath_s.wrip       <= '1';                 -- Update IP+nbreq register
                    
                            next_state  <= Swritemem;                   -- start write cycle            
                                                    
                        else                                            -- 'd'=1 SRC=rm, DEST=Reg, Read Cycle 
                            path_s.datareg_input<= MDBUS_IN & instr.ireg(0) & instr.reg;    -- dimux & w & seldreg
                            path_s.alu_operation<= '0'&instr.rm & DONTCARE(3 downto 0) & ALU_PASSA;  -- selalua & selalub & aluopr

                            path_s.ea_output    <= NB_DS_EA;            -- dispmux & eamux & segop  (unless Segment OP flag is set)

                            wrpath_s.wrd        <= '1';                 -- Write Memory to Data Register
                            wrpath_s.wrip       <= '1';                 -- Update IP+nbreq register
                    
                            next_state  <= Sreadmem;                    -- start read cycle             
                        end if;                     


                    end if;
                   
                ---------------------------------------------------------------------------------
                -- Move Segment register to data register or memory 
                ---------------------------------------------------------------------------------
                when MOVS2RM => 
                                                                    
                    second_pass_s <= '0';
                    if instr.xmod="11" then                             -- Segment Register to Data Register , rm=reg field

                        path_s.datareg_input<= '1'& instr.reg(1 downto 0) & '1' & instr.rm;     -- dimux & w & seldreg                          
                        path_s.ea_output    <= NB_CS_IP;                -- IPREG+NB ADDR=CS:IP

                        wrpath_s.wrd        <= '1';                     -- Write Seg to Data Register
                        wrpath_s.wrip       <= '1';                     -- Update IP+nbreq register
                    
                        next_state <= Sexecute;
                    else                                                -- Segment Register to memory indexed by rm
                        
                        path_s.datareg_input<= '1'& instr.reg(1 downto 0) & '1' & DONTCARE(2 downto 0);     -- dimux only -- [dimux(3) & w & seldreg(3)]
                        path_s.dbus_output  <= DIBUS_OUT;               --(Odd/Even) domux setting
                        path_s.ea_output    <= NB_DS_EA;                -- dispmux & eamux & segop  (unless Segment OP flag is set)

                        wrpath_s.wrip       <= '1';                     -- Update IP+nbreq register
                    
                        next_state  <= Swritemem;                       -- start write cycle                          
                    end if; 

                ---------------------------------------------------------------------------------
                -- Register or Memory to Segment Register
                -- In case of memory, stalls until operand is read from memory
                ---------------------------------------------------------------------------------
                when MOVRM2S => 

                    irq_blocked_s <= '1';                               -- Block IRQ if asserted during next instr.

                    second_pass_s <= '0';
                    if instr.reg(1 downto 0)="01" then
                        proc_error_s<='1';                              -- if segment register = CS report error
                        -- pragma synthesis_off
                        report "MOVRM2S : MOV CS,REG/Memory not valid" severity failure;
                        -- pragma synthesis_on
                    end if;

                    path_s.datareg_input<= DONTCARE(2 downto 0)& '1' & DONTCARE(2 downto 0);  -- dimux & w=1 & seldreg  
                                        
                    if instr.xmod="11" then                             -- Register to Segment Register , rm=reg field

                        path_s.alu_operation<= '0'&instr.rm & DONTCARE(3 downto 0) & ALU_PASSA; --selalua & selalub & aluopr
                        path_s.segreg_input <= SALUBUS_IN & instr.reg(1 downto 0); -- simux & selsreg
                    
                        path_s.ea_output    <= NB_CS_IP;                -- IPREG+NB ADDR=CS:IP                      

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?