?? decoder_arm.v
字號:
out_MEMTargetRegister=`Def_LinkRegister;
else
out_MEMTargetRegister=TargetRegisterNumber;
//simple thread of mem stage
out_SimpleMEMType=`MEMType_Null;
out_SimpleMEMTargetRegister=`Def_LinkRegister;
end
end
else
begin
//post index
//perform alu but use origin base as address to load
//in this mode the write back bit is always 1'b0
//but the alu result must ALWAYS WRITE BACK to base register
//because if you do not want to write back, you do not need this address mode,
// a normal address mode with 0 offset will be enough
//so main alu thread compute the result,main mem thread will load according to simple alu result
//simple alu will pass leftoperand(base) to main mem,simple mem will pass main alu result to write
out_SimpleALUType=`ALUType_Mvl;
out_SimpleALUTargetRegister=`Def_LinkRegister;
out_ALUTargetRegister=LeftRegisterNumber;
//main thread of mem stage
out_MEMEnable=1'b1;
if(in_PipelineRegister_IFID[22]==1'b1)
out_MEMType=`MEMType_LoadSimpleByte;
else
out_MEMType=`MEMType_LoadSimpleWord;
if(TargetRegisterNumber==`Def_PCNumber)
out_MEMTargetRegister=`Def_LinkRegister;
else
out_MEMTargetRegister=TargetRegisterNumber;
//simple thread of mem stage
out_SimpleMEMType=`MEMType_MovMain;
out_SimpleMEMTargetRegister=LeftRegisterNumber;
end
out_IDOwnCanGo=1'b1;
//when target register is pc,then this bit will tell mem stage to write loaded value to if
if(TargetRegisterNumber==`Def_PCNumber)
out_ALUMisc[7]=1'b1;
Next_PrevOperationWantWriteRegisterFromMEM=1'b1;
Next_PrevWriteRegister=TargetRegisterNumber;
end//load instruction
else if(`Def_IsStoreInstruction)
begin
//left source register can be direct read
if(LeftRegisterNumber==`Def_PCNumber)
begin
//left register is pc
//do not read register file
//just send out pc on out_AddressGoWithInstruction2ALU
out_AddressGoWithInstruction2ALU=PCAdder8or4Result;
out_LeftReadRegisterEnable=1'b0;
out_LeftReadRegisterNumber=LeftRegisterNumber;
//left come from imm pc
//do not forward
out_ALULeftFromImm=1'b1;
end
else
begin
//left register is not pc
out_LeftReadRegisterEnable=1'b1;
out_LeftReadRegisterNumber=LeftRegisterNumber;
//left operand are not from immediate
out_ALULeftFromImm=1'b0;
end
//deal with the offset
//right read bus
if(in_PipelineRegister_IFID[25]==1'b1)
begin
//offset come from register and need a shift
out_RightReadRegisterNumber=RightRegisterNumber;
out_RightReadRegisterEnable=1'b1;
out_ALURightFromImm=1'b0;
//imm is not need here
out_ALUExtendedImmediateValue=`WordDontCare;
//shift type
out_ALURightShiftType=in_PipelineRegister_IFID[6:5];
//shift ammount
//use out_ALUMisc to pass shift count
// the third read register bus will be use as store value read
out_ALUMisc[5:0]={in_PipelineRegister_IFID[11:7],1'b1};
end
else
begin
//offset come from imm in instruction
out_RightReadRegisterNumber=RightRegisterNumber;
out_RightReadRegisterEnable=1'b0;
out_ALURightFromImm=1'b1;
//imm act as offset
out_ALUExtendedImmediateValue={20'h00000,in_PipelineRegister_IFID[11:0]};
out_ALURightShiftType=in_PipelineRegister_IFID[6:5];
//shift ammount is always 0
//use out_ALUMisc to pass shift count
// the third read register bus will be use as store value read
out_ALUMisc[5:0]={6'b000001};
end
//third read bus will be use to read store value
if(ThirdRegisterNumber==`Def_PCNumber)
begin
out_ALUSecondImmediateValue=PCAdder12or4Result;
//do not read register
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
//can not be forward
out_ALUThirdFromImm=1'b1;
end
else
begin
out_ALUSecondImmediateValue=`WordDontCare;
out_ThirdReadRegisterEnable=1'b1;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
//can be forward
out_ALUThirdFromImm=1'b0;
end
out_ALUEnable=1'b1;
//add or sub the offset from base
if(in_PipelineRegister_IFID[23]==1'b1)
begin
//add
out_ALUType=`ALUType_Add;
end
else
begin
//sub
out_ALUType=`ALUType_Sub;
end
//deal with the case of pre or post index
if(in_PipelineRegister_IFID[24]==1'b1)
begin
//pre index
//first perform alu then use result as the address to store
out_SimpleALUType=`ALUType_Null;
out_SimpleALUTargetRegister=`Def_LinkRegister;
if(in_PipelineRegister_IFID[21]==1'b1)
begin
//write back alu result to base register
out_ALUTargetRegister=LeftRegisterNumber;
//main thread of mem stage
out_MEMEnable=1'b1;
if(in_PipelineRegister_IFID[22]==1'b1)
out_MEMType=`MEMType_StoreMainByte;
else
out_MEMType=`MEMType_StoreMainWord;
out_MEMTargetRegister=`Def_LinkRegister;
//simple thread of mem stage
out_SimpleMEMType=`MEMType_MovMain;
out_SimpleMEMTargetRegister=LeftRegisterNumber;
end
else
begin
//no need to write back
out_ALUTargetRegister=`Def_LinkRegister;
//main thread of mem stage
out_MEMEnable=1'b1;
if(in_PipelineRegister_IFID[22]==1'b1)
out_MEMType=`MEMType_StoreMainByte;
else
out_MEMType=`MEMType_StoreMainWord;
out_MEMTargetRegister=`Def_LinkRegister;
//simple thread of mem stage
out_SimpleMEMType=`MEMType_Null;
out_SimpleMEMTargetRegister=`Def_LinkRegister;
end
end
else
begin
//post index
//perform alu but use origin base as address to load
//in this mode the write back bit is always 1'b0
//but the alu result must ALWAYS WRITE BACK to base register
//because if you do not want to write back, you do not need this address mode,
// a normal address mode with 0 offset will be enough
//so main alu thread compute the result,main mem thread will load according to simple alu result
//simple alu will pass leftoperand(base) to main mem,simple mem will pass main alu result to write
out_SimpleALUType=`ALUType_Mvl;
out_SimpleALUTargetRegister=`Def_LinkRegister;
out_ALUTargetRegister=LeftRegisterNumber;
//main thread of mem stage
out_MEMEnable=1'b1;
if(in_PipelineRegister_IFID[22]==1'b1)
out_MEMType=`MEMType_StoreSimpleByte;
else
out_MEMType=`MEMType_StoreSimpleWord;
out_MEMTargetRegister=`Def_LinkRegister;
//simple thread of mem stage
out_SimpleMEMType=`MEMType_MovMain;
out_SimpleMEMTargetRegister=LeftRegisterNumber;
end
out_IDOwnCanGo=1'b1;
end
else if(`Def_IsLDM)
begin
if(in_PipelineRegister_IFID[23]==1'b0)
begin//down
if(DecRegNumber[7:4]==4'b1110)
begin
//perform delayed branch
//except delay branch signal, nothing is use
out_LeftReadRegisterEnable=1'b0;
out_LeftReadRegisterNumber=LeftRegisterNumber;
out_ALULeftFromImm=1'b1;
//deal with offset
out_RightReadRegisterNumber=RightRegisterNumber;
out_RightReadRegisterEnable=1'b0;
out_ALURightFromImm=1'b1;
out_ALUExtendedImmediateValue=32'h0000_0000;
out_ALURightShiftType=`Def_ShiftType_LogicLeft;
//shift ammount is always 0
out_ALUSecondImmediateValue=`WordZero;
//third read bus will be use
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
out_ALUThirdFromImm=1'b1;
//a valid ALU
out_ALUEnable=1'b1;
//sub 4 from current register
out_ALUType=`ALUType_Sub;
out_ALUTargetRegister=`Def_LinkRegister;
out_SimpleALUType=`ALUType_Null;
out_SimpleALUTargetRegister=`Def_LinkRegister;
//main thread of mem stage
out_MEMEnable=1'b1;
//always load word
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
//simple thread of mem stage
out_SimpleMEMType=`MEMType_Null;
out_SimpleMEMTargetRegister=`Def_LinkRegister;
out_IDOwnCanGo=1'b1;
//out_ALUMisc[14] means delay branch
if(in_PipelineRegister_IFID[15]==1'b1)
out_ALUMisc[14]=1'b1;
else
out_ALUMisc[14]=1'b0;
//out_ALUMisc[15] means store delay branch target
out_ALUMisc[15]=1'b0;
if(in_IsInPrivilegedMode==1'b1 && in_PipelineRegister_IFID[15]==1'b1 && in_PipelineRegister_IFID[22]==1'b1)
begin
//condition code valid in alu and mem stage
out_ALUPSRType=`ALUPSRType_SPSR2CPSR;
out_MEMPSRType=`MEMPSRType_WriteCPSR;
end
Next_IncRegNumber=`Def_RegisterSelectZero;
Next_DecRegNumber=`Def_RegisterSelectAllOne;
Next_PrevOperationWantWriteRegisterFromMEM=1'b0;
Next_PrevWriteRegister=`Def_LinkRegister;
end//of DecRegNumber[7:4]==4'b1110
else
begin
out_LeftReadRegisterEnable=1'b1;
//if write back is need, then just read left register as base
//if write back is not need and it is the first access ,also read left register as base
// if write back is not need and it is not the first access, then just use LocalForwardRegister
if(in_PipelineRegister_IFID[21]==1'b1 || IsFirstAccess==1'b1)
out_LeftReadRegisterNumber=LeftRegisterNumber;
else
out_LeftReadRegisterNumber=`Def_LocalForwardRegister;
//left operand are not from immediate
out_ALULeftFromImm=1'b0;
//deal with offset
//offset come from imm in instruction
out_RightReadRegisterNumber=RightRegisterNumber;
out_RightReadRegisterEnable=1'b0;
out_ALURightFromImm=1'b1;
//imm act as offset
if(IfCurrentRegAccessByLDMSTM==1'b1)
out_ALUExtendedImmediateValue=32'h0000_0004;
else
out_ALUExtendedImmediateValue=32'h0000_0000;
out_ALURightShiftType=`Def_ShiftType_LogicLeft;
//shift ammount is always 0
out_ALUSecondImmediateValue=`WordZero;
//third read bus will be use
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
out_ALUThirdFromImm=1'b1;
//a valid ALU
out_ALUEnable=1'b1;
//sub 4 from current register
out_ALUType=`ALUType_Sub;
//deal with the case of pre or post index
if(in_PipelineRegister_IFID[24]==1'b1)
begin
//pre index
//first perform alu then use result as the address to load
out_SimpleALUType=`ALUType_Null;
out_SimpleALUTargetRegister=`Def_LinkRegister;
if(in_PipelineRegister_IFID[21]==1'b1)
begin
//write back alu result to base register
out_ALUTargetRegister=LeftRegisterNumber;
//main thread of mem stage
out_MEMEnable=1'b1;
//always load word
if(IfCurrentRegAccessByLDMSTM==1'b1)
begin
out_MEMType=`MEMType_LoadMainWord;
if({4'b0000,DecRegNumber[3:0]}==`Def_PCNumber)
out_MEMTargetRegister=`Def_LinkRegister;
else
out_MEMTargetRegister={4'b0000,DecRegNumber[3:0]};
end
else
begin
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
end
//simple thread of mem stage
out_SimpleMEMType=`MEMType_MovMain;
out_SimpleMEMTargetRegister=LeftRegisterNumber;
end
else
begin
//no need to write back
//so just write base value to Def_LocalForwardRegister
out_ALUTargetRegister=`Def_LocalForwardRegister;
//main thread of mem stage
out_MEMEnable=1'b1;
//always load word
if(IfCurrentRegAccessByLDMSTM==1'b1)
begin
out_MEMType=`MEMType_LoadMainWord;
if({4'b0000,DecRegNumber[3:0]}==`Def_PCNumber)
out_MEMTargetRegister=`Def_LinkRegister;
else
out_MEMTargetRegister={4'b0000,DecRegNumber[3:0]};
end
else
begin
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
end
//simple thread of mem stage
//no need to write back, so just write the modified base to Def_LocalForwardRegister
out_SimpleMEMType=`MEMType_MovMain;
out_SimpleMEMTargetRegister=`Def_LocalForwardRegister;
end
end
else
begin
//post index
//perform alu but use origin base as address to load
out_SimpleALUType=`ALUType_Mvl;
out_SimpleALUTargetRegister=`Def_LinkRegister;
if(in_PipelineRegister_IFID[21]==1'b1)
begin
out_ALUTargetRegister=LeftRegisterNumber;
//main thread of mem stage
out_MEMEnable=1'b1;
//always load word
if(IfCurrentRegAccessByLDMSTM==1'b1)
begin
out_MEMType=`MEMType_LoadSimpleWord;
if({4'b0000,DecRegNumber[3:0]}==`Def_PCNumber)
out_MEMTargetRegister=`Def_LinkRegister;
else
out_MEMTargetRegister={4'b0000,DecRegNumber[3:0]};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -