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

📄 piccore.vhd

📁 PIC源代码很不错
💻 VHD
📖 第 1 页 / 共 4 页
字号:
-- PICCORE.vhd-- CPU core of CQPIC (PIC16F84/16F84A)-- (1) Version 1.00a		Nov 1  1999-- (2) Version 1.00b		Dec 10 2000		made a patch for BUG in MAX+plus2 VHDL compiler-- (3) Version 1.00c		Aug 07 2002		made a patch for carry flag operations at substraction operations-- (4) Version 1.00d		Aug 26 2004		debugged Z flag behavior (in case such that distinations are same as them)---- Copyright(c)1999-2004 Sumio Morioka-- e-mail:morioka@fb3.so-net.ne.jp, URL:http://www02.so-net.ne.jp/~morioka/cqpic.htmlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity piccore is	generic (		-- You can change the following parameters as you would like		STACK_SIZE	: integer := 8;									-- Size of PC stack		WDT_SIZE	: integer := 255								-- Size of watch dog timer (WDT)	);	port (	-- program ROM data bus/address bus		progdata	: in  std_logic_vector(13 downto 0);			-- ROM read data		progadr		: out std_logic_vector(12 downto 0);			-- ROM address	-- data RAM data bus/address bus/control signals		ramdtin		: in  std_logic_vector(7 downto 0);				-- RAM read data		ramdtout	: out std_logic_vector(7 downto 0);				-- RAM write data		ramadr		: out std_logic_vector(8 downto 0);				-- RAM address; ramadr(8..7) indicates RAM-BANK		readram		: out std_logic;								-- RAM read strobe (H active)		writeram	: out std_logic;								-- RAM write strobe (H active)	-- EEPROM data bus/address bus		existeeprom	: in  std_logic;								-- Set to '1' if EEPROM is implemented.		eepdtin		: in  std_logic_vector(7 downto 0);				-- EEPROM read data		eepdtout	: out std_logic_vector(7 downto 0);				-- EEPROM write data		eepadr		: out std_logic_vector(7 downto 0);				-- EEPROM address		readeepreq	: out std_logic;								-- EEPROM read request (H active)		readeepack	: in  std_logic;								-- EEPROM read acknowledge (H active)		writeeepreq	: out std_logic;								-- EEPROM write request (H active)		writeeepack	: in  std_logic;								-- EEPROM write acknowledge (H active)	-- I/O ports		porta_in	: in  std_logic_vector(4 downto 0);				-- PORT-A input data		porta_out	: out std_logic_vector(4 downto 0);				-- PORT-A output data		porta_dir	: out std_logic_vector(4 downto 0);				-- TRISA: PORT-A signal direction (H:input, L:output)		portb_in	: in  std_logic_vector(7 downto 0);				-- PORT-B input data		portb_out	: out std_logic_vector(7 downto 0);				-- PORT-B output data		portb_dir	: out std_logic_vector(7 downto 0);				-- TRISB: PORT-B signal direction (H:input, L:output)		rbpu		: out std_logic;								-- PORT_B pull-up enable (usually not used)	-- PORT-B interrupt input		int0		: in  std_logic;								-- PORT-B(0) INT		int4		: in  std_logic;								-- PORT-B(4) INT		int5		: in  std_logic;								-- PORT-B(5) INT		int6		: in  std_logic;								-- PORT-B(6) INT		int7		: in  std_logic;								-- PORT-B(7) INT	-- TMR0 Control		t0cki		: in  std_logic;								-- T0CKI (PORT-A(4))	-- Watch Dog Timer Control		wdtena		: in  std_logic;								-- WDT enable (H active)		wdtclk		: in  std_logic;								-- WDT clock		wdtfull		: out std_logic;								-- WDT-full indicator (H active)	-- CPU clock stop/start indicators		powerdown	: out std_logic;								-- SLEEP-mode; if H, you can stop system clock clkin		startclkin	: out std_logic;								-- WAKEUP; if H, you should turn on clock for waking up from sleep-mode	-- CPU reset		ponrst_n	: in  std_logic;								-- Power-on reset (L active)		mclr_n		: in  std_logic;								-- Normal reset (L active)	-- CPU clock		clkin		: in  std_logic;								-- Clock input		clkout		: out std_logic									-- Clock output (clkin/4)	);end piccore;architecture RTL of piccore is	-- User registers	signal w_reg			: std_logic_vector(7 downto 0);			-- W	signal tmr0_reg			: std_logic_vector(7 downto 0);			-- TMR0	signal pc_reg			: std_logic_vector(12 downto 0);		-- PCH/PCL	signal status_reg		: std_logic_vector(7 downto 0);			-- STATUS	signal fsr_reg			: std_logic_vector(7 downto 0);			-- FSR	signal portain_sync_reg	: std_logic_vector(4 downto 0);			-- PORTA IN (synchronizer)	signal portaout_reg		: std_logic_vector(4 downto 0);			-- PORTA OUT	signal portbin_sync_reg	: std_logic_vector(7 downto 0);			-- PORTB IN (synchronizer)	signal portbout_reg		: std_logic_vector(7 downto 0);			-- PORTB OUT	signal eedata_reg		: std_logic_vector(7 downto 0);			-- EEDATA	signal eeadr_reg		: std_logic_vector(7 downto 0);			-- EEADR	signal pclath_reg		: std_logic_vector(4 downto 0);			-- PCLATH	signal intcon_reg		: std_logic_vector(7 downto 0);			-- INTCON	signal option_reg		: std_logic_vector(7 downto 0);			-- OPTION	signal trisa_reg		: std_logic_vector(4 downto 0);			-- TRISA	signal trisb_reg		: std_logic_vector(7 downto 0);			-- TRISB	signal eecon1_reg		: std_logic_vector(4 downto 0);			-- EECON1	-- Internal registers for controlling instruction execution	signal inst_reg			: std_logic_vector(13 downto 0);		-- Hold fetched op-code/operand	signal aluinp1_reg		: std_logic_vector(7 downto 0);			-- data source (1 of 2)--> changed ver1.00c, 2002/08/07--	signal aluinp2_reg		: std_logic_vector(7 downto 0);			-- data source (2 of 2)	signal aluinp2_reg		: std_logic_vector(8 downto 0);			-- data source (2 of 2)--<	signal aluout_reg		: std_logic_vector(7 downto 0);			-- result of calculation	signal exec_op_reg		: std_logic;							-- if L (i.e. GOTO instruction etc), stall exec of instruction	signal intstart_reg 	: std_logic;							-- if H (i.e. interrupt), stall exec of instruction	signal sleepflag_reg	: std_logic;							-- if H, sleeping	-- Stack	type STACK_TYPE is array (STACK_SIZE - 1 downto 0) of std_logic_vector(12 downto 0);	signal stack_reg		: STACK_TYPE;							-- stack body (array of data-registers)	signal stack_pnt_reg	: integer range 0 to STACK_SIZE - 1;	-- stack pointer (binary encoded)	signal stack_pos_node	: std_logic_vector(STACK_SIZE - 1 downto 0);	-- same with stack pointer, but one-hot encoded	signal stacktop_node	: std_logic_vector(12 downto 0);		-- data value of stack-top	-- WDT register and its control	signal wdt_reg				: integer range 0 to WDT_SIZE;		-- WDT counter	signal wdt_full_reg			: std_logic;						-- WDT->CPU; hold WDT-full signal until CPU is reset	signal wdt_full_sync_reg	: std_logic_vector(2 downto 0);		-- CPU; synchronizer for wdt_full_reg	signal wdt_clr_reg			: std_logic;						-- CPU->WDT; request to zero-clear wdt_reg	signal wdt_clr_reqhold_reg	: std_logic;						-- CPU; hold a clear-request if previous request is still processing	signal wdtclr_req_reg		: std_logic_vector(1 downto 0);		-- WDT; synchronizer for wdt_clr_reg	signal wdtclr_ack			: std_logic;						-- WDT->CPU; ack to wdt_clr_reg (same with wdtclr_req_reg(1))	signal wdtclr_ack_sync_reg	: std_logic;						-- CPU; synchronizer for wdtclr_ack	signal wdtfull_clr_reg		: std_logic;						-- CPU->WDT; requst to clear wdt_full_reg	signal wdtfullclr_req_reg	: std_logic_vector(1 downto 0);		-- WDT; synchronizer for wdtfull_clr_reg	-- TMR0 prescaler	signal psck				: std_logic;							-- clock for prescaler	signal pscale_reg		: integer range 0 to 255;				-- prescaler	signal ps_full_reg		: std_logic;							-- clock for TMR0, from prescaler	signal inctmrck			: std_logic;							-- clock for TMR0	signal inctmrhold_reg	: std_logic;							-- hold TMR0 increment request	-- Interrupt registers/nodes	signal intrise_reg		: std_logic_vector(4 downto 0);			-- detect positive edge of PORT-B inputs	signal intdown_reg		: std_logic_vector(4 downto 0);			-- detect negative edge of PORT-B inputs	signal rb0_int, rb4_int, rb5_int, rb6_int, rb7_int	: std_logic;-- interrupt trigger	signal rbint			: std_logic;							-- RB4-7 interrupt trigger	signal inte				: std_logic;							-- RB0   interrupt trigger	signal intclr_reg		: std_logic_vector(4 downto 0);			-- CPU; clear intrise_reg and intdown_reg	-- State register	constant STATEBIT_SIZE	: integer := 3;	signal state_reg		: std_logic_vector(STATEBIT_SIZE - 1 downto 0);	constant Qreset			: std_logic_vector(STATEBIT_SIZE - 1 downto 0) := "100";		-- reset state	constant Q1				: std_logic_vector(STATEBIT_SIZE - 1 downto 0) := "000";		-- state Q1	constant Q2				: std_logic_vector(STATEBIT_SIZE - 1 downto 0) := "001";		-- state Q2	constant Q3				: std_logic_vector(STATEBIT_SIZE - 1 downto 0) := "011";		-- state Q3	constant Q4				: std_logic_vector(STATEBIT_SIZE - 1 downto 0) := "010";		-- state Q4	-- Result of decoding instruction	signal INST_ADDLW, INST_ADDWF, INST_ANDLW, INST_ANDWF, INST_BCF, INST_BSF, INST_BTFSC, INST_BTFSS	: std_logic;	signal INST_CALL, INST_CLRF, INST_CLRW, INST_CLRWDT, INST_COMF, INST_DECF, INST_DECFSZ				: std_logic;	signal INST_GOTO, INST_INCF, INST_INCFSZ, INST_IORLW, INST_IORWF, INST_MOVLW, INST_MOVF, INST_MOVWF	: std_logic;	signal INST_RETFIE, INST_RETLW, INST_RET, INST_RLF, INST_RRF										: std_logic;	signal INST_SLEEP, INST_SUBLW, INST_SUBWF, INST_SWAPF, INST_XORLW, INST_XORWF						: std_logic;	-- Result of calculating RAM access address	signal ramadr_node		: std_logic_vector(8 downto 0);			-- RAM access address	signal ADDR_TMR0, ADDR_PCL, ADDR_STAT, ADDR_FSR, ADDR_PORTA, ADDR_PORTB								: std_logic;	signal ADDR_EEDATA, ADDR_EEADR, ADDR_PCLATH, ADDR_INTCON, ADDR_OPTION, ADDR_TRISA, ADDR_TRISB		: std_logic;--	signal ADDR_EECON1, ADDR_EECON2, ADDR_SRAM															: std_logic;	signal ADDR_EECON1, ADDR_SRAM																		: std_logic;	-- Other output registers (for removing hazards)	signal writeram_reg		: std_logic;							-- data-sram write strobe--> deleted ver1.00c, 2002/08/07--	signal ramadr_reg		: std_logic_vector(8 downto 0);			-- data-sram address--<	signal clkout_reg		: std_logic;							-- clkout output	-- Synchronizers	signal inte_sync_reg	: std_logic;	signal rbint_sync_reg	: std_logic;	signal inctmr_sync_reg	: std_logic_vector(1 downto 0);	signal rdeep_sync_reg	: std_logic;	signal wreep_sync_reg	: std_logic;	signal mclr_sync_reg	: std_logic;	signal poweron_sync_reg	: std_logic;begin-- CPU synchronizers	u0:process (clkin)	begin		if (clkin'event and clkin = '1') then			inte_sync_reg			<= inte;			rbint_sync_reg			<= rbint;			wdtclr_ack_sync_reg		<= wdtclr_ack;			mclr_sync_reg			<= mclr_n;			poweron_sync_reg		<= ponrst_n;			rdeep_sync_reg			<= readeepack;			wreep_sync_reg			<= writeeepack;			inctmr_sync_reg(0)		<= inctmrck;			inctmr_sync_reg(1)		<= inctmr_sync_reg(0);			if (poweron_sync_reg = '0' or mclr_sync_reg = '0') then				wdt_full_sync_reg		<= "000";			else				wdt_full_sync_reg(0)	<= wdt_full_reg;				wdt_full_sync_reg(1)	<= wdt_full_sync_reg(0);	-- (remove meta-stable)				wdt_full_sync_reg(2)	<= wdt_full_sync_reg(1);	-- (detect positive edge)			end if;		end if;	end process;-- Decode OPcode	(see pp.54 of PIC16F84 data sheet)	-- only 1 signal of the following signals will be '1'	INST_CALL		<= '1' when inst_reg(13 downto 11) = "100"				else '0';	INST_GOTO		<= '1' when inst_reg(13 downto 11) = "101"				else '0';	INST_BCF		<= '1' when inst_reg(13 downto 10) = "0100"				else '0';	INST_BSF		<= '1' when inst_reg(13 downto 10) = "0101"				else '0';	INST_BTFSC		<= '1' when inst_reg(13 downto 10) = "0110"				else '0';	INST_BTFSS		<= '1' when inst_reg(13 downto 10) = "0111"				else '0';	INST_MOVLW		<= '1' when inst_reg(13 downto 10) = "1100"				else '0';	INST_RETLW		<= '1' when inst_reg(13 downto 10) = "1101"				else '0';	INST_SUBLW		<= '1' when inst_reg(13 downto 9)  = "11110"			else '0';	INST_ADDLW		<= '1' when	inst_reg(13 downto 9)  = "11111"			else '0';	INST_IORLW		<= '1' when inst_reg(13 downto 8)  = "111000"			else '0';	INST_ANDLW		<= '1' when inst_reg(13 downto 8)  = "111001"			else '0';	INST_XORLW		<= '1' when inst_reg(13 downto 8)  = "111010"			else '0';	INST_SUBWF		<= '1' when inst_reg(13 downto 8)  = "000010"			else '0';	INST_DECF		<= '1' when inst_reg(13 downto 8)  = "000011"			else '0';	INST_IORWF		<= '1' when inst_reg(13 downto 8)  = "000100"			else '0';	INST_ANDWF		<= '1' when inst_reg(13 downto 8)  = "000101"			else '0';	INST_XORWF		<= '1' when inst_reg(13 downto 8)  = "000110"			else '0';	INST_ADDWF		<= '1' when inst_reg(13 downto 8)  = "000111"			else '0';	INST_MOVF		<= '1' when inst_reg(13 downto 8)  = "001000"			else '0';	INST_COMF		<= '1' when inst_reg(13 downto 8)  = "001001"			else '0';	INST_INCF		<= '1' when inst_reg(13 downto 8)  = "001010"			else '0';	INST_DECFSZ		<= '1' when inst_reg(13 downto 8)  = "001011"			else '0';	INST_RRF		<= '1' when inst_reg(13 downto 8)  = "001100"			else '0';	INST_RLF		<= '1' when inst_reg(13 downto 8)  = "001101"			else '0';	INST_SWAPF		<= '1' when inst_reg(13 downto 8)  = "001110"			else '0';	INST_INCFSZ		<= '1' when inst_reg(13 downto 8)  = "001111"			else '0';	INST_MOVWF		<= '1' when inst_reg(13 downto 7)  = "0000001"			else '0';	INST_CLRW		<= '1' when inst_reg(13 downto 7)  = "0000010"			else '0';	INST_CLRF		<= '1' when inst_reg(13 downto 7)  = "0000011"			else '0';	INST_RET		<= '1' when inst_reg(13 downto 0)  = "00000000001000"	else '0';	INST_RETFIE		<= '1' when inst_reg(13 downto 0)  = "00000000001001"	else '0';	INST_SLEEP		<= '1' when inst_reg(13 downto 0)  = "00000001100011"	else '0';	INST_CLRWDT		<= '1' when inst_reg(13 downto 0)  = "00000001100100"	else '0';-- Calculate RAM access address	(see pp.19 of PIC16F84 data sheet)	-- if "d"=0, indirect addressing is used, so RAM address is BANK+FSR	-- otherwise, RAM address is BANK+"d"	-- (see pp.19 of PIC16F84 data sheet)	ramadr_node <=	status_reg(7) & fsr_reg(7 downto 0)		when inst_reg(6 downto 0) = "0000000"	else					status_reg(6 downto 5) & inst_reg(6 downto 0);	-- check if this is an access to external RAM or not	ADDR_SRAM		<= '1' when ramadr_node(6 downto 0) > "0001011"	else '0';	-- 0CH-7FH, 8CH-FFH	-- check if this is an access to special register or not	-- only 1 signal of the following signals will be '1'	ADDR_TMR0		<= '1' when ramadr_node(7 downto 0) = "00000001"		else '0';	-- 01H	ADDR_PCL		<= '1' when ramadr_node(6 downto 0) =  "0000010"		else '0';	-- 02H, 82H	ADDR_STAT		<= '1' when ramadr_node(6 downto 0) =  "0000011"		else '0';	-- 03H, 83H	ADDR_FSR		<= '1' when ramadr_node(6 downto 0) =  "0000100"		else '0';	-- 04H, 84H	ADDR_PORTA		<= '1' when ramadr_node(7 downto 0) = "00000101"		else '0';	-- 05H	ADDR_PORTB		<= '1' when ramadr_node(7 downto 0) = "00000110"		else '0';	-- 06H	ADDR_EEDATA		<= '1' when ramadr_node(7 downto 0) = "00001000"		else '0';	-- 08H	ADDR_EEADR		<= '1' when ramadr_node(7 downto 0) = "00001001"		else '0';	-- 09H	ADDR_PCLATH		<= '1' when ramadr_node(6 downto 0) =  "0001010"		else '0';	-- 0AH, 8AH	ADDR_INTCON		<= '1' when ramadr_node(6 downto 0) =  "0001011"		else '0';	-- 0BH, 8BH	ADDR_OPTION		<= '1' when ramadr_node(7 downto 0) = "10000001"		else '0';	-- 81H	ADDR_TRISA		<= '1' when ramadr_node(7 downto 0) = "10000101"		else '0';	-- 85H	ADDR_TRISB		<= '1' when ramadr_node(7 downto 0) = "10000110"		else '0';	-- 86H	ADDR_EECON1		<= '1' when ramadr_node(7 downto 0) = "10001000"		else '0';	-- 88H--	ADDR_EECON2		<= '1' when ramadr_node(7 downto 0) = "10001001"		else '0';	-- 89H-- Read value of PC-STACK top	-- convert binary value of stack pointer into onehot value (for reducing circuit)	ND1: for I in 0 to STACK_SIZE - 1 generate		stack_pos_node(I)	<= '1' when stack_pnt_reg = I	else '0';	end generate ND1;	-- pick up value of stack-top from stack cells	u1:process (stack_reg, stack_pos_node)		variable stack_cell		: STACK_TYPE;						-- value of each stack cell		variable top			: std_logic_vector(12 downto 0);	-- value of stack top	begin		for I in 0 to STACK_SIZE - 1 loop			if (stack_pos_node(I) = '1') then		-- (if the position is stack top)				stack_cell(I) := stack_reg(I);			else				stack_cell(I) := "0000000000000";			end if;		end loop;

⌨️ 快捷键说明

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