kroszkanorber Maj 27, 2024 Autor tematu Udostępnij Maj 27, 2024 Hej @FlyingDutch Ten kod muszę jeszcze dopracować. Nie wszystko działa jak być powinno. Z GitHub nigdy nie miałem do czynienia. Wrzucam wszytko na forbot bo jest tutaj dla mnie prościej i intuicyjnie. Napisz konkretnie co chcesz to podeślę. Kod opisałem w oddzielnych komponentach i połączyłem w programie głównym. Jak skończę projekt to usunę ten temat i założę nowy, w którym będzie wszystko po kolei opisane. Pozdrawiam 1
kroszkanorber Maj 29, 2024 Autor tematu Udostępnij Maj 29, 2024 (edytowany) @FlyingDutch Witaj Kody napisałem w komponentach jak już wspominałem wcześniej. PIC18F do kod główny w którym umieściłem pozostałe kody. Zawiera on 8 bit port we-wy, wejście przerwania z zewnątrz, wejście zegara, i wejście reset. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity PIC18F is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; INTERRUPT : in STD_LOGIC; RA : inout STD_LOGIC_VECTOR (7 downto 0); ROM_ADDR : out STD_LOGIC_VECTOR (19 downto 0); ROM_DATA_EXT : in STD_LOGIC_VECTOR (15 downto 0) ); end PIC18F; architecture Behavioral of PIC18F is signal Clk1 : STD_LOGIC; signal ROM_DATA_INT1 : STD_LOGIC_vector (15 downto 0); signal ROM_DATA_EXT1 : STD_LOGIC_vector (15 downto 0); signal F_WE_d_EN : STD_LOGIC; signal F_WE_EN : STD_LOGIC; signal SKIP2_AeB : STD_LOGIC; signal SKIP2_AgB : STD_LOGIC; signal SKIP2_AlB : STD_LOGIC; signal SKIP2_Z : STD_LOGIC; signal SKIP2_NZ : STD_LOGIC; signal LIT : STD_LOGIC_vector (7 downto 0); signal ALU_A : STD_LOGIC_vector (7 downto 0); signal ALU_B : STD_LOGIC_vector (7 downto 0); signal ALU_Y : STD_LOGIC_vector (7 downto 0); signal ALU_C : STD_LOGIC; signal ALU_Z : STD_LOGIC; signal ALU_N : STD_LOGIC; signal ALU_NZ : STD_LOGIC; COMPONENT PORTA_CONTROL PORT( Clk : IN std_logic; Reset : IN std_logic; TRISA_WE : IN std_logic; PORTA_WE : IN std_logic; TRISA_EN : IN std_logic; PORTA_EN : IN std_logic; ALU_Y : IN std_logic_vector(7 downto 0); RA : INOUT std_logic_vector(7 downto 0); ALU_PORTA : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal TRISA_WE : std_logic; signal PORTA_WE : std_logic; signal TRISA_EN : std_logic; signal PORTA_EN : std_logic; signal ALU_PORTA : std_logic_vector(7 downto 0); COMPONENT ROM_INTERN PORT( ROM_ADDR : IN std_logic_vector(11 downto 0); ROM_DATA : OUT std_logic_vector(15 downto 0) ); END COMPONENT; signal ROM_DATA : std_logic_vector(15 downto 0); signal ROM_DATA_INT : std_logic_vector(15 downto 0); signal ADDR_ROM : std_logic_vector (19 downto 0); COMPONENT INSTRUKTION_SET PORT( ROM_DATA : IN std_logic_vector(7 downto 0); ADDWF : OUT std_logic; ADDWFC : OUT std_logic; ANDWF : OUT std_logic; CLRF : OUT std_logic; COMF : OUT std_logic; CPFSEQ : OUT std_logic; CPFSGT : OUT std_logic; CPFSLT : OUT std_logic; DECF : OUT std_logic; DECFSZ : OUT std_logic; DCFSNZ : OUT std_logic; INCF : OUT std_logic; INCFSZ : OUT std_logic; INFSNZ : OUT std_logic; IORWF : OUT std_logic; MOVF : OUT std_logic; MOVWF : OUT std_logic; MULWF : OUT std_logic; NEGF : OUT std_logic; RLCF : OUT std_logic; RLNCF : OUT std_logic; RRCF : OUT std_logic; RRNCF : OUT std_logic; SETF : OUT std_logic; SUBFWB : OUT std_logic; SUBWF : OUT std_logic; SUBWFB : OUT std_logic; SWAPF : OUT std_logic; TSTFSZ : OUT std_logic; XORWF : OUT std_logic; BCF : OUT std_logic; BSF : OUT std_logic; BTFSC : OUT std_logic; BTFSS : OUT std_logic; BTG : OUT std_logic; RETLW : OUT std_logic; ADDLW : OUT std_logic; ANDLW : OUT std_logic; IORLW : OUT std_logic; MOVLW : OUT std_logic; MULLW : OUT std_logic; SUBLW : OUT std_logic; XORLW : OUT std_logic; MOVLB : OUT std_logic; NdWord : OUT std_logic ); END COMPONENT; signal ADDWF : std_logic; signal ADDWFC : std_logic; signal ANDWF : std_logic; signal CLRF : std_logic; signal COMF : std_logic; signal CPFSEQ : std_logic; signal CPFSGT : std_logic; signal CPFSLT : std_logic; signal DECF : std_logic; signal DECFSZ : std_logic; signal DCFSNZ : std_logic; signal INCF : std_logic; signal INCFSZ : std_logic; signal INFSNZ : std_logic; signal IORWF : std_logic; signal MOVF : std_logic; signal MOVWF : std_logic; signal MULWF : std_logic; signal NEGF : std_logic; signal RLCF : std_logic; signal RLNCF : std_logic; signal RRCF : std_logic; signal RRNCF : std_logic; signal SETF : std_logic; signal SUBFWB : std_logic; signal SUBWF : std_logic; signal SUBWFB : std_logic; signal SWAPF : std_logic; signal TSTFSZ : std_logic; signal XORWF : std_logic; signal BCF : std_logic; signal BSF : std_logic; signal BTFSC : std_logic; signal BTFSS : std_logic; signal BTG : std_logic; signal RETLW : std_logic; signal ADDLW : std_logic; signal ANDLW : std_logic; signal IORLW : std_logic; signal MOVLW : std_logic; signal MULLW : std_logic; signal SUBLW : std_logic; signal XORLW : std_logic; signal MOVLB : std_logic; signal NdWord : std_logic; COMPONENT INSTRUKTION_BITSEL PORT( ROM_DATA : IN std_logic_vector(2 downto 0); BIT_SEL : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal BIT_SEL : std_logic_vector (7 downto 0); COMPONENT ADDER PORT( ADD_A : IN std_logic_vector(7 downto 0); ADD_B : IN std_logic_vector(7 downto 0); ADD_Ci : IN std_logic; ADDLW : IN std_logic; ADDWF : IN std_logic; ADDWFC : IN std_logic; SUBWFB : IN std_logic; SUBFWB : IN std_logic; SUBWF : IN std_logic; SUBLW : IN std_logic; DECF : IN std_logic; DECFSZ : IN std_logic; DCFSNZ : IN std_logic; INCF : IN std_logic; INCFSZ : IN std_logic; INFSNZ : IN std_logic; NEGF : IN std_logic; ADD_C : OUT std_logic; ADD_DC : OUT std_logic; ADD_OV : OUT std_logic; ADD_Y : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal ADD_Y : std_logic_vector(7 downto 0); signal ADD_Ci : std_logic; signal ADD_C : std_logic; signal ADD_DC : std_logic; signal ADD_OV : std_logic; COMPONENT LOGIC PORT( LOG_A : IN std_logic_vector(7 downto 0); LOG_B : IN std_logic_vector(7 downto 0); BIT_SEL : IN std_logic_vector(7 downto 0); LOG_Ci : IN std_logic; ANDWF : IN std_logic; ANDLW : IN std_logic; IORWF : IN std_logic; IORLW : IN std_logic; XORWF : IN std_logic; XORLW : IN std_logic; SWAPF : IN std_logic; RLNCF : IN std_logic; RLCF : IN std_logic; RRNCF : IN std_logic; RRCF : IN std_logic; SETF : IN std_logic; BSF : IN std_logic; BCF : IN std_logic; BTG : IN std_logic; BTFSS : IN std_logic; BTFSC : IN std_logic; COMF : IN std_logic; MOVWF : IN std_logic; TSTFSZ : IN std_logic; LOG_Co : OUT std_logic; LOG_Y : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal LOG_Y : std_logic_vector(7 downto 0); signal LOG_Ci : std_logic; signal LOG_C : std_logic; COMPONENT PC PORT( Clk : IN std_logic; Clk1 : INOUT std_logic; Reset : IN std_logic; RETLW : IN std_logic; NdWord : IN std_logic; INTERRUPT : IN std_logic; SKIP2 : IN std_logic; SHADOW_WE_EN : out STD_LOGIC; SHADOW_RD_EN : out STD_LOGIC; ROM_DATA : IN std_logic_vector(15 downto 0); ROM_ADDR : INOUT std_logic_vector(19 downto 0) ); END COMPONENT; signal SKIP2 : std_logic; signal SHADOW_WE_EN : std_logic; signal SHADOW_RD_EN : std_logic; COMPONENT RAM PORT( Clk : IN std_logic; RAM_WE : IN std_logic; RAM_EN : IN std_logic; RAM_ADDR : IN std_logic_vector(11 downto 0); RAM_DI : IN std_logic_vector(7 downto 0); RAM_DATA : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal RAM_ADDR : STD_LOGIC_vector (11 downto 0); signal RAM_DI : STD_LOGIC_vector (7 downto 0); signal RAM_DATA : STD_LOGIC_vector (7 downto 0); signal RAM_EN : STD_LOGIC; signal RAM_WE : STD_LOGIC; COMPONENT STATUS PORT( Clk : IN std_logic; Reset : IN std_logic; ADD_C : IN std_logic; ADD_DC : IN std_logic; ADD_OV : IN std_logic; ALU_Z : IN std_logic; ALU_N : IN std_logic; ADDWF : IN std_logic; ADDWFC : IN std_logic; DECF : IN std_logic; INCF : IN std_logic; NEGF : IN std_logic; SUBWF : IN std_logic; SUBWFB : IN std_logic; ADDLW : IN std_logic; SUBLW : IN std_logic; ANDWF : IN std_logic; COMF : IN std_logic; IORWF : IN std_logic; MOVF : IN std_logic; RLNCF : IN std_logic; RLCF : IN std_logic; RRCF : IN std_logic; RRNCF : IN std_logic; SETF : IN std_logic; XORWF : IN std_logic; ANDLW : IN std_logic; IORLW : IN std_logic; XORLW : IN std_logic; BSF : IN std_logic; BCF : IN std_logic; ROM_SEL : OUT std_logic; STATUS_EN : IN std_logic; SHADOW_WE_EN : in STD_LOGIC; SHADOW_RD_EN : in STD_LOGIC; STATUS : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal ROM_SEL : std_logic; signal STATUS1 : STD_LOGIC_vector (7 downto 0); signal STATUS_EN : STD_LOGIC; COMPONENT MUL PORT( Clk : IN std_logic; Reset : IN std_logic; MULWF : IN std_logic; MULLW : IN std_logic; RAM_DATA : IN std_logic_vector(7 downto 0); WREG : IN std_logic_vector(7 downto 0); LIT : IN std_logic_vector(7 downto 0); PRODH_EN : IN std_logic; PRODL_EN : IN std_logic; PRODH : OUT std_logic_vector(7 downto 0); PRODL : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal PRODH : STD_LOGIC_vector (7 downto 0); signal PRODL : STD_LOGIC_vector (7 downto 0); signal PRODH_EN : STD_LOGIC; signal PRODL_EN : STD_LOGIC; COMPONENT WREG_CONTROL PORT( Clk : IN std_logic; Reset : IN std_logic; WREG_WE : IN std_logic; SHADOW_WE_EN : in STD_LOGIC; SHADOW_RD_EN : in STD_LOGIC; ALU_Y : IN std_logic_vector(7 downto 0); WREG : INOUT std_logic_vector(7 downto 0) ); END COMPONENT; signal WREG : STD_LOGIC_vector (7 downto 0); signal W_WE_EN : STD_LOGIC; signal WREG_WE : STD_LOGIC; COMPONENT BSR_CONTROL PORT( Clk : IN std_logic; Reset : IN std_logic; ROM_DATA : IN std_logic_vector(3 downto 0); MOVLB : IN std_logic; SHADOW_WE_EN : IN std_logic; SHADOW_RD_EN : IN std_logic; BSR : INOUT std_logic_vector(3 downto 0) ); END COMPONENT; signal BSR : STD_LOGIC_vector (3 downto 0); begin ------------------------------------------------------------------------------------------------------------------- Inst_INSTRUKTION_BITSEL: INSTRUKTION_BITSEL PORT MAP( ROM_DATA => ROM_DATA(11 downto 9), BIT_SEL => BIT_SEL ); ------------------------------------------------------------------------------------------------------------------- PORTA_WE <= '1' when ((RAM_ADDR = X"F80") and (RAM_WE = '1') and (Clk1 = '1')) else '0'; TRISA_WE <= '1' when ((RAM_ADDR = X"F92") and (RAM_WE = '1') and (Clk1 = '1')) else '0'; PORTA_EN <= '1' when ((RAM_ADDR = X"F80") and (RAM_WE = '0')) else '0'; TRISA_EN <= '1' when ((RAM_ADDR = X"F92") and (RAM_WE = '0')) else '0'; Inst_PORTA_CONTROL: PORTA_CONTROL PORT MAP( Clk => Clk, Reset => Reset, TRISA_WE => TRISA_WE, PORTA_WE => PORTA_WE, TRISA_EN => TRISA_EN, PORTA_EN => PORTA_EN, RA => RA, ALU_PORTA => ALU_PORTA, ALU_Y => ALU_Y ); ------------------------------------------------------------------------------------------------------------------- ROM_DATA_INT1 <= ROM_DATA_INT when (ROM_SEL = '0') else (others => '0'); ROM_DATA_EXT1 <= ROM_DATA_EXT when (ROM_SEL = '1') else (others => '0'); ROM_DATA <= ROM_DATA_EXT1 or ROM_DATA_INT1; Inst_ROM_INTERN: ROM_INTERN PORT MAP( ROM_ADDR => ADDR_ROM(11 downto 0), ROM_DATA => ROM_DATA_INT ); ------------------------------------------------------------------------------------------------------------------- Inst_INSTRUKTION_SET: INSTRUKTION_SET PORT MAP( ADDWF => ADDWF, ADDWFC => ADDWFC, ANDWF => ANDWF, CLRF => CLRF, COMF => COMF, CPFSEQ => CPFSEQ, CPFSGT => CPFSGT, CPFSLT => CPFSLT, DECF => DECF, DECFSZ => DECFSZ, DCFSNZ => DCFSNZ, INCF => INCF, INCFSZ => INCFSZ, INFSNZ => INFSNZ, IORWF => IORWF, MOVF => MOVF, MOVWF => MOVWF, MULWF => MULWF, NEGF => NEGF, RLCF => RLCF, RLNCF => RLNCF, RRCF => RRCF, RRNCF => RRNCF, SETF => SETF, SUBFWB => SUBFWB , SUBWF => SUBWF, SUBWFB => SUBWFB, SWAPF => SWAPF, TSTFSZ =>TSTFSZ, XORWF => XORWF, BCF => BCF, BSF => BSF, BTFSC => BTFSC, BTFSS => BTFSS, BTG => BTG, RETLW => RETLW, ADDLW => ADDLW, ANDLW => ANDLW, IORLW => IORLW, MOVLW => MOVLW, MULLW => MULLW, SUBLW => SUBLW, XORLW => XORLW, NdWord => NdWord, MOVLB => MOVLB, ROM_DATA => ROM_DATA(15 downto 8) ); ------------------------------------------------------------------------------------------------------------------- Inst_ADDER: ADDER PORT MAP( ADD_A => ALU_A, ADD_B => ALU_B, ADD_Ci => ADD_Ci, ADD_C => ADD_C, ADD_DC => ADD_DC, ADD_OV => ADD_OV, ADD_Y => ADD_Y, ADDLW => ADDLW, ADDWF => ADDWF, ADDWFC => ADDWFC, SUBWFB => SUBWFB, SUBFWB => SUBFWB, SUBWF => SUBWF, SUBLW => SUBLW, DECF => DECF, DECFSZ => DECFSZ, DCFSNZ => DCFSNZ, INCF => INCF, INCFSZ => INCFSZ, INFSNZ => INFSNZ, NEGF => NEGF ); ADD_Ci <= STATUS1(0); ------------------------------------------------------------------------------------------------------------------- Inst_LOGIC: LOGIC PORT MAP( LOG_A => ALU_A, LOG_B => ALU_B, BIT_SEL => BIT_SEL, LOG_Ci => LOG_Ci, ANDWF => ANDWF, ANDLW => ANDLW, IORWF => IORWF, IORLW => IORLW, XORWF => XORWF, XORLW => XORLW, SWAPF => SWAPF, RLNCF => RLNCF, RLCF => RLCF, RRNCF => RRNCF, RRCF => RRCF, SETF => SETF, BSF => BSF, BCF => BCF, BTG => BTG, BTFSS => BTFSS, BTFSC => BTFSC, COMF => COMF, MOVWF => MOVWF, TSTFSZ => TSTFSZ, LOG_Co => LOG_C, LOG_Y => LOG_Y ); LOG_Ci <= STATUS1(0); ------------------------------------------------------------------------------------------------------------------- Inst_PC: PC PORT MAP( Clk => Clk, Clk1 => Clk1, Reset => Reset, RETLW => RETLW, NdWord => NdWord, INTERRUPT => INTERRUPT, SKIP2 => SKIP2, SHADOW_WE_EN => SHADOW_WE_EN, SHADOW_RD_EN => SHADOW_RD_EN, ROM_ADDR => ADDR_ROM, ROM_DATA => ROM_DATA ); ------------------------------------------------------------------------------------------------------------------- Inst_RAM: RAM PORT MAP( Clk => Clk, RAM_WE => RAM_WE, RAM_EN => RAM_EN, RAM_ADDR => RAM_ADDR, RAM_DI => RAM_DI, RAM_DATA => RAM_DATA ); F_WE_d_EN <= ADDWF or ADDWFC or ANDWF or COMF or DECF or DECFSZ or DCFSNZ or INCF or INCFSZ or INFSNZ or IORWF or MOVF or RLCF or RLNCF or RRCF or RRNCF or SUBFWB or SUBWF or SUBWFB or SWAPF or XORWF; F_WE_EN <= CLRF or MOVWF or MULWF or NEGF or SETF or BCF or BSF or BTG; RAM_WE <= ((F_WE_d_EN and ROM_DATA(9)) or F_WE_EN) and Clk1 ; RAM_EN <= '0' when (ROM_DATA(15 downto 12) = 0) or (RAM_ADDR > X"FD6") else '1'; RAM_DI <= ALU_Y ; RAM_ADDR(11) <= (ROM_DATA(8) and BSR(3)) ; RAM_ADDR(10) <= (ROM_DATA(8) and BSR(2)) ; RAM_ADDR(9) <= (ROM_DATA(8) and BSR(1)) ; RAM_ADDR(8) <= (ROM_DATA(8) and BSR(0)) ; RAM_ADDR(7 downto 0) <= ROM_DATA(7 downto 0); ------------------------------------------------------------------------------------------------------------------- Inst_STATUS: STATUS PORT MAP( Clk => Clk, Reset => Reset, ADD_C => ALU_C, ADD_DC => ADD_DC, ADD_OV => ADD_OV, ALU_Z => ALU_Z, ALU_N => ALU_N, ADDWF => ADDWF, ADDWFC => ADDWFC, DECF => DECF, INCF => INCF, NEGF => NEGF, SUBWF => SUBWF, SUBWFB => SUBWFB, ADDLW => ADDLW, SUBLW => SUBLW, ANDWF => ANDWF, COMF => COMF, IORWF => IORWF, MOVF => MOVF, RLNCF => RLNCF, RLCF => RLCF, RRCF => RRCF, RRNCF => RRNCF, SETF => SETF, XORWF => XORWF, ANDLW => ANDLW, IORLW => IORLW, XORLW => XORLW, BSF => BSF, BCF => BCF, ROM_SEL => ROM_SEL, STATUS_EN => STATUS_EN, SHADOW_WE_EN => SHADOW_WE_EN, SHADOW_RD_EN => SHADOW_RD_EN, STATUS => STATUS1 ); STATUS_EN <= '1' when (RAM_ADDR = X"FD8") else '0'; Alu_Z <= '1' when ALU_Y(7 downto 0) = 0 else '0'; Alu_NZ <= '1' when ALU_Y(7 downto 0) > 0 else '0'; Alu_N <= ALU_Y(7); ------------------------------------------------------------------------------------------------------------------- Inst_MUL: MUL PORT MAP( Clk => Clk, Reset => Reset, MULWF => MULWF, MULLW => MULLW, RAM_DATA => RAM_DATA, WREG => WREG, LIT => LIT, PRODH_EN => PRODH_EN, PRODL_EN => PRODL_EN, PRODH => PRODH, PRODL => PRODL ); PRODH_EN <= '1' when (RAM_ADDR = X"FF4") else '0'; PRODL_EN <= '1' when (RAM_ADDR = X"FF3") else '0'; ------------------------------------------------------------------------------------------------------------------- LIT <= ROM_DATA(7 downto 0) when (RAM_EN = '0') else (others => '0'); ALU_Y <= ADD_Y or LOG_Y or STATUS1 or PRODH or PRODL or LIT; ALU_A <= RAM_DATA or LIT or ALU_PORTA; ALU_B <= WREG; ALU_C <= ADD_C or LOG_C; ------------------------------------------------------------------------------------------------------------------- W_WE_EN <= RETLW or ANDLW or IORLW or MOVLW or RETLW or SUBLW or XORLW; WREG_WE <= ((F_WE_d_EN and (not ROM_DATA(9))) or W_WE_EN) and Clk1 ; Inst_WREG_CONTROL: WREG_CONTROL PORT MAP( Clk => Clk, Reset => Reset, WREG_WE => WREG_WE, ALU_Y => ALU_Y, SHADOW_WE_EN => SHADOW_WE_EN, SHADOW_RD_EN => SHADOW_RD_EN, WREG => WREG ); ------------------------------------------------------------------------------------------------------------------- Inst_BSR_CONTROL: BSR_CONTROL PORT MAP( Clk => Clk, Reset => Reset, ROM_DATA => ROM_DATA(3 downto 0), BSR => BSR, MOVLB => MOVLB, SHADOW_WE_EN => SHADOW_WE_EN, SHADOW_RD_EN => SHADOW_RD_EN ); ------------------------------------------------------------------------------------------------------------------- SKIP2_AeB <= '1' when ((CPFSEQ = '1') and (RAM_DATA = WREG)) else '0'; SKIP2_AgB <= '1' when ((CPFSGT = '1') and (RAM_DATA > WREG)) else '0'; SKIP2_AlB <= '1' when ((CPFSLT = '1') and (RAM_DATA < WREG)) else '0'; SKIP2_Z <= ALU_Z and (BTFSC or TSTFSZ or DECFSZ or INCFSZ); SKIP2_NZ <= ALU_NZ and (BTFSS or DCFSNZ or INFSNZ); SKIP2 <= SKIP2_AeB or SKIP2_AgB or SKIP2_AlB or SKIP2_Z or SKIP2_NZ; ROM_ADDR <= ADDR_ROM; end Behavioral; INSTRUKTION_SET to dekoder większości instrukcji w programie. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity INSTRUKTION_SET is Port ( ADDWF : out STD_LOGIC; ADDWFC : out STD_LOGIC; ANDWF : out STD_LOGIC; CLRF : out STD_LOGIC; COMF : out STD_LOGIC; CPFSEQ : out STD_LOGIC; CPFSGT : out STD_LOGIC; CPFSLT : out STD_LOGIC; DECF : out STD_LOGIC; DECFSZ : out STD_LOGIC; DCFSNZ : out STD_LOGIC; INCF : out STD_LOGIC; INCFSZ : out STD_LOGIC; INFSNZ : out STD_LOGIC; IORWF : out STD_LOGIC; MOVF : out STD_LOGIC; -- MOVFF : out STD_LOGIC; MOVWF : out STD_LOGIC; MULWF : out STD_LOGIC; NEGF : out STD_LOGIC; RLCF : out STD_LOGIC; RLNCF : out STD_LOGIC; RRCF : out STD_LOGIC; RRNCF : out STD_LOGIC; SETF : out STD_LOGIC; SUBFWB : out STD_LOGIC; SUBWF : out STD_LOGIC; SUBWFB : out STD_LOGIC; SWAPF : out STD_LOGIC; TSTFSZ : out STD_LOGIC; XORWF : out STD_LOGIC; BCF : out STD_LOGIC; BSF : out STD_LOGIC; BTFSC : out STD_LOGIC; BTFSS : out STD_LOGIC; BTG : out STD_LOGIC; RETLW : out STD_LOGIC; ADDLW : out STD_LOGIC; ANDLW : out STD_LOGIC; IORLW : out STD_LOGIC; MOVLW : out STD_LOGIC; MULLW : out STD_LOGIC; SUBLW : out STD_LOGIC; XORLW : out STD_LOGIC; NdWord : out STD_LOGIC; MOVLB : out STD_LOGIC; ROM_DATA : in STD_LOGIC_VECTOR (7 downto 0) ); end INSTRUKTION_SET; architecture Behavioral of INSTRUKTION_SET is begin ADDWF <= '1' when ROM_DATA(7 downto 2) = "001001" else '0' ; --ADDWF f, d, a C, DC, Z, OV, N ADDWFC <= '1' when ROM_DATA(7 downto 2) = "001000" else '0' ; --ADDWFC f, d, a C, DC, Z, OV, N ANDWF <= '1' when ROM_DATA(7 downto 2) = "000101" else '0' ; --ANDWF f, d, a Z, N CLRF <= '1' when ROM_DATA(7 downto 1) = "0110101" else '0' ; --CLRF f, a Z COMF <= '1' when ROM_DATA(7 downto 2) = "000111" else '0' ; --COMF f, d, a Z, N CPFSEQ <= '1' when ROM_DATA(7 downto 1) = "0110001" else '0' ; --CPFSEQ f, a CPFSGT <= '1' when ROM_DATA(7 downto 1) = "0110010" else '0' ; --CPFSGT f, a CPFSLT <= '1' when ROM_DATA(7 downto 1) = "0110000" else '0' ; --CPFSLT f, a DECF <= '1' when ROM_DATA(7 downto 2) = "000001" else '0' ; --DECF f, d, a C, DC, Z, OV, N DECFSZ <= '1' when ROM_DATA(7 downto 2) = "001011" else '0' ; --DECFSZ f, d, a DCFSNZ <= '1' when ROM_DATA(7 downto 2) = "010011" else '0' ; --DCFSNZ f, d, a INCF <= '1' when ROM_DATA(7 downto 2) = "001010" else '0' ; --INCF f, d, a C, DC, Z, OV, N INCFSZ <= '1' when ROM_DATA(7 downto 2) = "001111" else '0' ; --INCFSZ f, d, a INFSNZ <= '1' when ROM_DATA(7 downto 2) = "010010" else '0' ; --INFSNZ f, d, a IORWF <= '1' when ROM_DATA(7 downto 2) = "000100" else '0' ; --IORWF f, d, a Z, N MOVF <= '1' when ROM_DATA(7 downto 2) = "010100" else '0' ; --MOVF f, d, a Z, N --MOVFF <= '1' when ROM_DATA(7 downto 4) = "1100" else '0' ; --MOVFF fs, fd NdWord <= '1' when ROM_DATA(7 downto 4) = "1111" else '0' ; --NdWord MOVWF <= '1' when ROM_DATA(7 downto 1) = "0110111" else '0' ; --MOVWF f, a MULWF <= '1' when ROM_DATA(7 downto 1) = "0000001" else '0' ; --MULWF f, a NEGF <= '1' when ROM_DATA(7 downto 1) = "0110110" else '0' ; --NEGF f, a C, DC, Z, OV, N RLCF <= '1' when ROM_DATA(7 downto 2) = "001101" else '0' ; --RLCF f, d, a C, Z, N RLNCF <= '1' when ROM_DATA(7 downto 2) = "010001" else '0' ; --RLNCF f, d, a Z, N RRCF <= '1' when ROM_DATA(7 downto 2) = "001100" else '0' ; --RRCF f, d, a C, Z, N RRNCF <= '1' when ROM_DATA(7 downto 2) = "010000" else '0' ; --RRNCF f, d, a Z, N SETF <= '1' when ROM_DATA(7 downto 1) = "0110100" else '0' ; --SETF f, a SUBFWB <= '1' when ROM_DATA(7 downto 2) = "010110" else '0' ; --SUBFWB f, d, a C, DC, Z, OV, N SUBWF <= '1' when ROM_DATA(7 downto 2) = "010111" else '0' ; --SUBWF f, d, a C, DC, Z, OV, N SUBWFB <= '1' when ROM_DATA(7 downto 2) = "010101" else '0' ; --SUBWFB f, d, a C, DC, Z, OV, N SWAPF <= '1' when ROM_DATA(7 downto 2) = "010101" else '0' ; --SWAPF f, d, a TSTFSZ <= '1' when ROM_DATA(7 downto 1) = "0110011" else '0' ; --TSTFSZ f, a XORWF <= '1' when ROM_DATA(7 downto 2) = "000110" else '0' ; --XORWF f, d, a Z, N BCF <= '1' when ROM_DATA(7 downto 4) = "1001" else '0' ; --BCF f, b, a BSF <= '1' when ROM_DATA(7 downto 4) = "1000" else '0' ; --BSF f, b, a BTFSC <= '1' when ROM_DATA(7 downto 4) = "1011" else '0' ; --BTFSC f, b, a BTFSS <= '1' when ROM_DATA(7 downto 4) = "1010" else '0' ; --BTFSS f, b, a BTG <= '1' when ROM_DATA(7 downto 4) = "0111" else '0' ; --BTG f, b, a ADDLW <= '1' when ROM_DATA(7 downto 0) = "00001111" else '0' ; --ADDLW k C,DC,Z,OV,N ANDLW <= '1' when ROM_DATA(7 downto 0) = "00001011" else '0' ; --ANDLW k Z,N IORLW <= '1' when ROM_DATA(7 downto 0) = "00001001" else '0' ; --IORLW k Z, N MOVLW <= '1' when ROM_DATA(7 downto 0) = "00001110" else '0' ; --MOVLW k Z, N MULLW <= '1' when ROM_DATA(7 downto 0) = "00001101" else '0' ; --MULLW k Z, N SUBLW <= '1' when ROM_DATA(7 downto 0) = "00001000" else '0' ; --SUBLW k XORLW <= '1' when ROM_DATA(7 downto 0) = "00001010" else '0' ; --XORLW k Z, N RETLW <= '1' when ROM_DATA(7 downto 0) = "00001100" else '0' ; --RETLW k MOVLB <= '1' when ROM_DATA(7 downto 0) = "00000001" else '0'; --MOVLB k end Behavioral; INSTRUKTION_BITSEL to dekoder pomocniczy służący do wyboru jednego z ośmiu bitów które chcemy zmienić lub testować library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity INSTRUKTION_BITSEL is Port ( ROM_DATA : in STD_LOGIC_VECTOR (2 downto 0); BIT_SEL : out STD_LOGIC_VECTOR (7 downto 0)); end INSTRUKTION_BITSEL; architecture Behavioral of INSTRUKTION_BITSEL is begin with ROM_DATA select BIT_SEL <= "00000001" when "000", "00000010" when "001", "00000100" when "010", "00001000" when "011", "00010000" when "100", "00100000" when "101", "01000000" when "110", "10000000" when others; end Behavioral; PC to kod odpowiedzialny za sterowanie licznikiem programu. W nim zawiera się także stos przerwań o 16 poziomach library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity PC is Port ( Clk : in STD_LOGIC; Clk1 : inout STD_LOGIC; Reset : in STD_LOGIC; RETLW : in STD_LOGIC; NdWord : in STD_LOGIC; INTERRUPT : in STD_LOGIC; SKIP2 : in STD_LOGIC; SHADOW_WE_EN : out STD_LOGIC; SHADOW_RD_EN : out STD_LOGIC; ROM_ADDR : out STD_LOGIC_VECTOR(19 downto 0); ROM_DATA : in STD_LOGIC_VECTOR(15 downto 0) ); end PC; architecture Behavioral of PC is signal ADDR_ROM : STD_LOGIC_vector (19 downto 0); signal ADDRH : STD_LOGIC_vector (11 downto 0); signal ADDRL : STD_LOGIC_vector (7 downto 0); signal ADDRLL : STD_LOGIC_vector (7 downto 0); signal TOSCnt : STD_LOGIC_vector (3 downto 0); signal TOS : STD_LOGIC_vector (19 downto 0); signal TOS0 : STD_LOGIC_vector (19 downto 0); signal TOS1 : STD_LOGIC_vector (19 downto 0); signal TOS2 : STD_LOGIC_vector (19 downto 0); signal TOS3 : STD_LOGIC_vector (19 downto 0); signal TOS4 : STD_LOGIC_vector (19 downto 0); signal TOS5 : STD_LOGIC_vector (19 downto 0); signal TOS6 : STD_LOGIC_vector (19 downto 0); signal TOS7 : STD_LOGIC_vector (19 downto 0); signal TOS8 : STD_LOGIC_vector (19 downto 0); signal TOS9 : STD_LOGIC_vector (19 downto 0); signal TOS10 : STD_LOGIC_vector (19 downto 0); signal TOS11 : STD_LOGIC_vector (19 downto 0); signal TOS12 : STD_LOGIC_vector (19 downto 0); signal TOS13 : STD_LOGIC_vector (19 downto 0); signal TOS14 : STD_LOGIC_vector (19 downto 0); signal TOS15 : STD_LOGIC_vector (19 downto 0); signal TOSINT : STD_LOGIC_vector (19 downto 0); signal RETURN1 : STD_LOGIC; signal RETFIE : STD_LOGIC; signal SKIPEN : STD_LOGIC; signal INTEN : STD_LOGIC_vector (1 downto 0); signal CALL : STD_LOGIC; signal GOTO : STD_LOGIC; begin ROM_ADDR <= ADDR_ROM; RETURN1 <= '1' when ROM_DATA(15 downto 1) = "000000000001001" else '0'; RETFIE <= '1' when ROM_DATA(15 downto 1) = "000000000001000" else '0'; CALL <= '1' when ROM_DATA(15 downto 9) = "1110110" else '0'; GOTO <= '1' when ROM_DATA(15 downto 8) = "11101111" else '0'; ADDRLL <= ROM_DATA(7 downto 0) when ((GOTO = '1') or (CALL = '1')) else (others => '0'); ADDRH <= ROM_DATA(11 downto 0) when (NdWord = '1') else (others => '0'); SHADOW_WE_EN <= CALL and ROM_DATA(8); SHADOW_RD_EN <= (RETFIE or RETURN1) and ROM_DATA(0); process(Clk, Reset, SKIP2, ROM_DATA, ADDRLL, ADDRH, TOS, RETLW, RETURN1, RETFIE, INTERRUPT, GOTO, CALL, NdWord) begin if Reset = '0' then ADDR_ROM <= (others => '0'); ADDRL <= (others => '0'); TOSINT <= (others => '0'); TOSCnt <= (others => '0'); SKIPEN <= '0'; INTEN <= "00"; Clk1 <= '0'; else if Clk'event and Clk = '0' then Clk1 <= not Clk1; if Clk1 = '1' then if ((GOTO = '1') or (CALL = '1')) then ADDRL <= ADDRLL; else null; end if; if CALL = '1' then --CALL TOSCnt <= TOSCnt + 1; elsif ((RETURN1 = '1') or (RETLW = '1')) then --RETURN, RETLW, TOSCnt <= TOSCnt - 1; end if; if (GOTO = '1') then --GOTO SKIPEN <= '1'; elsif (CALL = '1') then --CALL SKIPEN <= '1'; elsif NdWord = '1' then SKIPEN <= '0'; end if; if ((INTERRUPT = '1') and (INTEN = "00")) then --INTERRUPT INTEN <= INTEN + 1; elsif (INTEN = "01") then --INTERRUPT TOSINT <= ADDR_ROM; INTEN <= INTEN + 1; elsif ((RETFIE = '1') and (INTEN = "10")) then --RETFIE INTEN <= "00"; else null; end if; if (INTEN = "01") then --INTERRUPT ADDR_ROM <= X"00008"; elsif (SKIPEN = '1') then ADDR_ROM(19 downto 8) <= ADDRH; ADDR_ROM(7 downto 0) <= ADDRL; elsif ((RETURN1 = '1') or (RETLW = '1')) then --RETURN, RETLW, ADDR_ROM <= TOS + 2; elsif ((RETFIE = '1') and (INTEN = "10")) then --RETFIE ADDR_ROM <= TOSINT + 1; elsif (SKIP2 = '1') then ADDR_ROM <= ADDR_ROM + 2; else ADDR_ROM <= ADDR_ROM + 1; end if; else null; end if; end if; end if; end process; with TOSCnt select TOS <= TOS0 when "0001", TOS1 when "0010", TOS2 when "0011", TOS3 when "0100", TOS4 when "0101", TOS5 when "0110", TOS6 when "0111", TOS7 when "1000", TOS8 when "1001", TOS9 when "1010", TOS10 when "1011", TOS11 when "1100", TOS12 when "1101", TOS13 when "1110", TOS14 when "1111", TOS15 when others; process(Clk, Clk1, Reset, TOSCnt, CALL, ADDR_ROM) begin if Reset = '0' then TOS0 <= (others => '0'); TOS1 <= (others => '0'); TOS2 <= (others => '0'); TOS3 <= (others => '0'); TOS4 <= (others => '0'); TOS5 <= (others => '0'); TOS6 <= (others => '0'); TOS7 <= (others => '0'); TOS8 <= (others => '0'); TOS9 <= (others => '0'); TOS10 <= (others => '0'); TOS11 <= (others => '0'); TOS12 <= (others => '0'); TOS13 <= (others => '0'); TOS14 <= (others => '0'); TOS15 <= (others => '0'); else if Clk'event and Clk = '0' then if Clk1 = '1' then if Call = '1' then case TOSCnt is when "0001" => TOS1 <= ADDR_ROM; when "0010" => TOS2 <= ADDR_ROM; when "0011" => TOS3 <= ADDR_ROM; when "0100" => TOS4 <= ADDR_ROM; when "0101" => TOS5 <= ADDR_ROM; when "0110" => TOS6 <= ADDR_ROM; when "0111" => TOS7 <= ADDR_ROM; when "1000" => TOS8 <= ADDR_ROM; when "1001" => TOS9 <= ADDR_ROM; when "1010" => TOS10 <= ADDR_ROM; when "1011" => TOS11 <= ADDR_ROM; when "1100" => TOS12 <= ADDR_ROM; when "1101" => TOS13 <= ADDR_ROM; when "1110" => TOS14 <= ADDR_ROM; when "1111" => TOS15 <= ADDR_ROM; when others => TOS0 <= ADDR_ROM; end case; else null; end if; end if; end if; end if; end process; end Behavioral; ADDER jest modułem odpowiedzialnym za operacje arytmetyczne. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ADDER is Port ( ADD_A : in STD_LOGIC_VECTOR (7 downto 0); --Wejście A ADD_B : in STD_LOGIC_VECTOR (7 downto 0); --Wejście B ADD_Ci : in STD_LOGIC; --Wejście Carry in ADD_C : out STD_LOGIC; --Carry dla 8 bitów ADD_DC : out STD_LOGIC; --Carry dla 4 bitów ADD_OV : out STD_LOGIC; --Przepełnienie dla liczb ze znakiem ADD_Y : out STD_LOGIC_VECTOR (7 downto 0); -- Wyjście Adder ADDLW : in STD_LOGIC; ADDWF : in STD_LOGIC; ADDWFC : in STD_LOGIC; SUBWFB : in STD_LOGIC; SUBFWB : in STD_LOGIC; SUBWF : in STD_LOGIC; SUBLW : in STD_LOGIC; DECF : in STD_LOGIC; DECFSZ : in STD_LOGIC; DCFSNZ : in STD_LOGIC; INCF : in STD_LOGIC; INCFSZ : in STD_LOGIC; INFSNZ : in STD_LOGIC; NEGF : in STD_LOGIC ); end ADDER; architecture Behavioral of ADDER is signal P : std_logic_vector (7 downto 0); --Propaguj (OR) signal G : std_logic_vector (7 downto 0); --Generuj (AND) signal ASB : std_logic_vector (7 downto 0); --Negacja wejścia B signal Q : std_logic_vector (7 downto 0); --Dane z sumatora signal Cin : std_logic; --Wejście Carry signal Cn : std_logic_vector (7 downto 0); --Wyjścia przeniesień signal A : std_logic_vector (7 downto 0); signal B : std_logic_vector (7 downto 0); signal Y : std_logic_vector (7 downto 0); signal IN_A : std_logic_vector (7 downto 0); signal INCDEC : std_logic_vector (7 downto 0); signal Ci : std_logic; signal INC : std_logic; signal DEC : std_logic; signal ADD_SUB : std_logic; signal ADDEN : std_logic; begin Cin <= ADD_SUB xor Ci; ASB(0) <= B(0) xor ADD_SUB; ASB(1) <= B(1) xor ADD_SUB; ASB(2) <= B(2) xor ADD_SUB; ASB(3) <= B(3) xor ADD_SUB; ASB(4) <= B(4) xor ADD_SUB; ASB(5) <= B(5) xor ADD_SUB; ASB(6) <= B(6) xor ADD_SUB; ASB(7) <= B(7) xor ADD_SUB; P(0) <= A(0) xor ASB(0); P(1) <= A(1) xor ASB(1); P(2) <= A(2) xor ASB(2); P(3) <= A(3) xor ASB(3); P(4) <= A(4) xor ASB(4); P(5) <= A(5) xor ASB(5); P(6) <= A(6) xor ASB(6); P(7) <= A(7) xor ASB(7); G(0) <= A(0) and ASB(0); G(1) <= A(1) and ASB(1); G(2) <= A(2) and ASB(2); G(3) <= A(3) and ASB(3); G(4) <= A(4) and ASB(4); G(5) <= A(5) and ASB(5); G(6) <= A(6) and ASB(6); G(7) <= A(7) and ASB(7); -- Carry lookahead (przeniesienie równoległe dla operacji dodawania, odejmowania) Q(0) <= Cin xor P(0); Cn(0) <= G(0) or (Cin and P(0)); Q(1) <= Cn(0) xor P(1); Cn(1) <= G(1) or (Cin and P(0) and P(1)) or (G(0) and P(1)); Q(2) <= Cn(1) xor P(2); Cn(2) <= G(2) or (Cin and P(0) and P(1) and P(2)) or (G(0) and P(1) and P(2)) or (G(1) and P(2)); Q(3) <= Cn(2) xor P(3); Cn(3) <= G(3) or (Cin and P(0) and P(1) and P(2) and P(3)) or (G(0) and P(1) and P(2) and P(3)) or (G(1) and P(2) and P(3)) or (G(2) and P(3)); Q(4) <= Cn(3) xor P(4); Cn(4) <= G(4) or (Cin and P(0) and P(1) and P(2) and P(3) and P(4)) or (G(0) and P(1) and P(2) and P(3) and P(4)) or (G(1) and P(2) and P(3) and P(4)) or (G(2) and P(3) and P(4)) or (G(3) and P(4)); Q(5) <= Cn(4) xor P(5); Cn(5) <= G(5) or (Cin and P(0) and P(1) and P(2) and P(3) and P(4) and P(5)) or (G(0) and P(1) and P(2) and P(3) and P(4) and P(5)) or (G(1) and P(2) and P(3) and P(4) and P(5)) or (G(2) and P(3) and P(4) and P(5)) or (G(3) and P(4) and P(5)) or (G(4) and P(5)); Q(6) <= Cn(5) xor P(6); Cn(6) <= G(6) or (Cin and P(0) and P(1) and P(2) and P(3) and P(4) and P(5) and P(6)) or (G(0) and P(1) and P(2) and P(3) and P(4) and P(5) and P(6)) or (G(1) and P(2) and P(3) and P(4) and P(5) and P(6)) or (G(2) and P(3) and P(4) and P(5) and P(6)) or (G(3) and P(4) and P(5) and P(6)) or (G(4) and P(5) and P(6)) or (G(5) and P(6)); Q(7) <= Cn(6) xor P(7); Cn(7) <= G(7) or (Cin and P(0) and P(1) and P(2) and P(3) and P(4) and P(5) and P(6) and P(7)) or (G(0) and P(1) and P(2) and P(3) and P(4) and P(5) and P(6) and P(7)) or (G(1) and P(2) and P(3) and P(4) and P(5) and P(6) and P(7)) or (G(2) and P(3) and P(4) and P(5) and P(6) and P(7)) or (G(3) and P(4) and P(5) and P(6) and P(7)) or (G(4) and P(5) and P(6) and P(7)) or (G(5) and P(6) and P(7)) or (G(6) and P(7)); ADD_DC <= Cn(3); ADD_C <= Cn(7); ADD_OV <= Cn(7) xor Cn(6); ADD_Y <= Y; Y <= Q when (ADDEN = '1') else (others => '0'); ADDEN <= ADDLW or ADDWF or ADDWFC or SUBWFB or SUBFWB or SUBWF or SUBLW or DECF or DECFSZ or DCFSNZ or INCF or INCFSZ or INFSNZ or NEGF; INC <= INCF or INCFSZ or INFSNZ; DEC <= DECF or DECFSZ or DCFSNZ; Ci <= INC or DEC or NEGF or (ADDWFC and ADD_Ci) or (SUBWFB and ADD_Ci) or (SUBFWB and ADD_Ci); ADD_SUB <= DEC or SUBWFB or SUBFWB or SUBWF or SUBLW; INCDEC <= (others => '0') when ((DEC = '1') or (INC = '1') or (NEGF = '1')) else (others => '1'); IN_A <= (not ADD_A) when (NEGF = '1') else ADD_A; A <= ADD_B when (SUBFWB = '1') else IN_A; B <= ADD_A when (SUBFWB = '1') else (ADD_B and INCDEC); end Behavioral; LOGIC ten kod odpowiada za operacje logiczne. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity LOGIC is Port ( LOG_A : in STD_LOGIC_VECTOR (7 downto 0); LOG_B : in STD_LOGIC_VECTOR (7 downto 0); BIT_SEL : in STD_LOGIC_VECTOR (7 downto 0); LOG_Ci : in STD_LOGIC; ANDWF : in STD_LOGIC; ANDLW : in STD_LOGIC; IORWF : in STD_LOGIC; IORLW : in STD_LOGIC; XORWF : in STD_LOGIC; XORLW : in STD_LOGIC; SWAPF : in STD_LOGIC; RLNCF : in STD_LOGIC; RLCF : in STD_LOGIC; RRNCF : in STD_LOGIC; RRCF : in STD_LOGIC; SETF : in STD_LOGIC; BSF : in STD_LOGIC; BCF : in STD_LOGIC; BTG : in STD_LOGIC; BTFSS : in STD_LOGIC; BTFSC : in STD_LOGIC; COMF : in STD_LOGIC; MOVWF : in STD_LOGIC; TSTFSZ : in STD_LOGIC; LOG_Co : out STD_LOGIC; LOG_Y : out STD_LOGIC_VECTOR (7 downto 0) ); end LOGIC; architecture Behavioral of LOGIC is signal ANDAB : std_logic_vector (7 downto 0); signal IORAB : std_logic_vector (7 downto 0); signal XORAB : std_logic_vector (7 downto 0); signal SETAB : std_logic_vector (7 downto 0); signal SWAPAB : std_logic_vector (7 downto 0); signal RLA : std_logic_vector (7 downto 0); signal RLCA : std_logic_vector (7 downto 0); signal RRA : std_logic_vector (7 downto 0); signal RRCA : std_logic_vector (7 downto 0); signal BIT_SEL_NEG : std_logic_vector (7 downto 0); signal BSFAB : std_logic_vector (7 downto 0); signal BCFAB : std_logic_vector (7 downto 0); signal BTGAB : std_logic_vector (7 downto 0); signal BTAB : std_logic_vector (7 downto 0); signal COMAB : std_logic_vector (7 downto 0); signal MOVBY : std_logic_vector (7 downto 0); signal TSTF : std_logic_vector (7 downto 0); signal RCo : std_logic; signal LCo : std_logic; begin LOG_Y <= ANDAB or IORAB or XORAB or SWAPAB or RLA or RLCA or RRA or RRA or RRCA or SETAB or BSFAB or BCFAB or BTGAB or BTAB or COMAB or MOVBY or TSTF; LOG_Co <= RCo or LCo; ANDAB <= (LOG_A and LOG_B) when ((ANDWF = '1') or (ANDLW = '1')) else (others => '0'); IORAB <= (LOG_A or LOG_B) when ((IORWF = '1') or (IORLW = '1')) else (others => '0'); XORAB <= (LOG_A xor LOG_B) when ((XORWF = '1') or (XORLW = '1')) else (others => '0'); BSFAB <= (LOG_A or BIT_SEL) when (BSF = '1') else (others => '0'); BCFAB <= (LOG_A and BIT_SEL_NEG) when (BCF = '1') else (others => '0'); BTGAB <= (LOG_A xor BIT_SEL) when (BTG = '1') else (others => '0'); BTAB <= (LOG_A and BIT_SEL) when ((BTFSS = '1') or (BTFSC = '1')) else (others => '0'); SETAB <= (others => '1') when (SETF = '1') else (others => '0'); COMAB <= (not LOG_A) when (COMF = '1') else (others => '0'); TSTF <= LOG_A when (TSTFSZ = '1') else (others => '0'); MOVBY <= LOG_B when (MOVWF = '1') else (others => '0'); SWAPAB <= (LOG_A(3 downto 0) & LOG_A(7 downto 4)) when (SWAPF = '1') else (others => '0'); RLA <= (LOG_A(6 downto 0) & LOG_A(7)) when (RLNCF = '1') else (others => '0'); RLCA <= (LOG_A(6 downto 0) & LOG_Ci) when (RLCF = '1') else (others => '0'); LCo <= LOG_A(7) when (RLCF = '1') else '0'; RRA <= (LOG_A(0) & LOG_A(7 downto 1)) when (RRNCF = '1') else (others => '0'); RRCA <= (LOG_Ci & LOG_A(7 downto 1)) when (RRCF = '1') else (others => '0'); RCo <= LOG_A(0) when (RRCF = '1') else '0'; BIT_SEL_NEG <= not BIT_SEL; end Behavioral; WREG_CONTROL to akumulator WREG (work register) w nim znajduje się również WREGS (shadow register) używany w przerwaniach by nie utracić danych z wykonywanego przed przerwaniem programu. W instrukcjach powrotu z przerwania możemy przywrócić zawartość rejestru roboczego. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity WREG_CONTROL is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; WREG_WE : in STD_LOGIC; SHADOW_WE_EN : in STD_LOGIC; SHADOW_RD_EN : in STD_LOGIC; ALU_Y : in STD_LOGIC_VECTOR (7 downto 0); WREG : inout STD_LOGIC_VECTOR (7 downto 0) ); end WREG_CONTROL; architecture Behavioral of WREG_CONTROL is signal WREGS : std_logic_vector (7 downto 0); begin process (Clk, Reset, ALU_Y, WREG_WE, SHADOW_WE_EN, SHADOW_RD_EN) begin if Reset = '0' then WREG <= (others => '0'); else if CLK'event and CLK = '0' then if (WREG_WE = '1') then WREG <= ALU_Y; elsif (SHADOW_WE_EN = '1') then WREGS <= WREG; elsif (SHADOW_RD_EN = '1') then WREG <= WREGS; else null; end if; end if; end if; end process; end Behavioral; STATUS to rejestr w którym zapamiętuje się dane takie jak C, DC, OV, N, Z. posiada on też shadow register i można go adresować w celu odczytu danych jak pamięć RAM pod adresem X"FD8". library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity STATUS is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; ADD_C : in STD_LOGIC; ADD_DC : in STD_LOGIC; ADD_OV : in STD_LOGIC; ALU_Z : in STD_LOGIC; ALU_N : in STD_LOGIC; ADDWF : in STD_LOGIC; ADDWFC : in STD_LOGIC; DECF : in STD_LOGIC; INCF : in STD_LOGIC; NEGF : in STD_LOGIC; SUBWF : in STD_LOGIC; SUBWFB : in STD_LOGIC; ADDLW : in STD_LOGIC; SUBLW : in STD_LOGIC; ANDWF : in STD_LOGIC; COMF : in STD_LOGIC; IORWF : in STD_LOGIC; MOVF : in STD_LOGIC; RLNCF : in STD_LOGIC; RLCF : in STD_LOGIC; RRCF : in STD_LOGIC; RRNCF : in STD_LOGIC; SETF : in STD_LOGIC; XORWF : in STD_LOGIC; ANDLW : in STD_LOGIC; IORLW : in STD_LOGIC; XORLW : in STD_LOGIC; BSF : in STD_LOGIC; BCF : in STD_LOGIC; STATUS_EN : in STD_LOGIC; SHADOW_WE_EN : in STD_LOGIC; SHADOW_RD_EN : in STD_LOGIC; ROM_SEL : out STD_LOGIC; STATUS : out STD_LOGIC_VECTOR (7 downto 0) ); end STATUS; architecture Behavioral of STATUS is signal STATUS1 : std_logic_vector (7 downto 0); signal STATUSS : std_logic_vector (7 downto 0); signal STATUS_C_WE : std_logic; signal STATUS_DC_WE : std_logic; signal STATUS_Z_WE : std_logic; signal STATUS_RS0_WE : std_logic; signal STATUS_RS1_WE : std_logic; begin STATUS_C_WE <= STATUS_DC_WE or RLCF or RRCF; STATUS_DC_WE <= ADDWF or ADDWFC or DECF or INCF or NEGF or SUBWF or SUBWFB or ADDLW or SUBLW; STATUS_Z_WE <= STATUS_C_WE or ANDWF or COMF or IORWF or MOVF or RLNCF or RLCF or RRCF or RRNCF or SETF or XORWF or ANDLW or IORLW or XORLW; STATUS_RS0_WE <= (BCF and STATUS_EN); STATUS_RS1_WE <= (BSF and STATUS_EN); ROM_SEL <= STATUS1(7); process (Clk, Reset, STATUS_C_WE, STATUS_DC_WE, STATUS_Z_WE, STATUS_RS0_WE, STATUS_RS1_WE, SHADOW_WE_EN) begin if Reset = '0' then STATUS1 <= (others => '0'); else if CLK'event and CLK = '0' then if STATUS_C_WE = '1' then STATUS1(0) <= ADD_C; else null; end if; if STATUS_DC_WE = '1' then STATUS1(1) <= ADD_DC; STATUS1(3) <= ADD_OV; else null; end if; if STATUS_Z_WE = '1' then STATUS1(2) <= ALU_Z; STATUS1(4) <= ALU_N; else null; end if; if STATUS_RS1_WE = '1' then STATUS1(7) <= '1'; elsif STATUS_RS0_WE = '1' then STATUS1(7) <= '0'; else null; end if; if SHADOW_WE_EN = '1' then STATUSS <= STATUS1; else null; end if; if SHADOW_RD_EN = '1' then STATUS1 <= STATUSS; else null; end if; end if; end if; end process; STATUS <= STATUS1 when (STATUS_EN = '1') else (others => '0'); end Behavioral; BSR_CONTROL jest to bank register select. przy operacjach ALU mamy możliwość podać w oprogramowaniu do 256 adresów RAM w celu zapisu wyniku, adres RAM możemy rozszerzyć do 12 bitów (4 kB). On również posiada shadow register library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity BSR_CONTROL is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; ROM_DATA : in STD_LOGIC_VECTOR (3 downto 0); BSR : inout STD_LOGIC_VECTOR (3 downto 0); MOVLB : in STD_LOGIC; SHADOW_WE_EN : in STD_LOGIC; SHADOW_RD_EN : in STD_LOGIC ); end BSR_CONTROL; architecture Behavioral of BSR_CONTROL is signal BSRS : std_logic_vector (3 downto 0); begin process (Clk, Reset, ROM_DATA, MOVLB) begin if Reset = '0' then BSR <= (others => '0'); BSRS <= (others => '0'); else if CLK'event and CLK = '0' then if MOVLB = '1' then BSR <= ROM_DATA; elsif SHADOW_WE_EN = '1' then BSRS <= BSR; elsif SHADOW_RD_EN = '1' then BSR <= BSRS; else null; end if; end if; end if; end process; end Behavioral; MUL jest kodem umożliwiającym przeprowadzenie operacji mnożenia. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity MUL is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; MULWF : in STD_LOGIC; MULLW : in STD_LOGIC; RAM_DATA : in STD_LOGIC_VECTOR (7 downto 0); WREG : in STD_LOGIC_VECTOR (7 downto 0); LIT : in STD_LOGIC_VECTOR (7 downto 0); PRODH_EN : in STD_LOGIC; PRODL_EN : in STD_LOGIC; PRODH : out STD_LOGIC_VECTOR (7 downto 0); PRODL : out STD_LOGIC_VECTOR (7 downto 0) ); end MUL; architecture Behavioral of MUL is signal PRODWF : std_logic_vector (15 downto 0); signal PRODLW : std_logic_vector (15 downto 0); signal PROD : std_logic_vector (15 downto 0); signal PROD1 : std_logic_vector (15 downto 0); signal MULEN : std_logic; begin PRODWF <= (RAM_DATA * WREG) when (MULWF = '1') else (others => '0'); PRODLW <= (LIT * WREG) when (MULLW = '1') else (others => '0'); PROD <= PRODWF or PRODLW; MULEN <= MULLW or MULWF; process (Clk, Reset, PROD, MULEN) begin if Reset = '0' then PROD1 <= (others => '0'); else if CLK'event and CLK = '0' then if (MULEN = '1') then PROD1 <= PROD; else null; end if; end if; end if; end process; PRODH <= PROD1(15 downto 8) when PRODH_EN = '1' else(others => '0') ; PRODL <= PROD1(7 downto 0) when PRODL_EN = '1' else(others => '0') ; end Behavioral; RAM pamięć library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity RAM is Port ( Clk : in STD_LOGIC; RAM_WE : in STD_LOGIC; RAM_EN : in STD_LOGIC; RAM_ADDR : in STD_LOGIC_VECTOR (11 downto 0); RAM_DI : in STD_LOGIC_VECTOR (7 downto 0); RAM_DATA : out STD_LOGIC_VECTOR (7 downto 0) ); end RAM; architecture Behavioral of RAM is type ram_type is array (4095 downto 0) of STD_LOGIC_vector (7 downto 0); signal RAM: ram_type; signal RAM_DOUT : std_logic_vector (7 downto 0); begin process (Clk, RAM_WE, RAM_ADDR, RAM_DI, RAM_EN) begin if CLK'event and CLK = '0' then if (RAM_WE = '1') then RAM(conv_integer(RAM_ADDR)) <= RAM_DI; end if; RAM_DOUT <= RAM(conv_integer(RAM_ADDR)) ; end if; end process; RAM_DATA <= RAM_DOUT when (RAM_EN = '1') else (others => '0') ; end Behavioral; ROM_INTERN jest to wewnętrzna pamięć programu która może być odłączona gdy ustawimy siódmy bit w rejestrze STATUS na '1'. Konsekwencją tego program będzie czytany z zewnętrznej pamięci. ROM_INTERN napisałem do testowania. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ROM_INTERN is Port ( ROM_ADDR : in STD_LOGIC_VECTOR (11 downto 0); ROM_DATA : out STD_LOGIC_VECTOR (15 downto 0) ); end ROM_INTERN; architecture Behavioral of ROM_INTERN is begin with ROM_ADDR select ROM_DATA <= X"0000" when X"000", X"0000" when X"001", X"0E07" when X"002", X"010F" when X"003", X"6F80" when X"004", X"2780" when X"005", X"2780" when X"006", X"5F80" when X"007", X"EF00" when X"008", X"F000" when X"009", X"0000" when others; end Behavioral; PORTA_CONTROL jest to zewnętrzny port komunikacyjny dwukierunkowy library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity PORTA_CONTROL is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; TRISA_WE : in STD_LOGIC; PORTA_WE : in STD_LOGIC; TRISA_EN : in STD_LOGIC; PORTA_EN : in STD_LOGIC; RA : inout STD_LOGIC_VECTOR(7 downto 0); ALU_PORTA : out STD_LOGIC_VECTOR(7 downto 0); ALU_Y : in STD_LOGIC_VECTOR(7 downto 0) ); end PORTA_CONTROL; architecture Behavioral of PORTA_CONTROL is signal PORTA_IO : std_logic_vector (7 downto 0); signal TRISA : std_logic_vector (7 downto 0); signal PORTA : std_logic_vector (7 downto 0); signal ALU_PTRISA : std_logic_vector (7 downto 0); signal ALU_PPORTA : std_logic_vector (7 downto 0); begin ALU_PORTA <= ALU_PTRISA or ALU_PPORTA; ALU_PPORTA <= PORTA_IO when (PORTA_EN = '1') else (others => '0'); ALU_PTRISA <= TRISA when (TRISA_EN = '1') else (others => '0'); RA(0) <= PORTA(0) when (TRISA(0) = '0') else 'Z'; --Ustawienie pinów portu jako wejście (wyjście) RA(1) <= PORTA(1) when (TRISA(1) = '0') else 'Z'; RA(2) <= PORTA(2) when (TRISA(2) = '0') else 'Z'; RA(3) <= PORTA(3) when (TRISA(3) = '0') else 'Z'; RA(4) <= PORTA(4) when (TRISA(4) = '0') else 'Z'; RA(5) <= PORTA(5) when (TRISA(5) = '0') else 'Z'; RA(6) <= PORTA(6) when (TRISA(6) = '0') else 'Z'; RA(7) <= PORTA(7) when (TRISA(7) = '0') else 'Z'; PORTA_IO(0) <= RA(0) when (TRISA(0) = '1') else PORTA(0); --Odczytywanie portu PORTA_IO(1) <= RA(1) when (TRISA(1) = '1') else PORTA(1); PORTA_IO(2) <= RA(2) when (TRISA(2) = '1') else PORTA(2); PORTA_IO(3) <= RA(3) when (TRISA(3) = '1') else PORTA(3); PORTA_IO(4) <= RA(4) when (TRISA(4) = '1') else PORTA(4); PORTA_IO(5) <= RA(5) when (TRISA(5) = '1') else PORTA(5); PORTA_IO(6) <= RA(6) when (TRISA(6) = '1') else PORTA(6); PORTA_IO(7) <= RA(7) when (TRISA(7) = '1') else PORTA(7); process (Clk, Reset, ALU_Y, PORTA_WE) begin if Reset = '0' then PORTA <= (others => '0'); else if CLK'event and CLK = '0' then if PORTA_WE = '1' then PORTA <= ALU_Y; end if; end if; end if; end process; process (Clk, Reset, ALU_Y, PORTA_WE) begin if Reset = '0' then TRISA <= (others => '0'); else if CLK'event and CLK = '0' then if TRISA_WE = '1' then TRISA <= ALU_Y; end if; end if; end if; end process; end Behavioral; Tabela z adresami do zapisu i odczytu rejestrów To na razie tyle. Pozdrawiam. Edytowano Maj 30, 2024 przez kroszkanorber 1
kroszkanorber Czerwiec 16, 2024 Autor tematu Udostępnij Czerwiec 16, 2024 (edytowany) Witam. Zamieszczam ostateczną wersją kodu. Wybrałem instrukcje kontrolera, które są moim zdaniem niezbędne dla programowania, a reszta kodów nie została zaimplementowana i są w tym przypadku instrukcjami pustymi (NOP). Kontroler posiada jedno wejście przerwania z zewnątrz wyzwalane stanem logicznym = '1', port 8 bit we/wy, port programowania pamięci programu (adres 12 bit, dane 16bit, sygnał zapisu WE). Układ posiada zaimplementowaną tylko jednostkę ALU z pamięcią ram 4kB, stosem przerwań o 16 poziomach, rejestry (work, status, bsr, port, prod). W celu zaadresowania pamięci wymagane jest ustawienie w rejestrze BSR banku pamięci z której chcemy odczytać, lub do której zapisać dane. Instrukcje ALU wykonywane są w jednym cyklu zegarowym równoważnym z jednym taktem zegara. Polecenia CALL, GOTO wykonywane są w dwóch cyklach czyli w dwóch taktach zegara ze względu na długość adresu skoku w programie. Polecenia są długości 16 bitów z możliwością adresowania licznika programu do 20 bitów. Rozwiązaniem microchip jest wprowadzenie polecenia ndword które jest powiązane z poleceniami CALL i GOTO. Polecenie ndword jest wpisywane do kodu przez kompilator, w związku z tym, nie ma takiej instrukcji w kodzie ASM. Polecenie ndword występuje w kodzie po poleceniu CALL lub GOTO uzupełniając informacje o adresie programu. Wszystkie instrukcje użyte w mojej interpretacji są kompatybilne z instrukcjami kontrolera PIC18F4550. Układ w którym umieściłem kod to spartan xc3s200a zajmuje 6 z 16 bloków pamięci konfigurowalnej RAM, 2 bloki wykorzystane są dla pamięci RAM kontrolera, 4 bloki połączone są w magistralę 16 bit (dane pamięci programu). Kod zajmuje 23% zasobów Slices(cokolwiek to znaczy). By korzystać z układu spartan xc3s50a wymagana jest modyfikacja w kodzie. Problemem są tylko 3 bloki dostępnej pamięci. Rozwiązaniem jest znaczne ograniczenie pamięci wewnętrznej programu lub korzystanie z pamięci zewnętrznej. Kod konfiguracyjny: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity PC18FCore is Port ( Clk : in STD_LOGIC; --wejście zegarowe Reset : in STD_LOGIC; --reset kontrolera Interrupt : in STD_LOGIC; --przerwanie z zewnątrz aktywne '1' RomWe : in STD_LOGIC; --zezwolenie dla zapisu danych do pamięci programu RomAddrin : in STD_LOGIC_VECTOR (11 downto 0); --adres zapisu danych do pamięci programu RomDatain : in STD_LOGIC_VECTOR (15 downto 0); --dane zapisywane do pamięci programu RA : inout STD_LOGIC_VECTOR (7 downto 0) --port 8 bit WE/WY ); end PC18FCore; architecture Behavioral of PC18FCore is -- instrukcje PIC signal ADDWF : STD_LOGIC; signal ANDWF : STD_LOGIC; signal COMF : STD_LOGIC; signal DECF : STD_LOGIC; signal DECFSZ : STD_LOGIC; signal INCF : STD_LOGIC; signal INCFSZ : STD_LOGIC; signal IORWF : STD_LOGIC; signal MOVF : STD_LOGIC; signal MOVWF : STD_LOGIC; signal MULWF : STD_LOGIC; signal RLCF : STD_LOGIC; signal RRCF : STD_LOGIC; signal SUBWF : STD_LOGIC; signal SWAPF : STD_LOGIC; signal TSTFSZ : STD_LOGIC; signal XORWF : STD_LOGIC; signal BCF : STD_LOGIC; signal BSF : STD_LOGIC; signal BTFSC : STD_LOGIC; signal BTFSS : STD_LOGIC; signal BTG : STD_LOGIC; signal ADDLW : STD_LOGIC; signal ANDLW : STD_LOGIC; signal IORLW : STD_LOGIC; signal MOVLW : STD_LOGIC; signal MULLW : STD_LOGIC; signal SUBLW : STD_LOGIC; signal XORLW : STD_LOGIC; signal NdWord : STD_LOGIC; signal MOVLB : STD_LOGIC; signal CALL : STD_LOGIC; signal GOTO : STD_LOGIC; signal RETFIE : STD_LOGIC; signal RETLW : STD_LOGIC; signal RETUR_N : STD_LOGIC; signal bd : STD_LOGIC; --wybór zapisu danych '0'=Wreg/ '1'=Ram signal ba : STD_LOGIC; --wybór banku pamięci Ram 1z16 '0'=RamAddr(11 downto 8) <= "0000"/'1'=RamAddr(11 downto 8) <= "BSRreg" signal bs : STD_LOGIC; --wybór zapisu do rejestru Shadow(zabezpieczenia danych przed nadpisaniem dla Wreg,BSRreg,Status) '1'=aktywny signal Shadow : STD_LOGIC; signal C : STD_LOGIC; signal DC : STD_LOGIC; signal Z : STD_LOGIC; signal OV : STD_LOGIC; signal N : STD_LOGIC; signal AluAND : STD_LOGIC; --sygnały aktywujące operacje w jednostce arytmetyczno-logicznej signal AluIOR : STD_LOGIC; signal AluXOR : STD_LOGIC; signal AluADD : STD_LOGIC; signal AluSUB : STD_LOGIC; signal Q1 : STD_LOGIC_VECTOR(4 downto 0); --rejestry pomocnicze dla sumatora signal Q2 : STD_LOGIC_VECTOR(3 downto 0); signal Q3 : STD_LOGIC_VECTOR(1 downto 0); signal A : STD_LOGIC_VECTOR(7 downto 0); --wejścia jednostki arytmetyczno-logicznej signal B : STD_LOGIC_VECTOR(7 downto 0); signal Y : STD_LOGIC_VECTOR(7 downto 0); --wyjście jednostki arytmetyczno-logicznej signal ASB : STD_LOGIC_VECTOR(7 downto 0); --wejście danych B dla sumatora negacja ddanych dla funkcji odejmowania signal Wreg : STD_LOGIC_VECTOR(7 downto 0); --rejestr roboczy signal WregWe : STD_LOGIC; --zezwolenie zapisu do rejestru roboczego signal WregShadow : STD_LOGIC_VECTOR(7 downto 0); --schowek danych rejestru roboczego signal Selb0 : STD_LOGIC_VECTOR(7 downto 0); --dekoder 1 z 8 signal Selb1 : STD_LOGIC_VECTOR(7 downto 0); --dekoder 1 z 8 zanegowany signal YAdd : STD_LOGIC_VECTOR(7 downto 0); --wyjścia alu signal YAnd : STD_LOGIC_VECTOR(7 downto 0); signal YIor : STD_LOGIC_VECTOR(7 downto 0); signal YXor : STD_LOGIC_VECTOR(7 downto 0); signal YSwa : STD_LOGIC_VECTOR(7 downto 0); signal YRrc : STD_LOGIC_VECTOR(7 downto 0); signal YRlc : STD_LOGIC_VECTOR(7 downto 0); signal Status : STD_LOGIC_VECTOR(7 downto 0); signal PROD : STD_LOGIC_VECTOR(15 downto 0); --rejestr wyniku mnożenia signal PRODH : STD_LOGIC_VECTOR(7 downto 0); signal PRODL : STD_LOGIC_VECTOR(7 downto 0); signal PortAEn : STD_LOGIC; signal PortAWe : STD_LOGIC; signal TrisAEn : STD_LOGIC; signal TrisAWe : STD_LOGIC; signal PortA : STD_LOGIC_VECTOR(7 downto 0); signal TrisA : STD_LOGIC_VECTOR(7 downto 0); signal PRODHEn : STD_LOGIC; signal PRODLEn : STD_LOGIC; signal StatusEn : STD_LOGIC; signal StatusWe : STD_LOGIC; signal C_DC_OV_We : STD_LOGIC; signal Z_N_We : STD_LOGIC; signal StatusShadow : STD_LOGIC_VECTOR(7 downto 0); signal BSRreg : STD_LOGIC_VECTOR(3 downto 0); --rejestr banków pamięci Ram signal BSRShadow : STD_LOGIC_VECTOR(3 downto 0); type ram_type is array (4095 downto 0) of std_logic_vector (7 downto 0); signal RAM : ram_type; signal RamWe : STD_LOGIC; signal RamAddr : STD_LOGIC_VECTOR(11 downto 0); signal RamData : STD_LOGIC_VECTOR(7 downto 0); signal RamDataout : STD_LOGIC_VECTOR(7 downto 0); type rom_type is array (4095 downto 0) of std_logic_vector (15 downto 0); signal ROM : rom_type; signal RomAddr : STD_LOGIC_vector (11 downto 0); signal RomData : STD_LOGIC_vector (15 downto 0); signal PCL : STD_LOGIC_vector (7 downto 0); signal TOSCnt : STD_LOGIC_vector (3 downto 0); --licznik stosu signal TOS : STD_LOGIC_vector (11 downto 0); signal TOS0 : STD_LOGIC_vector (11 downto 0); --rejestry w których zapisywane są adresy powrotne licznika programu dla przerwań signal TOS1 : STD_LOGIC_vector (11 downto 0); signal TOS2 : STD_LOGIC_vector (11 downto 0); signal TOS3 : STD_LOGIC_vector (11 downto 0); signal TOS4 : STD_LOGIC_vector (11 downto 0); signal TOS5 : STD_LOGIC_vector (11 downto 0); signal TOS6 : STD_LOGIC_vector (11 downto 0); signal TOS7 : STD_LOGIC_vector (11 downto 0); signal TOS8 : STD_LOGIC_vector (11 downto 0); signal TOS9 : STD_LOGIC_vector (11 downto 0); signal TOS10 : STD_LOGIC_vector (11 downto 0); signal TOS11 : STD_LOGIC_vector (11 downto 0); signal TOS12 : STD_LOGIC_vector (11 downto 0); signal TOS13 : STD_LOGIC_vector (11 downto 0); signal TOS14 : STD_LOGIC_vector (11 downto 0); signal TOS15 : STD_LOGIC_vector (11 downto 0); signal TOSINT : STD_LOGIC_vector (11 downto 0); --rejestr licznika programu z przerwania zewnętrznego signal SKIP : STD_LOGIC; -- sygnał pomocniczy dla instrukcji skoków w programie(polecenia skoków zawarte są w dwóch słowach ze względu na adresy do 2MB) signal INTEN : STD_LOGIC_vector (1 downto 0); ------------------------------------------------------------------------------------------------ begin ADDWF <= '1' when RomData(15 downto 10) = "001001" else '0' ; --ADDWF f, d, a C, DC, Z, OV, N ANDWF <= '1' when RomData(15 downto 10) = "000101" else '0' ; --ANDWF f, d, a Z, N COMF <= '1' when RomData(15 downto 10) = "000111" else '0' ; --COMF f, d, a Z, N DECF <= '1' when RomData(15 downto 10) = "000001" else '0' ; --DECF f, d, a C, DC, Z, OV, N DECFSZ <= '1' when RomData(15 downto 10) = "001011" else '0' ; --DECFSZ f, d, a INCF <= '1' when RomData(15 downto 10) = "001010" else '0' ; --INCF f, d, a C, DC, Z, OV, N INCFSZ <= '1' when RomData(15 downto 10) = "001111" else '0' ; --INCFSZ f, d, a IORWF <= '1' when RomData(15 downto 10) = "000100" else '0' ; --IORWF f, d, a Z, N MOVF <= '1' when RomData(15 downto 10) = "010100" else '0' ; --MOVF f, d, a Z, N NdWord <= '1' when RomData(15 downto 12) = "1111" else '0' ; --NdWord MOVWF <= '1' when RomData(15 downto 9) = "0110111" else '0' ; --MOVWF f, a MULWF <= '1' when RomData(15 downto 9) = "0000001" else '0' ; --MULWF f, a RLCF <= '1' when RomData(15 downto 10) = "001101" else '0' ; --RLCF f, d, a C, Z, N RRCF <= '1' when RomData(15 downto 10) = "001100" else '0' ; --RRCF f, d, a C, Z, N SUBWF <= '1' when RomData(15 downto 10) = "010111" else '0' ; --SUBWF f, d, a C, DC, Z, OV, N SWAPF <= '1' when RomData(15 downto 10) = "010101" else '0' ; --SWAPF f, d, a TSTFSZ <= '1' when RomData(15 downto 9) = "0110011" else '0' ; --TSTFSZ f, a XORWF <= '1' when RomData(15 downto 10) = "000110" else '0' ; --XORWF f, d, a Z, N BCF <= '1' when RomData(15 downto 12) = "1001" else '0' ; --BCF f, b, a BSF <= '1' when RomData(15 downto 12) = "1000" else '0' ; --BSF f, b, a BTFSC <= '1' when RomData(15 downto 12) = "1011" else '0' ; --BTFSC f, b, a BTFSS <= '1' when RomData(15 downto 12) = "1010" else '0' ; --BTFSS f, b, a BTG <= '1' when RomData(15 downto 12) = "0111" else '0' ; --BTG f, b, a ADDLW <= '1' when RomData(15 downto 8) = "00001111" else '0' ; --ADDLW k C,DC,Z,OV,N ANDLW <= '1' when RomData(15 downto 8) = "00001011" else '0' ; --ANDLW k Z,N IORLW <= '1' when RomData(15 downto 8) = "00001001" else '0' ; --IORLW k Z, N MOVLW <= '1' when RomData(15 downto 8) = "00001110" else '0' ; --MOVLW k Z, N MULLW <= '1' when RomData(15 downto 8) = "00001101" else '0' ; --MULLW k SUBLW <= '1' when RomData(15 downto 8) = "00001000" else '0' ; --SUBLW k C, DC, Z, OV, N XORLW <= '1' when RomData(15 downto 8) = "00001010" else '0' ; --XORLW k Z, N RETLW <= '1' when RomData(15 downto 8) = "00001100" else '0' ; --RETLW k MOVLB <= '1' when RomData(15 downto 8) = "00000001" else '0' ; --MOVLB k RETLW <= '1' when RomData(15 downto 8) = "00001100" else '0' ; --RETLW k GOTO <= '1' when RomData(15 downto 8) = "11101111" else '0' ; --GOTO n CALL <= '1' when RomData(15 downto 9) = "1110110" else '0' ; --CALL n RETFIE <= '1' when (RomData(7 downto 1) = "000000000001000") else '0' ; --RETFIE RETUR_N <= '1' when (RomData(7 downto 1) = "000000000001001") else '0' ; --RETURN bd <= RomData(9); ba <= RomData(8); bs <= RomData(0); Shadow <= (bs and (Interrupt or RETFIE or RETUR_N)) or (ba and CALL); --dekoder zapisu danych do schowka (tyko przerwania) --dekoder wyboru instrukcji ALU AluAND <= ANDLW or ANDWF or BCF or BTFSS or BTFSC; AluIOR <= IORLW or IORWF or BSF or MOVLW or MOVF or MOVWF; AluXOR <= XORLW or XORWF or BTG or COMF; AluADD <= ADDLW or ADDWF or INCF or INCFSZ or TSTFSZ; AluSUB <= SUBLW or SUBWF or DECF or DECFSZ; --dekoder zapisu danych RamWe <= '1' when ((RomData(15 downto 12) > "0000") and (RomData(15 downto 12) < "0110") and (bd = '1')) or ((RomData(15 downto 10) = "000001") and (bd = '1')) or ((RomData(15 downto 12) = "0110")) or ((RomData(15 downto 12) > "1000") and (RomData(15 downto 12) < "1100")) or ((RomData(15 downto 12) > "0111")) ; WregWe <= '1' when ((RomData(15 downto 12) > "0000") and (RomData(15 downto 12) < "0110") and (bd = '0')) or ((RomData(15 downto 10) = "000001") and (bd = '0')) or ((RomData(15 downto 8) > "00000111") and (RomData(15 downto 8) < "00010000")); ------------------------------------------------------------------------------------------------ --dekoder 1 z 8 dla instrukcji na pojedynczych bitach with RomData(11 downto 9) select Selb0 <= "00000001" when "000", "00000010" when "001", "00000100" when "010", "00001000" when "011", "00010000" when "100", "00100000" when "101", "01000000" when "110", "10000000" when others; Selb1 <= not Selb0; ------------------------------------------------------------------------------------------------ --wybór sygnałów podawanych na wejście jednostki ALU process(RomData, Wreg, RamData, Selb0, Selb1, COMF, MOVLW, MOVWF, MOVF, BCF, BSF, BTFSC, BTFSS, BTG, DECF, INCF, INCFSZ, DECFSZ, TSTFSZ) begin if (RomData(15 downto 8) = 0) then A <= RomData(7 downto 0); B <= Wreg; elsif (BCF = '1') then A <= RamData; B <= Selb1; elsif ((BSF = '1') or (BTFSC = '1') or (BTFSS = '1') or (BTG = '1')) then A <= RamData; B <= Selb0; elsif ((INCF = '1') or (DECF = '1') or (DECFSZ = '1') or (INCFSZ = '1')) then A <= RamData; B <= "00000001"; elsif (COMF = '1') then A <= RamData; B <= (others => '1'); elsif (MOVLW = '1') then A <= RomData(7 downto 0); B <= (others => '0'); elsif ((MOVF = '1') or (TSTFSZ = '1')) then A <= RamData; B <= (others => '0'); elsif (MOVWF = '1') then A <= (others => '0'); B <= Wreg; else A <= RamData; B <= Wreg; end if; end process; ------------------------------------------------------------------------------------------------ --sumator ASB <= (not B) when (AluSUB = '1') else B; Q1 <= ('0' & A(3 downto 0)) + ('0' & ASB(3 downto 0)) + AluSUB; --dodawanie(4 bity) z przepełnieniem i wejściem odejmowania Q2 <= ('0' & A(6 downto 4)) + ('0' & ASB(6 downto 4)) + Q1(4); --dodawanie(3 bity) z przepełnieniem Q3 <= ('0' & A(7)) + ('0' & ASB(7)) + ('0' & Q2(3)); --dodawanie(1 bit) z przepełnieniem C <= Q3(1); --flaga przepełnienia sumy 8 bit DC <= Q1(4); --flaga przepełnienia sumy 4 pierwszych bitów Z <= not (Y(0) or Y(1) or Y(2) or Y(3) or Y(4) or Y(5) or Y(6) or Y(7)); --dekoder wyniku zerowego ALU OV <= Q2(3) xor Q3(1); --flaga przepełnienia dla liczb ze znakiem N <= Y(7); --wskażnik dla znaku wyniku liczby ------------------------------------------------------------------------------------------------ YAdd <= (Q3(0) & Q2(2 downto 0) & Q1(3 downto 0)) when ((AluADD = '1') or (AluSUB = '1')) else (others => '0'); YAnd <= (A and B) when (AluAND = '1') else (others => '0'); YIor <= (A or B) when (AluIOR = '1') else (others => '0'); YXor <= (A xor B) when (AluXOR = '1') else (others => '0'); YSwa <= (A(3 downto 0) & A(7 downto 4)) when (SWAPF = '1') else (others => '0'); YRrc <= (Status(0) & A(7 downto 1)) when (RRCF = '1') else (others => '0'); YRlc <= (A(6 downto 0) & Status(0)) when (RRCF = '1') else (others => '0'); ------------------------------------------------------------------------------------------------ --rejestr Status w którym przechowywane są flagi ALU C_DC_OV_We <= AluADD or AluSUB; Z_N_We <= AluADD or AluSUB or AluAND or AluIOR or ALUXOR; process(Clk, Reset, Shadow, StatusWE, C_DC_OV_We, Z_N_We, C, DC, Z, OV, N, RRCF, RLCF, Y) begin if Reset = '0' then Status <= (others => '0'); StatusShadow <= (others => '0'); else if Clk'event and Clk = '0' then if Shadow = '1' then --używane tylko w przerwaniach i zezwoleniem "bs" Status <= StatusShadow; --zamiana zawartości rejestrów w celu zabezpieczenia danych przed nadpisaniem StatusShadow <= Status; elsif (StatusWe = '1') then --nadpisanie danych z woli żytkownika Status <= Y; elsif (C_DC_OV_We = '1') then --nadpisanie danych wynikające z zinstrukcji Status(0) <= C; Status(1) <= DC; Status(3) <= OV; elsif (Z_N_We = '1') then Status(2) <= Z; Status(4) <= N; elsif (RRCF = '1') then Status(0) <= Y(0); elsif (RLCF = '1') then Status(0) <= Y(7); end if; end if; end if; end process; StatusEn <= '1' when (RamAddr = X"FD8") else '0'; --rejestr Status znajduje się pod adresem Ram X"FD8" StatusWE <= '1' when ((RamAddr = X"FD8") and (bd = '1')) else '0'; ------------------------------------------------------------------------------------------------ process(Clk, Reset, RomData, MOVLB, Shadow) begin if Reset = '0' then BSRreg <= (others => '0'); BSRShadow <= (others => '0'); else if Clk'event and Clk = '0' then if Shadow = '1' then BSRShadow <= BSRreg; BSRreg <= BSRShadow; elsif MOVLB = '1' then --zapis danych do rejestru wyboru banku adresu Ram 1 z 16 BSRreg <= RomData(3 downto 0); end if; end if; end if; end process; ------------------------------------------------------------------------------------------------ process(Clk, Reset, MULLW, MULWF, A, B) begin if Reset = '0' then PROD <= (others => '0'); else if Clk'event and Clk = '0' then if ((MULLW = '1') or (MULWF = '1')) then --operacja mnożenia PROD <= A * B; end if; end if; end if; end process; PRODH <= PROD(15 downto 8); PRODL <= PROD(7 downto 0); PRODHEn <= '1' when (RamAddr = X"FF4") else '0'; PRODLEn <= '1' when (RamAddr = X"FF3") else '0'; ------------------------------------------------------------------------------------------------ process(Clk, Reset, Y, WregWe, Shadow) --rejestr roboczy begin if Reset = '0' then Wreg <= (others => '0'); WregShadow <= (others => '0'); else if Clk'event and Clk = '0' then if (Shadow = '1') then WregShadow <= Wreg; Wreg <= WregShadow; elsif (WregWe = '1') then Wreg <= Y; end if; end if; end if; end process; ------------------------------------------------------------------------------------------------ process(Clk, Reset, Y, PortAWe, TrisAWe) --PORTA begin if Reset = '0' then PortA <= (others => '0'); TrisA <= (others => '0'); else if Clk'event and Clk = '0' then if (PortAWe = '1') then --zapis danych wyjściowych do portu PortA <= Y; elsif (TrisAWe = '1') then --zapis bitów do protu ustawiających go jako wjście='1'/ wyjście='0' TrisA <= Y; end if; end if; end if; end process; PortAWe <= '1' when ((RamWe = '1') and (RamAddr = X"F80")) else '0'; PortAEn <= '1' when (RamAddr = X"F80") else '0'; TrisAWe <= '1' when ((RamWe = '1') and (RamAddr = X"F92")) else '0'; TrisAEn <= '1' when (RamAddr = X"F92") else '0'; RA(0) <= PortA(0) when (TrisA(0) = '0') else 'Z'; -- dekoder ustawiający port RA jako wejściowy lub wejściowy RA(1) <= PortA(1) when (TrisA(1) = '0') else 'Z'; RA(2) <= PortA(2) when (TrisA(2) = '0') else 'Z'; RA(3) <= PortA(3) when (TrisA(3) = '0') else 'Z'; RA(4) <= PortA(4) when (TrisA(4) = '0') else 'Z'; RA(5) <= PortA(5) when (TrisA(5) = '0') else 'Z'; RA(6) <= PortA(6) when (TrisA(6) = '0') else 'Z'; RA(7) <= PortA(7) when (TrisA(7) = '0') else 'Z'; ------------------------------------------------------------------------------------------------ process (CLK, RamWe, Y, RamAddr) --pamięć Ram 4kB begin if CLK'event and CLK = '0' then if (RamWe = '1') then RAM(conv_integer(RamAddr)) <= Y; end if; RamDataout <= RAM(conv_integer(RamAddr)); end if; end process; ------------------------------------------------------------------------------------------------ process (CLK, RomWe, RomAddrin, RomDatain) --pamięć Rom dwuportowa 4k słów begin if CLK'event and CLK = '0' then if (RomWe = '1') then ROM(conv_integer(RomAddrin)) <= RomDatain; end if; RomData <= ROM(conv_integer(RomAddr)); end if; end process; ------------------------------------------------------------------------------------------------ process(Clk, Reset, RomData, GOTO, CALL, RETUR_N, RETLW, NdWord, RETFIE, Interrupt, Z, BTFSC, BTFSS, DECFSZ, INCFSZ, TSTFSZ) --licznik programu begin if Reset = '0' then RomAddr <= (others => '0'); PCL <= (others => '0'); TOSINT <= (others => '0'); TOSCnt <= (others => '0'); SKIP <= '0'; INTEN <= "00"; else if Clk'event and Clk = '0' then if ((GOTO = '1') or (CALL = '1')) then PCL <= RomData(7 downto 0); else null; end if; if CALL = '1' then --CALL TOSCnt <= TOSCnt + 1; elsif ((RETUR_N = '1') or (RETLW = '1')) then --RETURN, RETLW, TOSCnt <= TOSCnt - 1; end if; if (GOTO = '1') then --GOTO SKIP <= '1'; elsif (CALL = '1') then --CALL SKIP <= '1'; elsif NdWord = '1' then SKIP <= '0'; end if; if ((INTERRUPT = '1') and (INTEN = "00")) then --INTERRUPT INTEN <= INTEN + 1; elsif (INTEN = "01") then --INTERRUPT TOSINT <= RomAddr; INTEN <= INTEN + 1; elsif ((RETFIE = '1') and (INTEN = "10")) then --RETFIE INTEN <= "00"; else null; end if; if (INTEN = "01") then --INTERRUPT RomAddr <= X"008"; elsif (SKIP = '1') then RomAddr(11 downto 8) <= RomData(3 downto 0); RomAddr(7 downto 0) <= PCL; elsif ((RETUR_N = '1') or (RETLW = '1')) then --RETURN, RETLW, RomAddr <= TOS + 2; elsif ((RETFIE = '1') and (INTEN = "10")) then --RETFIE RomAddr <= TOSINT + 1; elsif (((BTFSC = '1') or (DECFSZ = '1') or (INCFSZ = '1') or (TSTFSZ = '1')) and (Z = '1'))then RomAddr <= RomAddr + 2; elsif ((BTFSS = '1') and (Z = '0'))then RomAddr <= RomAddr + 2; else RomAddr <= RomAddr + 1; end if; end if; end if; end process; with TOSCnt select TOS <= TOS0 when "0001", TOS1 when "0010", TOS2 when "0011", TOS3 when "0100", TOS4 when "0101", TOS5 when "0110", TOS6 when "0111", TOS7 when "1000", TOS8 when "1001", TOS9 when "1010", TOS10 when "1011", TOS11 when "1100", TOS12 when "1101", TOS13 when "1110", TOS14 when "1111", TOS15 when others; process(Clk, Reset, TOSCnt, CALL, RomAddr) begin if Reset = '0' then TOS0 <= (others => '0'); TOS1 <= (others => '0'); TOS2 <= (others => '0'); TOS3 <= (others => '0'); TOS4 <= (others => '0'); TOS5 <= (others => '0'); TOS6 <= (others => '0'); TOS7 <= (others => '0'); TOS8 <= (others => '0'); TOS9 <= (others => '0'); TOS10 <= (others => '0'); TOS11 <= (others => '0'); TOS12 <= (others => '0'); TOS13 <= (others => '0'); TOS14 <= (others => '0'); TOS15 <= (others => '0'); else if Clk'event and Clk = '0' then if Call = '1' then case TOSCnt is when "0001" => TOS1 <= RomAddr; when "0010" => TOS2 <= RomAddr; when "0011" => TOS3 <= RomAddr; when "0100" => TOS4 <= RomAddr; when "0101" => TOS5 <= RomAddr; when "0110" => TOS6 <= RomAddr; when "0111" => TOS7 <= RomAddr; when "1000" => TOS8 <= RomAddr; when "1001" => TOS9 <= RomAddr; when "1010" => TOS10 <= RomAddr; when "1011" => TOS11 <= RomAddr; when "1100" => TOS12 <= RomAddr; when "1101" => TOS13 <= RomAddr; when "1110" => TOS14 <= RomAddr; when "1111" => TOS15 <= RomAddr; when others => TOS0 <= RomAddr; end case; else null; end if; end if; end if; end process; ------------------------------------------------------------------------------------------------ process(StatusEn, Status, RamDataout, PRODHEn, PRODH, PRODLEn, PRODL, PortAEn, TrisAEn, PortA, TrisA) begin if (StatusEn = '1') then --wybór danych dla RamData RamData <= Status; elsif (PRODHEn = '1') then RamData <= PRODH; elsif (PRODLEn = '1') then RamData <= PRODL; elsif (PortAEn = '1') then RamData <= PortA; elsif (TrisAEn = '1') then RamData <= TrisA; else RamData <= RamDataout; end if; end process; RamAddr(11) <= BSRreg(3) and ba; RamAddr(10) <= BSRreg(2) and ba; RamAddr(9) <= BSRreg(1) and ba; RamAddr(8) <= BSRreg(0) and ba; RamAddr(7 downto 0) <= RomData(7 downto 0); Y <= YAdd or YAnd or YIor or YXor or YSwa or YRrc or YRlc; end Behavioral; Edytowano Czerwiec 16, 2024 przez kroszkanorber 1
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »