stnolting / neorv32

:desktop_computer: A small, customizable and extensible MCU-class 32-bit RISC-V soft-core CPU and microcontroller-like SoC written in platform-independent VHDL.
https://neorv32.org
BSD 3-Clause "New" or "Revised" License
1.53k stars 212 forks source link

JTAG Scan chain interrogation failed: all ones #688

Closed cmenendezzz closed 10 months ago

cmenendezzz commented 11 months ago

Hey @cmenendezzz!

What hardware setup are you using (i.e. processor configuration)?

It seems to be that TDO is stuck at 1 so no communication with your target is going to work

Hmm, I know this problem, but in most cases there is just problem with the wiring between FPGA and JTAG. If you pull-down your TDO wire (so, the one going to the JTAG adapter) do you get an "all zero" error?

Originally posted by @stnolting in https://github.com/stnolting/neorv32/discussions/642#discussioncomment-6431058

Hello again! I am testing the NEORV32 in another FPGA. Nevertheless I encounter this same issue. And as you said, I pull-down the TDO wire and I obtain again an all zero error. I was wondering if you have any idea of what it is happening. Thank you in advance!

cmenendezzz commented 11 months ago

Here you can see an example of the error. image

cmenendezzz commented 11 months ago

And I put the jtag_rst in a high pull state as you mentioned.


  jtag_trst_i    : in  std_ulogic := 'H'; -- low-active TAP reset (optional)
    jtag_tck_i     : in  std_ulogic := 'U'; -- serial clock
    jtag_tdi_i     : in  std_ulogic := 'U'; -- serial data input
    jtag_tdo_o     : out std_ulogic;        -- serial data output
    jtag_tms_i     : in  std_ulogic := 'U'; -- mode select
cmenendezzz commented 11 months ago

I have analyzed each of the jtag signals and clk, tdi and tms verify JTAG specification. Nevertheless tdo, with and without the resistance, does not respond.

stnolting commented 11 months ago

Hey there!

Most of the time this seems to be caused by a simple wiring issue (for example switching TDI and TDO).

And I put the jtag_rst in a high pull state as you mentioned.

Better set this signal to logical one if you are not using it.

  jtag_trst_i => '1',

Can you say something about your setup (like processor configuration)? Does the processor actually run? For example, do you see the bootloader prompt or can you see the "hart beat" LED blinking?

mjutn commented 11 months ago

Hey all,

I had the same issue as mentioned here, with the CW305 Artix target from ChipWhisperer and Digilent HS-2 Rev A. JTAG interface. Setting the reset to a logical one did solve the all zeroes issue. However, I am still having problems with getting the JTAG interface to work, see image for the errors I am getting:

image

I am using the minimal boot configuration but with the CPU extension Zifencei enabled, the debug module enabled, and the JTAG signals connected properly to the interface (with reset set to logical one). The bootloader prompt does appear when resetting the CPU. The JTAG interface is configured as follows:

image

Is there something I am missing?

stnolting commented 10 months ago

Hey @mjutn!

What clock speed are you using for the processor?

I am not familiar with that specific JTAG adapter, but are you sure about the ftdi layout_init command's parameters? Do you have a logic analyzer / scope available to see if the JTAG signals are actually toggling?

Maybe TDI and TDO are just switched?

mjutn commented 10 months ago

Hey @stnolting,

The clock frequency of the processor is set to 10 MHz. The ftdi layout_init was taken from https://github.com/openocd-org/openocd/blob/master/tcl/interface/ftdi/digilent-hs2.cfg. The TDI and TDO signals are toggling for sure, checked with an oscilloscope. TDI and TDO should not be switched, as package pins and labels on the Digilent HS2 line up. I don't exactly know where the problems arise, whether I am missing something in the neorv32 top level file or the JTAG adapter is causing the issue.

Thanks for having a look with me.

stnolting commented 10 months ago

Sounds good so far. I assume TMS is also toggling?

TDI and TDO should not be switched, as package pins and labels on the Digilent HS2 line up.

