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

📄 piccore.vhd

📁 PIC源代码很不错
💻 VHD
📖 第 1 页 / 共 4 页
字号:
						aluinp2_reg		<= "0" & w_reg;					-- W register--<					end if;				-- 2-3-1-3. Set stack pointer register (pop stack)					if (INST_RET = '1' or INST_RETLW = '1' or INST_RETFIE = '1') then						if (stack_pnt_reg = 0) then							stack_pnt_reg	<= STACK_SIZE - 1;			-- if pointer=0, then next value should be STACK_SIZE-1						else							stack_pnt_reg	<= stack_pnt_reg - 1;		-- otherwise, current value - 1						end if;					end if;				-- 2-3-1-4. Set ramadr register (set RAM write address)--> deleted ver1.00c, 2002/08/07--					ramadr_reg	<= ramadr_node;		-- RAM write address--<				end if;			-- 2-3-2. Change clkout output				clkout_reg	<= '1';			-- 2-3-3. Check increment-TMR0 request				if (inctmr_sync_reg = "01") then					inctmrhold_reg	<= '1';				end if;			-- 2-3-4. Goto next cycle				if (reset_cond = '1') then					state_reg 	<= Qreset;				else					state_reg 	<= Q3;				end if;		-- 2-4. Q3 cycle			when Q3 =>			-- 2-4-1. Calculation and store result into alu-output regsiter				if (exec_op_reg = '1' and intstart_reg = '0') then	-- if NOT STALLED				-- 2-4-1-1. Set aluout register					if (INST_RLF = '1') then						aluout_reg	<= aluinp1_reg(6 downto 0) & status_reg(0);				-- rotate left					elsif (INST_RRF = '1') then						aluout_reg	<= status_reg(0) & aluinp1_reg(7 downto 1);				-- rotate right					elsif (INST_SWAPF = '1') then						aluout_reg	<= aluinp1_reg(3 downto 0) & aluinp1_reg(7 downto 4);	-- swap H-nibble and L-nibble					elsif (INST_COMF = '1') then						aluout_reg	<= not aluinp1_reg;										-- logical inversion					elsif (INST_ANDLW = '1' or INST_ANDWF = '1' or INST_BCF = '1' or INST_BTFSC = '1' or INST_BTFSS = '1') then--> modified ver1.00c, 2002/08/07--						aluout_reg	<= aluinp1_reg and aluinp2_reg;							-- logical AND/bit clear/bit test						aluout_reg	<= aluinp1_reg and aluinp2_reg(7 downto 0);				-- logical AND/bit clear/bit test					elsif (INST_BSF = '1' or INST_IORLW = '1' or INST_IORWF = '1') then--						aluout_reg	<= aluinp1_reg or aluinp2_reg;							-- logical OR/bit set						aluout_reg	<= aluinp1_reg or aluinp2_reg(7 downto 0);				-- logical OR/bit set					elsif (INST_XORLW = '1' or INST_XORWF = '1') then--						aluout_reg	<= aluinp1_reg xor aluinp2_reg;							-- logical XOR						aluout_reg	<= aluinp1_reg xor aluinp2_reg(7 downto 0);				-- logical XOR--<					elsif (INST_ADDLW = '1' or INST_ADDWF = '1' or INST_SUBLW = '1' or INST_SUBWF = '1'							or INST_DECF = '1' or INST_DECFSZ = '1' or INST_INCF = '1' or INST_INCFSZ = '1') then						aluout_reg	<= add_node(7 downto 0);								-- addition/subtraction/increment/decrement					else						aluout_reg	<= aluinp1_reg;											-- pass through					end if;				-- 2-4-1-2. Set C flag and DC flag--> modified ver1.00c, 2002/08/07--					if (INST_ADDLW = '1' or INST_ADDWF = '1' or INST_SUBLW = '1' or INST_SUBWF = '1') then--						status_reg(1)	<= addLow_node(4);			-- DC flag--						status_reg(0)	<= add_node(8);				-- C flag					if (INST_ADDLW = '1' or INST_ADDWF = '1') then						status_reg(1)	<= addLow_node(4);			-- DC flag						status_reg(0)	<= add_node(8);				-- C flag					elsif (INST_SUBLW = '1' or INST_SUBWF = '1') then						status_reg(1)	<= not addLow_node(4);		-- DC flag						status_reg(0)	<= not add_node(8);			-- C flag--<					elsif (INST_RLF = '1') then						status_reg(0)	<= aluinp1_reg(7);			-- C flag					elsif (INST_RRF = '1') then						status_reg(0)	<= aluinp1_reg(0);			-- C flag					end if;				-- 2-4-1-3. Set data-SRAM write enable (hazard-free)					if (writeram_node = '1' and ADDR_SRAM = '1') then						writeram_reg	<= '1';					else						writeram_reg	<= '0';					end if;				else	-- (if stalled)					writeram_reg		<= '0';				end if;			-- 2-4-2. Check external interrupt and set interrupt flag / Increment TMR0				if (intstart_reg = '0') then					if (intcon_reg(7) = '1') then				-- GIE						-- PORT-B0 INT						if (inte_sync_reg = '1') then							intcon_reg(1)			<= '1';		-- set INTF							intclr_reg(0)			<= '1';		-- clear external int-registers (intrise_reg(0) and intdown_reg(0))						end if;						-- PORT-B[4-7] INT						if (rbint_sync_reg = '1') then							intcon_reg(0)			<= '1';		-- set RBIF							intclr_reg(4 downto 1)	<= "1111";	-- clear external int-registers (intrise_reg(4-1) and intdown_reg(4-1))						end if;					end if;				end if;				-- Increment TMR0				if (inctmrhold_reg = '1' or inctmr_sync_reg = "01") then		-- increment trigger comes					tmr0_reg		<= tmr0_reg + "00000001";	-- increment					inctmrhold_reg	<= '0';					-- if intstart = '0' and GIE = '1' and T0IE = '1' and timer full, then set T0IF					if (intstart_reg = '0' and intcon_reg(7) = '1' and intcon_reg(5) = '1' and tmr0_reg = "11111111") then						intcon_reg(2)	<= '1';				-- set T0IF					end if;				end if;			-- 2-4-3. Goto next cycle				if (reset_cond = '1') then					state_reg 	<= Qreset;				else					state_reg 	<= Q4;				end if;		-- 2-5. Q4 cycle			when Q4 =>			-- 2-5-1. Fetch next program-instruction				inst_reg	<= progdata;				if (exec_op_reg = '0' and intstart_reg = '0') then		-- if STALLED					pc_reg			<= incpc_node;		-- increment PC					exec_op_reg		<= '1';				-- end of stall				else	-- if NOT stalled (note: if intstart_reg = '1', only stack/pc-operations in this else-clause will be performed)			-- 2-5-2. Store calculation result into distination, set PC and flags, and determine if execute next cycle or not				-- 2-5-2-1. Set W register, if not in stall cycle (intstart_reg = '0') and distination is W					if (writew_node = '1') then		-- ('0' if intstart_reg = '1')						w_reg	<= aluout_reg;									-- write W reg					end if;				-- 2-5-2-2. Set data RAM/special registers, if not in stall cycle (intstart_reg = '0')					if (writeram_node = '1') then	-- ('0' if intstart_reg = '1')						if (ADDR_STAT = '1') then							status_reg(7 downto 5)	<= aluout_reg(7 downto 5);		-- write IRP,RP1,RP0							-- status(4),status(3)...unwritable, see below (/PD,/T0 part)							status_reg(1 downto 0)	<= aluout_reg(1 downto 0);		-- write DC,C						end if;						if (ADDR_FSR = '1') then							fsr_reg			<= aluout_reg;							-- write FSR						end if;						if (ADDR_PORTA = '1') then							portaout_reg	<= aluout_reg(4 downto 0);				-- write PORT-A						end if;						if (ADDR_PORTB = '1') then							portbout_reg	<= aluout_reg;							-- write PORT-B						end if;						if (ADDR_EEDATA = '1') then							eedata_reg		<= aluout_reg;							-- write EEDATA						end if;						if (ADDR_EEADR = '1') then							eeadr_reg		<= aluout_reg;							-- write EEADR						end if;						if (ADDR_PCLATH = '1') then							pclath_reg		<= aluout_reg(4 downto 0);				-- write PCLATH						end if;						if (ADDR_INTCON = '1') then							intcon_reg(6 downto 0)	<= aluout_reg(6 downto 0);		-- write INTCON (except GIE)							-- intcon(7)...see below (GIE part)						end if;						if (ADDR_OPTION = '1') then							option_reg		<= aluout_reg;							-- write OPTION						end if;						if (ADDR_TRISA = '1') then							trisa_reg		<= aluout_reg(4 downto 0);				-- write TRISA						end if;						if (ADDR_TRISB = '1') then							trisb_reg		<= aluout_reg;							-- write TRISB						end if;						if (ADDR_TMR0 = '1') then							tmr0_reg		<= aluout_reg;							-- write TMR0						end if;						if (ADDR_EECON1 = '1') then									-- write EECON1							eecon1_reg(4 downto 3)	<= aluout_reg(4 downto 3);							eecon1_reg(2)			<= aluout_reg(2) and existeeprom;	-- WREN can be set only when EEPROM exists							if (aluout_reg(2 downto 0) = "110") then	-- if write enabled, write bit = '1', and no current read								eecon1_reg(1)	<= '1';								-- WR: only SET-operation is allowed to user							end if;							if (aluout_reg(1 downto 0) = "01") then		-- if no current write, and read bit = '1'								eecon1_reg(0)	<= '1';								-- RD: only SET-operation is allowed to user							end if;						end if;					end if;				-- 2-5-2-3. Set/clear Z flag, if not in stall cycle (intstart_reg = '0')					if (intstart_reg = '0') then-----> changed v1.00d, 2004/08/26						-- if (ADDR_STAT = '1') then						if (writeram_node = '1' and ADDR_STAT = '1' and INST_CLRF = '0') then-----< changed v1.00d, 2004/08/26							 status_reg(2)	<= aluout_reg(2);					-- (distination is Z flag)						elsif (INST_ADDLW = '1' or INST_ADDWF = '1' or INST_ANDLW = '1' or INST_ANDWF = '1'								or INST_CLRF = '1' or INST_CLRW = '1' or INST_COMF = '1' or INST_DECF = '1'								or INST_INCF = '1' or INST_MOVF = '1' or INST_SUBLW = '1' or INST_SUBWF = '1'								or INST_XORLW = '1' or INST_XORWF = '1') then							status_reg(2)	<= aluout_zero_node;				-- Z=1 if result == 0						elsif (INST_IORLW = '1' or INST_IORWF = '1') then-- SELECT ONE OF THE FOLLOWING TWO SENTENCES																				-- IORLW or IORWF instructions:							status_reg(2)	<= not aluout_zero_node;			-- Z=1 if result != 0 (same behavior with PIC16F84 data sheet pp.61-62)--							status_reg(2)	<= aluout_zero_node;				-- Z=1 if resutl == 0 (same behavior with the other instructions)						end if;					end if;				-- 2-5-2-4. Set PC register and determine if execute next cycle or not					if (intstart_reg = '1') then								-- After interrupt-stall cycle ends, jump to interrupt vector						pc_reg			<= "0000000000100";						-- (interrupt vector)						exec_op_reg 	<= '0';									-- the next cycle is stall cycle					elsif (INST_RET = '1' or INST_RETLW = '1' or INST_RETFIE = '1') then	-- "return" instructions						pc_reg			<= stacktop_node;						-- pc <= top of poped stack (the stack is poped at Q2 cycle)						exec_op_reg 	<= '0';									-- the next cycle is stall cycle					elsif (INST_GOTO = '1' or INST_CALL = '1') then				-- "goto/call" instructions						pc_reg			<= pclath_reg(4 downto 3) & inst_reg(10 downto 0);	-- (see pp.18 of PIC16F84 data sheet)						exec_op_reg 	<= '0';					elsif ( ((INST_BTFSC = '1' or INST_DECFSZ = '1' or INST_INCFSZ = '1') and aluout_zero_node = '1')							or (INST_BTFSS = '1' and aluout_zero_node = '0') ) then	-- bit_test instrcutions						pc_reg			<= incpc_node;						exec_op_reg 	<= '0';									-- the next cycle is stall cycle, if test conditions are met.					elsif (writeram_node = '1' and ADDR_PCL = '1') then			-- PCL is data-distination						pc_reg			<= pclath_reg(4 downto 0) & aluout_reg;	-- (see pp.18 of PIC16F84 data sheet)						exec_op_reg 	<= '0';					else						-- this check MUST be located AFTER the above if/elsif sentences						if (int_node = '0') then								-- check if interrupt trigger comes							pc_reg		<= incpc_node;							-- if not, the next instruction fetch/execution will be performed normally						else							pc_reg		<= pc_reg;								-- if so, value of PC must be hold (will be pushed into stack at the end of next instruction cycle)						end if;						exec_op_reg 	<= '1';					end if;				-- 2-5-2-5. Push current PC value into stack, if necessary					if (INST_CALL = '1' or intstart_reg = '1') then				-- CALL instruction or End of interrupt-stall cycle						-- write PC-value into stack top						for I in 0 to STACK_SIZE - 1 loop							if (stack_pos_node(I) = '1') then		-- check if the stack cell is stack top or not								stack_reg(I)	<= pc_reg;			-- if so, write PC value							end if;						end loop;						-- increment stack pointer-- >> Changed on Dec 10,2000						stack_full_node	:= STACK_SIZE - 1;--						if (stack_pnt_reg = STACK_SIZE - 1) then						if (stack_pnt_reg = stack_full_node) then-- << Changed on Dec 10,2000							stack_pnt_reg	<= 0;						else							stack_pnt_reg	<= stack_pnt_reg + 1;						end if;					end if;				-- 2-5-2-6. Set GIE bit in intcon register (intcon_reg(7))					if (intstart_reg = '0') then						if (int_node = '1') then					-- interrupt trigger comes							intcon_reg(7)	<= '0';					-- clear GIE							intstart_reg	<= '1';					-- the next cycle is interrupt-stall cycle						elsif (INST_RETFIE = '1') then				-- "return from interrupt" instruction							intcon_reg(7)	<= '1';							intstart_reg	<= '0';						elsif (writeram_node = '1' and ADDR_INTCON = '1') then	-- distination is GIE							intcon_reg(7)	<= aluout_reg(7);							intstart_reg	<= '0';						else							intstart_reg	<= '0';						end if;					else						intstart_reg	<= '0';					end if;				-- 2-5-2-7. Set/clear /PD and /TO flags					if (intstart_reg = '0') then						if (INST_CLRWDT	= '1'								or (INST_SLEEP = '1' and (wdtreset_node = '0' and intstart_reg = '0')) ) then	-- CLRWDT or (SLEEP and no interrupt trigger)							-- see pp.46,58 and 66 of PIC16F84 data-sheet							if (INST_SLEEP = '1') then								sleepflag_reg			<= '1';								status_reg(4 downto 3)	<= "10";	-- SLEEP: /T0,/PD = 1,0							else		-- (INST_CLRWDT)								status_reg(4 downto 3)	<= "11";	-- CLRWDT: /T0,/PD = 1,1							end if;						end if;					end if;				end if;		-- (if not stalled)			-- 2-5-3. Clear data-SRAM write enable (hazard-free)

⌨️ 快捷键说明

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