Skip to content

Commit

Permalink
[hw,rv_dm,rtl] Convert DMI to real TL-UL interface
Browse files Browse the repository at this point in the history
Change DMI implementation to TL-UL, and rework rv_dm to match
Ensure rv_dm continues to respond with zeroes when the DM is not
present / inaccessible.

Co-authored-by: Michael Schaffner <[email protected]>
Co-authored-by: Alexander Williams <[email protected]>
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
3 people authored and andreaskurth committed Nov 7, 2024
1 parent f4945ae commit b8596ff
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 95 deletions.
34 changes: 14 additions & 20 deletions hw/ip/rv_dm/data/rv_dm.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
{ protocol: "tlul", direction: "host", name: "sba" }
{ protocol: "tlul", direction: "device", name: "regs" }
{ protocol: "tlul", direction: "device", name: "mem" }
{ protocol: "tlul", direction: "device", name: "dbg" }
],
scan: "true", // Enable `scanmode_i` port
scan_reset: "true", // Enable `scan_rst_ni` port
Expand Down Expand Up @@ -108,26 +109,6 @@
asserted when the hardware debug mechanisms are enabled in the system.
'''
},
{
struct: "tl_h2d"
package: "tlul_pkg"
type: "uni"
name: "dmi_tl_h2d"
act: "rcv"
desc: '''
TLUL-based DMI request input port
'''
}
{
struct: "tl_d2h"
package: "tlul_pkg"
type: "uni"
name: "dmi_tl_d2h"
act: "req"
desc: '''
TLUL-based DMI response output port
'''
}
{ struct: "lc_tx"
type: "uni"
name: "lc_dft_en"
Expand Down Expand Up @@ -658,5 +639,18 @@
}
},
]
// Debug bus attachment
dbg: [
{ window: {
name: "dbg"
// 0x0 ... 0x40 word addresses are allocated here.
items: "128"
swaccess: "rw",
data-intg-passthru: "true",
byte-write: "false",
desc: '''Access window to DM CSRs.'''
}
},
]
}
}
5 changes: 2 additions & 3 deletions hw/ip/rv_dm/doc/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ All hardware interfaces of the debug system are documented in the [PULP RISC-V D
Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`rv_dm`** has the following hardware interfaces defined
- Primary Clock: **`clk_i`**
- Other Clocks: **`clk_lc_i`**
- Bus Device Interfaces (TL-UL): **`regs_tl_d`**, **`mem_tl_d`**
- Bus Device Interfaces (TL-UL): **`regs_tl_d`**, **`mem_tl_d`**, **`dbg_tl_d`**
- Bus Host Interfaces (TL-UL): **`sba_tl_h`**
- Peripheral Pins for Chip IO: *none*
- Interrupts: *none*
Expand All @@ -20,8 +20,6 @@ Referring to the [Comportable guideline for peripheral device functionality](htt
| next_dm_addr | rv_dm_pkg::next_dm_addr | uni | rcv | 1 | 32bit word address of the next debug module. Set to 0x0 if this is the last debug module in the chain. |
| jtag | jtag_pkg::jtag | req_rsp | rsp | 1 | JTAG signals for the RISC-V TAP. |
| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Multibit life cycle hardware debug enable signal coming from life cycle controller, asserted when the hardware debug mechanisms are enabled in the system. |
| dmi_tl_h2d | tlul_pkg::tl_h2d | uni | rcv | 1 | TLUL-based DMI request input port |
| dmi_tl_d2h | tlul_pkg::tl_d2h | uni | req | 1 | TLUL-based DMI response output port |
| lc_dft_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Multibit life cycle hardware debug enable signal coming from life cycle controller, asserted when the DFT mechanisms are enabled in the system. |
| pinmux_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Multibit life cycle hardware debug enable signal coming from pinmux. This is a latched version of the lc_hw_debug_en signal and is only used to gate the JTAG / TAP side of the RV_DM. It is used to keep a debug session live while the rest of the system undergoes an NDM reset. |
| otp_dis_rv_dm_late_debug | prim_mubi_pkg::mubi8 | uni | rcv | 1 | |
Expand All @@ -36,6 +34,7 @@ Referring to the [Comportable guideline for peripheral device functionality](htt
| sba_tl_h | tlul_pkg::tl | req_rsp | req | 1 | |
| regs_tl_d | tlul_pkg::tl | req_rsp | rsp | 1 | |
| mem_tl_d | tlul_pkg::tl | req_rsp | rsp | 1 | |
| dbg_tl_d | tlul_pkg::tl | req_rsp | rsp | 1 | |

## Security Alerts

Expand Down
14 changes: 14 additions & 0 deletions hw/ip/rv_dm/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -863,5 +863,19 @@ Access window into the debug ROM.
- Access: `ro`
- Byte writes are *not* supported.

## Summary of the **`dbg`** interface's registers

| Name | Offset | Length | Description |
|:--------------------|:---------|---------:|:--------------------------|
| rv_dm.[`dbg`](#dbg) | 0x0 | 512 | Access window to DM CSRs. |

## dbg
Access window to DM CSRs.

- Word Aligned Offset Range: `0x0`to`0x1fc`
- Size (words): `128`
- Access: `rw`
- Byte writes are *not* supported.


<!-- END CMDGEN -->
4 changes: 2 additions & 2 deletions hw/ip/rv_dm/dv/sva/rv_dm_bind.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ module rv_dm_bind;
) tlul_assert_device_dmi (
.clk_i,
.rst_ni,
.h2d (dmi_tl_h2d_i),
.d2h (dmi_tl_d2h_o)
.h2d (dbg_tl_d_i),
.d2h (dbg_tl_d_o)
);

bind rv_dm tlul_assert #(
Expand Down
14 changes: 7 additions & 7 deletions hw/ip/rv_dm/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ module tb;
rv_dm_if rv_dm_if(.clk(clk), .rst_n(rst_n));

// Used for JTAG DTM connections via TL-UL.
tlul_pkg::tl_h2d_t dmi_tl_h2d;
tlul_pkg::tl_d2h_t dmi_tl_d2h;
tlul_pkg::tl_h2d_t dbg_tl_h2d;
tlul_pkg::tl_d2h_t dbg_tl_d2h;

`DV_ALERT_IF_CONNECT()

Expand All @@ -43,11 +43,11 @@ module tb;
.jtag_o ({jtag_if.tdo, jtag_tdo_oe}),
.scan_rst_ni (rv_dm_if.scan_rst_n),
.scanmode_i (rv_dm_if.scanmode),
.tl_h2d_o (dmi_tl_h2d),
.tl_d2h_i (dmi_tl_d2h)
.tl_h2d_o (dbg_tl_h2d),
.tl_d2h_i (dbg_tl_d2h)
);
`else
assign dmi_tl_h2d = tlul_pkg::TL_H2D_DEFAULT;
assign dbg_tl_h2d = tlul_pkg::TL_H2D_DEFAULT;
`endif

// dut
Expand Down Expand Up @@ -100,8 +100,8 @@ module tb;
.jtag_o ({jtag_if.tdo, jtag_tdo_oe}),
`endif

.dmi_tl_h2d_i (dmi_tl_h2d),
.dmi_tl_d2h_o (dmi_tl_d2h)
.dbg_tl_d_i (dbg_tl_h2d),
.dbg_tl_d_o (dbg_tl_d2h)
);

// Apply the muxing that we get in rv_dm, where the JTAG interface that actually connects to the
Expand Down
46 changes: 30 additions & 16 deletions hw/ip/rv_dm/rtl/rv_dm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ module rv_dm
input jtag_pkg::jtag_req_t jtag_i,
output jtag_pkg::jtag_rsp_t jtag_o,
// TL-UL-based DMI
input tlul_pkg::tl_h2d_t dmi_tl_h2d_i,
output tlul_pkg::tl_d2h_t dmi_tl_d2h_o
input tlul_pkg::tl_h2d_t dbg_tl_d_i,
output tlul_pkg::tl_d2h_t dbg_tl_d_o
);

///////////////////////////
Expand Down Expand Up @@ -114,7 +114,7 @@ module rv_dm
tlul_pkg::tl_h2d_t mem_tl_win_h2d;
tlul_pkg::tl_d2h_t mem_tl_win_d2h;
rv_dm_reg_pkg::rv_dm_regs_reg2hw_t regs_reg2hw;
logic regs_intg_error, rom_intg_error, dmi_intg_error;
logic regs_intg_error, rom_intg_error, dmi_intg_error, dbg_intg_error;
logic sba_gate_intg_error, rom_gate_intg_error, dmi_gate_intg_error;

rv_dm_regs_reg_top u_reg_regs (
Expand All @@ -135,7 +135,7 @@ module rv_dm
// Alerts
logic [NumAlerts-1:0] alert_test, alerts;

assign alerts[0] = regs_intg_error | rom_intg_error | dmi_intg_error |
assign alerts[0] = regs_intg_error | rom_intg_error | dmi_intg_error | dbg_intg_error |
sba_gate_intg_error | rom_gate_intg_error | dmi_gate_intg_error;

assign alert_test = {
Expand Down Expand Up @@ -436,6 +436,19 @@ module rv_dm
// If DMIDirectTAP is defined, a bound-in DPI module replaces the TAP that's defined
// within the ifndef block
`ifndef DMIDirectTAP
tlul_pkg::tl_h2d_t dbg_tl_h2d_win;
tlul_pkg::tl_d2h_t dbg_tl_d2h_win;

rv_dm_dbg_reg_top u_rv_dm_dbg_reg_top (
.clk_i,
.rst_ni,
.tl_i (dbg_tl_d_i),
.tl_o (dbg_tl_d_o),
.tl_win_o (dbg_tl_h2d_win),
.tl_win_i (dbg_tl_d2h_win),
.intg_err_o(dbg_intg_error)
);

rv_dm_dmi_gate #(
.SecVolatileRawUnlockEn(SecVolatileRawUnlockEn)
) u_rv_dm_dmi_gate (
Expand All @@ -446,14 +459,14 @@ module rv_dm
.lc_hw_debug_en_i,
.lc_check_byp_en_i,
.lc_escalate_en_i,
.dbg_tl_h2d_win_i ( dmi_tl_h2d_i ),
.dbg_tl_d2h_win_o ( dmi_tl_d2h_o ),
.dmi_req_valid_o ( dmi_req_valid ),
.dmi_req_ready_i ( dmi_req_ready ),
.dmi_req_o ( dmi_req ),
.dmi_rsp_valid_i ( dmi_rsp_valid ),
.dmi_rsp_ready_o ( dmi_rsp_ready ),
.dmi_rsp_i ( dmi_rsp ),
.dbg_tl_h2d_win_i ( dbg_tl_h2d_win ),
.dbg_tl_d2h_win_o ( dbg_tl_d2h_win ),
.dmi_req_valid_o ( dmi_req_valid ),
.dmi_req_ready_i ( dmi_req_ready ),
.dmi_req_o ( dmi_req ),
.dmi_rsp_valid_i ( dmi_rsp_valid ),
.dmi_rsp_ready_o ( dmi_rsp_ready ),
.dmi_rsp_i ( dmi_rsp ),

// Integrity error
.intg_error_o( dmi_intg_error)
Expand Down Expand Up @@ -559,11 +572,12 @@ module rv_dm
`endif
// Tied-off and ignore signals from the DMI interface
assign dmi_intg_error = 1'b0;
assign dbg_intg_error = 1'b0;
assign dmi_gate_intg_error = 1'b0;
assign dmi_tl_d2h_o = tlul_pkg::TL_D2H_DEFAULT;
assign dbg_tl_d_o = tlul_pkg::TL_D2H_DEFAULT;

logic unused_signals;
assign unused_signals = ^{dmi_tl_h2d_i,
assign unused_signals = ^{dbg_tl_d_i,
lc_check_byp_en_i,
lc_escalate_en_i,
strap_en_i,
Expand Down Expand Up @@ -686,8 +700,8 @@ module rv_dm
`ASSERT_KNOWN(TlSbaAValidKnown_A, sba_tl_h_o.a_valid)
`ASSERT_KNOWN(TlSbaDReadyKnown_A, sba_tl_h_o.d_ready)

`ASSERT_KNOWN(TlDmiDValidKnown_A, dmi_tl_d2h_o.d_valid)
`ASSERT_KNOWN(TlDmiAReadyKnown_A, dmi_tl_d2h_o.a_ready)
`ASSERT_KNOWN(TlDmiDValidKnown_A, dbg_tl_d_o.d_valid)
`ASSERT_KNOWN(TlDmiAReadyKnown_A, dbg_tl_d_o.a_ready)

`ASSERT_KNOWN(NdmresetOKnown_A, ndmreset_req_o)
`ASSERT_KNOWN(DmactiveOKnown_A, dmactive_o)
Expand Down
60 changes: 60 additions & 0 deletions hw/ip/rv_dm/rtl/rv_dm_dbg_reg_top.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Register Top module auto-generated by `reggen`

`include "prim_assert.sv"

module rv_dm_dbg_reg_top (
input clk_i,
input rst_ni,
input tlul_pkg::tl_h2d_t tl_i,
output tlul_pkg::tl_d2h_t tl_o,

// Output port for window
output tlul_pkg::tl_h2d_t tl_win_o,
input tlul_pkg::tl_d2h_t tl_win_i,

// To HW

// Integrity check errors
output logic intg_err_o
);

import rv_dm_reg_pkg::* ;


// Add an unloaded flop to make use of clock / reset
// This is done to specifically address lint complaints of unused clocks/resets
// Since the flop is unloaded it will be removed during synthesis
logic unused_reg;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
unused_reg <= '0;
end else begin
unused_reg <= tl_i.a_valid;
end
end



// Since there are no registers in this block, commands are routed through to windows which
// can report their own integrity errors.
assign intg_err_o = 1'b0;

// outgoing integrity generation
tlul_pkg::tl_d2h_t tl_o_pre;
tlul_rsp_intg_gen #(
.EnableRspIntgGen(1),
.EnableDataIntgGen(0)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
.tl_o(tl_o)
);

assign tl_win_o = tl_i;
assign tl_o_pre = tl_win_i;

// Unused signal tieoff
endmodule
6 changes: 6 additions & 0 deletions hw/ip/rv_dm/rtl/rv_dm_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package rv_dm_reg_pkg;
// Address widths within the block
parameter int RegsAw = 4;
parameter int MemAw = 12;
parameter int DbgAw = 9;

///////////////////////////////////////////////
// Typedefs for registers for regs interface //
Expand Down Expand Up @@ -983,4 +984,9 @@ package rv_dm_reg_pkg;
4'b 1111 // index[280] RV_DM_FLAGS_255
};

// Window parameters for dbg interface
parameter logic [DbgAw-1:0] RV_DM_DBG_OFFSET = 9'h 0;
parameter int unsigned RV_DM_DBG_SIZE = 'h 200;
parameter int unsigned RV_DM_DBG_IDX = 0;

endpackage
1 change: 1 addition & 0 deletions hw/ip/rv_dm/rv_dm.core
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ filesets:
files:
- rtl/rv_dm_reg_pkg.sv
- rtl/rv_dm_regs_reg_top.sv
- rtl/rv_dm_dbg_reg_top.sv
- rtl/rv_dm_dmi_gate.sv
- rtl/rv_dm_pkg.sv
- rtl/rv_dm.sv
Expand Down
Loading

0 comments on commit b8596ff

Please sign in to comment.