Skip to content

Expose ports #239

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

Open
wants to merge 3 commits into
base: main
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
59 changes: 41 additions & 18 deletions hw/mem_interface/src/mem_wide_narrow_mux.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mem_wide_narrow_mux_intf module at the end of the file should also be adapted. In my view, we could also just get rid of it entirely otherwise.

Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@

`include "common_cells/assertions.svh"

/// This module multiplexes many narrow ports and one wide port onto many narrow
/// ports. The wide or narrow ports can be selected by using the `sel_wide_i` signal.
///
/// `1` selects the wide port.
/// `0` selects the narrow port.
/// This module multiplexes many narrow ports, one wide port, and one external port onto many narrow
/// ports. Arbitration is done statically: the wide port has the highest priority,
/// followed by the external port, and finally the narrow ports.
///
/// ## Constraint
///
Expand All @@ -21,7 +19,7 @@
/// ## Caution
///
/// As of now this module's request always need an immediate grant in case
/// `sel_wide_i` is high. Any delayed grant will break the module's behavior.
/// `in_wide_req_i.q_valid` is high. Any delayed grant will break the module's behavior.
module mem_wide_narrow_mux #(
/// Width of narrow data.
parameter int unsigned NarrowDataWidth = 0,
Expand All @@ -37,6 +35,10 @@ module mem_wide_narrow_mux #(
parameter type mem_wide_req_t = logic,
/// Response type of wide inputs.
parameter type mem_wide_rsp_t = logic,
/// Request type of ext inputs.
parameter type mem_ext_req_t = logic,
/// Response type of ext inputs.
parameter type mem_ext_rsp_t = logic,
/// Derived. *Do not override*
/// Number of narrow inputs.
parameter int unsigned NrPorts = WideDataWidth / NarrowDataWidth
Expand All @@ -50,11 +52,12 @@ module mem_wide_narrow_mux #(
/// Wide side.
input mem_wide_req_t in_wide_req_i,
output mem_wide_rsp_t in_wide_rsp_o,
/// External side.
input mem_ext_req_t in_ext_req_i,
output mem_ext_rsp_t in_ext_rsp_o,
// Multiplexed output.
output mem_narrow_req_t [NrPorts-1:0] out_req_o,
input mem_narrow_rsp_t [NrPorts-1:0] out_rsp_i,
/// `0`: Use narrow port, `1`: Use wide port
input logic sel_wide_i
input mem_narrow_rsp_t [NrPorts-1:0] out_rsp_i
);

localparam int unsigned NarrowStrbWidth = NarrowDataWidth/8;
Expand All @@ -67,18 +70,20 @@ module mem_wide_narrow_mux #(
// Broadcast data from all banks.
for (int i = 0; i < NrPorts; i++) begin
in_wide_rsp_o.p[i*NarrowDataWidth+:NarrowDataWidth] = out_rsp_i[i].p.data;
in_ext_rsp_o.p[i*NarrowDataWidth+:NarrowDataWidth] = out_rsp_i[i].p.data;
end

// ---------------
// Forward Channel
// ---------------
// By default feed through narrow requests.
out_req_o = in_narrow_req_i;
// Tie-off wide by default.
// Tie-off wide and ext by default.
in_wide_rsp_o.q_ready = 1'b0;
in_ext_rsp_o.q_ready = 1'b0;

// The wide port is selected.
if (sel_wide_i) begin
// The wide port has the highest priority
if (in_wide_req_i.q_valid) begin
for (int i = 0; i < NrPorts; i++) begin
out_req_o[i].q_valid = in_wide_req_i.q_valid;
// Block access from narrow ports.
Expand All @@ -92,9 +97,25 @@ module mem_wide_narrow_mux #(
user: in_wide_req_i.q.user
};
// The protocol requires that the response is always granted
// immediately (at least when `sel_wide_i` is high).
// immediately (at least when `in_wide_req_i.q_valid` is high).
in_wide_rsp_o.q_ready = 1'b1;
end
end else if (in_ext_req_i.q_valid) begin // The ext port has the second highest priority
for (int i = 0; i < NrPorts; i++) begin
out_req_o[i].q_valid = in_ext_req_i.q_valid;
// Block access from narrow ports.
in_narrow_rsp_o[i].q_ready = 1'b0;
out_req_o[i].q = '{
addr: in_ext_req_i.q.addr,
write: in_ext_req_i.q.write,
amo: reqrsp_pkg::AMONone,
data: in_ext_req_i.q.data[i*NarrowDataWidth+:NarrowDataWidth],
strb: in_ext_req_i.q.strb[i*NarrowStrbWidth+:NarrowStrbWidth],
user: in_ext_req_i.q.user
};

in_ext_rsp_o.q_ready = 1'b1;
end
end
end

Expand All @@ -108,21 +129,23 @@ module mem_wide_narrow_mux #(
logic [NrPorts-1:0] q_valid_flat;
logic [NrPorts-1:0][NarrowDataWidth-1:0] q_data;
logic [NrPorts-1:0][NarrowStrbWidth-1:0] q_strb;
// verilog_lint: waive-start line-length
`ASSERT(ImmediateGrantWide, in_wide_req_i.q_valid |-> in_wide_rsp_o.q_ready)
for (genvar i = 0; i < NrPorts; i++) begin : gen_per_port
assign q_valid_flat[i] = out_req_o[i].q_valid;
assign q_data[i] = out_req_o[i].q.data;
assign q_strb[i] = out_req_o[i].q.strb;
`ASSERT(ImmediateGrantOut, sel_wide_i & out_req_o[i].q_valid |-> out_rsp_i[i].q_ready)
`ASSERT(SilentNarrow, sel_wide_i |-> !in_narrow_rsp_o[i].q_ready)
`ASSERT(NarrowPassThrough, !sel_wide_i & in_narrow_req_i[i].q_valid |-> out_req_o[i].q_valid)
`ASSERT(ImmediateGrantOut, in_wide_req_i.q_valid & out_req_o[i].q_valid |-> out_rsp_i[i].q_ready)
`ASSERT(SilentNarrow, in_wide_req_i.q_valid |-> !in_narrow_rsp_o[i].q_ready)
`ASSERT(NarrowPassThrough, !in_wide_req_i.q_valid & in_narrow_req_i[i].q_valid |-> out_req_o[i].q_valid)
end
`ASSERT(DmaSelected, sel_wide_i & in_wide_req_i.q_valid |-> &q_valid_flat)
`ASSERT(DmaSelected, in_wide_req_i.q_valid & in_wide_req_i.q_valid |-> &q_valid_flat)
`ASSERT(DmaSelectedReadyWhenValid,
sel_wide_i & in_wide_req_i.q_valid |-> in_wide_rsp_o.q_ready)
in_wide_req_i.q_valid & in_wide_req_i.q_valid |-> in_wide_rsp_o.q_ready)
`ASSERT(DMAWriteDataCorrect,
in_wide_req_i.q_valid & in_wide_rsp_o.q_ready |->
(in_wide_req_i.q.data == q_data) && (in_wide_req_i.q.strb == q_strb))
// verilog_lint: waive-stop line-length

