JBUFE dc_dtv_din_gate1 (.O(dc_dtv_din_int1), .A(dc_dtv_din_int));
JBUFE dc_dtv_din_gate2 (.O(dc_dtv_din_int2), .A(dc_dtv_din_int1));
JBUFE dc_dtv_din_gate3 (.O(dc_dtv_din), .A(dc_dtv_din_int2));
assign dc_dtv_din_int =
// ASI tag write 0xe takes priority
(dc_asi_store_tag_w & dcc_stat) ?
iu_dout[0] :
(~bad_st_inv_e & ~dc_flush_op_w
& ~(dcc_st_stat & ~cached)
& ~(dcc_st_stat_wait & mm_dabort)
& ~parity_error_d1
& dt_be_vb);
// dc_miss is the main signal to tell MMU to start processing a ld/st
// miss
// wire dc_miss = (
//dc_miss_sustain |
// (dcc_idle & ~iu_in_trap_d1 & (ld_op_w | st_op_w) & ~bad_st_inv_hold
// & ( (normal_asi_w & (~dt_hit_w | ~mm_dcache_enbl))
// | (~normal_asi_w & ~nomiss_asi_w)
// ))) & ~possible_bad_mem_op_dt_hit_w ;
// Timing fix for path dt_hit_w -> dc_miss;
// This logic is in the mmu _cntrl now.
wire dc_miss_or_part = (dc_miss_sustain |
(dcc_miss_idle & ~iu_in_trap_d1 & (ld_op_w | st_op_w)
& ~bad_st_inv_hold & ~perr_in_atomic_wr
& ((normal_asi_w & ~mm_dcache_enbl) | (~normal_asi_w & ~nomiss_asi_w))))
& ~possible_bad_mem_op_dt_hit_w;
wire dc_miss_and_part = (dcc_miss_idle & ~iu_in_trap_d1
& (ld_op_w | st_op_w) & ~perr_in_atomic_wr
& ~bad_st_inv_hold & normal_asi_w) & ~possible_bad_mem_op_dt_hit_w
& ~(dt_be_vb_d1)
& ~dc_standby_w;
assign dc_miss = dc_miss_or_part | (~dt_hit_w & dc_miss_and_part);
// Mask dc_miss during parity invalidate
Mflipflop_r dt_be_vb_d1_ff (dt_be_vb_d1, dt_be_vb, ~ss_reset, ss_clock) ;
// dc_miss_sustain is active in 'dc_miss + 1' cycle (for timing fix)
// Hard coded path, logically its is (see below):
// assign dc_miss_sustain = dcc_stat_wait ;
//
JBUFE dc_miss_sustain_gate2(.A(dcc_stat_wait), .O(dc_miss_sustain));
// Replace iu_held with 'fast_hld_terms' in this equation also,
// iu_held is not needed because, the only 2 times dtag_in is
// used is for a store or a tag match. Both these times we are
// guaranteed that the _w stage dva will be used.
// Mux for dtag in ..
wire [31:`log2_dcachesize]
dva_w_in
= (fast_hld_terms) ? iu_dva_w[31:`log2_dcachesize]
: iu_dva_e[31:`log2_dcachesize] ;
//## Fixed hold violation of 0.1.04ns in dt_din, using 3 [JBUFDA] in series.
//## 2 are reused from below.
wire dt_cntx_in_sel_int
, dt_cntx_in_sel
;
wire dt_din_sel
;
JBUFDA dt_din_gate1 (.O(dt_din_sel), .A(dt_cntx_in_sel));
// ASI writes to tags
assign dt_din [31:`log2_dcachesize] =
(dt_din_sel) ? iu_dout[31:`log2_dcachesize] : dva_w_in [31:`log2_dcachesize];
//## Fixed hold violation of 0.42 in dc_dtv_din, using 2 [JBUFDA] in series.
JBUFDA dt_cntx_in_gate1
(.O(dt_cntx_in_sel_int), .A((dc_asi_store_tag_w & dcc_stat)));
JBUFDA dt_cntx_in_gate2 (.O(dt_cntx_in_sel), .A(dt_cntx_in_sel_int));
assign dt_cntx_in [7:0] = (dt_cntx_in_sel) ? iu_dout[11:4] : cxr[7:0] ;
// Switch D$ input bus on cache fills and in non-cached fills..
assign dc_di[63:0] = (fill_write_e |dcc_ld_nc_wait)
? cache_fill[63:0] : iu_dout[63:0];
// Random logic for streaming ..
Mflipflop_32 dva_reg (iu_dva_w[31:0], iu_dva_e[31:0], ss_clock, iu_held);
// Used to invalidate DTags on trapped Stores
wire [12:4] dva_r
;
Mflipflop_9 dva_r_reg (dva_r[12:4], iu_dva_w[12:4],
ss_clock, iu_held);
// Hold the dmar register throughout a miss seq. when D$ cntr is not idle.
Mflipflop_10 dmar_reg (dmar[12:3], iu_dva_w[12:3], ss_clock, ~dcc_idle);
// dcc_state sequence is due to a miss on a store
Mflipflop dcc_st_miss_ff (dcc_st_miss, (st_op_w & ~ld_op_w) | atomic_op_r,
ss_clock, ~dcc_idle);
// Mux for D$ address in ..
assign fill_dw = dmar[3] ^ ~dcc_fill_wait ;
/////////////////////////////////////////////////////////////////////////////
// Original equation below.
// assign dc_dva_e[`dc_msb:3] =
// (store_in_trap_w) ? iu_dva_w[`dc_msb:3] : (
// fill_write_e ? ({dmar[`dc_msb:4], fill_dw}) : (
// iu_held ? iu_dva_w[`dc_msb:3] : iu_dva_e[`dc_msb:3])) ;
wire [`dc_msb:3] dc_dva_e_zero
=
(bad_st_inv_e) ? {dva_r[`dc_msb:4],1'b0} : (
(fill_write_e | parity_error_d1) ?
({dmar[`dc_msb:4], fill_dw}) : iu_dva_e[`dc_msb:3]);
wire [`dc_msb:3] dc_dva_e_one
=
(bad_st_inv_e) ? {dva_r[`dc_msb:4],1'b0} : (
(fill_write_e | parity_error_d1) ?
({dmar[`dc_msb:4], fill_dw}) : iu_dva_w[`dc_msb:3]);
// Hand code this last mux(see logic below) to make iu_held -> dc_dva_e fast.
// assign dc_dva_e[`dc_msb:3] = (iu_held) ?
// dc_dva_e_one[`dc_msb:3] : dc_dva_e_zero[`dc_msb:3];
// Timing fix for dc_dva, Cannot switch the address bus from _w -> _e
// fast enough during certain holds, (holds due to it_hit_f).
// But there are cases (actually 2) during which this is possible,
// One is during I$ streaming, and the second due to D$ streaming.
// To patch up these 2 cases, we detect these conditions using:
// (~fast_hld_terms & iu_held & (ld_op_w|st_op_w))
// and then we keep on holding, (using dwait_w, which controls
// 'fast_hld_terms', untill such a condition does not exist anymore.
// Then we have re-read the D$, with the proper iu_dva address on the bus.
// Btw, 'fast_hld_terms' is a subset of iu_held.
// For the store case we make sure that the proper hit/miss is
// sustained (this only happens during streaming), untill the
// D$ can issue a dc_miss to the MMU(BUG 470).
//
// it_hit_f == == == ==
// iu_held == ==
// fast_hld_terms ==
// ld_op_e == ==
// ^^----- This hold cycle is guaranteed,
// since the I$ controller will atleast
// go thru the STAT state for 1 cycle,
// during which 'fast_hld_terms' will be
// asserted(since it includes iwait_f,
// and hence dc_dva will be
// switched from iu_dva_e -> iu_dva_w
assign dcc_miss_idle =
dcc_idle & ~(possible_bad_mem_op_w|possible_bad_mem_op_dt_hit_w)
& ~(dt_be_vb_d1 & parity_error_in_fill) & ~parity_error_d1
& ~parity_error_d2;
// Was this before:
// (~fast_hld_terms & iu_held & (ld_op_w|st_op_w))
wire timing_node_iu_held1
= ~fast_hld_terms & (ld_op_w|st_op_w);
wire bad_mem_op_ff_hold_in
;
// (iu_held & timing_node_iu_held1) HARDCODED.
JAND2B bad_mem_op_w_gate
(.A1 (iu_held), .A2(timing_node_iu_held1), .O(bad_mem_op_ff_hold_in));
Mflipflop_r bad_mem_op_ff(possible_bad_mem_op_w, (bad_mem_op_ff_hold_in),
~ss_reset, ss_clock);
// The purpose of this signal is to nuke dc_miss and stop the sm from
// thinking it is a miss. This is different from the possible_bad_mem_op_w
// signal which can return bad data, or create a false miss/hit.
// Note that this is important only during D$ hits(dt_hit_w term).
// A possible_bad_mem_op_dt_hit_w on the other hand screws up the timing of
// the interface between the MMU and the D$. BUG # 421
// Was this before:
// (~fast_hld_terms & iu_held & (st_op_w|ld_op_w) & enbl_dtag_match_w & dt_hit_w)
wire timing_node_iu_held2
=
~fast_hld_terms & (st_op_w|ld_op_w) & enbl_dtag_match_w & dt_hit_w;
wire bad_mem_op_dt_hit_hold_in
;
// (iu_held & timing_node_iu_held2) HARDCODED.
JAND2B bad_mem_op_dt_hit_w_gate
(.A1 (iu_held), .A2(timing_node_iu_held2), .O(bad_mem_op_dt_hit_hold_in));
Mflipflop_r bad_mem_op_dt_hit_ff(possible_bad_mem_op_dt_hit_w,
(bad_mem_op_dt_hit_hold_in), ~ss_reset, ss_clock);
// synopsys translate_off
wire iu_held_last
;
Mflipflop_r iu_held_last_ff(iu_held_last, iu_held, ~ss_reset, ss_clock);
always @(posedge ss_clock)
if (~dcc_miss_idle & dc_miss & ~iu_held_last)
$display("dcache: dcc_idle/dc_miss Protocol violated");
// synopsys translate_on
wire [`dc_msb:3] dc_dva_e_int
;
wire dva_sel
= fast_hld_terms;
wire dva_sel_l
= ~fast_hld_terms ;
JGB22A dc_dva_e_mux_3 ( .O(dc_dva_e_int[3]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[3]), .B2(~dc_dva_e_one[3]));
JINVE dc_dva_e_inv_3 ( .O(dc_dva_e[3]), .A(dc_dva_e_int[3]));
JGB22A dc_dva_e_mux_4 ( .O(dc_dva_e_int[4]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[4]), .B2(~dc_dva_e_one[4]));
JINVE dc_dva_e_inv_4 ( .O(dc_dva_e[4]), .A(dc_dva_e_int[4]));
JGB22A dc_dva_e_mux_5 ( .O(dc_dva_e_int[5]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[5]), .B2(~dc_dva_e_one[5]));
JINVE dc_dva_e_inv_5 ( .O(dc_dva_e[5]), .A(dc_dva_e_int[5]));
JGB22A dc_dva_e_mux_6 ( .O(dc_dva_e_int[6]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[6]), .B2(~dc_dva_e_one[6]));
JINVE dc_dva_e_inv_6 ( .O(dc_dva_e[6]), .A(dc_dva_e_int[6]));
JGB22A dc_dva_e_mux_7 ( .O(dc_dva_e_int[7]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[7]), .B2(~dc_dva_e_one[7]));
JINVE dc_dva_e_inv_7 ( .O(dc_dva_e[7]), .A(dc_dva_e_int[7]));
JGB22A dc_dva_e_mux_8 ( .O(dc_dva_e_int[8]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[8]), .B2(~dc_dva_e_one[8]));
JINVE dc_dva_e_inv_8 ( .O(dc_dva_e[8]), .A(dc_dva_e_int[8]));
JGB22A dc_dva_e_mux_9 ( .O(dc_dva_e_int[9]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[9]), .B2(~dc_dva_e_one[9]));
JINVE dc_dva_e_inv_9 ( .O(dc_dva_e[9]), .A(dc_dva_e_int[9]));
JGB22A dc_dva_e_mux_10 ( .O(dc_dva_e_int[10]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[10]), .B2(~dc_dva_e_one[10]));
JINVE dc_dva_e_inv_10 ( .O(dc_dva_e[10]), .A(dc_dva_e_int[10]));
JGB22A dc_dva_e_mux_11 ( .O(dc_dva_e_int[11]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[11]), .B2(~dc_dva_e_one[11]));
JINVE dc_dva_e_inv_11 ( .O(dc_dva_e[11]), .A(dc_dva_e_int[11]));
JGB22A dc_dva_e_mux_12 ( .O(dc_dva_e_int[12]),
.A1(dva_sel), .B1(dva_sel_l), .A2(~dc_dva_e_zero[12]), .B2(~dc_dva_e_one[12]));
JINVE dc_dva_e_inv_12 ( .O(dc_dva_e[12]), .A(dc_dva_e_int[12]));
/////////////////////////////////////////////////////////////////////////////
// ASI decodes ..
wire page_flush
= (iu_asi_e == 6'h10) & st_op_e ;
wire segment_flush
= (iu_asi_e == 6'h11) & st_op_e ;
wire region_flush
= (iu_asi_e == 6'h12) & st_op_e ;
wire context_flush
= (iu_asi_e == 6'h13) & st_op_e;
wire user_flush
= (iu_asi_e == 6'h14) & st_op_e ;
wire dt_index3
;
wire dt_index2
;
wire dt_index1
;
wire dt_flush_user
;
wire dt_flush_user_cntx
;
assign dt_index1 = (context_flush | user_flush) ;
assign dt_index2 = (region_flush | context_flush | user_flush) ;
assign dt_index3 = (segment_flush | region_flush | context_flush
| user_flush);
assign asi_flush_e = ((page_flush)
| (segment_flush)
| (region_flush)
| (context_flush)
| (user_flush));
assign dt_flush_user = (iu_asi_e == 6'h14) & st_op_e ;
assign dt_flush_user_cntx =
((iu_asi_e == 6'h13) | (iu_asi_e == 6'h14)) & st_op_e;
// These W stage signals for the D$ comparator, are used in the W1 stage.
MflipflopR dt_index1_w_ff (dt_index1_w, dt_index1,
ss_clock, iu_held, ss_reset) ;
MflipflopR dt_index2_w_ff (dt_index2_w, dt_index2,
ss_clock, iu_held, ss_reset) ;
MflipflopR dt_index3_w_ff (dt_index3_w, dt_index3,
ss_clock, iu_held, ss_reset) ;
MflipflopR dt_flush_user_ff (dt_flush_user_w, dt_flush_user,
ss_clock, iu_held, ss_reset) ;
MflipflopR dt_flush_user_cntx_ff (dt_flush_user_cntx_w, dt_flush_user_cntx,
ss_clock, iu_held, ss_reset) ;
// Latched to make timing; Could have made it a multicycle path instead.
// Instead used 5 freerunning flipflops. Worth the area hit ? I think so!
wire dt_index3_ee
;
Mflipflop_r dt_index3_multi_cycle_ff (dt_index3_ee,
dt_index3, ~ss_reset, ss_clock);
wire dt_index2_ee
;
Mflipflop_r dt_index2_multi_cycle_ff (dt_index2_ee,
dt_index2, ~ss_reset, ss_clock);
wire dt_index1_ee
;
Mflipflop_r dt_index1_multi_cycle_ff (dt_index1_ee,
dt_index1, ~ss_reset, ss_clock);
wire dt_flush_user_ee
;
Mflipflop_r dt_flush_user_multi_cycle_ff (dt_flush_user_ee,
dt_flush_user, ~ss_reset, ss_clock);
wire dt_flush_user_cntx_ee
;
Mflipflop_r dt_flush_user_cntx_multi_cycle_ff (dt_flush_user_cntx_ee,
dt_flush_user_cntx, ~ss_reset, ss_clock);
wire flush_ic_ee
;
Mflipflop_r flush_ic_e_multi_cycle_ff (flush_ic_ee,
(flush_ic_e & iu_held), ~ss_reset, ss_clock);
// IU generates a G stage signal, but we want to do the match in theF
// stage, so register it.
wire force_dva_f
;
Mflipflop_r force_dva_f_ff (force_dva_f,
(nforce_dva_f & ~iu_in_trap_d1),
~ss_reset, ss_clock);
// These are e/E/w/W stage signals for the I$ compare unit.
// They are qualified by (nforce_dva_f & flush_ic_e) in -1 cycle.
// Turn on I$ compare signals only for 1st (match) cycle of iflush ONLY.
assign it_index3_w = (force_dva_f) ?
((flush_ic_ee) ? dt_index3_ee : dt_index3_w) : 1'b0;
assign it_index2_w = (force_dva_f) ?
((flush_ic_ee) ? dt_index2_ee : dt_index2_w) : 1'b0;
assign it_index1_w = (force_dva_f) ?
((flush_ic_ee) ? dt_index1_ee : dt_index1_w) : 1'b0;
assign it_flush_w = (force_dva_f) ? 1'b0 : 1'b1;
assign it_flush_user_w =
(force_dva_f) ?
((flush_ic_ee) ? dt_flush_user_ee :dt_flush_user_w) : 1'b0;
assign it_flush_user_cntx_w =
(force_dva_f) ?
((flush_ic_ee) ? dt_flush_user_cntx_ee: dt_flush_user_cntx_w) : 1'b0;
// ASI Decodes for the I$ controller ..
wire ic_asi_load_tag_e
= ld_op_e & ~st_op_e & (iu_asi_e == 6'h0c) ;
assign ic_asi_load_tag_w = ld_op_w & ~st_op_w & (iu_asi_w == 6'h0c) ;
wire ic_asi_load_cache_e
= ld_op_e & ~st_op_e & (iu_asi_e == 6'h0d) ;
assign ic_asi_load_cache_w= ld_op_w & ~st_op_w & (iu_asi_w == 6'h0d) ;
assign ic_asi_store_tag_e = ~ld_op_e & st_op_e & (iu_asi_e == 6'h0c) ;
assign ic_asi_store_tag_w = ~ld_op_w & st_op_w & (iu_asi_w == 6'h0c) ;
assign ic_asi_store_cache_e=~ld_op_e & st_op_e & (iu_asi_e == 6'h0d) ;
assign ic_asi_store_cache_w=~ld_op_w & st_op_w & (iu_asi_w == 6'h0d) ;
wire dc_asi_store_tag_e
= ~ld_op_e & st_op_e & (iu_asi_e == 6'h0e);
MflipflopR dc_asi_store_tag_w_ff (dc_asi_store_tag_w, dc_asi_store_tag_e,
ss_clock, iu_held, ss_reset) ;
// Either an IFLUSH or a STA to the proper ASI asserts the signal flush_ic_e
// These are for the I$, nothing to do with the D$.
assign flush_ic_e = flush_op_e | asi_flush_e ;
// For iu_held timing, create another intermediate node.
wire ic_flush_w_ff_in
= flush_op_e & ~iu_in_trap_d1 ;
Mflipflop_r ic_flush_w_ff (ic_flush_op_w, (ic_flush_w_ff_in & iu_held_l),
~ss_reset, ss_clock) ;
// For iu_held timing, create another intermediate node.
wire dt_flush_w_ff_in
= flush_ic_e & ~iu_in_trap_d1 ;
Mflipflop_r dt_flush_w_ff (dc_flush_op_w, (dt_flush_w_ff_in & iu_held_l),
~ss_reset, ss_clock) ;
// Wierdo f/f's to signal the IU to switch dva->iva bus on a Itag read/write
// why the dc_asi_store_tag_w term? Why not dc_asi_load_tag_w?
// What do these have to do with 'flush'?
// Actually these are mis-named as flush, they are actually for asi ld/st's
wire flush1_out_a1
=
((ic_asi_load_tag_w|ic_asi_store_tag_w|ic_asi_load_cache_w
|ic_asi_store_cache_w|dc_asi_store_tag_w) & mm_dstat_avail) ;
Mflipflop_r flush1_ff (flush1_out, flush1_out_a1,
~ss_reset, ss_clock);
Mflipflop_r flush2_ff (flush2_out,
flush1_out, ~ss_reset, ss_clock);
// dwait_w asserted for 1 cycle more than i_dva_req
Mflipflop_r flush123_ff (flush123_out,
flush1_out_a1 | flush1_out | flush2_out,
~ss_reset, ss_clock);
// To prevent dva -> iva switch for DTag asi's.
assign i_dva_req = (flush1_out | flush2_out) & ~dc_asi_store_tag_w;
// Keeps dwait turned on until nforce_dva_f is asserted
Mflipflop_r
dt_flush_w_extended_hold_ff (dc_flush_hold,
(dc_flush_hold | dc_flush_op_w) & ~nforce_dva_f & ~iu_in_trap_d1,
~ss_reset, ss_clock) ;
// Used by dwait - first W-cycle of load or store to ICache, ITag, or
// DTag ASI.
Mflipflop_r dc_asi_load_tag_w1_ff(first_w_of_cache_ram_asi,
iu_held_l
& ((ld_op_e|st_op_e)
& ( (iu_asi_e == 6'h0c)
| (iu_asi_e == 6'h0d)
| (iu_asi_e == 6'h0e) )),
~ss_reset, ss_clock);
// State encoding
// IDLE = 12'b000000000001,
// STAT_WAIT = 12'b000000000010,
// STAT = 12'b000000000100,
// FILL_WAIT = 12'b000000001000,
// FILL_WRITE_F = 12'b000000010000,
// DEAD_CYC_1 = 12'b000000100000,
// DEAD_CYC_2 = 12'b000001000000,
// DEAD_CYC_3 = 12'b000010000000,
// FILL_WRITE_L = 12'b000100000000,
// NC_WAIT = 12'b001000000000,
// NC_BYP = 12'b010000000000,
// NC_RETRY = 12'b100000000000;
// Decodes of the state machine
assign dcc_idle = dcc_state[0];
assign dcc_stat_wait = dcc_state[1];
assign dcc_ld_stat_wait = dcc_stat_wait & ~dcc_st_miss ;
assign dcc_st_stat_wait = dcc_stat_wait & dcc_st_miss ;
// Added for 3 cycle stores
assign dcc_stat = (dcc_stat_new) ? 1'b1 :dcc_state[2];
assign dcc_ld_stat = dcc_stat & ~dcc_st_miss ;
assign dcc_st_stat = dcc_stat_new & dcc_st_miss ;
assign dcc_fill_wait = dcc_state[3];
assign dcc_fill_write_f = dcc_state[4];
assign dcc_dead_cyc_1 = dcc_state[5];
assign dcc_dead_cyc_2 = dcc_state[6];
assign dcc_dead_cyc_3 = dcc_state[7];
assign dcc_dead_cyc = dcc_dead_cyc_1 | dcc_dead_cyc_2 | dcc_dead_cyc_3 ;
assign dcc_fill_write_l = dcc_state[8];
assign dcc_nc_wait = dcc_state[9];
assign dcc_ld_nc_wait = dcc_nc_wait & ~dcc_st_miss ;
assign dcc_nc_bypass = dcc_state[10];
assign dcc_ld_nc_bypass = dcc_nc_bypass & ~dcc_st_miss ;
assign dcc_nc_retry = dcc_state[11];
assign dcc_ld_nc_retry = dcc_nc_retry & ~dcc_st_miss ;
// synopsys translate_off
always @(posedge ss_clock) if (mm_dstat_avail & mm_dabort)
Mclocks.print_error(
"dcache: mm_dstat_avail and mm_dabort both asserted in same cycle") ;
// synopsys translate_on
rl_dc_sm rl_dc_sm(
.dcc_state (dcc_state),
.normal_asi_w (normal_asi_w),
.wb_empty (wb_empty),
.ic_miss (ic_miss),
.nonheld_once (nonheld_once),
.parity_error_in_fill (parity_error_in_fill | parity_error),
.dcc_st_miss (dcc_st_miss),
.dc_miss (dc_miss),
.mm_dabort (mm_dabort),
.mm_dcstben (mm_dcstben),
// .mm_dstat_avail (mm_dstat_avail | dc_perf_dstat_avail), // For perfmeter
.mm_dstat_avail (mm_dstat_avail),
// .cached (cached & ~dc_perf_dstat_avail),
.cached (cached),
.iu_held (iu_held),
.iu_in_trap (iu_in_trap), // Register removed to fix Bug 260
.ss_reset (ss_reset),
.ss_clock (ss_clock)
);
herbulator herbulator (
.little_endian (little_endian), // add this bit for little endian support if = 1
.din (dc_do[63:0]),
.ld_iu (ld_iu[31:0]),
.ld_fpu (ld_fpu[63:0]),
.lddi_r (lddi_r),
.sel_ld_fpu_w (sel_ld_fpu_w),
.sgnd_ld_e (sgnd_ld_e),
.size_w (size_w),
.iu_dva_w (iu_dva_w[2:0]),
.iu_held (iu_held),
.ss_reset (ss_reset),
.rt_clk (ss_clock)
);
store_aligner store_aligner (
.fp_dout_e (fp_dout_e[63:0]),
.iu_dout (iu_dout[63:0]),
.wb_dout (wb_dout),
.little_endian (little_endian),
.iu_store_data (iu_store_data[31:0]),
.select_FP_DOUT (select_FP_DOUT),
.select_IU_DOUT (select_IU_DOUT),
.sel_ldstb_1 (sel_ldstb_1)
);
writebuffer writebuffer (
.release_hold (atomic_dstat_avail),
// .cancel_last (cancel_last),
.iu_in_trap (iu_in_trap),
.add_wb_entry_d1 (add_wb_entry_d1),
.wb_empty (wb_empty),
.wb_valid (wb_valid),
.wb0_hold_hi (wb0_hold_lo),
.wb1_hold_hi (wb1_hold_lo),
.wb2_hold_hi (wb2_hold_lo),
.wb3_hold_hi (wb3_hold_lo),
.wb_1_sel_lo (wb_1_sel),
.wb_2_sel_lo (wb_2_sel),
.wb_3_sel_lo (wb_3_sel),
.iu_held (iu_held),
.iu_held_l (iu_held_l),
.stdi_e (stdi_e),
.din (wb_dout[63:0]),
.little_endian (little_endian),
.st_op_wb_e (st_op_wb_e),
.dt_hit_w (dt_hit_w),
.dc_miss_or_part (dc_miss_or_part),
.dc_miss_and_part (dc_miss_and_part),
.nonatomic_st_e (nonatomic_st_e),
.nomiss_asi_e (nomiss_asi_e),
.atomic_op_w (atomic_op_w),
.nomiss_asi_w (nomiss_asi_w),
.dcc_idle (dcc_idle),
.atomic_wb_strobed (atomic_wb_strobed),
.dcc_stat_wait (dcc_stat_wait),
.mm_dstat_avail (mm_dstat_avail),
//
.wb_full (wb_full),
.dout (wrtbuf[31:0]),
// .dout (swapbuf[31:0]),
.mm_dcdaten_in (mm_dcdaten_in),
.mm_wbstb (mm_wbstb),
.mm_wbsel1 (mm_wbsel1),
.wb_reset (ss_reset),
.wb_clk (ss_clock)
);
// synopsys translate_off
// For dcc displays:
// Convert 1-hot state value to binary number
function [7:0] dc_state_encode ;
input [11:0] state ;
dc_state_encode = ((^state)===1'bx) ? 'bx : {
((state & 12'b111100000000)!=0),
((state & 12'b000011110000)!=0),
((state & 12'b110011001100)!=0),
((state & 12'b101010101010)!=0)
} ;
endfunction
reg [15:0] dc_state_str
[0:11] ;
initial begin
dc_state_str[0] = ". " ; // IDLE
dc_state_str[1] = "Sw" ; // STAT_WAIT
dc_state_str[2] = "S " ; // STAT
dc_state_str[3] = "Fw" ; // FILL_WAIT
dc_state_str[4] = "Ff" ; // FILL_WRITE_F
dc_state_str[5] = "D1" ; // DEAD_CYC_1
dc_state_str[6] = "D2" ; // DEAD_CYC_2
dc_state_str[7] = "D3" ; // DEAD_CYC_3
dc_state_str[8] = "Fl" ; // FILL_WRITE_L
dc_state_str[9] = "Nw" ; // NC_WAIT
dc_state_str[10] = "Nb" ; // NC_BYP
dc_state_str[11] = "Nr" ; // NC_RETRY
end
/*
task dc_st ;
input [(`LOGDCCBYTES-1):0] bidx ;
input [31:0] labellen ;
reg [(`LOGDCCCYCLES-1):0] cidx ;
reg [7:0] byte ;
begin
Mccdisp.pspaces(Mccdisp.dcc_labellen-labellen) ;
cidx=Mccdisp.from ;
repeat(Mccdisp.ccdn) begin
byte = Mccdisp.dccvec[{cidx,bidx}] ;
if ((^byte)===1'bx) $write(" x ") ;
else $write(" %s", dc_state_str[byte]) ;
cidx= cidx+1 ;
end
$display;
end
endtask
*/
// For signalscan displays:
wire [15:0] dc_state_lbl
=
(^dcc_state===1'bx) ? "x " : dc_state_str[dc_state_encode(dcc_state)] ;
// synopsys translate_on
endmodule
This page: |
Created: | Thu Aug 19 11:59:21 1999 |
| From: |
../../../sparc_v8/ssparc/cc/rl_dc_cntl/rtl/rl_dc_cntl.v
|