📄 if.v
字号:
/*
Daniel L. Rosenband
10/4/99
*/
module IF (/*AUTOARG*/
// Outputs
IAddr, IIF2RF, IIF2RFUnlatched, LinkPC, PCP8, LinkPCAddr,
// Inputs
MClk, IFClkEN, NewProg, IIn, AEqB, AEq0, ALt0, RaData
);
output [31:0] IAddr; // address to instruction memory -- must be valid by falling edge
output [31:0] IIF2RF; // instruction latched at IF and passed to RF
output [31:0] IIF2RFUnlatched;// unlatched version of IIF2RF
output LinkPC; // link instruction (pc should be stored...)
output [31:0] PCP8; // pc + 8 (for link instruction)
output [4:0] LinkPCAddr;
input MClk;
input IFClkEN;
input NewProg;
input [31:0] IIn;
input AEqB;
input AEq0;
input ALt0;
input [31:0] RaData;
reg LinkPC;
reg [31:0] PCP8;
reg [4:0] LinkPCAddr;
wire [5:0] op; // opcode
wire [4:0] rtAddr; // source
wire [4:0] rdAddr;
wire [5:0] funct; // opcode function
wire iIsBEQ;
wire iIsBGEZ;
wire iIsBGEZAL;
wire iIsBGTZ;
wire iIsBLEZ;
wire iIsBLTZ;
wire iIsBLTZAL;
wire iIsBNE;
wire iIsJ;
wire iIsJAL;
wire iIsJALR;
wire iIsJR;
wire iIsLW;
wire loadBubble;
wire [31:0] rsData;
reg [31:0] pc; // program counter
wire [31:0] pcP4; // pc + 4
wire [31:0] pcPOffset; // pc + offset
wire [31:0] pcTarget; // target field for pc
wire [31:0] pcReg;
wire usePCPOffset; // pcPOffset should be next PC
wire usePCTarget; // pcTarget should be next PC
wire usePCReg; // pcReg should be next PC
wire [15:0] offset;
wire [31:0] signExtendedOffset;
wire [25:0] target;
reg [31:0] i;
reg [31:0] newI;
wire sEqT; // s = t
wire sGEZ; // s >= 0
wire sGTZ; // s > 0
wire sLEZ; // s <= 0
wire sLTZ; // s < 0
wire sNET; // s != t
// signal renaming
assign IAddr = pc;
assign IIF2RF = i;
assign IIF2RFUnlatched = newI;
assign rsData = RaData;
always @ (posedge MClk)
i <= newI;
assign loadBubble = (iIsLW && ((IIn[25:21] == rdAddr) || (IIn[20:16] == rdAddr)));
always @ (/*AUTOSENSE*/IFClkEN or IIn or i or loadBubble)
begin
if (IFClkEN)
newI = loadBubble ? 32'b0 : IIn;
else //
newI = i;
end // always @ (...
assign op = i[31:26];
assign rtAddr = i[20:16];
assign rdAddr = i[15:11];
assign funct = i[5:0];
assign offset = i[15:0];
assign signExtendedOffset = {{14{offset[15]}}, offset[15:0], 2'b00};
assign target = i[25:0];
assign pcP4 = pc + 3'h4;
assign pcPOffset = pc + signExtendedOffset;
assign pcTarget = {pc[31:28], target, 2'b00};
assign pcReg = rsData;
assign sEqT = AEqB;
assign sGEZ = AEq0 || (!ALt0);
assign sGTZ = !(ALt0 || AEq0);
assign sLEZ = ALt0 || AEq0;
assign sLTZ = ALt0;
assign sNET = !AEqB;
assign iIsBEQ = (op == 6'b000100);
assign iIsBGEZ = (op == 6'b000001) && (rtAddr == 5'b00001);
assign iIsBGEZAL = (op == 6'b000001) && (rtAddr == 5'b10001);
assign iIsBGTZ = (op == 6'b000111) && (rtAddr == 5'b00000);
assign iIsBLEZ = (op == 6'b000110) && (rtAddr == 5'b00000);
assign iIsBLTZ = (op == 6'b000001) && (rtAddr == 5'b00000);
assign iIsBLTZAL = (op == 6'b000001) && (rtAddr == 5'b10000);
assign iIsBNE = (op == 6'b000101);
assign iIsJ = (op == 6'b000010);
assign iIsJAL = (op == 6'b000011);
assign iIsJALR = (op == 6'b000000) && (funct == 6'b001001); // TBD -- other 0 fields ?
assign iIsJR = (op == 6'b000000) && (funct == 6'b001000);
assign iIsLW = (op == 6'b100011);
assign usePCPOffset =
(iIsBEQ && sEqT) ||
((iIsBGEZ || iIsBGEZAL) && sGEZ) ||
(iIsBGTZ && sGTZ) ||
(iIsBLEZ && sLEZ) ||
((iIsBLTZ || iIsBLTZAL) && sLTZ) ||
(iIsBNE && sNET);
assign usePCTarget = iIsJ || iIsJAL;
assign usePCReg = iIsJALR || iIsJR;
always @ (posedge MClk)
begin
if (NewProg)
pc <= 32'b0;
else
if (IFClkEN)
casex ({loadBubble, usePCPOffset, usePCTarget, usePCReg}) /* $s full_case parallel_case */
4'b0000 : pc <= pcP4;
4'b1xxx : pc <= pc;
4'b01xx : pc <= pcPOffset;
4'b0x1x : pc <= pcTarget;
4'b0xx1 : pc <= pcReg;
endcase // casex({usePCOffset, usePCTarget, usePCReg})
end // always @ (posedge MClk)
always @ (/*AUTOSENSE*/iIsBGEZAL or iIsBLTZAL or iIsJAL or iIsJALR)
LinkPC <= iIsBGEZAL || iIsBLTZAL || iIsJAL || iIsJALR;
always @ (posedge MClk)
if (IFClkEN)
LinkPCAddr <= iIsJALR ? rdAddr : 5'b11111;
always @ (posedge MClk)
if (IFClkEN)
PCP8 <= pc + 4'h8;
endmodule // IF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -