📄 ifetch.v
字号:
always @(posedge nGCLK or negedge nRESET) begin if (!nRESET) eval <= 1'b0; else if (nWAIT) eval <= (wait2 | use_stall) & ~(clr_pred | hold_next_ex); end//This is a Pointer to the Next available set of Buffers//to store saved branch information//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) open_ptr <= 2'h0; else if (nWAIT) begin if (!if_enbar | clr_pred) open_ptr <= next_open_ptr; end end//This is a Pointer to the Pending Branch//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) eval_ptr <= 2'h0; else if (nWAIT) eval_ptr <= next_eval_ptr; end//This block controls the storing of the pc's//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) saved_pc0 <= 37'h0000000000; else if (nWAIT) begin if ((open_ptr == 2'h0)) begin if (pt) saved_pc0 <= {1'b1,pcstore}; else if (put) saved_pc0 <= {1'b0,pcstore}; end end end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) saved_pc1 <= 37'h0000000000; else if (nWAIT) begin if ((open_ptr == 2'h1)) begin if (pt) saved_pc1 <= {1'b1,pcstore}; else if (put) saved_pc1 <= {1'b0,pcstore}; end end end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) saved_pc2 <= 37'h0000000000; else if (nWAIT) begin if (open_ptr == 2'h2) begin if (pt) saved_pc2 <= {1'b1,pcstore}; else if (put) saved_pc2 <= {1'b0,pcstore}; end end end//synopsys async_set_reset "nRESET" always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) saved_ir0 <= 33'h0; else if (nWAIT) begin if ((open_ptr == 2'h0)) begin if (pt | put) saved_ir0 <= {fallthrough,irstore}; end end end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) saved_ir1 <= 33'h0; else if (nWAIT) begin if ((open_ptr == 2'h1)) begin if (pt | put) saved_ir1 <= {fallthrough,irstore}; end end end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) saved_ir2 <= 33'h0; else if (nWAIT) begin if ((open_ptr == 2'h2)) begin if (pt | put) saved_ir2 <= {fallthrough,irstore}; end end end//Create a FF that will halt Branch Prediction while//reading a new cache line into the line buffer//Want to assume reading a new line on reset, so //reset is actually a set for this flip-flop//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) updating_clb <= 1'b1; else if (nWAIT) updating_clb <= newline | ~latched_reset; end//This ff is used so that when a prediction stall is//encountered, if on the next cycle, updating_clb is //high, then could be branch to self and want to //not predict a branch in this cycle.//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) ps1 <= 1'b0; else if (nWAIT) ps1 <= (prediction_stall & ~if_enbar) | (ps1 & prediction_stall & if_enbar); end /*------------------------------------------------------------------------ Combinational Always Blocks------------------------------------------------------------------------*///Mux the pc value to be sent to the ID stagealways @(dabort or pc_if or was_dabort or pcp4 or wait1 or was_iabort) begin if (wait1 | was_iabort | dabort | was_dabort) pc = {pcp4,2'h0}; else pc = pc_if; end//Mux in the proper Exception Vectoralways @(latched_reset or dabort or iabort or s_nFIQ or s_nIRQ) begin if (!latched_reset) exc_vector = 32'h00000000; else if (dabort) exc_vector = 32'h00000010; else if (!s_nFIQ) exc_vector = 32'h0000001C; else if (!s_nIRQ) exc_vector = 32'h00000018; else if (iabort) exc_vector = 32'h0000000C; else exc_vector = 32'h00000000; end//Create the Exception Code by Exception Priority//DABORT = 00, FIQ = 01, IRQ = 10, IABORT = 11always @(dabort or iabort or s_nFIQ or s_nIRQ) begin if (dabort) exc_code = 2'h0; else if (!s_nFIQ) exc_code = 2'h1; else if (!s_nIRQ) exc_code = 2'h2; else exc_code = 2'h3; end//Mux out the PC or the Saved_PC for Predicted BL's//Combinational Multiplexer which sets up Data inputs//to the PCalways @(inc_pc or latched_reset or load_pc or me_result)//always @(inc_pc or nRESET or load_pc or me_result) begin if (~latched_reset) next_pc <= #1 32'h00000000; else if (load_pc) next_pc <= #1 me_result; else next_pc <= #1 inc_pc; end//Mux the two possible PC's from MEalways @(Rd_me or me_result or base_me) begin if (Rd_me == 5'h0F) pc_me = me_result; else pc_me = base_me; end //Mux the two possible predicted addressesalways @(pt or branch_addr or to_pcp4) begin if (pt) pred_addr = branch_addr; else pred_addr = {to_pcp4,2'h0}; end//Mux the outgoing PC to memory//Priority: Exception// Load to PC// Misprediction// Branch in Pipe// Predictionalways @(exception or exc_vector or load_pc or pc_me or mispredicted or saved_pc or pc_touched or ex_result or pt or put or pred_addr or pc_if) begin if (exception) inst_addr_in = exc_vector; else if (load_pc) inst_addr_in = pc_me; else if (mispredicted) inst_addr_in = saved_pc; else if (pc_touched) inst_addr_in = ex_result; else if (pt | put) inst_addr_in = pred_addr; else inst_addr_in = pc_if; end//Mux the instruction data to the ID stage, It will//be either the instruction bus, or a mov->R14 always @(iplus1 or saved_ir or misp_rec or iplus2 or puntaken1) begin if (misp_rec) inst_if = saved_ir; else if (puntaken1) inst_if = iplus2; else inst_if = iplus1; end//Mux the three sets of conditionsalways @(eval_ptr or saved_pc0 or saved_pc1 or saved_pc2) begin case (eval_ptr) //synopsys full_case parallel_case 2'h2: saved_cond = saved_pc2[36:32]; 2'h1: saved_cond = saved_pc1[36:32]; default: saved_cond = saved_pc0[36:32]; endcase end//Mux the three saved pc'salways @(eval_ptr or saved_pc0 or saved_pc1 or saved_pc2) begin case (eval_ptr) //synopsys full_case parallel_case 2'h2: saved_pc = saved_pc2[31:0]; 2'h1: saved_pc = saved_pc1[31:0]; default: saved_pc = saved_pc0[31:0]; endcase endalways @(eval_ptr or saved_ir0 or saved_ir1 or saved_ir2) begin case (eval_ptr) //synopsys full_case parallel_case 2'h2: saved_ir = saved_ir2[31:0]; 2'h1: saved_ir = saved_ir1[31:0]; default: saved_ir = saved_ir0[31:0]; endcase end//Mux the Recoverable bitalways @(eval_ptr or saved_ir0 or saved_ir1 or saved_ir2) begin case (eval_ptr) //synopsys full_case parallel_case 2'h2: recoverable = saved_ir2[32]; 2'h1: recoverable = saved_ir1[32]; default: recoverable = saved_ir0[32]; endcase end//Check the Predicted Branch conditionsalways @(saved_cond or N or Z or C or V) begin case (saved_cond[3:0]) //synopsys full_case parallel_case `EQ: cond_false = !(Z); `NE: cond_false = !(~Z); `CS: cond_false = !(C); `CC: cond_false = !(~C); `MI: cond_false = !(N); `PL: cond_false = !(~N); `VS: cond_false = !(V); `VC: cond_false = !(~V); `HI: cond_false = !(C & ~Z); `LS: cond_false = !(~C | Z); `GE: cond_false = !((N && V)||(~N && ~V)); `LT: cond_false = !((N && ~V)||(~N && V)); `GT: cond_false = !(~Z && ((N && V)||(~N && ~V))); `LE: cond_false = !(Z || ((N && ~V)||(~N && V))); `AL: cond_false = 1'b0; `NV: cond_false = 1'b1; endcase end//Mux the offset added to the PC, only used for Predicting Branches//And storing the correct PC on Data Abortsalways @(ptaken2 or dabort or doff or boff1 or boff2) begin if (dabort) offset = doff; else if (ptaken2) offset = boff2; else offset = boff1; end//Find the Next State for the Open Pointeralways @(pt or put or open_ptr or clr_pred) begin if (clr_pred) next_open_ptr = 2'h0; else begin case(open_ptr) //synopsys full_case parallel_case 2'b00: next_open_ptr = (pt | put) ? 2'h1 : 2'h0; 2'b01: next_open_ptr = (pt | put) ? 2'h2 : 2'h1; 2'b10: next_open_ptr = (pt | put) ? 2'h0 : 2'h2; 2'b11: next_open_ptr = 2'h0; endcase end end//Find the Next State for the Eval Pointeralways @(eval_ptr or eval or clr_pred) begin if (clr_pred) next_eval_ptr = 2'h0; else begin case(eval_ptr) //synopsys full_case parallel_case 2'b00: next_eval_ptr = eval ? 2'h1 : 2'h0; 2'b01: next_eval_ptr = eval ? 2'h2 : 2'h1; 2'b10: next_eval_ptr = eval ? 2'h0 : 2'h2; 2'b11: next_eval_ptr = 2'h0; endcase end end//Mux in the pcstore value.//For PTaken, Want to Store PC/PC+4 (depends on where predicting from)//For PUnTaken, Want to Store Branch Addressalways @(ptaken1 or ptaken2 or puntaken1 or branch_addr or spci2 or spci1 or iplus2 or iplus1) begin case ({ptaken1,ptaken2,puntaken1}) //synopsys parallel_case full_case //Predict Untaken on Iplus1 3'h1: pcstore = {iplus1[31:28],branch_addr}; //Predict Taken on Iplus2 3'h2: pcstore = {iplus2[31:28],spci2}; //Predict Taken on Iplus1 3'h4: pcstore = {iplus1[31:28],spci1}; //No Predictions Being Made default: pcstore = 36'h0; endcase end //Mux in the Proper Instruction to Store//Want to Store the Next Instruction after Branchalways @(puntaken1 or ptaken1 or iplus2 or iplus3) begin if (puntaken1 | ptaken1) irstore = iplus2; else irstore = iplus3; end/*======================================================================*/endmodule //ifetch/*======================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -