Hello! 馃憢

Black Box output characterization of CD2003 DCR receiver

Circuit: DDX-Commercial-7 Antenna: Small jumper cable attached 10m: 36 dB on WSJT-X audio meter, on quiet and also with nearby beacon on !!! 12m: 36 dB on audio meter, on quiet and also with nearby beacon on !!! 15m: 46 dB on audio meter on quiet, 65 dB with nearby beacon on - OK 20m: 44 dB on quiet, 65 dB with beacon on - OK 40m: 40 dB on quiet, 60 dB with beacon on - OK ...

September 21, 2025 路 1 min 路 213 words 路 Dhiru Kholia

Running Vivado 2025.1 on Ubuntu 25.04 (plucky)

Notes to get Vivado 2025.1 running on Ubuntu 25.04 (plucky) Linux distribution. Original reference: https://pavel-demin.github.io/qmtech-xc7z020-notes/led-blinker-77-76/ Install dependencies: sudo apt-get update sudo apt-get --no-install-recommends install \ bc binfmt-support bison build-essential ca-certificates curl \ debootstrap device-tree-compiler dosfstools flex fontconfig git \ libncurses-dev libssl-dev libtinfo6 parted qemu-user-static \ squashfs-tools u-boot-tools x11-utils xvfb zerofree zip Hack deps a bit: sudo ln -s /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libtinfo.so.5 You can now go ahead and run the Vivado installer. Enable FPGA fabric consumption statistics Use the following patch: diff --git a/scripts/core.tcl b/scripts/core.tcl index 583de1b..79e3ae4 100644 --- a/scripts/core.tcl +++ b/scripts/core.tcl @@ -3,7 +3,7 @@ set core_name [lindex $argv 0] set part_name [lindex $argv 1] -file delete -force tmp/cores/$core_name tmp/cores/$core_name.cache tmp/cores/$core_name.hw tmp/cores/$core_name.ip_user_files tmp/cores/$core_name.sim tmp/cores/$core_name.xpr +file delete -force tmp/cores/$core_name tmp/cores/$core_name.cache tmp/cores/$core_name.hw tmp/cores/$core_name.ip_user_files tmp/cores/$core_name.sim create_project -part $part_name $core_name tmp/cores user@system:~/repos/qmtech-xc7z020-notes$ source ~/Xilinx/2025.1/Vivado/settings64.sh user@system:~/repos/qmtech-xc7z020-notes$ make NAME=sdr_receiver_ft8_77_76 bit ... $ vivado -mode tcl ... Vivado% open_project tmp/sdr_receiver_ft8_77_76.xpr Vivado% synth_design Vivado% report_utilization Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. Copyright 2022-2025 Advanced Micro Devices, Inc. All Rights Reserved. --------------------------------------------------------------------------------------------------------------------------------------------- | Tool Version : Vivado v.2025.1 (lin64) Build 6140274 Wed May 21 22:58:25 MDT 2025 | Date : Sun Sep 21 13:49:17 2025 | Host : system running 64-bit Ubuntu 25.04 | Command : report_utilization | Design : system_wrapper | Device : xc7z020clg484-1 | Speed File : -1 | Design State : Synthesized --------------------------------------------------------------------------------------------------------------------------------------------- Utilization Design Information Table of Contents ----------------- 1. Slice Logic 1.1 Summary of Registers by Type 2. Memory 3. DSP 4. IO and GT Specific 5. Clocking 6. Specific Feature 7. Primitives 8. Black Boxes 9. Instantiated Netlists 1. Slice Logic -------------- +----------------------------+-------+-------+------------+-----------+-------+ | Site Type | Used | Fixed | Prohibited | Available | Util% | +----------------------------+-------+-------+------------+-----------+-------+ | Slice LUTs* | 35992 | 0 | 0 | 53200 | 67.65 | | LUT as Logic | 31140 | 0 | 0 | 53200 | 58.53 | | LUT as Memory | 4852 | 0 | 0 | 17400 | 27.89 | | LUT as Distributed RAM | 228 | 0 | | | | | LUT as Shift Register | 4624 | 0 | | | | | Slice Registers | 38984 | 0 | 0 | 106400 | 36.64 | | Register as Flip Flop | 38984 | 0 | 0 | 106400 | 36.64 | | Register as Latch | 0 | 0 | 0 | 106400 | 0.00 | | F7 Muxes | 560 | 0 | 0 | 26600 | 2.11 | | F8 Muxes | 0 | 0 | 0 | 13300 | 0.00 | +----------------------------+-------+-------+------------+-----------+-------+ * Warning! The Final LUT count, after physical optimizations and full implementation, is typically lower. Run opt_design after synthesis, if not already completed, for a more realistic count. Warning! LUT value is adjusted to account for LUT combining. Warning! For any ECO changes, please run place_design if there are unplaced instances 1.1 Summary of Registers by Type -------------------------------- +-------+--------------+-------------+--------------+ | Total | Clock Enable | Synchronous | Asynchronous | +-------+--------------+-------------+--------------+ | 0 | _ | - | - | | 0 | _ | - | Set | | 0 | _ | - | Reset | | 0 | _ | Set | - | | 0 | _ | Reset | - | | 0 | Yes | - | - | | 0 | Yes | - | Set | | 0 | Yes | - | Reset | | 441 | Yes | Set | - | | 38543 | Yes | Reset | - | +-------+--------------+-------------+--------------+ 2. Memory --------- +-------------------+------+-------+------------+-----------+-------+ | Site Type | Used | Fixed | Prohibited | Available | Util% | +-------------------+------+-------+------------+-----------+-------+ | Block RAM Tile | 87 | 0 | 0 | 140 | 62.14 | | RAMB36/FIFO* | 77 | 0 | 0 | 140 | 55.00 | | RAMB36E1 only | 77 | | | | | | RAMB18 | 20 | 0 | 0 | 280 | 7.14 | | RAMB18E1 only | 20 | | | | | +-------------------+------+-------+------------+-----------+-------+ * Note: Each Block RAM Tile only has one FIFO logic available and therefore can accommodate only one FIFO36E1 or one FIFO18E1. However, if a FIFO18E1 occupies a Block RAM Tile, that tile can still accommodate a RAMB18E1 3. DSP ------ +----------------+------+-------+------------+-----------+-------+ | Site Type | Used | Fixed | Prohibited | Available | Util% | +----------------+------+-------+------------+-----------+-------+ | DSPs | 87 | 0 | 0 | 220 | 39.55 | | DSP48E1 only | 87 | | | | | +----------------+------+-------+------------+-----------+-------+ 4. IO and GT Specific --------------------- +-----------------------------+------+-------+------------+-----------+--------+ | Site Type | Used | Fixed | Prohibited | Available | Util% | +-----------------------------+------+-------+------------+-----------+--------+ | Bonded IOB | 22 | 22 | 0 | 200 | 11.00 | | IOB Master Pads | 11 | | | | | | IOB Slave Pads | 11 | | | | | | Bonded IPADs | 0 | 0 | 0 | 2 | 0.00 | | Bonded IOPADs | 130 | 130 | 0 | 130 | 100.00 | | PHY_CONTROL | 0 | 0 | 0 | 4 | 0.00 | | PHASER_REF | 0 | 0 | 0 | 4 | 0.00 | | OUT_FIFO | 0 | 0 | 0 | 16 | 0.00 | | IN_FIFO | 0 | 0 | 0 | 16 | 0.00 | | IDELAYCTRL | 0 | 0 | 0 | 4 | 0.00 | | IBUFDS | 8 | 8 | 0 | 192 | 4.17 | | PHASER_OUT/PHASER_OUT_PHY | 0 | 0 | 0 | 16 | 0.00 | | PHASER_IN/PHASER_IN_PHY | 0 | 0 | 0 | 16 | 0.00 | | IDELAYE2/IDELAYE2_FINEDELAY | 0 | 0 | 0 | 200 | 0.00 | | ILOGIC | 7 | 7 | 0 | 200 | 3.50 | | IFF_IDDR_Register | 7 | 7 | | | | | OLOGIC | 0 | 0 | 0 | 200 | 0.00 | +-----------------------------+------+-------+------------+-----------+--------+ 5. Clocking ----------- +------------+------+-------+------------+-----------+-------+ | Site Type | Used | Fixed | Prohibited | Available | Util% | +------------+------+-------+------------+-----------+-------+ | BUFGCTRL | 3 | 0 | 0 | 32 | 9.38 | | BUFIO | 0 | 0 | 0 | 16 | 0.00 | | MMCME2_ADV | 0 | 0 | 0 | 4 | 0.00 | | PLLE2_ADV | 1 | 0 | 0 | 4 | 25.00 | | BUFMRCE | 0 | 0 | 0 | 8 | 0.00 | | BUFHCE | 0 | 0 | 0 | 72 | 0.00 | | BUFR | 0 | 0 | 0 | 16 | 0.00 | +------------+------+-------+------------+-----------+-------+ 6. Specific Feature ------------------- +-------------+------+-------+------------+-----------+-------+ | Site Type | Used | Fixed | Prohibited | Available | Util% | +-------------+------+-------+------------+-----------+-------+ | BSCANE2 | 0 | 0 | 0 | 4 | 0.00 | | CAPTUREE2 | 0 | 0 | 0 | 1 | 0.00 | | DNA_PORT | 0 | 0 | 0 | 1 | 0.00 | | EFUSE_USR | 0 | 0 | 0 | 1 | 0.00 | | FRAME_ECCE2 | 0 | 0 | 0 | 1 | 0.00 | | ICAPE2 | 0 | 0 | 0 | 2 | 0.00 | | STARTUPE2 | 0 | 0 | 0 | 1 | 0.00 | | XADC | 0 | 0 | 0 | 1 | 0.00 | +-------------+------+-------+------------+-----------+-------+ 7. Primitives ------------- +-----------+-------+----------------------+ | Ref Name | Used | Functional Category | +-----------+-------+----------------------+ | FDRE | 38543 | Flop & Latch | | LUT6 | 13222 | LUT | | LUT2 | 10550 | LUT | | SRL16E | 3820 | Distributed Memory | | LUT3 | 3616 | LUT | | CARRY4 | 3460 | CarryLogic | | LUT4 | 3334 | LUT | | LUT1 | 1584 | LUT | | LUT5 | 1315 | LUT | | SRLC32E | 804 | Distributed Memory | | MUXF7 | 560 | MuxFx | | FDSE | 441 | Flop & Latch | | RAMD64E | 228 | Distributed Memory | | BIBUF | 130 | IO | | DSP48E1 | 87 | Block Arithmetic | | RAMB36E1 | 77 | Block Memory | | RAMB18E1 | 20 | Block Memory | | IBUFDS | 8 | IO | | IDDR | 7 | IO | | OBUF | 4 | IO | | BUFG | 3 | Clock | | PS7 | 1 | Specialized Resource | | PLLE2_ADV | 1 | Clock | | OBUFT | 1 | IO | | IBUF | 1 | IO | +-----------+-------+----------------------+ 8. Black Boxes -------------- +----------+------+ | Ref Name | Used | +----------+------+ 9. Instantiated Netlists ------------------------ +----------+------+ | Ref Name | Used | +----------+------+ Bonus notes for EDGE ZYNQ SoC FPGA Development Board See https://gist.github.com/rikka0w0/24b58b54473227502fa0334bbe75c3c1 hack to let Vivado see the FPGA on this board using the onboard programmer. ...

