Skocz do zawartości

PIC18F4550 w fpga 1


kroszkanorber

Pomocna odpowiedź

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 

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

@FlyingDutch Witaj

Kody napisałem w komponentach jak już wspominałem wcześniej.

image.thumb.png.e101211116b9be72e6caff56055de085.png

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

image.thumb.png.81669dff0c7fea578410d608245c3e1e.png

To  na razie tyle.

Pozdrawiam.

Edytowano przez kroszkanorber
  • Pomogłeś! 1
Link do komentarza
Share on other sites

(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.

image.thumb.png.da8f95225724fcbd3e4aaf7a7f684110.png

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 przez kroszkanorber
  • Lubię! 1
Link do komentarza
Share on other sites

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ę »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.