CWLite/CW305 cannot lock ADC

Hello, I am trying to setup a CW305 with a Chipwhisperer Lite, but I consistently have the problem that scope.clock.reset_adc() fails. I have looked at other posts, mainly at CW-Lite and CW305 - ADC Lock Fail, but none of the solutions work for me. My setup Python script includes the following options:

scope.gain.db = 25
scope.adc.samples = 129
scope.adc.offset = 0
scope.adc.basic_mode = “rising_edge”
scope.clock.adc_src = “extclk_x4”
scope.io.hs2 = “disabled”

target.vccint_set(1.0)
target.pll.pll_enable_set(True)
target.pll.pll_outenable_set(False, 0)
target.pll.pll_outenable_set(True, 1)
target.pll.pll_outenable_set(False, 2)
target.pll.pll_outsource_set(“PLL0”, 0)
target.pll.pll_outfreq_set(10E6, 1)
target.clkusbautooff = True
target.clksleeptime = 1

Even when calling reset_adc() repeatedly, it does not work. The CW305 board settings are J16=0, K16=1, K15=1, L14=1. Printing scope.clock shows:
adc_src = extclk_x4
adc_phase = 0
adc_freq = 0
adc_rate = 0.0
adc_locked = False
freq_ctr = 0
freq_ctr_src = extclk
clkgen_src = system
extclk_freq = 10000000
clkgen_mul = 2
clkgen_div = 1
clkgen_freq = 192000000.0
clkgen_locked = True

What bitfile have you loaded on the CW305?
If it’s not one of ours, is it driving a clock out onto the HS1 pin of the 20-pin connector?
And have you connected the CW-lite to the CW305 with the 20-pin ribbon cable?

The boards are connected; I’m using a bitstream I built of Ibex for cw305, so I think it should have the right clock output?

No, it doesn’t. The Ibex soft-core can be clocked from either the CW305 PLL or from CW-lite’s HS2 output clock, however it doesn’t feed its clock back to CW-lite.
There is more info here, including the setup_ibex notebook that will set everything up for you.

Thanks! That was the issue, clocking Ibex off hs2 solved it. Sorry if this isn’t the right place to ask, but when I use load_demo_system.sh on the Ibex repo (modified to use the cw305 openocd cfg with correct id) to program my firmware .elf I get “invalid command name “load_image””, would you know how to fix this? I’ve tried looking for similar issues or modifying the config and changing openocd versions but found nothing so far.

Sounds like an openocd issue. The lowRISC repository states that version 0.11 or above is required; I’ve used this version successfully:

$ openocd --version
Open On-Chip Debugger 0.11.0+dev-00693-g0a36acbf6 (2022-05-23-22:39)

I’m currently using 0.12.0+dev-00569-gbc9ca5f4a; It seems the problem is that the cfg is missing init and halt commands, but init fails with

Error: failed to reset FTDI device: LIBUSB_ERROR_PIPE
Error: unable to open ftdi device with description '*', serial '*' at bus location '*'

which I think is an issue with the cfg file, like some parameters are missing? Though then I don’t know why it worked for you

Ah I think I understand – I hadn’t noticed your reference to cw305_openocd.cfg… are you trying to use your CW-lite in MPSSE mode to load the firmware? Unfortunately that won’t work, you need a standalone JTAG programmer, connected to the Xilinx JTAG header on the CW305 (connect the TMS, TCK, TDI, TDO, GND pins).

I’ve used a Tigard, with the following config file:

interface ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 1
adapter_khz 500
ftdi_layout_init 0x0038 0x003b
ftdi_layout_signal nTRST -data 0x0010
ftdi_layout_signal nSRST -data 0x0020
transport select jtag

# Configure JTAG chain and the target processor
set _CHIPNAME riscv

# Configure JTAG expected ID
# arty-a7-35t
set _EXPECTED_ID 0x0362D093 
# arty-a7-100t
#set _EXPECTED_ID 0x13631093 

jtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_EXPECTED_ID -ignore-version
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME

riscv set_ir idcode 0x09
riscv set_ir dtmcs 0x22
riscv set_ir dmi 0x23

#adapter speed 10000

riscv set_prefer_sba on
gdb_report_data_abort enable
gdb_report_register_access_error enable
gdb_breakpoint_override hard

reset_config none

init
halt

The alternative is to re-build the bitfile with the target FW image. I wouldn’t recommend this because it requires you to rebuild the bitfile every time you change the FW. Here are my notes on how to do this (from a long time ago, hopefully still applies):

  • need to generate .vmem file manually because the current build process doesn’t
  • copied steps from how blank.vmem is built:
$ riscv32-unknown-elf-objcopy -O binary demo demo.bin
$ srec_cat demo.bin -binary -offset 0x0000 -byte-swap 4 -o demo.vmem -vmem
  • then change the SRAMInitFile in .core to point to the new demo.vmem and rebuild the FPGA bitfile

I’ve been trying to get the second method to work, but I noticed that target.fpga_read always returns zeroes regardless of what I fpga_write to it. I’m a bit lost here, as everything works fine with the normal cw305 bitfile, including the capture, but with any Ibex one this happens. Is this something particular with the Ibex core? If so, how can I modify the capture examples (something like this one) to work for Ibex?

