📄 armcontroller.v
字号:
//////////////////////////////////////////////////// //// ARM Controller Mixed Model // // Revision History // // Version 1.0 - initial hack, 29 Mar 2000 //// Jon Moeller, Daryl Kowalski // // Version 1.01 - included interfaces //// Jon Moeller //// Version 1.02 - revised LDR/STR, //// - MUL, Data Proc. added //// - removed @(posedge sysclks) //// Jon Moeller & Matt Crum //// Version 1.03 - revised DP,signal names //// - setup all defines for muxes // // - debugged syntax errors //// Jon Moeller & Matt Crum //// Version 1.04 - tested dp instructions //// - played with LDR/STR //// Jon Moeller, Daryl K., Matt Crum //// Version 1.05 - added exception handling/SWI //// - added branches //// - removed IDLE, halt/cont loop //// Jon Moeller, Daryl K., //// Version 1.06 - added default signals to ENST //// - added SWP instruction //// - removed extra cycle after //// cache miss (using else) //// - improved handshaking with MEM //// in IF only. //// Mike Ni, Matt Crum, Jon Moeller, Amit //// Pandey, Anthony Doggett, Kevin Duda //// Version 1.07 - Switch `PSB to `MOV and `MOV //// to `PSA //// - Modified DP section : //// - Changed ALU_A_Sel to select //// RF_A_Bus. //// - Allowed DP instructions to //// execute if S bit set. //// - Changed RF_Write_Bus_Sel to //// select Alu_Result. //// - Removed Default ALU_A_Sel //// from ENST //// Kevin Duda, Amit Pandey, Mike Ni //// Version 1.08 - Removed Default nOPC from //// ENST //// - Changed Width of //// RF_Bus_Write_Sel to 3 bits //// - Moved nSTALL signal to 2nd //// cycle on LDR only. //// - Set ld_ir2_mult = 0 after //// wait loop //// - LDR wait loop modeled after //// IF wait loop //// Kevin Duda, Long Truong, Matt Crum, Mike //// Ni //// Version 1.09 - Added a register to hold the //// ALU_Result for driving the A //// bus in an LDR instruction for //// more than 1 cycle // // - This caused the mux which is //// controlled by AR_Bus_ALU_Sel //// to become a 4 input mux in //// the datapath //// - We also added the enable //// signal for this register //// to the controller and datapath//// Deanna Perry, Matt Crum //// Version 1.10 - Fixed register relative LDR //// - Fixed IFetch after LDR by add //// nOPC = 0 before wait state //// Mike Ni //// Version 1.11 - Fixed Store for multiple STR //// - Fixed LDR for LDR after STR //// Amit Pandey, Mike Ni //// //// Version 1.12 - Fixed Multiply instruction //// Amit Pandey //// version 1.13 - Added MSR and MRS //// - Vince and Amit 4/27/00 //// version 1.14 - Added sub8 unit for BL, //// exception return address //// adjustment. //// - Jon & Daryl K. 4/27/00 //// Version 1.15 - Added TST, TEQ, CMP, CMN //// Mike Ni //// Version 1.16 - Added more selective criteria //// to the if statement that //// decodes MSR and MRS to avoid //// overlap with other insts. //// - Added some visual breaks //// between sections of code //// Matt Crum //// Version 1.17 - changed CMN to set //// Alu_Cntrl to `ADD instead of //// `RSB //// Matt Crum //// Version 1.18 - added ALU_Hold_Sel in the //// module interface. This keeps address constant//// during mem requests -- Amit Pandey 4/30/00 ////////////////////////////////////////////////////// Please note all changes in the revision history // with a note of what you modified and who you are// Arm Controller module and input/output definitions// Deanna Perry, 3-29// Included interfaces as defined by djperry// Rearranged, cleaned up some parts// Jon Moeller, 3-30// Revised LDR/STR, added MUL, Data Proc., removed// @(posedge sysclk) on signal assignments.// Made various changes.// Jon Moeller & Matt Crum, 4-2// Added some mux select lines that were left out in LDR/STR// instructions// Amit Pandey 4/4/00// Added branches, SWI,exception handlers, removed// IDLE state and halt/cont loop.// Jon Moeller, Daryl K., 4/6/00// Debugged branch instruction - Amit & Isaac 4/17/00`include "defines.v"`timescale 1ns/100ps // LOCAL DEFINES (temporary)// module declaration for controller of ARM7module armcontroller(A_Addr_Sel,B_Addr_Sel,RF_Addr_Write_Sel,RF_Bus_Write_Sel,RF_PC_Write_Sel, RF_Load_Write,RF_Load_Flags,RF_PSR_R_Sel,RF_PSR_W_Sel,RF_PSR_Read, SC_Type,SC_Source,SZE_Sel,SZE_Ctrl,SAM_Ctrl,BS_Input_Sel,BS_Enable,BS_Cin, AR_Bus_ALU_Sel,AR_Bus_Sel,WD_DBE,WD_Load,nOPC,nCPI,CPA,CPB,nMREQ,nRW,MAS,nWAIT, Alu_A_Sel,Alu_Cntrl,Multiplier_Enable,Multiplier_Ready,ir2_bus,ir2_mult_bus, ir1_zero,ir2_zero,ld_ir2_mult,nSTALL,BBUS_Src,sysclk,nRESET,ABORT, nFIQ,nIRQ,ALU_Hold_Enable,ALU_Hold_Sel,Link_Sel); // Input/Output Declarations by instantiated module // Register File output B_Addr_Sel; output [2:0] RF_Addr_Write_Sel,RF_Bus_Write_Sel; output [1:0] A_Addr_Sel; output [3:0] RF_PC_Write_Sel; output RF_Load_Write,RF_Load_Flags,RF_PSR_R_Sel,RF_PSR_W_Sel; input [31:0] RF_PSR_Read; // Super CPSR output [4:0] SC_Type; output [3:0] SC_Source; // Zero/Sign Extender output [1:0] SZE_Sel; output SZE_Ctrl; // Barrel Shifter output [1:0] SAM_Ctrl; output BS_Input_Sel; output BS_Enable; output BS_Cin; // Address Register output [1:0] AR_Bus_ALU_Sel; output [1:0] AR_Bus_Sel; output ALU_Hold_Enable; output ALU_Hold_Sel; // 1 := select A_Bus 0 := sel Alu_Result output Link_Sel; // 0 = PC - 4; 1 = PC // Write Data Register output WD_DBE; output WD_Load; //Coprocessor output nOPC,nCPI; input CPA,CPB; //Memory Interface output nMREQ; output nRW; output [1:0] MAS; input nWAIT; //ALU output [1:0] Alu_A_Sel; output [4:0] Alu_Cntrl; //Multiplier output Multiplier_Enable; input Multiplier_Ready; //general input [31:0] ir2_bus, ir2_mult_bus; output ir1_zero, ir2_zero, ld_ir2_mult,nSTALL, BBUS_Src; input sysclk; // Exception Signals input nRESET; input ABORT; input nFIQ; input nIRQ; // Reg and Wire declarations by module // Register File reg B_Addr_Sel; reg [2:0] RF_Addr_Write_Sel, RF_Bus_Write_Sel; reg [1:0] A_Addr_Sel; reg [3:0] RF_PC_Write_Sel; reg RF_Load_Write,RF_Load_Flags,RF_PSR_R_Sel,RF_PSR_W_Sel; wire [31:0] RF_PSR_Read; // Super CPSR reg [4:0] SC_Type; reg [3:0] SC_Source; // Zero/Sign Extender reg [1:0] SZE_Sel; reg SZE_Ctrl; // Barrel Shifter reg [1:0] SAM_Ctrl; reg BS_Input_Sel; reg BS_Enable; reg BS_Cin; // Address Register reg [1:0] AR_Bus_ALU_Sel; reg [1:0] AR_Bus_Sel; reg ALU_Hold_Enable; reg ALU_Hold_Sel; reg Link_Sel; // Write Data Register reg WD_DBE; reg WD_Load; //Coprocessor reg nOPC,nCPI; wire CPA,CPB; //Memory Interface reg nMREQ; reg nRW; reg [1:0] MAS; wire nWAIT; //ALU reg [1:0] Alu_A_Sel; reg [4:0] Alu_Cntrl; //Multiplier reg Multiplier_Enable; wire Multiplier_Ready; //general wire [31:0] ir2_bus, ir2_mult_bus; reg ir1_zero, ir2_zero, ld_ir2_mult, nSTALL, BBUS_Src; wire sysclk; // Exception Signals wire nRESET; wire ABORT; wire nFIQ; wire nIRQ; // internal state reg [`NUM_STATE_BITS-1:0] present_state; always begin @(posedge sysclk) enter_new_state(`INIT); RF_PC_Write_Sel = `RF_PC_WRITE_SEL_0; // mux 0 into PC; SC_Type = 5'b10000; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_USR_MODE; // select USR mode RF_Load_Flags = 1; // assert loading of PSR RF_PSR_W_Sel = 0; // select CPSR RF_PSR_R_Sel = 0; // select CPSR AR_Bus_Sel = 1; // select PC ir1_zero = 1; // fill pipeline with NOPs ir2_zero = 1; @(posedge sysclk); forever @(sysclk or nRESET or ABORT or nFIQ or nIRQ) begin // handle exceptions //if( sysclk==1 && nRESET == 1 && ABORT ==0 && nFIQ == 0 && nIRQ ==0) // enter_new_state(`F1); if (nRESET == 0) begin SC_Type = 5'b10000; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_SVC_MODE; // select SVC mode RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_LINK_ADDR; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_R14; RF_Load_Write = 1; // save PC into R14_svc RF_PC_Write_Sel = `RF_PC_WRITE_SEL_0; // mux 0 into PC; end // if (nRESET == 0) else if (ABORT == 1) begin SC_Type = 5'b10000; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_ABT_MODE; // select ABT mode RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_LINK_ADDR; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_R14; RF_Load_Write = 1; // save PC into R14_abt RF_PC_Write_Sel = `RF_PC_WRITE_SEL_C; // mux h'C into PC; end // if (ABORT == 1) else if (nFIQ == 0) begin SC_Type = 5'b10000; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_FIQ_MODE; // select FIQ mode RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_LINK_ADDR; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_R14; RF_Load_Write = 1; // save PC into R14_fiq RF_PC_Write_Sel = `RF_PC_WRITE_SEL_1C; // mux h'1C into PC; end // if (nFIQ == 0) else if (nIRQ == 0) begin SC_Type = 5'b10000; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_IRQ_MODE; // select IRQ mode RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_LINK_ADDR; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_R14; RF_Load_Write = 1; // save PC into R14_irq RF_PC_Write_Sel = `RF_PC_WRITE_SEL_18; // mux h'18 into PC; end // if (nIRQ == 0) else begin @(posedge sysclk) enter_new_state(`F1); if (condx(ir2_bus[31:28],RF_PSR_Read) // condition passed // data processing instruction that writes to PC && ((ir2_bus[27:26]==2'b00 && ir2_bus[15:12]==15 && ~(ir2_bus[24:23] == 5'b10)) || (ir2_bus[27:25]==5))) // or branch instruction // ~(ir2_bus[27:23] == 5'b00010 && ir2_bus[21:16] == 6'b101001 && // ir2_bus[11:4] == 8'b00000000)) || ir2_bus[27:25]==5)) begin // "B/R15" ir1_zero = 1; end // if (condx(ir2_bus[31:28],RF_PSR_Read)... else begin // "NORMAL" ir1_zero = 0; ir2_zero = 0; nOPC = 0; RF_PC_Write_Sel = `RF_PC_WRITE_SEL_PC_PLUS4; AR_Bus_Sel = 2; nMREQ = 0; // request instruction from memory BBUS_Src = 0; // select read data reg to drive B bus. nRW = 0; MAS = 2'b10; //@(negedge nWAIT); #2; AR_Bus_Sel = 1; // INSTRUCTION FETCH LOOP while(~nWAIT) begin nSTALL = 0; RF_PC_Write_Sel = 4'b0110; #2; if (nWAIT) begin nMREQ = 1; // deassertion nOPC = 0; // fetching instruction (not data) nSTALL = 1; // deassert nSTALL nOPC = 0; // fetching instruction (not data) end else @(posedge sysclk) enter_new_state(`FETCH); end // while (~nWAIT) RF_PC_Write_Sel = `RF_PC_WRITE_SEL_PC_PLUS4; AR_Bus_Sel = 2; // ir2 <- ir1 - happens when nSTALL = 1 end // else: !if(condx(ir2_bus[31:28],RF_PSR_Read)... // CONDITIONALLY EXECUTE INSTRUCTIONS if (condx(ir2_bus[31:28],RF_PSR_Read)) begin//************************************** SWAP **************************************************************// if ((ir2_bus[27:23] == 5'b00010) && (ir2_bus[11:4] == 8'b00001001) && (ir2_bus[21:20] == 2'b00)) // SWP begin // First load the data to be written to mem into Write Data Reg // and also load the Address Reg with address ld_ir2_mult = 1; A_Addr_Sel = `RF_ADDR_A_SEL_IR21916; //ALU_Hold_Enable = 1; AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_A_BUS;// selects ALU out AR_Bus_Sel = 2'b00; // Select AR_Bus_Alu input to Add Reg B_Addr_Sel = `RF_ADDR_B_SEL_IR230; BBUS_Src = 0; // select regfile to drive B bus WD_Load = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -