Skip to content

Commit

Permalink
[hw,tlul_adapter_reg,rtl] Add RACL support
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Jan 8, 2025
1 parent 69f3aaa commit f571831
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 22 deletions.
1 change: 1 addition & 0 deletions hw/ip/tlul/adapter_reg.core
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ filesets:
- lowrisc:prim:secded
- lowrisc:tlul:common
- lowrisc:tlul:trans_intg
- lowrisc:systems:top_racl_pkg
files:
- rtl/tlul_adapter_reg.sv
file_type: systemVerilogSource
Expand Down
80 changes: 58 additions & 22 deletions hw/ip/tlul/rtl/tlul_adapter_reg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ module tlul_adapter_reg
import tlul_pkg::*;
import prim_mubi_pkg::mubi4_t;
#(
parameter bit CmdIntgCheck = 0, // 1: Enable command integrity check
parameter bit EnableRspIntgGen = 0, // 1: Generate response integrity
parameter bit EnableDataIntgGen = 0, // 1: Generate response data integrity
parameter int RegAw = 8, // Width of register address
parameter int RegDw = 32, // Shall be matched with TL_DW
parameter int AccessLatency = 0, // 0: same cycle, 1: next cycle
parameter bit CmdIntgCheck = 0, // 1: Enable command integrity check
parameter bit EnableRspIntgGen = 0, // 1: Generate response integrity
parameter bit EnableDataIntgGen = 0, // 1: Generate response data integrity
parameter int RegAw = 8, // Width of register address
parameter int RegDw = 32, // Shall be matched with TL_DW
parameter int AccessLatency = 0, // 0: same cycle, 1: next cycle
parameter bit EnableRacl = 0, // 1: Enable RACL checks on access
parameter bit RaclErrorRsp = 1, // 1: Return TLUL error on RACL errors
localparam int RegBw = RegDw/8
) (
input clk_i,
Expand All @@ -39,6 +41,12 @@ module tlul_adapter_reg
input mubi4_t en_ifetch_i,
output logic intg_error_o,

// RACL interface
input top_racl_pkg::racl_policy_vec_t racl_policies_i,
input integer racl_policy_sel_i,
output logic racl_error_o,
output top_racl_pkg::racl_error_log_t racl_error_log_o,

// Register interface
output logic re_o,
output logic we_o,
Expand Down Expand Up @@ -72,15 +80,39 @@ module tlul_adapter_reg
tl_d_op_e rspop_q;

logic rd_req, wr_req;
logic racl_read_allowed, racl_write_allowed, racl_violation;

if (EnableRacl) begin : gen_racl_role_logic
// Retrieve RACL role from user bits and one-hot encode that for the comparison bitmap
top_racl_pkg::racl_role_t racl_role;
assign racl_role = top_racl_pkg::tlul_extract_racl_role_bits(tl_i.a_user.rsvd);

top_racl_pkg::racl_role_vec_t racl_role_vec;
prim_onehot_enc #(
.OneHotWidth( $bits(prim_onehot_enc) )
) u_racl_role_encode (
.in_i ( racl_role ),
.en_i ( 1'b1 ),
.out_o( racl_role_vec )
);

assign racl_read_allowed = (|(racl_policies_i[racl_policy_sel_i].read_perm & racl_role_vec));
assign racl_write_allowed = (|(racl_policies_i[racl_policy_sel_i].write_perm & racl_role_vec));
assign racl_violation = (rd_req & ~racl_read_allowed) | (wr_req & ~racl_write_allowed);
end else begin : gen_no_racl_role_logic
assign racl_read_allowed = 1'b1;
assign racl_write_allowed = 1'b1;
assign racl_violation = 1'b0;
end

assign a_ack = tl_i.a_valid & tl_o.a_ready;
assign d_ack = tl_o.d_valid & tl_i.d_ready;
// Request signal
assign wr_req = a_ack & ((tl_i.a_opcode == PutFullData) | (tl_i.a_opcode == PutPartialData));
assign rd_req = a_ack & (tl_i.a_opcode == Get);

assign we_o = wr_req & ~err_internal;
assign re_o = rd_req & ~err_internal;
assign we_o = wr_req & racl_write_allowed & ~err_internal;
assign re_o = rd_req & racl_read_allowed & ~err_internal;
assign wdata_o = tl_i.a_data;
assign be_o = tl_i.a_mask;

Expand Down Expand Up @@ -110,29 +142,32 @@ module tlul_adapter_reg
end

if (AccessLatency == 1) begin : gen_access_latency1
logic wr_req_q, rd_req_q;
logic wr_req_q, rd_req_q, racl_violation_q;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
rdata_q <= '0;
error_q <= 1'b0;
wr_req_q <= 1'b0;
rd_req_q <= 1'b0;
rdata_q <= '0;
error_q <= 1'b0;
wr_req_q <= 1'b0;
rd_req_q <= 1'b0;
racl_violation_q <= 1'b0;
end else begin
rd_req_q <= rd_req;
wr_req_q <= wr_req;
rd_req_q <= rd_req;
wr_req_q <= wr_req;
racl_violation_q <= racl_violation;
// Addressing phase
if (a_ack) begin
error_q <= err_internal;
error_q <= err_internal || (RaclErrorRsp & racl_violation);
// Response phase
end else begin
error_q <= error;
rdata_q <= rdata;
end
end
end
assign rdata = (error_i || error_q || wr_req_q) ? '1 :
(rd_req_q) ? rdata_i :
rdata_q; // backpressure case
assign rdata = (error_i || error_q || racl_violation_q || wr_req_q) ? '1 :
(rd_req_q) ? rdata_i :
// backpressure case
rdata_q;
assign error = (rd_req_q || wr_req_q) ? (error_q || error_i) :
error_q; // backpressure case
end else begin : gen_access_latency0
Expand All @@ -141,8 +176,8 @@ module tlul_adapter_reg
rdata_q <= '0;
error_q <= 1'b0;
end else if (a_ack) begin
rdata_q <= (error_i || err_internal || wr_req) ? '1 : rdata_i;
error_q <= error_i || err_internal;
rdata_q <= (error_i || err_internal || wr_req || racl_violation) ? '1 : rdata_i;
error_q <= error_i || err_internal || (RaclErrorRsp & racl_violation);
end
end
assign rdata = rdata_q;
Expand Down Expand Up @@ -202,7 +237,8 @@ module tlul_adapter_reg
assign instr_error = prim_mubi_pkg::mubi4_test_true_strict(tl_i.a_user.instr_type) &
prim_mubi_pkg::mubi4_test_false_loose(en_ifetch_i);

assign err_internal = addr_align_err | tl_err | instr_error | intg_error;
assign err_internal = addr_align_err | tl_err | instr_error | intg_error |
(RaclErrorRsp & racl_error);

// addr_align_err
// Raised if addr isn't aligned with the size
Expand Down

0 comments on commit f571831

Please sign in to comment.