How about the FPGA's TDI and TDO pins? I always mix up the UART's RX and TX pins so maybe this a worth another check. 😅

Could you show your top entity and the processor configuration?

Which version of the processor are you using?

mjutn commented 10 months ago

Hey @stnolting, Excuse me for the tardy response. The TDI and TDO have been defined on the FPGA to correspond with the TDI and the TDO on the JTAG interface's package, should those be switched

The configuration looks as follows, I am using the neorv32_ProcessorTop_MinimalBoot config with some changes, and I am using the neorv32_top.vhd file without any changes:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library neorv32;

entity neorv32_ProcessorTop_MinimalBoot is
  generic (
    -- General --
    CLOCK_FREQUENCY   : natural := 10000000;       -- clock frequency of clk_i in Hz    
    -- Internal Instruction memory --
    MEM_INT_IMEM_EN   : boolean := true;    -- implement processor-internal instruction memory
    MEM_INT_IMEM_SIZE : natural := 128*1024; -- size of processor-internal instruction memory in bytes
    -- Internal Data memory --
    MEM_INT_DMEM_EN   : boolean := true;    -- implement processor-internal data memory 
    MEM_INT_DMEM_SIZE : natural := 128*1024; -- size of processor-internal data memory in bytes
    -- Processor peripherals --
    IO_GPIO_NUM       : natural := 4;       -- number of GPIO input/output pairs (0..64)
    IO_PWM_NUM_CH     : natural := 0        -- number of PWM channels to implement (0..12); 0 = disabled
  );
  port (
    -- Global control --
    clk_i      : in  std_logic;
    rstn_i     : in  std_logic;
    -- JTAG on-chip debugger interface --
    -- jtag_trst_i : in  std_ulogic; -- low-active TAP reset (optional)
    jtag_tck_i  : in  std_ulogic; -- serial clock
    jtag_tdi_i  : in  std_ulogic; -- serial data input
    jtag_tdo_o  : out std_ulogic; -- serial data output
    jtag_tms_i  : in  std_ulogic; -- mode
    -- GPIO (available if IO_GPIO_EN = true) --
    gpio_o     : out std_ulogic_vector(3 downto 0);
    -- primary UART0 (available if IO_UART0_EN = true) --
    uart_txd_o : out std_ulogic; -- UART0 send data
    uart_rxd_i : in  std_ulogic := '0'; -- UART0 receive data
    -- PWM (available if IO_PWM_NUM_CH > 0) --
    pwm_o      : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0)
  );
end entity;

architecture neorv32_ProcessorTop_MinimalBoot_rtl of neorv32_ProcessorTop_MinimalBoot is

  -- internal IO connection --
  signal con_gpio_o : std_ulogic_vector(63 downto 0);
  signal con_pwm_o  : std_ulogic_vector(11 downto 0);

