fixing dcache ways bug

This commit is contained in:
msa417 2025-01-31 10:22:10 -08:00
parent c60027995d
commit 3bd08f7802
2 changed files with 108 additions and 45 deletions

View file

@ -112,53 +112,68 @@ module multicore_arbiter
assign mems[i].write_outstanding = wcounts[i][$clog2(FIFO_DEPTH)] | write_outstanding[i];
end endgenerate
logic [4:0] rmw_len;
logic [31:2] rmw_addr;
logic [1:0] rmw_index;
// logic [4:0] rmw_len;
// logic [31:2] rmw_addr;
logic [(NUM_CORES == 1 ? 1 : $clog2(NUM_CORES))-1:0] rmw_index;
always_ff @(posedge clk or posedge rst) begin
if (rst) begin
rmw_len <= '0;
rmw_addr <= '0;
// rmw_len <= '0;
// rmw_addr <= '0;
rmw_index <= '0;
end
else if (in_req.rmw & in_req.rnw & request_push) begin
rmw_addr <= in_req.addr;
rmw_len <= in_req.rlen;
else if (in_req.rmw & request_push) begin
// rmw_addr <= in_req.addr;
// rmw_len <= in_req.rlen;
rmw_index <= chosen_port;
end
end
logic[1:0] rmw_in_fifo;
// logic[1:0] rmw_in_fifo;
// always_ff @(posedge clk or posedge rst) begin
// if (rst)
// rmw_in_fifo <= 0;
// else if (rmw_in_fifo == 2)begin
// if(rmw_counter == rmw_len+1)
// rmw_in_fifo <= 0;
// else
// rmw_in_fifo <= 2;
// end else if (in_req.rmw & in_req.rnw & request_push)
// rmw_in_fifo <= 1;
// else if (out_req.rmw & out_req.rnw & request_pop)
// rmw_in_fifo <= 2;
// end
// logic [4:0] rmw_counter;
// always_ff @(posedge clk) begin
// if(rst)begin
// rmw_counter <= '0;
// end else if(rmw_in_fifo==2) begin
// if(rvalids[rmw_index])
// rmw_counter <= rmw_counter + 1;
// else
// rmw_counter <= rmw_counter;
// end else begin
// rmw_counter <= '0;
// end
// end
logic rmw_is_on;
always_ff @(posedge clk or posedge rst) begin
if (rst)
rmw_in_fifo <= 0;
else if (rmw_in_fifo == 2)begin
if(rmw_counter == rmw_len+1)
rmw_in_fifo <= 0;
else
rmw_in_fifo <= 2;
end else if (in_req.rmw & in_req.rnw & request_push)
rmw_in_fifo <= 1;
else if (out_req.rmw & out_req.rnw & request_pop)
rmw_in_fifo <= 2;
end
logic [4:0] rmw_counter;
always_ff @(posedge clk) begin
if(rst)begin
rmw_counter <= '0;
end else if(rmw_in_fifo==2) begin
if(rvalids[rmw_index])
rmw_counter <= rmw_counter + 1;
else
rmw_counter <= rmw_counter;
end else begin
rmw_counter <= '0;
if (rst) begin
rmw_is_on <= 1'b0;
end else if(in_req.rmw & request_push) begin
rmw_is_on <= 1'b1;
end else if(in_req.rmw==0) begin
rmw_is_on <= 1'b0;
end
end
logic[NUM_CORES-1:0] accept_request_from_rmw_core;
assign request_push = ~request_fifo.full & |requests & ((rmw_in_fifo==0) | in_req.rnw | rmw_addr[31:6] != in_req.addr[31:6]);
logic rmw_hit;
assign rmw_hit = |(requests & accept_request_from_rmw_core);
assign accept_request_from_rmw_core = (rmw_is_on ? (1'b1 << rmw_index) : {NUM_CORES{1'b1}});
assign request_push = ~request_fifo.full & |requests & (~rmw_is_on | rmw_hit);//((rmw_in_fifo==0) | in_req.rnw | rmw_addr[31:6] != in_req.addr[31:6]);
assign request_fifo.data_in = in_req;
assign out_req = request_fifo.data_out;
assign request_valid = request_fifo.valid;
@ -176,7 +191,7 @@ module multicore_arbiter
//Arbitration
round_robin #(.NUM_PORTS(NUM_CORES)) rr (
.requests(requests),
.requests(requests & accept_request_from_rmw_core),
.grant(request_push),
.grantee(chosen_port),
.*);

View file