Comment on lines +132 to 149
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should extend these to cover also the newly added external port. Let's come back to this next week.

endmodule

Expand Down
12 changes: 10 additions & 2 deletions hw/snitch/src/snitch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
logic interrupt, ecall, ebreak;
logic zero_lsb;

logic meip, mtip, msip, mcip;
logic meip, mtip, msip, mcip, mxip;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly is the mxip? What does it stand for? Accelerator, external...?

Why is it needed? Can the existing meip not be used instead?

logic seip, stip, ssip, scip;
logic interrupts_enabled;
logic any_interrupt_pending;
Expand Down Expand Up @@ -266,6 +266,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
logic [1:0] tie_d, tie_q;
logic [1:0] sie_d, sie_q;
logic [1:0] cie_d, cie_q;
logic [1:0] xie_d, xie_q;
logic seip_d, seip_q;
logic stip_d, stip_q;
logic ssip_d, ssip_q;
Expand Down Expand Up @@ -299,6 +300,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
`FFAR(tie_q, tie_d, '0, clk_i, rst_i)
`FFAR(sie_q, sie_d, '0, clk_i, rst_i)
`FFAR(cie_q, cie_d, '0, clk_i, rst_i)
`FFAR(xie_q, xie_d, '0, clk_i, rst_i)
`FFAR(seip_q, seip_d, '0, clk_i, rst_i)
`FFAR(stip_q, stip_d, '0, clk_i, rst_i)
`FFAR(ssip_q, ssip_d, '0, clk_i, rst_i)
Expand Down Expand Up @@ -2296,14 +2298,15 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
assign mtip = irq_i.mtip & tie_q[M];
assign msip = irq_i.msip & sie_q[M];
assign mcip = irq_i.mcip & cie_q[M];
assign mxip = irq_i.mxip & xie_q[M];

assign seip = seip_q & eie_q[S];
assign stip = stip_q & tie_q[S];
assign ssip = ssip_q & sie_q[S];
assign scip = scip_q & cie_q[S];

assign interrupts_enabled = ((priv_lvl_q == PrivLvlM) & ie_q[M]) || (priv_lvl_q != PrivLvlM);
assign any_interrupt_pending = meip | mtip | msip | mcip | seip | stip | ssip | scip;
assign any_interrupt_pending = meip | mtip | msip | mcip | mxip | seip | stip | ssip | scip;
assign interrupt = interrupts_enabled & any_interrupt_pending;

// CSR logic
Expand Down Expand Up @@ -2333,6 +2336,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
tie_d = tie_q;
sie_d = sie_q;
cie_d = cie_q;
xie_d = xie_q;
seip_d = seip_q;
stip_d = stip_q;
ssip_d = ssip_q;
Expand Down Expand Up @@ -2462,6 +2466,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
csr_rvalue[MTI] = irq_i.mtip;
csr_rvalue[MSI] = irq_i.msip;
csr_rvalue[MCI] = irq_i.mcip;
csr_rvalue[MXI] = irq_i.mxip;
csr_rvalue[SEI] = seip_q;
csr_rvalue[STI] = stip_q;
csr_rvalue[SSI] = ssip_q;
Expand All @@ -2478,6 +2483,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
csr_rvalue[MTI] = tie_q[M];
csr_rvalue[MSI] = sie_q[M];
csr_rvalue[MCI] = cie_q[M];
csr_rvalue[MXI] = xie_q[M];
csr_rvalue[SEI] = eie_q[S];
csr_rvalue[STI] = tie_q[S];
csr_rvalue[SSI] = sie_q[S];
Expand All @@ -2487,6 +2493,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
tie_d[M] = alu_result[MTI];
sie_d[M] = alu_result[MSI];
cie_d[M] = alu_result[MCI];
xie_d[M] = alu_result[MXI];
eie_d[S] = alu_result[SEI];
tie_d[S] = alu_result[STI];
sie_d[S] = alu_result[SSI];
Expand Down Expand Up @@ -2610,6 +2617,7 @@ module snitch import snitch_pkg::*; import riscv_instr::*; #(
else if (mtip) cause_d[M] = MTI;
else if (msip) cause_d[M] = MSI;
else if (mcip) cause_d[M] = MCI;
else if (mxip) cause_d[M] = MXI;
else if (seip) cause_d[M] = SEI;
else if (stip) cause_d[M] = STI;
else if (ssip) cause_d[M] = SSI;
Expand Down
6 changes: 5 additions & 1 deletion hw/snitch/src/snitch_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ package snitch_pkg;
logic msip;
/// Machine cluster-local interrupt pending
logic mcip;
/// Machine cluster-local external interrupt pending
logic mxip;
} interrupts_t;

typedef enum logic [31:0] {
Expand Down Expand Up @@ -117,6 +119,7 @@ package snitch_pkg;
localparam logic [3:0] MTI = 7;
localparam logic [3:0] MEI = 11;
localparam logic [4:0] MCI = 19;
localparam logic [4:0] MXI = 20;
localparam logic [3:0] SSI = 1;
localparam logic [3:0] STI = 5;
localparam logic [3:0] SEI = 9;
Expand All @@ -126,7 +129,8 @@ package snitch_pkg;
typedef enum integer {
TCDM = 0,
ClusterPeripherals = 1,
SoC = 2
SoC = 2,
Ext = 3
} cluster_slave_e;

typedef enum integer {
Expand Down
Loading