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

📄 piccore.v

📁 PIC源代码很不错
💻 V
📖 第 1 页 / 共 4 页
字号:
					end				end else begin					intstart_reg	<= 1'b0;				end				// 2-5-2-7. Set/clear /PD and /TO flags				if (intstart_reg == 1'b0) begin					if (INST_CLRWDT == 1'b1 || (INST_SLEEP == 1'b1 && (wdtreset_node == 1'b0 && intstart_reg == 1'b0))) begin						// CLRWDT or (SLEEP and no interrupt trigger)						// see pp.46,58 and 66 of PIC16F84 data-sheet						if (INST_SLEEP == 1'b1) begin							sleepflag_reg	<= 1'b1;							status_reg[4:3]	<= 2'b10;	// SLEEP: /T0,/PD = 1,0						end else begin					// (INST_CLRWDT)							status_reg[4:3]	<= 2'b11;	// CLRWDT: /T0,/PD = 1,1						end					end				end			end			// (if not stalled)			// 2-5-3. Clear data-SRAM write enable (hazard-free)			writeram_reg	<= 1'b0;			// 2-5-4. Change clkout output			clkout_reg		<= 1'b0;			// 2-5-5. Check increment-TMR0 request			if (inctmr_sync_reg == 2'b01) begin				inctmrhold_reg	<= 1'b1;			end			// 2-5-6. Goto next cycle			if (reset_cond == 1'b1) begin				state_reg	<= Qreset;			end else begin				state_reg	<= Q1;			end		end		// 2-6. Illegal states (NEVER REACHED in normal execution)		default: begin			state_reg	<= Qreset;	// goto reset state		end		endcase	end	// TMR0 pre-scaler (see pp.27 of PIC16F84 data sheet)	// select pre-scaler	assign	psck	= (option_reg[5] == 1'b0) ? (clkout_reg)	// option_reg(5):T0CS									: (t0cki ^ option_reg[4]);	// option_reg(4):T0SE	// pre-scaler body	reg 	[7:0]	rateval;	always @(posedge psck or negedge ponrst_n) begin		if (ponrst_n == 1'b0) begin			pscale_reg	<= 0;			ps_full_reg	<= 1'b0;		end else begin			case (option_reg[2:0])	// select prescaler-full value by PS2-0			3'b000: begin				rateval	= 1;			end			3'b001: begin				rateval	= 3;			end			3'b010: begin				rateval	= 7;			end			3'b011: begin				rateval	= 15;			end			3'b100: begin				rateval	= 31;			end			3'b101: begin				rateval	= 63;			end			3'b110: begin				rateval	= 127;			end//			3'b111:	rateval = 255;			default: begin				rateval	= 255;			end			endcase			if (pscale_reg >= rateval) begin				pscale_reg	<= 0;				ps_full_reg	<= 1'b1;			end else begin				pscale_reg	<= pscale_reg + 1;				ps_full_reg	<= 1'b0;			end		end	end	// select TMR0-increment trigger	assign	inctmrck	= (option_reg[3] == 1'b1) ? (psck)	// option_reg(3):PSA										: (ps_full_reg);	// ps_full_reg:output of pre-scaler// WDT timer body	reg 	wdtfull_node;	wire	wdt_reset_n_node;	assign	wdt_reset_n_node	= (ponrst_n == 1'b0 || mclr_n == 1'b0) ? 1'b0 : 1'b1;	always @(posedge wdtclk or negedge wdt_reset_n_node) begin		if (wdt_reset_n_node == 1'b0) begin	// (async reset)			wdt_reg				<= 0;			wdt_full_reg		<= 1'b0;			wdtclr_req_reg		<= 2'b00;			wdtfullclr_req_reg	<= 2'b00;		end else begin			// synchronizers			// WDT-clear request (CLRWDT/SLEEP instruction)			wdtclr_req_reg[0]	<= wdt_clr_reg;	// (do not AND with sleepflag_reg, since WDT should be cleared at SLEEP instruction)			wdtclr_req_reg[1]	<= wdtclr_req_reg[0];			// WDT-full-clear request (after WDT reset)			wdtfullclr_req_reg[0]	<= wdtfull_clr_reg & ( ~sleepflag_reg);			wdtfullclr_req_reg[1]	<= wdtfullclr_req_reg[0];			// timer/full reg			if (wdt_reg >= 255) begin				wdtfull_node	= 1'b1;	// (intermidiate node)			end else begin				wdtfull_node	= 1'b0;	// (intermidiate node)			end			// wdt_reg(counter) body			if (wdtclr_req_reg == 2'b01 || wdtena == 1'b0) begin				wdt_reg	<= 0;			end else if (wdtfull_node == 1'b1) begin				wdt_reg	<= 0;			end else begin				wdt_reg	<= wdt_reg + 1;			end			// wdt_full_reg(interrupt trigger) body			if (wdtfullclr_req_reg == 2'b01 || wdtena == 1'b0) begin				wdt_full_reg	<= 1'b0;			end else if (wdtfull_node == 1'b1) begin				wdt_full_reg	<= 1'b1;			end		end	end	assign	wdtclr_ack	= wdtclr_req_reg[1];	// WDT-clear ack signal to CPU	assign	wdtfull	= wdt_full_reg;	// WDT-full signal (interrupt trigger) to CPU// WDT controller in CPU-clock line (handshake-interface between WDT and CPU-EFSM)	always @(posedge clkin) begin		if (poweron_sync_reg == 1'b0 || mclr_sync_reg == 1'b0) begin			wdt_clr_reg	<= 1'b0;			// WDT clear request register			wdt_clr_reqhold_reg	<= 1'b0;	// will be 1 when WDT clear request comes while another clear request is still processed			wdtfull_clr_reg	<= 1'b0;		// WDT-full clear request register		end else begin			// WDT-clear/hold WDT-clear request			// (handshake)			if (wdt_clr_reg == 1'b1) begin	// still processing clear-operation				if (wdtclr_ack_sync_reg == 1'b1) begin	// if ack comes, go down the clear request					wdt_clr_reg	<= 1'b0;				end			end else if (wdt_clr_reqhold_reg == 1'b1 || (state_reg == Q4 && exec_op_reg == 1'b1 && intstart_reg == 1'b0 && (INST_CLRWDT == 1'b1 || INST_SLEEP == 1'b1))) begin				// clear request comes				if (wdtclr_ack_sync_reg == 1'b0) begin	// confirm if ack is 0					wdt_clr_reg	<= 1'b1;					wdt_clr_reqhold_reg	<= 1'b0;				end else begin	// (wait until ack becomes 0)					wdt_clr_reqhold_reg	<= 1'b1;				end			end			// clear WDT-full (CPU reset request)			// (handshake)			if (wdtfull_clr_reg == 1'b1) begin	// still processing clear-operation				if (wdt_full_sync_reg[1] == 1'b0) begin	// if ack comes, go down the clear request					wdtfull_clr_reg	<= 1'b0;				end			end else if (wdt_full_sync_reg[1] == 1'b1) begin	// clear request comes				// the WDT-full signal does not come so often, so hold-register is not necessary				wdtfull_clr_reg	<= 1'b1;			end		end	end// Detect external interrupt requests	// INT0 I/F	wire	i0rst_node;	assign	i0rst_node	= intclr_reg[0];	always @(posedge int0 or posedge i0rst_node) begin		if (i0rst_node == 1'b1) begin			intrise_reg[0]	<= 1'b0;		end else begin			// catch positive edge			intrise_reg[0]	<= 1'b1;		end	end	always @(negedge int0 or posedge i0rst_node) begin		if (i0rst_node == 1'b1) begin			intdown_reg[0]	<= 1'b0;		end else begin			// catch negative edge			intdown_reg[0]	<= 1'b1;		end	end	assign	rb0_int	= (option_reg[6] == 1'b1) ? (intrise_reg[0])	// option_reg(6):INTEDG												: (intdown_reg[0]);	// INT4 I/F	wire	i4rst_node;	assign	i4rst_node	= intclr_reg[1];	always @(posedge int4 or posedge i4rst_node) begin		if (i4rst_node == 1'b1) begin			intrise_reg[1]	<= 1'b0;		end else begin			// catch positive edge			intrise_reg[1]	<= 1'b1;		end	end	always @(negedge int4 or posedge i4rst_node) begin		if (i4rst_node == 1'b1) begin			intdown_reg[1]	<= 1'b0;		end else begin			// catch negative edge			intdown_reg[1]	<= 1'b1;		end	end	assign	rb4_int	= intrise_reg[1] | intdown_reg[1];	// INT5 I/F	wire	i5rst_node;	assign	i5rst_node	= intclr_reg[2];	always @(posedge int5 or posedge i5rst_node) begin		if (i5rst_node == 1'b1) begin			intrise_reg[2]	<= 1'b0;		end else begin			// catch positive edge			intrise_reg[2]	<= 1'b1;		end	end	always @(negedge int5 or posedge i5rst_node) begin		if (i5rst_node == 1'b1) begin			intdown_reg[2]	<= 1'b0;		end else begin			// catch negative edge			intdown_reg[2]	<= 1'b1;		end	end	assign	rb5_int	= intrise_reg[2] | intdown_reg[2];	// INT6 I/F	wire	i6rst_node;	assign	i6rst_node	= intclr_reg[3];	always @(posedge int6 or posedge i6rst_node) begin		if (i6rst_node == 1'b1) begin			intrise_reg[3]	<= 1'b0;		end else begin			// catch positive edge			intrise_reg[3]	<= 1'b1;		end	end	always @(negedge int6 or posedge i6rst_node) begin		if (i6rst_node == 1'b1) begin			intdown_reg[3]	<= 1'b0;		end else begin			// catch negative edge			intdown_reg[3]	<= 1'b1;		end	end	assign	rb6_int	= intrise_reg[3] | intdown_reg[3];	// INT7 I/F	wire	i7rst_node;	assign	i7rst_node	= intclr_reg[4];	always @(posedge int7 or posedge i7rst_node) begin		if (i7rst_node == 1'b1) begin			intrise_reg[4]	<= 1'b0;		end else begin			// catch positive edge			intrise_reg[4]	<= 1'b1;		end	end	always @(negedge int7 or posedge i7rst_node) begin		if (i7rst_node == 1'b1) begin			intdown_reg[4]	<= 1'b0;		end else begin			// catch negative edge			intdown_reg[4]	<= 1'b1;		end	end	assign	rb7_int	= intrise_reg[4] | intdown_reg[4];// Decode INT triggers (do not AND with GIE(intcon_reg(7)), since these signals are also used for waking up from SLEEP)	assign	inte	= intcon_reg[4] & rb0_int;									// G0IE and raw-trigger signal	assign	rbint	= intcon_reg[3] & (rb4_int | rb5_int | rb6_int | rb7_int);	// RBIE and raw-trigger signal// Circuit's output siganals	assign	progadr	= pc_reg;	// program ROM address//> modified ver1.00c, 2002/08/07//	assign	ramadr	= ramadr_reg;					// data RAM address	// map 0F0-0FF,170-17F, and 1F0-1FF into 070-07F	assign	ramadr	= (ramadr_node[6:4] != 3'b111) ? (ramadr_node)				: ({5'b00111, ramadr_node[3:0]});	// data RAM address//<	assign	ramdtout	= aluout_reg;		// data RAM write data//> modified ver1.00c, 2002/08/07//	assign	readram	= (state_reg[1:0] = 2'b01) ? 1'b1 : 1'b0;	// data RAM read enable	(1 when state_reg = Q2)	assign	readram	=  ~writeram_reg;//<	assign	writeram	= writeram_reg;		// data RAM write enable	assign	eepadr	= eeadr_reg;			// EEPROM address	assign	eepdtout	= eedata_reg;		// EEPROM write data	assign	readeepreq	= eecon1_reg[0];	// EEPROM read request	assign	writeeepreq	= eecon1_reg[1];	// EEPROM write request	assign	porta_out	= portaout_reg;		// PORT-A output	assign	porta_dir	= trisa_reg;		// PORT-A direction	assign	portb_out	= portbout_reg;		// PORT-B output	assign	portb_dir	= trisb_reg;		// PORT-B direction	assign	rbpu	= option_reg[7];		// RBPU: pull-up enable	assign	clkout	= clkout_reg;			// clkout (clkin/4) output	assign	powerdown	= sleepflag_reg;	// CPU clock stop indicator	assign	startclkin	= inte | rbint | wdt_full_reg | ( ~mclr_n) | ( ~ponrst_n);	// CPU clock start indicatorendmodule

⌨️ 快捷键说明

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