Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ sources:
- src/ccu/ace_ccu_snoop_path.sv
- src/ccu/ace_ccu_master_path.sv
- src/ccu/ace_ccu_conflict_manager.sv
- src/ccu/ace_ccu_atomic_manager.sv
- src/ccu/ace_ccu_top.sv
#- src/ccu_ctrl_pkg.sv
## Level 2
Expand Down
10 changes: 9 additions & 1 deletion src/ace_ar_transaction_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ module ace_ar_transaction_decoder import ace_pkg::*; #(

arsnoop_t arsnoop;

logic lock;

logic is_shareable;
logic is_system;
logic is_barrier;
Expand All @@ -32,6 +34,7 @@ logic dvm_complete;
logic dvm_message;

assign arsnoop = ar_i.snoop;
assign lock = ar_i.lock;

assign is_shareable = ar_i.domain inside {InnerShareable, OuterShareable};
assign is_system = ar_i.domain inside {System};
Expand Down Expand Up @@ -59,6 +62,8 @@ always_comb begin
snoop_info_o.accepts_dirty = 1'b0;
snoop_info_o.accepts_dirty_shared = 1'b0;
snoop_info_o.accepts_shared = 1'b0;
snoop_info_o.excl_load = 1'b0;
snoop_info_o.excl_store = 1'b0;
unique case (1'b1)
read_no_snoop: begin
snooping_o = 1'b0;
Expand All @@ -70,9 +75,11 @@ always_comb begin
snoop_info_o.accepts_dirty = 1'b1;
snoop_info_o.accepts_dirty_shared = 1'b1;
snoop_info_o.accepts_shared = 1'b1;
snoop_info_o.excl_load = lock;
end
read_clean: begin
snoop_info_o.accepts_shared = 1'b1;
snoop_info_o.excl_load = lock;
end
read_not_shared_dirty: begin
snoop_info_o.accepts_dirty = 1'b1;
Expand All @@ -82,7 +89,8 @@ always_comb begin
snoop_info_o.accepts_dirty = 1'b1;
end
clean_unique: begin
snoop_info_o.snoop_trs = acsnoop_t'(CleanInvalid);
snoop_info_o.snoop_trs = acsnoop_t'(CleanInvalid);
snoop_info_o.excl_store = lock;
end
make_unique: begin
snoop_info_o.snoop_trs = acsnoop_t'(MakeInvalid);
Expand Down
2 changes: 2 additions & 0 deletions src/ace_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ package ace_pkg;
logic accepts_dirty;
logic accepts_dirty_shared;
logic accepts_shared;
logic excl_load;
logic excl_store;
} snoop_info_t;

///////////////
Expand Down
47 changes: 47 additions & 0 deletions src/ccu/ace_ccu_atomic_manager.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Manager for monitoring Exclusive sequences
// Similar to the PoS monitor defined in the ACE spec
module ace_ccu_atomic_manager #(
parameter int unsigned AmIdxWidth = 0,
parameter type mst_idx_t = logic,

localparam type am_idx_t = logic [AmIdxWidth-1:0]
) (
input logic clk_i,
input logic rst_ni,

input logic am_ex_load_i,
input logic am_ex_store_i,
input am_idx_t am_ex_addr_i,
/// Master ID
input mst_idx_t am_ex_id_i,
output logic am_ex_okay_o
);

localparam int unsigned NumEntries = 2**AmIdxWidth;

mst_idx_t [NumEntries-1:0] id_mask_q, id_mask_d;

always_comb begin
id_mask_d = id_mask_q;
am_ex_okay_o = 1'b0;
if (am_ex_store_i) begin
// Exclusive Store
static mst_idx_t new_mask = id_mask_q[am_ex_addr_i] & am_ex_id_i;
id_mask_d[am_ex_addr_i] = new_mask;
am_ex_okay_o = !(new_mask == 0);
end else if (am_ex_load_i) begin
// Exclusive Load
id_mask_d[am_ex_addr_i] = id_mask_q[am_ex_addr_i] | am_ex_id_i;
am_ex_okay_o = 1'b1;
end
end

always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
id_mask_q <= '0;
end else begin
id_mask_q <= id_mask_d;
end
end

endmodule
17 changes: 14 additions & 3 deletions src/ccu/ace_ccu_master_path.sv
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module ace_ccu_master_path import ace_pkg::*;
parameter type snoop_resp_t = logic,
parameter type domain_mask_t = logic,
parameter type domain_set_t = logic,
parameter type mst_idx_t = logic,
// Local parameters
localparam int unsigned NoGroups = NoSlvPorts / NoSlvPerGroup,
localparam int unsigned NoSnoopPortsPerGroup = 2,
Expand All @@ -47,12 +48,17 @@ module ace_ccu_master_path import ace_pkg::*;
output slv_resp_t [NoSlvPorts-1:0] slv_resp_o,
output snoop_req_t [NoSnoopPorts-1:0] snoop_req_o,
output domain_mask_t[NoSnoopPorts-1:0] snoop_masks_o,
output mst_idx_t [NoSnoopPorts-1:0] snoop_idx_o,
input snoop_resp_t [NoSnoopPorts-1:0] snoop_resp_i,
output mst_req_t mst_req_o,
input mst_resp_t mst_resp_i,

