Skip to content

Commit

Permalink
fix: support of AMOs in cv32 configurations (#1841)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cesar Fuguet authored Feb 18, 2024
1 parent 3d7e417 commit 45ffb59
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 39 deletions.
96 changes: 58 additions & 38 deletions core/cache_subsystem/cva6_hpdcache_if_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -104,24 +104,18 @@ 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
// {{{
always_comb begin : amo_op_comb
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;
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion core/cache_subsystem/hpdcache

0 comments on commit 45ffb59

Please sign in to comment.