?? decoder_arm.v
字號:
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//i assume that there is at most 32 function component, each //
// at most have 8 entry outstand operation entry,so a byte will //
//be enough for the tomasulo source operand that come from //
//function component,if a source come from register file entry //
//then i will direct read it from register file and tag it as //
//ready //
//a all zero component entry means null device,and you can not //
//treat it like normal device //
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
`include "Def_StructureParameter.v"
`include "Def_RegisterFile.v"
`include "Def_ARMALU.v"
//`include "Def_ComponentEntry.v"
`include "Def_ALUType.v"
`include "Def_Decoder.v"
`include "Def_BarrelShift.v"
`include "Def_ALUType.v"
`include "Def_mem.v"
`include "Def_psr.v"
`include "Def_Mode.v"
`include "Def_Exception.v"
module Decoder_ARM( in_ValidInstruction_IFID,
in_PipelineRegister_IFID,
in_AddressGoWithInstruction,
in_NextInstructionAddress,
out_IDOwnCanGo,
//signal for register file
out_LeftReadRegisterEnable,
out_LeftReadRegisterNumber,
out_RightReadRegisterEnable,
out_RightReadRegisterNumber,
//use to read the shift count stored in register
out_ThirdReadRegisterEnable,
out_ThirdReadRegisterNumber,
//signal for register file
//signal for ALU
out_ALUEnable,
out_ALUType,
out_ALULeftRegister,
out_ALURightRegister,
out_ALUThirdRegister,
out_ALULeftFromImm,
out_ALURightFromImm,
out_ALUThirdFromImm,
out_CPSRFromImm,
out_SPSRFromImm,
out_ALUTargetRegister,
out_ALUExtendedImmediateValue, //extended 32bit immediate value ,go to right bus
out_ALURightShiftType,
out_ALUSecondImmediateValue, //serve as the shift count
out_SimpleALUType, //serve for the pre index mode of load/store
out_SimpleALUTargetRegister,
out_ALUMisc, //some special signal
out_ALUPSRType,
out_AddressGoWithInstruction2ALU,
out_NextAddressGoWithInstruction2ALU,
//signal for mem stage
out_MEMEnable,
out_MEMType,
out_MEMTargetRegister,
out_SimpleMEMType,
out_SimpleMEMTargetRegister,
out_MEMPSRType,
//Thumb state
in_ThumbState,
in_IsInPrivilegedMode,
//interrupt signal
in_TrueFiq,
in_TrueIrq,
//can AUL go
in_ALUCanGo,
//clear internal state
in_ChangePC,
in_MEMChangePC,
clock,
reset
);
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// input and output declaration //
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//signal come from if register
input in_ValidInstruction_IFID;
input [`InstructionWidth-1:0] in_PipelineRegister_IFID;
input [`AddressBusWidth-1:0] in_AddressGoWithInstruction,in_NextInstructionAddress;
//can id its own go
output out_IDOwnCanGo;
//the three read register signal
output out_LeftReadRegisterEnable,
out_RightReadRegisterEnable,
out_ThirdReadRegisterEnable;
output [`Def_RegisterSelectWidth-1:0] out_LeftReadRegisterNumber,
out_RightReadRegisterNumber,
out_ThirdReadRegisterNumber;
//signal go to alu execute stage
output out_ALUEnable; //only when there is space for new operation and a known valid instruction can it be 1'b1
output [`ByteWidth-1:0] out_ALUType; //what type of main alu thread
//the source operand register,the alu will use it to enable forwarding
output [`Def_RegisterSelectWidth-1:0] out_ALULeftRegister,
out_ALURightRegister,
out_ALUThirdRegister;
//if the source operand come from immediate value,then forwording will be disable
output out_ALULeftFromImm,
out_ALURightFromImm,
out_ALUThirdFromImm,
out_CPSRFromImm,
out_SPSRFromImm;
//target register of the main alu result,will be use to enable forwarding and write back
output [`Def_RegisterSelectWidth-1:0] out_ALUTargetRegister;
//the immediate value go to right operand of alu
output [`WordWidth-1:0] out_ALUExtendedImmediateValue;
//shift type of right operand
output [`Def_ShiftTypeWidth-1:0] out_ALURightShiftType;
//the shift count specify in immediate field,will go to the third read bus
output [`WordWidth-1:0] out_ALUSecondImmediateValue;
//simple thread operation type ad target register
output [`ByteWidth-1:0] out_SimpleALUType;
//will be use to write back and enable forwarding
output [`Def_RegisterSelectWidth-1:0] out_SimpleALUTargetRegister;
//some special signal
output [`WordWidth-1:0] out_ALUMisc;
output [`ByteWidth-1:0] out_ALUPSRType;
output [`AddressBusWidth-1:0] out_AddressGoWithInstruction2ALU,out_NextAddressGoWithInstruction2ALU;
reg [`AddressBusWidth-1:0] out_AddressGoWithInstruction2ALU,out_NextAddressGoWithInstruction2ALU;
//the operations for main mem and simple mem thread
//the alu stage will hold these information untill this instruction reach mem stage
output out_MEMEnable;
output [`ByteWidth-1:0] out_MEMType;
output [`Def_RegisterSelectWidth-1:0] out_MEMTargetRegister;
output [`ByteWidth-1:0] out_SimpleMEMType;
output [`Def_RegisterSelectWidth-1:0] out_SimpleMEMTargetRegister;
output [`ByteWidth-1:0] out_MEMPSRType;
//thumb state
input in_ThumbState;
input in_IsInPrivilegedMode;
//interrupt signal
input in_TrueFiq,in_TrueIrq;
//the decoder need to know if alu can go
//if not, decoder will not send out useful information
input in_ALUCanGo;
//branch signal
input in_ChangePC,in_MEMChangePC;
//global signal
input clock,reset;
//reg style declaration of output signal
reg out_IDOwnCanGo;
reg out_LeftReadRegisterEnable,
out_RightReadRegisterEnable,
out_ThirdReadRegisterEnable;
reg [`Def_RegisterSelectWidth-1:0] out_LeftReadRegisterNumber,
out_RightReadRegisterNumber,
out_ThirdReadRegisterNumber;
reg out_ALUEnable;
reg [`ByteWidth-1:0] out_ALUType;
reg out_ALULeftFromImm,
out_ALURightFromImm,
out_ALUThirdFromImm,
out_CPSRFromImm,
out_SPSRFromImm;
reg [`Def_RegisterSelectWidth-1:0] out_ALUTargetRegister;
reg [`WordWidth-1:0] out_ALUExtendedImmediateValue;
reg [`Def_ShiftTypeWidth-1:0] out_ALURightShiftType;
reg [`WordWidth-1:0] out_ALUSecondImmediateValue;
reg [`ByteWidth-1:0] out_SimpleALUType;
reg [`Def_RegisterSelectWidth-1:0] out_SimpleALUTargetRegister;
reg [`WordWidth-1:0] out_ALUMisc;
reg [`ByteWidth-1:0] out_ALUPSRType;
reg out_MEMEnable;
reg [`ByteWidth-1:0] out_MEMType;
reg [`Def_RegisterSelectWidth-1:0] out_MEMTargetRegister;
reg [`ByteWidth-1:0] out_SimpleMEMType;
reg [`Def_RegisterSelectWidth-1:0] out_SimpleMEMTargetRegister;
reg [`ByteWidth-1:0] out_MEMPSRType;
//these register will not be infer
//left right third read register
//main and simple thread target register
reg [`Def_RegisterSelectWidth-1:0] LeftRegisterNumber,
RightRegisterNumber,
ThirdRegisterNumber,
TargetRegisterNumber,
SecondTargetRegisterNumber;
//these register will not be infer
//if current register number will be access in LDM or STM
reg [`Def_RegisterSelectWidth-1:0] RegCountInLDMSTM;
reg IfCurrentRegAccessByLDMSTM;
reg IsFirstAccess;
//map ARM alu type to independante alu type
reg [`ByteWidth-1:0] ALUTypeMapped;
//in fact this three wire is exclusive to each other
//there will not use at the same time
//so some type of share method must be found to share the same adder
wire [`WordWidth-1:0] PCAdder4Result;
wire [`WordWidth-1:0] PCAdder8or4Result;
wire [`WordWidth-1:0] PCAdder12or4Result;
//pipeline register
//previous operation will write register from MEM
reg PrevOperationWantWriteRegisterFromMEM;
reg Next_PrevOperationWantWriteRegisterFromMEM;
reg [`Def_RegisterSelectWidth-1:0] PrevWriteRegister;
reg [`Def_RegisterSelectWidth-1:0] Next_PrevWriteRegister;
//use in block transfer for register number
reg [`Def_RegisterSelectWidth-1:0] IncRegNumber,DecRegNumber;
reg [`Def_RegisterSelectWidth-1:0] Next_IncRegNumber,Next_DecRegNumber;
wire [`Def_RegisterSelectWidth-1:0] IncRegNumberAdd1,DecRegNumberSub1;
wire [`WordWidth-1:0] Inc8or4,Inc12or4;
always @(in_PipelineRegister_IFID or
DecRegNumber or
IncRegNumber
)
begin
if(in_PipelineRegister_IFID[23]==1'b0)
begin//down
RegCountInLDMSTM=DecRegNumber;
if(DecRegNumber==`Def_RegisterSelectAllOne)
IsFirstAccess=1'b1;
else
IsFirstAccess=1'b0;
end
else
begin//up
RegCountInLDMSTM=IncRegNumber;
if(IncRegNumber==`Def_RegisterSelectZero)
IsFirstAccess=1'b1;
else
IsFirstAccess=1'b0;
end
end
always @(RegCountInLDMSTM or
in_PipelineRegister_IFID
)
begin
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[0];
case (RegCountInLDMSTM[3:0])
4'b0000:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[0];
4'b0001:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[1];
4'b0010:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[2];
4'b0011:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[3];
4'b0100:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[4];
4'b0101:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[5];
4'b0110:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[6];
4'b0111:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[7];
4'b1000:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[8];
4'b1001:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[9];
4'b1010:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[10];
4'b1011:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[11];
4'b1100:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[12];
4'b1101:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[13];
4'b1110:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[14];
4'b1111:
IfCurrentRegAccessByLDMSTM=in_PipelineRegister_IFID[15];
endcase
end
always @(posedge clock or negedge reset)
begin
if(reset==1'b0)
begin
PrevOperationWantWriteRegisterFromMEM=1'b0;
PrevWriteRegister=`Def_RegisterSelectZero;
IncRegNumber=`Def_RegisterSelectZero;
DecRegNumber=`Def_RegisterSelectAllOne;
end
else
begin
PrevOperationWantWriteRegisterFromMEM=Next_PrevOperationWantWriteRegisterFromMEM;
PrevWriteRegister=Next_PrevWriteRegister;
IncRegNumber=Next_IncRegNumber;
DecRegNumber=Next_DecRegNumber;
end
end
assign IncRegNumberAdd1=IncRegNumber+1;
assign DecRegNumberSub1=DecRegNumber-1;
//exclusive to each other, must found a method to share this adder
assign PCAdder4Result=in_AddressGoWithInstruction+32'h0000_0004;
assign Inc8or4=(in_ThumbState==1'b1)?32'h0000_0004:32'h0000_0008;
//STM in thumb state do not store pc, so use PCAdder12or4Result for stm pc will be ok
assign Inc12or4=(in_ThumbState==1'b1)?32'h0000_0004:32'h0000_000C;
assign PCAdder8or4Result=in_AddressGoWithInstruction+Inc8or4;
assign PCAdder12or4Result=in_AddressGoWithInstruction+Inc12or4;
//output
always @(in_ValidInstruction_IFID or
in_PipelineRegister_IFID or
in_ALUCanGo or
in_ThumbState or
in_TrueFiq or
in_TrueIrq or
in_NextInstructionAddress or
ALUTypeMapped or
LeftRegisterNumber or
RightRegisterNumber or
ThirdRegisterNumber or
TargetRegisterNumber or
SecondTargetRegisterNumber or
in_AddressGoWithInstruction or
PCAdder4Result or
PCAdder8or4Result or
PCAdder12or4Result or
PrevOperationWantWriteRegisterFromMEM or
PrevWriteRegister or
IncRegNumber or
IncRegNumberAdd1 or
DecRegNumber or
DecRegNumberSub1 or
IfCurrentRegAccessByLDMSTM
)
begin
//to prevent latch to be infer
//invalid instruction
out_LeftReadRegisterEnable=1'b0;
out_LeftReadRegisterNumber=`Def_RegisterSelectZero;
out_ALULeftFromImm=1'b0;
out_RightReadRegisterEnable=1'b0;
out_RightReadRegisterNumber=`Def_RegisterSelectZero;
out_ALURightFromImm=1'b0;
//third read bus will not be use
out_ThirdReadRegisterEnable=1'b0;
out_ThirdReadRegisterNumber=ThirdRegisterNumber;
out_ALUThirdFromImm=1'b0;
out_ALUEnable=1'b0;
out_ALUType=`ALUType_Null;
out_ALUTargetRegister=`Def_LinkRegister;
//no use here
out_ALURightShiftType=2'b00;
out_ALUExtendedImmediateValue=`WordDontCare;
out_ALUSecondImmediateValue=`WordDontCare;
out_IDOwnCanGo=1'b1;
//mem not enable
out_MEMEnable=1'b0;
out_MEMType=`MEMType_Null;
out_MEMTargetRegister=`Def_LinkRegister;
//simple alu will not be use
out_SimpleALUType=`ALUType_Null;
out_SimpleALUTargetRegister=`Def_LinkRegister;
out_ALUMisc=`WordZero;
//send out the condition code
out_ALUMisc[31:28]=in_PipelineRegister_IFID[31:28];
//simple MEM thread
out_SimpleMEMType=`MEMType_Null;
out_SimpleMEMTargetRegister=`Def_LinkRegister;
//condition code valid in alu and mem stage
out_ALUPSRType=`ALUPSRType_Null;
out_MEMPSRType=`MEMPSRType_Null;
//default is come from register
out_CPSRFromImm=1'b0;
out_SPSRFromImm=1'b0;
//only a branch or alu/load/store use pc as base will send address on this port
//out to LeftReadBus
out_AddressGoWithInstruction2ALU=`WordDontCare;
out_NextAddressGoWithInstruction2ALU=`WordZero;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -