mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-24 05:57:22 -04:00
fixing dcache ways bug
This commit is contained in:
parent
c60027995d
commit
3bd08f7802
2 changed files with 108 additions and 45 deletions
|
@ -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),
|
||||
.*);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue