📄 decoder_arm.v
字号:
begin
//write right operand to spsr
out_ALUPSRType=`ALUPSRType_Right2SPSR;
out_MEMPSRType=`MEMPSRType_WriteSPSR;
end
else
begin
//write right to cpsr
out_ALUPSRType=`ALUPSRType_Right2CPSR;
out_MEMPSRType=`MEMPSRType_WriteCPSR;
end
end
else if(`Def_IsMSRCondition)
begin
out_ALUEnable=1'b1;
// i want to add alu result to imm to form new psr
out_ALUType=`ALUType_Mov;
if(in_PipelineRegister_IFID[22]==1'b0)
begin
out_ALUPSRType=`ALUPSRType_ALUResultAsConditionCode2CPSR;
out_MEMPSRType=`MEMPSRType_WriteCPSR;
end
else
begin
out_ALUPSRType=`ALUPSRType_ALUResultAsConditionCode2SPSR;
out_MEMPSRType=`MEMPSRType_WriteSPSR;
end
//deal with right operand
if(in_PipelineRegister_IFID[25]==1'b0)
begin
//right operand come from register
out_RightReadRegisterEnable=1'b1;
out_RightReadRegisterNumber=RightRegisterNumber;
out_ALURightFromImm=1'b0;
//shift type and count
out_ALURightShiftType=2'b00;
out_ALUThirdFromImm=1'b1;
out_ALUSecondImmediateValue=`WordZero;
end
else
begin
//right operand come from imm
out_RightReadRegisterEnable=1'b0;
out_RightReadRegisterNumber=RightRegisterNumber;
out_ALURightFromImm=1'b1;
out_ALUExtendedImmediateValue={24'h000000,in_PipelineRegister_IFID[7:0]};
//shift type and count
out_ALURightShiftType=`Def_ShiftType_RotateRight;
out_ALUThirdFromImm=1'b1;
out_ALUSecondImmediateValue={27'b0000_0000_0000_0000_0000_0000_000,in_PipelineRegister_IFID[11:8],1'b0};
end
end
else if(`Def_IsALUInstruction)
begin
//ALU operation
if(in_PipelineRegister_IFID[25]==1'b0)
begin
// op two register together
//19:16 is the first operand
//3:0 is the second source operand
//$monitor($time,"go to two reg ALU");
//deal with left operand
//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
if(in_PipelineRegister_IFID[4]==1'b1)
out_AddressGoWithInstruction2ALU=PCAdder12or4Result;
else
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
//right source register can be direct read
out_RightReadRegisterEnable=1'b1;
out_RightReadRegisterNumber=RightRegisterNumber;
//right operand are not from immediate
out_ALURightFromImm=1'b0;
//you have deal with the unshifted right operand
//but you must deal with shift type and shift count
out_ALURightShiftType=in_PipelineRegister_IFID[6:5];
//shift count
if(in_PipelineRegister_IFID[4]==1'b0)
begin
//shift count given in instruction
//no need to read shift count from register file
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=`Def_RegisterSelectZero;
//ALU must open to read in shift count
//shift count is a immediate
out_ALUThirdFromImm=1'b1;
out_ALUSecondImmediateValue={27'b0000_0000_0000_0000_0000_0000_000,in_PipelineRegister_IFID[11:7]};
end
else
begin
//the shift count given in a register
out_ALUSecondImmediateValue=`WordDontCare;
//this register can be direct read
out_ThirdReadRegisterEnable=1'b1;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
//shift count is not imm
out_ALUThirdFromImm=1'b0;
end
out_ALUExtendedImmediateValue=`WordDontCare;
//a valid ALU
out_ALUEnable=1'b1;
out_ALUType=ALUTypeMapped;
//these instruction will not write result,just set status psr
if(`Def_IsNoResultWritenInstruction)
begin
out_ALUTargetRegister=`Def_LinkRegister;
out_MEMEnable=1'b0;
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
end
else if(TargetRegisterNumber==`Def_PCNumber)//pc will not be forward or write to register file by mem stage
begin
out_ALUTargetRegister=`Def_LinkRegister;
out_MEMEnable=1'b0;
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
end
else
begin
out_ALUTargetRegister=TargetRegisterNumber;
out_MEMEnable=1'b1;
out_MEMType=`MEMType_MovMain;
out_MEMTargetRegister=TargetRegisterNumber;
end
out_IDOwnCanGo=1'b1;
//simple thread will not be use in write to R15 or other register
out_SimpleALUType=`ALUType_Null;
//simple lu thread will not attend forwarding
out_SimpleALUTargetRegister=`Def_LinkRegister;
//simple MEM thread will not be use in write to r15 or other register
out_SimpleMEMType=`MEMType_Null;
//simple mem thread will not attend forwarding
out_SimpleMEMTargetRegister=`Def_LinkRegister;
out_ALUMisc=`WordZero;
out_ALUMisc[31:28]=in_PipelineRegister_IFID[31:28];
//main thread result must be used to change pc
//output new pc to IF using main alu
if(TargetRegisterNumber==`Def_PCNumber)
out_ALUMisc[6]=1'b1;
else
out_ALUMisc[6]=1'b0;
//default is come from register
out_CPSRFromImm=1'b0;
out_SPSRFromImm=1'b0;
end//the second operand come from register
else
begin
//the second operand is a immediate value
//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
//right read bus here will not be use
out_RightReadRegisterNumber=RightRegisterNumber;
//right register will not be use
out_RightReadRegisterEnable=1'b0;
//ALU must read extended immediate value from RightReadBus
//the value come from the decoder
out_ALURightFromImm=1'b1;
//send out imediate value
out_ALUExtendedImmediateValue={24'h000000,in_PipelineRegister_IFID[7:0]};
//third read bus will be use
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
out_ALUThirdFromImm=1'b1;
//shift type and count
//rotate at twice the value of rotate field
out_ALURightShiftType=`Def_ShiftType_RotateRight;
out_ALUSecondImmediateValue={24'h000000,3'b000,in_PipelineRegister_IFID[11:8],1'b0};
//a valid ALU
out_ALUEnable=1'b1;
out_ALUType=ALUTypeMapped;
//these instruction will not write result,just set status psr
if(`Def_IsNoResultWritenInstruction)
begin
out_ALUTargetRegister=`Def_LinkRegister;
out_MEMEnable=1'b0;
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
end
else if(TargetRegisterNumber==`Def_PCNumber)//pc will not be forward or write to register file by mem stage
begin
out_ALUTargetRegister=`Def_LinkRegister;
out_MEMEnable=1'b0;
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
end
else
begin
out_ALUTargetRegister=TargetRegisterNumber;
out_MEMEnable=1'b1;
out_MEMType=`MEMType_MovMain;
out_MEMTargetRegister=TargetRegisterNumber;
end
out_IDOwnCanGo=1'b1;
//simple thread will not be use in write to R15 or other register
out_SimpleALUType=`ALUType_Null;
out_SimpleALUTargetRegister=`Def_LinkRegister;
//simple MEM thread will not be use in write to r15 or other register
out_SimpleMEMType=`MEMType_Null;
out_SimpleMEMTargetRegister=`Def_LinkRegister;
out_ALUMisc=`WordZero;
out_ALUMisc[31:28]=in_PipelineRegister_IFID[31:28];
//main thread result must be used to change pc
//output new pc to IF using main alu
if(TargetRegisterNumber==`Def_PCNumber)
out_ALUMisc[6]=1'b1;
else
out_ALUMisc[6]=1'b0;
//default is come from register
out_CPSRFromImm=1'b0;
out_SPSRFromImm=1'b0;
end//the second operand come from imm
//now deal with the status bit of psr
if(in_PipelineRegister_IFID[20]==1'b1)
begin
//set condition code in psr
if(TargetRegisterNumber!=`Def_PCNumber)
begin
//just set condition code
out_ALUPSRType=`ALUPSRType_WriteConditionCode;
out_MEMPSRType=`MEMPSRType_WriteConditionCode;
end
else
begin
//restore spsr to cpsr
out_ALUPSRType=`ALUPSRType_SPSR2CPSR;
out_MEMPSRType=`MEMPSRType_WriteCPSR;
end
end
else
begin
out_ALUPSRType=`ALUPSRType_Null;
out_MEMPSRType=`MEMPSRType_Null;
end
end//alu instruction
else if(`Def_IsLoadInstruction)
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 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
out_ALUSecondImmediateValue={24'h000000,3'b000,in_PipelineRegister_IFID[11:7]};
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
out_ALUSecondImmediateValue=`WordZero;
end
//third read bus will be use
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
out_ALUThirdFromImm=1'b1;
//a valid ALU
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 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;
if(in_PipelineRegister_IFID[22]==1'b1)
out_MEMType=`MEMType_LoadMainByte;
else
out_MEMType=`MEMType_LoadMainWord;
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
else
begin
//no need to write back
//only when now can the base register be r15
//because the r15 can not be 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_LoadMainByte;
else
out_MEMType=`MEMType_LoadMainWord;
if(TargetRegisterNumber==`Def_PCNumber)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -