Line 64... |
Line 64... |
input [63:0] dat_i;
|
input [63:0] dat_i;
|
output reg [1:0] ol_o;
|
output reg [1:0] ol_o;
|
output [31:0] pcr_o;
|
output [31:0] pcr_o;
|
output [63:0] pcr2_o;
|
output [63:0] pcr2_o;
|
output [63:0] pkeys_o;
|
output [63:0] pkeys_o;
|
output reg icl_o;
|
output icl_o;
|
output reg cr_o;
|
output reg cr_o;
|
output reg sr_o;
|
output reg sr_o;
|
input rbi_i;
|
input rbi_i;
|
input [31:0] signal_i;
|
input [31:0] signal_i;
|
(* mark_debug="true" *)
|
(* mark_debug="true" *)
|
Line 118... |
Line 118... |
parameter IQS_AGEN = 3'd3;
|
parameter IQS_AGEN = 3'd3;
|
parameter IQS_MEM = 3'd4;
|
parameter IQS_MEM = 3'd4;
|
parameter IQS_DONE = 3'd5;
|
parameter IQS_DONE = 3'd5;
|
parameter IQS_CMT = 3'd6;
|
parameter IQS_CMT = 3'd6;
|
|
|
|
`include "..\common\FT64_busStates.vh"
|
|
|
wire clk;
|
wire clk;
|
//BUFG uclkb1
|
//BUFG uclkb1
|
//(
|
//(
|
// .I(clk_i),
|
// .I(clk_i),
|
// .O(clk)
|
// .O(clk)
|
Line 135... |
Line 137... |
reg cyc;
|
reg cyc;
|
reg we;
|
reg we;
|
|
|
wire dc_ack;
|
wire dc_ack;
|
wire acki = ack_i|dc_ack;
|
wire acki = ack_i|dc_ack;
|
|
wire tlb_miss;
|
wire [RBIT:0] Ra0, Ra1, Ra2;
|
wire [RBIT:0] Ra0, Ra1, Ra2;
|
wire [RBIT:0] Rb0, Rb1, Rb2;
|
wire [RBIT:0] Rb0, Rb1, Rb2;
|
wire [RBIT:0] Rc0, Rc1, Rc2;
|
wire [RBIT:0] Rc0, Rc1, Rc2;
|
wire [RBIT:0] Rt0, Rt1, Rt2;
|
wire [RBIT:0] Rt0, Rt1, Rt2;
|
wire [63:0] rfoa0,rfob0,rfoc0,rfoc0a,rfot0;
|
wire [63:0] rfoa0,rfob0,rfoc0,rfoc0a,rfot0;
|
Line 279... |
Line 282... |
for (n = 0; n < AREGS; n = n + 1)
|
for (n = 0; n < AREGS; n = n + 1)
|
rf_source[n] = 1'b0;
|
rf_source[n] = 1'b0;
|
for (n = 0; n < 16; n = n + 1)
|
for (n = 0; n < 16; n = n + 1)
|
prf_source[n] <= 1'b0;
|
prf_source[n] <= 1'b0;
|
end
|
end
|
|
`ifdef SUPPORT_SMT
|
|
wire [1:0] ol [0:NTHREAD];
|
|
wire [1:0] dl [0:NTHREAD];
|
|
`else
|
|
wire [1:0] ol;
|
|
wire [1:0] dl;
|
|
`endif
|
wire [`ABITS] pc0a;
|
wire [`ABITS] pc0a;
|
wire [`ABITS] pc1a;
|
wire [`ABITS] pc1a;
|
wire [`ABITS] pc2a;
|
wire [`ABITS] pc2a;
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
wire [`ABITS] pc0 = (pc0a[47:40]==8'hFF||ol==2'b00) ? pc0a : {pb[50:0],13'd0} + pc0a[47:0];
|
wire [`ABITS] pc0 = (pc0a[47:40]==8'hFF||ol[0]==2'b00) ? pc0a : {pb[50:0],13'd0} + pc0a[47:0];
|
wire [`ABITS] pc1 = (pc1a[47:40]==8'hFF||ol==2'b00) ? pc1a : {pb[50:0],13'd0} + pc1a[47:0];
|
wire [`ABITS] pc1 = (pc1a[47:40]==8'hFF||ol[1]==2'b00) ? pc1a : {pb[50:0],13'd0} + pc1a[47:0];
|
wire [`ABITS] pc2 = (pc2a[47:40]==8'hFF||ol==2'b00) ? pc2a : {pb[50:0],13'd0} + pc2a[47:0];
|
wire [`ABITS] pc2 = (pc2a[47:40]==8'hFF||ol[2]==2'b00) ? pc2a : {pb[50:0],13'd0} + pc2a[47:0];
|
`else
|
`else
|
wire [`ABITS] pc0 = pc0a;
|
wire [`ABITS] pc0 = pc0a;
|
wire [`ABITS] pc1 = pc1a;
|
wire [`ABITS] pc1 = pc1a;
|
wire [`ABITS] pc2 = pc2a;
|
wire [`ABITS] pc2 = pc2a;
|
`endif
|
`endif
|
Line 355... |
Line 365... |
assign pcr2_o = pcr2;
|
assign pcr2_o = pcr2;
|
reg [63:0] aec;
|
reg [63:0] aec;
|
(* mark_debug = "true" *)
|
(* mark_debug = "true" *)
|
reg [15:0] cause[0:15];
|
reg [15:0] cause[0:15];
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
|
reg [31:0] im_stack [0:NTHREAD];
|
|
wire [3:0] im = im_stack[0][3:0];
|
|
reg [15:0] ol_stack [0:NTHREAD];
|
|
reg [15:0] dl_stack [0:NTHREAD];
|
|
assign ol[0] = ol_stack[0][1:0];
|
|
assign ol[1] = ol_stack[1][1:0];
|
|
assign ol[2] = ol_stack[2][1:0];
|
|
assign dl[0] = dl_stack[0][1:0];
|
|
assign dl[1] = dl_stack[1][1:0];
|
|
assign dl[2] = dl_stack[2][1:0];
|
reg [`ABITS] epc [0:NTHREAD];
|
reg [`ABITS] epc [0:NTHREAD];
|
reg [`ABITS] epc0 [0:NTHREAD];
|
reg [`ABITS] epc0 [0:NTHREAD];
|
reg [`ABITS] epc1 [0:NTHREAD];
|
reg [`ABITS] epc1 [0:NTHREAD];
|
reg [`ABITS] epc2 [0:NTHREAD];
|
reg [`ABITS] epc2 [0:NTHREAD];
|
reg [`ABITS] epc3 [0:NTHREAD];
|
reg [`ABITS] epc3 [0:NTHREAD];
|
Line 366... |
Line 386... |
reg [`ABITS] epc5 [0:NTHREAD];
|
reg [`ABITS] epc5 [0:NTHREAD];
|
reg [`ABITS] epc6 [0:NTHREAD];
|
reg [`ABITS] epc6 [0:NTHREAD];
|
reg [`ABITS] epc7 [0:NTHREAD];
|
reg [`ABITS] epc7 [0:NTHREAD];
|
reg [`ABITS] epc8 [0:NTHREAD]; // exception pc and stack
|
reg [`ABITS] epc8 [0:NTHREAD]; // exception pc and stack
|
reg [63:0] mstatus [0:NTHREAD]; // machine status
|
reg [63:0] mstatus [0:NTHREAD]; // machine status
|
wire [3:0] im = mstatus[0][3:0];
|
|
wire [1:0] ol [0:NTHREAD];
|
|
wire [1:0] dl [0:NTHREAD];
|
|
assign ol[0] = mstatus[0][5:4]; // operating level
|
assign ol[0] = mstatus[0][5:4]; // operating level
|
assign dl[0] = mstatus[0][21:20];
|
assign dl[0] = mstatus[0][21:20];
|
wire [7:0] cpl [0:NTHREAD];
|
wire [7:0] cpl [0:NTHREAD];
|
assign cpl[0] = mstatus[0][13:6]; // current privilege level
|
assign cpl[0] = mstatus[0][13:6]; // current privilege level
|
wire [5:0] rgs [0:NTHREAD];
|
wire [5:0] rgs [0:NTHREAD];
|
assign ol[1] = mstatus[1][5:4]; // operating level
|
assign ol[1] = mstatus[1][5:4]; // operating level
|
assign cpl[1] = mstatus[1][13:6]; // current privilege level
|
assign cpl[1] = mstatus[1][13:6]; // current privilege level
|
assign dl[1] = mstatus[1][21:20];
|
assign dl[1] = mstatus[1][21:20];
|
wire [7:0] ASID = mstatus[0][47:40];
|
wire [7:0] ASID = mstatus[0][47:40];
|
reg [15:0] ol_stack [0:NTHREAD];
|
|
reg [15:0] dl_stack [0:NTHREAD];
|
|
reg [31:0] im_stack [0:NTHREAD];
|
|
reg [63:0] pl_stack [0:NTHREAD];
|
reg [63:0] pl_stack [0:NTHREAD];
|
reg [63:0] rs_stack [0:NTHREAD];
|
reg [63:0] rs_stack [0:NTHREAD];
|
reg [63:0] brs_stack [0:NTHREAD];
|
reg [63:0] brs_stack [0:NTHREAD];
|
reg [63:0] fr_stack [0:NTHREAD];
|
reg [63:0] fr_stack [0:NTHREAD];
|
assign rgs[0] = rs_stack[0][5:0];
|
assign rgs[0] = rs_stack[0][5:0];
|
Line 392... |
Line 406... |
wire mprv = mstatus[0][55];
|
wire mprv = mstatus[0][55];
|
wire [5:0] fprgs = mstatus[0][25:20];
|
wire [5:0] fprgs = mstatus[0][25:20];
|
//assign ol_o = mprv ? ol_stack[0][2:0] : ol[0];
|
//assign ol_o = mprv ? ol_stack[0][2:0] : ol[0];
|
wire vca = mstatus[0][32]; // vector chaining active
|
wire vca = mstatus[0][32]; // vector chaining active
|
`else
|
`else
|
|
reg [31:0] im_stack = 32'hFFFFFFFF;
|
|
wire [3:0] im = im_stack[3:0];
|
reg [`ABITS] epc ;
|
reg [`ABITS] epc ;
|
reg [`ABITS] epc0 ;
|
reg [`ABITS] epc0 ;
|
reg [`ABITS] epc1 ;
|
reg [`ABITS] epc1 ;
|
reg [`ABITS] epc2 ;
|
reg [`ABITS] epc2 ;
|
reg [`ABITS] epc3 ;
|
reg [`ABITS] epc3 ;
|
Line 403... |
Line 419... |
reg [`ABITS] epc5 ;
|
reg [`ABITS] epc5 ;
|
reg [`ABITS] epc6 ;
|
reg [`ABITS] epc6 ;
|
reg [`ABITS] epc7 ;
|
reg [`ABITS] epc7 ;
|
reg [`ABITS] epc8 ; // exception pc and stack
|
reg [`ABITS] epc8 ; // exception pc and stack
|
reg [63:0] mstatus ; // machine status
|
reg [63:0] mstatus ; // machine status
|
wire [3:0] im = mstatus[3:0];
|
reg [15:0] ol_stack;
|
wire [1:0] ol ;
|
reg [15:0] dl_stack;
|
wire [1:0] dl;
|
assign ol = ol_stack[1:0]; // operating level
|
assign ol = mstatus[5:4]; // operating level
|
assign dl = dl_stack[1:0];
|
assign dl = mstatus[21:20];
|
|
wire [7:0] cpl ;
|
wire [7:0] cpl ;
|
assign cpl = mstatus[13:6]; // current privilege level
|
assign cpl = mstatus[13:6]; // current privilege level
|
wire [5:0] rgs ;
|
wire [5:0] rgs ;
|
reg [15:0] ol_stack ;
|
|
reg [15:0] dl_stack ;
|
|
reg [31:0] im_stack ;
|
|
reg [63:0] pl_stack ;
|
reg [63:0] pl_stack ;
|
reg [63:0] rs_stack ;
|
reg [63:0] rs_stack ;
|
reg [63:0] brs_stack ;
|
reg [63:0] brs_stack ;
|
reg [63:0] fr_stack ;
|
reg [63:0] fr_stack ;
|
assign rgs = rs_stack[5:0];
|
assign rgs = rs_stack[5:0];
|
Line 786... |
Line 798... |
reg [`ABITS] alu0_pc;
|
reg [`ABITS] alu0_pc;
|
reg [63:0] alu0_bus;
|
reg [63:0] alu0_bus;
|
wire [63:0] alu0b_bus;
|
wire [63:0] alu0b_bus;
|
wire [63:0] alu0_out;
|
wire [63:0] alu0_out;
|
wire [`QBITSP1] alu0_id;
|
wire [`QBITSP1] alu0_id;
|
|
(* mark_debug="true" *)
|
wire [`XBITS] alu0_exc;
|
wire [`XBITS] alu0_exc;
|
wire alu0_v;
|
wire alu0_v;
|
wire alu0_branchmiss;
|
wire alu0_branchmiss;
|
wire [`ABITS] alu0_misspc;
|
wire [`ABITS] alu0_misspc;
|
|
|
Line 1015... |
Line 1028... |
reg [RBIT:0] commit2_tgt;
|
reg [RBIT:0] commit2_tgt;
|
reg [7:0] commit2_we = 8'h00;
|
reg [7:0] commit2_we = 8'h00;
|
reg [63:0] commit2_bus;
|
reg [63:0] commit2_bus;
|
|
|
reg StoreAck1;
|
reg StoreAck1;
|
reg [4:0] bstate;
|
reg [4:0] bstate = BIDLE;
|
parameter BIDLE = 5'd0;
|
wire [3:0] icstate;
|
parameter B_StoreAck = 5'd1;
|
|
parameter B_DCacheLoadStart = 5'd2;
|
|
parameter B_DCacheLoadStb = 5'd3;
|
|
parameter B_DCacheLoadWait1 = 5'd4;
|
|
parameter B_DCacheLoadWait2 = 5'd5;
|
|
parameter B_DCacheLoadResetBusy = 5'd6;
|
|
parameter B_ICacheAck = 5'd7;
|
|
parameter B8 = 5'd8;
|
|
parameter B_ICacheNack = 5'd9;
|
|
parameter B_ICacheNack2 = 5'd10;
|
|
parameter B11 = 5'd11;
|
|
parameter B12 = 5'd12;
|
|
parameter B_DLoadAck = 5'd13;
|
|
parameter B14 = 5'd14;
|
|
parameter B15 = 5'd15;
|
|
parameter B16 = 5'd16;
|
|
parameter B17 = 5'd17;
|
|
parameter B18 = 5'd18;
|
|
parameter B_LSNAck = 5'd19;
|
|
parameter B2a = 5'd20;
|
|
parameter B2b = 5'd21;
|
|
parameter B2c = 5'd22;
|
|
parameter B_DCacheLoadAck = 5'd23;
|
|
parameter B20 = 5'd24;
|
|
parameter B21 = 5'd25;
|
|
parameter B_DCacheLoadWait3 = 5'd26;
|
|
parameter B_LoadDesc = 5'd27;
|
|
parameter B_LoadDescStb = 5'd28;
|
|
parameter B_WaitSeg = 5'd29;
|
|
parameter B_DLoadNack = 5'd30;
|
|
parameter SEG_IDLE = 2'd0;
|
parameter SEG_IDLE = 2'd0;
|
parameter SEG_CHK = 2'd1;
|
parameter SEG_CHK = 2'd1;
|
parameter SEG_UPD = 2'd2;
|
parameter SEG_UPD = 2'd2;
|
parameter SEG_DONE = 2'd3;
|
parameter SEG_DONE = 2'd3;
|
reg [1:0] bwhich;
|
reg [1:0] bwhich;
|
reg [3:0] icstate,picstate;
|
|
parameter IDLE = 4'd0;
|
|
parameter IC1 = 4'd1;
|
|
parameter IC2 = 4'd2;
|
|
parameter IC3 = 4'd3;
|
|
parameter IC_WaitL2 = 4'd4;
|
|
parameter IC5 = 4'd5;
|
|
parameter IC6 = 4'd6;
|
|
parameter IC7 = 4'd7;
|
|
parameter IC_Next = 4'd8;
|
|
parameter IC9 = 4'd9;
|
|
parameter IC10 = 4'd10;
|
|
parameter IC3a = 4'd11;
|
|
reg invic, invdc;
|
reg invic, invdc;
|
reg [1:0] icwhich;
|
reg invicl;
|
reg icnxt,L2_nxt;
|
wire [1:0] icwhich;
|
|
wire icnxt;
|
|
wire L2_nxt;
|
wire ihit0,ihit1,ihit2,ihitL2;
|
wire ihit0,ihit1,ihit2,ihitL2;
|
wire ihit = ihit0&ihit1&ihit2;
|
wire ihit = ihit0&ihit1&ihit2;
|
reg phit;
|
reg phit;
|
wire threadx;
|
wire threadx;
|
always @*
|
always @*
|
phit <= ihit&&icstate==IDLE;
|
phit <= (ihit&&icstate==IDLE) && !invicl;
|
reg [2:0] iccnt;
|
|
(* mark_debug="true" *)
|
(* mark_debug="true" *)
|
reg icack;
|
reg icack;
|
reg L1_wr0,L1_wr1,L1_wr2;
|
wire L1_wr0,L1_wr1,L1_wr2;
|
reg L1_invline;
|
wire L1_invline;
|
wire [1:0] ic0_fault,ic1_fault,ic2_fault;
|
wire [1:0] ic0_fault,ic1_fault,ic2_fault;
|
reg [9:0] L1_en;
|
wire [9:0] L1_en;
|
reg [71:0] L1_adr, L2_adr;
|
wire [71:0] L1_adr;
|
reg [305:0] L1_dati;
|
wire [71:0] L2_adr;
|
wire [305:0] L2_dato;
|
wire [305:0] L2_dato;
|
reg L2_xsel;
|
wire selL2;
|
|
|
|
wire icclk;
|
|
BUFH ucb1 (.I(clk), .O(icclk));
|
|
|
generate begin : gRegfileInst
|
generate begin : gRegfileInst
|
if (`WAYS > 2) begin : gb1
|
if (`WAYS > 2) begin : gb1
|
FT64_regfile2w9r_oc #(.RBIT(RBIT)) urf1
|
FT64_regfile2w9r_oc #(.RBIT(RBIT)) urf1
|
(
|
(
|
Line 1191... |
Line 1165... |
2'd1: fnInsLength = 4'd6 | pred_on;
|
2'd1: fnInsLength = 4'd6 | pred_on;
|
default: fnInsLength = 4'd2 | pred_on;
|
default: fnInsLength = 4'd2 | pred_on;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
wire [`ABITS] pc0plus6 = pc0 + 32'd7;
|
|
wire [`ABITS] pc0plus12 = pc0 + 32'd14;
|
|
|
|
generate begin : gInsnVar
|
generate begin : gInsnVar
|
if (`WAYS > 1) begin
|
if (`WAYS > 1) begin
|
always @*
|
always @*
|
if (thread_en)
|
if (thread_en)
|
insn1a <= insn1b;
|
insn1a <= insn1b;
|
Line 1212... |
Line 1183... |
insn2a <= {insn2b,insn1b,insn0a} >> {fnInsLength(insn0a) + fnInsLength(insn1a),3'b0};
|
insn2a <= {insn2b,insn1b,insn0a} >> {fnInsLength(insn0a) + fnInsLength(insn1a),3'b0};
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
wire L1_selpc;
|
|
wire [2:0] icti;
|
|
wire [1:0] ibte;
|
|
wire icyc;
|
|
wire istb;
|
|
wire [7:0] isel;
|
|
wire [71:0] iadr;
|
|
wire L2_ld;
|
|
wire [305:0] L1_dat;
|
|
wire [2:0] L2_cnt;
|
|
reg [71:0] invlineAddr;
|
|
|
|
FT64_ICController uL1ctrl
|
|
(
|
|
.clk_i(clk),
|
|
.asid(ASID),
|
|
.pc0(pc0),
|
|
.pc1(pc1),
|
|
.pc2(pc2),
|
|
.hit0(ihit0),
|
|
.hit1(ihit1),
|
|
.hit2(ihit2),
|
|
.bstate(bstate),
|
|
.state(icstate),
|
|
.invline(invicl),
|
|
.invlineAddr(invlineAddr),
|
|
.thread_en(thread_en),
|
|
.L1_selpc(L1_selpc),
|
|
.L1_adr(L1_adr),
|
|
.L1_dat(L1_dat),
|
|
.L1_wr0(L1_wr0),
|
|
.L1_wr1(L1_wr1),
|
|
.L1_wr2(L1_wr2),
|
|
.L1_en(L1_en),
|
|
.L1_invline(L1_invline),
|
|
.ihitL2(ihitL2),
|
|
.selL2(selL2),
|
|
.L2_ld(L2_ld),
|
|
.L2_cnt(L2_cnt),
|
|
.L2_adr(L2_adr),
|
|
.L2_dato(L2_dato),
|
|
.L2_nxt(L2_nxt),
|
|
.icnxt(icnxt),
|
|
.icwhich(icwhich),
|
|
.icl_o(icl_o),
|
|
.cti_o(icti),
|
|
.bte_o(ibte),
|
|
.bok_i(bok_i),
|
|
.cyc_o(icyc),
|
|
.stb_o(istb),
|
|
.ack_i(acki),
|
|
.err_i(err_i),
|
|
.tlbmiss_i(tlb_miss),
|
|
.exv_i(exv_i),
|
|
.sel_o(isel),
|
|
.adr_o(iadr),
|
|
.dat_i(dat_i)
|
|
);
|
|
|
FT64_L1_icache #(.pSize(`L1_ICACHE_SIZE)) uic0
|
FT64_L1_icache #(.pSize(`L1_ICACHE_SIZE)) uic0
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.nxt(icnxt),
|
.nxt(icnxt),
|
.wr(L1_wr0),
|
.wr(L1_wr0),
|
.wr_ack(),
|
.wr_ack(),
|
.en(L1_en),
|
.en(L1_en),
|
.adr((icstate==IDLE||icstate==IC_Next) ? {pcr[7:0],pc0} : L1_adr),
|
.adr(L1_selpc ? {ASID,pc0} : L1_adr),
|
.wadr(L1_adr),
|
.wadr(L1_adr),
|
.i(L1_dati),
|
.i(L1_dat),
|
.o(insn0a),
|
.o(insn0a),
|
.fault(ic0_fault),
|
.fault(ic0_fault),
|
.hit(ihit0),
|
.hit(ihit0),
|
.invall(invic),
|
.invall(invic),
|
.invline(L1_invline)
|
.invline(L1_invline)
|
Line 1239... |
Line 1269... |
.clk(clk),
|
.clk(clk),
|
.nxt(icnxt),
|
.nxt(icnxt),
|
.wr(L1_wr1),
|
.wr(L1_wr1),
|
.wr_ack(),
|
.wr_ack(),
|
.en(L1_en),
|
.en(L1_en),
|
.adr((icstate==IDLE||icstate==IC_Next) ? (thread_en ? {pcr[7:0],pc1}: {pcr[7:0],pc0plus6} ): L1_adr),
|
.adr(L1_selpc ? (thread_en ? {ASID,pc1}: {ASID,pc0plus6} ): L1_adr),
|
.wadr(L1_adr),
|
.wadr(L1_adr),
|
.i(L1_dati),
|
.i(L1_dat),
|
.o(insn1b),
|
.o(insn1b),
|
.fault(ic1_fault),
|
.fault(ic1_fault),
|
.hit(ihit1),
|
.hit(ihit1),
|
.invall(invic),
|
.invall(invic),
|
.invline(L1_invline)
|
.invline(L1_invline)
|
Line 1261... |
Line 1291... |
.clk(clk),
|
.clk(clk),
|
.nxt(icnxt),
|
.nxt(icnxt),
|
.wr(L1_wr2),
|
.wr(L1_wr2),
|
.wr_ack(),
|
.wr_ack(),
|
.en(L1_en),
|
.en(L1_en),
|
.adr((icstate==IDLE||icstate==IC_Next) ? (thread_en ? {pcr[7:0],pc2} : {pcr[7:0],pc0plus12}) : L1_adr),
|
.adr(L1_selpc ? (thread_en ? {ASID,pc2} : {ASID,pc0plus12}) : L1_adr),
|
.wadr(L1_adr),
|
.wadr(L1_adr),
|
.i(L1_dati),
|
.i(L1_dat),
|
.o(insn2b),
|
.o(insn2b),
|
.fault(ic2_fault),
|
.fault(ic2_fault),
|
.hit(ihit2),
|
.hit(ihit2),
|
.invall(invic),
|
.invall(invic),
|
.invline(L1_invline)
|
.invline(L1_invline)
|
Line 1281... |
Line 1311... |
FT64_L2_icache uic2
|
FT64_L2_icache uic2
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.nxt(L2_nxt),
|
.nxt(L2_nxt),
|
.wr(bstate==B_ICacheAck && (ack_i|err_i)),
|
.wr(L2_ld),
|
.xsel(L2_xsel),
|
.adr(selL2 ? L2_adr: L1_adr),
|
.adr(L2_adr),
|
.cnt(L2_cnt),
|
.cnt(iccnt),
|
|
.exv_i(exvq),
|
.exv_i(exvq),
|
.i(dat_i),
|
.i(dat_i),
|
.err_i(errq),
|
.err_i(errq),
|
.o(L2_dato),
|
.o(L2_dato),
|
.hit(ihitL2),
|
.hit(ihitL2),
|
Line 1859... |
Line 1888... |
if (~|irq_i)
|
if (~|irq_i)
|
insn0 <= {8'h00,`NOP_INSN};
|
insn0 <= {8'h00,`NOP_INSN};
|
else
|
else
|
insn0[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
insn0[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
end
|
end
|
else if (ic0_fault[1])
|
else if (insn0a[15:0]==16'h0000)
|
insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
else if (ic0_fault[0])
|
else
|
insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
case(ic0_fault)
|
|
2'd0: ; // no fault, don't alter instruction
|
|
2'd1: insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_TLB,2'b00,`BRK};
|
|
2'd2: insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
|
2'd3: insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
|
endcase
|
end
|
end
|
else begin
|
else begin
|
insn0 <= {8'h00,`NOP_INSN};
|
insn0 <= {8'h00,`NOP_INSN};
|
end
|
end
|
|
|
Line 1885... |
Line 1919... |
if (~|irq_i)
|
if (~|irq_i)
|
insn1 <= {8'h00,`NOP_INSN};
|
insn1 <= {8'h00,`NOP_INSN};
|
else
|
else
|
insn1[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
insn1[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
end
|
end
|
else if (ic1_fault[1])
|
case(ic1_fault)
|
insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
2'd0: ; // no fault, don't alter instruction
|
else if (ic1_fault[0])
|
2'd1: insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_TLB,2'b00,`BRK};
|
insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
2'd2: insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
|
2'd3: insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
|
endcase
|
end
|
end
|
else begin
|
else begin
|
insn1 <= {8'h00,`NOP_INSN};
|
insn1 <= {8'h00,`NOP_INSN};
|
end
|
end
|
end
|
end
|
Line 1909... |
Line 1945... |
if (~|irq_i)
|
if (~|irq_i)
|
insn2 <= {8'h00,`NOP_INSN};
|
insn2 <= {8'h00,`NOP_INSN};
|
else
|
else
|
insn2[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
insn2[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
end
|
end
|
else if (ic2_fault[1])
|
case(ic2_fault)
|
insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
2'd0: ; // no fault, don't alter instruction
|
else if (ic2_fault[0])
|
2'd1: insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_TLB,2'b00,`BRK};
|
insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
2'd2: insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
|
2'd3: insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
|
endcase
|
end
|
end
|
else
|
else
|
insn2 <= `NOP_INSN;
|
insn2 <= `NOP_INSN;
|
end
|
end
|
end
|
end
|
Line 1927... |
Line 1965... |
assign rdat1 = dram1_unc ? xdati[63:0] : dc1_out;
|
assign rdat1 = dram1_unc ? xdati[63:0] : dc1_out;
|
assign rdat2 = dram2_unc ? xdati[63:0] : dc2_out;
|
assign rdat2 = dram2_unc ? xdati[63:0] : dc2_out;
|
|
|
reg preload;
|
reg preload;
|
reg [1:0] dccnt;
|
reg [1:0] dccnt;
|
|
reg [3:0] dcwait = 4'd3;
|
|
reg [3:0] dcwait_ctr = 4'd3;
|
wire dhit0, dhit1, dhit2;
|
wire dhit0, dhit1, dhit2;
|
wire dhit0a, dhit1a, dhit2a;
|
wire dhit0a, dhit1a, dhit2a;
|
wire dhit00, dhit10, dhit20;
|
wire dhit00, dhit10, dhit20;
|
wire dhit01, dhit11, dhit21;
|
wire dhit01, dhit11, dhit21;
|
reg [`ABITS] dc_wadr;
|
reg [`ABITS] dc_wadr;
|
reg [63:0] dc_wdat;
|
reg [63:0] dc_wdat;
|
reg isStore;
|
reg isStore;
|
|
reg [31:0] dcsel;
|
|
reg [255:0] dcbuf;
|
|
reg dcwr;
|
|
|
// If the data is in the write buffer, give the buffer a chance to
|
// If the data is in the write buffer, give the buffer a chance to
|
// write out the data before trying to load from the cache.
|
// write out the data before trying to load from the cache.
|
reg wb_hit0, wb_hit1, wb_hit2;
|
reg wb_hit0, wb_hit1, wb_hit2;
|
always @*
|
always @*
|
Line 1958... |
Line 2001... |
assign dhit0 = dhit0a && !wb_hit0;
|
assign dhit0 = dhit0a && !wb_hit0;
|
assign dhit1 = dhit1a && !wb_hit1;
|
assign dhit1 = dhit1a && !wb_hit1;
|
assign dhit2 = dhit2a && !wb_hit2;
|
assign dhit2 = dhit2a && !wb_hit2;
|
wire whit0, whit1, whit2;
|
wire whit0, whit1, whit2;
|
|
|
wire wr_dcache0 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit0);
|
wire wr_dcache0 = (dcwr)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit0);
|
wire wr_dcache1 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit1);
|
wire wr_dcache1 = (dcwr)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit1);
|
wire wr_dcache2 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit2);
|
wire wr_dcache2 = (dcwr)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit2);
|
|
|
FT64_dcache udc0
|
FT64_dcache udc0
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.wclk(clk),
|
.wclk(clk),
|
.dce(dce),
|
.dce(dce),
|
.wr(wr_dcache0),
|
.wr(wr_dcache0),
|
.sel(sel_o),
|
.sel(dcsel),
|
.wadr({pcr[7:0],vadr}),
|
.wadr({ASID,vadr}),
|
.whit(whit0),
|
.whit(whit0),
|
.i((bstate==B_DCacheLoadAck) ? dat_i : dat_o),
|
.i(dcbuf),
|
.rclk(clk),
|
.rclk(clk),
|
.rdsize(dram0_memsize),
|
.rdsize(dram0_memsize),
|
.radr({pcr[7:0],dram0_addr}),
|
.radr({ASID,dram0_addr}),
|
.o(dc0_out),
|
.o(dc0_out),
|
.rhit(dhit0a)
|
.rhit(dhit0a)
|
);
|
);
|
generate begin : gDCacheInst
|
generate begin : gDCacheInst
|
if (`NUM_MEM > 1) begin
|
if (`NUM_MEM > 1) begin
|
Line 1986... |
Line 2029... |
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.wclk(clk),
|
.wclk(clk),
|
.dce(dce),
|
.dce(dce),
|
.wr(wr_dcache1),
|
.wr(wr_dcache1),
|
.sel(sel_o),
|
.sel(dcsel),
|
.wadr({pcr[7:0],vadr}),
|
.wadr({ASID,vadr}),
|
.whit(whit1),
|
.whit(whit1),
|
.i((bstate==B_DCacheLoadAck) ? dat_i : dat_o),
|
.i(dcbuf),
|
.rclk(clk),
|
.rclk(clk),
|
.rdsize(dram1_memsize),
|
.rdsize(dram1_memsize),
|
.radr({pcr[7:0],dram1_addr}),
|
.radr({ASID,dram1_addr}),
|
.o(dc1_out),
|
.o(dc1_out),
|
.rhit(dhit1a)
|
.rhit(dhit1a)
|
);
|
);
|
end
|
end
|
if (`NUM_MEM > 2) begin
|
if (`NUM_MEM > 2) begin
|
Line 2004... |
Line 2047... |
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.wclk(clk),
|
.wclk(clk),
|
.dce(dce),
|
.dce(dce),
|
.wr(wr_dcache2),
|
.wr(wr_dcache2),
|
.sel(sel_o),
|
.sel(dcsel),
|
.wadr({pcr[7:0],vadr}),
|
.wadr({ASID,vadr}),
|
.whit(whit2),
|
.whit(whit2),
|
.i((bstate==B_DCacheLoadAck) ? dat_i : dat_o),
|
.i(dcbuf),
|
.rclk(clk),
|
.rclk(clk),
|
.rdsize(dram2_memsize),
|
.rdsize(dram2_memsize),
|
.radr({pcr[7:0],dram2_addr}),
|
.radr({ASID,dram2_addr}),
|
.o(dc2_out),
|
.o(dc2_out),
|
.rhit(dhit2a)
|
.rhit(dhit2a)
|
);
|
);
|
end
|
end
|
end
|
end
|
Line 3034... |
Line 3077... |
`CACHEX: CacheCmd = isn[17:13];
|
`CACHEX: CacheCmd = isn[17:13];
|
default: CacheCmd = 5'd0;
|
default: CacheCmd = 5'd0;
|
endcase
|
endcase
|
else
|
else
|
CacheCmd = 5'd0;
|
CacheCmd = 5'd0;
|
`CACHE: CacheCmd = isn[15:11];
|
`CACHE: CacheCmd = isn[17:13];
|
default: CacheCmd = 5'd0;
|
default: CacheCmd = 5'd0;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsMemsb;
|
function IsMemsb;
|
Line 5303... |
Line 5346... |
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
reg [2:0] wbptr;
|
reg [2:0] wbptr = 2'd0;
|
// Stomp logic for branch miss.
|
// Stomp logic for branch miss.
|
/*
|
/*
|
FT64_stomp #(QENTRIES) ustmp1
|
FT64_stomp #(QENTRIES) ustmp1
|
(
|
(
|
.branchmiss(branchmiss),
|
.branchmiss(branchmiss),
|
Line 5354... |
Line 5397... |
wire [4:0] id1_ido, id2_ido, id3_ido;
|
wire [4:0] id1_ido, id2_ido, id3_ido;
|
wire id1_vo, id2_vo, id3_vo;
|
wire id1_vo, id2_vo, id3_vo;
|
wire id1_clk, id2_clk, id3_clk;
|
wire id1_clk, id2_clk, id3_clk;
|
|
|
// Always at least one decoder
|
// Always at least one decoder
|
assign id1_clk = clk_i;
|
BUFH uidclk (.I(clk_i), .O(id1_clk));
|
|
//assign id1_clk = clk_i;
|
//BUFGCE uclkb2
|
//BUFGCE uclkb2
|
//(
|
//(
|
// .I(clk_i),
|
// .I(clk_i),
|
// .CE(id1_available),
|
// .CE(id1_available),
|
// .O(id1_clk)
|
// .O(id1_clk)
|
Line 5514... |
Line 5558... |
`CSR_TVEC: csr_r <= tvec[csrno[2:0]];
|
`CSR_TVEC: csr_r <= tvec[csrno[2:0]];
|
`CSR_BADADR: csr_r <= badaddr[{alu0_thrd,csrno[11:10]}];
|
`CSR_BADADR: csr_r <= badaddr[{alu0_thrd,csrno[11:10]}];
|
`CSR_BADINSTR: csr_r <= bad_instr[{alu0_thrd,csrno[11:10]}];
|
`CSR_BADINSTR: csr_r <= bad_instr[{alu0_thrd,csrno[11:10]}];
|
`CSR_CAUSE: csr_r <= {48'd0,cause[{alu0_thrd,csrno[11:10]}]};
|
`CSR_CAUSE: csr_r <= {48'd0,cause[{alu0_thrd,csrno[11:10]}]};
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
|
`CSR_ODL_STACK: csr_r <= {16'h0,dl_stack[alu0_thrd],16'h0,ol_stack[alu0_thrd]};
|
`CSR_IM_STACK: csr_r <= im_stack[alu0_thrd];
|
`CSR_IM_STACK: csr_r <= im_stack[alu0_thrd];
|
`CSR_OL_STACK: csr_r <= {dl_stack[alu0_thrd],ol_stack[alu0_thrd]};
|
|
`CSR_PL_STACK: csr_r <= pl_stack[alu0_thrd];
|
`CSR_PL_STACK: csr_r <= pl_stack[alu0_thrd];
|
`CSR_RS_STACK: csr_r <= rs_stack[alu0_thrd];
|
`CSR_RS_STACK: csr_r <= rs_stack[alu0_thrd];
|
`CSR_STATUS: csr_r <= mstatus[alu0_thrd][63:0];
|
`CSR_STATUS: csr_r <= mstatus[alu0_thrd][63:0];
|
`CSR_BRS_STACK: csr_r <= brs_stack[alu0_thrd];
|
`CSR_BRS_STACK: csr_r <= brs_stack[alu0_thrd];
|
`CSR_EPC0: csr_r <= epc0[alu0_thrd];
|
`CSR_EPC0: csr_r <= epc0[alu0_thrd];
|
Line 5529... |
Line 5573... |
`CSR_EPC4: csr_r <= epc4[alu0_thrd];
|
`CSR_EPC4: csr_r <= epc4[alu0_thrd];
|
`CSR_EPC5: csr_r <= epc5[alu0_thrd];
|
`CSR_EPC5: csr_r <= epc5[alu0_thrd];
|
`CSR_EPC6: csr_r <= epc6[alu0_thrd];
|
`CSR_EPC6: csr_r <= epc6[alu0_thrd];
|
`CSR_EPC7: csr_r <= epc7[alu0_thrd];
|
`CSR_EPC7: csr_r <= epc7[alu0_thrd];
|
`else
|
`else
|
|
`CSR_ODL_STACK: csr_r <= {16'h0,dl_stack,16'h0,ol_stack};
|
`CSR_IM_STACK: csr_r <= im_stack;
|
`CSR_IM_STACK: csr_r <= im_stack;
|
`CSR_OL_STACK: csr_r <= {dl_stack,ol_stack};
|
|
`CSR_PL_STACK: csr_r <= pl_stack;
|
`CSR_PL_STACK: csr_r <= pl_stack;
|
`CSR_RS_STACK: csr_r <= rs_stack;
|
`CSR_RS_STACK: csr_r <= rs_stack;
|
`CSR_STATUS: csr_r <= mstatus[63:0];
|
`CSR_STATUS: csr_r <= mstatus[63:0];
|
`CSR_BRS_STACK: csr_r <= brs_stack;
|
`CSR_BRS_STACK: csr_r <= brs_stack;
|
`CSR_EPC0: csr_r <= epc0;
|
`CSR_EPC0: csr_r <= epc0;
|
Line 5599... |
Line 5643... |
alu0_xs <= 64'd0;
|
alu0_xs <= 64'd0;
|
always @*
|
always @*
|
alu1_xs <= 64'd0;
|
alu1_xs <= 64'd0;
|
`endif
|
`endif
|
|
|
|
wire alu_clk = clk;
|
|
//BUFH uclka (.I(clk), .O(alu_clk));
|
|
|
//always @*
|
//always @*
|
// read_csr(alu0_instr[29:18],csr_r,alu0_thrd);
|
// read_csr(alu0_instr[29:18],csr_r,alu0_thrd);
|
FT64_alu #(.BIG(1'b1),.SUP_VECTOR(SUP_VECTOR)) ualu0 (
|
FT64_alu #(.BIG(1'b1),.SUP_VECTOR(SUP_VECTOR)) ualu0 (
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(alu_clk),
|
.ld(alu0_ld),
|
.ld(alu0_ld),
|
.abort(alu0_abort),
|
.abort(alu0_abort),
|
.instr(alu0_instr),
|
.instr(alu0_instr),
|
.sz(alu0_sz),
|
.sz(alu0_sz),
|
.tlb(alu0_tlb),
|
|
.store(alu0_store),
|
.store(alu0_store),
|
.a(alu0_argA),
|
.a(alu0_argA),
|
.b(alu0_argB),
|
.b(alu0_argB),
|
.c(alu0_argC),
|
.c(alu0_argC),
|
.pc(alu0_pc),
|
.pc(alu0_pc),
|
Line 5628... |
Line 5674... |
.excen(aec[4:0]),
|
.excen(aec[4:0]),
|
.exc(alu0_exc),
|
.exc(alu0_exc),
|
.thrd(alu0_thrd),
|
.thrd(alu0_thrd),
|
.mem(alu0_mem),
|
.mem(alu0_mem),
|
.shift(alu0_shft), // 48 bit shift inst.
|
.shift(alu0_shft), // 48 bit shift inst.
|
.ol(ol),
|
.ol(ol)
|
.ASID(ASID),
|
|
.icl_i(icl_o),
|
|
.cyc_i(cyc),
|
|
.we_i(we),
|
|
.vadr_i(vadr),
|
|
.cyc_o(cyc_o),
|
|
.we_o(we_o),
|
|
.padr_o(adr_o),
|
|
.uncached(),
|
|
.tlb_miss(tlb_miss),
|
|
.exv_o(exv_i),
|
|
.wrv_o(wrv_i),
|
|
.rdv_o(rdv_i)
|
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
.pb(dl==2'b00 ? 64'd0 : pb),
|
, .pb(dl==2'b00 ? 64'd0 : pb),
|
.cbl(cbl),
|
.cbl(cbl),
|
.cbu(cbu),
|
.cbu(cbu),
|
.ro(ro),
|
.ro(ro),
|
.dbl(dbl),
|
.dbl(dbl),
|
.dbu(dbu),
|
.dbu(dbu),
|
Line 5663... |
Line 5696... |
.clk(clk),
|
.clk(clk),
|
.ld(alu1_ld),
|
.ld(alu1_ld),
|
.abort(alu1_abort),
|
.abort(alu1_abort),
|
.instr(alu1_instr),
|
.instr(alu1_instr),
|
.sz(alu1_sz),
|
.sz(alu1_sz),
|
.tlb(1'b0),
|
|
.store(alu1_store),
|
.store(alu1_store),
|
.a(alu1_argA),
|
.a(alu1_argA),
|
.b(alu1_argB),
|
.b(alu1_argB),
|
.c(alu1_argC),
|
.c(alu1_argC),
|
.pc(alu1_pc),
|
.pc(alu1_pc),
|
Line 5683... |
Line 5715... |
.excen(aec[4:0]),
|
.excen(aec[4:0]),
|
.exc(alu1_exc),
|
.exc(alu1_exc),
|
.thrd(1'b0),
|
.thrd(1'b0),
|
.mem(alu1_mem),
|
.mem(alu1_mem),
|
.shift(alu1_shft),
|
.shift(alu1_shft),
|
.ol(2'b0),
|
.ol(2'b0)
|
.ASID(8'h0),
|
|
.cyc_i(1'b0),
|
|
.we_i(1'b0),
|
|
.vadr_i(64'd0),
|
|
.cyc_o(),
|
|
.we_o(),
|
|
.padr_o(),
|
|
.uncached(),
|
|
.tlb_miss(),
|
|
.exv_o(),
|
|
.wrv_o(),
|
|
.rdv_o()
|
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
.pb(dl==2'b00 ? 64'd0 : pb),
|
, .pb(dl==2'b00 ? 64'd0 : pb),
|
.cbl(cbl),
|
.cbl(cbl),
|
.cbu(cbu),
|
.cbu(cbu),
|
.ro(ro),
|
.ro(ro),
|
.dbl(dbl),
|
.dbl(dbl),
|
.dbu(dbu),
|
.dbu(dbu),
|
Line 5712... |
Line 5732... |
);
|
);
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
wire tlb_done;
|
|
wire tlb_idle;
|
|
wire [63:0] tlbo;
|
|
wire uncached;
|
|
`ifdef SUPPORT_TLB
|
|
FT64_TLB utlb1 (
|
|
.clk(clk),
|
|
.ld(alu0_ld & alu0_tlb),
|
|
.done(tlb_done),
|
|
.idle(tlb_idle),
|
|
.ol(ol),
|
|
.ASID(ASID),
|
|
.op(alu0_instr[25:22]),
|
|
.regno(alu0_instr[21:18]),
|
|
.dati(alu0_argA),
|
|
.dato(tlbo),
|
|
.uncached(uncached),
|
|
.icl_i(icl_o),
|
|
.cyc_i(cyc),
|
|
.we_i(we),
|
|
.vadr_i(vadr),
|
|
.cyc_o(cyc_o),
|
|
.we_o(we_o),
|
|
.padr_o(adr_o),
|
|
.TLBMiss(tlb_miss),
|
|
.wrv_o(wrv_o),
|
|
.rdv_o(rdv_o),
|
|
.exv_o(exv_o),
|
|
.HTLBVirtPageo()
|
|
);
|
|
`else
|
|
assign tlb_done = 1'b1;
|
|
assign tlb_idle = 1'b1;
|
|
assign tlbo = 64'hDEADDEADDEADDEAD;
|
|
assign uncached = 1'b0;
|
|
assign adr_o = vadr;
|
|
assign cyc_o = cyc;
|
|
assign we_o = we;
|
|
assign tlb_miss = 1'b0;
|
|
assign wrv_o = 1'b0;
|
|
assign rdv_o = 1'b0;
|
|
assign exv_o = 1'b0;
|
|
assign exv_i = 1'b0; // for now
|
|
`endif
|
|
|
always @*
|
always @*
|
begin
|
begin
|
alu0_cmt <= 1'b1;
|
alu0_cmt <= 1'b1;
|
alu1_cmt <= 1'b1;
|
alu1_cmt <= 1'b1;
|
fpu1_cmt <= 1'b1;
|
fpu1_cmt <= 1'b1;
|
Line 6262... |
Line 6327... |
// misspc <= excmiss ? excmisspc : fcu_misspc;
|
// misspc <= excmiss ? excmisspc : fcu_misspc;
|
// missid <= excmiss ? (|iqentry_exc[heads[0]] ? heads[0] : heads[1]) : fcu_sourceid;
|
// missid <= excmiss ? (|iqentry_exc[heads[0]] ? heads[0] : heads[1]) : fcu_sourceid;
|
// branchmiss_thrd <= excmiss ? excthrd : fcu_thrd;
|
// branchmiss_thrd <= excmiss ? excthrd : fcu_thrd;
|
//end
|
//end
|
wire alu0_done_pe, alu1_done_pe, pe_wait;
|
wire alu0_done_pe, alu1_done_pe, pe_wait;
|
edge_det uedalu0d (.clk(clk), .ce(1'b1), .i(alu0_done), .pe(alu0_done_pe), .ne(), .ee());
|
edge_det uedalu0d (.clk(clk), .ce(1'b1), .i(alu0_done&tlb_done), .pe(alu0_done_pe), .ne(), .ee());
|
edge_det uedalu1d (.clk(clk), .ce(1'b1), .i(alu1_done), .pe(alu1_done_pe), .ne(), .ee());
|
edge_det uedalu1d (.clk(clk), .ce(1'b1), .i(alu1_done), .pe(alu1_done_pe), .ne(), .ee());
|
edge_det uedwait1 (.clk(clk), .ce(1'b1), .i((waitctr==48'd1) || signal_i[fcu_argA[4:0]|fcu_argI[4:0]]), .pe(pe_wait), .ne(), .ee());
|
edge_det uedwait1 (.clk(clk), .ce(1'b1), .i((waitctr==48'd1) || signal_i[fcu_argA[4:0]|fcu_argI[4:0]]), .pe(pe_wait), .ne(), .ee());
|
|
|
// Bus randomization to mitigate meltdown attacks
|
// Bus randomization to mitigate meltdown attacks
|
wire [63:0] ralu0_bus = |alu0_exc ? {4{lfsro}} : alu0_bus;
|
wire [63:0] ralu0_bus = |alu0_exc ? {4{lfsro}} : alu0_tlb ? tlbo : alu0_bus;
|
wire [63:0] ralu1_bus = |alu1_exc ? {4{lfsro}} : alu1_bus;
|
wire [63:0] ralu1_bus = |alu1_exc ? {4{lfsro}} : alu1_bus;
|
wire [63:0] rfpu1_bus = |fpu1_exc ? {4{lfsro}} : fpu1_bus;
|
wire [63:0] rfpu1_bus = |fpu1_exc ? {4{lfsro}} : fpu1_bus;
|
wire [63:0] rfpu2_bus = |fpu2_exc ? {4{lfsro}} : fpu2_bus;
|
wire [63:0] rfpu2_bus = |fpu2_exc ? {4{lfsro}} : fpu2_bus;
|
wire [63:0] rfcu_bus = |fcu_exc ? {4{lfsro}} : fcu_bus;
|
wire [63:0] rfcu_bus = |fcu_exc ? {4{lfsro}} : fcu_bus;
|
wire [63:0] rdramA_bus = dramA_bus;
|
wire [63:0] rdramA_bus = dramA_bus;
|
wire [63:0] rdramB_bus = dramB_bus;
|
wire [63:0] rdramB_bus = dramB_bus;
|
wire [63:0] rdramC_bus = dramC_bus;
|
wire [63:0] rdramC_bus = dramC_bus;
|
|
|
|
// Hold reset for five seconds
|
|
reg [31:0] rst_ctr;
|
|
always @(posedge clk)
|
|
if (rst)
|
|
rst_ctr <= 32'd0;
|
|
else begin
|
|
if (rst_ctr < 32'd10)
|
|
rst_ctr <= rst_ctr + 24'd1;
|
|
end
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst) begin
|
if (rst|(rst_ctr < 32'd10)) begin
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
mstatus[0] <= 64'h4000F; // select register set #16 for thread 0
|
mstatus[0] <= 64'h4000F; // select register set #16 for thread 0
|
mstatus[1] <= 64'h4800F; // select register set #18 for thread 1
|
mstatus[1] <= 64'h4800F; // select register set #18 for thread 1
|
rs_stack[0] <= 64'd16;
|
rs_stack[0] <= 64'd16;
|
brs_stack[0] <= 64'd16;
|
brs_stack[0] <= 64'd16;
|
rs_stack[1] <= 64'd18;
|
rs_stack[1] <= 64'd18;
|
brs_stack[1] <= 64'd18;
|
brs_stack[1] <= 64'd18;
|
`else
|
`else
|
|
im_stack <= 32'hFFFFFFFF;
|
mstatus <= 64'h4000F; // select register set #16 for thread 0
|
mstatus <= 64'h4000F; // select register set #16 for thread 0
|
rs_stack <= 64'd16;
|
rs_stack <= 64'd16;
|
brs_stack <= 64'd16;
|
brs_stack <= 64'd16;
|
`endif
|
`endif
|
for (n = 0; n < QENTRIES; n = n + 1) begin
|
for (n = 0; n < QENTRIES; n = n + 1) begin
|
Line 6361... |
Line 6437... |
dram1_addr <= 32'h0;
|
dram1_addr <= 32'h0;
|
dram2_addr <= 32'h0;
|
dram2_addr <= 32'h0;
|
dram0_id <= 1'b0;
|
dram0_id <= 1'b0;
|
dram1_id <= 1'b0;
|
dram1_id <= 1'b0;
|
dram2_id <= 1'b0;
|
dram2_id <= 1'b0;
|
L1_adr <= RSTPC;
|
dram0_store <= 1'b0;
|
L2_adr <= RSTPC;
|
dram1_store <= 1'b0;
|
|
dram2_store <= 1'b0;
|
invic <= FALSE;
|
invic <= FALSE;
|
|
invicl <= FALSE;
|
tail0 <= 3'd0;
|
tail0 <= 3'd0;
|
tail1 <= 3'd1;
|
tail1 <= 3'd1;
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
heads[n] <= n;
|
heads[n] <= n;
|
panic = `PANIC_NONE;
|
panic = `PANIC_NONE;
|
Line 6406... |
Line 6484... |
dramA_v <= 0;
|
dramA_v <= 0;
|
dramB_v <= 0;
|
dramB_v <= 0;
|
dramC_v <= 0;
|
dramC_v <= 0;
|
I <= 0;
|
I <= 0;
|
CC <= 0;
|
CC <= 0;
|
icstate <= IDLE;
|
|
bstate <= BIDLE;
|
bstate <= BIDLE;
|
tick <= 64'd0;
|
tick <= 64'd0;
|
ol_o <= 2'b0;
|
ol_o <= 2'b0;
|
bte_o <= 2'b00;
|
bte_o <= 2'b00;
|
cti_o <= 3'b000;
|
cti_o <= 3'b000;
|
Line 6420... |
Line 6497... |
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
dat_o <= 64'hFFFFFFFFFFFFFFFF;
|
dat_o <= 64'hFFFFFFFFFFFFFFFF;
|
sr_o <= `LOW;
|
sr_o <= `LOW;
|
cr_o <= `LOW;
|
cr_o <= `LOW;
|
vadr <= RSTPC;
|
vadr <= RSTPC;
|
icl_o <= `LOW; // instruction cache load
|
|
L1_dati <= 306'd0;
|
|
cr0 <= 64'd0;
|
cr0 <= 64'd0;
|
cr0[13:8] <= 6'd0; // select compressed instruction group #0
|
cr0[13:8] <= 6'd0; // select compressed instruction group #0
|
cr0[30] <= TRUE; // enable data caching
|
cr0[30] <= TRUE; // enable data caching
|
cr0[32] <= TRUE; // enable branch predictor
|
cr0[32] <= TRUE; // enable branch predictor
|
cr0[16] <= 1'b0; // disable SMT
|
cr0[16] <= 1'b0; // disable SMT
|
Line 6473... |
Line 6548... |
wb_v[n] <= 1'b0;
|
wb_v[n] <= 1'b0;
|
wb_rmw[n] <= 1'b0;
|
wb_rmw[n] <= 1'b0;
|
wb_id[n] <= {QENTRIES{1'b0}};
|
wb_id[n] <= {QENTRIES{1'b0}};
|
wb_ol[n] <= 2'b00;
|
wb_ol[n] <= 2'b00;
|
wb_sel[n] <= 8'h00;
|
wb_sel[n] <= 8'h00;
|
wb_addr[n] <= 32'd0;
|
wb_addr[n] <= 64'd0;
|
wb_data[n] <= 64'd0;
|
wb_data[n] <= 64'd0;
|
end
|
end
|
wb_en <= `TRUE;
|
wb_en <= `TRUE;
|
wbo_id <= {QENTRIES{1'b0}};
|
wbo_id <= {QENTRIES{1'b0}};
|
wbptr <= 2'd0;
|
wbptr <= 2'd0;
|
Line 6577... |
Line 6652... |
`endif
|
`endif
|
|
|
nop_fetchbuf <= 4'h0;
|
nop_fetchbuf <= 4'h0;
|
excmiss <= FALSE;
|
excmiss <= FALSE;
|
invic <= FALSE;
|
invic <= FALSE;
|
|
if (L1_invline)
|
|
invicl <= FALSE;
|
tick <= tick + 64'd1;
|
tick <= tick + 64'd1;
|
alu0_ld <= FALSE;
|
alu0_ld <= FALSE;
|
alu1_ld <= FALSE;
|
alu1_ld <= FALSE;
|
fpu1_ld <= FALSE;
|
fpu1_ld <= FALSE;
|
fpu2_ld <= FALSE;
|
fpu2_ld <= FALSE;
|
Line 6991... |
Line 7068... |
|
|
if (alu0_v) begin
|
if (alu0_v) begin
|
iqentry_tgt [ alu0_id[`QBITS] ] <= alu0_tgt;
|
iqentry_tgt [ alu0_id[`QBITS] ] <= alu0_tgt;
|
iqentry_res [ alu0_id[`QBITS] ] <= ralu0_bus;
|
iqentry_res [ alu0_id[`QBITS] ] <= ralu0_bus;
|
iqentry_exc [ alu0_id[`QBITS] ] <= alu0_exc;
|
iqentry_exc [ alu0_id[`QBITS] ] <= alu0_exc;
|
if (!iqentry_mem[ alu0_id[`QBITS] ] && alu0_done) begin
|
if (!iqentry_mem[ alu0_id[`QBITS] ] && alu0_done && tlb_done) begin
|
// iqentry_done[ alu0_id[`QBITS] ] <= `TRUE;
|
// iqentry_done[ alu0_id[`QBITS] ] <= `TRUE;
|
iqentry_state[alu0_id[`QBITS]] <= IQS_CMT;
|
iqentry_state[alu0_id[`QBITS]] <= IQS_CMT;
|
end
|
end
|
// if (alu0_done)
|
// if (alu0_done)
|
// iqentry_cmt [ alu0_id[`QBITS] ] <= `TRUE;
|
// iqentry_cmt [ alu0_id[`QBITS] ] <= `TRUE;
|
Line 7744... |
Line 7821... |
end
|
end
|
endcase
|
endcase
|
|
|
|
|
rf_source[0] <= 0;
|
rf_source[0] <= 0;
|
L1_wr0 <= FALSE;
|
|
L1_wr1 <= FALSE;
|
|
L1_wr2 <= FALSE;
|
|
L1_en <= 10'h000;
|
|
L1_invline <= FALSE;
|
|
icnxt <= FALSE;
|
|
L2_nxt <= FALSE;
|
|
// Instruction cache state machine.
|
|
// On a miss first see if the instruction is in the L2 cache. No need to go to
|
|
// the BIU on an L1 miss.
|
|
// If not the machine will wait until the BIU loads the L2 cache.
|
|
|
|
// Capture the previous ic state, used to determine how long to wait in
|
|
// icstate #4.
|
|
picstate <= icstate;
|
|
case(icstate)
|
|
IDLE:
|
|
// If the bus unit is busy doing an update involving L1_adr or L2_adr
|
|
// we have to wait.
|
|
if (bstate != B_ICacheAck && bstate != B_ICacheNack && bstate != B_ICacheNack2) begin
|
|
if (!ihit0) begin
|
|
L1_adr <= {pcr[7:0],pc0[AMSB:5],5'h0};
|
|
L2_adr <= {pcr[7:0],pc0[AMSB:5],5'h0};
|
|
L1_invline <= TRUE;
|
|
icwhich <= 2'b00;
|
|
iccnt <= 3'b00;
|
|
icstate <= IC2;
|
|
end
|
|
else if (!ihit1 && `WAYS > 1) begin
|
|
if (thread_en) begin
|
|
L1_adr <= {pcr[7:0],pc1[AMSB:5],5'h0};
|
|
L2_adr <= {pcr[7:0],pc1[AMSB:5],5'h0};
|
|
end
|
|
else begin
|
|
L1_adr <= {pcr[7:0],pc0plus6[AMSB:5],5'h0};
|
|
L2_adr <= {pcr[7:0],pc0plus6[AMSB:5],5'h0};
|
|
end
|
|
L1_invline <= TRUE;
|
|
icwhich <= 2'b01;
|
|
iccnt <= 3'b00;
|
|
icstate <= IC2;
|
|
end
|
|
else if (!ihit2 && `WAYS > 2) begin
|
|
if (thread_en) begin
|
|
L1_adr <= {pcr[7:0],pc2[AMSB:5],5'h0};
|
|
L2_adr <= {pcr[7:0],pc2[AMSB:5],5'h0};
|
|
end
|
|
else begin
|
|
L1_adr <= {pcr[7:0],pc0plus12[AMSB:5],5'h0};
|
|
L2_adr <= {pcr[7:0],pc0plus12[AMSB:5],5'h0};
|
|
end
|
|
L1_invline <= TRUE;
|
|
icwhich <= 2'b10;
|
|
iccnt <= 3'b00;
|
|
icstate <= IC2;
|
|
end
|
|
end
|
|
IC2: icstate <= IC3;
|
|
IC3: icstate <= IC3a;
|
|
IC3a: icstate <= IC_WaitL2;
|
|
// If data was in the L2 cache already there's no need to wait on the
|
|
// BIU to retrieve data. It can be determined if the hit signal was
|
|
// already active when this state was entered in which case waiting
|
|
// will do no good.
|
|
// The IC machine will stall in this state until the BIU has loaded the
|
|
// L2 cache.
|
|
IC_WaitL2:
|
|
if (ihitL2 && picstate==IC3a) begin
|
|
L1_en <= 10'h3FF;
|
|
L1_wr0 <= TRUE;
|
|
L1_wr1 <= TRUE && `WAYS > 1;
|
|
L1_wr2 <= TRUE && `WAYS > 2;
|
|
// L1_adr <= L2_adr;
|
|
// L1_dati is loaded dring an L2 icache load operation
|
|
// if (picstate==IC3a)
|
|
L1_dati <= L2_dato;
|
|
icstate <= IC5;
|
|
end
|
|
else if (bstate!=B_ICacheNack)
|
|
;
|
|
else begin
|
|
L1_en <= 10'h3FF;
|
|
L1_wr0 <= TRUE;
|
|
L1_wr1 <= TRUE && `WAYS > 1;
|
|
L1_wr2 <= TRUE && `WAYS > 2;
|
|
// L1_adr <= L2_adr;
|
|
// L1_dati set below while loading cache line
|
|
//L1_dati <= L2_dato;
|
|
icstate <= IC5;
|
|
end
|
|
|
|
IC5: icstate <= IC6;
|
|
IC6: icstate <= IC7;
|
|
IC7: icstate <= IC_Next;
|
|
IC_Next:
|
|
begin
|
|
icstate <= IDLE;
|
|
icnxt <= TRUE;
|
|
end
|
|
default: icstate <= IDLE;
|
|
endcase
|
|
|
|
|
// A store will never be stomped on because they aren't issued until it's
|
|
// guarenteed there will be no change of flow.
|
|
// A load or other long running instruction might be stomped on by a change
|
|
// of program flow. Stomped on loads already in progress can be aborted early.
|
|
// In the case of an aborted load, random data is returned and any exceptions
|
|
// are nullified.
|
if (dram0_load)
|
if (dram0_load)
|
case(dram0)
|
case(dram0)
|
`DRAMSLOT_AVAIL: ;
|
`DRAMSLOT_AVAIL: ;
|
`DRAMSLOT_BUSY:
|
`DRAMSLOT_BUSY:
|
// if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
dram0 <= dram0 + !dram0_unc;
|
dram0 <= dram0 + !dram0_unc;
|
// else begin
|
else begin
|
// dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMREQ_READY;
|
// dram0_load <= `FALSE;
|
dram0_load <= `FALSE;
|
// end
|
xdati[63:0] <= {4{lfsro}};
|
3'd2:
|
end
|
// if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
3'd2,3'd3:
|
dram0 <= dram0 + 3'd1;
|
if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
// else begin
|
|
// dram0 <= `DRAMSLOT_AVAIL;
|
|
// dram0_load <= `FALSE;
|
|
// end
|
|
3'd3:
|
|
// if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
|
dram0 <= dram0 + 3'd1;
|
dram0 <= dram0 + 3'd1;
|
// else begin
|
else begin
|
// dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMREQ_READY;
|
// dram0_load <= `FALSE;
|
dram0_load <= `FALSE;
|
// end
|
xdati[63:0] <= {4{lfsro}};
|
|
end
|
3'd4:
|
3'd4:
|
// if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]]) begin
|
if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]]) begin
|
if (dhit0)
|
if (dhit0)
|
dram0 <= `DRAMREQ_READY;
|
dram0 <= `DRAMREQ_READY;
|
else
|
else
|
dram0 <= `DRAMSLOT_REQBUS;
|
dram0 <= `DRAMSLOT_REQBUS;
|
// end
|
end
|
// else begin
|
else begin
|
// dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMREQ_READY;
|
// dram0_load <= `FALSE;
|
dram0_load <= `FALSE;
|
// end
|
xdati[63:0] <= {4{lfsro}};
|
`DRAMSLOT_REQBUS: ;
|
end
|
`DRAMSLOT_HASBUS: ;
|
`DRAMSLOT_REQBUS:
|
|
if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
|
;
|
|
else begin
|
|
dram0 <= `DRAMREQ_READY;
|
|
dram0_load <= `FALSE;
|
|
xdati[63:0] <= {4{lfsro}};
|
|
end
|
|
`DRAMSLOT_HASBUS:
|
|
if (iqentry_v[dram0_id[`QBITS]] && !iqentry_stomp[dram0_id[`QBITS]])
|
|
;
|
|
else begin
|
|
dram0 <= `DRAMREQ_READY;
|
|
dram0_load <= `FALSE;
|
|
xdati[63:0] <= {4{lfsro}};
|
|
end
|
`DRAMREQ_READY: dram0 <= `DRAMSLOT_AVAIL;
|
`DRAMREQ_READY: dram0 <= `DRAMSLOT_AVAIL;
|
endcase
|
endcase
|
|
|
if (dram1_load && `NUM_MEM > 1)
|
if (dram1_load && `NUM_MEM > 1)
|
case(dram1)
|
case(dram1)
|
Line 7921... |
Line 7913... |
3'd2:
|
3'd2:
|
dram2 <= dram2 + 3'd1;
|
dram2 <= dram2 + 3'd1;
|
3'd3:
|
3'd3:
|
dram2 <= dram2 + 3'd1;
|
dram2 <= dram2 + 3'd1;
|
3'd4:
|
3'd4:
|
// if (iqentry_v[dram2_id[`QBITS]] && !iqentry_stomp[dram2_id[`QBITS]]) begin
|
|
if (dhit2)
|
if (dhit2)
|
dram2 <= `DRAMREQ_READY;
|
dram2 <= `DRAMREQ_READY;
|
else
|
else
|
dram2 <= `DRAMSLOT_REQBUS;
|
dram2 <= `DRAMSLOT_REQBUS;
|
// end
|
|
/* else begin
|
|
dram2 <= `DRAMSLOT_AVAIL;
|
|
dram2_load <= `FALSE;
|
|
end*/
|
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMREQ_READY: dram2 <= `DRAMSLOT_AVAIL;
|
`DRAMREQ_READY: dram2 <= `DRAMSLOT_AVAIL;
|
endcase
|
endcase
|
|
|
Line 7973... |
Line 7959... |
dram0_id,
|
dram0_id,
|
`FALSE,
|
`FALSE,
|
fnSelect(dram0_instr,dram0_addr),
|
fnSelect(dram0_instr,dram0_addr),
|
dram0_ol,
|
dram0_ol,
|
dram0_addr,
|
dram0_addr,
|
fnDato(dram0_instr,dram0_data)
|
fnDato(dram0_instr,dram0_data),
|
|
wbptr
|
);
|
);
|
// iqentry_done[ dram0_id[`QBITS] ] <= `VAL;
|
wbptr <= wbptr + 2'd1;
|
// iqentry_out[ dram0_id[`QBITS] ] <= `INV;
|
|
iqentry_state[ dram0_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram0_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
end
|
end
|
else if (dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin
|
else if (dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin
|
if (wbptr<`WB_DEPTH-1) begin
|
if (wbptr<`WB_DEPTH-1) begin
|
Line 7990... |
Line 7976... |
dram1_id,
|
dram1_id,
|
`FALSE,
|
`FALSE,
|
fnSelect(dram1_instr,dram1_addr),
|
fnSelect(dram1_instr,dram1_addr),
|
dram1_ol,
|
dram1_ol,
|
dram1_addr,
|
dram1_addr,
|
fnDato(dram1_instr,dram1_data)
|
fnDato(dram1_instr,dram1_data),
|
|
wbptr
|
);
|
);
|
|
wbptr <= wbptr + 2'd1;
|
iqentry_state[ dram1_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram1_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
end
|
end
|
else if (dram2==`DRAMSLOT_BUSY && dram2_store && `NUM_MEM > 2) begin
|
else if (dram2==`DRAMSLOT_BUSY && dram2_store && `NUM_MEM > 2) begin
|
if (wbptr<`WB_DEPTH-1) begin
|
if (wbptr<`WB_DEPTH-1) begin
|
Line 8005... |
Line 7993... |
dram2_id,
|
dram2_id,
|
`FALSE,
|
`FALSE,
|
fnSelect(dram2_instr,dram2_addr),
|
fnSelect(dram2_instr,dram2_addr),
|
dram2_ol,
|
dram2_ol,
|
dram2_addr,
|
dram2_addr,
|
fnDato(dram2_instr,dram2_data)
|
fnDato(dram2_instr,dram2_data),
|
|
wbptr
|
);
|
);
|
|
wbptr <= wbptr + 2'd1;
|
iqentry_state[ dram2_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram2_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
|
|
Line 8033... |
Line 8023... |
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
we <= `HIGH;
|
we <= `HIGH;
|
sel_o <= wb_sel[0];
|
sel_o <= wb_sel[0];
|
vadr <= wb_addr[0];
|
vadr <= wb_addr[0];
|
dat_o <= wb_data[0];
|
dat_o <= wb_data[0];
|
|
dcbuf <= {4{wb_data[0]}};
|
|
dcsel <= wb_sel[0] << {wb_addr[0][4:3],3'b0};
|
ol_o <= wb_ol[0];
|
ol_o <= wb_ol[0];
|
wbo_id <= wb_id[0];
|
wbo_id <= wb_id[0];
|
isStore <= TRUE;
|
isStore <= TRUE;
|
bstate <= wb_rmw[0] ? B12 : B_StoreAck;
|
bstate <= wb_rmw[0] ? B_RMWAck : B_StoreAck;
|
wb_v[0] <= `INV;
|
wb_v[0] <= `INV;
|
end
|
end
|
if (wb_v[0]==`INV && !writing_wb) begin
|
if (wb_v[0]==`INV && !writing_wb) begin
|
for (j = 1; j < `WB_DEPTH; j = j + 1) begin
|
for (j = 1; j < `WB_DEPTH; j = j + 1) begin
|
wb_v[j-1] <= wb_v[j];
|
wb_v[j-1] <= wb_v[j];
|
Line 8056... |
Line 8048... |
wb_v[`WB_DEPTH-1] <= `INV;
|
wb_v[`WB_DEPTH-1] <= `INV;
|
wb_rmw[`WB_DEPTH-1] <= `FALSE;
|
wb_rmw[`WB_DEPTH-1] <= `FALSE;
|
end
|
end
|
|
|
`endif
|
`endif
|
if (~|wb_v && dram0==`DRAMSLOT_BUSY && dram0_rmw) begin
|
if (~|wb_v && dram0==`DRAMSLOT_BUSY && dram0_rmw
|
|
&& !iqentry_stomp[dram0_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_smatch0|dbg_lmatch0) begin
|
if (dbg_smatch0|dbg_lmatch0) begin
|
dramA_v <= `TRUE;
|
dramA_v <= `TRUE;
|
dramA_id <= dram0_id;
|
dramA_id <= dram0_id;
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
Line 8078... |
Line 8071... |
bwhich <= 2'b00;
|
bwhich <= 2'b00;
|
dram0 <= `DRAMSLOT_HASBUS;
|
dram0 <= `DRAMSLOT_HASBUS;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= fnSelect(dram0_instr,dram0_addr);
|
sel_o <= fnSelect(dram0_instr,dram0_addr);
|
|
dcbuf <= {4{fnDato(dram0_instr,dram0_data)}};
|
|
dcsel <= fnSelect(dram0_instr,dram0_addr) << {dram0_addr[4:3],3'b0};
|
vadr <= dram0_addr;
|
vadr <= dram0_addr;
|
dat_o <= fnDato(dram0_instr,dram0_data);
|
dat_o <= fnDato(dram0_instr,dram0_data);
|
ol_o <= dram0_ol;
|
ol_o <= dram0_ol;
|
bstate <= B12;
|
bstate <= B_RMWAck;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && dram1==`DRAMSLOT_BUSY && dram1_rmw && `NUM_MEM > 1) begin
|
else if (~|wb_v && dram1==`DRAMSLOT_BUSY && dram1_rmw && `NUM_MEM > 1
|
|
&& !iqentry_stomp[dram1_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_smatch1|dbg_lmatch1) begin
|
if (dbg_smatch1|dbg_lmatch1) begin
|
dramB_v <= `TRUE;
|
dramB_v <= `TRUE;
|
dramB_id <= dram1_id;
|
dramB_id <= dram1_id;
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
Line 8109... |
Line 8105... |
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= fnSelect(dram1_instr,dram1_addr);
|
sel_o <= fnSelect(dram1_instr,dram1_addr);
|
vadr <= dram1_addr;
|
vadr <= dram1_addr;
|
dat_o <= fnDato(dram1_instr,dram1_data);
|
dat_o <= fnDato(dram1_instr,dram1_data);
|
ol_o <= dram1_ol;
|
ol_o <= dram1_ol;
|
bstate <= B12;
|
dcbuf <= {4{fnDato(dram1_instr,dram1_data)}};
|
|
dcsel <= fnSelect(dram1_instr,dram1_addr) << {dram1_addr[4:3],3'b0};
|
|
bstate <= B_RMWAck;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && dram2==`DRAMSLOT_BUSY && dram2_rmw && `NUM_MEM > 2) begin
|
else if (~|wb_v && dram2==`DRAMSLOT_BUSY && dram2_rmw && `NUM_MEM > 2
|
|
&& !iqentry_stomp[dram2_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_smatch2|dbg_lmatch2) begin
|
if (dbg_smatch2|dbg_lmatch2) begin
|
dramC_v <= `TRUE;
|
dramC_v <= `TRUE;
|
dramC_id <= dram2_id;
|
dramC_id <= dram2_id;
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
Line 8137... |
Line 8136... |
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= fnSelect(dram2_instr,dram2_addr);
|
sel_o <= fnSelect(dram2_instr,dram2_addr);
|
vadr <= dram2_addr;
|
vadr <= dram2_addr;
|
dat_o <= fnDato(dram2_instr,dram2_data);
|
dat_o <= fnDato(dram2_instr,dram2_data);
|
ol_o <= dram2_ol;
|
ol_o <= dram2_ol;
|
bstate <= B12;
|
dcbuf <= {4{fnDato(dram2_instr,dram2_data)}};
|
|
dcsel <= fnSelect(dram2_instr,dram2_addr) << {dram2_addr[4:3],3'b0};
|
|
bstate <= B_RMWAck;
|
end
|
end
|
end
|
end
|
`ifndef HAS_WB
|
`ifndef HAS_WB
|
// Check write buffer enable ?
|
// Check write buffer enable ?
|
else if (dram0==`DRAMSLOT_BUSY && dram0_store) begin
|
else if (dram0==`DRAMSLOT_BUSY && dram0_store) begin
|
Line 8167... |
Line 8168... |
vadr <= dram0_addr;
|
vadr <= dram0_addr;
|
dat_o <= fnDato(dram0_instr,dram0_data);
|
dat_o <= fnDato(dram0_instr,dram0_data);
|
ol_o <= dram0_ol;
|
ol_o <= dram0_ol;
|
isStore <= TRUE;
|
isStore <= TRUE;
|
bstate <= B_StoreAck;
|
bstate <= B_StoreAck;
|
|
dcbuf <= {4{fnDato(dram0_instr,dram0_data)}};
|
|
dcsel <= fnSelect(dram0_instr,dram0_addr) << {dram0_addr[4:3],3'b0};
|
end
|
end
|
// cr_o <= IsSWC(dram0_instr);
|
// cr_o <= IsSWC(dram0_instr);
|
end
|
end
|
end
|
end
|
else if (dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin
|
else if (dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin
|
Line 8195... |
Line 8198... |
sel_o <= fnSelect(dram1_instr,dram1_addr);
|
sel_o <= fnSelect(dram1_instr,dram1_addr);
|
vadr <= dram1_addr;
|
vadr <= dram1_addr;
|
dat_o <= fnDato(dram1_instr,dram1_data);
|
dat_o <= fnDato(dram1_instr,dram1_data);
|
ol_o <= dram1_ol;
|
ol_o <= dram1_ol;
|
isStore <= TRUE;
|
isStore <= TRUE;
|
|
dcbuf <= {4{fnDato(dram1_instr,dram1_data)}};
|
|
dcsel <= fnSelect(dram1_instr,dram1_addr) << {dram1_addr[4:3],3'b0};
|
bstate <= B_StoreAck;
|
bstate <= B_StoreAck;
|
end
|
end
|
// cr_o <= IsSWC(dram0_instr);
|
// cr_o <= IsSWC(dram0_instr);
|
end
|
end
|
end
|
end
|
Line 8224... |
Line 8229... |
sel_o <= fnSelect(dram2_instr,dram2_addr);
|
sel_o <= fnSelect(dram2_instr,dram2_addr);
|
vadr <= dram2_addr;
|
vadr <= dram2_addr;
|
dat_o <= fnDato(dram2_instr,dram2_data);
|
dat_o <= fnDato(dram2_instr,dram2_data);
|
ol_o <= dram2_ol;
|
ol_o <= dram2_ol;
|
isStore <= TRUE;
|
isStore <= TRUE;
|
|
dcbuf <= {4{fnDato(dram2_instr,dram2_data)}};
|
|
dcsel <= fnSelect(dram2_instr,dram2_addr) << {dram2_addr[4:3],3'b0};
|
bstate <= B_StoreAck;
|
bstate <= B_StoreAck;
|
end
|
end
|
// cr_o <= IsSWC(dram0_instr);
|
// cr_o <= IsSWC(dram0_instr);
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
// Check for read misses on the data cache
|
// Check for read misses on the data cache
|
else if (~|wb_v && !dram0_unc && dram0==`DRAMSLOT_REQBUS && dram0_load) begin
|
else if (~|wb_v && !dram0_unc && dram0==`DRAMSLOT_REQBUS && dram0_load
|
|
&& !iqentry_stomp[dram0_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_lmatch0) begin
|
if (dbg_lmatch0) begin
|
dramA_v <= `TRUE;
|
dramA_v <= `TRUE;
|
dramA_id <= dram0_id;
|
dramA_id <= dram0_id;
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
Line 8249... |
Line 8257... |
bwhich <= 2'b00;
|
bwhich <= 2'b00;
|
preload <= dram0_preload;
|
preload <= dram0_preload;
|
bstate <= B_DCacheLoadStart;
|
bstate <= B_DCacheLoadStart;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && !dram1_unc && dram1==`DRAMSLOT_REQBUS && dram1_load && `NUM_MEM > 1) begin
|
else if (~|wb_v && !dram1_unc && dram1==`DRAMSLOT_REQBUS && dram1_load && `NUM_MEM > 1
|
|
&& !iqentry_stomp[dram1_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_lmatch1) begin
|
if (dbg_lmatch1) begin
|
dramB_v <= `TRUE;
|
dramB_v <= `TRUE;
|
dramB_id <= dram1_id;
|
dramB_id <= dram1_id;
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
Line 8267... |
Line 8276... |
bwhich <= 2'b01;
|
bwhich <= 2'b01;
|
preload <= dram1_preload;
|
preload <= dram1_preload;
|
bstate <= B_DCacheLoadStart;
|
bstate <= B_DCacheLoadStart;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && !dram2_unc && dram2==`DRAMSLOT_REQBUS && dram2_load && `NUM_MEM > 2) begin
|
else if (~|wb_v && !dram2_unc && dram2==`DRAMSLOT_REQBUS && dram2_load && `NUM_MEM > 2
|
|
&& !iqentry_stomp[dram2_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_lmatch2) begin
|
if (dbg_lmatch2) begin
|
dramC_v <= `TRUE;
|
dramC_v <= `TRUE;
|
dramC_id <= dram2_id;
|
dramC_id <= dram2_id;
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
Line 8285... |
Line 8295... |
preload <= dram2_preload;
|
preload <= dram2_preload;
|
bwhich <= 2'b10;
|
bwhich <= 2'b10;
|
bstate <= B_DCacheLoadStart;
|
bstate <= B_DCacheLoadStart;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && dram0_unc && dram0==`DRAMSLOT_BUSY && dram0_load) begin
|
else if (~|wb_v && dram0_unc && dram0==`DRAMSLOT_BUSY && dram0_load
|
|
&& !iqentry_stomp[dram0_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_lmatch0) begin
|
if (dbg_lmatch0) begin
|
dramA_v <= `TRUE;
|
dramA_v <= `TRUE;
|
dramA_id <= dram0_id;
|
dramA_id <= dram0_id;
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
Line 8298... |
Line 8309... |
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
bwhich <= 2'b00;
|
bwhich <= 2'b00;
|
|
dram0 <= `DRAMSLOT_HASBUS;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= fnSelect(dram0_instr,dram0_addr);
|
sel_o <= fnSelect(dram0_instr,dram0_addr);
|
vadr <= {dram0_addr[AMSB:3],3'b0};
|
vadr <= {dram0_addr[AMSB:3],3'b0};
|
sr_o <= IsLWR(dram0_instr);
|
sr_o <= IsLWR(dram0_instr);
|
ol_o <= dram0_ol;
|
ol_o <= dram0_ol;
|
dccnt <= 2'd0;
|
dccnt <= 2'd0;
|
bstate <= B_DLoadAck;
|
bstate <= B_DLoadAck;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && dram1_unc && dram1==`DRAMSLOT_BUSY && dram1_load && `NUM_MEM > 1) begin
|
else if (~|wb_v && dram1_unc && dram1==`DRAMSLOT_BUSY && dram1_load && `NUM_MEM > 1
|
|
&& !iqentry_stomp[dram1_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_lmatch1) begin
|
if (dbg_lmatch1) begin
|
dramB_v <= `TRUE;
|
dramB_v <= `TRUE;
|
dramB_id <= dram1_id;
|
dramB_id <= dram1_id;
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
Line 8321... |
Line 8334... |
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
bwhich <= 2'b01;
|
bwhich <= 2'b01;
|
|
dram1 <= `DRAMSLOT_HASBUS;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= fnSelect(dram1_instr,dram1_addr);
|
sel_o <= fnSelect(dram1_instr,dram1_addr);
|
vadr <= {dram1_addr[AMSB:3],3'b0};
|
vadr <= {dram1_addr[AMSB:3],3'b0};
|
sr_o <= IsLWR(dram1_instr);
|
sr_o <= IsLWR(dram1_instr);
|
ol_o <= dram1_ol;
|
ol_o <= dram1_ol;
|
dccnt <= 2'd0;
|
dccnt <= 2'd0;
|
bstate <= B_DLoadAck;
|
bstate <= B_DLoadAck;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && dram2_unc && dram2==`DRAMSLOT_BUSY && dram2_load && `NUM_MEM > 2) begin
|
else if (~|wb_v && dram2_unc && dram2==`DRAMSLOT_BUSY && dram2_load && `NUM_MEM > 2
|
|
&& !iqentry_stomp[dram2_id[`QBITS]]) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_lmatch2) begin
|
if (dbg_lmatch2) begin
|
dramC_v <= `TRUE;
|
dramC_v <= `TRUE;
|
dramC_id <= dram2_id;
|
dramC_id <= dram2_id;
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
Line 8344... |
Line 8359... |
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
bwhich <= 2'b10;
|
bwhich <= 2'b10;
|
|
dram2 <= `DRAMSLOT_HASBUS;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= fnSelect(dram2_instr,dram2_addr);
|
sel_o <= fnSelect(dram2_instr,dram2_addr);
|
vadr <= {dram2_addr[AMSB:3],3'b0};
|
vadr <= {dram2_addr[AMSB:3],3'b0};
|
sr_o <= IsLWR(dram2_instr);
|
sr_o <= IsLWR(dram2_instr);
|
Line 8357... |
Line 8373... |
end
|
end
|
end
|
end
|
// Check for L2 cache miss
|
// Check for L2 cache miss
|
else if (~|wb_v && !ihitL2 && !acki)
|
else if (~|wb_v && !ihitL2 && !acki)
|
begin
|
begin
|
cti_o <= 3'b001;
|
bstate <= B_WaitIC;
|
bte_o <= 2'b00;//2'b01; // 4 beat burst wrap
|
/*
|
cyc <= `HIGH;
|
cti_o <= 3'b001;
|
stb_o <= `HIGH;
|
bte_o <= 2'b00;//2'b01; // 4 beat burst wrap
|
sel_o <= 8'hFF;
|
cyc <= `HIGH;
|
icl_o <= `HIGH;
|
stb_o <= `HIGH;
|
iccnt <= 3'd0;
|
sel_o <= 8'hFF;
|
icack <= 1'b0;
|
icl_o <= `HIGH;
|
// adr_o <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
iccnt <= 3'd0;
|
// L2_adr <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
icack <= 1'b0;
|
vadr <= {pcr[7:0],L1_adr[AMSB:5],5'h0};
|
// adr_o <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
`ifdef SUPPORT_SMT
|
// L2_adr <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
`else
|
vadr <= {L1_adr[AMSB:5],5'h0};
|
ol_o <= ol;//???
|
`ifdef SUPPORT_SMT
|
`endif
|
`else
|
L2_adr <= {pcr[7:0],L1_adr[AMSB:5],5'h0};
|
ol_o <= ol;//???
|
L2_xsel <= 1'b0;
|
`endif
|
bstate <= B_ICacheAck;
|
L2_adr <= {L1_adr[AMSB:5],5'h0};
|
|
L2_xsel <= 1'b0;
|
|
selL2 <= TRUE;
|
|
bstate <= B_ICacheAck;
|
|
*/
|
|
end
|
end
|
end
|
|
B_WaitIC:
|
|
begin
|
|
cti_o <= icti;
|
|
bte_o <= ibte;
|
|
cyc <= icyc;
|
|
stb_o <= istb;
|
|
sel_o <= isel;
|
|
vadr <= iadr;
|
|
we <= 1'b0;
|
|
if (L2_nxt)
|
|
bstate <= BIDLE;
|
end
|
end
|
|
|
// Terminal state for a store operation.
|
// Terminal state for a store operation.
|
// Note that if only a single memory channel is selected, bwhich will be a
|
// Note that if only a single memory channel is selected, bwhich will be a
|
// constant 0. This should cause the extra code to be removed.
|
// constant 0. This should cause the extra code to be removed.
|
Line 8449... |
Line 8481... |
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
// Select should be selecting all byte lanes for a cache load
|
// Select should be selecting all byte lanes for a cache load
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
// bwhich should always be one of the three channels.
|
// bwhich should always be one of the three channels.
|
|
// If single bit upset, continue to select channel zero when
|
|
// there's only one available.
|
case(bwhich)
|
case(bwhich)
|
2'd0: begin
|
|
vadr <= {dram0_addr[AMSB:5],5'b0};
|
|
ol_o <= dram0_ol;
|
|
end
|
|
2'd1: if (`NUM_MEM > 1) begin
|
2'd1: if (`NUM_MEM > 1) begin
|
vadr <= {dram1_addr[AMSB:5],5'b0};
|
vadr <= {dram1_addr[AMSB:5],5'b0};
|
ol_o <= dram1_ol;
|
ol_o <= dram1_ol;
|
|
if (iqentry_stomp[dram1_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram1 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
end
|
|
else begin
|
|
vadr <= {dram0_addr[AMSB:5],5'b0};
|
|
ol_o <= dram0_ol;
|
|
if (iqentry_stomp[dram0_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram0 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
end
|
end
|
2'd2: if (`NUM_MEM > 2) begin
|
2'd2: if (`NUM_MEM > 2) begin
|
vadr <= {dram2_addr[AMSB:5],5'b0};
|
vadr <= {dram2_addr[AMSB:5],5'b0};
|
ol_o <= dram2_ol;
|
ol_o <= dram2_ol;
|
|
if (iqentry_stomp[dram2_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram2 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
end
|
|
else if (`NUM_MEM > 1) begin
|
|
vadr <= {dram1_addr[AMSB:5],5'b0};
|
|
ol_o <= dram1_ol;
|
|
if (iqentry_stomp[dram1_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram1 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
end
|
|
else begin
|
|
vadr <= {dram0_addr[AMSB:5],5'b0};
|
|
ol_o <= dram0_ol;
|
|
if (iqentry_stomp[dram0_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram0 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
$display("Invalid memory channel selection");
|
vadr <= {dram0_addr[AMSB:5],5'b0};
|
$stop;
|
ol_o <= dram0_ol;
|
|
if (iqentry_stomp[dram0_id[`QBITS]]) begin
|
wb_nack();
|
wb_nack();
|
|
dram0 <= `DRAMREQ_READY;
|
bstate <= BIDLE;
|
bstate <= BIDLE;
|
end
|
end
|
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
// Data cache load terminal state
|
// Data cache load terminal state
|
B_DCacheLoadAck:
|
B_DCacheLoadAck:
|
|
begin
|
|
dcsel <= 32'hFFFFFFFF;
|
if (acki|err_i|tlb_miss|rdv_i) begin
|
if (acki|err_i|tlb_miss|rdv_i) begin
|
if (!bok_i) begin
|
if (!bok_i) begin
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
bstate <= B_DCacheLoadStb;
|
bstate <= B_DCacheLoadStb;
|
end
|
end
|
errq <= errq | err_i;
|
errq <= errq | err_i;
|
rdvq <= rdvq | rdv_i;
|
rdvq <= rdvq | rdv_i;
|
if (!preload) // A preload instruction ignores any error
|
if (!preload) // A preload instruction ignores any error
|
|
if (dccnt==3'd3)
|
case(bwhich)
|
case(bwhich)
|
2'd0: iqentry_exc[dram0_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
2'd0:
|
2'd1: iqentry_exc[dram1_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
if (iqentry_stomp[dram0_id[`QBITS]])
|
2'd2: iqentry_exc[dram2_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc[dram0_id[`QBITS]] <= `FLT_NONE;
|
default: ;
|
else
|
|
iqentry_exc[dram0_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
|
2'd1:
|
|
if (iqentry_stomp[dram1_id[`QBITS]])
|
|
iqentry_exc[dram1_id[`QBITS]] <= `FLT_NONE;
|
|
else
|
|
iqentry_exc[dram1_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
|
2'd2:
|
|
if (iqentry_stomp[dram2_id[`QBITS]])
|
|
iqentry_exc[dram2_id[`QBITS]] <= `FLT_NONE;
|
|
else
|
|
iqentry_exc[dram2_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
|
default:
|
|
if (iqentry_stomp[dram0_id[`QBITS]])
|
|
iqentry_exc[dram0_id[`QBITS]] <= `FLT_NONE;
|
|
else
|
|
iqentry_exc[dram0_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
|
endcase
|
|
case(dccnt)
|
|
2'd0: dcbuf[63:0] <= dat_i;
|
|
2'd1: dcbuf[127:64] <= dat_i;
|
|
2'd2: dcbuf[191:128] <= dat_i;
|
|
2'd3: dcbuf[255:192] <= dat_i;
|
endcase
|
endcase
|
dccnt <= dccnt + 2'd1;
|
dccnt <= dccnt + 2'd1;
|
vadr[4:3] <= vadr[4:3] + 2'd1;
|
vadr[4:3] <= vadr[4:3] + 2'd1;
|
if (dccnt==2'd2)
|
if (dccnt==2'd2)
|
cti_o <= 3'b111;
|
cti_o <= 3'b111;
|
if (dccnt==2'd3) begin
|
if (dccnt==2'd3) begin
|
wb_nack();
|
wb_nack();
|
bstate <= B_DCacheLoadWait1;
|
dcwr <= 1'b1;
|
|
dcwait_ctr <= dcwait;
|
|
bstate <= B_DCacheLoadWait;
|
|
end
|
end
|
end
|
end
|
end
|
B_DCacheLoadStb:
|
B_DCacheLoadStb:
|
begin
|
begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
bstate <= B_DCacheLoadAck;
|
bstate <= B_DCacheLoadAck;
|
|
case(bwhich)
|
|
2'd0:
|
|
if (iqentry_stomp[dram0_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram0 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
2'd1:
|
|
if (iqentry_stomp[dram1_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram1 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
2'd2:
|
|
if (iqentry_stomp[dram2_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram2 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
default:
|
|
if (iqentry_stomp[dram0_id[`QBITS]]) begin
|
|
wb_nack();
|
|
dram0 <= `DRAMREQ_READY;
|
|
bstate <= BIDLE;
|
|
end
|
|
endcase
|
|
end
|
|
B_DCacheLoadWait:
|
|
begin
|
|
dcsel <= 32'h0;
|
|
dcwr <= 1'b0;
|
|
dcwait_ctr <= dcwait_ctr - 4'd1;
|
|
if (dcwait_ctr[3]) // detect underflow
|
|
bstate <= B_DCacheLoadResetBusy;
|
end
|
end
|
B_DCacheLoadWait1: bstate <= B_DCacheLoadWait2;
|
|
B_DCacheLoadWait2: bstate <= B_DCacheLoadResetBusy;
|
|
//B_DCacheLoadWait3: bstate <= B_DCacheLoadResetBusy;
|
|
// There could be more than one memory cycle active. We reset the state
|
// There could be more than one memory cycle active. We reset the state
|
// of all the machines to retest for a hit because otherwise sequential
|
// of the other machines to retest for a hit because otherwise sequential
|
// loading of memory will cause successive machines to miss resulting in
|
// loading of memory will cause successive machines to miss resulting in
|
// multiple dcache loads that aren't needed.
|
// multiple dcache loads that aren't needed.
|
B_DCacheLoadResetBusy:
|
B_DCacheLoadResetBusy:
|
begin
|
begin
|
|
if (`NUM_MEM > 1)
|
|
case(bwhich)
|
|
2'b01:
|
|
begin
|
|
dram1 <= `DRAMREQ_READY;
|
if (dram0 != `DRAMSLOT_AVAIL && dram0_addr[AMSB:5]==vadr[AMSB:5]) dram0 <= `DRAMSLOT_BUSY; // causes retest of dhit
|
if (dram0 != `DRAMSLOT_AVAIL && dram0_addr[AMSB:5]==vadr[AMSB:5]) dram0 <= `DRAMSLOT_BUSY; // causes retest of dhit
|
if (dram1 != `DRAMSLOT_AVAIL && dram1_addr[AMSB:5]==vadr[AMSB:5]) dram1 <= `DRAMSLOT_BUSY;
|
|
if (dram2 != `DRAMSLOT_AVAIL && dram2_addr[AMSB:5]==vadr[AMSB:5]) dram2 <= `DRAMSLOT_BUSY;
|
if (dram2 != `DRAMSLOT_AVAIL && dram2_addr[AMSB:5]==vadr[AMSB:5]) dram2 <= `DRAMSLOT_BUSY;
|
bstate <= BIDLE;
|
|
end
|
end
|
|
2'b10:
|
// Ack state for instruction cache load
|
if (`NUM_MEM > 2) begin
|
// Once the first ack is received in burst mode, further acks are not necessary
|
dram2 <= `DRAMREQ_READY;
|
// as the core counts the number of data items. Occasionally missing acks were
|
if (dram0 != `DRAMSLOT_AVAIL && dram0_addr[AMSB:5]==vadr[AMSB:5]) dram0 <= `DRAMSLOT_BUSY; // causes retest of dhit
|
// causing a problem.
|
if (dram1 != `DRAMSLOT_AVAIL && dram1_addr[AMSB:5]==vadr[AMSB:5]) dram1 <= `DRAMSLOT_BUSY;
|
B_ICacheAck:
|
|
if (acki|err_i|tlb_miss|exv_i|icack) begin
|
|
if (!bok_i) begin
|
|
stb_o <= `LOW;
|
|
bstate <= B_ICacheNack2;
|
|
end
|
|
else
|
|
icack <= 1'b1;
|
|
errq <= errq | err_i;
|
|
exvq <= exvq | exv_i;
|
|
if (tlb_miss) begin
|
|
L1_dati <= {19{`INSN_FLT_TLB}};
|
|
wb_nack();
|
|
icl_o <= `LOW;
|
|
bstate <= B_ICacheNack;
|
|
end
|
end
|
else if (exv_i) begin
|
else begin
|
L1_dati <= {19{`INSN_FLT_EXF}};
|
dram0 <= `DRAMREQ_READY;
|
wb_nack();
|
if (dram1 != `DRAMSLOT_AVAIL && dram1_addr[AMSB:5]==vadr[AMSB:5]) dram1 <= `DRAMSLOT_BUSY;
|
icl_o <= `LOW;
|
if (dram2 != `DRAMSLOT_AVAIL && dram2_addr[AMSB:5]==vadr[AMSB:5]) dram2 <= `DRAMSLOT_BUSY;
|
bstate <= B_ICacheNack;
|
|
end
|
end
|
else if (err_i) begin
|
default:
|
L1_dati <= {19{`INSN_FLT_IBE}};
|
begin
|
wb_nack();
|
dram0 <= `DRAMREQ_READY;
|
icl_o <= `LOW;
|
if (dram1 != `DRAMSLOT_AVAIL && dram1_addr[AMSB:5]==vadr[AMSB:5]) dram1 <= `DRAMSLOT_BUSY;
|
bstate <= B_ICacheNack;
|
if (dram2 != `DRAMSLOT_AVAIL && dram2_addr[AMSB:5]==vadr[AMSB:5]) dram2 <= `DRAMSLOT_BUSY;
|
end
|
end
|
else
|
|
case(iccnt)
|
|
3'd0: L1_dati[63:0] <= dat_i;
|
|
3'd1: L1_dati[127:64] <= dat_i;
|
|
3'd2: L1_dati[191:128] <= dat_i;
|
|
3'd3: L1_dati[255:192] <= dat_i;
|
|
3'd4: L1_dati[305:256] <= {2'b00,dat_i[47:0]};
|
|
default: L1_dati <= L1_dati;
|
|
endcase
|
endcase
|
iccnt <= iccnt + 3'd1;
|
|
if (iccnt==3'd3)
|
|
cti_o <= 3'b111;
|
|
if (iccnt==3'd4) begin
|
|
wb_nack();
|
|
icl_o <= `LOW;
|
|
bstate <= B_ICacheNack;
|
|
end
|
|
else begin
|
else begin
|
L2_adr[4:3] <= L2_adr[4:3] + 2'd1;
|
dram0 <= `DRAMREQ_READY;
|
if (L2_adr[4:3]==2'b11)
|
|
L2_xsel <= 1'b1;
|
|
end
|
|
end
|
|
B_ICacheNack2:
|
|
if (~acki) begin
|
|
stb_o <= `HIGH;
|
|
vadr[AMSB:3] <= vadr[AMSB:3] + 2'd1;
|
|
bstate <= B_ICacheAck;
|
|
end
|
end
|
B_ICacheNack:
|
|
begin
|
|
L2_xsel <= 1'b0;
|
|
if (~acki) begin
|
|
icl_ctr <= icl_ctr + 40'd1;
|
|
bstate <= BIDLE;
|
bstate <= BIDLE;
|
L2_nxt <= TRUE;
|
|
vadr <= 32'hCCCCCCC8;
|
|
end
|
|
end
|
end
|
|
|
B12:
|
B_RMWAck:
|
if (acki|err_i|tlb_miss|rdv_i) begin
|
if (acki|err_i|tlb_miss|rdv_i) begin
|
if (isCAS) begin
|
if (isCAS) begin
|
iqentry_res [ casid[`QBITS] ] <= (dat_i == cas);
|
iqentry_res [ casid[`QBITS] ] <= (dat_i == cas);
|
iqentry_exc [ casid[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc [ casid[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
// iqentry_done[ casid[`QBITS] ] <= `VAL;
|
// iqentry_done[ casid[`QBITS] ] <= `VAL;
|
// iqentry_out [ casid[`QBITS] ] <= `INV;
|
// iqentry_out [ casid[`QBITS] ] <= `INV;
|
iqentry_state [ casid[`QBITS] ] <= IQS_DONE;
|
iqentry_state [ casid[`QBITS] ] <= IQS_DONE;
|
iqentry_instr[ casid[`QBITS]] <= `NOP_INSN;
|
iqentry_instr[ casid[`QBITS]] <= `NOP_INSN;
|
if (err_i | rdv_i) iqentry_ma[casid[`QBITS]] <= vadr;
|
if (err_i | rdv_i)
|
|
iqentry_ma[casid[`QBITS]] <= vadr;
|
if (dat_i == cas) begin
|
if (dat_i == cas) begin
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
we <= `TRUE;
|
we <= `TRUE;
|
bstate <= B15;
|
bstate <= B15;
|
|
check_abort_load();
|
end
|
end
|
else begin
|
else begin
|
cas <= dat_i;
|
cas <= dat_i;
|
cyc <= `LOW;
|
cyc <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
Line 8615... |
Line 8700... |
2'b01: dram1 <= `DRAMREQ_READY;
|
2'b01: dram1 <= `DRAMREQ_READY;
|
2'b10: dram2 <= `DRAMREQ_READY;
|
2'b10: dram2 <= `DRAMREQ_READY;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
bstate <= B_LSNAck;
|
bstate <= B_LSNAck;
|
|
check_abort_load();
|
end
|
end
|
end
|
end
|
else if (isRMW) begin
|
else if (isRMW) begin
|
rmw_instr <= iqentry_instr[casid[`QBITS]];
|
rmw_instr <= iqentry_instr[casid[`QBITS]];
|
rmw_argA <= dat_i;
|
rmw_argA <= dat_i;
|
Line 8637... |
Line 8723... |
rmw_argB <= iqentry_instr[casid[`QBITS]][31] ? {{59{iqentry_instr[casid[`QBITS]][20:16]}},iqentry_instr[casid[`QBITS]][20:16]} : iqentry_a2[casid[`QBITS]];
|
rmw_argB <= iqentry_instr[casid[`QBITS]][31] ? {{59{iqentry_instr[casid[`QBITS]][20:16]}},iqentry_instr[casid[`QBITS]][20:16]} : iqentry_a2[casid[`QBITS]];
|
end
|
end
|
iqentry_exc [ casid[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc [ casid[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
bstate <= B20;
|
bstate <= B20;
|
|
check_abort_load();
|
end
|
end
|
end
|
end
|
|
|
// Regular load
|
// Regular load
|
B_DLoadAck:
|
B_DLoadAck:
|
Line 8667... |
Line 8754... |
bstate <= B_DLoadNack;
|
bstate <= B_DLoadNack;
|
end
|
end
|
end
|
end
|
else
|
else
|
dram0 <= `DRAMREQ_READY;
|
dram0 <= `DRAMREQ_READY;
|
|
if (iqentry_stomp[dram0_id[`QBITS]])
|
|
iqentry_exc [dram0_id[`QBITS]] <= `FLT_NONE;
|
|
else
|
iqentry_exc [ dram0_id[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc [ dram0_id[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
end
|
end
|
2'b01: if (`NUM_MEM > 1) begin
|
2'b01: if (`NUM_MEM > 1) begin
|
dram1 <= `DRAMREQ_READY;
|
dram1 <= `DRAMREQ_READY;
|
|
if (iqentry_stomp[dram1_id[`QBITS]])
|
|
iqentry_exc [dram1_id[`QBITS]] <= `FLT_NONE;
|
|
else
|
iqentry_exc [ dram1_id[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc [ dram1_id[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
end
|
end
|
2'b10: if (`NUM_MEM > 2) begin
|
2'b10: if (`NUM_MEM > 2) begin
|
dram2 <= `DRAMREQ_READY;
|
dram2 <= `DRAMREQ_READY;
|
|
if (iqentry_stomp[dram2_id[`QBITS]])
|
|
iqentry_exc [dram2_id[`QBITS]] <= `FLT_NONE;
|
|
else
|
iqentry_exc [ dram2_id[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc [ dram2_id[`QBITS] ] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DRF : rdv_i ? `FLT_DRF : `FLT_NONE;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
bstate <= B_LSNAck;
|
bstate <= B_LSNAck;
|
|
check_abort_load();
|
end
|
end
|
B_DLoadNack:
|
B_DLoadNack:
|
if (~acki) begin
|
if (~acki) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
bstate <= B_DLoadAck;
|
bstate <= B_DLoadAck;
|
|
check_abort_load();
|
end
|
end
|
|
|
// Three cycles to detemrine if there's a cache hit during a store.
|
// Three cycles to detemrine if there's a cache hit during a store.
|
B16: begin
|
B16:
|
|
begin
|
case(bwhich)
|
case(bwhich)
|
2'd0: if (dhit0) begin dram0 <= `DRAMREQ_READY; bstate <= B17; end
|
2'd0: if (dhit0) begin dram0 <= `DRAMREQ_READY; bstate <= B17; end
|
2'd1: if (dhit1) begin dram1 <= `DRAMREQ_READY; bstate <= B17; end
|
2'd1: if (dhit1) begin dram1 <= `DRAMREQ_READY; bstate <= B17; end
|
2'd2: if (dhit2) begin dram2 <= `DRAMREQ_READY; bstate <= B17; end
|
2'd2: if (dhit2) begin dram2 <= `DRAMREQ_READY; bstate <= B17; end
|
default: bstate <= BIDLE;
|
default: bstate <= BIDLE;
|
endcase
|
endcase
|
|
check_abort_load();
|
|
end
|
|
B17:
|
|
begin
|
|
bstate <= B18;
|
|
check_abort_load();
|
|
end
|
|
B18:
|
|
begin
|
|
bstate <= B_LSNAck;
|
|
check_abort_load();
|
end
|
end
|
B17: bstate <= B18;
|
|
B18: bstate <= B_LSNAck;
|
|
B_LSNAck:
|
B_LSNAck:
|
begin
|
begin
|
bstate <= BIDLE;
|
bstate <= BIDLE;
|
StoreAck1 <= `FALSE;
|
StoreAck1 <= `FALSE;
|
isStore <= `FALSE;
|
isStore <= `FALSE;
|
|
check_abort_load();
|
end
|
end
|
B20:
|
B20:
|
if (~acki) begin
|
if (~acki) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
we <= `HIGH;
|
we <= `HIGH;
|
dat_o <= fnDato(rmw_instr,rmw_res);
|
dat_o <= fnDato(rmw_instr,rmw_res);
|
bstate <= B_StoreAck;
|
bstate <= B_StoreAck;
|
|
check_abort_load();
|
end
|
end
|
B21:
|
B21:
|
if (~acki) begin
|
if (~acki) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
bstate <= B12;
|
bstate <= B_RMWAck;
|
|
check_abort_load();
|
end
|
end
|
default: bstate <= BIDLE;
|
default: bstate <= BIDLE;
|
endcase
|
endcase
|
|
|
|
|
Line 9111... |
Line 9222... |
end
|
end
|
end
|
end
|
*/
|
*/
|
assign exc_o = iqentry_exc[heads[0]][7:0];
|
assign exc_o = iqentry_exc[heads[0]][7:0];
|
|
|
|
task check_abort_load;
|
|
begin
|
|
case(bwhich)
|
|
2'd0: if (iqentry_stomp[dram0_id[`QBITS]]) begin bstate <= BIDLE; dram0 <= `DRAMREQ_READY; end
|
|
2'd1: if (iqentry_stomp[dram1_id[`QBITS]]) begin bstate <= BIDLE; dram1 <= `DRAMREQ_READY; end
|
|
2'd2: if (iqentry_stomp[dram2_id[`QBITS]]) begin bstate <= BIDLE; dram2 <= `DRAMREQ_READY; end
|
|
default: if (iqentry_stomp[dram0_id[`QBITS]]) begin bstate <= BIDLE; dram0 <= `DRAMREQ_READY; end
|
|
endcase
|
|
end
|
|
endtask
|
|
|
// Update the write buffer.
|
// Update the write buffer.
|
task wb_update;
|
task wb_update;
|
input [`QBITS] id;
|
input [`QBITS] id;
|
input rmw;
|
input rmw;
|
input [7:0] sel;
|
input [7:0] sel;
|
input [1:0] ol;
|
input [1:0] ol;
|
input [`ABITS] addr;
|
input [`ABITS] addr;
|
input [63:0] data;
|
input [63:0] data;
|
|
input [2:0] wbptr;
|
begin
|
begin
|
if (wbm && wbptr > 1 && wb_addr[wbptr-1][AMSB:3]==addr[AMSB:3]
|
if (wbm && wbptr > 1 && wb_addr[wbptr-1][AMSB:3]==addr[AMSB:3]
|
&& wb_ol[wbptr-1]==ol && wb_rmw[wbptr-1]==rmw && wb_v[wbptr-1]) begin
|
&& wb_ol[wbptr-1]==ol && wb_rmw[wbptr-1]==rmw && wb_v[wbptr-1]) begin
|
// The write buffer is always shifted during the bus IDLE state. That means
|
// The write buffer is always shifted during the bus IDLE state. That means
|
// the data is out of place by a slot. The slot the data is moved from is
|
// the data is out of place by a slot. The slot the data is moved from is
|
Line 9151... |
Line 9274... |
wb_rmw[wbptr] <= rmw;
|
wb_rmw[wbptr] <= rmw;
|
wb_ol[wbptr] <= ol;
|
wb_ol[wbptr] <= ol;
|
wb_sel[wbptr] <= sel;
|
wb_sel[wbptr] <= sel;
|
wb_addr[wbptr] <= {addr[AMSB:3],3'b0};
|
wb_addr[wbptr] <= {addr[AMSB:3],3'b0};
|
wb_data[wbptr] <= data;
|
wb_data[wbptr] <= data;
|
wbptr <= wbptr + 2'd1;
|
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
// Increment the head pointers
|
// Increment the head pointers
|
Line 9546... |
Line 9668... |
input [`QBITS] head;
|
input [`QBITS] head;
|
input thread;
|
input thread;
|
input [7:0] causecd;
|
input [7:0] causecd;
|
begin
|
begin
|
excmiss <= TRUE;
|
excmiss <= TRUE;
|
`ifdef SUPPORT_SMT
|
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol[thread],5'h00};
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol[thread],5'h00};
|
excthrd <= iqentry_thrd[head];
|
|
badaddr[{thread,2'd0}] <= iqentry_ma[head];
|
badaddr[{thread,2'd0}] <= iqentry_ma[head];
|
bad_instr[{thread,2'd0}] <= iqentry_instr[head];
|
bad_instr[{thread,2'd0}] <= iqentry_instr[head];
|
|
im_stack <= {im_stack[27:0],4'hF};
|
|
`ifdef SUPPORT_SMT
|
|
excthrd <= iqentry_thrd[head];
|
|
ol_stack[thread] <= {ol_stack[thread][13:0],2'b00};
|
|
dl_stack[thread] <= {dl_stack[thread][13:0],2'b00};
|
epc0[thread] <= iqentry_pc[head];
|
epc0[thread] <= iqentry_pc[head];
|
epc1[thread] <= epc0[thread];
|
epc1[thread] <= epc0[thread];
|
epc2[thread] <= epc1[thread];
|
epc2[thread] <= epc1[thread];
|
epc3[thread] <= epc2[thread];
|
epc3[thread] <= epc2[thread];
|
epc4[thread] <= epc3[thread];
|
epc4[thread] <= epc3[thread];
|
epc5[thread] <= epc4[thread];
|
epc5[thread] <= epc4[thread];
|
epc6[thread] <= epc5[thread];
|
epc6[thread] <= epc5[thread];
|
epc7[thread] <= epc6[thread];
|
epc7[thread] <= epc6[thread];
|
epc8[thread] <= epc7[thread];
|
epc8[thread] <= epc7[thread];
|
im_stack[thread] <= {im_stack[thread][27:0],im};
|
|
ol_stack[thread] <= {ol_stack[thread][13:0],ol[thread]};
|
|
dl_stack[thread] <= {dl_stack[thread][13:0],dl[thread]};
|
|
pl_stack[thread] <= {pl_stack[thread][55:0],cpl[thread]};
|
pl_stack[thread] <= {pl_stack[thread][55:0],cpl[thread]};
|
rs_stack[thread] <= {rs_stack[thread][59:0],`EXC_RGS};
|
rs_stack[thread] <= {rs_stack[thread][59:0],`EXC_RGS};
|
brs_stack[thread] <= {brs_stack[thread][59:0],`EXC_RGS};
|
brs_stack[thread] <= {brs_stack[thread][59:0],`EXC_RGS};
|
cause[{thread,2'd0}] <= {8'd0,causecd};
|
cause[{thread,2'd0}] <= {8'd0,causecd};
|
mstatus[thread][5:4] <= 2'd0;
|
mstatus[thread][5:4] <= 2'd0;
|
mstatus[thread][13:6] <= 8'h00;
|
mstatus[thread][13:6] <= 8'h00;
|
mstatus[thread][19:14] <= `EXC_RGS;
|
mstatus[thread][19:14] <= `EXC_RGS;
|
`else
|
`else
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol,5'h00};
|
|
excthrd <= 1'b0;
|
excthrd <= 1'b0;
|
badaddr[{1'b0,2'd0}] <= iqentry_ma[head];
|
ol_stack <= {ol_stack[13:0],2'b00};
|
bad_instr[3'd0] <= iqentry_instr[head];
|
dl_stack <= {dl_stack[13:0],2'b00};
|
epc0 <= iqentry_pc[head];
|
epc0 <= iqentry_pc[head];
|
epc1 <= epc0;
|
epc1 <= epc0;
|
epc2 <= epc1;
|
epc2 <= epc1;
|
epc3 <= epc2;
|
epc3 <= epc2;
|
epc4 <= epc3;
|
epc4 <= epc3;
|
epc5 <= epc4;
|
epc5 <= epc4;
|
epc6 <= epc5;
|
epc6 <= epc5;
|
epc7 <= epc6;
|
epc7 <= epc6;
|
epc8 <= epc7;
|
epc8 <= epc7;
|
im_stack <= {im_stack[27:0],im};
|
|
ol_stack <= {ol_stack[13:0],ol};
|
|
dl_stack <= {dl_stack[13:0],dl};
|
|
pl_stack <= {pl_stack[55:0],cpl};
|
pl_stack <= {pl_stack[55:0],cpl};
|
rs_stack <= {rs_stack[59:0],`EXC_RGS};
|
rs_stack <= {rs_stack[59:0],`EXC_RGS};
|
brs_stack <= {rs_stack[59:0],`EXC_RGS};
|
brs_stack <= {rs_stack[59:0],`EXC_RGS};
|
cause[3'd0] <= {8'd0,causecd};
|
cause[3'd0] <= {8'd0,causecd};
|
mstatus[5:4] <= 2'd0;
|
mstatus[5:4] <= 2'd0;
|
Line 9624... |
Line 9742... |
`BRK:
|
`BRK:
|
// BRK is treated as a nop unless it's a software interrupt or a
|
// BRK is treated as a nop unless it's a software interrupt or a
|
// hardware interrupt at a higher priority than the current priority.
|
// hardware interrupt at a higher priority than the current priority.
|
if ((|iqentry_instr[head][25:21]) || iqentry_instr[head][20:17] > im) begin
|
if ((|iqentry_instr[head][25:21]) || iqentry_instr[head][20:17] > im) begin
|
excmiss <= TRUE;
|
excmiss <= TRUE;
|
|
im_stack <= {im_stack[27:0],4'hF};
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
|
ol_stack[thread] <= {ol_stack[thread][13:0],2'b00};
|
|
dl_stack[thread] <= {dl_stack[thread][13:0],2'b00};
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol[thread],5'h00};
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol[thread],5'h00};
|
excthrd <= iqentry_thrd[head];
|
excthrd <= iqentry_thrd[head];
|
epc0[thread] <= iqentry_pc[head] + {iqentry_instr[head][25:21],1'b0};
|
epc0[thread] <= iqentry_pc[head] + {iqentry_instr[head][25:21],1'b0};
|
epc1[thread] <= epc0[thread];
|
epc1[thread] <= epc0[thread];
|
epc2[thread] <= epc1[thread];
|
epc2[thread] <= epc1[thread];
|
Line 9636... |
Line 9757... |
epc4[thread] <= epc3[thread];
|
epc4[thread] <= epc3[thread];
|
epc5[thread] <= epc4[thread];
|
epc5[thread] <= epc4[thread];
|
epc6[thread] <= epc5[thread];
|
epc6[thread] <= epc5[thread];
|
epc7[thread] <= epc6[thread];
|
epc7[thread] <= epc6[thread];
|
epc8[thread] <= epc7[thread];
|
epc8[thread] <= epc7[thread];
|
im_stack[thread] <= {im_stack[thread][27:0],im};
|
|
ol_stack[thread] <= {ol_stack[thread][13:0],ol[thread]};
|
|
dl_stack[thread] <= {dl_stack[thread][13:0],dl[thread]};
|
|
pl_stack[thread] <= {pl_stack[thread][55:0],cpl[thread]};
|
pl_stack[thread] <= {pl_stack[thread][55:0],cpl[thread]};
|
rs_stack[thread] <= {rs_stack[thread][59:0],`BRK_RGS};
|
rs_stack[thread] <= {rs_stack[thread][59:0],`BRK_RGS};
|
brs_stack[thread] <= {brs_stack[thread][59:0],`BRK_RGS};
|
brs_stack[thread] <= {brs_stack[thread][59:0],`BRK_RGS};
|
cause[{thread,2'd0}] <= iqentry_res[head][7:0];
|
cause[{thread,2'd0}] <= iqentry_res[head][7:0];
|
mstatus[thread][5:4] <= 2'd0;
|
mstatus[thread][5:4] <= 2'd0;
|
Line 9662... |
Line 9780... |
mstatus[thread][19:14] <= `BRK_RGS;
|
mstatus[thread][19:14] <= `BRK_RGS;
|
rs_stack[thread][5:0] <= `BRK_RGS;
|
rs_stack[thread][5:0] <= `BRK_RGS;
|
brs_stack[thread][5:0] <= `BRK_RGS;
|
brs_stack[thread][5:0] <= `BRK_RGS;
|
end
|
end
|
`else
|
`else
|
|
ol_stack <= {ol_stack[13:0],2'b00};
|
|
dl_stack <= {dl_stack[13:0],2'b00};
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol,5'h00};
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol,5'h00};
|
excthrd <= 1'b0;
|
excthrd <= 1'b0;
|
epc0 <= iqentry_pc[head] + {iqentry_instr[head][25:21],1'b0};
|
epc0 <= iqentry_pc[head] + {iqentry_instr[head][25:21],1'b0};
|
epc1 <= epc0;
|
epc1 <= epc0;
|
epc2 <= epc1;
|
epc2 <= epc1;
|
Line 9673... |
Line 9793... |
epc4 <= epc3;
|
epc4 <= epc3;
|
epc5 <= epc4;
|
epc5 <= epc4;
|
epc6 <= epc5;
|
epc6 <= epc5;
|
epc7 <= epc6;
|
epc7 <= epc6;
|
epc8 <= epc7;
|
epc8 <= epc7;
|
im_stack <= {im_stack[27:0],im};
|
|
ol_stack <= {ol_stack[13:0],ol};
|
|
dl_stack <= {dl_stack[13:0],dl};
|
|
pl_stack <= {pl_stack[55:0],cpl};
|
pl_stack <= {pl_stack[55:0],cpl};
|
rs_stack <= {rs_stack[59:0],`BRK_RGS};
|
rs_stack <= {rs_stack[59:0],`BRK_RGS};
|
brs_stack <= {brs_stack[59:0],`BRK_RGS};
|
brs_stack <= {brs_stack[59:0],`BRK_RGS};
|
cause[3'd0] <= iqentry_res[head][7:0];
|
cause[3'd0] <= iqentry_res[head][7:0];
|
mstatus[5:4] <= 2'd0;
|
mstatus[5:4] <= 2'd0;
|
Line 9796... |
Line 9913... |
endcase
|
endcase
|
`MEMNDX:
|
`MEMNDX:
|
case(iqentry_instr[head][`INSTRUCTION_S2])
|
case(iqentry_instr[head][`INSTRUCTION_S2])
|
`CACHEX:
|
`CACHEX:
|
case(iqentry_instr[head][22:18])
|
case(iqentry_instr[head][22:18])
|
|
5'h02: begin invicl <= TRUE; invlineAddr <= {ASID,iqentry_res[head]}; end
|
5'h03: invic <= TRUE;
|
5'h03: invic <= TRUE;
|
5'h10: cr0[30] <= FALSE;
|
5'h10: cr0[30] <= FALSE;
|
5'h11: cr0[30] <= TRUE;
|
5'h11: cr0[30] <= TRUE;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
Line 9828... |
Line 9946... |
mstatus[13:6] <= iqentry_instr[head][25:18] | iqentry_a1[head][7:0];
|
mstatus[13:6] <= iqentry_instr[head][25:18] | iqentry_a1[head][7:0];
|
end
|
end
|
`endif
|
`endif
|
`CACHE:
|
`CACHE:
|
case(iqentry_instr[head][17:13])
|
case(iqentry_instr[head][17:13])
|
|
5'h02: begin invicl <= TRUE; invlineAddr <= {ASID,iqentry_res[head]}; end
|
5'h03: invic <= TRUE;
|
5'h03: invic <= TRUE;
|
5'h10: cr0[30] <= FALSE;
|
5'h10: cr0[30] <= FALSE;
|
5'h11: cr0[30] <= TRUE;
|
5'h11: cr0[30] <= TRUE;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
Line 9952... |
Line 10071... |
`CSR_BADADR: dat <= badaddr[{thread,csrno[11:10]}];
|
`CSR_BADADR: dat <= badaddr[{thread,csrno[11:10]}];
|
`CSR_BADINSTR: dat <= bad_instr[{thread,csrno[11:10]}];
|
`CSR_BADINSTR: dat <= bad_instr[{thread,csrno[11:10]}];
|
`CSR_CAUSE: dat <= {48'd0,cause[{thread,csrno[11:10]}]};
|
`CSR_CAUSE: dat <= {48'd0,cause[{thread,csrno[11:10]}]};
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
`CSR_IM_STACK: dat <= im_stack[thread];
|
`CSR_IM_STACK: dat <= im_stack[thread];
|
`CSR_OL_STACK: dat <= {dl_stack[thread],ol_stack[thread]};
|
`CSR_OL_STACK: dat <= {16'h0,dl_stack[thread],16'h0,ol_stack[thread]};
|
`CSR_PL_STACK: dat <= pl_stack[thread];
|
`CSR_PL_STACK: dat <= pl_stack[thread];
|
`CSR_RS_STACK: dat <= rs_stack[thread];
|
`CSR_RS_STACK: dat <= rs_stack[thread];
|
`CSR_STATUS: dat <= mstatus[thread][63:0];
|
`CSR_STATUS: dat <= mstatus[thread][63:0];
|
`CSR_EPC0: dat <= epc0[thread];
|
`CSR_EPC0: dat <= epc0[thread];
|
`CSR_EPC1: dat <= epc1[thread];
|
`CSR_EPC1: dat <= epc1[thread];
|
Line 9966... |
Line 10085... |
`CSR_EPC5: dat <= epc5[thread];
|
`CSR_EPC5: dat <= epc5[thread];
|
`CSR_EPC6: dat <= epc6[thread];
|
`CSR_EPC6: dat <= epc6[thread];
|
`CSR_EPC7: dat <= epc7[thread];
|
`CSR_EPC7: dat <= epc7[thread];
|
`else
|
`else
|
`CSR_IM_STACK: dat <= im_stack;
|
`CSR_IM_STACK: dat <= im_stack;
|
`CSR_OL_STACK: dat <= {dl_stack,ol_stack};
|
`CSR_ODL_STACK: dat <= {16'h0,dl_stack,16'h0,ol_stack};
|
`CSR_PL_STACK: dat <= pl_stack;
|
`CSR_PL_STACK: dat <= pl_stack;
|
`CSR_RS_STACK: dat <= rs_stack;
|
`CSR_RS_STACK: dat <= rs_stack;
|
`CSR_STATUS: dat <= mstatus[63:0];
|
`CSR_STATUS: dat <= mstatus[63:0];
|
`CSR_EPC0: dat <= epc0;
|
`CSR_EPC0: dat <= epc0;
|
`CSR_EPC1: dat <= epc1;
|
`CSR_EPC1: dat <= epc1;
|
Line 10075... |
Line 10194... |
`endif
|
`endif
|
`CSR_CAS: cas <= dat;
|
`CSR_CAS: cas <= dat;
|
`CSR_TVEC: tvec[csrno[2:0]] <= dat[31:0];
|
`CSR_TVEC: tvec[csrno[2:0]] <= dat[31:0];
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
`CSR_IM_STACK: im_stack[thread] <= dat[31:0];
|
`CSR_IM_STACK: im_stack[thread] <= dat[31:0];
|
`CSR_OL_STACK: begin
|
`CSR_ODL_STACK: begin
|
ol_stack[thread] <= dat[15:0];
|
ol_stack[thread] <= dat[15:0];
|
dl_stack[thread] <= dat[31:16];
|
dl_stack[thread] <= dat[31:16];
|
end
|
end
|
`CSR_PL_STACK: pl_stack[thread] <= dat;
|
`CSR_PL_STACK: pl_stack[thread] <= dat;
|
`CSR_RS_STACK: rs_stack[thread] <= dat;
|
`CSR_RS_STACK: rs_stack[thread] <= dat;
|
Line 10092... |
Line 10211... |
`CSR_EPC5: epc5[thread] <= dat;
|
`CSR_EPC5: epc5[thread] <= dat;
|
`CSR_EPC6: epc6[thread] <= dat;
|
`CSR_EPC6: epc6[thread] <= dat;
|
`CSR_EPC7: epc7[thread] <= dat;
|
`CSR_EPC7: epc7[thread] <= dat;
|
`else
|
`else
|
`CSR_IM_STACK: im_stack <= dat[31:0];
|
`CSR_IM_STACK: im_stack <= dat[31:0];
|
`CSR_OL_STACK: begin
|
`CSR_ODL_STACK: begin
|
ol_stack <= dat[15:0];
|
ol_stack <= dat[15:0];
|
dl_stack <= dat[31:16];
|
dl_stack <= dat[47:32];
|
end
|
end
|
`CSR_PL_STACK: pl_stack <= dat;
|
`CSR_PL_STACK: pl_stack <= dat;
|
`CSR_RS_STACK: rs_stack <= dat;
|
`CSR_RS_STACK: rs_stack <= dat;
|
`CSR_STATUS: mstatus[63:0] <= dat;
|
`CSR_STATUS: mstatus[63:0] <= dat;
|
`CSR_EPC0: epc0 <= dat;
|
`CSR_EPC0: epc0 <= dat;
|