@ -185,8 +185,19 @@ module dcache_inv
logic stage1_tb_wval_r;
logic[CONFIG.DCACHE.WAYS-1:0] hit_ohot_r;
assign a_en = snoop_write | (stage1_tb_write_r & ~inv_matches_stage1) | ls.new_request;
assign a_wbe = ({CONFIG.DCACHE.WAYS{snoop_write}} & snoop_hit) | ({CONFIG.DCACHE.WAYS{stage1_tb_write_r}} & (stage1_type == CBO ? hit_ohot_r : replacement_way));
assign a_en = snoop_write | stage1_tb_write_r | ls.new_request ;// & ~inv_matches_stage1 )
assign a_wbe = ({CONFIG.DCACHE.WAYS{snoop_write}} & snoop_hit) | ({CONFIG.DCACHE.WAYS{stage1_tb_write_r}} & (stage1_type == CBO ? hit_ohot_r : (coming_to_read_after_snoop_reg == 1'b1 ? hit_ohot_r : replacement_way)));
logic[CONFIG.DCACHE.WAYS-1:0] rmw_refill_way;
always_ff @(posedge clk) begin
if (rst)
rmw_refill_way <= 0;
else if (current_state==RMW_FILLING & a_wbe!=0)
rmw_refill_way <= a_wbe;
else if (current_state!=RMW_FILLING)
rmw_refill_way <= 0;
end
always_comb begin
if (snoop_write)
@ -248,10 +259,15 @@ module dcache_inv
logic hit_r;
logic[CONFIG.DCACHE.WAYS-1:0] hit_ohot;
logic hit_state = 0;
always_comb begin
hit_ohot = '0;
for (int i = 0; i < CONFIG.DCACHE.WAYS; i++)
hit_ohot[i] = a_rdata[i].valid & (a_rdata[i].tag == stage1.addr[2+SCONFIG.SUB_LINE_ADDR_W+SCONFIG.LINE_ADDR_W+:SCONFIG.TAG_W]);
// if(hit_state==2'd2)begin
// hit_ohot = hit_ohot_r;
// end else begin
for (int i = 0; i < CONFIG.DCACHE.WAYS; i++)
hit_ohot[i] = a_rdata[i].valid & (a_rdata[i].tag == stage1.addr[2+SCONFIG.SUB_LINE_ADDR_W+SCONFIG.LINE_ADDR_W+:SCONFIG.TAG_W]);
// end
end
assign hit = |hit_ohot;
@ -259,9 +275,26 @@ module dcache_inv
if (stage0_advance_r) begin
hit_r <= hit;
hit_ohot_r <= hit_ohot;
end
end
// else if(hit_state==2'd1 && (stage1_tb_write_r & ~inv_matches_stage1))begin
// hit_r <= 0;
// hit_ohot_r <= a_wbe;
// end
// end else if((rmw_stage1_tb_write))begin
// hit_r <= 0;
// end
end
// always_ff @(posedge clk)begin
// if(rst)begin
// hit_state<=2'd0;
// end else if(stage0_advance_r) begin
// hit_state<=2'd0;
// end else if(rmw_retry)begin
// hit_state<=2'd1;
// end
// end
////////////////////////////////////////////////////
//Atomic read/modify/write state machine
//Separate from other logic because atomic requests will need to be retried on a snoop invalidation
@ -292,9 +325,19 @@ module dcache_inv
current_state <= next_state;
end
logic coming_to_read_after_snoop;
logic coming_to_read_after_snoop_reg;
always_ff @(posedge clk) begin
if (rst)
coming_to_read_after_snoop_reg <= 0;
else
coming_to_read_after_snoop_reg <= coming_to_read_after_snoop;
end
always_comb begin
unique case (current_state)
RMW_READ : begin
coming_to_read_after_snoop = coming_to_read_after_snoop_reg;
rmw_mem_request = 1;
rmw_mem_rnw = 1;
rmw_stage1_tb_write = mem.ack & ~stage1.uncacheable;
@ -305,6 +348,7 @@ module dcache_inv
next_state = mem.ack ? RMW_FILLING : RMW_READ;
end
RMW_WRITE : begin
coming_to_read_after_snoop = 0;
rmw_mem_request = ~rmw_retry;
rmw_mem_rnw = 0;
rmw_stage1_tb_write = 0;
@ -314,12 +358,14 @@ module dcache_inv
rmw_stage1_done = mem.ack;
if (mem.ack)
next_state = RMW_IDLE;
else if (rmw_retry)
else if (rmw_retry)begin
next_state = RMW_READ;
else
coming_to_read_after_snoop = 1;
end else
next_state = RMW_WRITE;
end
RMW_FILLING : begin
coming_to_read_after_snoop = 0;
rmw_mem_request = 0;
rmw_mem_rnw = 'x;
rmw_stage1_tb_write = 0;
@ -327,12 +373,14 @@ module dcache_inv
rmw_db_wdata = mem.rdata;
rmw_ls_data_valid = 0;
rmw_stage1_done = 0;
if (return_done)
if (return_done)begin
next_state = rmw_retry ? RMW_READ : RMW_WRITE;
else
coming_to_read_after_snoop = rmw_retry;
end else
next_state = RMW_FILLING;
end
RMW_IDLE : begin
coming_to_read_after_snoop = 0;
rmw_mem_request = 0;
rmw_mem_rnw = 'x;
rmw_stage1_tb_write = 0;