target.fpga_write() and target.fpga_read() are our of scope for the soft cores; they are built to “look and feel” like our normal microprocessor targets (i.e. STM32, XMEGA, SAM4S…), so they’re simpleserial targets (assuming you build simpleserial firmware from e.g. chipwhisperer/hardware/victims/firmware at develop · newaetech/chipwhisperer · GitHub).

This is explained here: CW312T-XC7A35 - NewAE Hardware Product Documentation (page is for the CW312_A35 target, but it’s exactly the same for the CW305 version).

I see, so can the usual capture process be used for soft cores? capture_trace(scope, target, text, key).textout is also only zeroes, but it’s difficult to debug without fpga_read()

You should be able to run most of notebooks (not the CW305 ones), but you have to modify them to use Setup_Ibex.ipynb instead of Setup_Generic.ipynb.

Furthermore in your case you’ll have to modify Setup_Ibex.ipynb to program your custom bitfile instead of the one that’s packaged with ChipWhisperer.

If you still have issues communicating with your target, the next step is to fire up a debugger, following the instructions here. You’ll need an external debugger for that.

Thanks, I’ll look into it.

I believe this is the wrong link, as it’s Setup_Ibex again?

Yes sorry, correct link is:

1 Like

I switched to using a Xilinx JTAG programmer to load my firmware, using the openocd cfg you provided before, but it fails with

Warn : libusb_detach_kernel_driver() failed with LIBUSB_ERROR_INVALID_PARAM, trying to continue anyway
Error: libusb_claim_interface() failed with LIBUSB_ERROR_NOT_FOUND
Error: unable to open ftdi device with description '*', serial '*' at bus location '*'

Could it be the Xilinx programmer is not suitable for this? I feel like that is the only difference with your process.

AFAIK, Xilinx JTAG programmers only work for programming FPGA bitfiles; they don’t work as a generic JTAG programming device.

You need something that’s supported by openocd: Supported JTAG interfaces

I’ve used Tigard.

I tried using Tigard with the following file, I’ve also connected the 5 required pins

adapter driver ftdi
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 1
#adapter_khz 500
adapter speed 500
ftdi_layout_init 0x0038 0x003b
ftdi_layout_signal nTRST -data 0x0010
ftdi_layout_signal nSRST -data 0x0020
transport select jtag

# Configure JTAG chain and the target processor
set _CHIPNAME riscv

# Configure JTAG expected ID
# arty-a7-35t
#set _EXPECTED_ID 0x0362D093 
# arty-a7-100t
set _EXPECTED_ID 0x13631093 

jtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_EXPECTED_ID -ignore-version
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME

riscv set_ir idcode 0x09
riscv set_ir dtmcs 0x22
riscv set_ir dmi 0x23

#adapter speed 10000

riscv set_prefer_sba on
gdb_report_data_abort enable
gdb_report_register_access_error enable
gdb_breakpoint_override hard

reset_config none

init
halt

but it still doesn’t work:

Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
force hard breakpoints
Info : clock speed 500 kHz
Info : JTAG tap: riscv.cpu tap/device found: 0x13631093 (mfg: 0x049 (Xilinx), part: 0x3631, ver: 0x1)
Error: dtmcontrol is 0. Check JTAG connectivity/board power.
Warn : target riscv.cpu examination failed
Info : starting gdb server for riscv.cpu on 3333
Info : Listening on port 3333 for gdb connections
Error: Target not examined yet

I’m kind of lost where I’m going wrong

Are you supplying a clock to the FPGA? What’s your CW305 and scope setup?

Largely copied from Setup_Ibex except using a custom bitfile built from the Ibex-demo repo:

scope.default_setup()
scope.clock.clkgen_src = 'system'
scope.clock.clkgen_freq = 100e6
scope.clock.adc_src = 'clkgen_x1'
target = cw.target(scope, cw.targets.SimpleSerial)
target.baud = 115200

cw305 = cw.target(None, cw.targets.CW305, bsfile="path/ibex-demo-system/build/lowrisc_ibex_demo_system_0/synth_cw305-vivado/lowrisc_ibex_demo_system_0.runs/impl_1/top_cw305.bit", fpga_id='100t', force=True)

and this is scope.clock afterwards:

adc_src       = clkgen_x1
adc_phase     = 0
adc_freq      = 99999996
adc_rate      = 99999996.0
adc_locked    = True
freq_ctr      = 0
freq_ctr_src  = extclk
clkgen_src    = system
extclk_freq   = 10000000
clkgen_mul    = 25
clkgen_div    = 24
clkgen_freq   = 100000000.0
clkgen_locked = True

J16 is on, LED1 and LED7 are blinking if that helps. I also noticed that changing dtmcs in the openocd cfg errors with e.g. Error: Unsupported DTM version: 9 instead, so it doesn’t look like it’s only reading zeroes (since it’s getting the version from the specified register by 6.1.4 of this riscv spec).

Hmm, since you’ve rebuilt the bitfile, I’m wondering if you’ve run into this issue?
Can you try using the bitfile that’s included in the ChipWhisperer repository instead, since that is known to work?