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

⚠️ remove redundant JTAG reset signal (TRST) #928

Merged
merged 6 commits into from
Jun 18, 2024
Merged
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 17.05.2024 | 1.10.0.1 | :warning: remove (optional and redundant) JTAG reset signal `jtag_trst_i` | [#928](https://github.com/stnolting/neorv32/pull/928) |
| 16.05.2024 | [**:rocket:1.10.0**](https://github.com/stnolting/neorv32/releases/tag/v1.10.0) | **New release** | |
| 15.06.2024 | 1.9.9.9 | :sparkles: add pre-configured example project for Eclipse IDE | [#926](https://github.com/stnolting/neorv32/pull/926) |
| 14.06.2024 | 1.9.9.8 | minor rtl edits/cleanups; increase bootloader's auto-boot timeout from 8s to 10s | [#925](https://github.com/stnolting/neorv32/pull/925) |
Expand Down
6 changes: 5 additions & 1 deletion docs/datasheet/on_chip_debugger.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ External JTAG access is provided by the following top-level ports:
[options="header",grid="rows"]
|=======================
| Name | Width | Direction | Description
| `jtag_trst_i` | 1 | in | TAP reset (low-active); this signal is optional, make sure to pull it **high** if not used
| `jtag_tck_i` | 1 | in | serial clock
| `jtag_tdi_i` | 1 | in | serial data input
| `jtag_tdo_o` | 1 | out | serial data output
Expand All @@ -94,6 +93,11 @@ All JTAG signals are synchronized to the processor's clock domain. Hence, no add
However, this constraints the maximal JTAG clock frequency (`jtag_tck_i`) to be less than or equal to **1/5** of the processor
clock frequency (`clk_i`).

.JTAG TAP Reset
[NOTE]
The NEORV32 JTAG TAP does not provide a dedicated reset signal ("TRST"). However, the missing TRST is not a problem,
since JTAG-level resets can be triggered using with TMS signaling.

.Maintaining JTAG Chain
[NOTE]
If the on-chip debugger is disabled the JTAG serial input `jtag_tdi_i` is directly
Expand Down
1 change: 0 additions & 1 deletion docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in t
| `clk_i` | 1 | in | none | global clock line, all registers triggering on rising edge
| `rstn_i` | 1 | in | none | global reset, asynchronous, **low-active**
5+^| **JTAG Access Port for <<_on_chip_debugger_ocd>>**
| `jtag_trst_i` | 1 | in | `'H'` | TAP reset, low-active (optional)
| `jtag_tck_i` | 1 | in | `'L'` | serial clock
| `jtag_tdi_i` | 1 | in | `'L'` | serial data input
| `jtag_tdo_o` | 1 | out | - | serial data output
Expand Down
14 changes: 7 additions & 7 deletions docs/userguide/debugging_with_ocd.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ RISC-V _GNU debugger_ `gdb`.
.TLDR
[TIP]
You can start a pre-configured debug session (using default `main.elf` as executable and
`target extended-remote localhost:3333` as gdb connection configuration) by using the **gdb** makefile target
`target extended-remote localhost:3333` as GDB connection configuration) by using the **GDB** makefile target
(i.e. `make gdb`).

.OCD Hardware Implementation
Expand Down Expand Up @@ -39,17 +39,17 @@ also use a FTDI-based adapter like the "FT2232H-56Q Mini Module", which is a sim
[cols="^3,^2,^2"]
[options="header",grid="rows"]
|=======================
| NEORV32 top signal | JTAG signal | FTDI port
| NEORV32 top signal | JTAG signal | Default FTDI port
| `jtag_tck_i` | TCK | D0
| `jtag_tdi_i` | TDI | D1
| `jtag_tdo_o` | TDO | D2
| `jtag_tms_i` | TMS | D3
| `jtag_trst_i` | TRST | D4
|=======================

[TIP]
The low-active JTAG tap reset `jtag_trst_i` signals is _optional_ as a reset can also be triggered via the TAP controller
issuing special commands. If `jtag_trst_i` is not connected make sure to pull the signal _high_.
.JTAG TAP Reset
[NOTE]
The NEORV32 JTAG TAP does not provide a dedicated reset signal ("TRST"). However, the missing TRST is not a problem,
since JTAG-level resets can be triggered using with TMS signaling.


:sectnums:
Expand Down Expand Up @@ -239,7 +239,7 @@ instruction. Whenever execution reaches this instruction, debug mode is entered
instruction at this address to maintain original program behavior. +
+
When debugging programs executed from ROM _hardware-assisted_ breakpoints using the core's trigger module have to be used.
See section <<_hardware_breakpoints>> for more information.
See section <<_hardware_breakpoints>> for more information.

Now execute `c` (= continue). The CPU will resume operation until it hits the break-point.
By this we can move from one counter increment to another.
Expand Down
64 changes: 32 additions & 32 deletions rtl/core/neorv32_debug_dm.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ begin
dm_ctrl.pbuf_en <= '0';
dm_ctrl.illegal_cmd <= '0';
dm_ctrl.illegal_state <= '0';
dm_ctrl.cmderr <= "000";
dm_ctrl.cmderr <= (others => '0');
elsif rising_edge(clk_i) then
if (dm_reg.dmcontrol_dmactive = '0') then -- DM reset / DM disabled
dm_ctrl.state <= CMD_IDLE;
Expand All @@ -223,7 +223,7 @@ begin
--
dm_ctrl.illegal_cmd <= '0';
dm_ctrl.illegal_state <= '0';
dm_ctrl.cmderr <= "000";
dm_ctrl.cmderr <= (others => '0');
else -- DM active

-- defaults --
Expand Down Expand Up @@ -416,8 +416,8 @@ begin
dm_reg.halt_req <= dmi_req_i.data(31); -- haltreq (-/w): write 1 to request halt; has to be cleared again by debugger
dm_reg.resume_req <= dmi_req_i.data(30); -- resumereq (-/w1): write 1 to request resume; auto-clears
dm_reg.reset_ack <= dmi_req_i.data(28); -- ackhavereset (-/w1): write 1 to ACK reset; auto-clears
dm_reg.dmcontrol_ndmreset <= dmi_req_i.data(01); -- ndmreset (r/w): SoC reset when high
dm_reg.dmcontrol_dmactive <= dmi_req_i.data(00); -- dmactive (r/w): DM reset when low
dm_reg.dmcontrol_ndmreset <= dmi_req_i.data(1); -- ndmreset (r/w): SoC reset when high
dm_reg.dmcontrol_dmactive <= dmi_req_i.data(0); -- dmactive (r/w): DM reset when low
end if;

-- write abstract command --
Expand All @@ -430,7 +430,7 @@ begin
-- write abstract command autoexec --
if (dmi_req_i.addr = addr_abstractauto_c) then
if (dm_ctrl.busy = '0') then -- idle and no errors yet
dm_reg.abstractauto_autoexecdata <= dmi_req_i.data(00);
dm_reg.abstractauto_autoexecdata <= dmi_req_i.data(0);
dm_reg.abstractauto_autoexecprogbuf(0) <= dmi_req_i.data(16);
dm_reg.abstractauto_autoexecprogbuf(1) <= dmi_req_i.data(17);
end if;
Expand Down Expand Up @@ -529,13 +529,13 @@ begin
dmi_rsp_o.data(12) <= dm_reg.dmcontrol_ndmreset; -- anyunavail (r/-): there is only one hart that is unavailable during reset
dmi_rsp_o.data(11) <= not dm_ctrl.hart_halted; -- allrunning (r/-): there is only one hart that can be RUNNING or HALTED
dmi_rsp_o.data(10) <= not dm_ctrl.hart_halted; -- anyrunning (r/-): there is only one hart that can be RUNNING or HALTED
dmi_rsp_o.data(09) <= dm_ctrl.hart_halted; -- allhalted (r/-): there is only one hart that can be RUNNING or HALTED
dmi_rsp_o.data(08) <= dm_ctrl.hart_halted; -- anyhalted (r/-): there is only one hart that can be RUNNING or HALTED
dmi_rsp_o.data(07) <= '1'; -- authenticated (r/-): authentication passed since there is no authentication
dmi_rsp_o.data(06) <= '0'; -- authbusy (r/-): always ready since there is no authentication
dmi_rsp_o.data(05) <= '0'; -- hasresethaltreq (r/-): halt-on-reset not implemented
dmi_rsp_o.data(04) <= '0'; -- confstrptrvalid (r/-): no configuration string available
dmi_rsp_o.data(03 downto 00) <= dm_version_c; -- version (r/-): DM spec. version
dmi_rsp_o.data(9) <= dm_ctrl.hart_halted; -- allhalted (r/-): there is only one hart that can be RUNNING or HALTED
dmi_rsp_o.data(8) <= dm_ctrl.hart_halted; -- anyhalted (r/-): there is only one hart that can be RUNNING or HALTED
dmi_rsp_o.data(7) <= '1'; -- authenticated (r/-): authentication passed since there is no authentication
dmi_rsp_o.data(6) <= '0'; -- authbusy (r/-): always ready since there is no authentication
dmi_rsp_o.data(5) <= '0'; -- hasresethaltreq (r/-): halt-on-reset not implemented
dmi_rsp_o.data(4) <= '0'; -- confstrptrvalid (r/-): no configuration string available
dmi_rsp_o.data(3 downto 0) <= dm_version_c; -- version (r/-): DM spec. version

-- debug module control --
when addr_dmcontrol_c =>
Expand All @@ -546,12 +546,12 @@ begin
dmi_rsp_o.data(27) <= '0'; -- reserved (r/-)
dmi_rsp_o.data(26) <= '0'; -- hasel (r/-) - only a single hart can be selected at once
dmi_rsp_o.data(25 downto 16) <= (others => '0'); -- hartsello (r/-) - there is only one hart
dmi_rsp_o.data(15 downto 06) <= (others => '0'); -- hartselhi (r/-) - there is only one hart
dmi_rsp_o.data(05 downto 04) <= (others => '0'); -- reserved (r/-)
dmi_rsp_o.data(03) <= '0'; -- setresethaltreq (-/w1): halt-on-reset request - halt-on-reset not implemented
dmi_rsp_o.data(02) <= '0'; -- clrresethaltreq (-/w1): halt-on-reset ack - halt-on-reset not implemented
dmi_rsp_o.data(01) <= dm_reg.dmcontrol_ndmreset; -- ndmreset (r/w): soc reset
dmi_rsp_o.data(00) <= dm_reg.dmcontrol_dmactive; -- dmactive (r/w): DM reset
dmi_rsp_o.data(15 downto 6) <= (others => '0'); -- hartselhi (r/-) - there is only one hart
dmi_rsp_o.data(5 downto 4) <= (others => '0'); -- reserved (r/-)
dmi_rsp_o.data(3) <= '0'; -- setresethaltreq (-/w1): halt-on-reset request - halt-on-reset not implemented
dmi_rsp_o.data(2) <= '0'; -- clrresethaltreq (-/w1): halt-on-reset ack - halt-on-reset not implemented
dmi_rsp_o.data(1) <= dm_reg.dmcontrol_ndmreset; -- ndmreset (r/w): soc reset
dmi_rsp_o.data(0) <= dm_reg.dmcontrol_dmactive; -- dmactive (r/w): DM reset

-- hart info --
when addr_hartinfo_c =>
Expand All @@ -560,31 +560,31 @@ begin
dmi_rsp_o.data(19 downto 17) <= (others => '0'); -- reserved (r/-)
dmi_rsp_o.data(16) <= dataaccess_c; -- dataaccess (r/-): 1: data registers are memory-mapped, 0: data registers are CSR-mapped
dmi_rsp_o.data(15 downto 12) <= datasize_c; -- datasize (r/-): number data registers in memory/CSR space
dmi_rsp_o.data(11 downto 00) <= dataaddr_c(11 downto 0); -- dataaddr (r/-): data registers base address (memory/CSR)
dmi_rsp_o.data(11 downto 0) <= dataaddr_c(11 downto 0); -- dataaddr (r/-): data registers base address (memory/CSR)

-- abstract control and status --
when addr_abstractcs_c =>
dmi_rsp_o.data(31 downto 24) <= (others => '0'); -- reserved (r/-)
dmi_rsp_o.data(28 downto 24) <= "00010"; -- progbufsize (r/-): number of words in program buffer = 2
dmi_rsp_o.data(12) <= dm_ctrl.busy; -- busy (r/-): abstract command in progress (1) / idle (0)
dmi_rsp_o.data(11) <= '1'; -- relaxedpriv (r/-): PMP rules are ignored when in debug-mode
dmi_rsp_o.data(10 downto 08) <= dm_ctrl.cmderr; -- cmderr (r/w1c): any error during execution?
dmi_rsp_o.data(07 downto 04) <= (others => '0'); -- reserved (r/-)
dmi_rsp_o.data(03 downto 00) <= "0001"; -- datacount (r/-): number of implemented data registers = 1
dmi_rsp_o.data(10 downto 8) <= dm_ctrl.cmderr; -- cmderr (r/w1c): any error during execution?
dmi_rsp_o.data(7 downto 4) <= (others => '0'); -- reserved (r/-)
dmi_rsp_o.data(3 downto 0) <= "0001"; -- datacount (r/-): number of implemented data registers = 1

-- abstract command (-/w) --
when addr_command_c =>
dmi_rsp_o.data <= (others => '0'); -- register is write-only
-- -- abstract command (-/w) --
-- when addr_command_c =>
-- dmi_rsp_o.data <= (others => '0'); -- register is write-only

-- abstract command autoexec (r/w) --
when addr_abstractauto_c =>
dmi_rsp_o.data(00) <= dm_reg.abstractauto_autoexecdata; -- autoexecdata(0): read/write access to data0 triggers execution of program buffer
dmi_rsp_o.data(0) <= dm_reg.abstractauto_autoexecdata; -- autoexecdata(0): read/write access to data0 triggers execution of program buffer
dmi_rsp_o.data(16) <= dm_reg.abstractauto_autoexecprogbuf(0); -- autoexecprogbuf(0): read/write access to progbuf0 triggers execution of program buffer
dmi_rsp_o.data(17) <= dm_reg.abstractauto_autoexecprogbuf(1); -- autoexecprogbuf(1): read/write access to progbuf1 triggers execution of program buffer

-- next debug module (r/-) --
when addr_nextdm_c =>
dmi_rsp_o.data <= (others => '0'); -- this is the only DM
-- -- next debug module (r/-) --
-- when addr_nextdm_c =>
-- dmi_rsp_o.data <= (others => '0'); -- this is the only DM

-- abstract data 0 (r/w) --
when addr_data0_c =>
Expand All @@ -596,9 +596,9 @@ begin
when addr_progbuf1_c =>
if (LEGACY_MODE = true) then dmi_rsp_o.data <= dm_reg.progbuf(1); else dmi_rsp_o.data <= (others => '0'); end if; -- program buffer 1

-- system bus access control and status (r/-) --
when addr_sbcs_c =>
dmi_rsp_o.data <= (others => '0'); -- system bus access not implemented
-- -- system bus access control and status (r/-) --
-- when addr_sbcs_c =>
-- dmi_rsp_o.data <= (others => '0'); -- system bus access not implemented

-- halt summary 0 (r/-) --
when addr_haltsum0_c =>
Expand Down
49 changes: 17 additions & 32 deletions rtl/core/neorv32_debug_dtm.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,16 @@ entity neorv32_debug_dtm is
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active
-- jtag connection --
jtag_trst_i : in std_ulogic;
jtag_tck_i : in std_ulogic;
jtag_tdi_i : in std_ulogic;
jtag_tdo_o : out std_ulogic;
jtag_tms_i : in std_ulogic;
jtag_tck_i : in std_ulogic;
jtag_tdi_i : in std_ulogic;
jtag_tdo_o : out std_ulogic;
jtag_tms_i : in std_ulogic;
-- debug module interface (DMI) --
dmi_req_o : out dmi_req_t; -- request
dmi_rsp_i : in dmi_rsp_t -- response
dmi_req_o : out dmi_req_t; -- request
dmi_rsp_i : in dmi_rsp_t -- response
);
end neorv32_debug_dtm;

Expand All @@ -51,16 +50,9 @@ architecture neorv32_debug_dtm_rtl of neorv32_debug_dtm is
-- tap JTAG signal synchronizer --
type tap_sync_t is record
-- internal --
trst_ff : std_ulogic_vector(2 downto 0);
tck_ff : std_ulogic_vector(2 downto 0);
tdi_ff : std_ulogic_vector(2 downto 0);
tms_ff : std_ulogic_vector(2 downto 0);
tck_ff, tdi_ff, tms_ff : std_ulogic_vector(2 downto 0);
-- external --
trst : std_ulogic;
tck_rising : std_ulogic;
tck_falling : std_ulogic;
tdi : std_ulogic;
tms : std_ulogic;
tck_rising, tck_falling, tdi, tms: std_ulogic;
end record;
signal tap_sync : tap_sync_t;

Expand Down Expand Up @@ -106,21 +98,16 @@ begin
tap_synchronizer: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
tap_sync.trst_ff <= (others => '0');
tap_sync.tck_ff <= (others => '0');
tap_sync.tdi_ff <= (others => '0');
tap_sync.tms_ff <= (others => '0');
tap_sync.tck_ff <= (others => '0');
tap_sync.tdi_ff <= (others => '0');
tap_sync.tms_ff <= (others => '0');
elsif rising_edge(clk_i) then
tap_sync.trst_ff <= tap_sync.trst_ff(1 downto 0) & jtag_trst_i;
tap_sync.tck_ff <= tap_sync.tck_ff( 1 downto 0) & jtag_tck_i;
tap_sync.tdi_ff <= tap_sync.tdi_ff( 1 downto 0) & jtag_tdi_i;
tap_sync.tms_ff <= tap_sync.tms_ff( 1 downto 0) & jtag_tms_i;
tap_sync.tck_ff <= tap_sync.tck_ff(1 downto 0) & jtag_tck_i;
tap_sync.tdi_ff <= tap_sync.tdi_ff(1 downto 0) & jtag_tdi_i;
tap_sync.tms_ff <= tap_sync.tms_ff(1 downto 0) & jtag_tms_i;
end if;
end process tap_synchronizer;

-- JTAG reset --
tap_sync.trst <= '0' when (tap_sync.trst_ff(2 downto 1) = "00") else '1';

-- JTAG clock edge --
tap_sync.tck_rising <= '1' when (tap_sync.tck_ff(2 downto 1) = "01") else '0';
tap_sync.tck_falling <= '1' when (tap_sync.tck_ff(2 downto 1) = "10") else '0';
Expand All @@ -139,9 +126,7 @@ begin
if (rstn_i = '0') then
tap_ctrl_state <= LOGIC_RESET;
elsif rising_edge(clk_i) then
if (tap_sync.trst = '0') then -- reset
tap_ctrl_state <= LOGIC_RESET;
elsif (tap_sync.tck_rising = '1') then -- clock pulse (evaluate TMS on the rising edge of TCK)
if (tap_sync.tck_rising = '1') then -- clock pulse (evaluate TMS on the rising edge of TCK)
case tap_ctrl_state is -- JTAG state machine
when LOGIC_RESET => if (tap_sync.tms = '0') then tap_ctrl_state <= RUN_IDLE; else tap_ctrl_state <= LOGIC_RESET; end if;
when RUN_IDLE => if (tap_sync.tms = '0') then tap_ctrl_state <= RUN_IDLE; else tap_ctrl_state <= DR_SCAN; end if;
Expand Down
3 changes: 1 addition & 2 deletions rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package neorv32_package is

-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100000"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100001"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

Expand Down Expand Up @@ -809,7 +809,6 @@ package neorv32_package is
clk_i : in std_ulogic;
rstn_i : in std_ulogic;
-- JTAG on-chip debugger interface --
jtag_trst_i : in std_ulogic := 'H';
jtag_tck_i : in std_ulogic := 'L';
jtag_tdi_i : in std_ulogic := 'L';
jtag_tdo_o : out std_ulogic;
Expand Down
18 changes: 8 additions & 10 deletions rtl/core/neorv32_top.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ entity neorv32_top is
rstn_i : in std_ulogic; -- global reset, low-active, async

-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i : in std_ulogic := 'H'; -- low-active TAP reset (optional)
jtag_tck_i : in std_ulogic := 'L'; -- serial clock
jtag_tdi_i : in std_ulogic := 'L'; -- serial data input
jtag_tdo_o : out std_ulogic; -- serial data output
Expand Down Expand Up @@ -1640,15 +1639,14 @@ begin
IDCODE_MANID => JEDEC_ID
)
port map (
clk_i => clk_i,
rstn_i => rstn_ext,
jtag_trst_i => jtag_trst_i,
jtag_tck_i => jtag_tck_i,
jtag_tdi_i => jtag_tdi_i,
jtag_tdo_o => jtag_tdo_o,
jtag_tms_i => jtag_tms_i,
dmi_req_o => dmi_req,
dmi_rsp_i => dmi_rsp
clk_i => clk_i,
rstn_i => rstn_ext,
jtag_tck_i => jtag_tck_i,
jtag_tdi_i => jtag_tdi_i,
jtag_tdo_o => jtag_tdo_o,
jtag_tms_i => jtag_tms_i,
dmi_req_o => dmi_req,
dmi_rsp_i => dmi_rsp
);

-- On-Chip Debugger - Debug Module (DM) ---------------------------------------------------
Expand Down
Loading