begin

  -- The core of the problem ----------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  neorv32_inst: entity neorv32.neorv32_top
  generic map (
    -- General --
    CLOCK_FREQUENCY   => CLOCK_FREQUENCY,   -- clock frequency of clk_i in Hz
    INT_BOOTLOADER_EN => true,              -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
    -- On-Chip Debugger (OCD) --
    ON_CHIP_DEBUGGER_EN => true,            -- implement on-chip debugger
    -- RISC-V CPU Extensions --
    CPU_EXTENSION_RISCV_Zifencei => true,   -- implement instruction stream sync. (required for the on-chip debugger)
    -- Internal Instruction memory --
    MEM_INT_IMEM_EN   => MEM_INT_IMEM_EN,   -- implement processor-internal instruction memory
    MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
    -- Internal Data memory --
    MEM_INT_DMEM_EN   => MEM_INT_DMEM_EN,   -- implement processor-internal data memory 
    MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
    -- Processor peripherals --
    IO_GPIO_NUM       => IO_GPIO_NUM,       -- number of GPIO input/output pairs (0..64)
    IO_MTIME_EN       => true,              -- implement machine system timer (MTIME)?  
    IO_UART0_EN       => true,              -- implement primary universal asynchronous receiver/transmitter (UART0)?
    IO_PWM_NUM_CH     => IO_PWM_NUM_CH      -- number of PWM channels to implement (0..12); 0 = disabled
  )
  port map (
    -- Global control --
    clk_i       => clk_i,                        -- global clock, rising edge
    rstn_i      => rstn_i,                       -- global reset, low-active, async     
    -- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --     
    -- jtag_trst_i => jtag_trst_i, -- low-active TAP reset (optional)
    jtag_tck_i  => jtag_tck_i,  -- serial clock
    jtag_tdi_i  => jtag_tdi_i,  -- serial data input
    jtag_tdo_o  => jtag_tdo_o,  -- serial data output
    jtag_tms_i  => jtag_tms_i,  -- mode select

    jtag_trst_i => '1',
    -- GPIO (available if IO_GPIO_NUM > 0) --
    gpio_o      => con_gpio_o,                   -- parallel output
    gpio_i      => (others => '0'),              -- parallel input
    -- primary UART0 (available if IO_UART0_EN = true) --
    uart0_txd_o => uart_txd_o,                   -- UART0 send data
    uart0_rxd_i => uart_rxd_i,                   -- UART0 receive data
    -- PWM (available if IO_PWM_NUM_CH > 0) --
    pwm_o       => con_pwm_o                     -- pwm channels
  );

  -- GPIO --
  gpio_o <= con_gpio_o(3 downto 0);
  -- PWM --
  pwm_o <= con_pwm_o(IO_PWM_NUM_CH-1 downto 0);

end architecture;

I should be using the most recent version of the processor, I cloned the repository a few weeks ago and have been working with it since.

Now unfortunately I was using a Raspberry Pi, but that crashed. I can unfortunately not try simply switching TDI and TDO as on WSL2 Ubuntu I get a different problem:

Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
  neorv32.cpu.0 riscv
    neorv32.cpu.0 riscv authdata_read
    neorv32.cpu.0 riscv authdata_write value
    neorv32.cpu.0 riscv dmi_read address
    neorv32.cpu.0 riscv dmi_write address value
    neorv32.cpu.0 riscv expose_csrs n0[-m0][,n1[-m1]]...
    neorv32.cpu.0 riscv expose_custom n0[-m0][,n1[-m1]]...
    neorv32.cpu.0 riscv reset_delays [wait]
    neorv32.cpu.0 riscv resume_order normal|reversed
    neorv32.cpu.0 riscv set_command_timeout_sec [sec]
    neorv32.cpu.0 riscv set_ebreakm on|off
    neorv32.cpu.0 riscv set_ebreaks on|off
    neorv32.cpu.0 riscv set_ebreaku on|off
    neorv32.cpu.0 riscv set_enable_virt2phys on|off
    neorv32.cpu.0 riscv set_enable_virtual on|off
    neorv32.cpu.0 riscv set_ir [idcode|dtmcs|dmi] value
    neorv32.cpu.0 riscv set_prefer_sba on|off
    neorv32.cpu.0 riscv set_reset_timeout_sec [sec]
    neorv32.cpu.0 riscv test_compliance
    neorv32.cpu.0 riscv test_sba_config_reg legal_address num_words illegal_address run_sbbusyerror_test[on/off]
    neorv32.cpu.0 riscv use_bscan_tunnel value [type]
riscv
  riscv authdata_read
  riscv authdata_write value
  riscv dmi_read address
  riscv dmi_write address value
  riscv expose_csrs n0[-m0][,n1[-m1]]...
  riscv expose_custom n0[-m0][,n1[-m1]]...
  riscv reset_delays [wait]
  riscv resume_order normal|reversed
  riscv set_command_timeout_sec [sec]
  riscv set_ebreakm on|off
  riscv set_ebreaks on|off
  riscv set_ebreaku on|off
  riscv set_enable_virt2phys on|off
  riscv set_enable_virtual on|off
  riscv set_ir [idcode|dtmcs|dmi] value
  riscv set_prefer_sba on|off
  riscv set_reset_timeout_sec [sec]
  riscv test_compliance
  riscv test_sba_config_reg legal_address num_words illegal_address run_sbbusyerror_test[on/off]
  riscv use_bscan_tunnel value [type]
