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

📄 ifetch.v

📁 arm9_fpga2_verilog是一个可以综合的用verilog写的arm9的ip软核
💻 V
📖 第 1 页 / 共 2 页
字号:
`timescale 1ns/10ps`include "pardef"/*****************************************************************************$RCSfile: ifetch.v,v $$Revision: 1.8 $$Author: kohlere $$Date: 2000/05/10 20:35:48 $$State: Exp $$Source: /home/lefurgy/tmp/ISC-repository/isc/hardware/ARM10/behavioral/pipelined/fpga2/ifetch.v,v $Description: Currently, this is the first stage of the pipeline.  This		stage handles the PC and fetches the next instruction.  It 		also performs a simple branch prediction (BTFNT).*****************************************************************************/module ifetch(nGCLK, nWAIT, nRESET, dabort, iabort, if_enbar,		inst_bus, flags, load_pc, s_nFIQ, s_nIRQ, exception_to_id,		fill_state, pc, inst_if, inst_addr, eval,		mispredicted, misp_rec, pt, put, me_result, base_me, 		ex_result, Rd_ex, Rd_me, pc_touched, InMREQ,		Rn_me, write_Rd_ex, hold_next_ex, load_pc_ex,		exc_code, prediction_stall, newline);/*------------------------------------------------------------------------        Ports------------------------------------------------------------------------*/input   [95:0]  inst_bus;		//Instruction Datainput	[31:0]	me_result;		//Rd Data in ME Stageinput	[31:0]	base_me;		//Base Data in ME Stageinput	[31:0]	ex_result;		//Result of Ex Stageinput	[4:0]	Rd_me;			//Rd in ME Stageinput	[4:0]	Rn_me;			//Rn in ME Stageinput	[4:0]	Rd_ex;			//Rd in EX Stageinput	[3:0]	flags;			//CPSR Flagsinput	[2:0]	fill_state;		//Machine Stateinput		nGCLK;			//clock signalinput		nWAIT;			//clock enableinput        	nRESET;			//reset signalinput		iabort;			//Inst Abortinput		dabort;			//Data Abortinput		s_nFIQ;			//FIQinput		s_nIRQ;			//IRQinput         	if_enbar;		//PC enable (active low)input		write_Rd_ex;		//Write Rd in ME Stageinput		hold_next_ex;		//EX is stallinginput		load_pc_ex;		//Load the PC from Memory nextinput		load_pc;		//Load the PC from Memoryoutput 	[31:0] 	pc;			//Program Counter Valueoutput	[31:0]	inst_if;		//Instruction to ID stageoutput	[31:0]	inst_addr;		//Instruction Addressoutput	[1:0]	exc_code;		//Which Exceptionoutput		InMREQ;			//Instruction Fetch Requestedoutput		newline;		//New Cache Line Requiredoutput		pc_touched;		//PC is being Modified by Pipeoutput		exception_to_id;	//Take Exceptionoutput		mispredicted;		//Mispredicted a branchoutput		misp_rec;		//Recoverable Mispredictionoutput		prediction_stall;	//Need a Bubble for Predictionoutput		pt;			//Predict Takenoutput		put;			//Predict Untakenoutput		eval;			//Predicted Br in Ex/*------------------------------------------------------------------------        Variable Declarations------------------------------------------------------------------------*/reg	[35:0]  pcstore;	//Value to Store in Saved_PC Reg	reg     [36:0]  saved_pc0;      //Stored PC + BR Conditionreg     [36:0]  saved_pc1;      //Stored PC + BR Conditionreg	[36:0]	saved_pc2;	//Stored PC + BR Conditionreg	[31:0]	irstore;	//Instruction to Storereg	[32:0]	saved_ir0;	//Saved Instructionreg	[32:0]	saved_ir1;	//Saved Instructionreg	[32:0]	saved_ir2;	//Saved Instructionreg	[31:0]	pc_me;		//PC Value from MEreg	[31:0]	inst_addr;	//Address Bus Latchreg	[31:0]	inst_addr_in;	//Muxed PCreg	[31:0]	pred_addr;	//Predicted Addressreg	[31:0]	pc;		//PC to ID stagereg 	[31:0] 	pc_if;		//Program Counter Registerreg	[31:2]  pcp4;		//PC plus 4reg 	[31:0] 	next_pc;	//Output from Multiplexer to D input of PCreg	[31:0]	saved_pc;	//Muxed saved_pc valuereg	[31:0]	saved_ir;	//Muxed saved_ir valuereg	[31:0]	inst_if;	//Instruction to ID stagereg	[31:0]	exc_vector;	//Exception Vectorreg	[31:0]	offset;		//Muxed between Branch/Dabortreg	[31:5]	lastline;	//Last {Tag,Line} Numberreg	[4:0]	saved_cond;	//Muxed saved_cond valuereg	[4:2]	lastword;	//Last Word Numberreg	[1:0]	open_ptr;	//Pointer To Open Save Bufferreg	[1:0]	eval_ptr;	//Pointer to Current Branch reg	[1:0]	next_open_ptr;	//Next State for Open Pointerreg	[1:0]	next_eval_ptr;	//Next State for Eval Pointerreg	[1:0]	exc_code;	//Exception Codereg		was_iabort;	//Was Instruction Abortreg		was_dabort;	//Wast Data Access Abortreg		ps1;		//Prediction Stall Nowreg		updating_clb;	//Updating Cache Line Bufferreg		recoverable;	//Stored the fall-through Instructionreg	   	latched_reset;	//Captured Reset Signalreg		wait1;		//Branch was Predicted, in IF stage nowreg		wait2;		//Branch was Predicted, in ID stage nowreg		eval;		//Predicted Branch in EX stagereg		cond_false;	//Condition is falsereg		use_stall;	//Use a Bubble to Check Branch Predwire	[31:0]	inc_pc;		//Incremented PCwire	[31:0]	branch_addr;	//Branch Addresswire	[31:0]	boff1;		//Branch Offset 1wire	[31:0]	boff2;		//Branch Offset 2wire	[31:0]	doff;		//Offset for Data Aborts (-4)wire	[31:0]	iplus1;		//Next Instructionwire	[31:0]	iplus2;		//Next Next Instructionwire	[31:0]	iplus3;		//Next Next Next Instructionwire    [31:0]  spci2;     	//PC to Store for Misprediction recoverywire	[31:0]	spci1;		//PC to Store for Misprediction recoverywire	[31:0]	pc_for_br;	//PC to add Offset To for Brancheswire	[31:2]	to_pcp4;	//Output of PC Incrementerwire	[31:0]	pcp8;		//Output of PC + 8 Incrementerwire	[29:0]	pc_plus;	//PC + 4wire	[29:0]	pc_plus_off;	//PC + Offsetwire		InMREQ;		//Instruction Request (low)wire		newline;	//Change Cache Lineswire		fallthrough;	//This is the fallthrough instructionwire		exception;	//Exceptionwire		exception_to_id;//Exceptionwire		exc_no_inc;	//Don't Increment PCwire		ptaken1;  	//Predict Taken on iplus1wire		ptaken2;	//Predict Taken on iplus2wire		puntaken1;	//Predict Not Taken on iplus1wire		pc_touched;	//PC modified by an instructionwire		mispredicted;	//mispredicted a branchwire		misp_rec;	//mispredicted, but recoverablewire		clr_pred;	//Clear Any/All Predictionswire		N;		//N Flag (negative)wire		Z;		//Z Flag (zero)wire		C;		//C Flag (carry)wire		V;		//V Flag (overflow)wire		pt = ptaken1 | ptaken2;wire		put = puntaken1;/*------------------------------------------------------------------------        Basic Assignments------------------------------------------------------------------------*///Break off Instructionsassign iplus1 = inst_bus[31:0];assign iplus2 = inst_bus[63:32];assign iplus3 = inst_bus[95:64];//Assign the Inst Request Signalassign InMREQ = if_enbar | ~latched_reset;//Reset the Branch Prediction State Machineassign clr_pred = (pc_touched | mispredicted | dabort | load_pc_ex |			load_pc);//This signal detects that FIQ and IRQ have been takenassign exc_no_inc = exception & ((exc_code == 2'h1) | (exc_code == 2'h2));assign exception = dabort |		        ((iabort | !s_nFIQ | !s_nIRQ) 			& !if_enbar & !mispredicted & !pc_touched			& ~(wait1 | wait2 | eval));assign exception_to_id = exception;//This is the last PC fetch, incremented by '4'//If there is a load to the PC, I don't want to //increment it until the next cycleassign pc_plus = inst_addr[31:2] + 1;assign inc_pc = {pc_plus,2'h0};//Check for a mispredicted Branchassign mispredicted = (cond_false & eval & saved_cond[4]) |		      (!cond_false & eval & !saved_cond[4]);//Check to see that an instruction modified the PCassign pc_touched = ((Rd_ex == 5'h0F && write_Rd_ex == 1'b1) &			~load_pc_ex);//This is the branch offset.  Its sign exteded and shifted left two places.//On Data Aborts, have to sub 4 from PC so that it will end up being PC+8assign doff = 32'hFFFFFFF8;assign boff1 = {{6{iplus1[23]}},iplus1[23:0],2'b00};assign boff2 = {{6{iplus2[23]}},iplus2[23:0],2'b00};//This performs the branch calculation.  Because the pc_if is only PC + 4,//in relation to the instruction in the instruction buffer, an extra 4 must//be added to compensate for the usual PC+8 condition.assign to_pcp4 = (pc_if[31:2] + 1);assign pc_for_br = (ptaken2) ? {to_pcp4,2'h0} : pc_if;assign pc_plus_off = (pc_for_br[31:2] + offset[31:2] + 1);assign branch_addr = {pc_plus_off,2'h0};//Predict a Branch to be taken if://1) Its an Unconditional BR/BL//2) Its a Branch Backward (loop?)//Note that the extra conditions for p2//are there to assure one-hot'edness //between ptaken1, ptaken2, puntaken1assign ptaken1 = (((iplus1[31:24] == 8'hEA)	|	//Uncond Branch		  (iplus1[27:23] == 5'h15))	&	//Branch Backwords		  ~(updating_clb | 			//Reading New Line		   (ps1 & ~updating_clb)));		//Br to Selfassign ptaken2 = (((iplus2[31:24] == 8'hEA)	|       //Uncond Branch                   (iplus2[27:23] == 5'h15))	&	//Branch Backwords		  ~(ptaken1 | puntaken1 |			updating_clb));			//Reading New Line//Predict a Branch to be not taken if://1) Its a Conditional Branch Forward//If want to predict untaken on last word, no gain//If try to predict while another prediction is in the IF stage,//will have to eval 2 at once in order to insure an incorrect //instruction in EX doesn't modify state.  Just don't predict//to save the hassle of checking two at a time.  chthJ8.4554assign puntaken1 = (((iplus1[27:23] == 5'h14) 	&	//Branch Forwards		     (iplus1[31:28] != 4'hE))	&	//!Uncond Branch		    ~(updating_clb | 			//Reading New Line		      lastword == 3'h7 |		//End of Line		      wait1 | use_stall));		//Watch the Cache Line, when it changes, stop predictingassign newline = (lastline != inst_addr[31:5]);//Create a Bubble for Predict Takens on Iplus1assign prediction_stall = ptaken1;//Determine whether we have stored the next instruction//for a predicted branch.  If so, we can hide the prefetch//operation and eliminate a bubble in the pipeline.assign misp_rec = mispredicted & recoverable;//Figure Out if we have the fall through instruction, //necessary to recover from mispredicted taken branchesassign fallthrough = (ptaken1 & (lastword != 3'h7)) |		     (ptaken2 & (lastword != 3'h7) &				(lastword != 3'h6));//Mux the Values which will need to be saved for Branch predictionassign pcp8 = {(pc_if[31:3] + 1),pc_if[2],2'b00};assign spci2 = (ptaken2 & fallthrough) ? pcp8 : {to_pcp4,2'h0};assign spci1 = (ptaken1 & fallthrough) ? {to_pcp4,2'h0} : pc_if;//Assign each flag for later use.assign N = flags[3];assign Z = flags[2];assign C = flags[1];assign V = flags[0];/*------------------------------------------------------------------------        Sequential Always Blocks------------------------------------------------------------------------*/	//This block controls the operations of //the PC registeralways @(posedge nGCLK)    begin      if (nWAIT)        begin          if (!if_enbar & !exc_no_inc)            pc_if <= next_pc;        end    end//This block follows the pc, only//necessary when predicting early//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)  begin    if (~nRESET)      pcp4 <= 30'h00000000;    else if (nWAIT)      begin        if (~if_enbar & ~exc_no_inc)          pcp4 <= to_pcp4;      end  end//This latches the Inst Address Busalways @(nGCLK or if_enbar or inst_addr_in or nWAIT or inst_addr)    begin      if (~nGCLK)	begin          if (nWAIT & ~if_enbar)	    inst_addr <= inst_addr_in;	  else	    inst_addr <= inst_addr;        end    end	  //This catches the previous {Tag,Line}//synopsys async_set_reset "nRESET"wire update_line = ~if_enbar & latched_reset;always @(posedge nGCLK or negedge nRESET)  begin    if (~nRESET)      lastline <= 27'h7FFFFFF;    else if (nWAIT)      begin        if (update_line)          lastline <= inst_addr[31:5];      end  end//This catches the previous Word Number//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)  begin    if (~nRESET)      lastword <= 3'h7;    else if (nWAIT)      begin        if (~if_enbar)          lastword <= inst_addr[4:2];      end  end//This block latches the inst abort signalalways @(posedge nGCLK or negedge nRESET)  begin    if (~nRESET)      was_iabort <= 1'b0;    else if (nWAIT)      begin        if (~if_enbar)          was_iabort <= iabort;      end  endalways@(negedge nRESET or posedge nGCLK)  begin    if (~nRESET)      was_dabort <= 1'b0;    else if (nWAIT)      begin        if (~if_enbar)          was_dabort <= dabort;      end  end//This block captures the nRESET signalalways @(negedge nRESET or posedge nGCLK)    begin      if (!nRESET)	  latched_reset <= 1'b0;      else if (nWAIT)	  latched_reset <= 1'b1;    end//The next three flip-flops create a state machine which//waits two cycles, and then indicates that the condition//of a predicted branch must be evaluated.  Do not begin//this procedure if either mispredicted or pc_touched is//high because the branch prediction is not being used.//These two cases have higher priority.//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)  begin    if (!nRESET)      wait1 <= 1'h0;    else if (nWAIT)      begin        if (!if_enbar)          wait1 <= (ptaken2) & ~(clr_pred);      end    end//putting in the hold_next & wait2 because if hold+next goes high//while wait2 is high, its possible that if_enbar will be low, so//don't want to reset in this case rodan.99-Aug-19.27461//putting in this condition because don't want signal to last longer//even if if_enbar is high...because pipe is advancing smaug-Aug20//but pipe is not advancing if hold_next is high, so this must be //considered as well smaug-Sep3//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)  begin    if (!nRESET)      wait2 <= 1'b0;    else if (nWAIT)      begin        if (~if_enbar)          wait2 <= (wait1 | ptaken1 | puntaken1 | (wait2 & hold_next_ex)) 		& ~(clr_pred);        else if (~hold_next_ex)          wait2 <= 1'b0;      end  end//This flip-flop records the fact that back2back predictions//can only occur if there is a natural delay cycle to check the//second prediction.  If so, then this ff will extend the eval //cycle to check the second branch.//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET)  begin    if (~nRESET)      use_stall <= 1'b0;    else if (nWAIT)      use_stall <= ((wait1 & ptaken1 & ~if_enbar) | (use_stall & wait2))			& ~clr_pred;  end//synopsys async_set_reset "nRESET"

⌨️ 快捷键说明

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