📄 it51_core.vhd
字号:
-- PSW PSW0 <= ACC(7) xor ACC(6) xor ACC(5) xor ACC(4) xor ACC(3) xor ACC(2) xor ACC(1) xor ACC(0); Next_PSW7 <= Res_Bus(7) when SFR_Wr_i = '1' and Int_AddrA_r = "11010000" else Status_D(7) when Status_Wr(7) = '1' else PSW(7); Next_ACC_Z <= '1' when ACC_Q = "00000000" and ACC_Wr = '1' else '1' when ACC = "00000000" else '0'; process (Rst_n, Clk) begin if Rst_n = '0' then PSW <= "0000000"; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "11010000" then PSW <= Res_Bus(7 downto 1); end if; -- CY if Status_Wr(7) = '1' then PSW(7) <= Status_D(7); end if; -- AC if Status_Wr(6) = '1' then PSW(6) <= Status_D(6); end if; -- OV if Status_Wr(5) = '1' then PSW(2) <= Status_D(5); end if; end if; end process; ---------------------------------------------------------------------------- -- B process (Rst_n, Clk) begin if Rst_n = '0' then B <= "00000000"; B_Wr <= '0'; elsif Clk'event and Clk = '1' then if ((cInst_is_DIV and not PCPause) or cInst_is_MUL) and Last_Cycle then -- DIV, MUL B_Wr <= '1'; else B_Wr <= '0'; end if; if B_Wr = '1' then B <= B_Q; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "11110000" then B <= Res_Bus; end if; end if; end process; ---------------------------------------------------------------------------- -- ACC process (Rst_n, Clk) begin if Rst_n = '0' then ACC <= "00000000"; ACC_Wr <= '0'; elsif Clk'event and Clk = '1' then if (cInst_is_A_Write and Last_Cycle and not PCPause) or (cInst_is_DIV and not PCPause) then ACC_Wr <= '1'; else ACC_Wr <= '0'; end if; if ACC_Wr = '1' then ACC <= ACC_Q; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "11100000" then ACC <= Res_Bus; end if; if RAM_Rd_i = '1' then ACC <= RAM_RData; end if; if cInst_is_MOVC and Third_Cycle then -- MOVC ACC <= nInst; end if; end if; end process; ---------------------------------------------------------------------------- -- MUX process (Clk, Rst_n) begin if Rst_n = '0' then AMux_SFR <= false; BMux_Inst2 <= false; RMux_PCL <= false; RMux_PCH <= false; elsif Clk'event and Clk = '1' then AMux_SFR <= false; BMux_Inst2 <= false; RMux_PCL <= false; RMux_PCH <= false; if Int_AddrA(7) = '1' then AMux_SFR <= true; end if; if cInst(3 downto 1) = "011" then if not (cInst(7 downto 4) = "1010" and Second_Cycle) then -- Indirect addressing AMux_SFR <= false; end if; end if; if cInst_is_POP and First_Cycle then -- 11010000 2 POP data addr MOV <dest>,"@SP": DEC SP AMux_SFR <= false; end if; if cInst(3 downto 0) = "0011" or cInst(3 downto 0) = "0101" then BMux_Inst2 <= true; end if; -- LCALL, ACALL, Int if cInst_is_LCALL or cInst_is_ACALL or ICall then if First_Cycle then RMux_PCL <= true; elsif Second_Cycle then RMux_PCH <= true; end if; end if; end if; end process; ---------------------------------------------------------------------------- -- DPTR0, DPTR1, CKCON, Port2_Reg process (Rst_n, Clk) begin if Rst_n = '0' then MPAGE <= "00000000"; DPTR0 <= (others => '0'); DPTR1 <= (others => '0'); CKCON <= "00000001"; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "10010010" then MPAGE <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10100000" then MPAGE <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000010" then DPL0 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000011" then DPH0 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000100" then DPL1 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10000101" then DPH1 <= Res_Bus; end if; if SFR_Wr_i = '1' and Int_AddrA_r = "10001110" then CKCON <= Res_Bus; end if; if Ready then -- 10010000 3 MOV DPTR,#data if cInst = "10010000" and Second_Cycle then if DPS_SEL = '0' then DPH0 <= cInst1; else DPH1 <= cInst1; end if; end if; if cInst = "10010000" and Third_Cycle then if DPS_SEL = '0' then DPL0 <= cInst2; else DPL1 <= cInst2; end if; end if; -- 10100011 1 INC DPTR if INC_DPTR then if DPS_SEL = '0' then DPTR0 <= DPTR0 + 1; else DPTR1 <= DPTR1 + 1; end if; end if; end if; end if; end process; ---------------------------------------------------------------------------- -- INC_DPTR process (Rst_n, Clk) begin if Rst_n = '0' then INC_DPTR <= false; elsif Clk'event and Clk = '1' then if Ready then INC_DPTR <= cInst_is_INC_DPTR; end if; end if; end process; ---------------------------------------------------------------------------- -- DPS process (Rst_n, Clk) begin if Rst_n = '0' then DPS <= "00000000"; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "10000110" then DPS <= Res_Bus; end if; end if; end process; ---------------------------------------------------------------------------- -- Interrupts IStart <= Last_Cycle and IPending and not Inst_Skip and not PCPause and not Ri_Stall and not PSW_Stall and not RW_Stall ; -- no interrupt in 4 cycle after RETI process (Rst_n, Clk) begin if Rst_n = '0' then INT_reject <= false; elsif Clk'event and Clk = '1' then if cInst_is_RETI then INT_reject <= true; else INT_reject <= false; end if; end if; end process; -- IP process (Rst_n, Clk) begin if Rst_n = '0' then IP <= "10000000"; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "10111000" then IP <= Res_Bus; end if; end if; end process; -- EIP process (Rst_n, Clk) begin if Rst_n = '0' then EIP <= "10000000"; elsif Clk'event and Clk = '1' then if SFR_Wr_i = '1' and Int_AddrA_r = "11111000" then EIP <= Res_Bus; end if; end if; end process; -- LPInt, HPInt, IPending, Int_Acc, Int_Trig_r INT_IP <= EIP(3 downto 0) & IP(6 downto 0); process (Rst_n, Clk) begin if Rst_n = '0' then LPInt <= false; HPInt <= false; Int_Trig_r <= (others => '0'); IPending <= false; elsif Clk'event and Clk = '1' then if Ready then if ICall then IPending <= false; elsif (Int_Trig and INT_IP) /= "00000000000" and not HPInt and not IPending and not ICall and not INT_reject then Int_Trig_r <= Int_Trig and INT_IP; IPending <= true; HPInt <= true; elsif Int_Trig /= "00000000000" and not LPInt and not HPInt and not IPending and not ICall and not INT_reject then Int_Trig_r <= Int_Trig; IPending <= true; LPInt <= true; end if; if cInst_is_RETI then if not HPInt then LPInt <= false; else HPInt <= false; end if; end if; if ICall and Last_Cycle then Int_Trig_r <= (others => '0'); end if; end if; end if; end process; -- Int_Acc process (Rst_n, Clk) begin if Rst_n = '0' then Int_Acc <= (others => '0'); elsif Clk'event and Clk = '1' then if Ready then Int_Acc <= (others => '0'); if IPending and ICall then if Int_Trig_r( 0) = '1' then Int_Acc( 0) <= '1'; elsif Int_Trig_r( 1) = '1' then Int_Acc( 1) <= '1'; elsif Int_Trig_r( 2) = '1' then Int_Acc( 2) <= '1'; elsif Int_Trig_r( 3) = '1' then Int_Acc( 3) <= '1'; elsif Int_Trig_r( 4) = '1' then Int_Acc( 4) <= '1'; elsif Int_Trig_r( 5) = '1' then Int_Acc( 5) <= '1'; elsif Int_Trig_r( 6) = '1' then Int_Acc( 6) <= '1'; elsif Int_Trig_r( 7) = '1' then Int_Acc( 7) <= '1'; elsif Int_Trig_r( 8) = '1' then Int_Acc( 8) <= '1'; elsif Int_Trig_r( 9) = '1' then Int_Acc( 9) <= '1'; elsif Int_Trig_r(10) = '1' then Int_Acc(10) <= '1'; end if; end if; end if; end if; end process; -- ICall process (Rst_n, Clk) begin if Rst_n = '0' then ICall <= false; elsif Clk'event and Clk = '1' then if Ready then if ICall and Last_Cycle then ICall <= false; elsif IStart then ICall <= true; end if; end if; end if; end process; ----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -