//==================================================================== // // 5 stage pipeline: IF, ID, EX, MEM, WB // Instructions: register-register ALU instructions with 2 register ids // register-immediate ALU instructions with 2 register ids // store instructions // load instructions // All in a dual issue fashion // // Author: Aaron Kobayashi (baudburn at instructor dot net) // // Date: 12/1/02 // //==================================================================== (bit phi1 phi2 phi3 phi4 Flush Flush_bar //Regwrite bits RegWrite IF_RegWrite IF_ID_RegWrite ID_EX_RegWrite EX_MEM_RegWrite MEM_WB_RegWrite write_PC write_RegFile_In //Register-Immediate Bits use_Imm IF_ID_use_Imm ID_EX_use_Imm //Store Instruction Bits MemWrite IF_MemWrite IF_ID_MemWrite ID_EX_MemWrite EX_MEM_MemWrite write_DMem_In //Load Instruction Bits MemToReg IF_ID_MemToReg ID_EX_MemToReg EX_MEM_MemToReg MEM_WB_MemToReg ID_StallReg ID_StallReg1 ID_StallReg2 ID_WriteResult EX_WriteResult ID_StallTmp ID_Stall ID_Stall_bar stall_PC //For Bubbles ID_MemWrite ID_RegWrite //Second Pipeline bits //Register-Immediate Bits pipe2_use_Imm pipe2_IF_ID_use_Imm pipe2_ID_EX_use_Imm //Regwrite bits pipe2_RegWrite pipe2_IF_RegWrite pipe2_IF_ID_RegWrite pipe2_ID_EX_RegWrite pipe2_ID_RegWrite pipe2_EX_MEM_RegWrite pipe2_MEM_WB_RegWrite //Store Instruction Bits pipe2_MemWrite pipe2_IF_MemWrite pipe2_IF_ID_MemWrite pipe2_ID_MemWrite pipe2_ID_EX_MemWrite pipe2_EX_MEM_MemWrite //Load Instruction Bits pipe2_MemToReg pipe2_IF_ID_MemToReg pipe2_ID_EX_MemToReg pipe2_EX_MEM_MemToReg pipe2_MEM_WB_MemToReg //ALU Forwarding Bits pipe1_fwd_MEMD1_P1 pipe1_fwd_MEMD2_P1 pipe1_fwd_WBD1_P1 pipe1_fwd_WBD2_P1 pipe1_fwd_MEMD1_P2 pipe1_fwd_MEMD2_P2 pipe1_fwd_WBD1_P2 pipe1_fwd_WBD2_P2 pipe2_fwd_MEMD1_P1 pipe2_fwd_MEMD2_P1 pipe2_fwd_WBD1_P1 pipe2_fwd_WBD2_P1 pipe2_fwd_MEMD1_P2 pipe2_fwd_MEMD2_P2 pipe2_fwd_WBD1_P2 pipe2_fwd_WBD2_P2 pipe1_RegsEqual_MEMD1_P1 pipe1_RegsEqual_MEMD2_P1 pipe1_RegsEqual_WBD1_P1 pipe1_RegsEqual_WBD2_P1 pipe1_RegsEqual_MEMD1_P2 pipe1_RegsEqual_MEMD2_P2 pipe1_RegsEqual_WBD1_P2 pipe1_RegsEqual_WBD2_P2 pipe2_RegsEqual_MEMD1_P1 pipe2_RegsEqual_MEMD2_P1 pipe2_RegsEqual_WBD1_P1 pipe2_RegsEqual_WBD2_P1 pipe2_RegsEqual_MEMD1_P2 pipe2_RegsEqual_MEMD2_P2 pipe2_RegsEqual_WBD1_P2 pipe2_RegsEqual_WBD2_P2 //Instruction Issue Bits issue_ID1_to_EX1 issue_ID1_to_EX1_bar issue_ID2_to_EX2 issue_ID2_to_EX2_bar pipe1_RAW_pipe2_EX_tmp2 is_Load2pipe2 is_Store2pipe2 pipe1_RAW_pipe2 pipe1_RAW_pipe2_tmp pipe1_RAW_pipe2_EX pipe1_RAW_pipe2_EX_tmp pipe1_RAW_pipe2_r1 pipe1_RAW_pipe2_r2 pipe1_RAW_pipe2_r1_EX pipe1_RAW_pipe2_r2_EX pipe2_write_RegFile_In issue_both_instructions_at_ID issue_both_instructions_at_ID1 issue_1_instruction_at_ID issue_1_instruction_at_ID1 //Jump and Branch Bits issued_both_inst write_PC1 write_PC1_2 squash_instructions squash_instructions_bar pipe2_is_Jump pipe2_is_Branch is_Jump is_Branch do_issue_ID2 do_issue_ID2_bar EX_RegWrite pipe2_EX_RegWrite EX_MemWrite issue_ID1_to_EX2 issue_ID1_to_EX2_bar ID_EX_enable1 ID_EX_enable2 ID1_isJumpOrBranch ID2_isJumpOrBranch ID2_isJumpOrBranch_bar ID2_is_Load_or_Store write_PC1_3 ID1_is_issued IF_is_Jump IF_is_Branch IF_ID_is_Jump IF_ID_is_Branch IF_ID_is_Jump_bar IF_ID_is_Branch_bar pipe2_IF_is_Jump pipe2_IF_is_Branch pipe2_IF_ID_is_Jump pipe2_IF_ID_is_Branch pipe2_ID_EX_is_Jump pipe2_ID_EX_is_Branch ID2_is_Jump ID2_is_Branch pipe2_ID_is_Jump pipe2_ID_is_Branch pipe2_EX_TakeBranch pipe2_EX_is_taken_branch pipe2_EX_use_TargetPC pipe2_EX_MEM_use_TargetPC EX_useTargetPC ID1_ID2_squash_bar do_issue_ID1 ID1_squash_bar ID2_squash_bar ID2_RegWrite ) (term PC sequentialPC SrcReg1 SrcReg2 DestReg Op Data1 Data2 //Inst. Fetch / Decode IF_ID_SrcReg1 IF_ID_SrcReg2 IF_ID_DestReg IF_ID_Op //Decode / Execute ID_EX_SrcReg1 ID_EX_SrcReg2 ID_EX_DestReg ID_EX_Op ID_EX_Data1 ID_EX_Data2 //For forwarding Result EX_MEM_Result EX_MEM_DestReg MEM_WB_Result MEM_WB_DestReg //For Reg-Immediate Imm IF_ID_Imm ID_EX_Imm ALU_Data1 ALU_Data2 //For Store Instructions NextMemState PresentMemState EX_DestAddr EX_MEM_DestAddr EX_MEM_Op //For Load Instructions ReadData MEM_WB_ReadData WriteData //For Second Pipeline next_PC next_sequential_PC pipe2_SrcReg1 pipe2_SrcReg2 pipe2_DestReg pipe2_Op pipe2_Imm pipe2_IF_ID_SrcReg1 pipe2_IF_ID_SrcReg2 pipe2_IF_ID_DestReg pipe2_IF_ID_Op pipe2_ID_EX_SrcReg1 pipe2_ID_EX_SrcReg2 pipe2_ID_EX_DestReg pipe2_ID_EX_Op pipe2_EX_MEM_Op pipe2_Data1 pipe2_Data2 pipe2_ALU_Data1 pipe2_ALU_Data2 pipe2_ID_EX_Data1 pipe2_ID_EX_Data2 pipe2_EX_MEM_Data2 pipe2_IF_ID_Imm pipe2_ID_EX_Imm pipe2_Result pipe2_EX_MEM_Result pipe2_EX_MEM_DestReg pipe2_MEM_WB_Result pipe2_MEM_WB_DestReg pipe2_WriteData //For ALU Forwarding pipe1_FwdSelector_WBD1_1 pipe1_FwdSelector_WBD1_2 pipe1_FwdSelector_EXD1_1 pipe1_FwdSelector_EXD1_2 pipe1_FwdSelector_WBD2_1 pipe1_FwdSelector_WBD2_2 pipe1_FwdSelector_EXD2_1 pipe1_FwdSelector_EXD2_2 pipe2_FwdSelector_WBD1_1 pipe2_FwdSelector_WBD1_2 pipe2_FwdSelector_EXD1_1 pipe2_FwdSelector_EXD1_2 pipe2_FwdSelector_WBD2_1 pipe2_FwdSelector_WBD2_2 pipe2_FwdSelector_EXD2_1 pipe2_FwdSelector_EXD2_2 //For Jump and Branch next_PC_1 pipe2_EX_TargetPC pipe2_EX_MEM_TargetPC IF_ID_sequentialPC pipe2_IF_ID_sequentialPC pipe2_ID_EX_sequentialPC pipe2_EX_DAddr ) (input phi1 phi2 phi3 phi4 Flush) // Logic to handle how and when we can issue instructions // We first need to do some housekeeping. We will need to know the // following things in order to safely issue the second instruction: // 1) Is the second instruction going to try to load from // memory? // 2) Is the second instruction going to try to write to // memory? // 3) Is the second instruction dependent on the results // of the first instruction? //Check if we are trying to to a memop in pipe 2 is_Load2pipe2 = (and pipe2_IF_ID_RegWrite pipe2_IF_ID_MemToReg) is_Store2pipe2 = (buf pipe2_IF_ID_MemWrite) //Check for RAW dependencies pipe1_RAW_pipe2_r1 = (= IF_ID_DestReg pipe2_IF_ID_SrcReg1) pipe1_RAW_pipe2_r2 = (= IF_ID_DestReg pipe2_IF_ID_SrcReg2) pipe1_RAW_pipe2_tmp = (or pipe1_RAW_pipe2_r1 pipe1_RAW_pipe2_r2) pipe1_RAW_pipe2 = (and IF_ID_RegWrite pipe1_RAW_pipe2_tmp) //Check for RAW in EX stage pipe1_RAW_pipe2_r1_EX = (= ID_EX_DestReg pipe2_IF_ID_SrcReg1) pipe1_RAW_pipe2_r2_EX = (= ID_EX_DestReg pipe2_IF_ID_SrcReg2) pipe1_RAW_pipe2_EX_tmp = (or pipe1_RAW_pipe2_r1_EX pipe1_RAW_pipe2_r2_EX) pipe1_RAW_pipe2_EX_tmp2 = (and ID_EX_RegWrite ID_EX_MemToReg) pipe1_RAW_pipe2_EX = (and pipe1_RAW_pipe2_EX_tmp pipe1_RAW_pipe2_EX_tmp2) //As long as we are not stalling, branching, or jumping, we can issue to pipe 1 IF_ID_is_Jump_bar = (not IF_ID_is_Jump) IF_ID_is_Branch_bar = (not IF_ID_is_Branch) issue_ID1_to_EX1 = (and ID_Stall_bar IF_ID_is_Jump_bar IF_ID_is_Branch_bar) issue_ID1_to_EX1_bar = (not issue_ID1_to_EX1) //Pipe 2 is more complicated. If it is a memory operation or if the //instruction is dependent on the first instruction, we cannot issue //it. Of course if we are stalling then we can't issue either. ID2_is_Load_or_Store = (or is_Load2pipe2 is_Store2pipe2) issue_ID2_to_EX2 = (not issue_ID2_to_EX2_bar) issue_ID2_to_EX2_bar = (or ID_Stall ID2_is_Load_or_Store issue_ID1_to_EX2 pipe1_RAW_pipe2 pipe1_RAW_pipe2_EX) //We might have to cross up the pipes if there is a jump instruction //that is trying to be issued to pipe1. Since the spec only defines //that pipe 2 can do jumps we need to fix this potential problem. ID1_isJumpOrBranch = (or IF_ID_is_Jump IF_ID_is_Branch) ID2_isJumpOrBranch = (or pipe2_IF_ID_is_Jump pipe2_IF_ID_is_Branch) ID2_isJumpOrBranch_bar = (not ID2_isJumpOrBranch) issue_ID1_to_EX2 = (and ID_Stall_bar ID1_isJumpOrBranch) issue_ID1_to_EX2_bar = (not issue_ID1_to_EX2) // IF Stage Logic // ============================================ //--- Define the PC as a nontransparent latch Flush_bar = (not Flush) //Logic to stall the PC if we are inserting bubbles into the pipeline ID1_is_issued = (or issue_ID1_to_EX1 issue_ID1_to_EX2) stall_PC = (and Flush_bar ID1_is_issued) write_PC1 = (or squash_instructions stall_PC) write_PC = (and phi4 write_PC1) issued_both_inst = (and issue_ID1_to_EX1 issue_ID2_to_EX2 ) next_PC_1 = (mux issued_both_inst next_sequential_PC sequentialPC) next_PC = (mux squash_instructions pipe2_EX_MEM_TargetPC next_PC_1) (latch PC PC // memory definition name (inport write_PC (next_PC) ) (outport phi1 (PC) ) ) sequentialPC = (PCAdder PC) next_sequential_PC = (PCAdder sequentialPC) //--- Define the instruction memory (memory IMem IMem // memory definition name (outport phi2 PC (SrcReg1 SrcReg2 DestReg Op RegWrite Imm use_Imm MemWrite is_Jump is_Branch MemToReg) ) (outport phi2 sequentialPC (pipe2_SrcReg1 pipe2_SrcReg2 pipe2_DestReg pipe2_Op pipe2_RegWrite pipe2_Imm pipe2_use_Imm pipe2_MemWrite pipe2_is_Jump pipe2_is_Branch pipe2_MemToReg) ) ) // Handle flush of pipeline for RegWrites IF_RegWrite = (and RegWrite Flush_bar squash_instructions_bar) // Handle flush of pipeline for MemWrites IF_MemWrite = (and MemWrite Flush_bar squash_instructions_bar) // Handle flush of pipeline for Jumps IF_is_Jump = (and is_Jump Flush_bar squash_instructions_bar) // Handle flush of pipeline for Branches IF_is_Branch = (and is_Branch Flush_bar squash_instructions_bar) // Handle flush of pipeline2 for RegWrites pipe2_IF_RegWrite = (and pipe2_RegWrite Flush_bar squash_instructions_bar) // Handle flush of pipeline2 for MemWrites pipe2_IF_MemWrite = (and pipe2_MemWrite Flush_bar squash_instructions_bar) // Handle flush of pipeline2 for Jumps pipe2_IF_is_Jump = (and pipe2_is_Jump Flush_bar squash_instructions_bar) // Handle flush of pipeline2 for Branches pipe2_IF_is_Branch = (and pipe2_is_Branch Flush_bar squash_instructions_bar) // ID Stage Logic // ============================================ //"If the first instruction in Decode is issued but not the second, //then the second instruction moves to the ID slot of the first //pipeline, and the processor fetches only one new instruction that //goes into the ID slot of the second pipeline" do_issue_ID1 = (or ID1_is_issued squash_instructions) do_issue_ID2 = (or issue_ID2_to_EX2 squash_instructions) do_issue_ID2_bar = (not do_issue_ID2) issue_both_instructions_at_ID = (and phi4 do_issue_ID1 do_issue_ID2) issue_1_instruction_at_ID = (and phi4 do_issue_ID1 do_issue_ID2_bar) //--- Define the IF/ID latch (latch IF_ID IF_ID // memory definition name (inport issue_both_instructions_at_ID ( //Issue new instruction into Pipe 1 SrcReg1 SrcReg2 DestReg Op IF_RegWrite Imm use_Imm IF_MemWrite MemToReg IF_is_Jump IF_is_Branch sequentialPC //Issue new instruction into Pipe 2 pipe2_SrcReg1 pipe2_SrcReg2 pipe2_DestReg pipe2_Op pipe2_IF_RegWrite pipe2_Imm pipe2_use_Imm pipe2_IF_MemWrite pipe2_MemToReg pipe2_IF_is_Jump pipe2_IF_is_Branch next_sequential_PC ) ) (inport issue_1_instruction_at_ID ( //Since we execute in program order, we bring in the instruction //fetched in the last step (It is in pipe 2 during this cycle) pipe2_IF_ID_SrcReg1 pipe2_IF_ID_SrcReg2 pipe2_IF_ID_DestReg pipe2_IF_ID_Op pipe2_IF_ID_RegWrite pipe2_IF_ID_Imm pipe2_IF_ID_use_Imm pipe2_IF_ID_MemWrite pipe2_IF_ID_MemToReg pipe2_IF_ID_is_Jump pipe2_IF_ID_is_Branch pipe2_IF_ID_sequentialPC SrcReg1 SrcReg2 DestReg Op IF_RegWrite Imm use_Imm IF_MemWrite MemToReg IF_is_Jump IF_is_Branch sequentialPC ) ) (outport phi1 (IF_ID_SrcReg1 IF_ID_SrcReg2 IF_ID_DestReg IF_ID_Op IF_ID_RegWrite IF_ID_Imm IF_ID_use_Imm IF_ID_MemWrite IF_ID_MemToReg IF_ID_is_Jump IF_ID_is_Branch IF_ID_sequentialPC pipe2_IF_ID_SrcReg1 pipe2_IF_ID_SrcReg2 pipe2_IF_ID_DestReg pipe2_IF_ID_Op pipe2_IF_ID_RegWrite pipe2_IF_ID_Imm pipe2_IF_ID_use_Imm pipe2_IF_ID_MemWrite pipe2_IF_ID_MemToReg pipe2_IF_ID_is_Jump pipe2_IF_ID_is_Branch pipe2_IF_ID_sequentialPC ) ) ) //--- Define the register file write_RegFile_In = (and phi2 MEM_WB_RegWrite) pipe2_write_RegFile_In = (and phi2 pipe2_MEM_WB_RegWrite) (memory RegFile RegFile // memory definition name (inport write_RegFile_In MEM_WB_DestReg (WriteData) ) (inport pipe2_write_RegFile_In pipe2_MEM_WB_DestReg (pipe2_WriteData) ) (outport phi3 IF_ID_SrcReg1 (Data1) ) (outport phi3 IF_ID_SrcReg2 (Data2) ) (outport phi3 pipe2_IF_ID_SrcReg1 (pipe2_Data1) ) (outport phi3 pipe2_IF_ID_SrcReg2 (pipe2_Data2) ) ) //Load-Interlock Logic - Based on information obtained on page A-34 of //H+P //Check if load destination register is one of the source registers //in ID ID_StallReg1 = (= IF_ID_SrcReg1 ID_EX_DestReg) ID_StallReg2 = (= IF_ID_SrcReg2 ID_EX_DestReg) //If it is in either case, we might have to stall ID_StallReg = (or ID_StallReg1 ID_StallReg2) //Check if we will be saving the result, we will need to stall ID_WriteResult = (or IF_ID_RegWrite IF_ID_MemWrite IF_ID_is_Branch IF_ID_is_Jump) //Check if the result in the EX stage will be saved to both memory and //to a register file. If it will not be saved to a register, there is //no reason to stall the pipeline EX_WriteResult = (and ID_EX_RegWrite ID_EX_MemToReg) //If we will be saving the result of the op in the ID stage and the op //in the EX stage will be written to memory, we will stall ID_StallTmp = (and ID_StallReg ID_WriteResult) ID_Stall = (and ID_StallTmp EX_WriteResult) ID_Stall_bar = (not ID_Stall) //If we have to stall, we need to insert a bubble in the pipeline. //This can be done by not writing back an operation to either the //registers or the memory ID1_squash_bar = (and issue_ID1_to_EX1 squash_instructions_bar) ID1_ID2_squash_bar = (and issue_ID1_to_EX2 squash_instructions_bar) ID2_squash_bar = (and issue_ID2_to_EX2 squash_instructions_bar) ID_MemWrite = (and IF_ID_MemWrite ID1_squash_bar) ID_RegWrite = (and IF_ID_RegWrite ID1_squash_bar) pipe2_ID_MemWrite = (and pipe2_IF_ID_MemWrite ID2_squash_bar) pipe2_ID_RegWrite = (and pipe2_IF_ID_RegWrite ID2_squash_bar) ID2_RegWrite = (and IF_ID_RegWrite ID1_ID2_squash_bar) ID2_is_Jump = (and IF_ID_is_Jump ID1_ID2_squash_bar) ID2_is_Branch = (and IF_ID_is_Branch ID1_ID2_squash_bar) pipe2_ID_is_Jump = (and pipe2_IF_ID_is_Jump ID2_squash_bar) pipe2_ID_is_Branch = (and pipe2_IF_ID_is_Branch ID2_squash_bar) // EX Stage Logic // ============================================ ID_EX_enable1 = (and phi4 issue_ID1_to_EX2) ID_EX_enable2 = (and phi4 issue_ID1_to_EX2_bar) //--- Define the ID/EX latch (latch ID_EX ID_EX // memory definition name (inport ID_EX_enable1 (IF_ID_SrcReg1 IF_ID_SrcReg2 IF_ID_DestReg IF_ID_Op ID_RegWrite Data1 Data2 IF_ID_Imm IF_ID_use_Imm ID_MemWrite IF_ID_MemToReg IF_ID_SrcReg1 IF_ID_SrcReg2 IF_ID_DestReg IF_ID_Op ID2_RegWrite Data1 Data2 IF_ID_Imm IF_ID_use_Imm ID2_is_Jump ID2_is_Branch IF_ID_sequentialPC ) ) (inport ID_EX_enable2 (IF_ID_SrcReg1 IF_ID_SrcReg2 IF_ID_DestReg IF_ID_Op ID_RegWrite Data1 Data2 IF_ID_Imm IF_ID_use_Imm ID_MemWrite IF_ID_MemToReg pipe2_IF_ID_SrcReg1 pipe2_IF_ID_SrcReg2 pipe2_IF_ID_DestReg pipe2_IF_ID_Op pipe2_ID_RegWrite pipe2_Data1 pipe2_Data2 pipe2_IF_ID_Imm pipe2_IF_ID_use_Imm pipe2_ID_is_Jump pipe2_ID_is_Branch pipe2_IF_ID_sequentialPC ) ) (outport phi1 (ID_EX_SrcReg1 ID_EX_SrcReg2 ID_EX_DestReg ID_EX_Op ID_EX_RegWrite ID_EX_Data1 ID_EX_Data2 ID_EX_Imm ID_EX_use_Imm ID_EX_MemWrite ID_EX_MemToReg pipe2_ID_EX_SrcReg1 pipe2_ID_EX_SrcReg2 pipe2_ID_EX_DestReg pipe2_ID_EX_Op pipe2_ID_EX_RegWrite pipe2_ID_EX_Data1 pipe2_ID_EX_Data2 pipe2_ID_EX_Imm pipe2_ID_EX_use_Imm pipe2_ID_EX_is_Jump pipe2_ID_EX_is_Branch pipe2_ID_EX_sequentialPC ) ) ) //Forwarding logic for Pipe 1 //Forwarding logic for data 1 //Forwarding logic for MEM stage pipe1_RegsEqual_MEMD1_P1 = (= ID_EX_SrcReg1 EX_MEM_DestReg) pipe1_RegsEqual_MEMD1_P2 = (= ID_EX_SrcReg1 pipe2_EX_MEM_DestReg) pipe1_fwd_MEMD1_P1 = (and EX_MEM_RegWrite pipe1_RegsEqual_MEMD1_P1) pipe1_fwd_MEMD1_P2 = (and pipe2_EX_MEM_RegWrite pipe1_RegsEqual_MEMD1_P2) //Forwarding logic for WB stage pipe1_RegsEqual_WBD1_P1 = (= ID_EX_SrcReg1 MEM_WB_DestReg) pipe1_RegsEqual_WBD1_P2 = (= ID_EX_SrcReg1 pipe2_MEM_WB_DestReg) pipe1_fwd_WBD1_P1 = (and MEM_WB_RegWrite pipe1_RegsEqual_WBD1_P1) pipe1_fwd_WBD1_P2 = (and pipe2_MEM_WB_RegWrite pipe1_RegsEqual_WBD1_P2) //Select Forwarded data or New Data pipe1_FwdSelector_WBD1_1 = (mux pipe1_fwd_WBD1_P1 WriteData ID_EX_Data1) pipe1_FwdSelector_WBD1_2 = (mux pipe1_fwd_WBD1_P2 pipe2_WriteData pipe1_FwdSelector_WBD1_1) pipe1_FwdSelector_EXD1_1 = (mux pipe1_fwd_MEMD1_P1 EX_MEM_Result pipe1_FwdSelector_WBD1_2) pipe1_FwdSelector_EXD1_2 = (mux pipe1_fwd_MEMD1_P2 pipe2_EX_MEM_Result pipe1_FwdSelector_EXD1_1) ALU_Data1 = (buf pipe1_FwdSelector_EXD1_2) //Forwarding logic for data 2 //Forwarding logic for MEM stage pipe1_RegsEqual_MEMD2_P1 = (= ID_EX_SrcReg2 EX_MEM_DestReg) pipe1_RegsEqual_MEMD2_P2 = (= ID_EX_SrcReg2 pipe2_EX_MEM_DestReg) pipe1_fwd_MEMD2_P1 = (and EX_MEM_RegWrite pipe1_RegsEqual_MEMD2_P1) pipe1_fwd_MEMD2_P2 = (and pipe2_EX_MEM_RegWrite pipe1_RegsEqual_MEMD2_P2) //Forwarding logic for WB stage pipe1_RegsEqual_WBD2_P1 = (= ID_EX_SrcReg2 MEM_WB_DestReg) pipe1_RegsEqual_WBD2_P2 = (= ID_EX_SrcReg2 pipe2_MEM_WB_DestReg) pipe1_fwd_WBD2_P1 = (and MEM_WB_RegWrite pipe1_RegsEqual_WBD2_P1) pipe1_fwd_WBD2_P2 = (and pipe2_MEM_WB_RegWrite pipe1_RegsEqual_WBD2_P2) //Select Forwarded data or New Data pipe1_FwdSelector_WBD2_1 = (mux pipe1_fwd_WBD2_P1 WriteData ID_EX_Data2) pipe1_FwdSelector_WBD2_2 = (mux pipe1_fwd_WBD2_P2 pipe2_WriteData pipe1_FwdSelector_WBD2_1) pipe1_FwdSelector_EXD2_1 = (mux pipe1_fwd_MEMD2_P1 EX_MEM_Result pipe1_FwdSelector_WBD2_2) pipe1_FwdSelector_EXD2_2 = (mux pipe1_fwd_MEMD2_P2 pipe2_EX_MEM_Result pipe1_FwdSelector_EXD2_1) ALU_Data2 = (mux ID_EX_use_Imm ID_EX_Imm pipe1_FwdSelector_EXD2_2) EX_DestAddr = (buf pipe1_FwdSelector_EXD2_2) //Forwarding logic for Pipe 2 //Forwarding logic for data 1 //Forwarding logic for MEM stage pipe2_RegsEqual_MEMD1_P1 = (= pipe2_ID_EX_SrcReg1 EX_MEM_DestReg) pipe2_RegsEqual_MEMD1_P2 = (= pipe2_ID_EX_SrcReg1 pipe2_EX_MEM_DestReg) pipe2_fwd_MEMD1_P1 = (and EX_MEM_RegWrite pipe2_RegsEqual_MEMD1_P1) pipe2_fwd_MEMD1_P2 = (and pipe2_EX_MEM_RegWrite pipe2_RegsEqual_MEMD1_P2) //Forwarding logic for WB stage pipe2_RegsEqual_WBD1_P1 = (= pipe2_ID_EX_SrcReg1 MEM_WB_DestReg) pipe2_RegsEqual_WBD1_P2 = (= pipe2_ID_EX_SrcReg1 pipe2_MEM_WB_DestReg) pipe2_fwd_WBD1_P1 = (and MEM_WB_RegWrite pipe2_RegsEqual_WBD1_P1) pipe2_fwd_WBD1_P2 = (and pipe2_MEM_WB_RegWrite pipe2_RegsEqual_WBD1_P2) //Select Forwarded data or New Data pipe2_FwdSelector_WBD1_1 = (mux pipe2_fwd_WBD1_P1 WriteData pipe2_ID_EX_Data1) pipe2_FwdSelector_WBD1_2 = (mux pipe2_fwd_WBD1_P2 pipe2_WriteData pipe2_FwdSelector_WBD1_1) pipe2_FwdSelector_EXD1_1 = (mux pipe2_fwd_MEMD1_P1 EX_MEM_Result pipe2_FwdSelector_WBD1_2) pipe2_FwdSelector_EXD1_2 = (mux pipe2_fwd_MEMD1_P2 pipe2_EX_MEM_Result pipe2_FwdSelector_EXD1_1) pipe2_ALU_Data1 = (buf pipe2_FwdSelector_EXD1_2) //Forwading logic for data 2 //Forwarding logic for MEM stage pipe2_RegsEqual_MEMD2_P1 = (= pipe2_ID_EX_SrcReg2 EX_MEM_DestReg) pipe2_RegsEqual_MEMD2_P2 = (= pipe2_ID_EX_SrcReg2 pipe2_EX_MEM_DestReg) pipe2_fwd_MEMD2_P1 = (and EX_MEM_RegWrite pipe2_RegsEqual_MEMD2_P1) pipe2_fwd_MEMD2_P2 = (and pipe2_EX_MEM_RegWrite pipe2_RegsEqual_MEMD2_P2) //Forwarding logic for WB stage pipe2_RegsEqual_WBD2_P1 = (= pipe2_ID_EX_SrcReg2 MEM_WB_DestReg) pipe2_RegsEqual_WBD2_P2 = (= pipe2_ID_EX_SrcReg2 pipe2_MEM_WB_DestReg) pipe2_fwd_WBD2_P1 = (and MEM_WB_RegWrite pipe2_RegsEqual_WBD2_P1) pipe2_fwd_WBD2_P2 = (and pipe2_MEM_WB_RegWrite pipe2_RegsEqual_WBD2_P2) //Select Forwarded data or New Data pipe2_FwdSelector_WBD2_1 = (mux pipe2_fwd_WBD2_P1 WriteData pipe2_ID_EX_Data2) pipe2_FwdSelector_WBD2_2 = (mux pipe2_fwd_WBD2_P2 pipe2_WriteData pipe2_FwdSelector_WBD2_1) pipe2_FwdSelector_EXD2_1 = (mux pipe2_fwd_MEMD2_P1 EX_MEM_Result pipe2_FwdSelector_WBD2_2) pipe2_FwdSelector_EXD2_2 = (mux pipe2_fwd_MEMD2_P2 pipe2_EX_MEM_Result pipe2_FwdSelector_EXD2_1) pipe2_EX_DAddr = (buf pipe2_FwdSelector_EXD2_2) pipe2_ALU_Data2 = (mux pipe2_ID_EX_use_Imm pipe2_ID_EX_Imm pipe2_FwdSelector_EXD2_2) Result = (ALU ID_EX_Op ALU_Data1 ALU_Data2) pipe2_Result = (ALU pipe2_ID_EX_Op pipe2_ALU_Data1 pipe2_ALU_Data2) //Jump and Branch computation (hardware is only in pipe 2) pipe2_EX_TargetPC = (SelectTargetPC pipe2_ID_EX_Op pipe2_ALU_Data1 pipe2_ID_EX_sequentialPC) pipe2_EX_TakeBranch = (TakeBranchALU pipe2_ID_EX_Op pipe2_ALU_Data1 pipe2_EX_DAddr) pipe2_EX_is_taken_branch = (and pipe2_EX_TakeBranch pipe2_ID_EX_is_Branch) pipe2_EX_use_TargetPC = (or pipe2_EX_is_taken_branch pipe2_ID_EX_is_Jump) //Handle Squashing EX stage instructions EX_RegWrite = (and ID_EX_RegWrite squash_instructions_bar) EX_MemWrite = (and ID_EX_MemWrite squash_instructions_bar) EX_useTargetPC = (and pipe2_EX_use_TargetPC squash_instructions_bar) pipe2_EX_RegWrite = (and pipe2_ID_EX_RegWrite squash_instructions_bar) // MEM Stage Logic // ============================================ //--- Define the ID/EX latch (latch EX_MEM EX_MEM // memory definition name (inport phi4 (Result ID_EX_DestReg EX_RegWrite EX_MemWrite EX_DestAddr ID_EX_Op ID_EX_MemToReg pipe2_Result pipe2_ID_EX_DestReg pipe2_EX_RegWrite EX_useTargetPC pipe2_EX_TargetPC ) ) (outport phi1 (EX_MEM_Result EX_MEM_DestReg EX_MEM_RegWrite EX_MEM_MemWrite EX_MEM_DestAddr EX_MEM_Op EX_MEM_MemToReg pipe2_EX_MEM_Result pipe2_EX_MEM_DestReg pipe2_EX_MEM_RegWrite pipe2_EX_MEM_use_TargetPC pipe2_EX_MEM_TargetPC ) ) ) //--- The data memory, abstracted as a finite state machine // that does not satisfy the forwarding property of the // memory semantics write_DMem_In = (and phi4 EX_MEM_MemWrite) (latch DMem DMem // memory definition name (inport write_DMem_In (NextMemState) ) (outport phi1 (PresentMemState) ) ) //--- the next memory state will depend on // -PresentMemState, the present state of the data memory // -Result, the ALU Result (e.g., used as address) // -Data2, the data to be written to that address // -Op, the opcode, as specifying the type of the store // in order to be able to model byte-accesses NextMemState = (DMem_Update PresentMemState EX_MEM_Result EX_MEM_DestAddr EX_MEM_Op) //--- model a read from address Result of the Data Memory; // the opcode, Op, allows us to model byte-accesses ReadData = (DMem_Read PresentMemState EX_MEM_Result EX_MEM_Op) //Handle squashing of jumps and branches squash_instructions = (buf pipe2_EX_MEM_use_TargetPC) squash_instructions_bar = (not squash_instructions) // WB Stage Logic // ============================================ (latch MEM_WB MEM_WB // memory definition name (inport phi4 (EX_MEM_DestReg EX_MEM_RegWrite EX_MEM_Result ReadData EX_MEM_MemToReg pipe2_EX_MEM_Result pipe2_EX_MEM_DestReg pipe2_EX_MEM_RegWrite ) ) (outport phi1 (MEM_WB_DestReg MEM_WB_RegWrite MEM_WB_Result MEM_WB_ReadData MEM_WB_MemToReg pipe2_MEM_WB_Result pipe2_MEM_WB_DestReg pipe2_MEM_WB_RegWrite ) ) ) WriteData = (mux MEM_WB_MemToReg MEM_WB_ReadData MEM_WB_Result) pipe2_WriteData = (buf pipe2_MEM_WB_Result)