Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add xnxti support #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
11 changes: 8 additions & 3 deletions src/clic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ module clic import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
localparam logic [1:0] M_MODE = 2'b11;

localparam logic [15:0] MCLICCFG_START = 16'h0000;
localparam logic [15:0] MCLICCFG_END = 16'h0800;
localparam logic [15:0] MCLICINT_START = 16'h1000;
localparam logic [15:0] MCLICINT_END = 16'h4fff;

Expand All @@ -81,6 +82,7 @@ module clic import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
logic [N_SOURCE-1:0] shv; // Handle per-irq SHV bits

logic [N_SOURCE-1:0] claim;
logic mnxti_cfg;

// handle incoming interrupts
clic_gateway #(
Expand Down Expand Up @@ -123,7 +125,9 @@ module clic import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
.irq_mode_o (irq_mode),

.irq_kill_req_o,
.irq_kill_ack_i
.irq_kill_ack_i,

.mnxti_cfg_i (mnxti_cfg)
);

// configuration registers
Expand Down Expand Up @@ -198,7 +202,7 @@ module clic import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
reg_rsp_o = '0;

unique case(reg_req_i.addr[15:0]) inside
MCLICCFG_START: begin
[MCLICCFG_START:MCLICCFG_END]: begin
reg_mclic_req = reg_req_i;
reg_rsp_o = reg_mclic_rsp;
end
Expand Down Expand Up @@ -261,7 +265,8 @@ module clic import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
.ie_o (ie),
.le_o (le),

.ip_i (ip)
.ip_i (ip),
.mnxti_cfg_o(mnxti_cfg)
);

// Create level and prio signals with dynamic indexing (#bits are read from
Expand Down
5 changes: 4 additions & 1 deletion src/clic_reg_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ module clic_reg_adapter import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
output logic [N_SOURCE-1:0] ie_o,
output logic [N_SOURCE-1:0] le_o,

input logic [N_SOURCE-1:0] ip_i
input logic [N_SOURCE-1:0] ip_i,
output logic mnxti_cfg_o
);

// We only support positive edge triggered and positive level triggered
Expand All @@ -50,4 +51,6 @@ module clic_reg_adapter import mclic_reg_pkg::*; import clicint_reg_pkg::*; #(
assign le_o[i] = clicint_reg2hw[i].clicint.attr_trig.q[0];
end

assign mnxti_cfg_o = mclic_reg2hw.clicmnxticonf.q;

endmodule // clic_reg_adapter
19 changes: 15 additions & 4 deletions src/clic_target.sv
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ module clic_target #(
output logic [ModeWidth-1:0] irq_mode_o,

output logic irq_kill_req_o,
input logic irq_kill_ack_i
input logic irq_kill_ack_i,
input logic mnxti_cfg_i
);

// this only works with 2 or more sources
Expand Down Expand Up @@ -185,9 +186,19 @@ module clic_target #(
// wait for handshake
ACK: begin
irq_valid_d = 1'b1;
irq_id_d = irq_id_q;
irq_max_d = irq_max_q;
irq_mode_d = irq_mode_q;
if (!mnxti_cfg_i) begin
irq_id_d = irq_id_q;
irq_max_d = irq_max_q;
irq_mode_d = irq_mode_q;
end else begin
if (irq_root_valid) begin
irq_id_d = irq_root_id; // give irq_id_d the most updated value
irq_max_d = max_tree[0]; // give irq_max_d the most updated value
end else begin
irq_id_d = '0;
irq_max_d = '0;
end
end
// level sensitive interrupts (le_i == 1'b0) can be cleared (ip_i goes
// to 1'b0) and shouldn't fire anymore so we should get unstuck here
if (!le_i[irq_id_q] && !ip_i[irq_id_q]) begin
Expand Down
8 changes: 8 additions & 0 deletions src/gen/mclic.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
{ bits: "3:0", name: "mnlbits", desc: "number of interrupt level bits in machine mode" },
],
},
{ name: "CLICMNXTICONF",
desc: "CLIC enable mnxti irq forwarding logic",
swaccess: "rw",
hwaccess: "hro",
fields: [
{ bits: "0" }
],
},
]
}

20 changes: 14 additions & 6 deletions src/mclic_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package mclic_reg_pkg;

// Address widths within the block
parameter int BlockAw = 2;
parameter int BlockAw = 3;

////////////////////////////
// Typedefs for registers //
Expand All @@ -28,22 +28,30 @@ package mclic_reg_pkg;
} unlbits;
} mclic_reg2hw_mcliccfg_reg_t;