output logic [2*NoGroups-1:0] cm_req_o,
output cm_addr_t [2*NoGroups-1:0] cm_addr_o
output cm_addr_t [2*NoGroups-1:0] cm_addr_o,

output logic [2*NoGroups-1:0] excl_load_o,
output logic [2*NoGroups-1:0] excl_store_o,
input logic [2*NoGroups-1:0] excl_resp_i
);

typedef logic [AxiAddrWidth -1:0] addr_t;
Expand Down Expand Up @@ -376,7 +382,8 @@ module ace_ccu_master_path import ace_pkg::*;
.snoop_req_t (snoop_req_t),
.snoop_resp_t (snoop_resp_t),
.domain_mask_t (domain_mask_t),
.domain_set_t (domain_set_t)
.domain_set_t (domain_set_t),
.mst_idx_t (mst_idx_t)
) i_snoop_path (
.clk_i (clk_i),
.rst_ni (rst_ni),
Expand All @@ -387,7 +394,11 @@ module ace_ccu_master_path import ace_pkg::*;
.domain_set_i (domain_set_i [(NoSlvPerGroup*i)+:NoSlvPerGroup]),
.snoop_reqs_o (snoop_req_o [(2*i)+:2]),
.snoop_resps_i (snoop_resp_i [(2*i)+:2]),
.snoop_masks_o (snoop_masks_o [(2*i)+:2])
.snoop_masks_o (snoop_masks_o [(2*i)+:2]),
.snoop_idx_o (snoop_idx_o [(2*i)+:2]),
.excl_load_o (excl_load_o [(2*i)+:2]),
.excl_store_o (excl_store_o [(2*i)+:2]),
.excl_resp_i (excl_resp_i [(2*i)+:2])
);

for (genvar j = 1; j < NoMemPortsPerGroup; j++) begin : gen_ace_to_axi
Expand Down
76 changes: 59 additions & 17 deletions src/ccu/ace_ccu_snoop_interconnect.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
parameter bit BufferInpResp = 1,
parameter int unsigned CmAddrWidth = 0,
parameter int unsigned CmAddrBase = 0,
parameter int unsigned AmAddrWidth = 0,
parameter int unsigned AmAddrBase = 0,
parameter type ac_chan_t = logic,
parameter type cr_chan_t = logic,
parameter type cd_chan_t = logic,
parameter type snoop_req_t = logic,
parameter type snoop_resp_t = logic,
parameter type mst_idx_t = logic,

localparam type oup_sel_t = logic [NumOup-1:0],
localparam type cm_addr_t = logic [CmAddrWidth-1:0]
Expand All @@ -22,11 +25,16 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
input logic rst_ni,

input oup_sel_t [NumInp-1:0] inp_sel_i,
input mst_idx_t [NumInp-1:0] inp_idx_i,
input snoop_req_t [NumInp-1:0] inp_req_i,
output snoop_resp_t [NumInp-1:0] inp_resp_o,
output snoop_req_t [NumOup-1:0] oup_req_o,
input snoop_resp_t [NumOup-1:0] oup_resp_i,

input logic [NumInp-1:0] excl_load_i,
input logic [NumInp-1:0] excl_store_i,
output logic [NumInp-1:0] excl_resp_o,

output logic cm_valid_o,
output logic cm_ready_o,
output cm_addr_t cm_addr_o,
Expand All @@ -38,6 +46,7 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
typedef struct packed {
oup_sel_t sel;
inp_idx_t idx;
logic excl_okay;
} ctrl_t;

logic [NumInp-1:0] inp_ac_valids, inp_ac_readies;
Expand All @@ -46,9 +55,10 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
cr_chan_t [NumInp-1:0] inp_cr_chans;
logic [NumInp-1:0] inp_cd_valids, inp_cd_readies;
cd_chan_t [NumInp-1:0] inp_cd_chans;
logic [NumInp-1:0] inp_excl_load, inp_excl_store;

oup_sel_t [NumInp-1:0] inp_sel;

mst_idx_t [NumInp-1:0] inp_idx;

