fix: support of AMOs in cv32 configurations (#1841)

This commit is contained in:
Cesar Fuguet 2024-02-18 23:30:41 +01:00 committed by GitHub
parent 3d7e417bce
commit 45ffb59980
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 59 additions and 39 deletions

View file

@ -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

@ -1 +1 @@
Subproject commit 04f338b2e976a5e7a8a512f224d9c5d59d3be4d3
Subproject commit 41fe79977aa86fc4be8066839c1ea64304d606f8