diff --git a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv index 311540387a..f3a1d2e040 100644 --- a/core/cache_subsystem/cva6_hpdcache_if_adapter.sv +++ b/core/cache_subsystem/cva6_hpdcache_if_adapter.sv @@ -104,10 +104,11 @@ module cva6_hpdcache_if_adapter hpdcache_req_offset_t amo_addr_offset; hpdcache_tag_t amo_tag; logic amo_is_word, amo_is_word_hi; - hpdcache_req_data_t amo_data; - hpdcache_req_be_t amo_data_be; - hpdcache_req_op_t amo_op; - logic [31:0] amo_resp_word; + logic [63:0] amo_data; + logic [ 7:0] amo_data_be; + hpdcache_req_op_t amo_op; + logic [31:0] amo_resp_word; + logic amo_pending_q; // AMO logic // {{{ @@ -115,13 +116,6 @@ module cva6_hpdcache_if_adapter amo_addr = cva6_amo_req_i.operand_a; amo_addr_offset = amo_addr[0+:HPDCACHE_REQ_OFFSET_WIDTH]; amo_tag = amo_addr[HPDCACHE_REQ_OFFSET_WIDTH+:HPDCACHE_TAG_WIDTH]; - amo_is_word = (cva6_amo_req_i.size == 2'b10); - amo_is_word_hi = cva6_amo_req_i.operand_a[2]; - - amo_data = amo_is_word ? {2{cva6_amo_req_i.operand_b[0+:32]}} : cva6_amo_req_i.operand_b; - - amo_data_be = amo_is_word_hi ? 8'hf0 : amo_is_word ? 8'h0f : 8'hff; - unique case (cva6_amo_req_i.amo_op) ariane_pkg::AMO_LR: amo_op = HPDCACHE_REQ_AMO_LR; ariane_pkg::AMO_SC: amo_op = HPDCACHE_REQ_AMO_SC; @@ -137,9 +131,6 @@ module cva6_hpdcache_if_adapter default: amo_op = HPDCACHE_REQ_LOAD; endcase end - - assign amo_resp_word = amo_is_word_hi ? hpdcache_rsp_i.rdata[0][32 +: 32] - : hpdcache_rsp_i.rdata[0][0 +: 32]; // }}} // Request forwarding @@ -153,37 +144,66 @@ module cva6_hpdcache_if_adapter } ); - assign forward_store = cva6_req_i.data_req, forward_amo = cva6_amo_req_i.req; + assign amo_is_word = (cva6_amo_req_i.size == 2'b10); + assign amo_is_word_hi = cva6_amo_req_i.operand_a[2]; + if (riscv::XLEN == 64) begin : amo_data_64_gen + assign amo_data = amo_is_word ? {2{cva6_amo_req_i.operand_b[0+:32]}} : cva6_amo_req_i.operand_b; + assign amo_data_be = amo_is_word_hi ? 8'hf0 : amo_is_word ? 8'h0f : 8'hff; + end else begin : amo_data_32_gen + assign amo_data = {32'b0, cva6_amo_req_i.operand_b}; + assign amo_data_be = 8'h0f; + end - assign hpdcache_req_valid_o = forward_store | forward_amo, - hpdcache_req_o.addr_offset = forward_amo ? amo_addr_offset : cva6_req_i.address_index, - hpdcache_req_o.wdata = forward_amo ? amo_data : cva6_req_i.data_wdata, - hpdcache_req_o.op = forward_amo ? amo_op : hpdcache_pkg::HPDCACHE_REQ_STORE, - hpdcache_req_o.be = forward_amo ? amo_data_be : cva6_req_i.data_be, - hpdcache_req_o.size = forward_amo ? cva6_amo_req_i.size : cva6_req_i.data_size, - hpdcache_req_o.sid = hpdcache_req_sid_i, - hpdcache_req_o.tid = forward_amo ? '1 : '0, - hpdcache_req_o.need_rsp = forward_amo, - hpdcache_req_o.phys_indexed = 1'b1, - hpdcache_req_o.addr_tag = forward_amo ? amo_tag : cva6_req_i.address_tag, - hpdcache_req_o.pma.uncacheable = hpdcache_req_is_uncacheable, - hpdcache_req_o.pma.io = 1'b0, - hpdcache_req_abort_o = 1'b0, // unused on physically indexed requests - hpdcache_req_tag_o = '0, // unused on physically indexed requests - hpdcache_req_pma_o = '0; // unused on physically indexed requests + assign forward_store = cva6_req_i.data_req; + assign forward_amo = cva6_amo_req_i.req; + + assign hpdcache_req_valid_o = forward_store | (forward_amo & ~amo_pending_q); + assign hpdcache_req_o.addr_offset = forward_amo ? amo_addr_offset : cva6_req_i.address_index; + assign hpdcache_req_o.wdata = forward_amo ? amo_data : cva6_req_i.data_wdata; + assign hpdcache_req_o.op = forward_amo ? amo_op : hpdcache_pkg::HPDCACHE_REQ_STORE; + assign hpdcache_req_o.be = forward_amo ? amo_data_be : cva6_req_i.data_be; + assign hpdcache_req_o.size = forward_amo ? cva6_amo_req_i.size : cva6_req_i.data_size; + assign hpdcache_req_o.sid = hpdcache_req_sid_i; + assign hpdcache_req_o.tid = forward_amo ? '1 : '0; + assign hpdcache_req_o.need_rsp = forward_amo; + assign hpdcache_req_o.phys_indexed = 1'b1; + assign hpdcache_req_o.addr_tag = forward_amo ? amo_tag : cva6_req_i.address_tag; + assign hpdcache_req_o.pma.uncacheable = hpdcache_req_is_uncacheable; + assign hpdcache_req_o.pma.io = 1'b0; + assign hpdcache_req_abort_o = 1'b0; // unused on physically indexed requests + assign hpdcache_req_tag_o = '0; // unused on physically indexed requests + assign hpdcache_req_pma_o = '0; // unused on physically indexed requests // }}} // Response forwarding // {{{ - assign cva6_req_o.data_rvalid = hpdcache_rsp_valid_i && (hpdcache_rsp_i.tid != '1), - cva6_req_o.data_rdata = hpdcache_rsp_i.rdata, - cva6_req_o.data_rid = hpdcache_rsp_i.tid, - cva6_req_o.data_gnt = hpdcache_req_ready_i; + if (riscv::XLEN == 64) begin : amo_resp_64_gen + assign amo_resp_word = amo_is_word_hi + ? hpdcache_rsp_i.rdata[0][32 +: 32] + : hpdcache_rsp_i.rdata[0][0 +: 32]; + end else begin : amo_resp_32_gen + assign amo_resp_word = hpdcache_rsp_i.rdata[0]; + end - assign cva6_amo_resp_o.ack = hpdcache_rsp_valid_i && (hpdcache_rsp_i.tid == '1), - cva6_amo_resp_o.result = amo_is_word ? {{32{amo_resp_word[31]}}, amo_resp_word} - : hpdcache_rsp_i.rdata[0][63:0]; + assign cva6_req_o.data_rvalid = hpdcache_rsp_valid_i && (hpdcache_rsp_i.tid != '1); + assign cva6_req_o.data_rdata = hpdcache_rsp_i.rdata; + assign cva6_req_o.data_rid = hpdcache_rsp_i.tid; + assign cva6_req_o.data_gnt = hpdcache_req_ready_i; + + assign cva6_amo_resp_o.ack = hpdcache_rsp_valid_i && (hpdcache_rsp_i.tid == '1); + assign cva6_amo_resp_o.result = amo_is_word ? {{32{amo_resp_word[31]}}, amo_resp_word} + : hpdcache_rsp_i.rdata[0]; // }}} + + always_ff @(posedge clk_i or negedge rst_ni) begin : amo_pending_ff + if (!rst_ni) begin + amo_pending_q <= 1'b0; + end else begin + amo_pending_q <= + ( cva6_amo_req_i.req & hpdcache_req_ready_i & ~amo_pending_q) | + (~cva6_amo_resp_o.ack & amo_pending_q); + end + end end // }}} endgenerate diff --git a/core/cache_subsystem/hpdcache b/core/cache_subsystem/hpdcache index 04f338b2e9..41fe79977a 160000 --- a/core/cache_subsystem/hpdcache +++ b/core/cache_subsystem/hpdcache @@ -1 +1 @@ -Subproject commit 04f338b2e976a5e7a8a512f224d9c5d59d3be4d3 +Subproject commit 41fe79977aa86fc4be8066839c1ea64304d606f8