logic [NumOup-1:0] oup_ac_valids, oup_ac_readies;
ac_chan_t [NumOup-1:0] oup_ac_chans;
Expand All @@ -59,7 +69,9 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(

logic ac_valid, ac_ready;
logic oup_ac_valid, oup_ac_ready;
logic oup_excl_load, oup_excl_store;
ac_chan_t ac_chan;
mst_idx_t ac_mst_idx;

logic req_ctrl_valid, req_ctrl_ready;
logic resp_ctrl_valid, resp_ctrl_ready;
Expand All @@ -77,15 +89,24 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
typedef struct packed {
ac_chan_t ac;
oup_sel_t sel;
mst_idx_t idx;
logic excl_load;
logic excl_store;
} ac_fifo_entry_t;

ac_fifo_entry_t ac_fifo_in, ac_fifo_out;

assign ac_fifo_in.ac = inp_req_i[i].ac;
assign ac_fifo_in.sel = inp_sel_i[i];
assign ac_fifo_in.ac = inp_req_i[i].ac;
assign ac_fifo_in.sel = inp_sel_i[i];
assign ac_fifo_in.idx = inp_idx_i[i];
assign ac_fifo_in.excl_load = excl_load_i[i];
assign ac_fifo_in.excl_store = excl_store_i[i];

assign inp_ac_chans[i] = ac_fifo_out.ac;
assign inp_sel[i] = ac_fifo_out.sel;
assign inp_ac_chans[i] = ac_fifo_out.ac;
assign inp_sel[i] = ac_fifo_out.sel;
assign inp_idx[i] = ac_fifo_out.idx;
assign inp_excl_load[i] = ac_fifo_out.excl_load;
assign inp_excl_store[i] = ac_fifo_out.excl_store;

stream_fifo_optimal_wrap #(
.Depth (2),
Expand All @@ -108,11 +129,21 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
assign inp_resp_o[i].ac_ready = inp_ac_readies[i];
assign inp_ac_chans[i] = inp_req_i[i].ac;
assign inp_sel[i] = inp_sel_i[i];
assign inp_idx[i] = inp_idx_i[i];
assign inp_excl_load[i] = excl_load_i[i];
assign inp_excl_store[i] = excl_store_i[i];
end
if (BufferInpResp) begin : gen_buffer_resp

typedef struct packed {
snoop_resp_t cr_resp;
logic excl_okay;
} cr_bundle_t;
cr_bundle_t cr_in, cr_out;

stream_fifo_optimal_wrap #(
.Depth (2),
.type_t (cr_chan_t)
.type_t (cr_bundle_t)
) i_cr_fifo (
.clk_i,
.rst_ni,
Expand All @@ -121,10 +152,10 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
.usage_o (),
.valid_i (inp_cr_valids [i]),
.ready_o (inp_cr_readies[i]),
.data_i (inp_cr_chans [i]),
.data_i (cr_in),
.valid_o (inp_resp_o[i].cr_valid),
.ready_i (inp_req_i [i].cr_ready),
.data_o (inp_resp_o[i].cr_resp)
.data_o (cr_out)
);
stream_fifo_optimal_wrap #(
.Depth (4),
Expand All @@ -142,13 +173,18 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
.ready_i (inp_req_i [i].cd_ready),
.data_o (inp_resp_o[i].cd)
);
assign cr_in.cr_resp = inp_cr_chans[i];
assign cr_in.excl_okay = cr_ctrl.excl_okay;
assign inp_resp_o[i].cr_resp = cr_out.cr_resp;
assign excl_resp_o[i] = cr_out.excl_okay;
end else begin : gen_no_buffer_resp
assign inp_cr_readies[i] = inp_req_i[i].cr_ready;
assign inp_resp_o[i].cr_valid = inp_cr_valids[i];
assign inp_resp_o[i].cr_resp = inp_cr_chans[i];
assign inp_cd_readies[i] = inp_req_i[i].cd_ready;
assign inp_resp_o[i].cd_valid = inp_cd_valids[i];
assign inp_resp_o[i].cd = inp_cd_chans[i];
assign excl_resp_o[i] = cr_ctrl.excl_okay;
end
end

Expand Down Expand Up @@ -219,17 +255,23 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
end

ace_ccu_snoop_req #(
.NumInp (NumInp),
.NumOup (NumOup),
.ac_chan_t (ac_chan_t),
.ctrl_t (ctrl_t)
.NumInp (NumInp),
.NumOup (NumOup),
.AmAddrWidth (AmAddrWidth),
.AmAddrBase (AmAddrBase),
.ac_chan_t (ac_chan_t),
.ctrl_t (ctrl_t),
.mst_idx_t (mst_idx_t)
) i_snoop_req (
.clk_i,
.rst_ni,
.ac_valids_i (inp_ac_valids),
.ac_readies_o (inp_ac_readies),
.ac_chans_i (inp_ac_chans),
.ac_mst_idxs_i (inp_idx),
.ac_sel_i (inp_sel),
.excl_load_i (inp_excl_load),
.excl_store_i (inp_excl_store),
.ac_valid_o (ac_valid),
.ac_ready_i (ac_ready),
.ac_chan_o (ac_chan),
Expand All @@ -238,11 +280,11 @@ module ace_ccu_snoop_interconnect import ace_pkg::*; #(
.ctrl_o (req_ctrl)
);

assign cm_valid_o = ac_valid;
assign cm_ready_o = oup_ac_ready;
assign cm_addr_o = ac_chan.addr[CmAddrBase+:CmAddrWidth];
assign ac_ready = oup_ac_ready && !cm_stall_i;
assign oup_ac_valid = ac_valid && !cm_stall_i;
assign cm_valid_o = ac_valid;
assign cm_ready_o = oup_ac_ready;
assign cm_addr_o = ac_chan.addr[CmAddrBase+:CmAddrWidth];
assign ac_ready = oup_ac_ready && !cm_stall_i;
assign oup_ac_valid = ac_valid && !cm_stall_i;

stream_fifo_optimal_wrap #(
.Depth (2),
Expand Down
Loading