September 21, 2025 路 8 min 路 1548 words 路 Dhiru Kholia

Single Transistor LNA for HF

Note: This HF LNA design is inspired by Charlie Morris ZL2CTM's prior work. The idea that a single-transistor-preamp with 10 dB gain is more than enough for HF comes from Gajendra Kumar (VU2BGS). As a new "designer" I am often overwhelmed by the different possible design paths - so having guidance from an elmer becomes crucial. It seems even MMBT2222A should work for building a HF LNA! ...

September 21, 2025 路 1 min 路 94 words 路 Dhiru Kholia

WSPR Decoding Challenges

The https://github.com/rxt1077/wspr_spread work is pretty awesome. It helped us debug why our TCXO-powered-WSPR beacon was pretty decent on 4m band but flaky on 2m. Doppler shift value on 70 MHz: ... 70.0924994 VU3CER MK68 23 0 0.29 1 1 0 1 44 1 810 0.517 Now see the problem on 144 MHz: ... 144.4905417 VU3CER MK68 23 -3 0.12 1 1 0 1 39 1 810 0.865 Pretty all over the place! ...

September 21, 2025 路 1 min 路 96 words 路 Dhiru Kholia

WSPRing on higher bands

Our WSPR beacon design works fine even on the 4m band (~70 MHz) . The key is to use a 25 MHz high-quality TCXO, like the 25 MHz HCI 0.5ppm TCXO! 2m WSPR is still out of reach for now - see the following sporadic decodes. Of course, the next challenge is to get 2m WSPR beacons working 100% reliably at a low cost. ...