Error: invalid subcommand "set_mem_access progbuf"
neorv32/sw/openocd/openocd_neorv32.cfg:36: Error: 
in procedure 'script' 
at file "embedded:startup.tcl", line 26
at file "neorv32/sw/openocd/openocd_neorv32.cfg", line 36
Error: Target has not been initialized

Could the openOCD version be the problem? Since I am using WSL2 it is running on the Ubuntu 22.04.3 LTS system so it says it is up to date, but now I see the pi was running a different version. Sorry to hijack the thread with different problems like this, and once again thank you so much for your time!

stnolting commented 10 months ago

The wiring and the generics configuration looks fine. Btw, there is a "know-good" pre-defined test setup for the on-chip debugger: rtl/test_setups/neorv32_test_setup_on_chip_debugger.vhd 😉

MEM_INT_IMEM_SIZE : natural := 128*1024; -- size of processor-internal instruction memory in MEM_INT_DMEM_SIZE : natural := 128*1024; -- size of processor-internal data memory in bytes

That's a lot of block RAM! May I ask which FPGA you are using?

on WSL2 Ubuntu I get a different problem:

I am using openocd version 0.10.0 and it works without any problems.

You can safely remove the set_mem_access progbuf line from the openocd configuration file as progbuf is the default mechanism anyway. However, I wonder why this causes an error... As far as I know this config switch has not been deprecated. 🤔

mjutn commented 10 months ago

Removing the set_mem_access progbuf line gives new errors:


Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Error: Parse error at character = in:
Error: 2048=cfusel
Error:     ^
    neorv32.cpu.0 riscv expose_csrs n0[-m0][,n1[-m1]]...
  riscv expose_csrs n0[-m0][,n1[-m1]]...

Error: Target has not been initialized

This coupled with the fact that I had to add underscores to the config file, so ftdi_layout_init instead of ftdi layout_init leaves me feeling like I am missing a package or part of a program or something. Furthermore, reducing RAM count did not affect my config. The on chip debugger test setup spits out questions marks into my UART terminal, even though my own config works fine... I added the cpu extensions enabled in the on chip debugger test setup to my own config, although I am not able to test it since openOCD struggles with each command in the config file for some reason.

stnolting commented 10 months ago

Can you try a different openOCD version or maybe even a different machine?

The on chip debugger test setup spits out questions marks into my UART terminal

So even the bootloader does not work?! Have you checked the synthesis results? Are there any relevant warnings?

mjutn commented 10 months ago

Hey @stnolting,

Good news! I have managed to get it working. What was needed was:

Anyways, now I get target halted finally. Thank you so much for your suggestions!

stnolting commented 10 months ago

Awesome!!!

A newer OpenOCD version, the version that comes with WSL2 is 0.11.0, I installed 0.12.0-2. This allowed for ftdi layout instead of ftdi_layout as well.

Good to know!

The bootloader issue was a user error, the default clock speed in the on chip debugger setup is 100MHz, not 10MHz (counting zeros is hard)

Happens to me all the time... 😅 I think VHDL allows to use underscores to separate triplets like 10_000_000.

2MHz adapter speed did not work, 1MHz did work for adapter speed for my chosen clock frequency of 10MHz. In the requirements it is stated that maximum one fifth of clock frequency is allowed, but apparently 2MHz is too close to that for a 10MHz clock frequency?

1/5 of the main clock is the physical maximum that the clock domain crossing can support (i.e. sampling the JTAG clock into the processor clock domain), but the actual clock frequency might be lower as it might also depend on your wiring setup. However, I will check that frequency statement again.

Anyways, now I get target halted finally. Thank you so much for your suggestions!

👍 🚀

So I think we can close this, right?