📄 ex.v
字号:
`timescale 1ns/10ps`include "pardef"/*****************************************************************************$RCSfile: ex.v,v $$Revision: 1.6 $$Author: kohlere $$Date: 2000/04/17 18:12:48 $$State: Exp $$Source: /home/lefurgy/tmp/ISC-repository/isc/hardware/ARM10/behavioral/pipelined/fpga2/ex.v,v $Description: This is the Execution Stage of the Pipeline. It contains the Shifter, ALU, and PSR's. Note: In the earlier versions, I saved the RF address decode until the registers were accessed. This was going to cause problems for instructions that had different modes when it came to writing and forwarding data. Now that I decode the address in the ID stage, any place where I was using Rn[0] as a bit of the instruction is wrong. However, due to the fortunate nature of my coding scheme, any register with and even address will always map to an even addressed register and vice versa, so the decoded register address bit 0 will be equal to the intruction register address bit 0.*****************************************************************************/module ex(nGCLK, nWAIT, nRESET, ex_enbar, op1_in, op2_in, alu_opcode_in, addr_me, condition_in, shift_amount_in, shift_type_in, ir_id, Rd_id, Rn_id, id_second, need_2cycles_id, inst_type_in, s_id, ex_result, store_addr, Rd_ex, Rn_ex, second_ex, inst_type_ex, mode, signed_byte_ex, write_Rd_ex, write_Rn_ex, unsigned_byte_ex, aux_data_id, unsigned_hw_ex, signed_hw_ex, base_ex, mul_first_id, double_id, double_ex, double_me, cpsr_flags, load_use_id, cop_mem_id, pc_mod_ex, hold_next_ex, mcr_ex, cop_mem_ld, store_ex, mispredicted, exc_code, load_pc_ex, cop_mem_st, fiq_disable, irq_disable, exception, write_Pc_Rn, write_Pc_Rd, DnMREQ, PASS, DnWR, stop_id, stop_ex);/*------------------------------------------------------------------------ Ports------------------------------------------------------------------------*/input [31:0] op1_in; //OP1 from ID stageinput [31:0] op2_in; //OP2 from ID stageinput [31:0] aux_data_id; //Auxillary Data from ID stageinput [31:0] addr_me; //Address from ME stageinput [7:0] shift_amount_in; //Shift by this amountinput [4:0] Rd_id; //First(Main) Destination Registerinput [4:0] Rn_id; //Second Destination Registerinput [3:0] alu_opcode_in; //Alu Opcodeinput [3:0] condition_in; //Condition of Executioninput [3:0] inst_type_in; //Instruction Codeinput [2:0] shift_type_in; //Shift Controlsinput [6:4] ir_id; //Bits 6-5 of Irinput [1:0] exc_code; //Which Exceptioninput nGCLK; //clock signalinput nWAIT; //clock enableinput nRESET; //reset signalinput exception; //Take Exceptioninput ex_enbar; //EX stage enable (active low)input id_second; //ID Stage in Second Cycleinput need_2cycles_id; //Need_2cycles For this instructioninput load_use_id; //Need_2cycles due to Load Useinput s_id; //S Bit of Instructioninput mul_first_id; //First Cycle of LDM/STMinput double_id; //64-bit Memory Accessinput double_me; //Inc by 4 or 8?input cop_mem_id; //Coprocessor requiring Memoryinput mispredicted; //Mispredicted Branchinput stop_id; //Stop Executionoutput [31:0] ex_result; //Result of Executionoutput [31:0] store_addr; //Usually Addressoutput [31:0] base_ex; //Base Addressoutput [4:0] mode; //Current Processor Modeoutput [4:0] Rd_ex; //Latched Fisrt Destination Regoutput [4:0] Rn_ex; //Latched Second Destination Regoutput [3:0] cpsr_flags; //Flags from CPSRoutput [3:0] inst_type_ex; //Instruction Codeoutput write_Pc_Rd; //Inst May Write PC in Rd fieldoutput write_Pc_Rn; //Inst May Write PC in Rn fieldoutput fiq_disable; //FIQ's Disabled (CPSR[6])output irq_disable; //IRQ's Disabled (CPSR[6])output second_ex; //Second Cycle of Instructionoutput store_ex; //Inst should Store in ME cycleoutput write_Rn_ex; //Write Back Signaloutput write_Rd_ex; //Write to Destination?output unsigned_byte_ex; //Inst uses Unsigned bytesoutput signed_byte_ex; //Inst uses Signed Bytesoutput unsigned_hw_ex; //Inst uses Unsigned Halfwords output signed_hw_ex; //Inst uses Signed Halfwordsoutput double_ex; //64-bit Memory Accessoutput pc_mod_ex; //One of last two inst modified pcoutput load_pc_ex; //Load to the PCoutput hold_next_ex; //Ex Stage requires another cycleoutput mcr_ex; //Ex Stage has MCRoutput cop_mem_ld; //Coprocessor Performing a Loadoutput cop_mem_st; //Coprocessor Performing a Storeoutput PASS; //Coprocessor should executeoutput DnMREQ; //Data Not Memory Requestoutput DnWR; //Data Not Write Readoutput stop_ex; //Stop Execution/*------------------------------------------------------------------------ Variable Declarations------------------------------------------------------------------------*///Declare Outputs of Combinational Logicwire [63:0] mult_result; //Output from Multiplierwire [63:0] acc_op1; //Mult Op1 to Addwire [63:0] acc_op2; //Mult Op2 to Addwire [63:0] alu_op1; //Op1 to ALUwire [63:0] alu_op2; //Op2 to ALUwire [31:0] upper_mult; //Output from Upper Adderwire [31:0] alu_result; //Output from ALUwire [31:0] shifted_op2; //Output from Shifterwire [31:0] inc_add; //Incremented Addresswire [4:0] mode; //Processor Modewire [3:0] cpsr_flags; //CPSR[31:28]wire [3:0] alu_flags; //Flags from ALU wire [2:0] spsr_index; //SPSR Indexwire [1:0] mult_flags; //Mult Flags (N,Z)wire fiq_disable; //CPSR[6]wire irq_disable; //CPSR[7]wire store_ex; //Want to Store On next Cyclewire signed_byte_ex; //Inst uses Signed Byteswire unsigned_byte_ex; //Inst uses Unsigned Byteswire signed_hw_ex; //Inst uses Signed Halfwordswire unsigned_hw_ex; //Inst uses Unsigned Halfwordswire shift_c_out; //Shifter Carry Outputwire multiply; //MUL/MULL instwire mult_res; //Multiplier Resetwire cop_mem_ld; //Coprocessor going to Loadwire cop_mem_st; //Coprocessor going to Stallwire inst_exception; //SWI or UNDwire alu; //ALU instwire str; //STRW/STRH instwire ldr; //LDRW/LDRH instwire branch; //BR/BL instwire swap; //Swap instwire mrs; //MRS instwire und; //Undefined Instwire swi; //SWI Instwire msr; //MSR instwire mrc; //MRC instwire mcr_ex; //MCR instwire ldm; //LDM instwire stm; //STM instwire load; //Inst is a Loadwire load_pc_ex; //Inst is a Load to the PCwire N; //N Flag from CPSRwire Z; //Z Flag from CPSRwire C; //C Flag from CPSRwire V; //V Flag from CPSRwire write_Rn_ex; //Write Back Base?wire u; //Inc/Decwire write_Rd_ex; //Write to Rd?wire write_Pc_Rn; //Write to PC (Rn)wire write_Pc_Rd; //Write to PC (Rd)wire r15_inlist; //R15 in Transfer Listwire rd_pc; //Rd is the PCwire alu_no_wb; //Alu Inst with No WBwire no_writes; //No Write Back this Cyclewire link; //Link on Branches?wire long; //Long Multiply Requiredwire acc; //Accumulatewire cdp; //Coprocessor Data Operationwire mrcmcr; //Coprocessor Register Transferwire pc_mod_ex; //One of Last 2 inst modified pcwire hold_next_ex; //Disable Registers for Next Cyclewire ex_mod_pc; //PC will be modifiedwire cpsr_disable; //Write to CPSR?wire DnMREQ; //Data Access next Cyclewire DnWR; //Data Not Write Read//Declare Outputs of Multiplexers and Registersreg [31:0] ex_result; //Final Muxed Resultreg [31:0] store_addr; //Address to be stored/loadedreg [31:0] aux_data_ex; //Auxillary Data reg [31:0] CPSR; //Current Program Status Reg.reg [31:0] spsr_fiq; //Saved Program Status Registerreg [31:0] spsr_svc; //Saved Program Status Registerreg [31:0] spsr_abt; //Saved Program Status Registerreg [31:0] spsr_irq; //Saved Program Status Registerreg [31:0] spsr_und; //Saved Program Status Registerreg [31:0] op1; //First Operand Registerreg [31:0] op2; //Second Operand Registerreg [31:0] psr; //CPSR/SPSR for MRS Instructionsreg [31:0] next_cpsr; //Next Value to load into CPSRreg [31:0] next_spsr; //Next Value to load into SPSRreg [31:0] flg_all_spsr; //Muxed value from Shifted_Op2reg [31:0] current_spsr; //Current SPSRreg [31:0] base_ex; //Base Value for Post-Indexedreg [31:0] cpsr_const; //Possible Next CPSR Constant Valuereg [7:0] increment; //4/8 for LDM/STM'sreg [31:0] addr_2b_inc; //Input Address to Incrementerreg [7:0] shift_amount; //Shift Amount Register reg [4:0] Rd_ex; //First Destination Regreg [4:0] Rn_ex; //Second Destination Regreg [3:0] inst_type_ex; //Latched Instr. Codereg [3:0] condition; //Condition of Executionreg [3:0] alu_opcode; //Opcode from ID Stagereg [3:0] opcode; //Multiplexed Opcode (LD/ST)reg [3:0] flags_from_alu; //Flags From ALU/SHIFTERreg [3:0] early_flags; //Flags Available Earlyreg [2:0] shift_type; //Shift Control Registerreg [2:0] write_spsr_index; //Indicates which SPSR to updatereg [6:4] ir_ex; //IR bits 6-5reg [1:0] exc_code_ex; //Exception Codereg exception_ex; //Exceptionreg was_disabled; //Last Inst was squashedreg second_ex; //Second Cycle of Instructionreg need_2cycles_ex; //Need 2 cycles for Current instreg load_use_ex; //Need 2 cycles due to Load Usereg cond_failed_ex; //Inst Does Not Meet Conditionreg s; //S-Bit of Instructionreg stop_ex; //Stop Executionreg mul_first_ex; //First Cycle of LDM/STMreg double_ex; //64-bit Memory Accessreg latched_nRESET; //One cycle delayedreg cop_mem_ex; //Cop. Inst requiring Memoryreg me_mod_pc; //PC to be modified by inst in MEreg ldc_stc; //LDC/STC instreg PASS; //Cop. should Execute Inst./*------------------------------------------------------------------------ Basic Assignments------------------------------------------------------------------------*///Detect several types of instructionsassign swap = (inst_type_ex == `SWAP);assign multiply = ((inst_type_ex == `MUL) || (inst_type_ex == `MULL));assign mult_res = (cond_failed_ex | me_mod_pc | was_disabled | load_use_ex | mispredicted | !nRESET);assign alu_op1 = (multiply) ? acc_op1 : {32'h00000000,op1};assign alu_op2 = (multiply) ? acc_op2 : {32'h00000000,shifted_op2};assign alu = (inst_type_ex == `ALU);assign str = ((inst_type_ex == `STRW) || (inst_type_ex == `STRH));assign ldr = ((inst_type_ex == `LDRW) || (inst_type_ex == `LDRH));assign branch = (inst_type_ex == `BR);assign mrs = (inst_type_ex == `MRS);assign msr = (inst_type_ex == `MSR);assign link = alu_opcode[3];assign long = (inst_type_ex == `MULL);assign ldm = (inst_type_ex == `LDM);assign stm = (inst_type_ex == `STM);assign acc = (alu_opcode[0]);assign und = (inst_type_ex == `UND);assign swi = (inst_type_ex == `SWI);assign fiq_disable = CPSR[6];assign irq_disable = CPSR[7];assign cop_mem_ld = cop_mem_ex & s;assign cop_mem_st = cop_mem_ex & ~s & ~alu_opcode[1];assign inst_exception = und | swi;assign mult_result = {upper_mult,alu_result};assign pc_mod_ex = me_mod_pc | (write_Pc_Rn && (Rn_ex == 5'h0F)) | (write_Pc_Rd && (Rd_ex == 5'h0F));assign #1 cpsr_flags = CPSR[31:28];assign N = CPSR[31];assign Z = CPSR[30];assign C = CPSR[29];assign V = CPSR[28];assign mult_flags[1] = (long) ? mult_result[63] : mult_result[31];assign mult_flags[0] = (long) ? (~(| mult_result[63:32]) & alu_flags[2]) : alu_flags[2];//This will detect the CDP Instructionassign cdp = ((inst_type_ex == `COP) && (!ir_ex[4]));//This will detect an MRC or MCRassign mrcmcr = ((inst_type_ex == `COP) && (ir_ex[4]));//This will determine the MRCassign mrc = mrcmcr & s;//This will determine the MCRassign mcr_ex = mrcmcr & ~s;//This is the address incrementer...its a 32'bit adder. Maybe better//if the increment is just 4 bits?assign inc_add = addr_2b_inc + {{24{increment[7]}},increment};//The TEQ, TST, CMN, and CMP Instructions do not write back//the results of the instruction to Rdassign alu_no_wb = ((opcode == `TEQ) || (opcode == `TST) || (opcode == `CMN) || (opcode == `CMP));//There is usually no need to write to Rd on the 1st//Cycle of instructions requiring two cycles.assign no_writes = (need_2cycles_ex & !second_ex & !swap) | (load_use_ex);//Write the Base Back on Long Multiplies (mult_res[63:32) and //any ldr/str with write back bit set. WB is implied on ldr/str with//post index addressing. Also write back the base (R14)//on BL instructions. No writeback for non-executed instructions.//Also write back for LDC/STC with W-Bit set// write_Rn_ex = (fail)' . (bl + (cop_mem_ex . w) + ((ldm + stm).mul_first) // + (ldm.double) + und + // (nw' . (MULL + ((ldr + str).ao[0])))) //Might not need to base writeback in exceptions *******assign write_Rn_ex = exception_ex | (!cond_failed_ex & !was_disabled & !hold_next_ex & ((branch & link) | (und) | (swi) | (cop_mem_ex & alu_opcode[0]) | (ldm & double_ex) | (mul_first_ex & alu_opcode[0]) | (!no_writes & ((long) | ((ldr | str) & (alu_opcode[0] | !alu_opcode[3]))))));//Write to PC where Rn = PC//Ignore from multiplies, mrc (only updates flags), mrs, swap, bl, und, //swi, ldr, cop_mem (ldc, stc) //For above instruction, Rn should never be R15 (PC)//This is only a signal that indicates that PC may be written,//Rn must still be compared to PCassign write_Pc_Rn = !cond_failed_ex & !was_disabled & (ldm & double_ex);//Write to Rd if the condition passes and there is a branch, or//on the 1st cycle of a swap or on the final cycle of a //mul/ldr/alu (wb specified) or on a mrc//write_Rd_ex=(fail)'.(branch + und + mrc + mrs + ldm + (swap.sec')+// (nw'.(mul+ldr+(ALU.nowb'))))assign write_Rd_ex = (!cond_failed_ex & !was_disabled & !no_writes & !hold_next_ex & !exception_ex & (branch | mrc | mrs | ldm | und | (swap & !second_ex) | multiply | ldr | swi | (alu & !alu_no_wb)));//Write to PC where Rd = Pc//Ignore from multiplies, mrc (only updates flags), mrs, swap//For above instruction, Rd should never be R15 (PC)//This is only a signal that indicates that PC may be written,//Rd must still be compared to PCassign #1 write_Pc_Rd = !cond_failed_ex & !was_disabled & !no_writes & !exception_ex & (branch | ldm | und | ldr | swi | (alu & !alu_no_wb));//Assign the Unsigned Bit for Long Multiplicationassign u = alu_opcode[2];//Instructions using Unsigned Bytes are STRB, LDRB, SWPBassign unsigned_byte_ex = (((inst_type_ex == `STRW)|| (inst_type_ex == `LDRW)|| (inst_type_ex == `SWAP)) && (alu_opcode[1]));//Instructions using Signed Bytes are LDRSBassign signed_byte_ex = ((inst_type_ex == `LDRH) && (ir_ex[6:5] == 2'b10));//Instructions using Unsigned Halfwords are STRH, LDRHassign unsigned_hw_ex = (((inst_type_ex == `STRH) || (inst_type_ex == `LDRH)) && (ir_ex[6:5] == 2'b01));//Instructions using Signed Halfwords are LDRSHassign signed_hw_ex = ((inst_type_ex == `LDRH) && (ir_ex[6:5] == 2'b11));//Determine whether this instruction will modify the PCassign ex_mod_pc = (((Rd_ex == 5'h0F) & write_Rd_ex) | ((Rn_ex == 5'h0F) & write_Rn_ex)) & !me_mod_pc;//Determine whether or not CPSR can be updatedassign cpsr_disable = ~((!was_disabled & !me_mod_pc & !load_use_ex & !mispredicted & !cond_failed_ex & !(need_2cycles_ex & !second_ex)) | (!nRESET | exception_ex));//this tells ME to drive the DD Busassign store_ex = (((str & !id_second) | (stm) | (swap & second_ex)) & !load_use_ex & !cond_failed_ex & !me_mod_pc & !was_disabled);//This tells the cache its a store/readassign DnWR = ~(((str & !id_second) | (stm) | (swap & second_ex) | (cop_mem_st)) & !load_use_ex & !cond_failed_ex & !me_mod_pc & !was_disabled);assign r15_inlist = ((Rd_ex == 5'h0F) | (Rn_ex == 5'h0F));assign rd_pc = (Rd_ex == 5'h0F);assign load = ((inst_type_ex == `LDRW)|| (inst_type_ex == `LDRH)||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -