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

📄 piccore.v

📁 PIC源代码很不错
💻 V
📖 第 1 页 / 共 4 页
字号:
				end else if (INST_MOVLW == 1'b1 || INST_ADDLW == 1'b1 || INST_SUBLW == 1'b1 						|| INST_ANDLW == 1'b1 || INST_IORLW == 1'b1 || INST_XORLW == 1'b1 						|| INST_RETLW == 1'b1) begin					aluinp1_reg	<= inst_reg[7:0];	// Immidiate value ("k")				end else if (INST_CLRF == 1'b1 || INST_CLRW == 1'b1) begin					aluinp1_reg	<= {8{1'b0}};		// 0				end else begin					aluinp1_reg	<= w_reg;			// W register				end				// 2-3-1-2. Set aluinp2 register (source #2)				case (inst_reg[9:7])	// construct bit-mask for logical operations/bit test				3'b000: begin					mask_node	= 8'b00000001;				end				3'b001: begin					mask_node	= 8'b00000010;				end				3'b010: begin					mask_node	= 8'b00000100;				end				3'b011: begin					mask_node	= 8'b00001000;				end				3'b100: begin					mask_node	= 8'b00010000;				end				3'b101: begin					mask_node	= 8'b00100000;				end				3'b110: begin					mask_node	= 8'b01000000;				end				default: begin					mask_node	= 8'b10000000;				end				endcase				if (INST_DECF == 1'b1 || INST_DECFSZ == 1'b1) begin					aluinp2_reg	<= {(8 - 0 + 1){1'b1}};	// -1 (for decrement)				end else if (INST_INCF == 1'b1 || INST_INCFSZ == 1'b1) begin//> modified ver1.00c, 2002/08/07//					aluinp2_reg	<= 8'b00000001;		// 1 (for increment)					aluinp2_reg	<= 9'b000000001;	// 1 (for increment)				end else if (INST_SUBLW == 1'b1 || INST_SUBWF == 1'b1) begin//					aluinp2_reg	<= (~w_reg) + 8'b00000001;	// -1 * W register (for subtract)					aluinp2_reg	<= ({1'b1, ( ~w_reg)}) + 9'b000000001;	// -1 * W register (for subtract)				end else if (INST_BCF == 1'b1) begin//					aluinp2_reg	<= ~mask_node;				// mask for BCF: value of only one position is '0'					aluinp2_reg	<= {1'b0, ( ~mask_node)};	// mask for BCF: value of only one position is '0'				end else if (INST_BTFSC == 1'b1 || INST_BTFSS == 1'b1 || INST_BSF == 1'b1) begin	// operation of BCF: AND with inverted mask ("1..101..1")//					aluinp2_reg	<= mask_node;			// operation of BSF: OR with mask_node ("0..010..0")					aluinp2_reg	<= {1'b0, mask_node};	// operation of BSF: OR with mask_node ("0..010..0")				end else begin	// operation of FSC and FSS: AND with mask_node and then compare with zero//					aluinp2_reg	<= w_reg;			// W register					aluinp2_reg	<= {1'b0, w_reg};	// W register				end//<				// 2-3-1-3. Set stack pointer register (pop stack)				if (INST_RET == 1'b1 || INST_RETLW == 1'b1 || INST_RETFIE == 1'b1) begin					if (stack_pnt_reg == 0) begin						stack_pnt_reg	<= 8 - 1;	// if pointer=0, then next value should be 8-1					end else begin						stack_pnt_reg	<= stack_pnt_reg - 1;	// otherwise, current value - 1					end				end			end			// 2-3-1-4. Set ramadr register (set RAM write address)//> deleted ver1.00c, 2002/08/07//			ramadr_reg	<= ramadr_node;		// RAM write address//<			// 2-3-2. Change clkout output			clkout_reg	<= 1'b1;			// 2-3-3. Check increment-TMR0 request			if (inctmr_sync_reg == 2'b01) begin				inctmrhold_reg	<= 1'b1;			end			// 2-3-4. Goto next cycle			if (reset_cond == 1'b1) begin				state_reg	<= Qreset;			end else begin				state_reg	<= Q3;			end		end		// 2-4. Q3 cycle		Q3: begin			// 2-4-1. Calculation and store result into alu-output regsiter			if (exec_op_reg == 1'b1 && intstart_reg == 1'b0) begin	// if NOT STALLED				// 2-4-1-1. Set aluout register				if (INST_RLF == 1'b1) begin					aluout_reg	<= {aluinp1_reg[6:0], status_reg[0]};	// rotate left				end else if (INST_RRF == 1'b1) begin					aluout_reg	<= {status_reg[0], aluinp1_reg[7:1]};	// rotate right				end else if (INST_SWAPF == 1'b1) begin					aluout_reg	<= {aluinp1_reg[3:0], aluinp1_reg[7:4]};	// swap H-nibble and L-nibble				end else if (INST_COMF == 1'b1) begin					aluout_reg	<=  ~aluinp1_reg;	// logical inversion				end else if (INST_ANDLW == 1'b1 || INST_ANDWF == 1'b1 || INST_BCF == 1'b1 || INST_BTFSC == 1'b1 || INST_BTFSS == 1'b1) begin//> modified ver1.00c, 2002/08/07//					aluout_reg	<= aluinp1_reg & aluinp2_reg;		// logical AND/bit clear/bit test					aluout_reg	<= aluinp1_reg & aluinp2_reg[7:0];	// logical AND/bit clear/bit test				end else if (INST_BSF == 1'b1 || INST_IORLW == 1'b1 || INST_IORWF == 1'b1) begin//					aluout_reg	<= aluinp1_reg | aluinp2_reg;		// logical OR/bit set					aluout_reg	<= aluinp1_reg | aluinp2_reg[7:0];	// logical OR/bit set				end else if (INST_XORLW == 1'b1 || INST_XORWF == 1'b1) begin//					aluout_reg	<= aluinp1_reg ^ aluinp2_reg;		// logical XOR					aluout_reg	<= aluinp1_reg ^ aluinp2_reg[7:0];	// logical XOR//<				end else if (INST_ADDLW == 1'b1 || INST_ADDWF == 1'b1 || INST_SUBLW == 1'b1 || INST_SUBWF == 1'b1 || INST_DECF == 1'b1 || INST_DECFSZ == 1'b1 || INST_INCF == 1'b1 || INST_INCFSZ == 1'b1) begin	//<					aluout_reg	<= add_node[7:0];	// addition/subtraction/increment/decrement				end else begin					aluout_reg	<= aluinp1_reg;	// pass through				end				// 2-4-1-2. Set C flag and DC flag//> modified ver1.00c, 2002/08/07//				if (INST_ADDLW == 1'b1 || INST_ADDWF == 1'b1 || INST_SUBLW == 1'b1 || INST_SUBWF == 1'b1) begin//					status_reg(1)	<= addLow_node(4);	// DC flag//					status_reg(0)	<= add_node(8);		// C flag				if (INST_ADDLW == 1'b1 || INST_ADDWF == 1'b1) begin					status_reg[1]	<= addLow_node[4];	// DC flag					status_reg[0]	<= add_node[8];		// C flag				end else if (INST_SUBLW == 1'b1 || INST_SUBWF == 1'b1) begin					status_reg[1]	<=  ~addLow_node[4];	// DC flag					status_reg[0]	<=  ~add_node[8];		// C flag//<				end else if (INST_RLF == 1'b1) begin						status_reg[0]	<= aluinp1_reg[7];	// C flag				end else if (INST_RRF == 1'b1) begin					status_reg[0]	<= aluinp1_reg[0];	// C flag				end				// 2-4-1-3. Set data-SRAM write enable (hazard-free)				if (writeram_node == 1'b1 && ADDR_SRAM == 1'b1) begin					writeram_reg	<= 1'b1;				end else begin					writeram_reg	<= 1'b0;				end			end else begin	// (if stalled)				writeram_reg	<= 1'b0;			end			// 2-4-2. Check external interrupt and set interrupt flag / Increment TMR0			if (intstart_reg == 1'b0) begin				if (intcon_reg[7] == 1'b1) begin	// GIE					// PORT-B0 INT					if (inte_sync_reg == 1'b1) begin						intcon_reg[1]	<= 1'b1;	// set INTF						intclr_reg[0]	<= 1'b1;	// clear external int-registers (intrise_reg(0) and intdown_reg(0))					end					// PORT-B[4-7] INT					if (rbint_sync_reg == 1'b1) begin						intcon_reg[0]	<= 1'b1;	// set RBIF						intclr_reg[4:1]	<= 4'b1111;	// clear external int-registers (intrise_reg(4-1) and intdown_reg(4-1))					end				end			end			// Increment TMR0			if (inctmrhold_reg == 1'b1 || inctmr_sync_reg == 2'b01) begin	// increment trigger comes				tmr0_reg		<= tmr0_reg + 8'b00000001;	// increment				inctmrhold_reg	<= 1'b0;				// if intstart = '0' and GIE = '1' and T0IE = '1' and timer full, then set T0IF				if (intstart_reg == 1'b0 && intcon_reg[7] == 1'b1 && intcon_reg[5] == 1'b1 && tmr0_reg == 8'b11111111) begin					intcon_reg[2]	<= 1'b1;	// set T0IF				end			end			// 2-4-3. Goto next cycle			if (reset_cond == 1'b1) begin				state_reg	<= Qreset;			end else begin				state_reg	<= Q4;			end		end		// 2-5. Q4 cycle		Q4: begin			// 2-5-1. Fetch next program-instruction			inst_reg	<= progdata;			if (exec_op_reg == 1'b0 && intstart_reg == 1'b0) begin	// if STALLED				pc_reg	<= incpc_node;	// increment PC				exec_op_reg	<= 1'b1;	// end of stall			end else begin	// 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'b1) begin	// ('0' if intstart_reg = '1')					w_reg	<= aluout_reg;	// write W reg				end				// 2-5-2-2. Set data RAM/special registers, if not in stall cycle (intstart_reg = '0')				if (writeram_node == 1'b1) begin	// ('0' if intstart_reg = '1')					if (ADDR_STAT == 1'b1) begin						status_reg[7:5]	<= aluout_reg[7:5];	// write IRP,RP1,RP0						// status(4),status(3)...unwritable, see below (/PD,/T0 part)						status_reg[1:0]	<= aluout_reg[1:0];	// write DC,C					end					if (ADDR_FSR == 1'b1) begin						fsr_reg	<= aluout_reg;			// write FSR					end					if (ADDR_PORTA == 1'b1) begin						portaout_reg	<= aluout_reg[4:0];	// write PORT-A					end					if (ADDR_PORTB == 1'b1) begin						portbout_reg	<= aluout_reg;	// write PORT-B					end					if (ADDR_EEDATA == 1'b1) begin						eedata_reg	<= aluout_reg;		// write EEDATA					end					if (ADDR_EEADR == 1'b1) begin						eeadr_reg	<= aluout_reg;		// write EEADR					end					if (ADDR_PCLATH == 1'b1) begin						pclath_reg	<= aluout_reg[4:0];	// write PCLATH					end					if (ADDR_INTCON == 1'b1) begin						intcon_reg[6:0]	<= aluout_reg[6:0];	// write INTCON (except GIE)					end					// intcon(7)...see below (GIE part)					if (ADDR_OPTION == 1'b1) begin						option_reg	<= aluout_reg;		// write OPTION					end					if (ADDR_TRISA == 1'b1) begin						trisa_reg	<= aluout_reg[4:0];	// write TRISA					end					if (ADDR_TRISB == 1'b1) begin						trisb_reg	<= aluout_reg;		// write TRISB					end					if (ADDR_TMR0 == 1'b1) begin						tmr0_reg	<= aluout_reg;		// write TMR0					end					if (ADDR_EECON1 == 1'b1) begin		// write EECON1						eecon1_reg[4:3]	<= aluout_reg[4:3];						eecon1_reg[2]	<= aluout_reg[2] & existeeprom;	// WREN can be set only when EEPROM exists						if (aluout_reg[2:0] == 3'b110) begin	// if write enabled, write bit = '1', and no current read							eecon1_reg[1]	<= 1'b1;	// WR: only SET-operation is allowed to user						end						if (aluout_reg[1:0] == 2'b01) begin	// if no current write, and read bit = '1'							eecon1_reg[0]	<= 1'b1;	// RD: only SET-operation is allowed to user						end					end				end				// 2-5-2-3. Set/clear Z flag, if not in stall cycle (intstart_reg = '0')				if (intstart_reg == 1'b0) begin//---> changed v1.00d, 2004/08/26					// if (ADDR_STAT == 1'b1) begin					if (writeram_node == 1'b1 && ADDR_STAT == 1'b1 && INST_CLRF == 1'b0) begin//---< changed v1.00d, 2004/08/26						status_reg[2]	<= aluout_reg[2];		// (distination is Z flag)					end else if (INST_ADDLW == 1'b1 || INST_ADDWF == 1'b1 || INST_ANDLW == 1'b1 || INST_ANDWF == 1'b1 || INST_CLRF == 1'b1 || INST_CLRW == 1'b1 || INST_COMF == 1'b1 || INST_DECF == 1'b1 || INST_INCF == 1'b1 || INST_MOVF == 1'b1 || INST_SUBLW == 1'b1 || INST_SUBWF == 1'b1 || INST_XORLW == 1'b1 || INST_XORWF == 1'b1) begin						status_reg[2]	<= aluout_zero_node;	// Z=1 if result == 0					end else if (INST_IORLW == 1'b1 || INST_IORWF == 1'b1) begin// SELECT ONE OF THE FOLLOWING TWO SENTENCES																// IORLW or IORWF instructions:						status_reg[2]	<=  ~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				end				// 2-5-2-4. Set PC register and determine if execute next cycle or not				if (intstart_reg == 1'b1) begin		// After interrupt-stall cycle ends, jump to interrupt vector					pc_reg	<= 13'b0000000000100;	// (interrupt vector)					exec_op_reg	<= 1'b0;			// the next cycle is stall cycle				end else if (INST_RET == 1'b1 || INST_RETLW == 1'b1 || INST_RETFIE == 1'b1) begin	// "return" instructions					pc_reg	<= stacktop_node;		// pc <= top of poped stack (the stack is poped at Q2 cycle)					exec_op_reg	<= 1'b0;			// the next cycle is stall cycle				end else if (INST_GOTO == 1'b1 || INST_CALL == 1'b1) begin	// "goto/call" instructions					pc_reg	<= {pclath_reg[4:3], inst_reg[10:0]};	// (see pp.18 of PIC16F84 data sheet)					exec_op_reg	<= 1'b0;				end else if (((INST_BTFSC == 1'b1 || INST_DECFSZ == 1'b1 || INST_INCFSZ == 1'b1) && aluout_zero_node == 1'b1) || (INST_BTFSS == 1'b1 && aluout_zero_node == 1'b0)) begin					// bit_test instrcutions					pc_reg	<= incpc_node;					exec_op_reg	<= 1'b0;	// the next cycle is stall cycle, if test conditions are met.				end else if (writeram_node == 1'b1 && ADDR_PCL == 1'b1) begin	// PCL is data-distination					pc_reg	<= {pclath_reg[4:0], aluout_reg};	// (see pp.18 of PIC16F84 data sheet)					exec_op_reg	<= 1'b0;				end else begin					// this check MUST be located AFTER the above if/elsif sentences					if (int_node == 1'b0) begin		// check if interrupt trigger comes						pc_reg	<= incpc_node;		// if not, the next instruction fetch/execution will be performed normally					end else begin						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					exec_op_reg	<= 1'b1;				end				// 2-5-2-5. Push current PC value into stack, if necessary				if (INST_CALL == 1'b1 || intstart_reg == 1'b1) begin	// CALL instruction or End of interrupt-stall cycle					// write PC-value into stack top					if (stack_pos_node[0] == 1'b1) begin	// check if the stack cell is stack top or not						stack_reg[0]	<= pc_reg;	// if so, write PC value					end					if (stack_pos_node[1] == 1'b1) begin						stack_reg[1]	<= pc_reg;					end					if (stack_pos_node[2] == 1'b1) begin						stack_reg[2]	<= pc_reg;					end					if (stack_pos_node[3] == 1'b1) begin						stack_reg[3]	<= pc_reg;					end					if (stack_pos_node[4] == 1'b1) begin						stack_reg[4]	<= pc_reg;					end					if (stack_pos_node[5] == 1'b1) begin						stack_reg[5]	<= pc_reg;					end					if (stack_pos_node[6] == 1'b1) begin						stack_reg[6]	<= pc_reg;					end					if (stack_pos_node[7] == 1'b1) begin						stack_reg[7]	<= pc_reg;					end					// increment stack pointer// >> Changed on Dec 10,2000					stack_full_node	= 8 - 1;//					if (stack_pnt_reg == 8 - 1) then					if (stack_pnt_reg == stack_full_node) begin// << Changed on Dec 10,2000						stack_pnt_reg	<= 0;					end else begin						stack_pnt_reg	<= stack_pnt_reg + 1;					end				end				// 2-5-2-6. Set GIE bit in intcon register (intcon_reg(7))				if (intstart_reg == 1'b0) begin					if (int_node == 1'b1) begin		// interrupt trigger comes						intcon_reg[7]	<= 1'b0;	// clear GIE						intstart_reg	<= 1'b1;	// the next cycle is interrupt-stall cycle					end else if (INST_RETFIE == 1'b1) begin	// "return from interrupt" instruction						intcon_reg[7]	<= 1'b1;						intstart_reg	<= 1'b0;					end else if (writeram_node == 1'b1 && ADDR_INTCON == 1'b1) begin	// distination is GIE						intcon_reg[7]	<= aluout_reg[7];						intstart_reg	<= 1'b0;					end else begin						intstart_reg	<= 1'b0;

⌨️ 快捷键说明

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