Line 115... |
Line 115... |
C_INVA = 3,
|
C_INVA = 3,
|
C_STATES = 4;
|
C_STATES = 4;
|
|
|
localparam [3:0] CS_INIT = 4'd0,
|
localparam [3:0] CS_INIT = 4'd0,
|
CS_IDLE = 4'd1,
|
CS_IDLE = 4'd1,
|
CS_FILL0 = 4'd2,
|
CS_FILL = 4'd2,
|
CS_FILL1 = 4'd3,
|
CS_FILL_COMPLETE = 4'd3,
|
CS_FILL2 = 4'd4,
|
CS_TURN_AROUND = 4'd4,
|
CS_FILL3 = 4'd5,
|
CS_WRITE_HIT = 4'd5,
|
CS_FILL_COMPLETE = 4'd6,
|
CS_WRITE_HIT_WAIT_WB = 4'd6,
|
CS_TURN_AROUND = 4'd7,
|
CS_WRITE_MISS_WAIT_WB = 4'd7,
|
CS_WRITE_HIT1 = 4'd8,
|
CS_EX_DELETE = 4'd8;
|
CS_WRITE_HIT_WAIT_WB = 4'd8,
|
|
CS_WRITE_MISS_WAIT_WB = 4'd9,
|
|
CS_EX_DELETE = 4'd10;
|
|
|
|
|
|
reg [3:0] c_state = CS_IDLE;
|
reg [3:0] c_state = CS_IDLE;
|
reg [C_STATES-1:0] source_sel = 1'd1 << C_CORE;
|
reg [C_STATES-1:0] source_sel = 1'd1 << C_CORE;
|
reg [CACHE_ADDR_WIDTH:0] init_count = 'd0;
|
reg [CACHE_ADDR_WIDTH:0] init_count = 'd0;
|
Line 264... |
Line 261... |
select_way <= data_hit_way | ex_read_hit_way;
|
select_way <= data_hit_way | ex_read_hit_way;
|
c_state <= CS_EX_DELETE;
|
c_state <= CS_EX_DELETE;
|
source_sel <= 1'd1 << C_INVA;
|
source_sel <= 1'd1 << C_INVA;
|
end
|
end
|
else if ( read_miss )
|
else if ( read_miss )
|
c_state <= CS_FILL3;
|
c_state <= CS_FILL;
|
else if ( write_hit )
|
else if ( write_hit )
|
begin
|
begin
|
if ( i_wb_cached_ready )
|
if ( i_wb_cached_ready )
|
c_state <= CS_WRITE_HIT1;
|
c_state <= CS_WRITE_HIT;
|
else
|
else
|
c_state <= CS_WRITE_HIT_WAIT_WB;
|
c_state <= CS_WRITE_HIT_WAIT_WB;
|
end
|
end
|
else if ( write_miss && !i_wb_cached_ready )
|
else if ( write_miss && !i_wb_cached_ready )
|
c_state <= CS_WRITE_MISS_WAIT_WB;
|
c_state <= CS_WRITE_MISS_WAIT_WB;
|
end
|
end
|
|
|
|
|
CS_FILL3 :
|
CS_FILL :
|
// third read of burst of 4
|
// third read of burst of 4
|
// wb read request asserted, wait for ack
|
// wb read request asserted, wait for ack
|
if ( i_wb_cached_ready )
|
if ( i_wb_cached_ready )
|
begin
|
begin
|
c_state <= CS_FILL_COMPLETE;
|
c_state <= CS_FILL_COMPLETE;
|
Line 327... |
Line 324... |
c_state <= CS_TURN_AROUND;
|
c_state <= CS_TURN_AROUND;
|
source_sel <= 1'd1 << C_CORE;
|
source_sel <= 1'd1 << C_CORE;
|
end
|
end
|
|
|
|
|
CS_WRITE_HIT1:
|
CS_WRITE_HIT:
|
if ( !consecutive_write )
|
if ( !consecutive_write )
|
c_state <= CS_IDLE;
|
c_state <= CS_IDLE;
|
|
|
|
|
CS_WRITE_HIT_WAIT_WB:
|
CS_WRITE_HIT_WAIT_WB:
|
Line 376... |
Line 373... |
data_wdata_r <= data_wdata;
|
data_wdata_r <= data_wdata;
|
end
|
end
|
|
|
assign consecutive_write = miss_address[31:4] == i_address[31:4] &&
|
assign consecutive_write = miss_address[31:4] == i_address[31:4] &&
|
i_write_enable &&
|
i_write_enable &&
|
c_state == CS_WRITE_HIT1 &&
|
c_state == CS_WRITE_HIT &&
|
request_pulse;
|
request_pulse;
|
|
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ( o_wb_cached_req )
|
if ( o_wb_cached_req )
|
wb_address <= i_address;
|
wb_address <= i_address;
|
else if ( i_wb_cached_ready && fill_state )
|
else if ( i_wb_cached_ready && fill_state )
|
wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
|
wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
|
|
|
assign fill_state = c_state == CS_FILL0 || c_state == CS_FILL1 || c_state == CS_FILL2 || c_state == CS_FILL3 ;
|
assign fill_state = c_state == CS_FILL ;
|
assign wb_hit = i_address == wb_address && i_wb_cached_ready && fill_state;
|
assign wb_hit = i_address == wb_address && i_wb_cached_ready && fill_state;
|
|
|
|
|
// ======================================
|
// ======================================
|
// Hold Requests
|
// Hold Requests
|
Line 529... |
Line 526... |
assign ex_read_cache_busy = exclusive_access && !i_write_enable && c_state != CS_IDLE;
|
assign ex_read_cache_busy = exclusive_access && !i_write_enable && c_state != CS_IDLE;
|
|
|
// Need to stall for a write miss to wait for the current wb
|
// Need to stall for a write miss to wait for the current wb
|
// read miss access to complete. Also for a write idle_hit, need
|
// read miss access to complete. Also for a write idle_hit, need
|
// to stall for 1 cycle while the data cache is being written to
|
// to stall for 1 cycle while the data cache is being written to
|
assign write_state = c_state == CS_IDLE || c_state == CS_WRITE_HIT1 ||
|
assign write_state = c_state == CS_IDLE || c_state == CS_WRITE_HIT ||
|
c_state == CS_WRITE_HIT_WAIT_WB || c_state == CS_WRITE_MISS_WAIT_WB;
|
c_state == CS_WRITE_HIT_WAIT_WB || c_state == CS_WRITE_MISS_WAIT_WB;
|
|
|
assign write_stall = (write_miss && !(i_wb_cached_ready && write_state)) || (write_hit && !i_wb_cached_ready);
|
assign write_stall = (write_miss && !(i_wb_cached_ready && write_state)) || (write_hit && !i_wb_cached_ready);
|
|
|
assign read_stall = request_hold && !idle_hit && !rbuf_hit && !wb_hit && !i_write_enable;
|
assign read_stall = request_hold && !idle_hit && !rbuf_hit && !wb_hit && !i_write_enable;
|
|
|
assign cache_busy_stall = c_state == CS_FILL_COMPLETE || c_state == CS_TURN_AROUND || c_state == CS_INIT ||
|
assign cache_busy_stall = c_state == CS_FILL_COMPLETE || c_state == CS_TURN_AROUND || c_state == CS_INIT ||
|
(fill_state && !rbuf_hit && !wb_hit) ||
|
(fill_state && !rbuf_hit && !wb_hit) ||
|
(c_state == CS_WRITE_HIT1 && !consecutive_write);
|
(c_state == CS_WRITE_HIT && !consecutive_write);
|
|
|
|
|
// ======================================
|
// ======================================
|
// Instantiate RAMS
|
// Instantiate RAMS
|
// ======================================
|
// ======================================
|
Line 870... |
Line 867... |
source_sel[C_INIT] ? "C_INIT" :
|
source_sel[C_INIT] ? "C_INIT" :
|
source_sel[C_FILL] ? "C_FILL" :
|
source_sel[C_FILL] ? "C_FILL" :
|
source_sel[C_INVA] ? "C_INVA" :
|
source_sel[C_INVA] ? "C_INVA" :
|
"UNKNON" ;
|
"UNKNON" ;
|
|
|
assign xC_STATE = c_state == CS_INIT ? "CS_INIT" :
|
assign xC_STATE = c_state == CS_INIT ? "INIT" :
|
c_state == CS_IDLE ? "CS_IDLE" :
|
c_state == CS_IDLE ? "IDLE" :
|
c_state == CS_FILL0 ? "CS_FILL0" :
|
c_state == CS_FILL ? "FILL" :
|
c_state == CS_FILL1 ? "CS_FILL1" :
|
c_state == CS_FILL_COMPLETE ? "FILL_COMPLETE" :
|
c_state == CS_FILL2 ? "CS_FILL2" :
|
c_state == CS_EX_DELETE ? "EX_DELETE" :
|
c_state == CS_FILL3 ? "CS_FILL3" :
|
c_state == CS_TURN_AROUND ? "TURN_AROUND" :
|
c_state == CS_FILL_COMPLETE ? "CS_FILL_COMPLETE" :
|
c_state == CS_WRITE_HIT ? "WRITE_HIT" :
|
c_state == CS_EX_DELETE ? "CS_EX_DELETE" :
|
c_state == CS_WRITE_HIT_WAIT_WB ? "WRITE_HIT_WAIT_WB" :
|
c_state == CS_TURN_AROUND ? "CS_TURN_AROUND" :
|
c_state == CS_WRITE_MISS_WAIT_WB ? "WRITE_MISS_WAIT_WB" :
|
c_state == CS_WRITE_HIT1 ? "CS_WRITE_HIT1" :
|
|
c_state == CS_WRITE_HIT_WAIT_WB ? "CS_WRITE_HIT_WAIT_WB" :
|
|
c_state == CS_WRITE_MISS_WAIT_WB ? "CS_WRITE_MISS_WAIT_WB" :
|
|
"UNKNOWN" ;
|
"UNKNOWN" ;
|
|
|
|
|
generate
|
generate
|
if ( WAYS == 2 ) begin : check_hit_2ways
|
if ( WAYS == 2 ) begin : check_hit_2ways
|