Line 1... |
Line 1... |
// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2017-2018 Robert Finch, Waterloo
|
// \\__/ o\ (C) 2017-2019 Robert Finch, Waterloo
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch<remove>@finitron.ca
|
// \/_// robfinch<remove>@finitron.ca
|
// ||
|
// ||
|
//
|
//
|
// FT64.v
|
// FT64.v
|
Line 40... |
Line 40... |
//
|
//
|
`include "FT64_config.vh"
|
`include "FT64_config.vh"
|
`include "FT64_defines.vh"
|
`include "FT64_defines.vh"
|
|
|
module FT64(hartid, rst, clk_i, clk4x, tm_clk_i, irq_i, vec_i, bte_o, cti_o, bok_i, cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_o, dat_i,
|
module FT64(hartid, rst, clk_i, clk4x, tm_clk_i, irq_i, vec_i, bte_o, cti_o, bok_i, cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_o, dat_i,
|
ol_o, pcr_o, pcr2_o, pkeys_o, icl_o, sr_o, cr_o, rbi_i, signal_i);
|
ol_o, pcr_o, pcr2_o, pkeys_o, icl_o, sr_o, cr_o, rbi_i, signal_i, exc_o);
|
input [63:0] hartid;
|
input [63:0] hartid;
|
input rst;
|
input rst;
|
input clk_i;
|
input clk_i;
|
input clk4x;
|
input clk4x;
|
input tm_clk_i;
|
input tm_clk_i;
|
Line 69... |
Line 69... |
output reg icl_o;
|
output reg 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" *)
|
|
output [7:0] exc_o;
|
|
|
parameter TM_CLKFREQ = 20000000;
|
parameter TM_CLKFREQ = 20000000;
|
parameter QENTRIES = `QENTRIES;
|
parameter QENTRIES = `QENTRIES;
|
parameter RSTPC = 64'hFFFFFFFFFFFC0100;
|
parameter RSTPC = 64'hFFFFFFFFFFFC0100;
|
parameter BRKPC = 64'hFFFFFFFFFFFC0000;
|
parameter BRKPC = 64'hFFFFFFFFFFFC0000;
|
Line 106... |
Line 108... |
// Memory access sizes
|
// Memory access sizes
|
parameter byt = 3'd0;
|
parameter byt = 3'd0;
|
parameter wyde = 3'd1;
|
parameter wyde = 3'd1;
|
parameter tetra = 3'd2;
|
parameter tetra = 3'd2;
|
parameter octa = 3'd3;
|
parameter octa = 3'd3;
|
|
parameter hexi = 3'd4;
|
// IQ states
|
// IQ states
|
parameter IQS_INVALID = 3'd0;
|
parameter IQS_INVALID = 3'd0;
|
parameter IQS_QUEUED = 3'd1;
|
parameter IQS_QUEUED = 3'd1;
|
parameter IQS_OUT = 3'd2;
|
parameter IQS_OUT = 3'd2;
|
parameter IQS_AGEN = 3'd3;
|
parameter IQS_AGEN = 3'd3;
|
Line 177... |
Line 180... |
wire [5:0] Rt0s = {Rt0[5:0]};
|
wire [5:0] Rt0s = {Rt0[5:0]};
|
wire [5:0] Rt1s = {Rt1[5:0]};
|
wire [5:0] Rt1s = {Rt1[5:0]};
|
*/
|
*/
|
`endif
|
`endif
|
|
|
`ifdef SUPPORT_PREDICATION
|
|
reg [3:0] pregs [0:1023];
|
|
`endif
|
|
|
|
reg [63:0] wbrcd;
|
reg [63:0] wbrcd;
|
wire [5:0] brgs;
|
wire [5:0] brgs;
|
`ifdef SUPPORT_SEGMENTATION
|
|
reg [23:0] currentCSSelector;
|
|
reg [63:0] zs_base [0:63];
|
|
reg [63:0] ds_base [0:63];
|
|
reg [63:0] es_base [0:63];
|
|
reg [63:0] fs_base [0:63];
|
|
reg [63:0] gs_base [0:63];
|
|
reg [63:0] hs_base [0:63];
|
|
reg [63:0] ss_base [0:63];
|
|
reg [63:0] cs_base [0:63];
|
|
reg [63:0] zsx_base;
|
|
reg [63:0] dsx_base;
|
|
reg [63:0] esx_base;
|
|
reg [63:0] fsx_base;
|
|
reg [63:0] gsx_base;
|
|
reg [63:0] hsx_base;
|
|
reg [63:0] ssx_base;
|
|
reg [63:0] csx_base;
|
|
reg [63:0] zs_lb [0:63];
|
|
reg [63:0] ds_lb [0:63];
|
|
reg [63:0] es_lb [0:63];
|
|
reg [63:0] fs_lb [0:63];
|
|
reg [63:0] gs_lb [0:63];
|
|
reg [63:0] hs_lb [0:63];
|
|
reg [63:0] ss_lb [0:63];
|
|
reg [63:0] cs_lb [0:63];
|
|
reg [63:0] zslb;
|
|
reg [63:0] dslb;
|
|
reg [63:0] eslb;
|
|
reg [63:0] fslb;
|
|
reg [63:0] gslb;
|
|
reg [63:0] hslb;
|
|
reg [63:0] sslb;
|
|
reg [63:0] cslb;
|
|
reg [63:0] zs_ub [0:63];
|
|
reg [63:0] ds_ub [0:63];
|
|
reg [63:0] es_ub [0:63];
|
|
reg [63:0] fs_ub [0:63];
|
|
reg [63:0] gs_ub [0:63];
|
|
reg [63:0] hs_ub [0:63];
|
|
reg [63:0] ss_ub [0:63];
|
|
reg [63:0] cs_ub [0:63];
|
|
reg [63:0] zsub;
|
|
reg [63:0] dsub;
|
|
reg [63:0] esub;
|
|
reg [63:0] fsub;
|
|
reg [63:0] gsub;
|
|
reg [63:0] hsub;
|
|
reg [63:0] ssub;
|
|
reg [63:0] csub;
|
|
reg [23:0] zs_sel [0:63];
|
|
reg [23:0] ds_sel [0:63];
|
|
reg [23:0] es_sel [0:63];
|
|
reg [23:0] fs_sel [0:63];
|
|
reg [23:0] gs_sel [0:63];
|
|
reg [23:0] hs_sel [0:63];
|
|
reg [23:0] ss_sel [0:63];
|
|
reg [23:0] cs_sel [0:63];
|
|
reg [15:0] zs_acr [0:63];
|
|
reg [15:0] ds_acr [0:63];
|
|
reg [15:0] es_acr [0:63];
|
|
reg [15:0] fs_acr [0:63];
|
|
reg [15:0] gs_acr [0:63];
|
|
reg [15:0] hs_acr [0:63];
|
|
reg [15:0] ss_acr [0:63];
|
|
reg [15:0] cs_acr [0:63];
|
|
initial begin
|
|
for (n = 0; n < 64; n = n + 1) begin
|
|
zs_base[n] <= 64'h0;
|
|
ds_base[n] <= 64'h0;
|
|
es_base[n] <= 64'h0;
|
|
fs_base[n] <= 64'h0;
|
|
gs_base[n] <= 64'h0;
|
|
hs_base[n] <= 64'h0;
|
|
ss_base[n] <= 64'h0;
|
|
cs_base[n] <= 64'h0;
|
|
zs_lb[n] <= 64'h0;
|
|
ds_lb[n] <= 64'h0;
|
|
es_lb[n] <= 64'h0;
|
|
fs_lb[n] <= 64'h0;
|
|
gs_lb[n] <= 64'h0;
|
|
hs_lb[n] <= 64'h0;
|
|
ss_lb[n] <= 64'h0;
|
|
cs_lb[n] <= 64'h0;
|
|
zs_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
ds_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
es_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
fs_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
gs_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
hs_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
ss_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
cs_ub[n] <= 64'hFFFFFFFFFFFFFFFF;
|
|
zs_sel[n] <= 24'h0;
|
|
ds_sel[n] <= 24'h0;
|
|
es_sel[n] <= 24'h0;
|
|
fs_sel[n] <= 24'h0;
|
|
gs_sel[n] <= 24'h0;
|
|
hs_sel[n] <= 24'h0;
|
|
ss_sel[n] <= 24'h0;
|
|
cs_sel[n] <= 24'h0;
|
|
zs_acr[n] <= 16'h8000;
|
|
ds_acr[n] <= 16'h9200;
|
|
es_acr[n] <= 16'h8000;
|
|
fs_acr[n] <= 16'h8000;
|
|
gs_acr[n] <= 16'h8000;
|
|
hs_acr[n] <= 16'h8000;
|
|
ss_acr[n] <= 16'h9600;
|
|
cs_acr[n] <= 16'h9A00;
|
|
end
|
|
end
|
|
always @(posedge clk_i)
|
|
begin
|
|
zsx_base <= zs_base[brgs];
|
|
dsx_base <= ds_base[brgs];
|
|
esx_base <= es_base[brgs];
|
|
fsx_base <= fs_base[brgs];
|
|
gsx_base <= gs_base[brgs];
|
|
hsx_base <= hs_base[brgs];
|
|
ssx_base <= ss_base[brgs];
|
|
csx_base <= cs_base[brgs];
|
|
zsub <= zs_ub[brgs];
|
|
dsub <= ds_ub[brgs];
|
|
esub <= es_ub[brgs];
|
|
fsub <= fs_ub[brgs];
|
|
gsub <= gs_ub[brgs];
|
|
hsub <= hs_ub[brgs];
|
|
ssub <= ss_ub[brgs];
|
|
csub <= cs_ub[brgs];
|
|
zslb <= zs_lb[brgs];
|
|
dslb <= ds_lb[brgs];
|
|
eslb <= es_lb[brgs];
|
|
fslb <= fs_lb[brgs];
|
|
gslb <= gs_lb[brgs];
|
|
hslb <= hs_lb[brgs];
|
|
sslb <= ss_lb[brgs];
|
|
cslb <= cs_lb[brgs];
|
|
currentCSSelector <= cs_sel[brgs];
|
|
end
|
|
`endif
|
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
reg [15:0] thrd_handle [0:63];
|
reg [15:0] thrd_handle [0:63];
|
reg [63:0] prg_base [0:63];
|
reg [63:0] prg_base [0:63];
|
reg [63:0] prg_limit [0:63];
|
reg [63:0] prg_limit [0:63];
|
reg [63:0] en_barrier [0:63]; // environment bound
|
reg [63:0] en_barrier [0:63]; // environment bound
|
Line 422... |
Line 282... |
prf_source[n] <= 1'b0;
|
prf_source[n] <= 1'b0;
|
end
|
end
|
wire [`ABITS] pc0a;
|
wire [`ABITS] pc0a;
|
wire [`ABITS] pc1a;
|
wire [`ABITS] pc1a;
|
wire [`ABITS] pc2a;
|
wire [`ABITS] pc2a;
|
`ifdef SUPPORT_SEGMENTATION
|
|
wire [`ABITS] pc0 = (pc0a[47:40]==8'hFF||ol==2'b00) ? pc0a : {csx_base[50:0],13'd0} + pc0a[47:0];
|
|
wire [`ABITS] pc1 = (pc1a[47:40]==8'hFF||ol==2'b00) ? pc1a : {csx_base[50:0],13'd0} + pc1a[47:0];
|
|
wire [`ABITS] pc2 = (pc2a[47:40]==8'hFF||ol==2'b00) ? pc2a : {csx_base[50:0],13'd0} + pc2a[47:0];
|
|
`else
|
|
`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==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==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'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
|
`endif
|
|
|
|
reg excmiss;
|
reg excmiss;
|
reg [`ABITS] excmisspc;
|
reg [`ABITS] excmisspc;
|
reg excthrd;
|
reg excthrd;
|
reg exception_set;
|
reg exception_set;
|
Line 462... |
Line 316... |
wire dce = cr0[30]; // data cache enable
|
wire dce = cr0[30]; // data cache enable
|
wire bpe = cr0[32]; // branch predictor enable
|
wire bpe = cr0[32]; // branch predictor enable
|
wire wbm = cr0[34];
|
wire wbm = cr0[34];
|
wire sple = cr0[35]; // speculative load enable
|
wire sple = cr0[35]; // speculative load enable
|
wire ctgtxe = cr0[33];
|
wire ctgtxe = cr0[33];
|
`ifdef SUPPORT_PREDICATION
|
|
wire pred_on = cr0[36]; // predicated execution mode on
|
|
`else
|
|
wire pred_on = 1'b0;
|
wire pred_on = 1'b0;
|
`endif
|
|
reg [63:0] pmr;
|
reg [63:0] pmr;
|
wire id1_available = pmr[0];
|
wire id1_available = pmr[0];
|
wire id2_available = pmr[1];
|
wire id2_available = pmr[1];
|
wire id3_available = pmr[2];
|
wire id3_available = pmr[2];
|
wire alu0_available = pmr[8];
|
wire alu0_available = pmr[8];
|
Line 487... |
Line 337... |
wire thread_en = cr0[16];
|
wire thread_en = cr0[16];
|
`else
|
`else
|
wire thread_en = 1'b0;
|
wire thread_en = 1'b0;
|
`endif
|
`endif
|
wire vechain = cr0[18];
|
wire vechain = cr0[18];
|
|
// Performance CSR's
|
reg [39:0] iq_ctr;
|
reg [39:0] iq_ctr;
|
reg [39:0] irq_ctr; // count of number of interrupts
|
reg [39:0] irq_ctr; // count of number of interrupts
|
reg [39:0] bm_ctr; // branch miss counter
|
reg [39:0] bm_ctr; // branch miss counter
|
|
reg [39:0] br_ctr; // branch counter
|
reg [39:0] icl_ctr; // instruction cache load counter
|
reg [39:0] icl_ctr; // instruction cache load counter
|
|
|
reg [7:0] fcu_timeout;
|
reg [7:0] fcu_timeout;
|
reg [63:0] tick;
|
reg [63:0] tick;
|
reg [63:0] wc_time;
|
reg [63:0] wc_time;
|
reg [31:0] pcr;
|
reg [31:0] pcr;
|
reg [63:0] pcr2;
|
reg [63:0] pcr2;
|
assign pcr_o = pcr;
|
assign pcr_o = pcr;
|
assign pcr2_o = pcr2;
|
assign pcr2_o = pcr2;
|
reg [63:0] aec;
|
reg [63:0] aec;
|
|
(* mark_debug = "true" *)
|
reg [15:0] cause[0:15];
|
reg [15:0] cause[0:15];
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
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];
|
Line 677... |
Line 530... |
reg [55:0] insn1a, insn2a;
|
reg [55:0] insn1a, insn2a;
|
// Only need enough bits in the seqnence number to cover the instructions in
|
// Only need enough bits in the seqnence number to cover the instructions in
|
// the queue plus an extra count for skipping on branch misses. In this case
|
// the queue plus an extra count for skipping on branch misses. In this case
|
// that would be four bits minimum (count 0 to 8).
|
// that would be four bits minimum (count 0 to 8).
|
wire [63:0] rdat0,rdat1,rdat2;
|
wire [63:0] rdat0,rdat1,rdat2;
|
reg [63:0] xdati;
|
reg [127:0] xdati;
|
|
|
reg canq1, canq2, canq3;
|
reg canq1, canq2, canq3;
|
(* mark_debug = "true" *)
|
(* mark_debug = "true" *)
|
reg queued1;
|
reg queued1;
|
reg queued2;
|
reg queued2;
|
Line 714... |
Line 567... |
reg [QENTRIES-1:0] iqentry_fc; // flow control instruction
|
reg [QENTRIES-1:0] iqentry_fc; // flow control instruction
|
reg [QENTRIES-1:0] iqentry_canex = 8'h00; // true if it's an instruction that can exception
|
reg [QENTRIES-1:0] iqentry_canex = 8'h00; // true if it's an instruction that can exception
|
reg [QENTRIES-1:0] iqentry_oddball = 8'h00; // writes to register file
|
reg [QENTRIES-1:0] iqentry_oddball = 8'h00; // writes to register file
|
reg [QENTRIES-1:0] iqentry_load; // is a memory load instruction
|
reg [QENTRIES-1:0] iqentry_load; // is a memory load instruction
|
reg [QENTRIES-1:0] iqentry_loadv; // is a volatile memory load instruction
|
reg [QENTRIES-1:0] iqentry_loadv; // is a volatile memory load instruction
|
|
reg [QENTRIES-1:0] iqentry_loadseg;
|
reg [QENTRIES-1:0] iqentry_store; // is a memory store instruction
|
reg [QENTRIES-1:0] iqentry_store; // is a memory store instruction
|
reg [QENTRIES-1:0] iqentry_preload; // is a memory preload instruction
|
reg [QENTRIES-1:0] iqentry_preload; // is a memory preload instruction
|
reg [QENTRIES-1:0] iqentry_ldcmp;
|
reg [QENTRIES-1:0] iqentry_ldcmp;
|
reg [QENTRIES-1:0] iqentry_mem; // touches memory: 1 if LW/SW
|
reg [QENTRIES-1:0] iqentry_mem; // touches memory: 1 if LW/SW
|
reg [QENTRIES-1:0] iqentry_memndx; // indexed memory operation
|
reg [QENTRIES-1:0] iqentry_memndx; // indexed memory operation
|
Line 743... |
Line 597... |
reg [QENTRIES-1:0] iqentry_cmp;
|
reg [QENTRIES-1:0] iqentry_cmp;
|
reg [QENTRIES-1:0] iqentry_rfw = 1'b0; // writes to register file
|
reg [QENTRIES-1:0] iqentry_rfw = 1'b0; // writes to register file
|
reg [QENTRIES-1:0] iqentry_prfw = 1'b0;
|
reg [QENTRIES-1:0] iqentry_prfw = 1'b0;
|
reg [7:0] iqentry_we [0:QENTRIES-1]; // enable strobe
|
reg [7:0] iqentry_we [0:QENTRIES-1]; // enable strobe
|
reg [63:0] iqentry_res [0:QENTRIES-1]; // instruction result
|
reg [63:0] iqentry_res [0:QENTRIES-1]; // instruction result
|
|
reg [63:0] iqentry_seg_base [0:QENTRIES-1]; //
|
|
reg [63:0] iqentry_seg_lb [0:QENTRIES-1]; //
|
|
reg [63:0] iqentry_seg_ub [0:QENTRIES-1]; //
|
|
reg [63:0] iqentry_seg_acr [0:QENTRIES-1]; //
|
reg [63:0] iqentry_ares [0:QENTRIES-1]; // alternate instruction result
|
reg [63:0] iqentry_ares [0:QENTRIES-1]; // alternate instruction result
|
reg [47:0] iqentry_instr[0:QENTRIES-1]; // instruction opcode
|
reg [47:0] iqentry_instr[0:QENTRIES-1]; // instruction opcode
|
reg [2:0] iqentry_insln[0:QENTRIES-1]; // instruction length
|
reg [2:0] iqentry_insln[0:QENTRIES-1]; // instruction length
|
reg [7:0] iqentry_exc [0:QENTRIES-1]; // only for branches ... indicates a HALT instruction
|
reg [7:0] iqentry_exc [0:QENTRIES-1]; // only for branches ... indicates a HALT instruction
|
reg [RBIT:0] iqentry_tgt[0:QENTRIES-1]; // Rt field or ZERO -- this is the instruction's target (if any)
|
reg [RBIT:0] iqentry_tgt[0:QENTRIES-1]; // Rt field or ZERO -- this is the instruction's target (if any)
|
Line 801... |
Line 659... |
|
|
reg [PREGS-1:1] livetarget;
|
reg [PREGS-1:1] livetarget;
|
reg [PREGS-1:1] iqentry_livetarget [0:QENTRIES-1];
|
reg [PREGS-1:1] iqentry_livetarget [0:QENTRIES-1];
|
reg [PREGS-1:1] iqentry_latestID [0:QENTRIES-1];
|
reg [PREGS-1:1] iqentry_latestID [0:QENTRIES-1];
|
reg [PREGS-1:1] iqentry_cumulative [0:QENTRIES-1];
|
reg [PREGS-1:1] iqentry_cumulative [0:QENTRIES-1];
|
`ifdef SUPPORT_PREDICATION
|
|
reg [QENTRIES-1:0] iqentry_psource = {QENTRIES{1'b0}};
|
|
reg [15:0] plivetarget;
|
|
reg [15:0] iqentry_plivetarget [0:QENTRIES-1];
|
|
reg [15:0] iqentry_platestID [0:QENTRIES-1];
|
|
reg [15:0] iqentry_pcumulative [0:QENTRIES-1];
|
|
`endif
|
|
wire [PREGS-1:1] iq_out [0:QENTRIES-1];
|
wire [PREGS-1:1] iq_out [0:QENTRIES-1];
|
|
|
reg [`QBITS] tail0;
|
reg [`QBITS] tail0;
|
reg [`QBITS] tail1;
|
reg [`QBITS] tail1;
|
reg [`QBITS] tail2;
|
reg [`QBITS] tail2;
|
Line 850... |
Line 701... |
wire [`ABITS] fetchbuf2_pc;
|
wire [`ABITS] fetchbuf2_pc;
|
wire fetchbuf2_v;
|
wire fetchbuf2_v;
|
wire fetchbuf2_thrd;
|
wire fetchbuf2_thrd;
|
wire fetchbuf2_mem;
|
wire fetchbuf2_mem;
|
wire fetchbuf2_rfw;
|
wire fetchbuf2_rfw;
|
`ifdef SUPPORT_PREDICATION
|
|
wire fetchbuf0_prfw;
|
|
wire [7:0] fetchbuf0_pbyte;
|
|
wire fetchbuf1_prfw;
|
|
wire [7:0] fetchbuf1_pbyte;
|
|
wire fetchbuf2_prfw;
|
|
wire [7:0] fetchbuf2_pbyte;
|
|
`endif
|
|
wire [47:0] fetchbufA_instr;
|
wire [47:0] fetchbufA_instr;
|
wire [`ABITS] fetchbufA_pc;
|
wire [`ABITS] fetchbufA_pc;
|
wire fetchbufA_v;
|
wire fetchbufA_v;
|
wire [47:0] fetchbufB_instr;
|
wire [47:0] fetchbufB_instr;
|
wire [`ABITS] fetchbufB_pc;
|
wire [`ABITS] fetchbufB_pc;
|
Line 1052... |
Line 895... |
reg [63:0] fcu_argB;
|
reg [63:0] fcu_argB;
|
reg [63:0] fcu_argC;
|
reg [63:0] fcu_argC;
|
reg [63:0] fcu_argI; // only used by BEQ
|
reg [63:0] fcu_argI; // only used by BEQ
|
reg [63:0] fcu_argT;
|
reg [63:0] fcu_argT;
|
reg [63:0] fcu_argT2;
|
reg [63:0] fcu_argT2;
|
|
reg [63:0] fcu_epc;
|
|
reg [23:0] fcu_ecs; // excepted code segment
|
|
reg [23:0] fcu_rs; // return selector
|
reg [`ABITS] fcu_pc;
|
reg [`ABITS] fcu_pc;
|
reg [`ABITS] fcu_nextpc;
|
reg [`ABITS] fcu_nextpc;
|
reg [`ABITS] fcu_brdisp;
|
reg [`ABITS] fcu_brdisp;
|
wire [63:0] fcu_out;
|
wire [63:0] fcu_out;
|
reg [63:0] fcu_bus;
|
reg [63:0] fcu_bus;
|
Line 1105... |
Line 951... |
reg [47:0] dram0_instr;
|
reg [47:0] dram0_instr;
|
reg dram0_rmw;
|
reg dram0_rmw;
|
reg dram0_preload;
|
reg dram0_preload;
|
reg [RBIT:0] dram0_tgt;
|
reg [RBIT:0] dram0_tgt;
|
reg [`QBITSP1] dram0_id;
|
reg [`QBITSP1] dram0_id;
|
reg [`XBITS] dram0_exc;
|
|
reg dram0_unc;
|
reg dram0_unc;
|
reg [2:0] dram0_memsize;
|
reg [2:0] dram0_memsize;
|
reg dram0_load; // is a load operation
|
reg dram0_load; // is a load operation
|
|
reg dram0_loadseg;
|
reg dram0_store;
|
reg dram0_store;
|
reg [1:0] dram0_ol;
|
reg [1:0] dram0_ol;
|
reg [63:0] dram1_data;
|
reg [63:0] dram1_data;
|
reg [`ABITS] dram1_addr;
|
reg [`ABITS] dram1_addr;
|
reg [47:0] dram1_instr;
|
reg [47:0] dram1_instr;
|
reg dram1_rmw;
|
reg dram1_rmw;
|
reg dram1_preload;
|
reg dram1_preload;
|
reg [RBIT:0] dram1_tgt;
|
reg [RBIT:0] dram1_tgt;
|
reg [`QBITSP1] dram1_id;
|
reg [`QBITSP1] dram1_id;
|
reg [`XBITS] dram1_exc;
|
|
reg dram1_unc;
|
reg dram1_unc;
|
reg [2:0] dram1_memsize;
|
reg [2:0] dram1_memsize;
|
reg dram1_load;
|
reg dram1_load;
|
|
reg dram1_loadseg;
|
reg dram1_store;
|
reg dram1_store;
|
reg [1:0] dram1_ol;
|
reg [1:0] dram1_ol;
|
reg [63:0] dram2_data;
|
reg [63:0] dram2_data;
|
reg [`ABITS] dram2_addr;
|
reg [`ABITS] dram2_addr;
|
reg [47:0] dram2_instr;
|
reg [47:0] dram2_instr;
|
reg dram2_rmw;
|
reg dram2_rmw;
|
reg dram2_preload;
|
reg dram2_preload;
|
reg [RBIT:0] dram2_tgt;
|
reg [RBIT:0] dram2_tgt;
|
reg [`QBITSP1] dram2_id;
|
reg [`QBITSP1] dram2_id;
|
reg [`XBITS] dram2_exc;
|
|
reg dram2_unc;
|
reg dram2_unc;
|
reg [2:0] dram2_memsize;
|
reg [2:0] dram2_memsize;
|
reg dram2_load;
|
reg dram2_load;
|
|
reg dram2_loadseg;
|
reg dram2_store;
|
reg dram2_store;
|
reg [1:0] dram2_ol;
|
reg [1:0] dram2_ol;
|
|
|
reg dramA_v;
|
reg dramA_v;
|
reg [`QBITSP1] dramA_id;
|
reg [`QBITSP1] dramA_id;
|
reg [63:0] dramA_bus;
|
reg [63:0] dramA_bus;
|
reg [`XBITS] dramA_exc;
|
|
reg dramB_v;
|
reg dramB_v;
|
reg [`QBITSP1] dramB_id;
|
reg [`QBITSP1] dramB_id;
|
reg [63:0] dramB_bus;
|
reg [63:0] dramB_bus;
|
reg [`XBITS] dramB_exc;
|
|
reg dramC_v;
|
reg dramC_v;
|
reg [`QBITSP1] dramC_id;
|
reg [`QBITSP1] dramC_id;
|
reg [63:0] dramC_bus;
|
reg [63:0] dramC_bus;
|
reg [`XBITS] dramC_exc;
|
|
|
|
wire outstanding_stores;
|
wire outstanding_stores;
|
reg [63:0] I; // instruction count
|
reg [63:0] I; // instruction count
|
reg [63:0] CC; // commit count
|
reg [63:0] CC; // commit count
|
|
|
Line 1192... |
Line 1035... |
parameter B14 = 5'd14;
|
parameter B14 = 5'd14;
|
parameter B15 = 5'd15;
|
parameter B15 = 5'd15;
|
parameter B16 = 5'd16;
|
parameter B16 = 5'd16;
|
parameter B17 = 5'd17;
|
parameter B17 = 5'd17;
|
parameter B18 = 5'd18;
|
parameter B18 = 5'd18;
|
parameter B19 = 5'd19;
|
parameter B_LSNAck = 5'd19;
|
parameter B2a = 5'd20;
|
parameter B2a = 5'd20;
|
parameter B2b = 5'd21;
|
parameter B2b = 5'd21;
|
parameter B2c = 5'd22;
|
parameter B2c = 5'd22;
|
parameter B_DCacheLoadAck = 5'd23;
|
parameter B_DCacheLoadAck = 5'd23;
|
parameter B20 = 5'd24;
|
parameter B20 = 5'd24;
|
parameter B21 = 5'd25;
|
parameter B21 = 5'd25;
|
parameter B_DCacheLoadWait3 = 5'd26;
|
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_CHK = 2'd1;
|
|
parameter SEG_UPD = 2'd2;
|
|
parameter SEG_DONE = 2'd3;
|
reg [1:0] bwhich;
|
reg [1:0] bwhich;
|
reg [3:0] icstate,picstate;
|
reg [3:0] icstate,picstate;
|
parameter IDLE = 4'd0;
|
parameter IDLE = 4'd0;
|
parameter IC1 = 4'd1;
|
parameter IC1 = 4'd1;
|
parameter IC2 = 4'd2;
|
parameter IC2 = 4'd2;
|
Line 1224... |
Line 1075... |
reg phit;
|
reg phit;
|
wire threadx;
|
wire threadx;
|
always @*
|
always @*
|
phit <= ihit&&icstate==IDLE;
|
phit <= ihit&&icstate==IDLE;
|
reg [2:0] iccnt;
|
reg [2:0] iccnt;
|
|
(* mark_debug="true" *)
|
|
reg icack;
|
reg L1_wr0,L1_wr1,L1_wr2;
|
reg L1_wr0,L1_wr1,L1_wr2;
|
reg L1_invline;
|
reg L1_invline;
|
wire [1:0] ic0_fault,ic1_fault,ic2_fault;
|
wire [1:0] ic0_fault,ic1_fault,ic2_fault;
|
reg [8:0] L1_en;
|
reg [9:0] L1_en;
|
reg [71:0] L1_adr, L2_adr;
|
reg [71:0] L1_adr, L2_adr;
|
reg [297:0] L2_rdat;
|
reg [305:0] L1_dati;
|
wire [297:0] L2_dato;
|
wire [305:0] L2_dato;
|
reg L2_xsel;
|
reg L2_xsel;
|
|
|
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 1369... |
Line 1222... |
.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((icstate==IDLE||icstate==IC_Next) ? {pcr[7:0],pc0} : L1_adr),
|
.wadr(L1_adr),
|
.wadr(L1_adr),
|
.i(L2_rdat),
|
.i(L1_dati),
|
.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 1388... |
Line 1241... |
.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((icstate==IDLE||icstate==IC_Next) ? (thread_en ? {pcr[7:0],pc1}: {pcr[7:0],pc0plus6} ): L1_adr),
|
.wadr(L1_adr),
|
.wadr(L1_adr),
|
.i(L2_rdat),
|
.i(L1_dati),
|
.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 1410... |
Line 1263... |
.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((icstate==IDLE||icstate==IC_Next) ? (thread_en ? {pcr[7:0],pc2} : {pcr[7:0],pc0plus12}) : L1_adr),
|
.wadr(L1_adr),
|
.wadr(L1_adr),
|
.i(L2_rdat),
|
.i(L1_dati),
|
.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 1993... |
Line 1846... |
// If a hardware interrupt instruction is encountered in the instruction stream
|
// If a hardware interrupt instruction is encountered in the instruction stream
|
// flag it as a privilege violation.
|
// flag it as a privilege violation.
|
wire freezePC = (irq_i > im) && !int_commit;
|
wire freezePC = (irq_i > im) && !int_commit;
|
always @*
|
always @*
|
if (freezePC) begin
|
if (freezePC) begin
|
insn0 <= {8'h00,6'd0,5'd0,irq_i,1'b0,vec_i,2'b00,`BRK};
|
insn0 <= {32'h00,6'd0,5'd0,irq_i,1'b0,vec_i,2'b00,`BRK};
|
end
|
end
|
else if (phit) begin
|
else if (phit) begin
|
// if (insn0a[`INSTRUCTION_OP]==`BRK && insn0a[25:21]==5'd0 && insn0a[`INSTRUCTION_L2]==2'b00)
|
// if (insn0a[`INSTRUCTION_OP]==`BRK && insn0a[25:21]==5'd0 && insn0a[`INSTRUCTION_L2]==2'b00)
|
// insn0 <= {6'd1,5'd0,4'b0,1'b0,`FLT_PRIV,2'b00,`BRK};
|
// insn0 <= {6'd1,5'd0,4'b0,1'b0,`FLT_PRIV,2'b00,`BRK};
|
// else
|
// else
|
insn0 <= insn0a;
|
insn0 <= insn0a;
|
|
if (insn0a[15:0]==16'hFF00) begin // BRK #255
|
|
if (~|irq_i)
|
|
insn0 <= {8'h00,`NOP_INSN};
|
|
else
|
|
insn0[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
|
end
|
|
else if (ic0_fault[1])
|
|
insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
|
else if (ic0_fault[0])
|
|
insn0 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
end
|
end
|
else begin
|
else begin
|
insn0 <= {8'h00,`NOP_INSN};
|
insn0 <= {8'h00,`NOP_INSN};
|
end
|
end
|
|
|
generate begin : gInsnMux
|
generate begin : gInsnMux
|
if (`WAYS > 1) begin
|
if (`WAYS > 1) begin
|
always @*
|
always @*
|
if (freezePC && !thread_en) begin
|
if (freezePC && !thread_en) begin
|
insn1 <= {8'h00,6'd0,5'd0,irq_i,1'b0,vec_i,2'b00,`BRK};
|
insn1 <= {8'h00,6'd0,5'd0,irq_i,1'b0,vec_i,2'b00,`BRK};
|
Line 2015... |
Line 1879... |
else if (phit) begin
|
else if (phit) begin
|
// if (insn1a[`INSTRUCTION_OP]==`BRK && insn1a[25:21]==5'd0 && insn1a[`INSTRUCTION_L2]==2'b00)
|
// if (insn1a[`INSTRUCTION_OP]==`BRK && insn1a[25:21]==5'd0 && insn1a[`INSTRUCTION_L2]==2'b00)
|
// insn1 <= {6'd1,5'd0,4'b0,1'b0,`FLT_PRIV,2'b00,`BRK};
|
// insn1 <= {6'd1,5'd0,4'b0,1'b0,`FLT_PRIV,2'b00,`BRK};
|
// else
|
// else
|
insn1 <= insn1a;
|
insn1 <= insn1a;
|
|
if (insn1a[15:0]==16'hFF00) begin
|
|
if (~|irq_i)
|
|
insn1 <= {8'h00,`NOP_INSN};
|
|
else
|
|
insn1[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
|
end
|
|
else if (ic1_fault[1])
|
|
insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
|
else if (ic1_fault[0])
|
|
insn1 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
end
|
end
|
else begin
|
else begin
|
insn1 <= {8'h00,`NOP_INSN};
|
insn1 <= {8'h00,`NOP_INSN};
|
end
|
end
|
end
|
end
|
Line 2029... |
Line 1903... |
else if (phit) begin
|
else if (phit) begin
|
// if (insn2a[`INSTRUCTION_OP]==`BRK && insn1a[25:21]==5'd0 && insn2a[`INSTRUCTION_L2]==2'b00)
|
// if (insn2a[`INSTRUCTION_OP]==`BRK && insn1a[25:21]==5'd0 && insn2a[`INSTRUCTION_L2]==2'b00)
|
// insn2 <= {6'd1,5'd0,4'b0,1'b0,`FLT_PRIV,2'b00,`BRK};
|
// insn2 <= {6'd1,5'd0,4'b0,1'b0,`FLT_PRIV,2'b00,`BRK};
|
// else
|
// else
|
insn2 <= insn2a;
|
insn2 <= insn2a;
|
|
if (insn2a[15:0]==16'hFF00) begin
|
|
if (~|irq_i)
|
|
insn2 <= {8'h00,`NOP_INSN};
|
|
else
|
|
insn2[20:0] <= {irq_i,1'b0,vec_i,2'b00,`BRK};
|
|
end
|
|
else if (ic2_fault[1])
|
|
insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_IBE,2'b00,`BRK};
|
|
else if (ic2_fault[0])
|
|
insn2 <= {32'h00,6'd0,5'd0,4'h0,1'b0,`FLT_EXF,2'b00,`BRK};
|
end
|
end
|
else
|
else
|
insn2 <= `NOP_INSN;
|
insn2 <= `NOP_INSN;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
wire [63:0] dc0_out, dc1_out, dc2_out;
|
wire [63:0] dc0_out, dc1_out, dc2_out;
|
assign rdat0 = dram0_unc ? xdati : dc0_out;
|
assign rdat0 = dram0_unc ? xdati[63:0] : dc0_out;
|
assign rdat1 = dram1_unc ? xdati : dc1_out;
|
assign rdat1 = dram1_unc ? xdati[63:0] : dc1_out;
|
assign rdat2 = dram2_unc ? xdati : dc2_out;
|
assign rdat2 = dram2_unc ? xdati[63:0] : dc2_out;
|
|
|
reg preload;
|
reg preload;
|
reg [1:0] dccnt;
|
reg [1:0] dccnt;
|
wire dhit0, dhit1, dhit2;
|
wire dhit0, dhit1, dhit2;
|
wire dhit0a, dhit1a, dhit2a;
|
wire dhit0a, dhit1a, dhit2a;
|
Line 2074... |
Line 1958... |
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==B19 && isStore)) && whit0);
|
wire wr_dcache0 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit0);
|
wire wr_dcache1 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B19 && isStore)) && whit1);
|
wire wr_dcache1 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit1);
|
wire wr_dcache2 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B19 && isStore)) && whit2);
|
wire wr_dcache2 = (bstate==B_DCacheLoadAck && ack_i)||(((bstate==B_StoreAck && StoreAck1) || (bstate==B_LSNAck && isStore)) && whit2);
|
|
|
FT64_dcache udc0
|
FT64_dcache udc0
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.wclk(clk),
|
.wclk(clk),
|
Line 2333... |
Line 2217... |
default: fnRt = {fp_rgs[thrd],1'b0,isn[`INSTRUCTION_RT]};
|
default: fnRt = {fp_rgs[thrd],1'b0,isn[`INSTRUCTION_RT]};
|
endcase
|
endcase
|
`BRK: fnRt = 12'd0;
|
`BRK: fnRt = 12'd0;
|
`REX: fnRt = 12'd0;
|
`REX: fnRt = 12'd0;
|
`CHK: fnRt = 12'd0;
|
`CHK: fnRt = 12'd0;
|
`EXEC: fnRt = 12'd0;
|
//`EXEC: fnRt = 12'd0;
|
`Bcc: fnRt = 12'd0;
|
`Bcc: fnRt = 12'd0;
|
|
`BLcc: fnRt = 12'd0;
|
`BBc: fnRt = 12'd0;
|
`BBc: fnRt = 12'd0;
|
`NOP: fnRt = 12'd0;
|
`NOP: fnRt = 12'd0;
|
`BEQI: fnRt = 12'd0;
|
`BEQI: fnRt = 12'd0;
|
|
`BNEI: fnRt = 12'd0;
|
`SB,`Sx,`SWC,`CACHE:
|
`SB,`Sx,`SWC,`CACHE:
|
fnRt = 12'd0;
|
fnRt = 12'd0;
|
`JMP: fnRt = 12'd0;
|
`JMP: fnRt = 12'd0;
|
`CALL: fnRt = {rgs[thrd],1'b0,5'd29}; // regLR
|
`CALL: fnRt = {rgs[thrd],1'b0,5'd29}; // regLR
|
`LV: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RT]};
|
`LV: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RT]};
|
Line 2565... |
Line 2451... |
default: fnRt = {fp_rgs,1'b0,isn[`INSTRUCTION_RT]};
|
default: fnRt = {fp_rgs,1'b0,isn[`INSTRUCTION_RT]};
|
endcase
|
endcase
|
`BRK: fnRt = 12'd0;
|
`BRK: fnRt = 12'd0;
|
`REX: fnRt = 12'd0;
|
`REX: fnRt = 12'd0;
|
`CHK: fnRt = 12'd0;
|
`CHK: fnRt = 12'd0;
|
`EXEC: fnRt = 12'd0;
|
//`EXEC: fnRt = 12'd0;
|
`Bcc: fnRt = 12'd0;
|
`Bcc: fnRt = 12'd0;
|
|
`BLcc: fnRt = 12'd0;
|
`BBc: fnRt = 12'd0;
|
`BBc: fnRt = 12'd0;
|
`NOP: fnRt = 12'd0;
|
`NOP: fnRt = 12'd0;
|
`BEQI: fnRt = 12'd0;
|
`BEQI: fnRt = 12'd0;
|
|
`BNEI: fnRt = 12'd0;
|
`SB,`Sx,`SWC,`CACHE:
|
`SB,`Sx,`SWC,`CACHE:
|
fnRt = 12'd0;
|
fnRt = 12'd0;
|
`JMP: fnRt = 12'd0;
|
`JMP: fnRt = 12'd0;
|
`CALL: fnRt = {rgs,1'b0,5'd29}; // regLR
|
`CALL: fnRt = {rgs,1'b0,5'd29}; // regLR
|
`LV: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RT]};
|
`LV: fnRt = {vqei,1'b1,isn[`INSTRUCTION_RT]};
|
Line 2592... |
Line 2480... |
`R2:
|
`R2:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
`CMP: fnWe = 8'h00;
|
`CMP: fnWe = 8'h00;
|
default: fnWe = 8'hFF;
|
default: fnWe = 8'hFF;
|
endcase
|
endcase
|
`CMPI: fnWe = 8'h00;
|
|
default: fnWe = 8'hFF;
|
default: fnWe = 8'hFF;
|
endcase
|
endcase
|
/*
|
/*
|
casez(isn[`INSTRUCTION_OP])
|
casez(isn[`INSTRUCTION_OP])
|
`R2:
|
`R2:
|
Line 2642... |
Line 2529... |
function Source1Valid;
|
function Source1Valid;
|
input [47:0] isn;
|
input [47:0] isn;
|
casez(isn[`INSTRUCTION_OP])
|
casez(isn[`INSTRUCTION_OP])
|
`BRK: Source1Valid = isn[16] ? isn[`INSTRUCTION_RA]==5'd0 : TRUE;
|
`BRK: Source1Valid = isn[16] ? isn[`INSTRUCTION_RA]==5'd0 : TRUE;
|
`Bcc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`Bcc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
|
`BLcc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`BBc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`BBc: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`BEQI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`BEQI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
|
`BNEI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`CHK: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`CHK: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`RR: case(isn[`INSTRUCTION_S2])
|
`RR: case(isn[`INSTRUCTION_S2])
|
`SHIFT31: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SHIFT31: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SHIFT63: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SHIFT63: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SHIFTR: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SHIFTR: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
default: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
default: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
endcase
|
endcase
|
`MEMNDX:Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`MEMNDX:Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`ADDI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`ADDI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
|
`SEQI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SLTI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SLTI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SLTUI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SLTUI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SGTI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SGTI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SGTUI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SGTUI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`ANDI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`ANDI: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
Line 2679... |
Line 2569... |
`LVxU: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`LVxU: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SB: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SB: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`Sx: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`Sx: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SWC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SWC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SV: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`SV: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
|
`PUSHC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`INC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`INC: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`CAS: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`CAS: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`CACHE: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`CACHE: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`JAL: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`JAL: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`RET: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
`RET: Source1Valid = isn[`INSTRUCTION_RA]==5'd0;
|
Line 2700... |
Line 2591... |
function Source2Valid;
|
function Source2Valid;
|
input [47:0] isn;
|
input [47:0] isn;
|
casez(isn[`INSTRUCTION_OP])
|
casez(isn[`INSTRUCTION_OP])
|
`BRK: Source2Valid = TRUE;
|
`BRK: Source2Valid = TRUE;
|
`Bcc: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`Bcc: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
|
`BLcc: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`BBc: Source2Valid = TRUE;
|
`BBc: Source2Valid = TRUE;
|
`BEQI: Source2Valid = TRUE;
|
`BEQI: Source2Valid = TRUE;
|
|
`BNEI: Source2Valid = TRUE;
|
`CHK: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`CHK: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`R2: casez(isn[`INSTRUCTION_S2])
|
`R2: casez(isn[`INSTRUCTION_S2])
|
`TLB: Source2Valid = TRUE;
|
`TLB: Source2Valid = TRUE;
|
`R1: Source2Valid = TRUE;
|
`R1: Source2Valid = TRUE;
|
`MOV: Source2Valid = TRUE;
|
`MOV: Source2Valid = TRUE;
|
`SHIFTR: Source2Valid = isn[25] ? 1'b1 : isn[`INSTRUCTION_RB]==5'd0;
|
`SHIFT31: Source2Valid = TRUE;
|
`SHIFT31: Source2Valid = isn[25] ? 1'b1 : isn[`INSTRUCTION_RB]==5'd0;
|
`SHIFT63: Source2Valid = TRUE;
|
`SHIFT63: Source2Valid = isn[25] ? 1'b1 : isn[`INSTRUCTION_RB]==5'd0;
|
|
`LVX,`SVX: Source2Valid = FALSE;
|
`LVX,`SVX: Source2Valid = FALSE;
|
default: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
default: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
endcase
|
endcase
|
`MEMNDX:
|
`MEMNDX:
|
begin
|
begin
|
Line 2730... |
Line 2622... |
`SVX: Source2Valid = FALSE;
|
`SVX: Source2Valid = FALSE;
|
default: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
default: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
endcase
|
endcase
|
end
|
end
|
`ADDI: Source2Valid = TRUE;
|
`ADDI: Source2Valid = TRUE;
|
|
`SEQI: Source2Valid = TRUE;
|
`SLTI: Source2Valid = TRUE;
|
`SLTI: Source2Valid = TRUE;
|
`SLTUI: Source2Valid = TRUE;
|
`SLTUI: Source2Valid = TRUE;
|
`SGTI: Source2Valid = TRUE;
|
`SGTI: Source2Valid = TRUE;
|
`SGTUI: Source2Valid = TRUE;
|
`SGTUI: Source2Valid = TRUE;
|
`ANDI: Source2Valid = TRUE;
|
`ANDI: Source2Valid = TRUE;
|
Line 2751... |
Line 2644... |
`LVxU: Source2Valid = TRUE;
|
`LVxU: Source2Valid = TRUE;
|
`INC: Source2Valid = TRUE;
|
`INC: Source2Valid = TRUE;
|
`SB: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`SB: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`Sx: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`Sx: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`SWC: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`SWC: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
|
`PUSHC: Source2Valid = TRUE;
|
`CAS: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`CAS: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`JAL: Source2Valid = TRUE;
|
`JAL: Source2Valid = TRUE;
|
`RET: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`RET: Source2Valid = isn[`INSTRUCTION_RB]==5'd0;
|
`IVECTOR:
|
`IVECTOR:
|
case(isn[`INSTRUCTION_S2])
|
case(isn[`INSTRUCTION_S2])
|
Line 2819... |
Line 2713... |
`BITFIELD: Source3Valid = isn[`INSTRUCTION_RC]==5'd0 || isn[32]==1'b0;
|
`BITFIELD: Source3Valid = isn[`INSTRUCTION_RC]==5'd0 || isn[32]==1'b0;
|
default: Source3Valid = TRUE;
|
default: Source3Valid = TRUE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
// For predication logic
|
|
function SourceTValid;
|
|
input [47:0] isn;
|
|
case(isn[`INSTRUCTION_OP])
|
|
`BRK: SourceTValid = TRUE;
|
|
`Bcc: SourceTValid = TRUE;
|
|
`BBc: SourceTValid = TRUE;
|
|
`BEQI: SourceTValid = TRUE;
|
|
`IVECTOR:
|
|
case(isn[`INSTRUCTION_S2])
|
|
`VEX: SourceTValid = TRUE;
|
|
default: SourceTValid = TRUE;
|
|
endcase
|
|
`CHK: SourceTValid = isn[`INSTRUCTION_RT]==5'd0;
|
|
`R2:
|
|
if (isn[`INSTRUCTION_L2]==2'b01)
|
|
case(isn[47:42])
|
|
`CMOVEZ,`CMOVNZ: SourceTValid = isn[`INSTRUCTION_RT]==5'd0;
|
|
default: SourceTValid = TRUE;
|
|
endcase
|
|
else
|
|
case(isn[`INSTRUCTION_S2])
|
|
`MAJ: SourceTValid = isn[`INSTRUCTION_RT]==5'd0;
|
|
default: SourceTValid = TRUE;
|
|
endcase
|
|
`MEMNDX:
|
|
if (!isn[31])
|
|
case({isn[31:28],isn[22:21]})
|
|
`CACHEX,
|
|
`LVBX,`LVBUX,`LVCX,`LVCUX,`LVHX,`LVHUX,`LVWX,
|
|
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,`LWRX:
|
|
SourceTValid = isn[`INSTRUCTION_RT]==5'd0;
|
|
default: SourceTValid = TRUE;
|
|
endcase
|
|
else
|
|
SourceTValid = TRUE;
|
|
`SB: SourceTValid = TRUE;
|
|
`Sx: SourceTValid = TRUE;
|
|
`SWC: SourceTValid = TRUE;
|
|
`CAS: SourceTValid = TRUE;
|
|
`BITFIELD: SourceTValid = isn[`INSTRUCTION_RT]==5'd0 || isn[32]==1'b0;
|
|
default: SourceTValid = isn[`INSTRUCTION_RT]==5'd0;
|
|
endcase
|
|
endfunction
|
|
|
|
// Used to indicate to the queue logic that the instruction needs to be
|
// Used to indicate to the queue logic that the instruction needs to be
|
// recycled to the queue VL number of times.
|
// recycled to the queue VL number of times.
|
function IsVector;
|
function IsVector;
|
input [47:0] isn;
|
input [47:0] isn;
|
Line 2955... |
Line 2805... |
`RR: fnM2 = isn[24:23];
|
`RR: fnM2 = isn[24:23];
|
default: fnM2 = 2'b00;
|
default: fnM2 = 2'b00;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsCmp;
|
function IsMem;
|
input [47:0] isn;
|
|
case(isn[`INSTRUCTION_OP])
|
|
`R2:
|
|
if (isn[`INSTRUCTION_L2]==2'b00)
|
|
case(isn[31:26])
|
|
`CMP: IsCmp = TRUE;
|
|
default: IsCmp = FALSE;
|
|
endcase
|
|
else
|
|
IsCmp = FALSE;
|
|
`CMPI: IsCmp = TRUE;
|
|
default: IsCmp = FALSE;
|
|
endcase
|
|
endfunction
|
|
|
|
function [0:0] IsMem;
|
|
input [47:0] isn;
|
input [47:0] isn;
|
case(isn[`INSTRUCTION_OP])
|
case(isn[`INSTRUCTION_OP])
|
`MEMNDX: IsMem = TRUE;
|
`MEMNDX: IsMem = TRUE;
|
`AMO: IsMem = TRUE;
|
`AMO: IsMem = TRUE;
|
`LB: IsMem = TRUE;
|
`LB: IsMem = TRUE;
|
Line 2986... |
Line 2820... |
`LV,`SV: IsMem = TRUE;
|
`LV,`SV: IsMem = TRUE;
|
`INC: IsMem = TRUE;
|
`INC: IsMem = TRUE;
|
`SB: IsMem = TRUE;
|
`SB: IsMem = TRUE;
|
`Sx: IsMem = TRUE;
|
`Sx: IsMem = TRUE;
|
`SWC: IsMem = TRUE;
|
`SWC: IsMem = TRUE;
|
|
`PUSHC: IsMem = TRUE;
|
`CAS: IsMem = TRUE;
|
`CAS: IsMem = TRUE;
|
`LVx: IsMem = TRUE;
|
`LVx: IsMem = TRUE;
|
`LVxU: IsMem = TRUE;
|
`LVxU: IsMem = TRUE;
|
default: IsMem = FALSE;
|
default: IsMem = FALSE;
|
endcase
|
endcase
|
Line 3126... |
Line 2961... |
// Does not include BccR's
|
// Does not include BccR's
|
function IsBranch;
|
function IsBranch;
|
input [47:0] isn;
|
input [47:0] isn;
|
casez(isn[`INSTRUCTION_OP])
|
casez(isn[`INSTRUCTION_OP])
|
`Bcc: IsBranch = TRUE;
|
`Bcc: IsBranch = TRUE;
|
|
`BLcc: IsBranch = TRUE;
|
`BBc: IsBranch = TRUE;
|
`BBc: IsBranch = TRUE;
|
`BEQI: IsBranch = TRUE;
|
`BEQI: IsBranch = TRUE;
|
|
`BNEI: IsBranch = TRUE;
|
`CHK: IsBranch = TRUE;
|
`CHK: IsBranch = TRUE;
|
default: IsBranch = FALSE;
|
default: IsBranch = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
Line 3157... |
Line 2994... |
`R2: case(isn[`INSTRUCTION_S2])
|
`R2: case(isn[`INSTRUCTION_S2])
|
`RTI: IsFlowCtrl = TRUE;
|
`RTI: IsFlowCtrl = TRUE;
|
default: IsFlowCtrl = FALSE;
|
default: IsFlowCtrl = FALSE;
|
endcase
|
endcase
|
`Bcc: IsFlowCtrl = TRUE;
|
`Bcc: IsFlowCtrl = TRUE;
|
|
`BLcc: IsFlowCtrl = TRUE;
|
`BBc: IsFlowCtrl = TRUE;
|
`BBc: IsFlowCtrl = TRUE;
|
`BEQI: IsFlowCtrl = TRUE;
|
`BEQI: IsFlowCtrl = TRUE;
|
|
`BNEI: IsFlowCtrl = TRUE;
|
`CHK: IsFlowCtrl = TRUE;
|
`CHK: IsFlowCtrl = TRUE;
|
`JAL: IsFlowCtrl = TRUE;
|
`JAL: IsFlowCtrl = TRUE;
|
`JMP: IsFlowCtrl = TRUE;
|
`JMP: IsFlowCtrl = TRUE;
|
`CALL: IsFlowCtrl = TRUE;
|
`CALL: IsFlowCtrl = TRUE;
|
`RET: IsFlowCtrl = TRUE;
|
`RET: IsFlowCtrl = TRUE;
|
Line 3226... |
Line 3065... |
`LV: IsLV = TRUE;
|
`LV: IsLV = TRUE;
|
default: IsLV = FALSE;
|
default: IsLV = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
function IsRet;
|
|
input [47:0] isn;
|
|
IsRet = isn[`INSTRUCTION_OP]==`RET;
|
|
endfunction
|
|
|
function IsRFW;
|
function IsRFW;
|
input [47:0] isn;
|
input [47:0] isn;
|
input [5:0] vqei;
|
input [5:0] vqei;
|
input [5:0] vli;
|
input [5:0] vli;
|
input thrd;
|
input thrd;
|
Line 3248... |
Line 3092... |
`MEMDB,`MEMSB,`SYNC,`SETWB,5'h14,5'h15: IsRFW = FALSE;
|
`MEMDB,`MEMSB,`SYNC,`SETWB,5'h14,5'h15: IsRFW = FALSE;
|
default: IsRFW = TRUE;
|
default: IsRFW = TRUE;
|
endcase
|
endcase
|
`ADD: IsRFW = TRUE;
|
`ADD: IsRFW = TRUE;
|
`SUB: IsRFW = TRUE;
|
`SUB: IsRFW = TRUE;
|
|
`SEQ: IsRFW = TRUE;
|
`SLT: IsRFW = TRUE;
|
`SLT: IsRFW = TRUE;
|
`SLTU: IsRFW = TRUE;
|
`SLTU: IsRFW = TRUE;
|
`SLE: IsRFW = TRUE;
|
`SLE: IsRFW = TRUE;
|
`SLEU: IsRFW = TRUE;
|
`SLEU: IsRFW = TRUE;
|
`AND: IsRFW = TRUE;
|
`AND: IsRFW = TRUE;
|
Line 3345... |
Line 3190... |
else
|
else
|
IsRFW = FALSE;
|
IsRFW = FALSE;
|
`BBc: IsRFW = FALSE;
|
`BBc: IsRFW = FALSE;
|
`BITFIELD: IsRFW = TRUE;
|
`BITFIELD: IsRFW = TRUE;
|
`ADDI: IsRFW = TRUE;
|
`ADDI: IsRFW = TRUE;
|
|
`SEQI: IsRFW = TRUE;
|
`SLTI: IsRFW = TRUE;
|
`SLTI: IsRFW = TRUE;
|
`SLTUI: IsRFW = TRUE;
|
`SLTUI: IsRFW = TRUE;
|
`SGTI: IsRFW = TRUE;
|
`SGTI: IsRFW = TRUE;
|
`SGTUI: IsRFW = TRUE;
|
`SGTUI: IsRFW = TRUE;
|
`ANDI: IsRFW = TRUE;
|
`ANDI: IsRFW = TRUE;
|
Line 3370... |
Line 3216... |
`LxU: IsRFW = TRUE;
|
`LxU: IsRFW = TRUE;
|
`LWR: IsRFW = TRUE;
|
`LWR: IsRFW = TRUE;
|
`LV: IsRFW = TRUE;
|
`LV: IsRFW = TRUE;
|
`LVx: IsRFW = TRUE;
|
`LVx: IsRFW = TRUE;
|
`LVxU: IsRFW = TRUE;
|
`LVxU: IsRFW = TRUE;
|
|
`PUSHC: IsRFW = TRUE;
|
`CAS: IsRFW = TRUE;
|
`CAS: IsRFW = TRUE;
|
`AMO: IsRFW = TRUE;
|
`AMO: IsRFW = TRUE;
|
`CSRRW: IsRFW = TRUE;
|
`CSRRW: IsRFW = TRUE;
|
`AUIPC: IsRFW = TRUE;
|
`AUIPC: IsRFW = TRUE;
|
`LUI: IsRFW = TRUE;
|
`LUI: IsRFW = TRUE;
|
Line 3476... |
Line 3323... |
`DIVUI,`DIVI,`MODI: IsDivmod = TRUE;
|
`DIVUI,`DIVI,`MODI: IsDivmod = TRUE;
|
default: IsDivmod = FALSE;
|
default: IsDivmod = FALSE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function IsExec;
|
|
input [47:0] isn;
|
|
case(isn[`INSTRUCTION_OP])
|
|
`EXEC: IsExec = TRUE;
|
|
default: IsExec = FALSE;
|
|
endcase
|
|
endfunction
|
|
|
|
function [7:0] fnSelect;
|
function [7:0] fnSelect;
|
input [47:0] ins;
|
input [47:0] ins;
|
input [`ABITS] adr;
|
input [`ABITS] adr;
|
begin
|
begin
|
case(ins[`INSTRUCTION_OP])
|
case(ins[`INSTRUCTION_OP])
|
Line 3601... |
Line 3440... |
2'd2: fnSelect = 8'h30;
|
2'd2: fnSelect = 8'h30;
|
2'd3: fnSelect = 8'hC0;
|
2'd3: fnSelect = 8'hC0;
|
endcase
|
endcase
|
default: fnSelect = 8'h00;
|
default: fnSelect = 8'h00;
|
endcase
|
endcase
|
|
`PUSHC,
|
`INC,
|
`INC,
|
`LWR,`SWC,`CAS: fnSelect = 8'hFF;
|
`LWR,`SWC,`CAS: fnSelect = 8'hFF;
|
`LV,`SV: fnSelect = 8'hFF;
|
`LV,`SV: fnSelect = 8'hFF;
|
`AMO:
|
`AMO:
|
case(ins[23:21])
|
case(ins[23:21])
|
Line 3865... |
Line 3705... |
|
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
// FETCH
|
// FETCH
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
//
|
//
|
assign fetchbuf0_mem = IsMem(fetchbuf0_instr);// & IsLoad(fetchbuf0_instr);
|
assign fetchbuf0_mem = IsMem(fetchbuf0_instr) & ~IsRet(fetchbuf0_instr);// & IsLoad(fetchbuf0_instr);
|
assign fetchbuf0_rfw = IsRFW(fetchbuf0_instr,vqe0,vl,fetchbuf0_thrd);
|
assign fetchbuf0_rfw = IsRFW(fetchbuf0_instr,vqe0,vl,fetchbuf0_thrd);
|
`ifdef SUPPORT_PREDICATION
|
|
assign fetchbuf0_prfw = IsCmp(fetchbuf0_instr);
|
|
`endif
|
|
|
|
generate begin: gFetchbufDec
|
generate begin: gFetchbufDec
|
if (`WAYS > 1) begin
|
if (`WAYS > 1) begin
|
assign fetchbuf1_mem = IsMem(fetchbuf1_instr);// & IsLoad(fetchbuf1_instr);
|
assign fetchbuf1_mem = IsMem(fetchbuf1_instr) & ~IsRet(fetchbuf1_instr);// & IsLoad(fetchbuf1_instr);
|
assign fetchbuf1_rfw = IsRFW(fetchbuf1_instr,vqe1,vl,fetchbuf1_thrd);
|
assign fetchbuf1_rfw = IsRFW(fetchbuf1_instr,vqe1,vl,fetchbuf1_thrd);
|
`ifdef SUPPORT_PREDICATION
|
|
assign fetchbuf1_prfw = IsCmp(fetchbuf1_instr);
|
|
`endif
|
|
end
|
end
|
if (`WAYS > 2) begin
|
if (`WAYS > 2) begin
|
assign fetchbuf2_mem = IsMem(fetchbuf2_instr);// & IsLoad(fetchbuf2_instr);
|
assign fetchbuf2_mem = IsMem(fetchbuf2_instr) & ~IsRet(fetchbuf2_instr);// & IsLoad(fetchbuf2_instr);
|
assign fetchbuf2_rfw = IsRFW(fetchbuf2_instr,vqe2,vl,fetchbuf2_thrd);
|
assign fetchbuf2_rfw = IsRFW(fetchbuf2_instr,vqe2,vl,fetchbuf2_thrd);
|
`ifdef SUPPORT_PREDICATION
|
|
assign fetchbuf2_prfw = IsCmp(fetchbuf2_instr);
|
|
`endif
|
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
generate begin : gFetchbufInst
|
generate begin : gFetchbufInst
|
Line 3964... |
Line 3795... |
.fetchbuf1_v(fetchbuf1_v),
|
.fetchbuf1_v(fetchbuf1_v),
|
.fetchbuf2_v(fetchbuf2_v),
|
.fetchbuf2_v(fetchbuf2_v),
|
.fetchbuf0_insln(fetchbuf0_insln),
|
.fetchbuf0_insln(fetchbuf0_insln),
|
.fetchbuf1_insln(fetchbuf1_insln),
|
.fetchbuf1_insln(fetchbuf1_insln),
|
.fetchbuf2_insln(fetchbuf2_insln),
|
.fetchbuf2_insln(fetchbuf2_insln),
|
.codebuf0(codebuf[insn0[21:16]]),
|
.codebuf0(codebuf[insn0[13:8]]),
|
.codebuf1(codebuf[insn1[21:16]]),
|
.codebuf1(codebuf[insn1[13:8]]),
|
.codebuf2(codebuf[insn2[21:16]]),
|
.codebuf2(codebuf[insn2[13:8]]),
|
.btgtA(btgtA),
|
.btgtA(btgtA),
|
.btgtB(btgtB),
|
.btgtB(btgtB),
|
.btgtC(btgtC),
|
.btgtC(btgtC),
|
.btgtD(btgtD),
|
.btgtD(btgtD),
|
.btgtE(btgtE),
|
.btgtE(btgtE),
|
Line 4041... |
Line 3872... |
.fetchbuf1_pc(fetchbuf1_pc),
|
.fetchbuf1_pc(fetchbuf1_pc),
|
.fetchbuf0_v(fetchbuf0_v),
|
.fetchbuf0_v(fetchbuf0_v),
|
.fetchbuf1_v(fetchbuf1_v),
|
.fetchbuf1_v(fetchbuf1_v),
|
.fetchbuf0_insln(fetchbuf0_insln),
|
.fetchbuf0_insln(fetchbuf0_insln),
|
.fetchbuf1_insln(fetchbuf1_insln),
|
.fetchbuf1_insln(fetchbuf1_insln),
|
.codebuf0(codebuf[insn0[21:16]]),
|
.codebuf0(codebuf[insn0[13:8]]),
|
.codebuf1(codebuf[insn1[21:16]]),
|
.codebuf1(codebuf[insn1[13:8]]),
|
.btgtA(btgtA),
|
.btgtA(btgtA),
|
.btgtB(btgtB),
|
.btgtB(btgtB),
|
.btgtC(btgtC),
|
.btgtC(btgtC),
|
.btgtD(btgtD),
|
.btgtD(btgtD),
|
.nop_fetchbuf(nop_fetchbuf),
|
.nop_fetchbuf(nop_fetchbuf),
|
Line 4098... |
Line 3929... |
.fetchbuf0_thrd(fetchbuf0_thrd),
|
.fetchbuf0_thrd(fetchbuf0_thrd),
|
.fetchbuf0_pc(fetchbuf0_pc),
|
.fetchbuf0_pc(fetchbuf0_pc),
|
.fetchbuf0_v(fetchbuf0_v),
|
.fetchbuf0_v(fetchbuf0_v),
|
.fetchbuf0_insln(fetchbuf0_insln),
|
.fetchbuf0_insln(fetchbuf0_insln),
|
.fetchbuf0_pbyte(fetchbuf0_pbyte),
|
.fetchbuf0_pbyte(fetchbuf0_pbyte),
|
.codebuf0(codebuf[insn0[21:16]]),
|
.codebuf0(codebuf[insn0[13:8]]),
|
.btgtA(btgtA),
|
.btgtA(btgtA),
|
.btgtB(btgtB),
|
.btgtB(btgtB),
|
.nop_fetchbuf(nop_fetchbuf),
|
.nop_fetchbuf(nop_fetchbuf),
|
.take_branch0(take_branch0),
|
.take_branch0(take_branch0),
|
.stompedRets(stompedOnRets),
|
.stompedRets(stompedOnRets),
|
Line 4112... |
Line 3943... |
assign fetchbuf1_v = `INV;
|
assign fetchbuf1_v = `INV;
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
|
// Stores might exception so we don't want the heads to advance if a subsequent
|
|
// instruction is store even though there's no target register.
|
wire cmt_head1 = (!iqentry_rfw[heads[1]] && !iqentry_oddball[heads[1]] && ~|iqentry_exc[heads[1]]);
|
wire cmt_head1 = (!iqentry_rfw[heads[1]] && !iqentry_oddball[heads[1]] && ~|iqentry_exc[heads[1]]);
|
wire cmt_head2 = (!iqentry_rfw[heads[2]] && !iqentry_oddball[heads[2]] && ~|iqentry_exc[heads[2]]);
|
wire cmt_head2 = (!iqentry_rfw[heads[2]] && !iqentry_oddball[heads[2]] && ~|iqentry_exc[heads[2]]);
|
|
|
// Determine the head increment amount, this must match code later on.
|
// Determine the head increment amount, this must match code later on.
|
reg [2:0] hi_amt;
|
reg [2:0] hi_amt;
|
Line 4260... |
Line 4093... |
livetarget[j] = livetarget[j] | iqentry_livetarget[n][j];
|
livetarget[j] = livetarget[j] | iqentry_livetarget[n][j];
|
end
|
end
|
|
|
always @*
|
always @*
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
`ifdef SUPPORT_PREDICATION
|
|
iqentry_livetarget[n] = {PREGS {iqentry_v[n]}} & {PREGS {~iqentry_stomp[n] && iqentry_thrd[n]==branchmiss_thrd}} & iq_out[n] & ~{PREGS{iqentry_cmp[n]}};
|
|
`else
|
|
iqentry_livetarget[n] = {PREGS {iqentry_v[n]}} & {PREGS {~iqentry_stomp[n] && iqentry_thrd[n]==branchmiss_thrd}} & iq_out[n];
|
iqentry_livetarget[n] = {PREGS {iqentry_v[n]}} & {PREGS {~iqentry_stomp[n] && iqentry_thrd[n]==branchmiss_thrd}} & iq_out[n];
|
`endif
|
|
|
|
`ifdef SUPPORT_PREDICATION
|
|
always @*
|
|
for (j = 1; j < 16; j = j + 1) begin
|
|
plivetarget[j] = 1'b0;
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
|
plivetarget[j] = plivetarget[j] | iqentry_plivetarget[n][j];
|
|
end
|
|
|
|
always @*
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
|
iqentry_plivetarget[n] = {16 {iqentry_v[n]}} & {16 {~iqentry_stomp[n] && iqentry_thrd[n]==branchmiss_thrd}} & iq_out[n] & {16{iqentry_cmp[n]}};
|
|
`endif
|
|
|
|
//
|
//
|
// BRANCH-MISS LOGIC: latestID
|
// BRANCH-MISS LOGIC: latestID
|
//
|
//
|
// latestID is the instruction queue ID of the newest instruction (latest) that targets
|
// latestID is the instruction queue ID of the newest instruction (latest) that targets
|
Line 4305... |
Line 4121... |
|
|
always @*
|
always @*
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
iqentry_source[n] = | iqentry_latestID[n];
|
iqentry_source[n] = | iqentry_latestID[n];
|
|
|
`ifdef SUPPORT_PREDICATION
|
|
always @*
|
|
for (n = 0; n < QENTRIES; n = n + 1) begin
|
|
iqentry_pcumulative[n] = 1'b0;
|
|
for (j = n; j < n + QENTRIES; j = j + 1) begin
|
|
if (missid==(j % QENTRIES))
|
|
for (k = n; k <= j; k = k + 1)
|
|
iqentry_pcumulative[n] = iqentry_pcumulative[n] | iqentry_plivetarget[k % QENTRIES];
|
|
end
|
|
end
|
|
|
|
always @*
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
|
iqentry_platestID[n] = (missid == n || ((iqentry_plivetarget[n] & iqentry_pcumulative[(n+1)%QENTRIES]) == {16{1'b0}}))
|
|
? iqentry_plivetarget[n]
|
|
: {16{1'b0}};
|
|
|
|
always @*
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
|
iqentry_psource[n] = | iqentry_platestID[n];
|
|
|
|
`endif
|
|
|
|
reg vqueued2;
|
reg vqueued2;
|
assign Ra0 = fnRa(fetchbuf0_instr,vqe0,vl,fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Ra0 = fnRa(fetchbuf0_instr,vqe0,vl,fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Rb0 = fnRb(fetchbuf0_instr,1'b0,vqe0,rfoa0[5:0],rfoa1[5:0],fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Rb0 = fnRb(fetchbuf0_instr,1'b0,vqe0,rfoa0[5:0],rfoa1[5:0],fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Rc0 = fnRc(fetchbuf0_instr,vqe0,fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Rc0 = fnRc(fetchbuf0_instr,vqe0,fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Rt0 = fnRt(fetchbuf0_instr,vqet0,vl,fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
assign Rt0 = fnRt(fetchbuf0_instr,vqet0,vl,fetchbuf0_thrd) | {fetchbuf0_thrd,7'b0};
|
Line 4674... |
Line 4467... |
end
|
end
|
|
|
always @*
|
always @*
|
begin
|
begin
|
for (n = 0; n < QENTRIES; n = n + 1) begin
|
for (n = 0; n < QENTRIES; n = n + 1) begin
|
iqentry_v[n] <= iqentry_state[n] != IQS_INVALID;
|
iqentry_v[n] = iqentry_state[n] != IQS_INVALID;
|
iqentry_done[n] <= iqentry_state[n]==IQS_DONE || iqentry_state[n]==IQS_CMT;
|
iqentry_done[n] = iqentry_state[n]==IQS_DONE || iqentry_state[n]==IQS_CMT;
|
iqentry_out[n] <= iqentry_state[n]==IQS_OUT;
|
iqentry_out[n] = iqentry_state[n]==IQS_OUT;
|
iqentry_agen[n] <= iqentry_state[n]==IQS_AGEN;
|
iqentry_agen[n] = iqentry_state[n]==IQS_AGEN;
|
end
|
end
|
end
|
end
|
|
|
//
|
//
|
// determine if the instructions ready to issue can, in fact, issue.
|
// determine if the instructions ready to issue can, in fact, issue.
|
Line 5487... |
Line 5280... |
begin
|
begin
|
last_issue0 = QENTRIES;
|
last_issue0 = QENTRIES;
|
last_issue1 = QENTRIES;
|
last_issue1 = QENTRIES;
|
last_issue2 = QENTRIES;
|
last_issue2 = QENTRIES;
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
if (~iqentry_stomp[heads[n]] && iqentry_memissue[heads[n]]) begin
|
if (~iqentry_stomp[heads[n]] && iqentry_memissue[heads[n]] && !iqentry_done[heads[n]] && iqentry_v[heads[n]]) begin
|
if (mem1_available && dram0 == `DRAMSLOT_AVAIL) begin
|
if (mem1_available && dram0 == `DRAMSLOT_AVAIL) begin
|
last_issue0 = heads[n];
|
last_issue0 = heads[n];
|
end
|
end
|
end
|
end
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
Line 5763... |
Line 5556... |
`CSR_DBU: csr_r <= dbu;
|
`CSR_DBU: csr_r <= dbu;
|
`CSR_SBL: csr_r <= sbl;
|
`CSR_SBL: csr_r <= sbl;
|
`CSR_SBU: csr_r <= sbu;
|
`CSR_SBU: csr_r <= sbu;
|
`CSR_ENU: csr_r <= en;
|
`CSR_ENU: csr_r <= en;
|
`endif
|
`endif
|
`ifdef SUPPORT_PREDICATION
|
|
`CSR_PREGS: read_pregs(csr_r);
|
|
`endif
|
|
`CSR_Q_CTR: csr_r <= iq_ctr;
|
`CSR_Q_CTR: csr_r <= iq_ctr;
|
`CSR_BM_CTR: csr_r <= bm_ctr;
|
`CSR_BM_CTR: csr_r <= bm_ctr;
|
`CSR_ICL_CTR: csr_r <= icl_ctr;
|
`CSR_ICL_CTR: csr_r <= icl_ctr;
|
`CSR_IRQ_CTR: csr_r <= irq_ctr;
|
`CSR_IRQ_CTR: csr_r <= irq_ctr;
|
`CSR_TIME: csr_r <= wc_times;
|
`CSR_TIME: csr_r <= wc_times;
|
Line 5852... |
Line 5642... |
.uncached(),
|
.uncached(),
|
.tlb_miss(tlb_miss),
|
.tlb_miss(tlb_miss),
|
.exv_o(exv_i),
|
.exv_o(exv_i),
|
.wrv_o(wrv_i),
|
.wrv_o(wrv_i),
|
.rdv_o(rdv_i)
|
.rdv_o(rdv_i)
|
`ifdef SUPPORT_SEGMENTATION
|
|
,
|
|
.zs_base(zsx_base),
|
|
.ds_base(dsx_base),
|
|
.es_base(esx_base),
|
|
.fs_base(fsx_base),
|
|
.gs_base(gsx_base),
|
|
.hs_base(hsx_base),
|
|
.ss_base(ssx_base),
|
|
.cs_base(csx_base),
|
|
.zsub(zsub),
|
|
.dsub(dsub),
|
|
.esub(esub),
|
|
.fsub(fsub),
|
|
.gsub(gsub),
|
|
.hsub(hsub),
|
|
.ssub(ssub),
|
|
.csub(csub),
|
|
.zslb(zslb),
|
|
.dslb(dslb),
|
|
.eslb(eslb),
|
|
.fslb(fslb),
|
|
.gslb(gslb),
|
|
.hslb(hslb),
|
|
.sslb(sslb),
|
|
.cslb(cslb)
|
|
`endif
|
|
`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),
|
Line 5933... |
Line 5696... |
.uncached(),
|
.uncached(),
|
.tlb_miss(),
|
.tlb_miss(),
|
.exv_o(),
|
.exv_o(),
|
.wrv_o(),
|
.wrv_o(),
|
.rdv_o()
|
.rdv_o()
|
`ifdef SUPPORT_SEGMENTATION
|
|
,
|
|
.zs_base(zsx_base),
|
|
.ds_base(dsx_base),
|
|
.es_base(esx_base),
|
|
.fs_base(fsx_base),
|
|
.gs_base(gsx_base),
|
|
.hs_base(hsx_base),
|
|
.ss_base(ssx_base),
|
|
.cs_base(csx_base),
|
|
.zsub(zsub),
|
|
.dsub(dsub),
|
|
.esub(esub),
|
|
.fsub(fsub),
|
|
.gsub(gsub),
|
|
.hsub(hsub),
|
|
.ssub(ssub),
|
|
.csub(csub),
|
|
.zslb(zslb),
|
|
.dslb(dslb),
|
|
.eslb(eslb),
|
|
.fslb(fslb),
|
|
.gslb(gslb),
|
|
.hslb(hslb),
|
|
.sslb(sslb),
|
|
.cslb(cslb)
|
|
`endif
|
|
`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),
|
Line 6098... |
Line 5834... |
|
|
always @*
|
always @*
|
begin
|
begin
|
fcu_exc <= `FLT_NONE;
|
fcu_exc <= `FLT_NONE;
|
casez(fcu_instr[`INSTRUCTION_OP])
|
casez(fcu_instr[`INSTRUCTION_OP])
|
`ifdef SUPPORT_SEGMENTATION
|
|
`LDCS: fcu_exc <= fcu_instr[31:8] != fcu_pc[63:40] ? `FLT_CS : `FLT_NONE;
|
|
`RET: fcu_exc <= fcu_argB[63:40] != fcu_pc[63:40] ? `FLT_RET : `FLT_NONE;
|
|
`endif
|
|
`ifdef SUPPORT_BBMS
|
`ifdef SUPPORT_BBMS
|
`LFCS: fcu_exc <= currentCSSelector != fcu_instr[31:8] ? `FLT_CS : `FLT_NONE;
|
`LFCS: fcu_exc <= currentCSSelector != fcu_instr[31:8] ? `FLT_CS : `FLT_NONE;
|
`RET: fcu_exc <= fcu_argB[63:40] != currentCSSelector ? `FLT_RET : `FLT_NONE;
|
`RET: fcu_exc <= fcu_argB[63:40] != currentCSSelector ? `FLT_RET : `FLT_NONE;
|
`endif
|
`endif
|
`CHK: begin
|
`CHK: begin
|
Line 6115... |
Line 5847... |
`REX:
|
`REX:
|
case(olm)
|
case(olm)
|
`OL_USER: fcu_exc <= `FLT_PRIV;
|
`OL_USER: fcu_exc <= `FLT_PRIV;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
// Could have long branches exceptioning and unimplmented in the fetch stage.
|
|
// `BBc: fcu_exc <= fcu_instr[6] ? `FLT_BRN : `FLT_NONE;
|
default: fcu_exc <= `FLT_NONE;
|
default: fcu_exc <= `FLT_NONE;
|
endcase
|
endcase
|
end
|
end
|
|
|
FT64_EvalBranch ube1
|
FT64_EvalBranch ube1
|
Line 6146... |
Line 5880... |
wire will_clear_branchmiss = branchmiss && ((fetchbuf0_v && fetchbuf0_pc==misspc) || (fetchbuf1_v && fetchbuf1_pc==misspc));
|
wire will_clear_branchmiss = branchmiss && ((fetchbuf0_v && fetchbuf0_pc==misspc) || (fetchbuf1_v && fetchbuf1_pc==misspc));
|
|
|
always @*
|
always @*
|
begin
|
begin
|
case(fcu_instr[`INSTRUCTION_OP])
|
case(fcu_instr[`INSTRUCTION_OP])
|
`R2: fcu_misspc = fcu_argB; // RTI (we don't bother fully decoding this as it's the only R2)
|
`R2: fcu_misspc = fcu_epc; // RTI (we don't bother fully decoding this as it's the only R2)
|
`RET: fcu_misspc = fcu_argB;
|
`RET: fcu_misspc = fcu_argB;
|
`REX: fcu_misspc = fcu_bus;
|
`REX: fcu_misspc = fcu_bus;
|
`BRK: fcu_misspc = {tvec[0][AMSB:8], 1'b0, olm, 5'h0};
|
`BRK: fcu_misspc = {tvec[0][AMSB:8], 1'b0, olm, 5'h0};
|
`JAL: fcu_misspc = fcu_argA + fcu_argI;
|
`JAL: fcu_misspc = fcu_argA + fcu_argI;
|
//`CHK: fcu_misspc = fcu_nextpc + fcu_argI; // Handled as an instruction exception
|
//`CHK: fcu_misspc = fcu_nextpc + fcu_argI; // Handled as an instruction exception
|
// Default: branch
|
// Default: branch
|
default: fcu_misspc = fcu_takb ? {fcu_pc[31:8] + fcu_brdisp[31:8],fcu_brdisp[7:0]} : fcu_nextpc;
|
default: fcu_misspc = fcu_pt ? fcu_nextpc : {fcu_pc[AMSB:32],fcu_pc[31:0] + fcu_brdisp[31:0]};
|
endcase
|
endcase
|
fcu_misspc[0] = 1'b0;
|
fcu_misspc[0] = 1'b0;
|
end
|
end
|
|
|
// To avoid false branch mispredicts the branch isn't evaluated until the
|
// To avoid false branch mispredicts the branch isn't evaluated until the
|
Line 6509... |
Line 6243... |
end
|
end
|
end
|
end
|
end
|
end
|
|
|
wire writing_wb =
|
wire writing_wb =
|
(mem1_available && dram0==`DRAMSLOT_BUSY && dram0_store && !iqentry_stomp[dram0_id[`QBITS]] && wbptr<`WB_DEPTH-1)
|
(mem1_available && dram0==`DRAMSLOT_BUSY && dram0_store && wbptr<`WB_DEPTH-1)
|
|| (mem2_available && dram1==`DRAMSLOT_BUSY && dram1_store && !iqentry_stomp[dram1_id[`QBITS]] && `NUM_MEM > 1 && wbptr<`WB_DEPTH-1)
|
|| (mem2_available && dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1 && wbptr<`WB_DEPTH-1)
|
|| (mem3_available && dram2==`DRAMSLOT_BUSY && dram2_store && !iqentry_stomp[dram2_id[`QBITS]] && `NUM_MEM > 2 && wbptr<`WB_DEPTH-1)
|
|| (mem3_available && dram2==`DRAMSLOT_BUSY && dram2_store && `NUM_MEM > 2 && wbptr<`WB_DEPTH-1)
|
;
|
;
|
|
|
// Monster clock domain.
|
// Monster clock domain.
|
// Like to move some of this to clocking under different always blocks in order
|
// Like to move some of this to clocking under different always blocks in order
|
// to help out the toolset's synthesis, but it ain't gonna be easy.
|
// to help out the toolset's synthesis, but it ain't gonna be easy.
|
Line 6538... |
Line 6272... |
wire [63:0] ralu0_bus = |alu0_exc ? {4{lfsro}} : alu0_bus;
|
wire [63:0] ralu0_bus = |alu0_exc ? {4{lfsro}} : 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_exc ? {4{lfsro}} : dramA_bus;
|
wire [63:0] rdramA_bus = dramA_bus;
|
wire [63:0] rdramB_bus = |dramB_exc ? {4{lfsro}} : dramB_bus;
|
wire [63:0] rdramB_bus = dramB_bus;
|
wire [63:0] rdramC_bus = |dramC_exc ? {4{lfsro}} : dramC_bus;
|
wire [63:0] rdramC_bus = dramC_bus;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst) begin
|
if (rst) 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
|
Line 6612... |
Line 6346... |
iqentry_a2_v[n] <= `INV;
|
iqentry_a2_v[n] <= `INV;
|
iqentry_a3_v[n] <= `INV;
|
iqentry_a3_v[n] <= `INV;
|
iqentry_a1_s[n] <= 5'd0;
|
iqentry_a1_s[n] <= 5'd0;
|
iqentry_a2_s[n] <= 5'd0;
|
iqentry_a2_s[n] <= 5'd0;
|
iqentry_a3_s[n] <= 5'd0;
|
iqentry_a3_s[n] <= 5'd0;
|
`ifdef SUPPORT_PREDICATION
|
|
iqentry_aT[n] <= 64'd0;
|
|
iqentry_aT_s[n] <= 1'd0;
|
|
`endif
|
|
iqentry_canex[n] <= FALSE;
|
iqentry_canex[n] <= FALSE;
|
end
|
end
|
bwhich <= 2'b00;
|
bwhich <= 2'b00;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
Line 6632... |
Line 6362... |
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;
|
L1_adr <= RSTPC;
|
|
L2_adr <= RSTPC;
|
invic <= FALSE;
|
invic <= 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;
|
Line 6669... |
Line 6400... |
alu1_tgt <= 6'h00;
|
alu1_tgt <= 6'h00;
|
alu1_ven <= 6'd0;
|
alu1_ven <= 6'd0;
|
`endif
|
`endif
|
fcu_dataready <= 0;
|
fcu_dataready <= 0;
|
fcu_instr <= `NOP_INSN;
|
fcu_instr <= `NOP_INSN;
|
|
fcu_call <= 1'b0;
|
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;
|
Line 6689... |
Line 6421... |
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
|
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 6752... |
Line 6485... |
wb_merges <= 32'd0;
|
wb_merges <= 32'd0;
|
`endif
|
`endif
|
iq_ctr <= 40'd0;
|
iq_ctr <= 40'd0;
|
icl_ctr <= 40'd0;
|
icl_ctr <= 40'd0;
|
bm_ctr <= 40'd0;
|
bm_ctr <= 40'd0;
|
|
br_ctr <= 40'd0;
|
irq_ctr <= 40'd0;
|
irq_ctr <= 40'd0;
|
cmt_timer <= 9'd0;
|
cmt_timer <= 9'd0;
|
StoreAck1 <= `FALSE;
|
StoreAck1 <= `FALSE;
|
keys <= 64'h0;
|
keys <= 64'h0;
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
Line 7330... |
Line 7064... |
if (IsWait(fcu_instr)) begin
|
if (IsWait(fcu_instr)) begin
|
if (pe_wait)
|
if (pe_wait)
|
fcu_dataready <= `TRUE;
|
fcu_dataready <= `TRUE;
|
end
|
end
|
|
|
|
// If the return segment is not the same as the current code segment then a
|
|
// segment load is triggered via the memory unit by setting the iq state to
|
|
// AGEN. Otherwise the state is set to CMT which will cause a bypass of the
|
|
// segment load from memory.
|
|
|
if (fcu_v) begin
|
if (fcu_v) begin
|
fcu_done <= `TRUE;
|
fcu_done <= `TRUE;
|
iqentry_ma [ fcu_id[`QBITS] ] <= fcu_misspc;
|
iqentry_ma [ fcu_id[`QBITS] ] <= fcu_misspc;
|
iqentry_res [ fcu_id[`QBITS] ] <= rfcu_bus;
|
iqentry_res [ fcu_id[`QBITS] ] <= rfcu_bus;
|
iqentry_exc [ fcu_id[`QBITS] ] <= fcu_exc;
|
iqentry_exc [ fcu_id[`QBITS] ] <= fcu_exc;
|
// iqentry_done[ fcu_id[`QBITS] ] <= `TRUE;
|
|
// iqentry_out [ fcu_id[`QBITS] ] <= `INV;
|
|
iqentry_state[fcu_id[`QBITS] ] <= IQS_CMT;
|
iqentry_state[fcu_id[`QBITS] ] <= IQS_CMT;
|
// takb is looked at only for branches to update the predictor. Here it is
|
// takb is looked at only for branches to update the predictor. Here it is
|
// unconditionally set, the value will be ignored if it's not a branch.
|
// unconditionally set, the value will be ignored if it's not a branch.
|
iqentry_takb[ fcu_id[`QBITS] ] <= fcu_takb;
|
iqentry_takb[ fcu_id[`QBITS] ] <= fcu_takb;
|
|
br_ctr <= br_ctr + fcu_branch;
|
fcu_dataready <= `INV;
|
fcu_dataready <= `INV;
|
end
|
end
|
|
|
// dramX_v only set on a load
|
// dramX_v only set on a load
|
if (mem1_available && dramA_v && iqentry_v[ dramA_id[`QBITS] ]) begin
|
if (dramA_v && iqentry_v[ dramA_id[`QBITS] ]) begin
|
iqentry_res [ dramA_id[`QBITS] ] <= rdramA_bus;
|
iqentry_res [ dramA_id[`QBITS] ] <= rdramA_bus;
|
iqentry_exc [ dramA_id[`QBITS] ] <= dramA_exc;
|
|
// iqentry_done[ dramA_id[`QBITS] ] <= `VAL;
|
// iqentry_done[ dramA_id[`QBITS] ] <= `VAL;
|
// iqentry_out [ dramA_id[`QBITS] ] <= `INV;
|
// iqentry_out [ dramA_id[`QBITS] ] <= `INV;
|
iqentry_state[dramA_id[`QBITS] ] <= IQS_CMT;
|
iqentry_state[dramA_id[`QBITS] ] <= IQS_CMT;
|
iqentry_aq [ dramA_id[`QBITS] ] <= `INV;
|
iqentry_aq [ dramA_id[`QBITS] ] <= `INV;
|
end
|
end
|
if (mem2_available && `NUM_MEM > 1 && dramB_v && iqentry_v[ dramB_id[`QBITS] ]) begin
|
if (`NUM_MEM > 1 && dramB_v && iqentry_v[ dramB_id[`QBITS] ]) begin
|
iqentry_res [ dramB_id[`QBITS] ] <= rdramB_bus;
|
iqentry_res [ dramB_id[`QBITS] ] <= rdramB_bus;
|
iqentry_exc [ dramB_id[`QBITS] ] <= dramB_exc;
|
|
// iqentry_done[ dramB_id[`QBITS] ] <= `VAL;
|
|
iqentry_state[dramB_id[`QBITS] ] <= IQS_CMT;
|
iqentry_state[dramB_id[`QBITS] ] <= IQS_CMT;
|
// iqentry_out [ dramB_id[`QBITS] ] <= `INV;
|
|
iqentry_aq [ dramB_id[`QBITS] ] <= `INV;
|
iqentry_aq [ dramB_id[`QBITS] ] <= `INV;
|
end
|
end
|
if (mem3_available && `NUM_MEM > 2 && dramC_v && iqentry_v[ dramC_id[`QBITS] ]) begin
|
if (`NUM_MEM > 2 && dramC_v && iqentry_v[ dramC_id[`QBITS] ]) begin
|
iqentry_res [ dramC_id[`QBITS] ] <= rdramC_bus;
|
iqentry_res [ dramC_id[`QBITS] ] <= rdramC_bus;
|
iqentry_exc [ dramC_id[`QBITS] ] <= dramC_exc;
|
|
// iqentry_done[ dramC_id[`QBITS] ] <= `VAL;
|
|
iqentry_state[dramC_id[`QBITS] ] <= IQS_CMT;
|
iqentry_state[dramC_id[`QBITS] ] <= IQS_CMT;
|
// iqentry_out [ dramC_id[`QBITS] ] <= `INV;
|
|
iqentry_aq [ dramC_id[`QBITS] ] <= `INV;
|
iqentry_aq [ dramC_id[`QBITS] ] <= `INV;
|
// if (iqentry_lptr[dram2_id[`QBITS]])
|
// if (iqentry_lptr[dram2_id[`QBITS]])
|
// wbrcd[pcr[5:0]] <= 1'b1;
|
// wbrcd[pcr[5:0]] <= 1'b1;
|
end
|
end
|
|
|
Line 7653... |
Line 7384... |
iqentry_a3_v[n] ? iqentry_a3[n]
|
iqentry_a3_v[n] ? iqentry_a3[n]
|
: (iqentry_a3_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
: (iqentry_a3_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
`else
|
`else
|
iqentry_a3[n];
|
iqentry_a3[n];
|
`endif
|
`endif
|
`ifdef SUPPORT_PREDICATION
|
|
fpu1_pred <= iqentry_p_v[n] ? iqentry_pred[n] :
|
|
`ifdef FU_BYPASS
|
|
(iqentry_p_s[n] == alu0_id) ? alu0nyb[iqentry_preg[n]] :
|
|
(iqentry_p_s[n] == alu1_id) ? alu1nyb[iqentry_preg[n]] :
|
|
`endif
|
|
4'h0;
|
|
fpu1_argT <=
|
|
`ifdef FU_BYPASS
|
|
iqentry_aT_v[n] ? iqentry_aT[n]
|
|
: (iqentry_aT_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
|
`else
|
|
iqentry_aT[n];
|
|
`endif
|
|
`endif
|
|
fpu1_argI <= iqentry_a0[n];
|
fpu1_argI <= iqentry_a0[n];
|
fpu1_dataready <= `VAL;
|
fpu1_dataready <= `VAL;
|
fpu1_ld <= TRUE;
|
fpu1_ld <= TRUE;
|
iqentry_state[n] <= IQS_OUT;
|
iqentry_state[n] <= IQS_OUT;
|
end
|
end
|
Line 7708... |
Line 7424... |
iqentry_a3_v[n] ? iqentry_a3[n]
|
iqentry_a3_v[n] ? iqentry_a3[n]
|
: (iqentry_a3_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
: (iqentry_a3_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
`else
|
`else
|
iqentry_a3[n];
|
iqentry_a3[n];
|
`endif
|
`endif
|
`ifdef SUPPORT_PREDICATION
|
|
fpu2_pred <= iqentry_p_v[n] ? iqentry_pred[n] :
|
|
`ifdef FU_BYPASS
|
|
(iqentry_p_s[n] == alu0_id) ? alu0nyb[iqentry_preg[n]] :
|
|
(iqentry_p_s[n] == alu1_id) ? alu1nyb[iqentry_preg[n]] :
|
|
`endif
|
|
4'h0;
|
|
fpu2_argT <=
|
|
`ifdef FU_BYPASS
|
|
iqentry_aT_v[n] ? iqentry_aT[n]
|
|
: (iqentry_aT_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
|
`else
|
|
iqentry_aT[n];
|
|
`endif
|
|
`endif
|
|
fpu2_argI <= iqentry_a0[n];
|
fpu2_argI <= iqentry_a0[n];
|
fpu2_dataready <= `VAL;
|
fpu2_dataready <= `VAL;
|
fpu2_ld <= TRUE;
|
fpu2_ld <= TRUE;
|
iqentry_state[n] <= IQS_OUT;
|
iqentry_state[n] <= IQS_OUT;
|
end
|
end
|
Line 7740... |
Line 7441... |
fcu_instr <= iqentry_instr[n];
|
fcu_instr <= iqentry_instr[n];
|
fcu_insln <= iqentry_insln[n];
|
fcu_insln <= iqentry_insln[n];
|
fcu_pc <= iqentry_pc[n];
|
fcu_pc <= iqentry_pc[n];
|
fcu_nextpc <= iqentry_pc[n] + iqentry_insln[n];
|
fcu_nextpc <= iqentry_pc[n] + iqentry_insln[n];
|
fcu_pt <= iqentry_pt[n];
|
fcu_pt <= iqentry_pt[n];
|
fcu_brdisp <= iqentry_instr[n][6] ? {{37{iqentry_instr[n][47]}},iqentry_instr[n][47:23],iqentry_instr[n][17:16]}
|
fcu_brdisp <= iqentry_instr[n][6] ? {{36{iqentry_instr[n][47]}},iqentry_instr[n][47:23],iqentry_instr[n][17:16],1'b0}
|
: {{53{iqentry_instr[n][31]}},iqentry_instr[n][31:23],iqentry_instr[n][17:16]};
|
: {{52{iqentry_instr[n][31]}},iqentry_instr[n][31:23],iqentry_instr[n][17:16],1'b0};
|
fcu_branch <= iqentry_br[n];
|
fcu_branch <= iqentry_br[n];
|
fcu_call <= IsCall(iqentry_instr[n])|iqentry_jal[n];
|
fcu_call <= IsCall(iqentry_instr[n])|iqentry_jal[n];
|
fcu_jal <= iqentry_jal[n];
|
fcu_jal <= iqentry_jal[n];
|
fcu_ret <= iqentry_ret[n];
|
fcu_ret <= iqentry_ret[n];
|
fcu_brk <= iqentry_brk[n];
|
fcu_brk <= iqentry_brk[n];
|
Line 7754... |
Line 7455... |
fcu_argA <= iqentry_a1_v[n] ? iqentry_a1[n]
|
fcu_argA <= iqentry_a1_v[n] ? iqentry_a1[n]
|
: (iqentry_a1_s[n] == alu0_id) ? ralu0_bus
|
: (iqentry_a1_s[n] == alu0_id) ? ralu0_bus
|
: (iqentry_a1_s[n] == fpu1_id && `NUM_FPU > 0) ? rfpu1_bus
|
: (iqentry_a1_s[n] == fpu1_id && `NUM_FPU > 0) ? rfpu1_bus
|
: ralu1_bus;
|
: ralu1_bus;
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
fcu_argB <= iqentry_rti[n] ? epc0[iqentry_thrd[n]]
|
// fcu_argB <= iqentry_rti[n] ? epc0[iqentry_thrd[n]]
|
|
fcu_epc <= epc0[iqentry_thrd[n]];
|
`else
|
`else
|
fcu_argB <= iqentry_rti[n] ? epc0
|
fcu_epc <= epc0;
|
|
// fcu_argB <= iqentry_rti[n] ? epc0
|
`endif
|
`endif
|
: (iqentry_a2_v[n] ? iqentry_a2[n]
|
fcu_argB <=
|
|
(iqentry_a2_v[n] ? iqentry_a2[n]
|
: (iqentry_a2_s[n] == alu0_id) ? ralu0_bus
|
: (iqentry_a2_s[n] == alu0_id) ? ralu0_bus
|
: (iqentry_a2_s[n] == fpu1_id && `NUM_FPU > 0) ? rfpu1_bus
|
: (iqentry_a2_s[n] == fpu1_id && `NUM_FPU > 0) ? rfpu1_bus
|
: ralu1_bus);
|
: ralu1_bus);
|
// argB
|
// argB
|
waitctr <= (iqentry_a2_v[n] ? iqentry_a2[n][47:0]
|
waitctr <= (iqentry_a2_v[n] ? iqentry_a2[n][47:0]
|
: (iqentry_a2_s[n] == alu0_id) ? ralu0_bus[47:0]
|
: (iqentry_a2_s[n] == alu0_id) ? ralu0_bus[47:0]
|
: (iqentry_a2_s[n] == fpu1_id && `NUM_FPU > 0) ? rfpu1_bus[47:0]
|
: (iqentry_a2_s[n] == fpu1_id && `NUM_FPU > 0) ? rfpu1_bus[47:0]
|
: ralu1_bus[47:0]);
|
: ralu1_bus[47:0]);
|
fcu_argC <= iqentry_a3_v[n] ? iqentry_a3[n]
|
fcu_argC <= iqentry_a3_v[n] ? iqentry_a3[n]
|
: (iqentry_a3_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
: (iqentry_a3_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
`ifdef SUPPORT_PREDICATION
|
|
fcu_pred <= iqentry_p_v[n] ? iqentry_pred[n] :
|
|
`ifdef FU_BYPASS
|
|
(iqentry_p_s[n] == alu0_id) ? alu0nyb[iqentry_preg[n]] :
|
|
(iqentry_p_s[n] == alu1_id) ? alu1nyb[iqentry_preg[n]] :
|
|
`endif
|
|
4'h0;
|
|
fcu_argT <=
|
|
`ifdef FU_BYPASS
|
|
iqentry_aT_v[n] ? iqentry_aT[n]
|
|
: (iqentry_aT_s[n] == alu0_id) ? ralu0_bus : ralu1_bus;
|
|
`else
|
|
iqentry_aT[n];
|
|
`endif
|
|
`endif
|
|
fcu_argI <= iqentry_a0[n];
|
fcu_argI <= iqentry_a0[n];
|
fcu_thrd <= iqentry_thrd[n];
|
fcu_thrd <= iqentry_thrd[n];
|
fcu_dataready <= !IsWait(iqentry_instr[n]);
|
fcu_dataready <= !IsWait(iqentry_instr[n]);
|
fcu_clearbm <= `FALSE;
|
fcu_clearbm <= `FALSE;
|
fcu_ld <= TRUE;
|
fcu_ld <= TRUE;
|
Line 7825... |
Line 7514... |
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
if (dram2 == `DRAMREQ_READY && `NUM_MEM > 2)
|
if (dram2 == `DRAMREQ_READY && `NUM_MEM > 2)
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2 <= `DRAMSLOT_AVAIL;
|
|
|
// grab requests that have finished and put them on the dram_bus
|
// grab requests that have finished and put them on the dram_bus
|
|
// If stomping on the instruction don't place the value on the argument
|
|
// bus to be loaded.
|
if (dram0 == `DRAMREQ_READY && dram0_load) begin
|
if (dram0 == `DRAMREQ_READY && dram0_load) begin
|
dramA_v <= `VAL;//!iqentry_stomp[dram0_id[`QBITS]];
|
dramA_v <= !iqentry_stomp[dram0_id[`QBITS]];
|
dramA_id <= dram0_id;
|
dramA_id <= dram0_id;
|
dramA_exc <= dram0_exc;
|
|
dramA_bus <= fnDatiAlign(dram0_instr,dram0_addr,rdat0);
|
dramA_bus <= fnDatiAlign(dram0_instr,dram0_addr,rdat0);
|
end
|
end
|
if (dram1 == `DRAMREQ_READY && dram1_load && `NUM_MEM > 1) begin
|
if (dram1 == `DRAMREQ_READY && dram1_load && `NUM_MEM > 1) begin
|
dramB_v <= `VAL;//!iqentry_stomp[dram1_id[`QBITS]];
|
dramB_v <= !iqentry_stomp[dram1_id[`QBITS]];
|
dramB_id <= dram1_id;
|
dramB_id <= dram1_id;
|
dramB_exc <= dram1_exc;
|
|
dramB_bus <= fnDatiAlign(dram1_instr,dram1_addr,rdat1);
|
dramB_bus <= fnDatiAlign(dram1_instr,dram1_addr,rdat1);
|
end
|
end
|
if (dram2 == `DRAMREQ_READY && dram2_load && `NUM_MEM > 2) begin
|
if (dram2 == `DRAMREQ_READY && dram2_load && `NUM_MEM > 2) begin
|
dramC_v <= `VAL;//!iqentry_stomp[dram2_id[`QBITS]];
|
dramC_v <= !iqentry_stomp[dram2_id[`QBITS]];
|
dramC_id <= dram2_id;
|
dramC_id <= dram2_id;
|
dramC_exc <= dram2_exc;
|
|
dramC_bus <= fnDatiAlign(dram2_instr,dram2_addr,rdat2);
|
dramC_bus <= fnDatiAlign(dram2_instr,dram2_addr,rdat2);
|
end
|
end
|
|
|
if (dram0 == `DRAMREQ_READY && dram0_store)
|
if (dram0 == `DRAMREQ_READY && dram0_store)
|
$display("m[%h] <- %h", dram0_addr, dram0_data);
|
$display("m[%h] <- %h", dram0_addr, dram0_data);
|
Line 7855... |
Line 7542... |
$display("m[%h] <- %h", dram2_addr, dram2_data);
|
$display("m[%h] <- %h", dram2_addr, dram2_data);
|
|
|
//
|
//
|
// determine if the instructions ready to issue can, in fact, issue.
|
// determine if the instructions ready to issue can, in fact, issue.
|
// "ready" means that the instruction has valid operands but has not gone yet
|
// "ready" means that the instruction has valid operands but has not gone yet
|
iqentry_memissue <= memissue;
|
for (n = 0; n < QENTRIES; n = n + 1)
|
|
if (memissue[n])
|
|
iqentry_memissue[n] <= `VAL;
|
|
//iqentry_memissue <= memissue;
|
missue_count <= issue_count;
|
missue_count <= issue_count;
|
|
|
if (dram0 == `DRAMSLOT_AVAIL) dram0_exc <= `FLT_NONE;
|
|
if (dram1 == `DRAMSLOT_AVAIL) dram1_exc <= `FLT_NONE;
|
|
if (dram2 == `DRAMSLOT_AVAIL) dram2_exc <= `FLT_NONE;
|
|
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
if (iqentry_v[n] && iqentry_stomp[n]) begin
|
if (iqentry_v[n] && iqentry_stomp[n]) begin
|
iqentry_iv[n] <= `INV;
|
iqentry_iv[n] <= `INV;
|
iqentry_mem[n] <= `INV;
|
iqentry_mem[n] <= `INV;
|
iqentry_load[n] <= `INV;
|
iqentry_load[n] <= `INV;
|
Line 7873... |
Line 7559... |
iqentry_state[n] <= IQS_INVALID;
|
iqentry_state[n] <= IQS_INVALID;
|
// iqentry_agen[n] <= `INV;
|
// iqentry_agen[n] <= `INV;
|
// iqentry_out[n] <= `INV;
|
// iqentry_out[n] <= `INV;
|
// iqentry_done[n] <= `INV;
|
// iqentry_done[n] <= `INV;
|
// iqentry_cmt[n] <= `INV;
|
// iqentry_cmt[n] <= `INV;
|
if (dram0_id[`QBITS] == n[`QBITS]) begin
|
|
if (dram0==`DRAMSLOT_HASBUS)
|
|
wb_nack();
|
|
dram0_load <= `FALSE;
|
|
dram0_store <= `FALSE;
|
|
dram0_rmw <= `FALSE;
|
|
dram0 <= `DRAMSLOT_AVAIL;
|
|
end
|
|
if (dram1_id[`QBITS] == n[`QBITS]) begin
|
|
if (dram1==`DRAMSLOT_HASBUS)
|
|
wb_nack();
|
|
dram1_load <= `FALSE;
|
|
dram1_store <= `FALSE;
|
|
dram1_rmw <= `FALSE;
|
|
dram1 <= `DRAMSLOT_AVAIL;
|
|
end
|
|
if (dram2_id[`QBITS] == n[`QBITS]) begin
|
|
if (dram2==`DRAMSLOT_HASBUS)
|
|
wb_nack();
|
|
dram2_load <= `FALSE;
|
|
dram2_store <= `FALSE;
|
|
dram2_rmw <= `FALSE;
|
|
dram2 <= `DRAMSLOT_AVAIL;
|
|
end
|
|
end
|
end
|
|
|
|
// A store can't be stomped on, because a store won't issue unless there are
|
|
// no instructions that could change the flow of execution before it. Meaning
|
|
// stomp would never be true for a store.
|
|
// A load could be stomped on, but the memory access is allowed to complete
|
|
// to ensure the bus acknowledge doesn't get out of sync.
|
|
/*
|
|
if (iqentry_stomp[dram0_id[`QBITS]]) begin
|
|
if (dram0==`DRAMSLOT_HASBUS)
|
|
wb_nack();
|
|
dram0_load <= `FALSE;
|
|
dram0_store <= `FALSE;
|
|
dram0_rmw <= `FALSE;
|
|
dram0 <= `DRAMSLOT_AVAIL;
|
|
end
|
|
if (iqentry_stomp[dram1_id[`QBITS]]) begin
|
|
if (dram1==`DRAMSLOT_HASBUS)
|
|
wb_nack();
|
|
dram1_load <= `FALSE;
|
|
dram1_store <= `FALSE;
|
|
dram1_rmw <= `FALSE;
|
|
dram1 <= `DRAMSLOT_AVAIL;
|
|
end
|
|
if (iqentry_stomp[dram2_id[`QBITS]]) begin
|
|
if (dram2==`DRAMSLOT_HASBUS)
|
|
wb_nack();
|
|
dram2_load <= `FALSE;
|
|
dram2_store <= `FALSE;
|
|
dram2_rmw <= `FALSE;
|
|
dram2 <= `DRAMSLOT_AVAIL;
|
|
end
|
|
*/
|
|
|
if (last_issue0 < QENTRIES)
|
if (last_issue0 < QENTRIES)
|
tDram0Issue(last_issue0);
|
tDram0Issue(last_issue0);
|
if (last_issue1 < QENTRIES)
|
if (last_issue1 < QENTRIES)
|
tDram1Issue(last_issue1);
|
tDram1Issue(last_issue1);
|
if (last_issue2 < QENTRIES)
|
if (last_issue2 < QENTRIES)
|
Line 7918... |
Line 7612... |
if (ohead[0]==heads[0])
|
if (ohead[0]==heads[0])
|
cmt_timer <= cmt_timer + 12'd1;
|
cmt_timer <= cmt_timer + 12'd1;
|
else
|
else
|
cmt_timer <= 12'd0;
|
cmt_timer <= 12'd0;
|
|
|
if (cmt_timer==12'd1000) begin
|
if (cmt_timer==12'd1000 && icstate==IDLE) begin
|
iqentry_state[heads[0]] <= IQS_CMT;
|
iqentry_state[heads[0]] <= IQS_CMT;
|
iqentry_exc[heads[0]] <= `FLT_CMT;
|
iqentry_exc[heads[0]] <= `FLT_CMT;
|
cmt_timer <= 12'd0;
|
cmt_timer <= 12'd0;
|
end
|
end
|
|
|
Line 8053... |
Line 7747... |
|
|
rf_source[0] <= 0;
|
rf_source[0] <= 0;
|
L1_wr0 <= FALSE;
|
L1_wr0 <= FALSE;
|
L1_wr1 <= FALSE;
|
L1_wr1 <= FALSE;
|
L1_wr2 <= FALSE;
|
L1_wr2 <= FALSE;
|
|
L1_en <= 10'h000;
|
L1_invline <= FALSE;
|
L1_invline <= FALSE;
|
icnxt <= FALSE;
|
icnxt <= FALSE;
|
L2_nxt <= FALSE;
|
L2_nxt <= FALSE;
|
// Instruction cache state machine.
|
// Instruction cache state machine.
|
// On a miss first see if the instruction is in the L2 cache. No need to go to
|
// On a miss first see if the instruction is in the L2 cache. No need to go to
|
Line 8117... |
Line 7812... |
// will do no good.
|
// will do no good.
|
// The IC machine will stall in this state until the BIU has loaded the
|
// The IC machine will stall in this state until the BIU has loaded the
|
// L2 cache.
|
// L2 cache.
|
IC_WaitL2:
|
IC_WaitL2:
|
if (ihitL2 && picstate==IC3a) begin
|
if (ihitL2 && picstate==IC3a) begin
|
L1_en <= 9'h1FF;
|
L1_en <= 10'h3FF;
|
L1_wr0 <= TRUE;
|
L1_wr0 <= TRUE;
|
L1_wr1 <= TRUE && `WAYS > 1;
|
L1_wr1 <= TRUE && `WAYS > 1;
|
L1_wr2 <= TRUE && `WAYS > 2;
|
L1_wr2 <= TRUE && `WAYS > 2;
|
L1_adr <= L2_adr;
|
// L1_adr <= L2_adr;
|
L2_rdat <= L2_dato;
|
// L1_dati is loaded dring an L2 icache load operation
|
|
// if (picstate==IC3a)
|
|
L1_dati <= L2_dato;
|
icstate <= IC5;
|
icstate <= IC5;
|
end
|
end
|
else if (bstate!=B_ICacheNack)
|
else if (bstate!=B_ICacheNack)
|
;
|
;
|
else begin
|
else begin
|
L1_en <= 9'h1FF;
|
L1_en <= 10'h3FF;
|
L1_wr0 <= TRUE;
|
L1_wr0 <= TRUE;
|
L1_wr1 <= TRUE && `WAYS > 1;
|
L1_wr1 <= TRUE && `WAYS > 1;
|
L1_wr2 <= TRUE && `WAYS > 2;
|
L1_wr2 <= TRUE && `WAYS > 2;
|
L1_adr <= L2_adr;
|
// L1_adr <= L2_adr;
|
// L2_rdat set below while loading cache line
|
// L1_dati set below while loading cache line
|
//L2_rdat <= L2_dato;
|
//L1_dati <= L2_dato;
|
icstate <= IC5;
|
icstate <= IC5;
|
end
|
end
|
IC5:
|
|
begin
|
IC5: icstate <= IC6;
|
L1_en <= 9'h000;
|
|
L1_wr0 <= FALSE;
|
|
L1_wr1 <= FALSE;
|
|
L1_wr2 <= FALSE;
|
|
icstate <= IC6;
|
|
end
|
|
IC6: icstate <= IC7;
|
IC6: icstate <= IC7;
|
IC7: icstate <= IC_Next;
|
IC7: icstate <= IC_Next;
|
IC_Next:
|
IC_Next:
|
begin
|
begin
|
icstate <= IDLE;
|
icstate <= IDLE;
|
icnxt <= TRUE;
|
icnxt <= TRUE;
|
end
|
end
|
default: icstate <= IDLE;
|
default: icstate <= IDLE;
|
endcase
|
endcase
|
|
|
if (mem1_available && 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;
|
Line 8180... |
Line 7871... |
// else begin
|
// else begin
|
// dram0 <= `DRAMSLOT_AVAIL;
|
// dram0 <= `DRAMSLOT_AVAIL;
|
// dram0_load <= `FALSE;
|
// dram0_load <= `FALSE;
|
// end
|
// 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 <= `DRAMSLOT_AVAIL;
|
dram0_load <= `FALSE;
|
// dram0_load <= `FALSE;
|
end
|
// end
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMREQ_READY: dram0 <= `DRAMSLOT_AVAIL;
|
`DRAMREQ_READY: dram0 <= `DRAMSLOT_AVAIL;
|
endcase
|
endcase
|
|
|
if (mem2_available && dram1_load && `NUM_MEM > 1)
|
if (dram1_load && `NUM_MEM > 1)
|
case(dram1)
|
case(dram1)
|
`DRAMSLOT_AVAIL: ;
|
`DRAMSLOT_AVAIL: ;
|
`DRAMSLOT_BUSY:
|
`DRAMSLOT_BUSY:
|
dram1 <= dram1 + !dram1_unc;
|
dram1 <= dram1 + !dram1_unc;
|
3'd2:
|
3'd2:
|
dram1 <= dram1 + 3'd1;
|
dram1 <= dram1 + 3'd1;
|
3'd3:
|
3'd3:
|
dram1 <= dram1 + 3'd1;
|
dram1 <= dram1 + 3'd1;
|
3'd4:
|
3'd4:
|
if (iqentry_v[dram1_id[`QBITS]] && !iqentry_stomp[dram1_id[`QBITS]]) begin
|
// if (iqentry_v[dram1_id[`QBITS]] && !iqentry_stomp[dram1_id[`QBITS]]) begin
|
if (dhit1)
|
if (dhit1)
|
dram1 <= `DRAMREQ_READY;
|
dram1 <= `DRAMREQ_READY;
|
else
|
else
|
dram1 <= `DRAMSLOT_REQBUS;
|
dram1 <= `DRAMSLOT_REQBUS;
|
end
|
// end
|
else begin
|
/* else begin
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1_load <= `FALSE;
|
dram1_load <= `FALSE;
|
end
|
end*/
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMREQ_READY: dram1 <= `DRAMSLOT_AVAIL;
|
`DRAMREQ_READY: dram1 <= `DRAMSLOT_AVAIL;
|
endcase
|
endcase
|
|
|
if (mem3_available && dram2_load && `NUM_MEM > 2)
|
if (dram2_load && `NUM_MEM > 2)
|
case(dram2)
|
case(dram2)
|
`DRAMSLOT_AVAIL: ;
|
`DRAMSLOT_AVAIL: ;
|
`DRAMSLOT_BUSY:
|
`DRAMSLOT_BUSY:
|
dram2 <= dram2 + !dram2_unc;
|
dram2 <= dram2 + !dram2_unc;
|
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 (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
|
// end
|
else begin
|
/* else begin
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2_load <= `FALSE;
|
dram2_load <= `FALSE;
|
end
|
end*/
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_REQBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMSLOT_HASBUS: ;
|
`DRAMREQ_READY: dram2 <= `DRAMSLOT_AVAIL;
|
`DRAMREQ_READY: dram2 <= `DRAMSLOT_AVAIL;
|
endcase
|
endcase
|
|
|
Line 8263... |
Line 7954... |
// iqentry_out[ dram0_id[`QBITS] ] <= `INV;
|
// iqentry_out[ dram0_id[`QBITS] ] <= `INV;
|
iqentry_state[ dram0_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram0_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
if (mem2_available && `NUM_MEM > 1 && dram1 == `DRAMSLOT_BUSY && dram1_store) begin
|
if (mem2_available && `NUM_MEM > 1 && dram1 == `DRAMSLOT_BUSY && dram1_store) begin
|
if ((alu0_v && (dram1_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram1_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE;
|
if ((alu0_v && (dram1_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram1_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE;
|
// iqentry_done[ dram1_id[`QBITS] ] <= `VAL;
|
|
// iqentry_out[ dram1_id[`QBITS] ] <= `INV;
|
|
iqentry_state[ dram1_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram1_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
if (mem3_available && `NUM_MEM > 2 && dram2 == `DRAMSLOT_BUSY && dram2_store) begin
|
if (mem3_available && `NUM_MEM > 2 && dram2 == `DRAMSLOT_BUSY && dram2_store) begin
|
if ((alu0_v && (dram2_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram2_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE;
|
if ((alu0_v && (dram2_id[`QBITS] == alu0_id[`QBITS])) || (alu1_v && (dram2_id[`QBITS] == alu1_id[`QBITS]))) panic <= `PANIC_MEMORYRACE;
|
// iqentry_done[ dram2_id[`QBITS] ] <= `VAL;
|
|
// iqentry_out[ dram2_id[`QBITS] ] <= `INV;
|
|
iqentry_state[ dram2_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram2_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
`endif
|
`endif
|
|
|
`ifdef HAS_WB
|
`ifdef HAS_WB
|
if (mem1_available && dram0==`DRAMSLOT_BUSY && dram0_store && !iqentry_stomp[dram0_id[`QBITS]]) begin
|
if (dram0==`DRAMSLOT_BUSY && dram0_store) begin
|
if (wbptr<`WB_DEPTH-1) begin
|
if (wbptr<`WB_DEPTH-1) begin
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0_instr[`INSTRUCTION_OP] <= `NOP;
|
dram0_instr[`INSTRUCTION_OP] <= `NOP;
|
wb_update(
|
wb_update(
|
dram0_id,
|
dram0_id,
|
Line 8293... |
Line 7980... |
// iqentry_done[ dram0_id[`QBITS] ] <= `VAL;
|
// iqentry_done[ dram0_id[`QBITS] ] <= `VAL;
|
// iqentry_out[ dram0_id[`QBITS] ] <= `INV;
|
// 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 (mem2_available && dram1==`DRAMSLOT_BUSY && dram1_store && !iqentry_stomp[dram1_id[`QBITS]] && `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
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1_instr[`INSTRUCTION_OP] <= `NOP;
|
dram1_instr[`INSTRUCTION_OP] <= `NOP;
|
wb_update(
|
wb_update(
|
dram1_id,
|
dram1_id,
|
Line 8308... |
Line 7995... |
fnDato(dram1_instr,dram1_data)
|
fnDato(dram1_instr,dram1_data)
|
);
|
);
|
iqentry_state[ dram1_id[`QBITS] ] <= IQS_DONE;
|
iqentry_state[ dram1_id[`QBITS] ] <= IQS_DONE;
|
end
|
end
|
end
|
end
|
else if (mem3_available && dram2==`DRAMSLOT_BUSY && dram2_store && !iqentry_stomp[dram2_id[`QBITS]] && `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
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2_instr[`INSTRUCTION_OP] <= `NOP;
|
dram2_instr[`INSTRUCTION_OP] <= `NOP;
|
wb_update(
|
wb_update(
|
dram2_id,
|
dram2_id,
|
Line 8369... |
Line 8056... |
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 && mem1_available && dram0==`DRAMSLOT_BUSY && dram0_rmw) begin
|
if (~|wb_v && dram0==`DRAMSLOT_BUSY && dram0_rmw) 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_exc <= `FLT_DBG;
|
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
|
iqentry_exc[dram0_id[`QBITS]] <= `FLT_DBG;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
Line 8397... |
Line 8084... |
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 <= B12;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && mem2_available && dram1==`DRAMSLOT_BUSY && dram1_rmw && `NUM_MEM > 1) begin
|
else if (~|wb_v && dram1==`DRAMSLOT_BUSY && dram1_rmw && `NUM_MEM > 1) 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_exc <= `FLT_DBG;
|
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
|
iqentry_exc[dram1_id[`QBITS]] <= `FLT_DBG;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
Line 8425... |
Line 8112... |
dat_o <= fnDato(dram1_instr,dram1_data);
|
dat_o <= fnDato(dram1_instr,dram1_data);
|
ol_o <= dram1_ol;
|
ol_o <= dram1_ol;
|
bstate <= B12;
|
bstate <= B12;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && mem3_available && dram2==`DRAMSLOT_BUSY && dram2_rmw && `NUM_MEM > 2) begin
|
else if (~|wb_v && dram2==`DRAMSLOT_BUSY && dram2_rmw && `NUM_MEM > 2) 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_exc <= `FLT_DBG;
|
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
|
iqentry_exc[dram2_id[`QBITS]] <= `FLT_DBG;
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
Line 8455... |
Line 8142... |
bstate <= B12;
|
bstate <= B12;
|
end
|
end
|
end
|
end
|
`ifndef HAS_WB
|
`ifndef HAS_WB
|
// Check write buffer enable ?
|
// Check write buffer enable ?
|
else if (mem1_available && dram0==`DRAMSLOT_BUSY && dram0_store) begin
|
else if (dram0==`DRAMSLOT_BUSY && dram0_store) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_smatch0) begin
|
if (dbg_smatch0) begin
|
dramA_v <= `TRUE;
|
dramA_v <= `TRUE;
|
dramA_id <= dram0_id;
|
dramA_id <= dram0_id;
|
dramA_exc <= `FLT_DBG;
|
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
|
iqentry_exc[dram0_id[`QBITS]] <= `FLT_DBG;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
Line 8473... |
Line 8160... |
if (!acki) begin
|
if (!acki) begin
|
dram0 <= `DRAMSLOT_HASBUS;
|
dram0 <= `DRAMSLOT_HASBUS;
|
dram0_instr[`INSTRUCTION_OP] <= `NOP;
|
dram0_instr[`INSTRUCTION_OP] <= `NOP;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
|
we <= `HIGH;
|
sel_o <= fnSelect(dram0_instr,dram0_addr);
|
sel_o <= fnSelect(dram0_instr,dram0_addr);
|
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;
|
end
|
end
|
// cr_o <= IsSWC(dram0_instr);
|
// cr_o <= IsSWC(dram0_instr);
|
end
|
end
|
end
|
end
|
else if (mem2_available && dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin
|
else if (dram1==`DRAMSLOT_BUSY && dram1_store && `NUM_MEM > 1) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_smatch1) begin
|
if (dbg_smatch1) begin
|
dramB_v <= `TRUE;
|
dramB_v <= `TRUE;
|
dramB_id <= dram1_id;
|
dramB_id <= dram1_id;
|
dramB_exc <= `FLT_DBG;
|
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
|
iqentry_exc[dram1_id[`QBITS]] <= `FLT_DBG;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
Line 8501... |
Line 8189... |
if (!acki) begin
|
if (!acki) begin
|
dram1 <= `DRAMSLOT_HASBUS;
|
dram1 <= `DRAMSLOT_HASBUS;
|
dram1_instr[`INSTRUCTION_OP] <= `NOP;
|
dram1_instr[`INSTRUCTION_OP] <= `NOP;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
|
we <= `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;
|
isStore <= TRUE;
|
isStore <= TRUE;
|
bstate <= B_StoreAck;
|
bstate <= B_StoreAck;
|
end
|
end
|
// cr_o <= IsSWC(dram0_instr);
|
// cr_o <= IsSWC(dram0_instr);
|
end
|
end
|
end
|
end
|
else if (mem3_available && dram2==`DRAMSLOT_BUSY && dram2_store && `NUM_MEM > 2) begin
|
else if (dram2==`DRAMSLOT_BUSY && dram2_store && `NUM_MEM > 2) begin
|
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
if (dbg_smatch2) begin
|
if (dbg_smatch2) begin
|
dramC_v <= `TRUE;
|
dramC_v <= `TRUE;
|
dramC_id <= dram2_id;
|
dramC_id <= dram2_id;
|
dramC_exc <= `FLT_DBG;
|
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
|
iqentry_exc[dram2_id[`QBITS]] <= `FLT_DBG;
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
Line 8529... |
Line 8218... |
if (!acki) begin
|
if (!acki) begin
|
dram2 <= `DRAMSLOT_HASBUS;
|
dram2 <= `DRAMSLOT_HASBUS;
|
dram2_instr[`INSTRUCTION_OP] <= `NOP;
|
dram2_instr[`INSTRUCTION_OP] <= `NOP;
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
|
we <= `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;
|
isStore <= TRUE;
|
isStore <= TRUE;
|
Line 8541... |
Line 8231... |
// 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 && mem1_available && !dram0_unc && dram0==`DRAMSLOT_REQBUS && dram0_load) begin
|
else if (~|wb_v && !dram0_unc && dram0==`DRAMSLOT_REQBUS && dram0_load) 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_exc <= `FLT_DBG;
|
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
|
iqentry_exc[dram0_id[`QBITS]] <= `FLT_DBG;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
Line 8559... |
Line 8249... |
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 && mem2_available && !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) 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_exc <= `FLT_DBG;
|
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
|
iqentry_exc[dram1_id[`QBITS]] <= `FLT_DBG;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
Line 8577... |
Line 8267... |
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 && mem3_available && !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) 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_exc <= `FLT_DBG;
|
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
|
iqentry_exc[dram2_id[`QBITS]] <= `FLT_DBG;
|
dram2 <= `DRAMSLOT_AVAIL;
|
dram2 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
begin
|
begin
|
Line 8595... |
Line 8285... |
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 && mem1_available && dram0_unc && dram0==`DRAMSLOT_BUSY && dram0_load) begin
|
else if (~|wb_v && dram0_unc && dram0==`DRAMSLOT_BUSY && dram0_load) 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_exc <= `FLT_DBG;
|
|
dramA_bus <= 64'h0;
|
dramA_bus <= 64'h0;
|
|
iqentry_exc[dram0_id[`QBITS]] <= `FLT_DBG;
|
dram0 <= `DRAMSLOT_AVAIL;
|
dram0 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
Line 8614... |
Line 8304... |
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;
|
bstate <= B_DLoadAck;
|
bstate <= B_DLoadAck;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && mem2_available && 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) 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_exc <= `FLT_DBG;
|
|
dramB_bus <= 64'h0;
|
dramB_bus <= 64'h0;
|
|
iqentry_exc[dram1_id[`QBITS]] <= `FLT_DBG;
|
dram1 <= `DRAMSLOT_AVAIL;
|
dram1 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
Line 8636... |
Line 8327... |
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;
|
bstate <= B_DLoadAck;
|
bstate <= B_DLoadAck;
|
end
|
end
|
end
|
end
|
else if (~|wb_v && mem3_available && 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) 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_exc <= `FLT_DBG;
|
|
dramC_bus <= 64'h0;
|
dramC_bus <= 64'h0;
|
|
iqentry_exc[dram2_id[`QBITS]] <= `FLT_DBG;
|
dram2 <= 2'd0;
|
dram2 <= 2'd0;
|
end
|
end
|
else
|
else
|
`endif
|
`endif
|
if (!acki) begin
|
if (!acki) begin
|
Line 8658... |
Line 8350... |
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);
|
ol_o <= dram2_ol;
|
ol_o <= dram2_ol;
|
|
dccnt <= 2'd0;
|
bstate <= B_DLoadAck;
|
bstate <= B_DLoadAck;
|
end
|
end
|
end
|
end
|
// Check for L2 cache miss
|
// Check for L2 cache miss
|
else if (~|wb_v && !ihitL2 && !acki) begin
|
else if (~|wb_v && !ihitL2 && !acki)
|
|
begin
|
cti_o <= 3'b001;
|
cti_o <= 3'b001;
|
bte_o <= 2'b00;//2'b01; // 4 beat burst wrap
|
bte_o <= 2'b00;//2'b01; // 4 beat burst wrap
|
cyc <= `HIGH;
|
cyc <= `HIGH;
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
sel_o <= 8'hFF;
|
sel_o <= 8'hFF;
|
icl_o <= `HIGH;
|
icl_o <= `HIGH;
|
iccnt <= 3'd0;
|
iccnt <= 3'd0;
|
|
icack <= 1'b0;
|
// adr_o <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
// adr_o <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
// L2_adr <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
// L2_adr <= icwhich ? {pc0[31:5],5'b0} : {pc1[31:5],5'b0};
|
vadr <= {pcr[7:0],L1_adr[AMSB:5],5'h0};
|
vadr <= {pcr[7:0],L1_adr[AMSB:5],5'h0};
|
ol_o <= ol[0];
|
`ifdef SUPPORT_SMT
|
|
`else
|
|
ol_o <= ol;//???
|
|
`endif
|
L2_adr <= {pcr[7:0],L1_adr[AMSB:5],5'h0};
|
L2_adr <= {pcr[7:0],L1_adr[AMSB:5],5'h0};
|
L2_xsel <= 1'b0;
|
L2_xsel <= 1'b0;
|
bstate <= B_ICacheAck;
|
bstate <= B_ICacheAck;
|
end
|
end
|
end
|
end
|
Line 8736... |
Line 8434... |
//iqentry_out[ dram2_id[`QBITS] ] <= `INV;
|
//iqentry_out[ dram2_id[`QBITS] ] <= `INV;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`endif
|
`endif
|
bstate <= B19;
|
bstate <= B_LSNAck;
|
end
|
end
|
end
|
end
|
|
|
B_DCacheLoadStart:
|
B_DCacheLoadStart:
|
if (~acki & ~cyc) begin // check for idle bus - it should be
|
if (~acki & ~cyc) begin // check for idle bus - it should be
|
Line 8776... |
Line 8474... |
endcase
|
endcase
|
end
|
end
|
|
|
// Data cache load terminal state
|
// Data cache load terminal state
|
B_DCacheLoadAck:
|
B_DCacheLoadAck:
|
if (ack_i|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
|
case(bwhich)
|
case(bwhich)
|
2'd0: if (err_i|rdv_i|tlb_miss) begin
|
2'd0: iqentry_exc[dram0_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
iqentry_exc[dram0_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : `FLT_DRF;
|
2'd1: iqentry_exc[dram1_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
end
|
2'd2: iqentry_exc[dram2_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : rdv_i ? `FLT_DRF : `FLT_NONE;
|
2'd1: if ((err_i|rdv_i|tlb_miss) && `NUM_MEM > 1) begin
|
|
iqentry_exc[dram1_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : `FLT_DRF;
|
|
end
|
|
2'd2: if ((err_i|rdv_i|tlb_miss) && `NUM_MEM > 2) begin
|
|
iqentry_exc[dram2_id[`QBITS]] <= tlb_miss ? `FLT_TLB : err_i ? `FLT_DBE : `FLT_DRF;
|
|
end
|
|
default: ;
|
default: ;
|
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;
|
bstate <= B_DCacheLoadAck;
|
|
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;
|
bstate <= B_DCacheLoadWait1;
|
end
|
end
|
end
|
end
|
|
|
B_DCacheLoadStb:
|
B_DCacheLoadStb:
|
begin
|
begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
bstate <= B_DCacheLoadAck;
|
bstate <= B_DCacheLoadAck;
|
end
|
end
|
B_DCacheLoadWait1: bstate <= B_DCacheLoadWait2;
|
B_DCacheLoadWait1: bstate <= B_DCacheLoadWait2;
|
B_DCacheLoadWait2: bstate <= B_DCacheLoadResetBusy;
|
B_DCacheLoadWait2: bstate <= B_DCacheLoadResetBusy;
|
//B_DCacheLoadWait3: bstate <= B_DCacheLoadResetBusy;
|
//B_DCacheLoadWait3: bstate <= B_DCacheLoadResetBusy;
|
B_DCacheLoadResetBusy: begin
|
|
// 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 all the 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:
|
|
begin
|
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 (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;
|
if (~ack_i) bstate <= BIDLE;
|
bstate <= BIDLE;
|
end
|
end
|
|
|
// Ack state for instruction cache load
|
// Ack state for instruction cache load
|
|
// Once the first ack is received in burst mode, further acks are not necessary
|
|
// as the core counts the number of data items. Occasionally missing acks were
|
|
// causing a problem.
|
B_ICacheAck:
|
B_ICacheAck:
|
if (ack_i|err_i|tlb_miss|exv_i) begin
|
if (acki|err_i|tlb_miss|exv_i|icack) begin
|
if (!bok_i) begin
|
if (!bok_i) begin
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
bstate <= B_ICacheNack2;
|
bstate <= B_ICacheNack2;
|
end
|
end
|
|
else
|
|
icack <= 1'b1;
|
errq <= errq | err_i;
|
errq <= errq | err_i;
|
exvq <= exvq | exv_i;
|
exvq <= exvq | exv_i;
|
// L1_en <= 9'h3 << {L2_xsel,L2_adr[4:3],1'b0};
|
|
// L1_wr0 <= `TRUE;
|
|
// L1_wr1 <= `TRUE;
|
|
// L1_adr <= L2_adr;
|
|
if (tlb_miss) begin
|
if (tlb_miss) begin
|
L2_rdat <= {18{`INSN_FLT_TLB}};
|
L1_dati <= {19{`INSN_FLT_TLB}};
|
wb_nack();
|
wb_nack();
|
icl_o <= `LOW;
|
icl_o <= `LOW;
|
bstate <= B_ICacheNack;
|
bstate <= B_ICacheNack;
|
end
|
end
|
else if (exv_i) begin
|
else if (exv_i) begin
|
L2_rdat <= {18{`INSN_FLT_EXF}};
|
L1_dati <= {19{`INSN_FLT_EXF}};
|
wb_nack();
|
wb_nack();
|
icl_o <= `LOW;
|
icl_o <= `LOW;
|
bstate <= B_ICacheNack;
|
bstate <= B_ICacheNack;
|
end
|
end
|
else if (err_i) begin
|
else if (err_i) begin
|
L2_rdat <= {18{`INSN_FLT_IBE}};
|
L1_dati <= {19{`INSN_FLT_IBE}};
|
wb_nack();
|
wb_nack();
|
icl_o <= `LOW;
|
icl_o <= `LOW;
|
bstate <= B_ICacheNack;
|
bstate <= B_ICacheNack;
|
end
|
end
|
else
|
else
|
case(iccnt)
|
case(iccnt)
|
3'd0: L2_rdat[63:0] <= dat_i;
|
3'd0: L1_dati[63:0] <= dat_i;
|
3'd1: L2_rdat[127:64] <= dat_i;
|
3'd1: L1_dati[127:64] <= dat_i;
|
3'd2: L2_rdat[191:128] <= dat_i;
|
3'd2: L1_dati[191:128] <= dat_i;
|
3'd3: L2_rdat[255:192] <= dat_i;
|
3'd3: L1_dati[255:192] <= dat_i;
|
3'd4: L2_rdat[297:256] <= {2'b00,dat_i[39:0]};
|
3'd4: L1_dati[305:256] <= {2'b00,dat_i[47:0]};
|
default: ;
|
default: L1_dati <= L1_dati;
|
endcase
|
endcase
|
//L2_rdat <= {dat_i[31:0],{4{dat_i}}};
|
|
iccnt <= iccnt + 3'd1;
|
iccnt <= iccnt + 3'd1;
|
//stb_o <= `LOW;
|
|
if (iccnt==3'd3)
|
if (iccnt==3'd3)
|
cti_o <= 3'b111;
|
cti_o <= 3'b111;
|
if (iccnt==3'd4) begin
|
if (iccnt==3'd4) begin
|
wb_nack();
|
wb_nack();
|
icl_o <= `LOW;
|
icl_o <= `LOW;
|
Line 8890... |
Line 8580... |
vadr[AMSB:3] <= vadr[AMSB:3] + 2'd1;
|
vadr[AMSB:3] <= vadr[AMSB:3] + 2'd1;
|
bstate <= B_ICacheAck;
|
bstate <= B_ICacheAck;
|
end
|
end
|
B_ICacheNack:
|
B_ICacheNack:
|
begin
|
begin
|
L1_wr0 <= `FALSE;
|
|
L1_wr1 <= `FALSE;
|
|
L1_wr2 <= `FALSE;
|
|
L1_en <= 9'h1FF;
|
|
L2_xsel <= 1'b0;
|
L2_xsel <= 1'b0;
|
if (~ack_i) begin
|
if (~acki) begin
|
icl_ctr <= icl_ctr + 40'd1;
|
icl_ctr <= icl_ctr + 40'd1;
|
bstate <= BIDLE;
|
bstate <= BIDLE;
|
L2_nxt <= TRUE;
|
L2_nxt <= TRUE;
|
|
vadr <= 32'hCCCCCCC8;
|
end
|
end
|
end
|
end
|
|
|
B12:
|
B12:
|
if (ack_i|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;
|
Line 8926... |
Line 8614... |
2'b00: dram0 <= `DRAMREQ_READY;
|
2'b00: dram0 <= `DRAMREQ_READY;
|
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 <= B19;
|
bstate <= B_LSNAck;
|
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 8954... |
Line 8642... |
end
|
end
|
end
|
end
|
|
|
// Regular load
|
// Regular load
|
B_DLoadAck:
|
B_DLoadAck:
|
if (ack_i|err_i|tlb_miss|rdv_i) begin
|
if (acki|err_i|tlb_miss|rdv_i) begin
|
wb_nack();
|
wb_nack();
|
sr_o <= `LOW;
|
sr_o <= `LOW;
|
xdati <= dat_i;
|
case(dccnt)
|
|
2'd0: xdati[63:0] <= dat_i;
|
|
2'd1: xdati[127:64] <= dat_i;
|
|
endcase
|
case(bwhich)
|
case(bwhich)
|
2'b00: begin
|
2'b00: begin
|
|
if (dram0_memsize==hexi) begin
|
|
if (dccnt==2'd1) begin
|
|
dram0 <= `DRAMREQ_READY;
|
|
iqentry_seg_base[dram0_id[`QBITS]] <= xdati[63:0];
|
|
iqentry_seg_acr[dram0_id[`QBITS]] <= dat_i;
|
|
end
|
|
else begin
|
|
dccnt <= dccnt + 2'd1;
|
|
cyc <= `HIGH;
|
|
sel_o <= 8'hFF;
|
|
vadr <= vadr + 64'd8;
|
|
bstate <= B_DLoadNack;
|
|
end
|
|
end
|
|
else
|
dram0 <= `DRAMREQ_READY;
|
dram0 <= `DRAMREQ_READY;
|
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;
|
Line 8973... |
Line 8679... |
dram2 <= `DRAMREQ_READY;
|
dram2 <= `DRAMREQ_READY;
|
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 <= B19;
|
bstate <= B_LSNAck;
|
|
end
|
|
B_DLoadNack:
|
|
if (~acki) begin
|
|
stb_o <= `HIGH;
|
|
bstate <= B_DLoadAck;
|
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)
|
Line 8986... |
Line 8697... |
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
|
end
|
end
|
B17: bstate <= B18;
|
B17: bstate <= B18;
|
B18: bstate <= B19;
|
B18: bstate <= B_LSNAck;
|
B19: if (~acki) begin
|
B_LSNAck:
|
sel_o <= 8'h00;
|
begin
|
bstate <= BIDLE;
|
bstate <= BIDLE;
|
StoreAck1 <= `FALSE;
|
StoreAck1 <= `FALSE;
|
isStore <= `FALSE;
|
isStore <= `FALSE;
|
end
|
end
|
B20:
|
B20:
|
if (~ack_i) 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;
|
end
|
end
|
B21:
|
B21:
|
if (~ack_i) begin
|
if (~acki) begin
|
stb_o <= `HIGH;
|
stb_o <= `HIGH;
|
bstate <= B12;
|
bstate <= B12;
|
end
|
end
|
default: bstate <= BIDLE;
|
default: bstate <= BIDLE;
|
endcase
|
endcase
|
|
|
|
|
if (!branchmiss) begin
|
if (!branchmiss) begin
|
case({fetchbuf0_v, fetchbuf1_v})
|
case({fetchbuf0_v, fetchbuf1_v})
|
2'b00: ;
|
2'b00: ;
|
2'b01:
|
2'b01:
|
if (canq1) begin
|
if (canq1) begin
|
Line 9128... |
Line 8840... |
for (i=0; i<QENTRIES; i=i+1)
|
for (i=0; i<QENTRIES; i=i+1)
|
$display("%c%c %d: %c%c%c%c %d %d %c%c %c %c%h %d %o %h %h %h %d %o %h %d %o %h %d %o %d:%h %h %d#",
|
$display("%c%c %d: %c%c%c%c %d %d %c%c %c %c%h %d %o %h %h %h %d %o %h %d %o %h %d %o %d:%h %h %d#",
|
(i[`QBITS]==heads[0])?"C":".",
|
(i[`QBITS]==heads[0])?"C":".",
|
(i[`QBITS]==tail0)?"Q":".",
|
(i[`QBITS]==tail0)?"Q":".",
|
i[`QBITS],
|
i[`QBITS],
|
iqentry_v[i] ? "v" : "-",
|
iqentry_state[i]==IQS_INVALID ? "-" :
|
|
iqentry_state[i]==IQS_QUEUED ? "Q" :
|
|
iqentry_state[i]==IQS_OUT ? "O" :
|
|
iqentry_state[i]==IQS_AGEN ? "A" :
|
|
iqentry_state[i]==IQS_MEM ? "M" :
|
|
iqentry_state[i]==IQS_DONE ? "D" :
|
|
iqentry_state[i]==IQS_CMT ? "C" : "?",
|
|
// iqentry_v[i] ? "v" : "-",
|
iqentry_iv[i] ? "I" : "-",
|
iqentry_iv[i] ? "I" : "-",
|
iqentry_done[i]?"d":"-",
|
iqentry_done[i]?"d":"-",
|
iqentry_out[i]?"o":"-",
|
iqentry_out[i]?"o":"-",
|
iqentry_bt[i],
|
iqentry_bt[i],
|
iqentry_memissue[i],
|
iqentry_memissue[i],
|
Line 9159... |
Line 8878... |
dram1_instr, dram1_id);
|
dram1_instr, dram1_id);
|
if (`NUM_MEM > 2)
|
if (`NUM_MEM > 2)
|
$display("%d %h %h %c%h %o #",
|
$display("%d %h %h %c%h %o #",
|
dram2, dram2_addr, dram2_data, (IsFlowCtrl(dram2_instr) ? 98 : (IsMem(dram2_instr)) ? 109 : 97),
|
dram2, dram2_addr, dram2_data, (IsFlowCtrl(dram2_instr) ? 98 : (IsMem(dram2_instr)) ? 109 : 97),
|
dram2_instr, dram2_id);
|
dram2_instr, dram2_id);
|
$display("%d %h %o %h #", dramA_v, dramA_bus, dramA_id, dramA_exc);
|
$display("%d %h %o #", dramA_v, dramA_bus, dramA_id);
|
if (`NUM_MEM > 1)
|
if (`NUM_MEM > 1)
|
$display("%d %h %o %h #", dramB_v, dramB_bus, dramB_id, dramB_exc);
|
$display("%d %h %o #", dramB_v, dramB_bus, dramB_id);
|
if (`NUM_MEM > 2)
|
if (`NUM_MEM > 2)
|
$display("%d %h %o %h #", dramC_v, dramC_bus, dramC_id, dramC_exc);
|
$display("%d %h %o #", dramC_v, dramC_bus, dramC_id);
|
$display("ALU");
|
$display("ALU");
|
$display("%d %h %h %h %c%h %o %h #",
|
$display("%d %h %h %h %c%h %o %h #",
|
alu0_dataready, alu0_argI, alu0_argA, alu0_argB,
|
alu0_dataready, alu0_argI, alu0_argA, alu0_argB,
|
(IsFlowCtrl(alu0_instr) ? 98 : IsMem(alu0_instr) ? 109 : 97),
|
(IsFlowCtrl(alu0_instr) ? 98 : IsMem(alu0_instr) ? 109 : 97),
|
alu0_instr, alu0_sourceid, alu0_pc);
|
alu0_instr, alu0_sourceid, alu0_pc);
|
Line 9390... |
Line 9109... |
end
|
end
|
// otherwise, it is the last instruction in the queue that has been mispredicted ... do nothing
|
// otherwise, it is the last instruction in the queue that has been mispredicted ... do nothing
|
end
|
end
|
end
|
end
|
*/
|
*/
|
|
assign exc_o = iqentry_exc[heads[0]][7:0];
|
|
|
// Update the write buffer.
|
// Update the write buffer.
|
task wb_update;
|
task wb_update;
|
input [`QBITS] id;
|
input [`QBITS] id;
|
input rmw;
|
input rmw;
|
Line 9551... |
Line 9271... |
iqentry_fpu [nn] <= bus[`IB_FPU];
|
iqentry_fpu [nn] <= bus[`IB_FPU];
|
iqentry_fc [nn] <= bus[`IB_FC];
|
iqentry_fc [nn] <= bus[`IB_FC];
|
iqentry_canex[nn] <= bus[`IB_CANEX];
|
iqentry_canex[nn] <= bus[`IB_CANEX];
|
iqentry_loadv[nn] <= bus[`IB_LOADV];
|
iqentry_loadv[nn] <= bus[`IB_LOADV];
|
iqentry_load [nn] <= bus[`IB_LOAD];
|
iqentry_load [nn] <= bus[`IB_LOAD];
|
|
iqentry_loadseg[nn]<= bus[`IB_LOADSEG];
|
iqentry_preload[nn]<= bus[`IB_PRELOAD];
|
iqentry_preload[nn]<= bus[`IB_PRELOAD];
|
iqentry_store[nn] <= bus[`IB_STORE];
|
iqentry_store[nn] <= bus[`IB_STORE];
|
iqentry_push [nn] <= bus[`IB_PUSH];
|
iqentry_push [nn] <= bus[`IB_PUSH];
|
iqentry_oddball[nn] <= bus[`IB_ODDBALL];
|
iqentry_oddball[nn] <= bus[`IB_ODDBALL];
|
iqentry_memsz[nn] <= bus[`IB_MEMSZ];
|
iqentry_memsz[nn] <= bus[`IB_MEMSZ];
|
Line 9570... |
Line 9291... |
iqentry_jmp [nn] <= bus[`IB_JMP];
|
iqentry_jmp [nn] <= bus[`IB_JMP];
|
iqentry_br [nn] <= bus[`IB_BR];
|
iqentry_br [nn] <= bus[`IB_BR];
|
iqentry_sync [nn] <= bus[`IB_SYNC];
|
iqentry_sync [nn] <= bus[`IB_SYNC];
|
iqentry_fsync[nn] <= bus[`IB_FSYNC];
|
iqentry_fsync[nn] <= bus[`IB_FSYNC];
|
iqentry_rfw [nn] <= bus[`IB_RFW];
|
iqentry_rfw [nn] <= bus[`IB_RFW];
|
`ifdef SUPPORT_PREDICATION
|
|
iqentry_prfw [nn] <= bus[`IB_PRFW];
|
|
`endif
|
|
iqentry_we [nn] <= bus[`IB_WE];
|
iqentry_we [nn] <= bus[`IB_WE];
|
end
|
end
|
endtask
|
endtask
|
|
|
task setinsn;
|
task setinsn;
|
Line 9700... |
Line 9418... |
iqentry_res [tail] <= `ZERO;
|
iqentry_res [tail] <= `ZERO;
|
iqentry_instr[tail] <= IsVLS(fetchbuf0_instr) ? (vm[fnM2(fetchbuf0_instr)] ? fetchbuf0_instr : `NOP_INSN) : fetchbuf0_instr;
|
iqentry_instr[tail] <= IsVLS(fetchbuf0_instr) ? (vm[fnM2(fetchbuf0_instr)] ? fetchbuf0_instr : `NOP_INSN) : fetchbuf0_instr;
|
iqentry_insln[tail] <= fetchbuf0_insln;
|
iqentry_insln[tail] <= fetchbuf0_insln;
|
iqentry_fc [tail] <= `INV;
|
iqentry_fc [tail] <= `INV;
|
iqentry_mem [tail] <= `INV;
|
iqentry_mem [tail] <= `INV;
|
|
iqentry_memissue[tail] <= `INV;
|
iqentry_alu [tail] <= `INV;
|
iqentry_alu [tail] <= `INV;
|
iqentry_fpu [tail] <= `INV;
|
iqentry_fpu [tail] <= `INV;
|
iqentry_load [tail] <= `INV;
|
iqentry_load [tail] <= `INV;
|
iqentry_pt [tail] <= predict_taken0;
|
iqentry_pt [tail] <= predict_taken0;
|
// If the previous instruction was a hardware interrupt and this instruction is a hardware interrupt
|
// If the previous instruction was a hardware interrupt and this instruction is a hardware interrupt
|
Line 9766... |
Line 9485... |
iqentry_res [tail] <= `ZERO;
|
iqentry_res [tail] <= `ZERO;
|
iqentry_instr[tail] <= IsVLS(fetchbuf1_instr) ? (vm[fnM2(fetchbuf1_instr)] ? fetchbuf1_instr : `NOP_INSN) : fetchbuf1_instr;
|
iqentry_instr[tail] <= IsVLS(fetchbuf1_instr) ? (vm[fnM2(fetchbuf1_instr)] ? fetchbuf1_instr : `NOP_INSN) : fetchbuf1_instr;
|
iqentry_insln[tail] <= fetchbuf1_insln;
|
iqentry_insln[tail] <= fetchbuf1_insln;
|
iqentry_fc [tail] <= `INV;
|
iqentry_fc [tail] <= `INV;
|
iqentry_mem [tail] <= `INV;
|
iqentry_mem [tail] <= `INV;
|
|
iqentry_memissue[tail] <= `INV;
|
iqentry_alu [tail] <= `INV;
|
iqentry_alu [tail] <= `INV;
|
iqentry_fpu [tail] <= `INV;
|
iqentry_fpu [tail] <= `INV;
|
iqentry_load [tail] <= `INV;
|
iqentry_load [tail] <= `INV;
|
iqentry_pt [tail] <= predict_taken1;
|
iqentry_pt [tail] <= predict_taken1;
|
// If queing 2nd instruction must read from first
|
// If queing 2nd instruction must read from first
|
Line 9820... |
Line 9540... |
setinsn1(tail,id2_bus);
|
setinsn1(tail,id2_bus);
|
`endif
|
`endif
|
end
|
end
|
endtask
|
endtask
|
|
|
// This task takes care of commits for things other than the register file.
|
task exc;
|
task oddball_commit;
|
|
input v;
|
|
input [`QBITS] head;
|
input [`QBITS] head;
|
input [1:0] which;
|
input thread;
|
reg thread;
|
input [7:0] causecd;
|
begin
|
begin
|
thread = iqentry_thrd[head];
|
|
if (v) begin
|
|
if (|iqentry_exc[head]) begin
|
|
excmiss <= TRUE;
|
excmiss <= TRUE;
|
`ifdef SUPPORT_SMT
|
`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];
|
excthrd <= iqentry_thrd[head];
|
badaddr[{thread,2'd0}] <= iqentry_ma[head];
|
badaddr[{thread,2'd0}] <= iqentry_ma[head];
|
Line 9851... |
Line 9566... |
ol_stack[thread] <= {ol_stack[thread][13:0],ol[thread]};
|
ol_stack[thread] <= {ol_stack[thread][13:0],ol[thread]};
|
dl_stack[thread] <= {dl_stack[thread][13:0],dl[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,iqentry_exc[head]};
|
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};
|
excmisspc <= {tvec[3'd0][AMSB:8],1'b0,ol,5'h00};
|
Line 9875... |
Line 9590... |
ol_stack <= {ol_stack[13:0],ol};
|
ol_stack <= {ol_stack[13:0],ol};
|
dl_stack <= {dl_stack[13:0],dl};
|
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,iqentry_exc[head]};
|
cause[3'd0] <= {8'd0,causecd};
|
mstatus[5:4] <= 2'd0;
|
mstatus[5:4] <= 2'd0;
|
mstatus[13:6] <= 8'h00;
|
mstatus[13:6] <= 8'h00;
|
mstatus[19:14] <= `EXC_RGS;
|
mstatus[19:14] <= `EXC_RGS;
|
`endif
|
`endif
|
wb_en <= `TRUE;
|
wb_en <= `TRUE;
|
Line 9888... |
Line 9603... |
`ifdef SUPPORT_DBG
|
`ifdef SUPPORT_DBG
|
dbg_ctrl[62:55] <= {dbg_ctrl[61:55],dbg_ctrl[63]};
|
dbg_ctrl[62:55] <= {dbg_ctrl[61:55],dbg_ctrl[63]};
|
dbg_ctrl[63] <= FALSE;
|
dbg_ctrl[63] <= FALSE;
|
`endif
|
`endif
|
end
|
end
|
|
endtask
|
|
|
|
// This task takes care of commits for things other than the register file.
|
|
task oddball_commit;
|
|
input v;
|
|
input [`QBITS] head;
|
|
input [1:0] which;
|
|
reg thread;
|
|
begin
|
|
thread = iqentry_thrd[head];
|
|
if (v) begin
|
|
if (|iqentry_exc[head]) begin
|
|
exc(head,thread,iqentry_exc[head]);
|
|
end
|
else
|
else
|
case(iqentry_instr[head][`INSTRUCTION_OP])
|
case(iqentry_instr[head][`INSTRUCTION_OP])
|
`ifdef SUPPORT_PREDICATION
|
|
`CMPI: pregs[{rgs,iqentry_tgt[head][3:0]}] <= which==2'd1 ? cmt1nyb[iqentry_tgt[head][3:0]] : cmt0nyb[iqentry_tgt[head][3:0]];//commit_bus[3:0];
|
|
`endif
|
|
|
|
`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;
|
Line 9989... |
Line 9714... |
8'b00101111: vl <= iqentry_res[head];
|
8'b00101111: vl <= iqentry_res[head];
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`R2:
|
`R2:
|
case(iqentry_instr[head][`INSTRUCTION_S2])
|
case(iqentry_instr[head][`INSTRUCTION_S2])
|
`ifdef SUPPORT_PREDICATION
|
|
`CMP: pregs[{rgs,iqentry_tgt[head][3:0]}] <= which==2'd1 ? cmt1nyb[iqentry_tgt[head][3:0]] : cmt0nyb[iqentry_tgt[head][3:0]];//commit_bus[3:0];
|
|
`endif
|
|
`R1: case(iqentry_instr[head][20:16])
|
`R1: case(iqentry_instr[head][20:16])
|
`CHAIN_OFF: cr0[18] <= 1'b0;
|
`CHAIN_OFF: cr0[18] <= 1'b0;
|
`CHAIN_ON: cr0[18] <= 1'b1;
|
`CHAIN_ON: cr0[18] <= 1'b1;
|
//`SETWB: wbrcd[pcr[5:0]] <= 1'b1;
|
//`SETWB: wbrcd[pcr[5:0]] <= 1'b1;
|
default: ;
|
default: ;
|
Line 10010... |
Line 9732... |
`else
|
`else
|
`SEI: mstatus[3:0] <= iqentry_res[head][3:0]; // S1
|
`SEI: mstatus[3:0] <= iqentry_res[head][3:0]; // S1
|
`endif
|
`endif
|
`RTI: begin
|
`RTI: begin
|
excmiss <= TRUE;
|
excmiss <= TRUE;
|
`ifdef SUPPORT_SMT
|
|
excmisspc <= epc0[thread];
|
|
excthrd <= thread;
|
excthrd <= thread;
|
|
excmisspc <= iqentry_ma[head];
|
|
`ifdef SUPPORT_SMT
|
|
// excmisspc <= epc0[thread];
|
mstatus[thread][3:0] <= im_stack[thread][3:0];
|
mstatus[thread][3:0] <= im_stack[thread][3:0];
|
mstatus[thread][5:4] <= ol_stack[thread][1:0];
|
mstatus[thread][5:4] <= ol_stack[thread][1:0];
|
mstatus[thread][21:20] <= dl_stack[thread][1:0];
|
mstatus[thread][21:20] <= dl_stack[thread][1:0];
|
mstatus[thread][13:6] <= pl_stack[thread][7:0];
|
mstatus[thread][13:6] <= pl_stack[thread][7:0];
|
mstatus[thread][19:14] <= rs_stack[thread][5:0];
|
mstatus[thread][19:14] <= rs_stack[thread][5:0];
|
Line 10034... |
Line 9757... |
epc5[thread] <= epc6[thread];
|
epc5[thread] <= epc6[thread];
|
epc6[thread] <= epc7[thread];
|
epc6[thread] <= epc7[thread];
|
epc7[thread] <= epc8[thread];
|
epc7[thread] <= epc8[thread];
|
epc8[thread] <= {tvec[0][AMSB:8], 1'b0, ol[thread], 5'h0};
|
epc8[thread] <= {tvec[0][AMSB:8], 1'b0, ol[thread], 5'h0};
|
`else
|
`else
|
excmisspc <= epc0;
|
// excmisspc <= epc0;
|
excthrd <= thread;
|
|
mstatus[3:0] <= im_stack[3:0];
|
mstatus[3:0] <= im_stack[3:0];
|
mstatus[5:4] <= ol_stack[1:0];
|
mstatus[5:4] <= ol_stack[1:0];
|
mstatus[21:20] <= dl_stack[1:0];
|
mstatus[21:20] <= dl_stack[1:0];
|
mstatus[13:6] <= pl_stack[7:0];
|
mstatus[13:6] <= pl_stack[7:0];
|
mstatus[19:14] <= rs_stack[5:0];
|
mstatus[19:14] <= rs_stack[5:0];
|
Line 10269... |
Line 9991... |
`CSR_DBU: dat <= dbu;
|
`CSR_DBU: dat <= dbu;
|
`CSR_SBL: dat <= sbl;
|
`CSR_SBL: dat <= sbl;
|
`CSR_SBU: dat <= sbu;
|
`CSR_SBU: dat <= sbu;
|
`CSR_ENU: dat <= en;
|
`CSR_ENU: dat <= en;
|
`endif
|
`endif
|
`ifdef SUPPORT_PREDICATION
|
|
`CSR_PREGS: read_pregs(dat);
|
|
`endif
|
|
`CSR_Q_CTR: dat <= iq_ctr;
|
`CSR_Q_CTR: dat <= iq_ctr;
|
`CSR_BM_CTR: dat <= bm_ctr;
|
`CSR_BM_CTR: dat <= bm_ctr;
|
`CSR_ICL_CTR: dat <= icl_ctr;
|
`CSR_ICL_CTR: dat <= icl_ctr;
|
`CSR_IRQ_CTR: dat <= irq_ctr;
|
`CSR_IRQ_CTR: dat <= irq_ctr;
|
`CSR_TIME: dat <= wc_times;
|
`CSR_TIME: dat <= wc_times;
|
Line 10400... |
Line 10119... |
`CSR_DBU: du_barrier[brgs] <= dat;
|
`CSR_DBU: du_barrier[brgs] <= dat;
|
`CSR_SBL: sl_barrier[brgs] <= dat;
|
`CSR_SBL: sl_barrier[brgs] <= dat;
|
`CSR_SBU: su_barrier[brgs] <= dat;
|
`CSR_SBU: su_barrier[brgs] <= dat;
|
`CSR_ENU: en_barrier[brgs] <= dat;
|
`CSR_ENU: en_barrier[brgs] <= dat;
|
`endif
|
`endif
|
`ifdef SUPPORT_PREDICATION
|
|
`CSR_PREGS: write_pregs(dat);
|
|
`endif
|
|
`CSR_TIME: begin
|
`CSR_TIME: begin
|
ld_time <= 6'h3f;
|
ld_time <= 6'h3f;
|
wc_time_dat <= dat;
|
wc_time_dat <= dat;
|
end
|
end
|
`CSR_CODEBUF: codebuf[csrno[5:0]] <= dat;
|
`CSR_CODEBUF: codebuf[csrno[5:0]] <= dat;
|
Line 10460... |
Line 10176... |
endtask
|
endtask
|
|
|
task tDram0Issue;
|
task tDram0Issue;
|
input [`QBITSP1] n;
|
input [`QBITSP1] n;
|
begin
|
begin
|
|
if (iqentry_state[n]==IQS_AGEN) begin
|
// dramA_v <= `INV;
|
// dramA_v <= `INV;
|
dram0 <= `DRAMSLOT_BUSY;
|
dram0 <= `DRAMSLOT_BUSY;
|
dram0_id <= { 1'b1, n[`QBITS] };
|
dram0_id <= { 1'b1, n[`QBITS] };
|
dram0_instr <= iqentry_instr[n];
|
dram0_instr <= iqentry_instr[n];
|
dram0_rmw <= iqentry_rmw[n];
|
dram0_rmw <= iqentry_rmw[n];
|
dram0_preload <= iqentry_preload[n];
|
dram0_preload <= iqentry_preload[n];
|
dram0_tgt <= iqentry_tgt[n];
|
dram0_tgt <= iqentry_tgt[n];
|
|
if (iqentry_imm[n] & iqentry_push[n])
|
|
dram0_data <= iqentry_a0[n];
|
|
else
|
dram0_data <= iqentry_a2[n];
|
dram0_data <= iqentry_a2[n];
|
dram0_addr <= iqentry_ma[n];
|
dram0_addr <= iqentry_ma[n];
|
// if (ol[iqentry_thrd[n]]==`OL_USER)
|
|
// dram0_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0};
|
|
// else
|
|
dram0_unc <= iqentry_ma[n][31:20]==12'hFFD || !dce || iqentry_loadv[n];
|
dram0_unc <= iqentry_ma[n][31:20]==12'hFFD || !dce || iqentry_loadv[n];
|
dram0_memsize <= iqentry_memsz[n];
|
dram0_memsize <= iqentry_memsz[n];
|
dram0_load <= iqentry_load[n];
|
dram0_load <= iqentry_load[n];
|
|
dram0_loadseg <= iqentry_loadseg[n];
|
dram0_store <= iqentry_store[n];
|
dram0_store <= iqentry_store[n];
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
dram0_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]];
|
dram0_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]];
|
`else
|
`else
|
dram0_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol : dl;
|
dram0_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol : dl;
|
Line 10488... |
Line 10206... |
// This is used for the load and compare instructions.
|
// This is used for the load and compare instructions.
|
// must reset the a1 source too.
|
// must reset the a1 source too.
|
//iqentry_a1_v[n] <= `INV;
|
//iqentry_a1_v[n] <= `INV;
|
iqentry_state[n] <= IQS_MEM;
|
iqentry_state[n] <= IQS_MEM;
|
end
|
end
|
|
end
|
endtask
|
endtask
|
|
|
task tDram1Issue;
|
task tDram1Issue;
|
input [`QBITSP1] n;
|
input [`QBITSP1] n;
|
begin
|
begin
|
dramB_v <= `INV;
|
if (iqentry_state[n]==IQS_AGEN) begin
|
|
// dramB_v <= `INV;
|
dram1 <= `DRAMSLOT_BUSY;
|
dram1 <= `DRAMSLOT_BUSY;
|
dram1_id <= { 1'b1, n[`QBITS] };
|
dram1_id <= { 1'b1, n[`QBITS] };
|
dram1_instr <= iqentry_instr[n];
|
dram1_instr <= iqentry_instr[n];
|
dram1_rmw <= iqentry_rmw[n];
|
dram1_rmw <= iqentry_rmw[n];
|
dram1_preload <= iqentry_preload[n];
|
dram1_preload <= iqentry_preload[n];
|
dram1_tgt <= iqentry_tgt[n];
|
dram1_tgt <= iqentry_tgt[n];
|
|
if (iqentry_imm[n] & iqentry_push[n])
|
|
dram1_data <= iqentry_a0[n];
|
|
else
|
dram1_data <= iqentry_a2[n];
|
dram1_data <= iqentry_a2[n];
|
dram1_addr <= iqentry_ma[n];
|
dram1_addr <= iqentry_ma[n];
|
// if (ol[iqentry_thrd[n]]==`OL_USER)
|
// if (ol[iqentry_thrd[n]]==`OL_USER)
|
// dram1_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0};
|
// dram1_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0};
|
// else
|
// else
|
dram1_unc <= iqentry_ma[n][31:20]==12'hFFD || !dce || iqentry_loadv[n];
|
dram1_unc <= iqentry_ma[n][31:20]==12'hFFD || !dce || iqentry_loadv[n];
|
dram1_memsize <= iqentry_memsz[n];
|
dram1_memsize <= iqentry_memsz[n];
|
dram1_load <= iqentry_load[n];
|
dram1_load <= iqentry_load[n];
|
|
dram1_loadseg <= iqentry_loadseg[n];
|
dram1_store <= iqentry_store[n];
|
dram1_store <= iqentry_store[n];
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
dram1_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]];
|
dram1_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]];
|
`else
|
`else
|
dram1_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol : dl;
|
dram1_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol : dl;
|
`endif
|
`endif
|
//iqentry_a1_v[n] <= `INV;
|
//iqentry_a1_v[n] <= `INV;
|
iqentry_state[n] <= IQS_MEM;
|
iqentry_state[n] <= IQS_MEM;
|
end
|
end
|
|
end
|
endtask
|
endtask
|
|
|
task tDram2Issue;
|
task tDram2Issue;
|
input [`QBITSP1] n;
|
input [`QBITSP1] n;
|
begin
|
begin
|
dramC_v <= `INV;
|
if (iqentry_state[n]==IQS_AGEN) begin
|
|
// dramC_v <= `INV;
|
dram2 <= `DRAMSLOT_BUSY;
|
dram2 <= `DRAMSLOT_BUSY;
|
dram2_id <= { 1'b1, n[`QBITS] };
|
dram2_id <= { 1'b1, n[`QBITS] };
|
dram2_instr <= iqentry_instr[n];
|
dram2_instr <= iqentry_instr[n];
|
dram2_rmw <= iqentry_rmw[n];
|
dram2_rmw <= iqentry_rmw[n];
|
dram2_preload <= iqentry_preload[n];
|
dram2_preload <= iqentry_preload[n];
|
dram2_tgt <= iqentry_tgt[n];
|
dram2_tgt <= iqentry_tgt[n];
|
|
if (iqentry_imm[n] & iqentry_push[n])
|
|
dram2_data <= iqentry_a0[n];
|
|
else
|
dram2_data <= iqentry_a2[n];
|
dram2_data <= iqentry_a2[n];
|
dram2_addr <= iqentry_ma[n];
|
dram2_addr <= iqentry_ma[n];
|
// if (ol[iqentry_thrd[n]]==`OL_USER)
|
// if (ol[iqentry_thrd[n]]==`OL_USER)
|
// dram2_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0};
|
// dram2_seg <= (iqentry_Ra[n]==5'd30 || iqentry_Ra[n]==5'd31) ? {ss[iqentry_thrd[n]],13'd0} : {ds[iqentry_thrd[n]],13'd0};
|
// else
|
// else
|
dram2_unc <= iqentry_ma[n][31:20]==12'hFFD || !dce || iqentry_loadv[n];
|
dram2_unc <= iqentry_ma[n][31:20]==12'hFFD || !dce || iqentry_loadv[n];
|
dram2_memsize <= iqentry_memsz[n];
|
dram2_memsize <= iqentry_memsz[n];
|
dram2_load <= iqentry_load[n];
|
dram2_load <= iqentry_load[n];
|
|
dram2_loadseg <= iqentry_loadseg[n];
|
dram2_store <= iqentry_store[n];
|
dram2_store <= iqentry_store[n];
|
`ifdef SUPPORT_SMT
|
`ifdef SUPPORT_SMT
|
dram2_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]];
|
dram2_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol[iqentry_thrd[n]] : dl[iqentry_thrd[n]];
|
`else
|
`else
|
dram2_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol : dl;
|
dram2_ol <= (iqentry_Ra[n][4:0]==5'd31 || iqentry_Ra[n][4:0]==5'd30) ? ol : dl;
|
`endif
|
`endif
|
//iqentry_a1_v[n] <= `INV;
|
//iqentry_a1_v[n] <= `INV;
|
iqentry_state[n] <= IQS_MEM;
|
iqentry_state[n] <= IQS_MEM;
|
end
|
end
|
|
end
|
endtask
|
endtask
|
|
|
task wb_nack;
|
task wb_nack;
|
begin
|
begin
|
cti_o <= 3'b000;
|
cti_o <= 3'b000;
|
bte_o <= 2'b00;
|
bte_o <= 2'b00;
|
cyc <= `LOW;
|
cyc <= `LOW;
|
stb_o <= `LOW;
|
stb_o <= `LOW;
|
we <= `LOW;
|
we <= `LOW;
|
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
|
// vadr <= 32'hCCCCCCCC;
|
end
|
end
|
endtask
|
endtask
|
|
|
endmodule
|
endmodule
|
|
|