Line 32... |
Line 32... |
// do nothing (kinda like alpha approach)
|
// do nothing (kinda like alpha approach)
|
// Like to turn this into an independent module at some point.
|
// Like to turn this into an independent module at some point.
|
//
|
//
|
module FT64_fetchbuf(rst, clk4x, clk, fcu_clk,
|
module FT64_fetchbuf(rst, clk4x, clk, fcu_clk,
|
cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i,
|
cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i,
|
hirq, thread_en,
|
freezePC, thread_en,
|
regLR,
|
regLR,
|
insn0, insn1, phit,
|
insn0, insn1, phit,
|
threadx,
|
threadx,
|
branchmiss, misspc, branchmiss_thrd, predict_taken0, predict_taken1,
|
branchmiss, misspc, branchmiss_thrd, predict_taken0, predict_taken1,
|
predict_takenA, predict_takenB, predict_takenC, predict_takenD,
|
predict_takenA, predict_takenB, predict_takenC, predict_takenD,
|
Line 70... |
Line 70... |
input stb_i;
|
input stb_i;
|
output ack_o;
|
output ack_o;
|
input we_i;
|
input we_i;
|
input [15:0] adr_i;
|
input [15:0] adr_i;
|
input [31:0] dat_i;
|
input [31:0] dat_i;
|
input hirq;
|
input freezePC;
|
input thread_en;
|
input thread_en;
|
input [4:0] regLR;
|
input [4:0] regLR;
|
input [47:0] insn0;
|
input [47:0] insn0;
|
input [47:0] insn1;
|
input [47:0] insn1;
|
input phit;
|
input phit;
|
Line 327... |
Line 327... |
edge_det ued1 (.rst(rst), .clk(clk4x), .ce(1'b1), .i(clk), .pe(peclk), .ne(neclk), .ee());
|
edge_det ued1 (.rst(rst), .clk(clk4x), .ce(1'b1), .i(clk), .pe(peclk), .ne(neclk), .ee());
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst) begin
|
if (rst) begin
|
pc0 <= RSTPC;
|
pc0 <= RSTPC;
|
`ifdef SUPPORT_SMT
|
|
pc1 <= RSTPC;
|
pc1 <= RSTPC;
|
`endif
|
|
fetchbufA_v <= 0;
|
fetchbufA_v <= 0;
|
fetchbufB_v <= 0;
|
fetchbufB_v <= 0;
|
fetchbufC_v <= 0;
|
fetchbufC_v <= 0;
|
fetchbufD_v <= 0;
|
fetchbufD_v <= 0;
|
fetchbuf <= 0;
|
fetchbuf <= 0;
|
Line 471... |
Line 469... |
// cycle 0 - fetched a INSTR+BEQ, with fbB holding a branchback
|
// cycle 0 - fetched a INSTR+BEQ, with fbB holding a branchback
|
// cycle 1 - could not enqueue fbA or fbB, stalled fetch + updated pc0/pc1
|
// cycle 1 - could not enqueue fbA or fbB, stalled fetch + updated pc0/pc1
|
// cycle 2 - where we are now ... fetch the two instructions & update fetchbufX_v appropriately
|
// cycle 2 - where we are now ... fetch the two instructions & update fetchbufX_v appropriately
|
// if fbA has the branchback, then it is scenario 1.
|
// if fbA has the branchback, then it is scenario 1.
|
// if fbB has it: if pc0 == fbB_pc, then it is the former scenario, else it is the latter
|
// if fbB has it: if pc0 == fbB_pc, then it is the former scenario, else it is the latter
|
4'b1100 : begin
|
4'b1100:
|
`ifdef SUPPORT_SMT
|
if (thread_en) begin
|
if (take_branchA && take_branchB) begin
|
if (take_branchA && take_branchB) begin
|
pc0 <= branch_pcA;
|
pc0 <= branch_pcA;
|
pc1 <= branch_pcB;
|
pc1 <= branch_pcB;
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
end
|
end
|
else
|
else if (take_branchA) begin
|
`endif
|
|
if (take_branchA) begin
|
|
pc0 <= branch_pcA;
|
pc0 <= branch_pcA;
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
`ifdef SUPPORT_SMT
|
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
`else
|
|
fetchbufB_v <= `INV;
|
|
if ((queued1|queuedNop)) fetchbuf <= 1'b1;
|
|
`endif
|
|
end
|
end
|
`ifdef SUPPORT_SMT
|
|
else if (take_branchB) begin
|
else if (take_branchB) begin
|
pc1 <= branch_pcB;
|
pc1 <= branch_pcB;
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
end
|
end
|
`else
|
end
|
|
else begin
|
|
if (take_branchA) begin
|
|
pc0 <= branch_pcA;
|
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
|
fetchbufB_v <= `INV;
|
|
if ((queued1|queuedNop)) fetchbuf <= 1'b1;
|
|
end
|
else begin
|
else begin
|
if (did_branchback0) begin
|
if (did_branchback0) begin
|
FetchCD();
|
FetchCD();
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
`ifdef SUPPORT_SMT
|
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
|
`else
|
|
fetchbuf <= fetchbuf + ((queued2|queuedNop));
|
fetchbuf <= fetchbuf + ((queued2|queuedNop));
|
`endif
|
|
end
|
end
|
else begin
|
else begin
|
pc0 <= branch_pcB;
|
pc0 <= branch_pcB;
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufB_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
end
|
end
|
end
|
end
|
`endif
|
|
end
|
end
|
|
|
// 4'b1101 : panic <= `PANIC_INVALIDFBSTATE;
|
// 4'b1101 : panic <= `PANIC_INVALIDFBSTATE;
|
// 4'b1110 : panic <= `PANIC_INVALIDFBSTATE;
|
// 4'b1110 : panic <= `PANIC_INVALIDFBSTATE;
|
|
|
Line 619... |
Line 611... |
// cycle 0 - fetched a INSTR+BEQ, with fbD holding a branchback
|
// cycle 0 - fetched a INSTR+BEQ, with fbD holding a branchback
|
// cycle 1 - could not enqueue fbC or fbD, stalled fetch + updated pc0/pc1
|
// cycle 1 - could not enqueue fbC or fbD, stalled fetch + updated pc0/pc1
|
// cycle 2 - where we are now ... fetch the two instructions & update fetchbufX_v appropriately
|
// cycle 2 - where we are now ... fetch the two instructions & update fetchbufX_v appropriately
|
// if fbC has the branchback, then it is scenario 1.
|
// if fbC has the branchback, then it is scenario 1.
|
// if fbD has it: if pc0 == fbB_pc, then it is the former scenario, else it is the latter
|
// if fbD has it: if pc0 == fbB_pc, then it is the former scenario, else it is the latter
|
4'b1100 : begin
|
4'b1100:
|
`ifdef SUPPORT_SMT
|
if (thread_en) begin
|
if (take_branchC && take_branchD) begin
|
if (take_branchC && take_branchD) begin
|
pc0 <= branch_pcC;
|
pc0 <= branch_pcC;
|
pc1 <= branch_pcD;
|
pc1 <= branch_pcD;
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
end
|
end
|
else
|
else if (take_branchC) begin
|
`endif
|
|
if (take_branchC) begin
|
|
pc0 <= branch_pcC;
|
pc0 <= branch_pcC;
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
`ifdef SUPPORT_SMT
|
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
`else
|
|
fetchbufD_v <= `INV;
|
|
if ((queued1|queuedNop)) fetchbuf <= 1'b1;
|
|
`endif
|
|
end
|
end
|
`ifdef SUPPORT_SMT
|
|
else if (take_branchD) begin
|
else if (take_branchD) begin
|
pc1 <= branch_pcD;
|
pc1 <= branch_pcD;
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
end
|
end
|
`else
|
end
|
|
else begin
|
|
if (take_branchC) begin
|
|
pc0 <= branch_pcC;
|
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
|
fetchbufD_v <= `INV;
|
|
if ((queued1|queuedNop)) fetchbuf <= 1'b1;
|
|
end
|
else begin
|
else begin
|
if (did_branchback1) begin
|
if (did_branchback1) begin
|
FetchAB();
|
FetchAB();
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
`ifdef SUPPORT_SMT
|
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
|
`else
|
|
fetchbuf <= fetchbuf + ((queued2|queuedNop));
|
fetchbuf <= fetchbuf + ((queued2|queuedNop));
|
`endif
|
|
end
|
end
|
else begin
|
else begin
|
pc0 <= branch_pcD;
|
pc0 <= branch_pcD;
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufC_v <= !(queued1|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
fetchbufD_v <= !(queued2|queuedNop); // if it can be queued, it will
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
if ((queued2|queuedNop)) fetchbuf <= 1'b1;
|
end
|
end
|
end
|
end
|
`endif
|
|
end
|
end
|
|
|
// 4'b1101 : panic <= `PANIC_INVALIDFBSTATE;
|
// 4'b1101 : panic <= `PANIC_INVALIDFBSTATE;
|
// 4'b1110 : panic <= `PANIC_INVALIDFBSTATE;
|
// 4'b1110 : panic <= `PANIC_INVALIDFBSTATE;
|
|
|
Line 806... |
Line 792... |
assign fetchbuf0_pc = (fetchbuf == 1'b0) ? fetchbufA_pc : fetchbufC_pc ;
|
assign fetchbuf0_pc = (fetchbuf == 1'b0) ? fetchbufA_pc : fetchbufC_pc ;
|
assign fetchbuf1_instr = (fetchbuf == 1'b0) ? fetchbufB_instr : fetchbufD_instr;
|
assign fetchbuf1_instr = (fetchbuf == 1'b0) ? fetchbufB_instr : fetchbufD_instr;
|
assign fetchbuf1_v = (fetchbuf == 1'b0) ? fetchbufB_v : fetchbufD_v ;
|
assign fetchbuf1_v = (fetchbuf == 1'b0) ? fetchbufB_v : fetchbufD_v ;
|
assign fetchbuf1_pc = (fetchbuf == 1'b0) ? fetchbufB_pc : fetchbufD_pc ;
|
assign fetchbuf1_pc = (fetchbuf == 1'b0) ? fetchbufB_pc : fetchbufD_pc ;
|
assign fetchbuf0_thrd = 1'b0;
|
assign fetchbuf0_thrd = 1'b0;
|
`ifdef SUPPORT_SMT
|
assign fetchbuf1_thrd = thread_en;
|
assign fetchbuf1_thrd = 1'b1;
|
|
`else
|
|
assign fetchbuf1_thrd = 1'b0;
|
|
`endif
|
|
|
|
`ifndef SUPPORT_SMT
|
|
always @*
|
|
pc1 <= pc0 + fetchbuf0_insln;
|
|
`endif
|
|
|
|
always @*
|
always @*
|
begin
|
begin
|
if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
|
if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
|
fetchbuf0_insln <= fnInsLength(codebuf0);
|
fetchbuf0_insln <= fnInsLength(codebuf0);
|
Line 860... |
Line 837... |
task FetchA;
|
task FetchA;
|
begin
|
begin
|
fetchbufA_instr <= cinsn0;
|
fetchbufA_instr <= cinsn0;
|
fetchbufA_v <= `VAL;
|
fetchbufA_v <= `VAL;
|
fetchbufA_pc <= pc0;
|
fetchbufA_pc <= pc0;
|
if (phit && ~hirq)
|
if (phit && ~freezePC) begin
|
`ifdef SUPPORT_SMT
|
if (thread_en)
|
pc0 <= pc0 + fetchbuf0_insln;
|
pc0 <= pc0 + fetchbuf0_insln;
|
`else
|
else if (`WAYS > 1)
|
if (`WAYS > 1)
|
|
pc0 <= pc0 + fetchbuf0_insln + fetchbuf1_insln;
|
pc0 <= pc0 + fetchbuf0_insln + fetchbuf1_insln;
|
else
|
else
|
pc0 <= pc0 + fetchbuf0_insln;
|
pc0 <= pc0 + fetchbuf0_insln;
|
`endif
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task FetchB;
|
task FetchB;
|
begin
|
begin
|
fetchbufB_instr <= cinsn1;
|
fetchbufB_instr <= cinsn1;
|
fetchbufB_v <= `WAYS > 1;
|
fetchbufB_v <= `WAYS > 1;
|
|
if (thread_en)
|
fetchbufB_pc <= pc1;
|
fetchbufB_pc <= pc1;
|
`ifdef SUPPORT_SMT
|
else
|
if (phit)
|
fetchbufB_pc <= pc0 + fetchbuf0_insln;
|
|
if (phit & thread_en)
|
pc1 <= pc1 + fetchbuf1_insln;
|
pc1 <= pc1 + fetchbuf1_insln;
|
`endif
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task FetchAB;
|
task FetchAB;
|
Line 897... |
Line 874... |
task FetchC;
|
task FetchC;
|
begin
|
begin
|
fetchbufC_instr <= cinsn0;
|
fetchbufC_instr <= cinsn0;
|
fetchbufC_v <= `VAL;
|
fetchbufC_v <= `VAL;
|
fetchbufC_pc <= pc0;
|
fetchbufC_pc <= pc0;
|
if (phit && ~hirq)
|
if (phit && ~freezePC) begin
|
`ifdef SUPPORT_SMT
|
if (thread_en)
|
pc0 <= pc0 + fetchbuf0_insln;
|
pc0 <= pc0 + fetchbuf0_insln;
|
`else
|
else if (`WAYS > 1)
|
if (`WAYS > 1)
|
|
pc0 <= pc0 + fetchbuf0_insln + fetchbuf1_insln;
|
pc0 <= pc0 + fetchbuf0_insln + fetchbuf1_insln;
|
else
|
else
|
pc0 <= pc0 + fetchbuf0_insln;
|
pc0 <= pc0 + fetchbuf0_insln;
|
`endif
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task FetchD;
|
task FetchD;
|
begin
|
begin
|
fetchbufD_instr <= cinsn1;
|
fetchbufD_instr <= cinsn1;
|
fetchbufD_v <= `WAYS > 1;
|
fetchbufD_v <= `WAYS > 1;
|
|
if (thread_en)
|
fetchbufD_pc <= pc1;
|
fetchbufD_pc <= pc1;
|
`ifdef SUPPORT_SMT
|
else
|
if (phit)
|
fetchbufD_pc <= pc0 + fetchbuf0_insln;
|
|
if (phit & thread_en)
|
pc1 <= pc1 + fetchbuf1_insln;
|
pc1 <= pc1 + fetchbuf1_insln;
|
`endif
|
|
end
|
end
|
endtask
|
endtask
|
|
|
task FetchCD;
|
task FetchCD;
|
begin
|
begin
|