?? id.v
?? arm9_fpga2_verilog是一個可以綜合的用verilog寫的arm9的ip軟核
?? V
?? 第 1 頁 / 共 4 頁
字號:
??
`timescale 1ns/10ps`include "pardef"/*****************************************************************************$RCSfile: id.v,v $$Revision: 1.10 $$Author: kohlere $$Date: 2000/04/17 18:12:50 $$State: Exp $$Source: /home/lefurgy/tmp/ISC-repository/isc/hardware/ARM10/behavioral/pipelined/fpga2/id.v,v $Description: This is the Instruction Decode Stage. It controls the reads of the Register File, as well as setting up some of the control signals.*****************************************************************************/module id(nGCLK, nWAIT, nRESET, id_enbar, inst, rf_a, rf_b, write_Rd_ex, Rd_ex, write_Rn_ex, Rn_ex, write_Rn_me, Rn_me, ex_result, me_result, base_ex, base_me, Rd_me, write_Rd_me, mode, index_a, index_b, op1, op2, alu_opcode, ldm, stm, condition, shift_amount, shift_type, ir_id, finished, second, need_2cycles, Rd_id, Rn_id, aux_data_id, inst_type_id, s, load_use, second_nlu, mul_first, cop_id, double_id, cop_mem_id, hold_next_ex, pc_if, stop_id, cop_absent, exception, exc_code, exception_id, exc_code_id);/*------------------------------------------------------------------------ Ports------------------------------------------------------------------------*/input [31:0] inst; //Instruction from main memory input [31:0] rf_a; //A data from RFinput [31:0] rf_b; //B data from RFinput [31:0] ex_result; //Result of EX Stageinput [31:0] me_result; //Result of ME Stageinput [31:0] base_ex; //Result2 of EX Stageinput [31:0] base_me; //Result2 of ME Stageinput [31:0] pc_if; //PC input [4:0] Rd_ex; //Rd in EX Stageinput [4:0] Rn_ex; //Rn in EX Stageinput [4:0] Rd_me; //Rd in ME Stageinput [4:0] Rn_me; //Rn in ME Stageinput [4:0] mode; //Mode of Processorinput [1:0] exc_code; //Exception Codeinput nGCLK; //clock signalinput nRESET; //reset signalinput nWAIT; //clock enable signalinput exception; //Take the Exception input id_enbar; //ID stage enable (active low)input write_Rd_ex; //Ex_result going to be written?input write_Rn_ex; //Base_ex going to be written?input write_Rd_me; //Me_result going to be written?input write_Rn_me; //Base_me going to be written?input cop_absent; //Coprocessor is Absentinput hold_next_ex; //Ex is Stallingoutput [31:0] op1; //First Operandoutput [31:0] op2; //Second Operandoutput [31:0] aux_data_id; //Auxillary Data Operandoutput [7:0] shift_amount; //Shift Amountoutput [4:0] index_a; //Address A for RFoutput [4:0] index_b; //Address B for RFoutput [4:0] Rd_id; //First Destinationoutput [4:0] Rn_id; //Second Destinationoutput [3:0] alu_opcode; //ALU Opcodeoutput [3:0] condition; //Conditionoutput [3:0] inst_type_id; //4-Bit Instruction Codeoutput [2:0] shift_type; //Shift Type output [6:4] ir_id; //Bits 6:4 of IRoutput need_2cycles; //Signal that three Regs Requiredoutput second; //Signal in Second Cycleoutput second_nlu; //2nd Cycle, not due to Load Useoutput load_use; //Load-Use Interlock Necessaryoutput ldm; //Inst is LDM to interlock.voutput stm; //Inst is STM to interlock.voutput finished; //Inst is finished to interlock.voutput s; //S bit of Instructionoutput double_id; //64-bit Memory accessoutput mul_first; //First cycle of LDM/STMoutput cop_mem_id; //Coprocessor Inst. req. Memoryoutput cop_id; //Coprocessor Inst Presentoutput exception_id; //Exception to EX Stageoutput stop_id; //Stop Executionoutput [1:0] exc_code_id; //Exception Code to EX Stage/*------------------------------------------------------------------------ Variable Declarations------------------------------------------------------------------------*///Declare Outputs of Multiplexers and Registersreg [31:0] ir; //Instruction Registerreg [31:0] op1; //Operand 1reg [31:0] op2; //Operand 2reg [31:0] aux_data_id; //Auxillary Data Operandreg [31:0] imm_32; //Imm 2B Shiftedreg [31:0] forwarded_op1; //Data to Forward to Op1reg [31:0] forwarded_op2; //Data to Forward to Op2reg [15:0] reg_mask_a; //Intermediate Reg Maskreg [15:0] next_reg_mask; //Next Register Maskreg [7:0] imm_8; //Imm Shfit Amountreg [7:0] shift_amount; //Shift Amountreg [4:0] mode_user_a; //Mode mux btwn Current/Userreg [4:0] mode_user_b; //Mode mux btwn Current/Userreg [4:0] mode_user_Rn; //Mode mux btwn Current/User/Undreg [3:0] addr_a; //Address A for RFreg [3:0] addr_b; //Address B for RFreg [3:0] map_Rn; //Base Register to Mapperreg [3:0] map_Rd; //Dest Register to Mapperreg [3:0] inst_type; //Inst Codereg [3:0] inst_type_id; //Inst Code/Exceptionreg [2:0] shift_type; //Shift Type Control Signalsreg [1:0] exc_code_id; //Exception Code to be takenreg exception_id; //Exception to be takenreg second; //2nd Cycle of RF readsreg ldm_stm; //One Bit Reg indicating LDM/STMreg ldr_ex; //Prev Inst was LDRW/Hreg ldm_ex; //Prev Inst was LDM//Declare Outputs of Combinational Logicwire [15:0] mask_a_n; //Anding Mask (inverted)wire [15:0] mask_b_n; //Anding Mask (inverted)wire [15:0] reg_mask_b; //One Bit removed wire [15:0] reg_mask_c; //Two Bits removedwire [4:0] index_a; //5-bit RF A indexwire [4:0] index_b; //5-bit RF B indexwire [4:0] Rd_id; //Mapped Rd wire [4:0] Rn_id; //Mapped Rn reg [3:0] mreg_a; //Multiple Instruction Reg Areg [3:0] mreg_b; //Multiple Instruction Reg Bwire [3:0] alu_opcode; //Opcode to ALUwire [3:0] condition; //Condition of Executionwire [3:0] Rd; //Rd from Instructionwire [3:0] Rn; //Rn from Instructionwire [3:0] Rm; //Rm from Instructionwire [3:0] Rs; //Rs from Instructionwire [6:4] ir_id; //Bits 6-5 of IRwire double_id; //64-bit Data Accesswire no_lu_on_op1; //No Load-Use match for Op1wire no_lu_on_op2; //No Load-Use match on Op2wire need_2cycles; //Inst Requires 2 Cycleswire branch; //Instruction is a Branchwire multiply; //Instruction is a MUL/MULLwire alu; //Instruction is an ALUwire swap; //Instruction is a SWAPwire ldrhi; //Inst is LDRH/SH/SB & imm offset wire ldrh; //Inst is LDRH/SH/SBwire ldri; //Inst is LDR with Imm Offsetwire ldrw; //Inst is a LDRWwire strhi; //Inst is STRH & imm offsetwire strh; //Inst is STRHwire strw; //Inst is STRWwire stri; //Inst is STRH/STR with imm Offsetwire ldm; //Inst is LDMwire stm; //Inst is STMwire str; //Inst is STR/STRHwire swi; //Inst is SWIwire msr; //Inst is MSRwire und; //Inst is Undefinedwire s; //S bit of Instructionwire forward_op1; //Forward op1?wire forward_op2; //Forward op2?wire forward_aux; //Forward Aux Data Valuewire forward_sh_amt; //Forward the data to Shift Amountwire op2_is_imm; //Op2 Immediate Value?wire alu_3_reg; //Shifted by Register Valuewire load_use; //Load Use Interlock Necessarywire load_use_Rn; //Load Use to Rnwire load_use_Rd; //Load Use to Rdwire second_nlu; //2nd Cycle, not due to Load Usewire swap_noforward; //If Rd=Rm of Swap, don't forwardwire mul_first; //LDM/STM in first cyclewire finished; //This signals the end of LDM/STMwire cop_id; //Coprocessor Instructionwire cop_mem_id; //Coprocessor Inst using Memorywire stop_id; //Stop Execution (BL to Self)/*------------------------------------------------------------------------ Component Instantiations------------------------------------------------------------------------*/// Instantiate mapreg// This will map Op1mapreg xmap_1 (.reg_field(addr_a), .mode(mode_user_a), .reg_addr(index_a));// Instantiate mapreg// This will map Op2mapreg xmap_2 (.reg_field(addr_b), .mode(mode_user_b), .reg_addr(index_b));// Instantiate mapreg// This will map Rnmapreg xmap_3 (.reg_field(map_Rn), .mode(mode_user_Rn), .reg_addr(Rn_id));// Instantiate mapreg// This will map Rdmapreg xmap_4 (.reg_field(map_Rd), .mode(mode_user_b), .reg_addr(Rd_id));//Decoders for LDM/STM commandsdecode xdec1 (.in(mreg_a), .out(mask_a_n));decode xdec2 (.in(mreg_b), .out(mask_b_n));/*------------------------------------------------------------------------ Combinational Logic------------------------------------------------------------------------*/assign multiply = ((inst_type==`MUL)||(inst_type==`MULL));assign str = ((inst_type==`STRW)||(inst_type==`STRH));assign alu = (inst_type == `ALU);assign strh = (inst_type == `STRH);assign strw = (inst_type == `STRW);assign swi = (inst_type == `SWI);assign branch = (inst_type == `BR);assign swap = (inst_type == `SWAP);assign msr = (inst_type == `MSR);assign ldm = (inst_type == `LDM);assign ldrw = (inst_type == `LDRW);assign stm = (inst_type == `STM);assign cop_id = (ir[27:26] == 2'h3) && (ir[25:24] != 2'h3);assign und = (inst_type == `UND) | ((inst_type == `COP) && (cop_absent==1'b1));assign ldrh = (inst_type == `LDRH);assign swap_noforward = (swap && (Rd == Rm));assign condition = ir[31:28];assign alu_opcode = ir[24:21];assign Rn = ir[19:16];assign Rd = ir[15:12];assign Rs = ir[11:8];assign Rm = ir[3:0];assign s = ir[20];assign ir_id = ir[6:4];assign finished = !(| reg_mask_c);assign reg_mask_b = reg_mask_a & ~mask_a_n;assign reg_mask_c = reg_mask_b & ~mask_b_n;assign double_id = ldm_stm & (| reg_mask_b);assign stop_id = ir == 32'hebfffffe; //Indicates a Coprocessor Instruction using Memoryassign cop_mem_id = (ir[27:25] == 3'h6) & !und;//Indicates an LDRH with an Immediate Offsetassign ldrhi = ((inst_type == `LDRH) & (ir[22]));//Indicates an LDR with an Immediate Offsetassign ldri = ((inst_type == `LDRW) & (!ir[25]));//Indicates a STRH with an Immediate offsetassign strhi = ((inst_type == `STRH) & (ir[22]));//Indicates that 3 Registers may be required, if this is indeed an//ALU type instruction.assign alu_3_reg = (!ir[25] & ir[4]);//Indicates that an LDM/STM is present in its first cycleassign mul_first = (ldm | stm) & !ldm_stm;//Indicates that an STR/STRH with Imm Offsetassign stri = ((inst_type == `STRH) & (ir[22])) || ((inst_type == `STRW) & (!ir[25]));//Indicates that this is the 2nd Cycle of the current instruction,//however, the extra cycle was not caused by a Load-Use interlock.//This is important for the EX stage, because it behaves differently//on the 2nd cycle of instructions that require two cycles, such as //Stores or ALU w/ 3 registers.assign second_nlu = second & need_2cycles;//Certain instructions shouldn't have a Load Use penalty (loads)//Op1 is the base for LDM (that's the only load that can issue a lu for op1)assign no_lu_on_op1 = (ldm & !mul_first) | ldrw | ldrh;assign no_lu_on_op2 = ldm;//Check for the Load-Use condition. This occurs when the previous//instruction is a load and the current instruction uses the value//that is being loaded.assign load_use_Rd = ((ldr_ex | ldm_ex) & ( (write_Rd_ex & (Rd_ex == index_a) & !no_lu_on_op1) | (write_Rd_ex & (Rd_ex == index_b) & !no_lu_on_op2 & !branch & !(op2_is_imm & !stri))));assign load_use_Rn = (ldm_ex & ( (write_Rn_ex & (Rn_ex == index_a) & !no_lu_on_op1) | (write_Rn_ex & (Rn_ex == index_b) & !no_lu_on_op2 & !branch & !op2_is_imm)));assign load_use = load_use_Rn | load_use_Rd;//Set up the Need Cycle Signal//Need extra Cycle for MLA, MLAL,STR/H with register offset, SWAP, & ALU//instructions that have a register specified shift amount.assign need_2cycles = ((strh & (!ir[22])) | //STRH (strw & (ir[25])) | //STRW (swap) | //SWAP (alu & alu_3_reg) | //ALU (multiply & ir[21])); //MLA/L //Determine whether Op2 is Reg or Imm Valueassign op2_is_imm = (swap | (alu & ir[25]) | ldri | stri | ldrhi | (msr & ir[25]) | cop_mem_id | (und | swi) | mul_first);//Forward Data to Op1 if there is a unfinished write to op1 reg.assign forward_op1 = ((write_Rd_ex && (Rd_ex == index_a))|| (write_Rn_ex && (Rn_ex == index_a))|| (write_Rd_me && (Rd_me == index_a))|| (write_Rn_me && (Rn_me == index_a))) ? 1'b1 : 1'b0;//Forward Data to Op2 if there is an unfinished write to op2 reg.//Don't forward if Op2 is an Immediate Value assign forward_op2 = (((write_Rd_ex && (Rd_ex == index_b))|| (write_Rn_ex && (Rn_ex == index_b))|| (write_Rd_me && (Rd_me == index_b))|| (write_Rn_me && (Rn_me == index_b))) && !op2_is_imm) ? 1'b1 : 1'b0;//Forward Data to Aux if there is an unfinished write to aux_data reg.//For Swap instructions with Rd=Rm, have to make sure that the//loaded data into Rd is not forwarded into Rm.assign forward_aux = (((write_Rd_ex && (Rd_ex == index_b)) && (!swap_noforward) || (write_Rn_ex && (Rn_ex == index_b))|| (write_Rd_me && (Rd_me == index_b))|| (write_Rn_me && (Rn_me == index_b)))) ? 1'b1 : 1'b0;//Forward Data to the shift amount mux if unfinished write to //Shift Register.assign forward_sh_amt = (second_nlu && (inst_type == `ALU) && ((write_Rd_ex && (Rd_ex == index_a)) || (write_Rn_ex && (Rn_ex == index_a)) || (write_Rd_me && (Rd_me == index_a)) || (write_Rn_me && (Rn_me == index_a))));/*------------------------------------------------------------------------ Sequential Always Blocks------------------------------------------------------------------------*///This block controls the IRalways @(posedge nGCLK or negedge nRESET) begin if (!nRESET) ir <= 32'h00000000; else if (nWAIT) begin if (!id_enbar) ir <= inst; end end//This block controls the Exception Bitalways @(posedge nGCLK or negedge nRESET) begin if (~nRESET) exception_id <= 1'b0; else if (nWAIT) begin if (~id_enbar) exception_id <= exception; end end//This block controls the Exception Code Bitsalways @(posedge nGCLK or negedge nRESET) begin if (~nRESET) exc_code_id <= 2'h0; else if (nWAIT) begin if (~id_enbar) exc_code_id <= exc_code; end end//This block controls the second bit//If id_enbar is not high, then a new instruction//will be loaded into the IR and thus, will not//be starting the 2nd cycle of past instructionalways @(posedge nGCLK or negedge nRESET) begin if (!nRESET) second <= 1'b0; else if (nWAIT)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -