📄 alushell.v
字号:
Next_MEMStoreDelayBranchTarget=1'b0;
Next_MEMDelayBranch=1'b0;
Next_MemAccessUserBankRegister=1'b0;
end
end
else
begin
//no new operation or previous instruction modify pc
Next_Valid=1'b0;
Next_ALUType=`ALUType_Null;
Next_LeftOperand=`WordZero;
Next_RightOperand=`WordZero;
Next_RightShiftType=`Def_ShiftTypeZero;
Next_RightShiftCount=`Def_ShiftCountZero;
Next_RightShiftCountHighBits=3'b000;
Next_RightShiftCountInReg=1'b0;
Next_Operand2IsReg=1'b0;
Next_TargetRegister=`Def_LinkRegister;
Next_CPSR=`WordZero;
Next_SPSR=`WordZero;
Next_StoredValue=`WordZero;
Next_SimpleALUType=`ALUType_Null;
Next_SimpleALUTargetRegister=`Def_LinkRegister;
Next_MEMType=`MEMType_Null;
Next_MEMTargetRegister=`Def_LinkRegister;
Next_SimpleMEMType=`MEMType_Null;
Next_SimpleMEMTargetRegister=`Def_LinkRegister;
Next_ALUPSRType=`ALUPSRType_Null;
Next_MEMPSRType=`MEMPSRType_Null;
Next_InstructionCondition=`ConditionField_NV;
Next_NextAddressGoWithInstruction2ALU=`AddressBusZero;
Next_IsBranch=1'b0;
Next_IsLoadToPC=1'b0;
Next_ALUOwnCanGo=1'b1;
Next_IfChangeState=1'b0;
Next_ChangeStateAction=5'b00000;
Next_MEMStoreDelayBranchTarget=1'b0;
Next_MEMDelayBranch=1'b0;
Next_MEMStoreDelayBranchTarget=1'b0;
Next_MEMDelayBranch=1'b0;
Next_MemAccessUserBankRegister=1'b0;
end
end
else
begin
//alu can not go
//save current state
Next_Valid=Valid;
Next_ALUType=ALUType;
Next_LeftOperand=LeftOperand;
Next_RightOperand=RightOperand;
Next_RightShiftType=RightShiftType;
Next_RightShiftCount=RightShiftCount;
Next_RightShiftCountHighBits=RightShiftCountHighBits;
Next_RightShiftCountInReg=RightShiftCountInReg;
Next_Operand2IsReg=Operand2IsReg;
Next_TargetRegister=TargetRegister;
Next_SimpleALUType=SimpleALUType;
Next_SimpleALUTargetRegister=SimpleALUTargetRegister;
Next_MEMType=MEMType;
Next_MEMTargetRegister=MEMTargetRegister;
Next_SimpleMEMType=SimpleMEMType;
Next_SimpleMEMTargetRegister=SimpleMEMTargetRegister;
Next_CPSR=CPSR;
Next_SPSR=SPSR;
Next_StoredValue=StoredValue;
Next_ALUPSRType=ALUPSRType;
Next_MEMPSRType=MEMPSRType;
Next_InstructionCondition=InstructionCondition;
Next_NextAddressGoWithInstruction2ALU=NextAddressGoWithInstruction2ALU;
Next_IsBranch=IsBranch;
Next_IsLoadToPC=IsLoadToPC;
Next_ALUOwnCanGo=ALUOwnCanGo;
Next_IfChangeState=IfChangeState;
Next_ChangeStateAction=ChangeStateAction;
Next_MEMStoreDelayBranchTarget=MEMStoreDelayBranchTarget;
Next_MEMDelayBranch=MEMDelayBranch;
Next_MemAccessUserBankRegister=MemAccessUserBankRegister;
end
end
//assign new computing
assign ALUComb_ALUType=ALUType;
assign ALUComb_LeftOperand=LeftOperand;
assign ALUComb_RightOperand=RightOperand;
assign ALUComb_ThirdOperand=StoredValue;
assign ALUComb_RightOperandShiftType=RightShiftType;
assign ALUComb_RightOperandShiftCount=RightShiftCount;
assign ALUComb_ShiftCountInReg=RightShiftCountInReg;
assign ALUComb_ShiftCountHigh3Bit=RightShiftCountHighBits;
assign ALUComb_Operand2IsReg=Operand2IsReg;
assign ALUComb_Carry=CPSR[`CarryPos];
assign ALUComb_Overflow=CPSR[`OverflowPos];
assign ALUComb_Neg=CPSR[`NegPos];
assign ALUComb_Zero=CPSR[`ZeroPos];
//assign output result
assign out_ALUWriteBus=(out_ALUWriteEnable==1'b1)?ALUCombResult:`WordZero;
assign out_ALUTargetRegister=(out_ALUWriteEnable==1'b1 && out_ALUOwnCanGo==1'b1)?TargetRegister:`Def_LinkRegister;
assign out_ALUPSRType=ALUPSRType;
assign out_ALUOwnCanGo=ALUOwnCanGo;
//pass these mem operation from decoder to mem stage
assign out_MEMType=MEMType;
assign out_MEMTargetRegister=MEMTargetRegister;
assign out_SimpleMEMType=SimpleMEMType;
assign out_SimpleMEMTargetRegister=(Valid==1'b1 && out_ALUOwnCanGo==1'b1)?SimpleMEMTargetRegister:`Def_LinkRegister;
assign out_StoredValue=StoredValue;
assign out_MEMPSRType=MEMPSRType;
assign out_IsLoadToPC=IsLoadToPC;
assign out_IfChangeState=IfChangeState;
assign out_ChangeStateAction=ChangeStateAction;
assign out_MEMStoreDelayBranchTarget=MEMStoreDelayBranchTarget;
assign out_MEMDelayBranch=MEMDelayBranch;
assign out_MemAccessUserBankRegister=MemAccessUserBankRegister;
//deal with simple ALU
always @(SimpleALUType or
LeftOperand or
RightOperand or
SimpleALUTargetRegister or
CPSR or
SPSR or
NextAddressGoWithInstruction2ALU
)
begin
case (SimpleALUType)
`ALUType_Mvl:
out_SimpleALUResult=LeftOperand;
`ALUType_Mvr:
out_SimpleALUResult=RightOperand;
`ALUType_MvCPSR:
out_SimpleALUResult=CPSR;
`ALUType_MvSPSR:
out_SimpleALUResult=SPSR;
`ALUType_MvNextInstructionAddress:
out_SimpleALUResult={NextAddressGoWithInstruction2ALU[`AddressBusWidth-1:1],CPSR[`ThumbPos]};
default:
out_SimpleALUResult=`WordZero;
endcase
out_SimpleALUTargetRegister=SimpleALUTargetRegister;
end
//deal with psr thread
always @(in_Neg or
in_Zero or
in_Carry or
in_Overflow or
CPSR or
SPSR or
ALUPSRType or
ALUCombResult or
RightOperand
)
begin
case(ALUPSRType)
`ALUPSRType_WriteConditionCode:
begin
//for normal alu instruction to write condition code
out_CPSR={in_Neg,in_Zero,in_Carry,in_Overflow,CPSR[27:0]};
out_SPSR=SPSR;
end
`ALUPSRType_WriteCPSR:
begin
//for psr transfer to write cpsr
out_CPSR=CPSR;
out_SPSR=SPSR;
end
`ALUPSRType_SPSR2CPSR:
begin
//write spsr to cpsr
out_CPSR=SPSR;
out_SPSR=SPSR;
end
`ALUPSRType_WriteSPSR:
begin
//write whole spsr
out_CPSR=CPSR;
out_SPSR=SPSR;
end
`ALUPSRType_Right2CPSR:
begin
out_CPSR=RightOperand;
out_SPSR=SPSR;
end
`ALUPSRType_Right2SPSR:
begin
out_CPSR=CPSR;
out_SPSR=RightOperand;
end
`ALUPSRType_ALUResultAsConditionCode2CPSR:
begin
//add alu result as condition code to cpsr
out_CPSR={ALUCombResult[31:28],CPSR[27:0]};
out_SPSR=SPSR;
end
`ALUPSRType_ALUResultAsConditionCode2SPSR:
begin
//add alu result as condition code to spsr
out_SPSR={ALUCombResult[31:28],SPSR[27:0]};
out_CPSR=CPSR;
end
`ALUPSRType_CPSR2SPSR:
begin
out_SPSR=CPSR;
out_CPSR=CPSR;
end
`ALUPSRType_ModifyThumbState:
begin
out_SPSR=SPSR;
out_CPSR=CPSR;
//the address bit 0 is new thumb state
out_CPSR[`ThumbPos]=RightOperand[0];
end
default:
begin
out_CPSR=CPSR;
out_SPSR=SPSR;
end
endcase
if(IfChangeState==1'b1)
begin
//an exception arise
//change mode
out_CPSR[4:0]=ChangeStateAction;
//switch to ARM state
out_CPSR[`ThumbPos]=1'b0;
//disable interrupt
out_CPSR[`FiqPos]=1'b1;
out_CPSR[`IrqPos]=1'b1;
end
end
//determine if the condition field is satisfied
always @(CPSR or
Valid or
InstructionCondition
)
begin
//defalut is 1'b0
out_ALUWriteEnable=1'b0;
if(Valid==1'b0)
begin
out_ALUWriteEnable=1'b0;
end
else
begin
//a vlid instruction
//but still do not decide if it can satisfy the condition field
case (InstructionCondition)
`ConditionField_EQ: //Z set(equal)
begin
if(CPSR[`ZeroPos]==1'b1)
out_ALUWriteEnable=1'b1;
end
`ConditionField_NE: //Z clear(not equal)
begin
if(CPSR[`ZeroPos]==1'b0)
out_ALUWriteEnable=1'b1;
end
`ConditionField_CS: //C set(unsigned higher or same)
begin
if(CPSR[`CarryPos]==1'b1)
out_ALUWriteEnable=1'b1;
end
`ConditionField_CC: //C clear(unsigned lower)
begin
if(CPSR[`CarryPos]==1'b0)
out_ALUWriteEnable=1'b1;
end
`ConditionField_MI: //N set(negative)
begin
if(CPSR[`NegPos]==1'b1)
out_ALUWriteEnable=1'b1;
end
`ConditionField_PL: //N clear(positive or zero)
begin
if(CPSR[`NegPos]==1'b0)
out_ALUWriteEnable=1'b1;
end
`ConditionField_VS: //V set(overflow)
begin
if(CPSR[`OverflowPos]==1'b1)
out_ALUWriteEnable=1'b1;
end
`ConditionField_VC: //V clear(no overflow)
begin
if(CPSR[`OverflowPos]==1'b0)
out_ALUWriteEnable=1'b1;
end
`ConditionField_HI: //C set and Z clear(unsigned higher,see ConditionField_CS)
begin
if(CPSR[`CarryPos]==1'b1 && CPSR[`ZeroPos]==1'b0)
out_ALUWriteEnable=1'b1;
end
`ConditionField_LS: //C clear or Z set(unsigned lower or same see ConditionField_CC)
begin
if(CPSR[`CarryPos]==1'b0 || CPSR[`ZeroPos]==1'b1)
out_ALUWriteEnable=1'b1;
end
`ConditionField_GE: //N set and V set, or N clear and V clear(greater or equal)
begin
if((CPSR[`NegPos]==1'b1 && CPSR[`OverflowPos]==1'b1) || (CPSR[`NegPos]==1'b0 && CPSR[`OverflowPos]==1'b0))
out_ALUWriteEnable=1'b1;
end
`ConditionField_LT: //N set and V clear,or N clear and V set(less than)
begin
if((CPSR[`NegPos]==1'b1 && CPSR[`OverflowPos]==1'b0) || (CPSR[`NegPos]==1'b0 && CPSR[`OverflowPos]==1'b1))
out_ALUWriteEnable=1'b1;
end
`ConditionField_GT: //Z clear, and either N set and V set, or N clear and V clear (greater than)
begin
if(CPSR[`ZeroPos]==1'b0 && ((CPSR[`NegPos]==1'b1 && CPSR[`OverflowPos]==1'b1) || (CPSR[`NegPos]==1'b0 && CPSR[`OverflowPos]==1'b0)))
out_ALUWriteEnable=1'b1;
end
`ConditionField_LE: //Z set, or N set and V clear, or N clear and V set (less than or equal)
begin
if(CPSR[`ZeroPos]==1'b1 || (CPSR[`NegPos]==1'b1 && CPSR[`OverflowPos]==1'b0) || (CPSR[`NegPos]==1'b0 && CPSR[`OverflowPos]==1'b1))
out_ALUWriteEnable=1'b1;
end
`ConditionField_AL: //always execute
begin
out_ALUWriteEnable=1'b1;
end
`ConditionField_NV: //never execute
begin
out_ALUWriteEnable=1'b0;
end
endcase
end
end
//determine change pc in branch instruction
always @(IsBranch or
out_ALUWriteEnable or
ALUCombResult
)
begin
if(IsBranch==1'b1)
begin
if(out_ALUWriteEnable==1'b1)
begin
out_ChangePC=1'b1;
out_NewPC={ALUCombResult[`WordWidth-1:2],out_CPSR[`ThumbPos]&ALUCombResult[1],1'b0};//half word align
end
else
begin
out_ChangePC=1'b0;
out_NewPC={ALUCombResult[`WordWidth-1:2],out_CPSR[`ThumbPos]&ALUCombResult[1],1'b0};
end
end
else
begin
out_ChangePC=1'b0;
out_NewPC={ALUCombResult[`WordWidth-1:2],out_CPSR[`ThumbPos]&ALUCombResult[1],1'b0};
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -