📄 armcontroller.v
字号:
@(posedge sysclk) enter_new_state(`SWAP_1); nSTALL = 0; RF_PC_Write_Sel = 4'b0110; //ALU_Hold_Enable = 0; //AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_HOLD; // Selects ALU hold out WD_Load = 0; // deassert load to WDreg if( ir2_mult_bus[22] == 0 ) MAS = 2'b10; else MAS = 2'b00; nRW = 0; nOPC = 1; nMREQ = 0; // request memory for data #2; while(~nWAIT) begin nSTALL = 0; RF_PC_Write_Sel = 4'b0110; #2; if (nWAIT) begin nMREQ = 1; // deassertion end else @(posedge sysclk) enter_new_state(`LOAD_REQUEST); end // while (~nWAIT) // @(posedge sysclk); // Write the data from memory into the regfile nMREQ = 1; // deassertion RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1512; RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_ALU_RESULT; BBUS_Src = 1; // select read data reg to drive B bus. BS_Enable = 0; // disable shifter Alu_Cntrl = `MOV; RF_Load_Write = 1; @(posedge sysclk) enter_new_state(`SWAP_3); nSTALL = 0; nRW = 1; nOPC = 1; WD_DBE = 1; // enable write data register nMREQ = 0; // request memory RF_PC_Write_Sel = 4'b0110; #2; while(~nWAIT) begin WD_DBE = 1; nSTALL = 0; RF_PC_Write_Sel = 4'b0110; #2; if (nWAIT) begin nMREQ = 1; end // if (nWAIT) else @(posedge sysclk) enter_new_state(`STORE_REQUEST); end // while (~nWAIT) AR_Bus_Sel = 1; // end // if ((ir2_bus[27:23] == 5'b00010) && (ir2_bus[11:4] == 8'b00001001))//************************************** DP or MULT or MRS/MSR **************************************************************// else if (ir2_bus[27:26] == 2'b00) // "DP or MUL or MRS or MSR" if ((ir2_bus[25:23] == 3'b010) && ((ir2_bus[21:16] == 6'b001111) || (ir2_bus[21:12] == 10'b1010011111))) //"MRS or reg to PSR MSR" begin if (ir2_bus[21:16] == 6'b001111) //"MRS" PSR to reg begin RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR21512; // Select PSR address RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_PSR_READ; // Select PSR data RF_PSR_R_Sel = ir2_bus[22]; // Either CPSR or SPSR_mode RF_Load_Write = 1; // Write to regfile end // if (ir2_bus[21:16] == 6'b001111) else if(ir2_bus[21:12] == 10'b1010011111) // reg to PSR MSR begin A_Addr_Sel = `RF_ADDR_A_SEL_IR230; //Rm Alu_A_Sel = `ALU_A_SEL_A; // Select regfile Alu_Cntrl = `PSA; // Pass A SC_Source = `SC_CTRL_SELECT_SOURCE_ALU; // Select ALU Result SC_Type = `SC_TYPE_CHANGE_MODE; RF_PSR_W_Sel = ir2_bus[22]; // Either CPSR or SPSR_mode RF_Load_Flags = 1; RF_Load_Flags <= @(posedge sysclk) 0; end // if (ir2_bus[21:12] == 10'b1010011111) end // if (ir2_bus[25:23] == 3'b010)//************************************** MULT **************************************************************// else if ((ir2_bus[27:22] == 6'b000000) && (ir2_bus[7:4] == 4'b1001)) // "MUL" begin A_Addr_Sel = `RF_ADDR_A_SEL_IR230; // Rm B_Addr_Sel = `RF_ADDR_B_SEL_IR21512; // Rn RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR21916; // Rd to regfile Multiplier_Enable = 1; // ready to multiply ld_ir2_mult = 1; nOPC = 1; nSTALL = 0; RF_PC_Write_Sel = 4'b0110; AR_Bus_Sel = 1; @(posedge sysclk); ld_ir2_mult = 0; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1916; // Rd to regfile RF_PC_Write_Sel = 4'b0110; nOPC = 1; nSTALL = 0; @(posedge sysclk); RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1916; // Rd to regfile RF_PC_Write_Sel = 4'b0110; nOPC = 1; nSTALL = 0; #2; while (!Multiplier_Ready) begin nOPC = 1; nSTALL = 0; @(posedge sysclk) enter_new_state(`MULT); RF_PC_Write_Sel = 4'b0110; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1916; // Rd to regfile end // while (!Multiplier_Ready)`ifdef BUG4`else Link_Sel = 1; // handle case where BL follows Multiply`endif AR_Bus_Sel = 1; Alu_A_Sel = `ALU_A_SEL_MUL; // route multiplier output to ALU input A BBUS_Src = 0; // select regfile to drive B bus. BS_Input_Sel = 0; // Rn to ALU B input BS_Enable = 0; // pass through shifter if (ir2_mult_bus[21] == 1) // MLA Alu_Cntrl = `ADD; // add A and B inputs else // MUL Alu_Cntrl = `PSA;`ifdef BUG3`else RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_ALU_RESULT; // Select output from ALU`endif RF_Load_Write = 1; // load Rd into regfile end // if ((ir2_bus[27:22] == 6'b000000) && (ir2_bus[7:4] == 4'b1001))//************************************** DP **************************************************************// else begin // "DP" A_Addr_Sel = `RF_ADDR_A_SEL_IR21916; Alu_A_Sel = `ALU_A_SEL_A; if (ir2_bus[25] == 1) // operand 2 is an immediate value begin BS_Input_Sel = `BS_INPUT_SEL_EXT; // Barrel Shifter input is zero extended immediate SZE_Ctrl = 0; SZE_Sel = `SZE_SEL_IR2_70; if( ir2_bus[11:8] == 4'b0000 ) begin BS_Enable = 0; end // if ( ir2_bus[11:8] == 4'b0000 ) else begin SAM_Ctrl = `SHIFT_TYPE4; // Rotate right BS_Enable = 1; // enable shifter end // else: !if( ir2_bus[11:8] == 4'b0000 ) end // if (ir2_bus[25] == 1) else begin BS_Input_Sel = `BS_INPUT_SEL_B; // operand 2 is from regfile B_Addr_Sel = `RF_ADDR_B_SEL_IR230; // select register to be shifted if (ir2_bus[4] == 0) SAM_Ctrl = `SHIFT_TYPE1; else SAM_Ctrl = `SHIFT_TYPE2; BS_Enable = 1; // enable shifter end // else: !if(ir2_bus[25] == 1) ///////////////////////////////////// // TST,TEQ,CMP,CMN - Set OpCode ///////////////////////////////////// if ((ir2_bus[24:21] == 4'h8) || (ir2_bus[24:21] == 4'h9) || (ir2_bus[24:21] == 4'ha) || (ir2_bus[24:21] == 4'hb)) begin if (ir2_bus[24:21] == 4'hb) begin Alu_Cntrl = 5'b00100; end // if (ir2_bus[24:21] == 4'hb) else begin Alu_Cntrl = {2'b00,ir2_bus[23:21]}; end // else: !if(ir2_bus[24:21] == 4'hb) end else begin Alu_Cntrl = {1'b0,ir2_bus[24:21]}; end if ((ir2_bus[24:21] == 4'h8) || //These instructions write back condition codes (ir2_bus[24:21] == 4'h9) || (ir2_bus[24:21] == 4'ha) || (ir2_bus[24:21] == 4'hb) || (ir2_bus[20] == 1)) begin //if (ir2_bus[15:12] != 4'hE) //normal operation if dest. is not R15 if (ir2_bus[15:12] != 4'hF) //normal operation if dest. is not R15 begin RF_Load_Flags = 1; // assert loading of PSR RF_PSR_W_Sel = 0; // Enable writing to CPSR case (Alu_Cntrl) `AND, `EOR, `ORR, `MOV, `BIC, `MVN: begin SC_Type = `SC_TYPE_CHANGE_NO_V; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_SFT_FLAGS;// Select Super CPSR to read flags from Alu end `SUB, `RSB, `ADD, `ADC, `SBC, `RSC: begin SC_Type = `SC_TYPE_CHANGE_ALL_FLAGS; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_ALU_FLAGS;// Select Super CPSR to read flags from Alu end endcase end else //load in SPSR -> CPSR (assumed not called while in user mode). begin RF_Load_Flags = 1; // assert loading of PSR RF_PSR_W_Sel = 0; // Enable writing to CPSR RF_PSR_R_Sel = 1; // Enable reading from SPSR SC_Type = `SC_TYPE_CHANGE_ALL_FLAGS; // change mode SC_Source = `SC_CTRL_SELECT_SOURCE_PASS_PSR;// Select Super CPSR to read flags from Alu end end // if ((ir2_bus[24:21] == 4'h8) ||... // else // begin if (!(ir2_bus[24:21] == 4'h8) && //NOT these instructions write back results !(ir2_bus[24:21] == 4'h9) && !(ir2_bus[24:21] == 4'ha) && !(ir2_bus[24:21] == 4'hb)) begin RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR21512; // Select proper destination register RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_ALU_RESULT; // Select output from ALU RF_Load_Write = 1; // Enable regfile load end // if (!(ir2_bus[24:21] == 4'h8) &&... //end // else: !if((ir2_bus[24:21] == 4'h8) ||... end // else: !if((ir2_bus[27:22] == 6'b000000) && (ir2_bus[7:4] == 4'b1001))//************************************** BRANCHES **************************************************************// else if (ir2_bus[27:25] == 3'b101) // BRANCHES begin if (ir2_bus[24] == 1) // Determine whether or not to link begin // LINK code - write PC+4 into R14 RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_LINK_ADDR; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_R14; RF_Load_Write = 1; end // if (ir2_bus[24] == 1) //BRANCH code - add PC to sign-extended offset << 2 Alu_A_Sel = `ALU_A_SEL_PC; //Put PC into ALU SZE_Sel = `SZE_SEL_IR2_230; // put ir2[23:0] into sign-extender SZE_Ctrl = 1; // sign-extend ir2[23:0] BS_Input_Sel = `BS_INPUT_SEL_EXT;//put sign-extended ir2[23:0] into Barrel Shifter SAM_Ctrl = `SHIFT_TYPE3; // Logical shift left by 2 BS_Enable = 1; Alu_Cntrl = `ADD; // Place result into PC RF_PC_Write_Sel = `RF_PC_WRITE_SEL_ALU_RESULT; // clear pipeline ir1_zero = 1; //ir2_zero = 1; AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_RESULT; ALU_Hold_Sel = 0; // Pass Alu_Result to the ALU_Hold Reg ALU_Hold_Enable = 1; AR_Bus_Sel = 2'b00; @(posedge sysclk) enter_new_state(`FETCH); AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_HOLD; ALU_Hold_Enable = 0; AR_Bus_Sel = 2'b00; nMREQ = 0; // request instruction from memory nOPC = 0; // fetching instruction (not data) BBUS_Src = 0; // select read data reg to drive B bus. nRW = 0; MAS = 2'b10; #2; // INSTRUCTION FETCH LOOP while(~nWAIT) begin nSTALL = 0; RF_PC_Write_Sel = 4'b0110; #2; if (nWAIT) begin nMREQ = 1; // deassertion nSTALL = 1; // deassert nSTALL 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; end // if (ir2_bus[27:25] == 3'b101) //************************************** SWI **************************************************************// else if (ir2_bus[27:24] == 4'b1111) // "SWI" 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_8; // route 8 to PC end // if (ir2_bus[27:24] == 4'b1111) //************************************** LDR and STR **************************************************************// else if (ir2_bus[27:26] == 2'b01) // LDR/STR begin if (ir2_bus[25]==1) begin B_Addr_Sel = `RF_ADDR_B_SEL_IR230; BS_Input_Sel = `BS_INPUT_SEL_B; // selects B bus to barrel shifter if( ir2_bus[4] == 1 ) // use shifting rules SAM_Ctrl = `SHIFT_TYPE2; else SAM_Ctrl = `SHIFT_TYPE1; end // if (ir2_bus[25]==1) else begin SZE_Sel = `SZE_SEL_IR2110; BS_Input_Sel = `BS_INPUT_SEL_EXT; // selects sext immediate val. SZE_Ctrl = 0; // tells extender to use zero fill SAM_Ctrl = `SHIFT_TYPE3; // aligns by shifting 2 end // else: !if(ir2_bus[25]==1) if (ir2_bus[23]==1) Alu_Cntrl = `ADD; else Alu_Cntrl = `SUB; A_Addr_Sel = `RF_ADDR_A_SEL_IR21916; Alu_A_Sel = `ALU_A_SEL_A; // Check for pre/post indexing. If pre indexing need to check for // Write back otherwise for post indexing always write back if( ir2_bus[24] == 1) begin // Pre-indexed AR_Bus_Sel = 2'b00; // `AR_ALU_SEL = 2'b00; in regfile define file AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_RESULT; // selects ALU out if ( ir2_bus[21] == 1 ) // Check for Write-back bit begin RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR21916; RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_ALU_RESULT; RF_Load_Write = 1; end // if ( ir2_bus[21] == 1 ) end // if ( ir2_bus[24] == 1) else begin AR_Bus_Sel = 2'b00; // Select AR_BUS_ALU AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_A_BUS; // Select the base register // Since post indexed, write back by default(no need to check) RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR21916; RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_ALU_RESULT; RF_Load_Write = 1; end // else: !if( ir2_bus[24] == 1) //AR_Bus_Sel = 2'b00; // `AR_ALU_SEL = 2'b00; in regfile define file // AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_RESULT; // selects ALU out ld_ir2_mult = 1; // latch multicycle instruction. if( ir2_bus[24] == 0) ALU_Hold_Sel = 1; // Pre-index so pass Alu_Result else ALU_Hold_Sel = 0; // Post-indexing so pass A_Bus ALU_Hold_Enable = 1; // latch ALU_Result // nSTALL = 0; // assert STALL if (ir2_bus[22] == 0) MAS = 2'b10; // word else MAS = 2'b00; // byte if (ir2_bus[20]==1) // LDR begin //RF_PC_Write_Sel = `RF_PC_WRITE_SEL_RF_PC_READ; @(posedge sysclk); RF_Load_Write = 0; RF_PC_Write_Sel = 4'b0110; ALU_Hold_Enable = 0; if(ir2_bus[24] == 1) AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_HOLD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -