blob: 2b4475a9c45fdfb5c01e460c3627a14363c68fc1 [file] [log] [blame]
module ProgramCounter (
clk,
en0,
en1,
rst,
IN_pc,
IN_write,
IN_branchTaken,
IN_fetchID,
IN_instr,
IN_clearICache,
IN_BP_branchFound,
IN_BP_branchTaken,
IN_BP_isJump,
IN_BP_branchSrc,
IN_BP_branchDst,
IN_BP_history,
IN_BP_info,
IN_BP_multipleBranches,
IN_BP_branchCompr,
IN_pcReadAddr,
OUT_pcReadData,
IN_ROB_curFetchID,
OUT_pcRaw,
OUT_instrAddr,
OUT_instrs,
OUT_stall,
OUT_MC_if,
IN_MC_cacheID,
IN_MC_progress,
IN_MC_busy
);
parameter NUM_UOPS = 3;
parameter NUM_BLOCKS = 8;
input wire clk;
input wire en0;
input wire en1;
input wire rst;
input wire [31:0] IN_pc;
input wire IN_write;
input wire IN_branchTaken;
input wire [4:0] IN_fetchID;
input wire [127:0] IN_instr;
input wire IN_clearICache;
input wire IN_BP_branchFound;
input wire IN_BP_branchTaken;
input wire IN_BP_isJump;
input wire [31:0] IN_BP_branchSrc;
input wire [31:0] IN_BP_branchDst;
input wire [15:0] IN_BP_history;
input wire [8:0] IN_BP_info;
input wire IN_BP_multipleBranches;
input wire IN_BP_branchCompr;
input wire [24:0] IN_pcReadAddr;
output wire [294:0] OUT_pcReadData;
input wire [4:0] IN_ROB_curFetchID;
output wire [31:0] OUT_pcRaw;
output wire [27:0] OUT_instrAddr;
output reg [(NUM_BLOCKS * 54) - 1:0] OUT_instrs;
output wire OUT_stall;
output wire [41:0] OUT_MC_if;
input wire [0:0] IN_MC_cacheID;
input wire [9:0] IN_MC_progress;
input wire IN_MC_busy;
integer i;
reg [4:0] fetchID;
reg [30:0] pc;
reg [30:0] pcLast;
wire [4:0] fetchIDlast;
reg [15:0] histLast;
reg [8:0] infoLast;
reg [2:0] branchPosLast;
reg multipleLast;
assign OUT_pcRaw = {pc, 1'b0};
always @(*)
for (i = 0; i < NUM_BLOCKS; i = i + 1)
OUT_instrs[(i * 54) + 53-:16] = IN_instr[16 * i+:16];
wire [58:0] PCF_writeData;
assign PCF_writeData[58-:31] = pcLast;
assign PCF_writeData[15-:16] = histLast;
assign PCF_writeData[24-:9] = infoLast;
assign PCF_writeData[27-:3] = branchPosLast;
PCFile #(.WORD_SIZE(59)) pcFile(
.clk(clk),
.wen0(en1),
.waddr0(fetchID),
.wdata0(PCF_writeData),
.raddr0(IN_pcReadAddr[0+:5]),
.rdata0(OUT_pcReadData[0+:59]),
.raddr1(IN_pcReadAddr[5+:5]),
.rdata1(OUT_pcReadData[59+:59]),
.raddr2(IN_pcReadAddr[10+:5]),
.rdata2(OUT_pcReadData[118+:59]),
.raddr3(IN_pcReadAddr[15+:5]),
.rdata3(OUT_pcReadData[177+:59]),
.raddr4(IN_pcReadAddr[20+:5]),
.rdata4(OUT_pcReadData[236+:59])
);
wire icacheStall;
ICacheTable ict(
.clk(clk),
.rst(rst || IN_clearICache),
.IN_lookupValid(en0),
.IN_lookupPC(pc),
.OUT_lookupAddress(OUT_instrAddr),
.OUT_stall(icacheStall),
.OUT_MC_if(OUT_MC_if),
.IN_MC_cacheID(IN_MC_cacheID),
.IN_MC_progress(IN_MC_progress),
.IN_MC_busy(IN_MC_busy)
);
assign OUT_stall = (IN_ROB_curFetchID == fetchID) || icacheStall;
always @(posedge clk)
if (rst) begin
pc <= 0;
fetchID <= 0;
end
else if (IN_write) begin
pc <= IN_pc[31:1];
fetchID <= IN_fetchID + 1;
end
else begin
if (en1) begin
for (i = 0; i < NUM_BLOCKS; i = i + 1)
begin
OUT_instrs[(i * 54) + 37-:31] <= {pcLast[30:3], i[2:0]};
OUT_instrs[i * 54] <= ((i[2:0] >= pcLast[2:0]) && (!infoLast[7] || (i[2:0] <= branchPosLast))) && (!multipleLast || (i[2:0] <= branchPosLast));
OUT_instrs[(i * 54) + 6-:5] <= fetchID;
OUT_instrs[(i * 54) + 1] <= infoLast[7] && (i[2:0] == branchPosLast);
end
fetchID <= fetchID + 1;
end
if (en0) begin
histLast <= IN_BP_history;
infoLast <= IN_BP_info;
pcLast <= pc;
branchPosLast <= IN_BP_branchSrc[3:1];
multipleLast <= IN_BP_multipleBranches;
if (IN_BP_branchFound) begin
if (IN_BP_isJump || IN_BP_branchTaken)
pc <= IN_BP_branchDst[31:1];
else if (IN_BP_multipleBranches)
pc <= IN_BP_branchSrc[31:1] + 1;
else
pc <= {pc[30:3] + 28'b0000000000000000000000000001, 3'b000};
end
else
pc <= {pc[30:3] + 28'b0000000000000000000000000001, 3'b000};
end
end
endmodule