typedef struct packed {
logic q;
} mclic_reg2hw_clicmnxticonf_reg_t;

// Register -> HW type
typedef struct packed {
mclic_reg2hw_mcliccfg_reg_t mcliccfg; // [13:0]
mclic_reg2hw_mcliccfg_reg_t mcliccfg; // [14:1]
mclic_reg2hw_clicmnxticonf_reg_t clicmnxticonf; // [0:0]
} mclic_reg2hw_t;

// Register offsets
parameter logic [BlockAw-1:0] MCLIC_MCLICCFG_OFFSET = 2'h 0;
parameter logic [BlockAw-1:0] MCLIC_MCLICCFG_OFFSET = 3'h 0;
parameter logic [BlockAw-1:0] MCLIC_CLICMNXTICONF_OFFSET = 3'h 4;

// Register index
typedef enum int {
MCLIC_MCLICCFG
MCLIC_MCLICCFG,
MCLIC_CLICMNXTICONF
} mclic_id_e;

// Register width information to check illegal writes
parameter logic [3:0] MCLIC_PERMIT [1] = '{
4'b 1111 // index[0] MCLIC_MCLICCFG
parameter logic [3:0] MCLIC_PERMIT [2] = '{
4'b 1111, // index[0] MCLIC_MCLICCFG
4'b 0001 // index[1] MCLIC_CLICMNXTICONF
};

endpackage
Expand Down
47 changes: 43 additions & 4 deletions src/mclic_reg_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
module mclic_reg_top #(
parameter type reg_req_t = logic,
parameter type reg_rsp_t = logic,
parameter int AW = 2
parameter int AW = 3
) (
input logic clk_i,
input logic rst_ni,
Expand Down Expand Up @@ -80,6 +80,9 @@ module mclic_reg_top #(
logic [3:0] mcliccfg_unlbits_wd;
logic mcliccfg_unlbits_we;
logic [3:0] mcliccfg_reserved_qs;
logic clicmnxticonf_qs;
logic clicmnxticonf_wd;
logic clicmnxticonf_we;

// Register instances
// R[mcliccfg]: V(False)
Expand Down Expand Up @@ -193,20 +196,49 @@ module mclic_reg_top #(
assign mcliccfg_reserved_qs = 4'h0;


// R[clicmnxticonf]: V(False)

prim_subreg #(
.DW (1),
.SWACCESS("RW"),
.RESVAL (1'h0)
) u_clicmnxticonf (
.clk_i (clk_i ),
.rst_ni (rst_ni ),

// from register interface
.we (clicmnxticonf_we),
.wd (clicmnxticonf_wd),

// from internal hardware
.de (1'b0),
.d ('0 ),

// to internal hardware
.qe (),
.q (reg2hw.clicmnxticonf.q ),

// to register interface (read)
.qs (clicmnxticonf_qs)
);


logic [0:0] addr_hit;


logic [1:0] addr_hit;
always_comb begin
addr_hit = '0;
addr_hit[0] = (reg_addr == MCLIC_MCLICCFG_OFFSET);
addr_hit[1] = (reg_addr == MCLIC_CLICMNXTICONF_OFFSET);
end

assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;

// Check sub-word write is permitted
always_comb begin
wr_err = (reg_we &
((addr_hit[0] & (|(MCLIC_PERMIT[0] & ~reg_be)))));
((addr_hit[0] & (|(MCLIC_PERMIT[0] & ~reg_be))) |
(addr_hit[1] & (|(MCLIC_PERMIT[1] & ~reg_be)))));
end

assign mcliccfg_mnlbits_we = addr_hit[0] & reg_we & !reg_error;
Expand All @@ -221,6 +253,9 @@ module mclic_reg_top #(
assign mcliccfg_unlbits_we = addr_hit[0] & reg_we & !reg_error;
assign mcliccfg_unlbits_wd = reg_wdata[27:24];

assign clicmnxticonf_we = addr_hit[1] & reg_we & !reg_error;
assign clicmnxticonf_wd = reg_wdata[0];

// Read data return
always_comb begin
reg_rdata_next = '0;
Expand All @@ -233,6 +268,10 @@ module mclic_reg_top #(
reg_rdata_next[31:28] = mcliccfg_reserved_qs;
end

addr_hit[1]: begin
reg_rdata_next[0] = clicmnxticonf_qs;
end

default: begin
reg_rdata_next = '1;
end
Expand All @@ -255,7 +294,7 @@ endmodule

module mclic_reg_top_intf
#(
parameter int AW = 2,
parameter int AW = 3,
localparam int DW = 32
) (
input logic clk_i,
Expand Down