August 30, 2025 路 1 min 路 86 words 路 Dhiru Kholia

Notes on coupled inductors

The usage of ready-made coupled inductors was pioneered by Jim Veatch in his award-winning RF amplifier designs. For Baby-QRO applications, we can use Wurth 744851330 coupled inductor. For 5W / 10W RF amplifier applications, we can use Bourns SRF1260A-4R7Y coupled inductor. Recently we were able to utilize very cost-effective YJYCOIN YPRH1207C-4R7M Chinese coupled inductor with excellent results. With our current Digital Amplifier designs, this Chinese coupled inductor works even at ~75 MHz. ...

August 17, 2025 路 1 min 路 81 words 路 Dhiru Kholia

Initial success with cost-effective 6m WSPR + 2m FT8 beacons

Our 6m WSPR beacon design works fine now. The key is to use a 25 MHz high-quality TCXO, like the 25 MHz HCI 0.5ppm TCXO! 2m WSPR is still out of reach for this VFO design - see the following drifty screenshots: While WSPR is no bueno, 2m FT8 works pretty fine! Of course, the next challenge is to get 2m WSPR beacons working at a low cost. ...

August 16, 2025 路 1 min 路 72 words 路 Dhiru Kholia

Checking Zoom latency externally

Here is a handy script that I often use to check the quality of the Zoom connection. It measures TCP latency instead of the usual ICMP stuff (which is often blocked). #!/usr/bin/env python3 """ TCP Ping Test (defaults to port 80, 10000 packets) Usage: ./tcpping.py host [port] [maxCount] - Ctrl-C Exits with Results """ """ pip3 install matplotlib numpy python3 ./tcp_ping_grapher.py 115.114.56.202 443 100 python3 ./tcp_ping_grapher.py teams.microsoft.com 443 100 """ import sys import socket import time import signal from timeit import default_timer as timer # https://matplotlib.org/examples/animation/animate_decay.html import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation host = None port = 80 # Default to 10000 connections max maxCount = 10000 ## Inputs # Required Host try: host = sys.argv[1] # host = "115.114.56.202" except IndexError: print("Usage: tcpping.py host [port] [maxCount]") sys.exit(1) # Optional Port try: port = int(sys.argv[2]) # port = 443 except ValueError: print("Error: Port Must be Integer:", sys.argv[2]) sys.exit(1) except IndexError: pass # Optional maxCount try: maxCount = int(sys.argv[3]) except ValueError: print("Error: Max Count Value Must be Integer", sys.argv[3]) sys.exit(1) except IndexError: pass # Pass/Fail counters passed = 0 failed = 0 def getResults(): """ Summarize Results """ lRate = 0 if failed != 0: lRate = failed / (count) * 100 lRate = "%.2f" % lRate print("\nTCP Ping Results: Connections (Total/Pass/Fail): [{:}/{:}/{:}] (Failed: {:}%)".format((count), passed, failed, str(lRate))) def signal_handler(signal, frame): """ Catch Ctrl-C and Exit """ getResults() sys.exit(0) # Register SIGINT Handler signal.signal(signal.SIGINT, signal_handler) def work(t=0): passed = 0 failed = 0 count = 0 maxCount = 3200 # Loop while less than max count or until Ctrl-C caught while count < maxCount: # Increment Counter count += 1 success = False # New Socket s = socket.socket( socket.AF_INET, socket.SOCK_STREAM) # 1sec Timeout s.settimeout(1) # Start a timer s_start = timer() # Try to Connect try: s.connect((host, int(port))) s.shutdown(socket.SHUT_RD) success = True # Connection Timed Out except socket.timeout: print("Connection timed out!") failed += 1 except OSError as e: print("OS Error:", e) failed += 1 # Stop Timer s_stop = timer() s_runtime = "%.2f" % (1000 * (s_stop - s_start)) if success: print("Connected to %s[%s]: tcp_seq=%s time=%s ms" % (host, port, (count-1), s_runtime)) passed += 1 # Sleep for 1sec if count < maxCount: # time.sleep(0.5) # time.sleep(1) time.sleep(2) t += 2 yield t, float(s_runtime) # Output Results if maxCount reached # getResults() def data_gen(t=0): cnt = 0 while cnt < 1000: cnt += 1 t += 0.1 yield t, np.sin(2*np.pi*t) * np.exp(-t/10.) def init(): ax.set_ylim(0, 128 * 3) ax.set_xlim(0, 300) del xdata[:] del ydata[:] line.set_data(xdata, ydata) return line, fig, ax = plt.subplots() line, = ax.plot([], [], lw=2) ax.grid() xdata, ydata = [], [] def run(data): # update the data t, y = data xdata.append(t) ydata.append(y) xmin, xmax = ax.get_xlim() if t >= xmax: ax.set_xlim(xmin, 2*xmax) ax.figure.canvas.draw() line.set_data(xdata, ydata) return line, ani = animation.FuncAnimation(fig, run, work, blit=False, interval=10, repeat=False, init_func=init) plt.show() Usage: ...

August 8, 2025 路 3 min 路 516 words 路 Dhiru Kholia

WiFi VFO, beacon and signal generator

We make heavy use of https://github.com/kholia/Easy-Digital-Beacons-v1 for testing RF amplifiers. This single board is a versatile WiFi VFO and FT8 / FT4 / WSPR beacon. You can also use our CW-SigGen project to generate a suitable test signal.

July 5, 2025 路 1 min 路 38 words 路 Dhiru Kholia

New RF parts and new promises - part 2

Tokmas CID9N65E3 rocks! It is CRAZY how efficient this GaN FET is in TO-252 (DPAK) package. It generates 5W @ 28 MHz with 13.8V at drain without even warming up! Close to 4W @ 50 MHz with 12.0V at drain. 5W+ @ 50 MHz with 13.8V at drain. 11W+ @ 50 MHz with 20V at drain. It even produces ~3W at 70 MHz with 13V at drain - w00t! ...

June 15, 2025 路 1 min 路 185 words 路 Dhiru Kholia