📄 armcontroller.v
字号:
else begin AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_A_BUS; A_Addr_Sel = `RF_ADDR_A_SEL_IR2_MULT1916; end // else: !if(ir2_mult_bus[24] == 1) ld_ir2_mult = 0; nSTALL = 0; nRW = 0; nOPC = 1; nMREQ = 0; // request memory #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); nMREQ = 1; // deassertion //nSTALL = 1; // deassert nSTALL AR_Bus_Sel = 1; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1512; RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_D; BBUS_Src = 1; // select read data reg to drive B bus. BS_Enable = 0; // disable shifter Alu_Cntrl = `MOV; RF_Load_Write = 1; end // if (ir2_bus[20]==1) else //STR begin BBUS_Src = 0;//select regfile to drive BBus WD_Load = 1; @(posedge sysclk); RF_Load_Write = 0; RF_PC_Write_Sel = 4'b0110; WD_Load = 0; AR_Bus_Sel = 0; ALU_Hold_Enable = 0; if(ir2_bus[24] == 1) AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_HOLD; else begin AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_A_BUS; A_Addr_Sel = `RF_ADDR_A_SEL_IR2_MULT1916; end // else: !if(ir2_mult_bus[24] == 1) ld_ir2_mult = 0; nSTALL = 0; nRW = 1; nOPC = 1; nMREQ = 0; // request memory B_Addr_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1512; BS_Enable = 0; // disable shifter Alu_Cntrl = `MOV; WD_DBE = 1; // enable write data register #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 // else: !if(ir2_bus[20]==1) end // if (ir2_bus[27:26] == 2'b01)//************************************** FPU INSTRUCTIONS **************************************************************// else if (ir2_bus[27:24] == 4'b1110) // CRT or CDO begin if (ir2_bus[4] == 1) // CRT begin nCPI = 0; @(negedge CPA or posedge sysclk); if (CPA == 1) //trap begin @(posedge sysclk) enter_new_state(`FPU_1A); SC_Type = 5'b10000; // change mode RF_PC_Write_Sel = `RF_PC_WRITE_SEL_4; // mux 4 into PC; ir1_zero = 1; // clear out the pipeline SC_Source = `SC_CTRL_SELECT_SOURCE_UND_MODE; // select SVC mode end // if (CPA == 1) else begin ld_ir2_mult = 1; if (ir2_bus[20] == 0) begin BBUS_Src = 0; // select RF to drive B bus. WD_Load = 1; //load WDR B_Addr_Sel = `RF_ADDR_B_SEL_IR21512; // Rn end else begin WD_DBE = 0; // output Z end while (CPB != 0) begin @(posedge sysclk) enter_new_state(`FPU_2A); //waiting for them to finish nCPI = 0; nSTALL = 0; //stalling //ld_ir2_mult = 1; end @(posedge sysclk) enter_new_state(`FPU_2A); //waiting for them to finish nCPI = 0; nOPC = 1; nSTALL = 0; //stalling #1; if (ir2_mult_bus[20] == 1) // Load/Store begin RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1512; RF_Load_Write = 1; RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_D; end else begin WD_DBE = 1; // output WDR end //nSTALL = 1; //un-stalling ld_ir2_mult = 0; // latch multicycle instruction. end //else //nCPI = 1; end //if (ir2_bus[4] == 1) else // CDO begin nCPI = 0; @(negedge CPA or posedge sysclk); if (CPA == 1) begin @(posedge sysclk) enter_new_state(`FPU_1A); SC_Type = 5'b10000; // change mode RF_PC_Write_Sel = `RF_PC_WRITE_SEL_4; // mux 4 into PC; ir1_zero = 1; // clear out the pipeline SC_Source = `SC_CTRL_SELECT_SOURCE_UND_MODE; // select SVC mode end // if (CPA == 1) else begin while (CPB != 0) begin @(posedge sysclk) enter_new_state(`FPU_2A); //waiting for them to finish nSTALL = 0; //stalling end nSTALL = 0; //stalling @(posedge sysclk) enter_new_state(`FPU_2A); //one more cycle after CPB <- 0 nSTALL = 1; //un-stalling end //else nCPI = 1; end //end CDO end //if (ir2_bus[27:24] == 4'b1110) else if (ir2_bus[27:25] == 3'b110) //CDT begin WD_DBE = 0; // output Z if (ir2_bus[24] == 0) //postindexing begin A_Addr_Sel = `RF_ADDR_A_SEL_IR21916; AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_A_BUS;// selects A Bus AR_Bus_Sel = 2'b01; // Select AR_Bus_Alu input to Add Reg end else if(ir2_bus[19:16] == 15) // special case for r15 begin AR_Bus_Sel = 2'b01; // Select PC+4 input to Add Reg end else //all other cases begin ALU_Hold_Sel = 0; // Pass Alu_Result ALU_Hold_Enable = 1; AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_RESULT;// selects ALU_RESULT AR_Bus_Sel = 2'b00; // Select AR_Bus_Alu input to Add Reg A_Addr_Sel = `RF_ADDR_A_SEL_IR21916; Alu_A_Sel = `ALU_A_SEL_A; // route A output to ALU input A BS_Input_Sel = `BS_INPUT_SEL_EXT; // Barrel Shifter input is zero extended immediate SZE_Ctrl = 0; SZE_Sel = `SZE_SEL_IR2_70; SAM_Ctrl = `SHIFT_TYPE3; // Logical shift left by 2 if (ir2_bus[23]==1) Alu_Cntrl = `ADD; else Alu_Cntrl = `SUB; 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 end nSTALL = 1; @(posedge sysclk) begin ALU_Hold_Enable = 0; AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_HOLD; nSTALL = 0; RF_PC_Write_Sel = 4'b0110; ld_ir2_mult = 0; nRW = 0; nOPC = 1; nMREQ = 0; // request memory #2; while(~nWAIT) begin nSTALL = 0; RF_PC_Write_Sel = 4'b0110; #2; if (nWAIT) begin nSTALL = 1; nCPI = 0; nMREQ = 1; // deassertion end else @(posedge sysclk) enter_new_state(`LOAD_REQUEST); end // while (~nWAIT) nMREQ = 1; // deassertion end // main loop where the coprocessor does work @(negedge CPA or posedge sysclk); if (CPA == 1) //trap begin @(posedge sysclk) enter_new_state(`FPU_1A); SC_Type = 5'b10000; // change mode RF_PC_Write_Sel = `RF_PC_WRITE_SEL_4; // mux 4 into PC; ir1_zero = 1; // clear out the pipeline SC_Source = `SC_CTRL_SELECT_SOURCE_UND_MODE; // select SVC mode end // if (CPA == 1) else begin ld_ir2_mult = 1; while (CPB != 0) begin @(posedge sysclk) enter_new_state(`FPU_2A); //waiting for them to finish nCPI = 0; nSTALL = 0; //stalling //ld_ir2_mult = 1; end @(posedge sysclk) enter_new_state(`FPU_2A); //waiting for them to finish nCPI = 0; nOPC = 1; nSTALL = 0; //stalling ld_ir2_mult = 0; // latch multicycle instruction. //end //else #1; //get ready for post-indexing for multicycle cases A_Addr_Sel = `RF_ADDR_A_SEL_IR2_MULT1916; SZE_Sel = `SZE_SEL_IR2_MUL70; RF_Addr_Write_Sel = `RF_ADDR_WRITE_SEL_IR2_MULT1916; nSTALL = 1; //not stalling if (ir2_mult_bus[24] == 0) //postindexing begin AR_Bus_ALU_Sel = `AR_BUS_ALU_SEL_ALU_RESULT;// selects ALU_RESULT AR_Bus_Sel = 2'b00; // Select AR_Bus_Alu input to Add Reg Alu_A_Sel = `ALU_A_SEL_A; // route A output to ALU input A BS_Input_Sel = `BS_INPUT_SEL_EXT; // Barrel Shifter input is zero extended immediate SZE_Ctrl = 0; SAM_Ctrl = `SHIFT_TYPE3; // Logical shift left by 2 if (ir2_mult_bus[23]==1) Alu_Cntrl = `ADD; else Alu_Cntrl = `SUB; 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 end //Write Back if (ir2_mult_bus[21] == 1) begin RF_Bus_Write_Sel = `RF_BUS_WRITE_SEL_ALU_RESULT; RF_Load_Write = 1; end end //else nSTALL = 1; //not stalling nCPI = 1; end //else if (ir2_bus[27:25] == 3'b110) else $display("other instructions..."); end // if (condx(ir2_bus[31:28],RF_PSR_Read)) end // else: !if(nIRQ == 0) end // forever @(sysclk end // always begin // ENTER NEW STATE TASK //////////////////////////////////////////////////// task enter_new_state; input [`NUM_STATE_BITS-1:0] this_state; begin present_state = this_state; // reset signals to their defaults //ir1_zero = 0; //ir2_zero = 0; //nOPC = 0; WD_Load = 0; WD_DBE = 0; RF_Load_Write = 0; if ((ir2_bus[27:24] != 4'b1011) && !((ir2_bus[27:22] == 6'b000000) && (ir2_bus[7:4] == 4'b1001))) Link_Sel = 0; // reset all other signals to 0... // Register File A_Addr_Sel = 0; B_Addr_Sel = 0; RF_Addr_Write_Sel = 3'b100; //RF_Bus_Write_Sel = 2'b00; RF_PC_Write_Sel = 4'b0110; RF_Load_Flags = 0; RF_PSR_R_Sel = 0; RF_PSR_W_Sel = 0; // Super CPSR SC_Type = 0; SC_Source = 0; // Zero/Sign Extender SZE_Sel = 2'b00; SZE_Ctrl = 0; // Barrel Shifter SAM_Ctrl = 2'b00; BS_Input_Sel = 0; BS_Enable = 0; BS_Cin = 0; // Address Register //AR_Bus_ALU_Sel = 0; //AR_Bus_Sel = 2'b01; //Coprocessor nCPI = 1; //Memory Interface nMREQ = 1; nRW = 0; //MAS = 2'b00; //ALU //Alu_A_Sel = 2'b00; Alu_Cntrl = 5'b00000; //Multiplier Multiplier_Enable = 0; //general ld_ir2_mult = 0; nSTALL = 1; BBUS_Src = 0; end endtask // enter_new_state // CONDX FUNCTION ////////////////////////////////////////////////////////// function condx; input [3:0] condtype; input [31:0] cpsr; begin case (condtype) 4'b0000: condx = cpsr[30]; // EQ 4'b0001: condx = !cpsr[30]; // NE 4'b0010: condx = cpsr[29]; // CS 4'b0011: condx = !cpsr[29]; // CC 4'b0100: condx = cpsr[31]; // MI 4'b0101: condx = !cpsr[31]; // PL 4'b0110: condx = cpsr[28]; // VS 4'b0111: condx = !cpsr[28]; // VC // 4'b1000: condx = cpsr[29] & !cpsr[30]; // HI 4'b1000: condx = cpsr[29] && !cpsr[30]; // HI`ifdef BUG1 4'b1001: condx = !cpsr[29] & cpsr[30]; // LS`else 4'b1001: condx = !cpsr[29] || cpsr[30]; // LS`endif 4'b1010: condx = cpsr[31] == cpsr[28]; // GE 4'b1011: condx = cpsr[31] != cpsr[28]; // LT 4'b1100: condx = !cpsr[30] && (cpsr[31] == cpsr[28]); // GT 4'b1101: condx = cpsr[30] || (cpsr[31] != cpsr[28]); // LE 4'b1110: condx = 1; // AL default: condx = 0; endcase // case(condtype) end endfunction // condx endmodule // armcontroller
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -