diff --git a/apu/busses/multicore_arbiter.sv b/apu/busses/multicore_arbiter.sv index a4a4fd2..8c59896 100644 --- a/apu/busses/multicore_arbiter.sv +++ b/apu/busses/multicore_arbiter.sv @@ -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), .*); diff --git a/core/execution_units/load_store_unit/dcache_inv.sv b/core/execution_units/load_store_unit/dcache_inv.sv index 4851c52..462954e 100644 --- a/core/execution_units/load_store_unit/dcache_inv.sv +++ b/core/execution_units/load_store_unit/dcache_inv.sv @@ -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;