Category: tutorial/howto Page 1 of 2

Writing and Understanding RISC-V Assembly Code

For quite a while I have followed the RISC-V ISA with growing intereset. Now that RISC-V is becoming more and more popular and catching a lot of public attention, it is time to get my hands dirty with some low level RISC-V assembly coding.

An instruction set architecture (ISA) is a specification of the commands/instructions a specific processor or processor architecture family does understand and that it can execute. For this tutorial we will be looking at the RISC-V ISA.
Assembly code (often abbreviated asm) is textual low-level program code, which can be directly translated to machine code. We will be working with the RISC-V assembly language.
The connection between an ISA and assembly code is such that assembly language/code is used to write a program for a corresponding ISA. In theory there could be more than one assembly language for the same ISA (like there are multiple high level programming language for the same machine architecture), but this is seldom the case (having different “flavors” of the same assembly language is more common).

I think there is no need to reproduce any details about the RISC-V ISA at this point. There are plenty of good sources online, the official specification of the RISCV user-level ISA of course, especially the chapters “Instruction Set Listings” and “RISC-V Assembly Programmer’s Handbook”, or one of the RISCV reference cards.

Another good tutorial for beginners, which is a little slow paced imho, is the Western Digital RISC-V ASM tutorial on Youtube (the tutorial really gets started with part 6). For beginners it is nice to see how the base addresses for peripherals can be found using the datasheet and how to “talk to” those peripheral blocks using assembly code.

Note that all examples presented in the following are created/run on Ubuntu 18.04 (WSL) and platformio is used for convenience (no need to set up the toolchains manually). On Ubuntu platformio can be obtained with apt:

$> sudo apt install platformio

Now lets start by creating a new folder for our platformio project and initializing it.

$> mkdir riscv-asm-examples
$> cd riscv-asm-examples 
$> platformio init

I use the following platformio.ini file to define the project parameters, since I have a HiFive1 board lying around somewhere. Feel free to use any other supported RISC-V board or framework instead. If you do not own a RISC-V board you can still run the assembler and have a look at the machine code. But I really recommend to get a board, the Longan Nano costs only 5$.
The platformio.ini file I am using is very simple:

$> cat ./platformio.ini
[env:freedom-e300-hifive1]
platform = riscv
board = freedom-e300-hifive1
framework = freedom-e-sdk

To check that platformio is installed and the platformio.ini file is correct run a sanity check using an empty main function:

$> echo "int main(void) {return 13;}" > ./src/main.c
$> platformio run

Running platformio for the first time can take a while because all the required packages and toolchains will be downloaded, so do not get impatient if its takes a little while.
If everything went fine a [SUCCESS] message should show up after a while.

Okay, the main function has been compiled. To see the assembler code which was produced we can used objdump -d. The -d option stands for disassemble, which means that the given object file will be “translated” to human readable assembler code.
The object file of interest is hidden away by platformio in .pio/build/freedom-e300-hifive1/src/ (folder may vary if you used a different build framework).
To disassemble the almost empty main function from before do like so:

$> objdump -d .pio/build/freedom-e300-hifive1/src/main.o
.pio/build/freedom-e300-hifive1/src/main.o:     file format elf32-little
 objdump: can't disassemble for architecture UNKNOWN!

Uh oh! Why isn’t it working? The tutorial said that this should work. Liar!
Here is why:

$> ls -lha $(which objdump)
lrwxrwxrwx 1 root root 24 May  8  2019 /usr/bin/objdump -> x86_64-linux-gnu-objdump*

The objdump we called is for the x86 ISA, not for RISC-V. We need to call the correct objdump executable from our RISC-V toolchain. The toolchain is hidden away by platformio inside the user’s home folder under ~/.platformio.

~/.platformio/packages/toolchain-riscv/riscv64-unknown-elf/bin/objdump -d .pio/build/freedom-e300-hifive1/src/main.o
Disassembly of section .text.startup:
 00000000 
:
    0:   4535                    li      a0,13
    2:   8082                    ret

Nice. The general structure of the assembly code is:

<memory_address>: <opcode>    <instruction> [<parameter(s)>]

So the assembly code above tells us that an immediate value 13 is loaded into register a0, then we return. Register a0 is the register which holds the function return value according to the RISC-V calling convention. The value 13 was given as return value in the main function. So this is really the assembly code corresponding to our main function. Hurrah!

To make things easier I recommend to set a symbolic link to the correct objdump executable, e.g. inside the platformio project folder.

$> ln -s ~/.platformio/packages/toolchain-riscv/riscv64-unknown-elf/bin/objdump objdump
$> ./objdump --version
GNU objdump (SiFive Binutils 2.32.0-2019.08.0) 2.32

OK, time to start with some assembly coding examples. Most examples are very minimalistic and use the main function as entry point from which the assembly code is invoced. The main goal, to show that assembly code can achieve the same things as C code, is proven nontheless.

Oh and to upload an example to your board (e.g. HiFive1) run the following command inside the project root directory (folder where platformio.ini is located):

$> platformio run -t upload

On my Windows 10 machine this only worked with VisualStudioCode (with the platformio plugin intalled). WSL did not work (USB driver stuff). Using a Linux VM should not pose any problem though.
Also the HiFive1 requires a push of the red reset button to reset the board and load the new program after it was uploaded.

Example 1: Superblink

This example just reproduces the WesternDigital RISC-V assembler tutorial from Youtube. Some GPIO pins are initialized and LEDs are toggled between on and off.
Check out the code on github.

Cycling through the RGB LEDs with superblink.

Example 2: Superfade

This example is an extension to superblink and uses PWM signals to control the intensity of LED’s. Three PWM channels are used to control the intensity of the 3 RGB color LEDs. One-by-one the LEDs are ramped up to full intensity and then reverted back to 0 intensity, creating a (incomplete) rainbow pattern.
Check out the code on github.

Fading the RGB LEDs with PWM signals.

Example 3: Simple UART Echo

This example waits to receive data in the UART RX FIFO and subsequently sends the same data out to the UART TX FIFO, thus echoing back any characters that are received.
Check out the code on github.

uartecho in action.

That’s all for the moment. See you next time.


References:

  1. https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md
  2. https://rv8.io/asm.html
  3. https://github.com/rv8-io/rv8
  4. https://www.youtube.com/watch?v=KLybwrpfQ3I
  5. https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
  6. https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf

First Steps with the iCEBreaker FPGA Development Board

The iCEBreaker board is the first FPGA development board with a fully open-source toolchain, which allows to go all the way from HDL code to configuration bitstream. All the schematics and hardware information is openly available at no extra cost.

The Board

The iCEBreaker board features a Lattice iCE40UP5K FPGA with the following integrated components:

  • 5280 PLB’s consisting of one 4-input LUT, carry-chain and one FF each
  • 128 Mbit dual-port BRAM’s
  • 1 MBit single-port BRAM’s
  • 8 DSP’s
  • 1 programmable PLL and 2 on-chip oscillators
  • 2 hard-IP’s for SPI and I2C each
  • 3 hard-IP’s for PWM
  • Up to 32 user IO pins. The IO pins are available as 3 PMOD edge connectors
  • One PMOD module with 3 push-buttons and 5 LEDs is included
  • On-board FTDI FT2232H for easy FPGA configuration and debugging via USB
  • 128 Mbit Winbond QSPI flash, programmable over USB or via a separate SPI pin-header
Overview of the iCEBreaker.

The Toolchain

The remainder of this article will guide through the procedure of setting up the open-source toolchain for the iCEBreaker. No Lattice tools and software will be used, maybe that will be covered another time. In a final step the toolchain will be tested by implementing and loading a simple example design. The OS will be asusmed to be Ubuntu 18.04 for the rest of this article.

Let’s begin by installing the dependencies which are required to build the toolchain. The command below will install the superset of all dependencies which are required for the steps that follow.

$> sudo apt install build-essential clang bison flex libreadline-dev gawk tcl-dev libffi-dev git mercurial graphviz xdot pkg-config python python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev libftdi-dev qt5-default python3-dev libboost-all-dev cmake libeigen3-dev

Next clone the github repository for yosys, the synthesis tool of the toolchain. The latest stable release/tag of yosys is recommended, but instead the latest master branch can also be used.

$> git clone https://github.com/yosyshq/yosys
$> cd yosys
$> git checkout yosys-v0.9
$> make -j(nproc)
$> sudo make install

Continue with the bitstream generation tool icestorm.

git clone https://github.com/cliffordwolf/icestorm
cd icestorm
make -j$(nproc)
sudo make install

Finally we have to choose between the place-and-route tool nextpnr and arachne-pnr. Since arachne-pnr is considered obsolete it’s successor nextpnr should be used. Since I like to play around and compare results between different tools I will install both, but note that only one of the two is required.

$> git clone https://github.com/yosyshq/nextpnr
$> cd nextpnr
$> cmake -DARCH=ice40
$> make -j$(nproc)
$> sudo make install
$> git clone https://github.com/yosyshq/arachne-pnr
$> cd arachne-pnr
$> make -j$(nproc)
$> sudo make install

That concludes the setup of the toolchain. Time for an example, to see if everything works.

The Example

Now that we are all set, let’s try to synthesize a simple example design, run the place-and-route tool and generate a bitstream for the iCEBreaker.

$> yosys -p "synth_ice40 -top icebreaker_top -blif icebreaker_top.blif" src/icebreaker_top.v
$> arachne-pnr -d 5k icebreaker_top.blif -o icebreaker_top.asc
$> icepack icebreaker_top.asc icebreaker_top.bin
$> iceprog icebreaker_top.bin

Aaaand the board is bricked (for the moment)! The iCEBreaker no longer is properly recognized neither by Ubuntu nor my Windows 10 machine. It took me a few moments to understand what had gone wrong, but not close to as long as I feared it would take.
Well, the problem was that no physical constraint file (.pcf) was passed to arachne-pnr. The .pcf file defines which top module port is connected to which physical package pin. Without this information arachne-pnr will choose these pins assignments arbitrarily, like most place-and-route tools do in such a situation. After asking arachne-pnr to output the pin assignments it had chosen (-w option) the problem became very clear.

$> arachne-pnr -d 5k icebreaker_top.blif -o icebreaker_top.asc -w icebreaker_top.asc.pcf
... (some irrelevant output)
$> cat icebreaker_top.asc.pcf 
$> arachne-pnr 0.1+328+0 (git sha1 c40fb22, g++ 7.4.0-1ubuntu1~18.04.1 -O2)
set_io led_o 35

Cross-checking this with the iCEBreaker pinout-sheet or schematic and we can see that pin 35 is actually connected to the external 12 MHz oscillator output. Unfortunately this oscillator also drives the FTDI chip (FT2232) which takes care of the USB connection to the outside world. Driving a dumb blinky LED signal on that pin will wreak havoc on the 12 MHz clock signal and mess with the FTDI chip.
To fix this issue the CRESET jumper on the board must be closed. Setting the CRESET jumper will keep the FPGA in reset. This way no output pin of the FPGA is driven and we have time to replace the bitstream in the SPI flash with one that doesn’t do any harm.

So let’s try again, this time with the correct .pcf file.

$> arachne-pnr -d 5k icebreaker_top.blif -o icebreaker_top.asc -p constr/icebreaker_top.pcf -w icebreaker_top.asc.pcf
... (some irrelevant output)
$> icepack icebreaker_top.asc icebreaker_top.bin
$> iceprog icebreaker_top.bin 
Behold, the iCEBreaker blinking like a boss! Imagine the possibilities…

The example from this article – and hopefully some more advanced stuff in the near future too – will be available on my iCEBreaker github repository.

That’s it for today. See you next time.


References:

  1. https://github.com/icebreaker-fpga/icebreaker
  2. https://github.com/icebreaker-fpga/icebreaker-examples
  3. https://github.com/YosysHQ/yosys
  4. http://www.clifford.at/icestorm/#install

First Steps with the Longan Nano RISC-V Development Board

The Longan Nano is a new contestor in the area of affordable RISC-V development boards. The Longan Nano’s form factor and price puts it up against the Arduino Nano and all other varieties of STM32-based “nano boards”, which can be found abundantly on Ebay and AliExpress.

The Longan Nano features a GigaDevices GD32VF103CBT6 core running at 108 MHz with 32KB SRAM and 128KB flash.
The Longan Nano comes with a small 160×80 pixel LCD glued on top of the board and a practical plastic case. Really no reason to complain for just 5 $. More details in the datasheet.

The first requirement is to install PlatformIO. The command line tools of platformio are sufficient. I will assume the OS as Ubuntu 18.04 in the following.

$> pip3 install platformio 

To get a feeling for the versatility of PlatformIO let’s list the supported boards:

$> python3 -m platformio boards
... (lots of boards)

Now let’s only look at the boards of interest, to see if the Longan Nano is supported at all:

$> python3 -m platformio boards | grep GD32
gd32vf103v-eval     GD32VF103VBT6  108MHz 128KB 32KB GD32VF103V-EVAL
sipeed-longan-nano  GD32VF103CBT6  108MHz 128KB 32KB Sipeed Longan Nano
wio_lite_risc-v     GD32VF103CBT6  108MHz 128KB 32KB Wio Lite RISC-V

Next create a project directory for the Longan Nano and initialize a platformio project:

$> mkdir longan_nano
$> cd longan_nano
$> python3 -m platformio init
$> ls
include  lib  platformio.ini  src  test

Have a look at some information about our platform:

$> python3 -m platformio platform search gd32v
gd32v ~ GigaDevice GD32V
The GigaDevice GD32V device is a 32-bit general-purpose microcontroller based on the RISC-V core with an impressive balance of processing power, reduced power consumption and peripheral set.
Home: http://platformio.org/platforms/gd32v
Frameworks: arduino, gd32vf103-sdk
Packages: framework-gd32vf103-sdk, framework-arduino-gd32v, tool-openocd-gd32v, tool-gd32vflash, toolchain-gd32v

Before a build can be run some minimum viable source code is required. It is sufficient to put an empty main function into the src folder like so:

$> echo 'int main(int argc, char* argv[]) { return 0; }' > ./src/main.c

Now the project can be run for the first time to make platformio install requires packages and other dependency stuff:

$> python3 -m platformio run
Processing sipeed-longan-nano (platform: gd32v; framework: gd32v103f-sdk; board: sipeed-longan-nano)
PlatformManager: Installing gd32v
...
Error: This board doesn't support gd32v103f-sdk framework!

Oops! What’s going on here? The content of platformio.ini is copied from Sipeed’s example page, so why isn’t it working?
Well, as so often human error is the cause of this catastrophe. Fix the framework defined in platformio.ini like so:

 framework = gd32vf103-sdk 

Repeat the failing step from before:

$> python3 -m platformio run
Processing sipeed-longan-nano (platform: gd32v; framework: gd32vf103-sdk; board: sipeed-longan-nano)
...
Building .pio/build/sipeed-longan-nano/firmware.bin
 ================================ [SUCCESS] Took 2.50 seconds ==========================

Success! An empty project has been built, oh the accomplishment! Well at least the toolchain seems to work.
Just for fun the empty program can be uploaded to the Longan Nano board to see that the LED stops blinking (i.e. overwrite the preloaded example design).

To load a program to the Longan Nano it must be properly recognized as a USB device by Ubuntu. This is achieved by pressing and holding down the BOOT button and then pressing the RESET button (while still holding the BOOT button). After the RESET button has been pressed and released the BOOT button can also be released. This is the official way to do it, but may only yield the expected result after several attempts. I could be wrong, but for me it seemed to work quite nicely to unplug the Longan Nano, then hold down the BOOT button and plug the board back in (while still holding the BOOT button).
An unnamed USB device should appear in Linux:

$> lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 28e9:0189  
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Next a USB-serial adapter (3.3V) is required. Check that platformio does recognize the adapter:

$> sudo python3 -m platformio device list
/dev/ttyUSB0
Hardware ID: USB VID:PID=0403:6001 SER=00000000 LOCATION=1-3
Description: FT232R USB UART

OK, one step back, it turns out the upload_protocol = serial part is not what I thought it was and only works with the Arduino framework.

$> sudo python3 -m platformio run --target upload
 Processing sipeed-longan-nano (platform: gd32v; framework: gd32vf103-sdk; board: sipeed-longan-nano)
...
CURRENT: upload_protocol = serial
 Looking for upload port…
 Auto-detected: /dev/ttyUSB0
 Uploading .pio/build/sipeed-longan-nano/firmware.bin
 Failed to init device.
 stm32flash Arduino_STM32_0.9
http://github.com/rogerclarkmelbourne/arduino_stm32
*** [upload] Error 1
 Using Parser : Raw BINARY
 Interface serial_posix: 115200 8E1
================================= [FAILED] Took 1.88 seconds ==========================

So that didn’t work.
The next alternative is to use dfu-util which is easily available via apt:

$> sudo apt install dfu-util

Subsequently change the upload_protocol in platformio.ini:

upload_protocol = dfu

Repeat the upload step from before:

$> sudo python3 -m platformio run --target upload
Processing sipeed-longan-nano (platform: gd32v; framework: gd32vf103-sdk; board: sipeed-longan-nano)
...
Download    [=========================] 100%         6584 bytes
 Download done.
 File downloaded successfully
 dfu-util: dfuse_download: libusb_control_transfer returned -9
 *** [upload] Error 74
================================= [FAILED] Took 2.71 seconds =========================

There is still an error showing at the end, but this one can be ignored (not sure why, but it does work despite of the error). After uploading a new program the Longan Nano has to be reset manually by pressing the RESET button. The Longan Nano should no longer blink it’s RGB LED, but instead remain dark and silent. Yippie?

Since this result is somewhat unsatisfying let’s load the official blinky example to bring the Longan Nano back to light. Get the sources from github (just clone the whole project) and descend into the example directory of interest, then build and upload the longan-nano-blink example.

$> git clone  https://github.com/sipeed/platform-gd32v
$> cd ./platform-gd32v/examples/longan-nano-blink
$> sudo python3 -m platformio run --target upload
 Processing sipeed-longan-nano (platform: gd32v; framework: gd32vf103-sdk; board: sipeed-longan-nano)
...
Download    [=========================] 100%         6584 bytes
 Download done.
 File downloaded successfully
 dfu-util: dfuse_download: libusb_control_transfer returned -9
 *** [upload] Error 74
 ================================= [FAILED] Took 2.91 seconds ==========================

After pressing the RESET button the Longan Nano does start blinking it’s RGB LED again, using only the red color. Success!

Blinking like a real pro: the Longan Nano.

In case at any point the messagedfu-util: No DFU capable USB device available appears this means your host machine dropped the USB device corresponding to the Longan Nano for some reason. Try to connect it again with the BOOT and RESET button combo described above.

And that concludes the first steps with the Longan Nano. See you next time.


References:

  1. https://longan.sipeed.com/en/get_started/blink.html
  2. https://docs.platformio.org/en/latest/core.html
  3. https://docs.platformio.org/en/latest/boards/gd32v/sipeed-longan-nano.html
  4. https://bbs.sipeed.com/t/topic/1338/4
  5. https://github.com/sipeed/platform-gd32v/issues/10
  6. http://dl.sipeed.com/LONGAN/Nano/DOC

Undelete Files with SnapRAID

Today I accidentally deleted a whole folder of important documents on my OpenMediaVault(OMV) NAS, while doing some cleaning up.
Of course I would have a backup of the folder on an external hard-drive, but this was the perfect opportunity to test SnapRAID.

SnapRAID is a software RAID which comes as a plugin for OMV. SnapRAID computes redundancy/parity information for the files stored on multiple data disks. This redundancy/parity must be stored on a separate disk. If one data disk fails, the lost data on that disk can be reconstructed from the redundancy/parity information and the other remaining data disks. SnapRAID is quite flexible and allows any number of data disks and redundancy disks and a lot of options, which I haven’t even looked at to be honest.
The most important difference to other RAID systems is that SnapRAID is an offline RAID. This means SnapRAID will not constantly monitor disks and update the redundancy in real-time. Instead you are required to run SnapRAID manually every couple of days/weeks or schedule a cronjob to periodically update the SnapRAID parity disk.

Enough of that, here is how a deleted file or folder can be restored. The SnapRAID plugin for OMV allows to do this from the web UI, but I ended up using the shell anyway.

To check which files have been removed (or added) since the last parity update:
$&gt; snapraid diff --test-fmt path
or
$&gt; snapraid diff --test-fmt disk

To fix an entire array, i.e. fix everything that is missing:
$&gt; snapraid fix -m
To fix everything on one disk (example disk name “MyDisk2” as assigned during SnapRAID creation):
$&gt; snapraid fix -m -d MyDisk2
To fix a folder with a given name (located on any data disk):
$&gt; snapraid fix -m -f myFolder/
or a file:
$&gt; snapraid fix -m -f myFile
To just check what SnapRAID would do instead of fixing errors right away do:
$&gt; snapraid check -m -f MyFile -v

After a couple of minutes my folder was back where it belonged. Feels good to be prepared for mishaps like that 🙂

References:
https://www.snapraid.it/manual
https://sourceforge.net/p/snapraid/discussion/1677233/thread/a7db07e5/

Getting Started with GHDL

If you haven’t heard of GHDL, it is *the* free open-source VHDL simulator out there.
GHDL stand for “G Hardware Description Language” (the G is without meaning). GHDL is mainly implemented in Ada and can be build with different backends: mcode, LLVM and GCC. The different backends provide different performance levels and vary in build complexity. I recommend LLVM since it performs well and is still quite straight forward to build. Building GHDL from latest sources from its github project is probably the best way to go.

Despite its free nature GHDL provides very good support for all major VHDL-LRM releases: VHDL-1987/1993/200X/2008(partial). Unforunately GHDL is a pure VHDL simulator, so there is no support for Verilog at all. This is understandable as there are already some very good simulators for Verilog out there.

Compiling GHDL

The following guide assumes a Ubuntu 18.04 environment (either a native installation or docker or WSL will do).
Clone the latest GHDL sources or any stable release from github:
$&gt; git clone https://github.com/ghdl/ghdl
Decent into the ghdl working copy and run the configure script with options to use LLVM as backend (–with-llvm-config) and a custom install path (–prefix):
$&gt; cd ghdl
$&gt; ./configure --prefix=/opt/ghdl-llvm --with-llvm-config

Install some dependencies:
$&gt; sudo apt install -y bison flex
Afterwards you can build and install ghdl:
$&gt; make
$&gt; make install

The ghdl main executable is located at /opt/ghdl-llvm/bin/ghdl (the path given to the –prefix option). I usually create a symbolic link to make the ghdl command directly available in the $PATH:
$&gt; ln -s /opt/ghdl-llvm/bin/ghdl /usr/bin/ghdl

That’s it for now. If you are familiar with docker, there is an easy to use docker image for ghdl available on dockerhub.

Anlogic TANG PriMER dev board

Recently I purchased a Sipeed TANG PriMER development board featuring an Anlogic EG4S20 FPGA (codenamed Eagle S20). The only reason I bought the board was to see what Anlogic FPGAs are capable of, since I had never heard of that FPGA vendor before. No need to think twice when the board costs less than 20$.

The TANG PriMER board is officially marketed as a RISC-V development board and comes with a Hummingbird E200 RISC-V softcore design preloaded into the onboard configuration flash. The Hummingbird is basically a slightly modified variation of the SiFive E2 core.
Setting up the tool chain was a bit of a hustle until I found this site which hosts both the TD IDE and the required license files. There are also some datasheets and schematics. Most of the official documentation is only available in Chinese, therefor I strongly recommend the inofficial english translation.

I have not done a lot with this board yet but verify the tool chain with a simple blink LED example. The design included a 32 bit counter which resulted in an estimated maximum frequency of 252 MHz. Not too bad. The TD IDE also comes with an IP wizard to generate IP cores, but it seems to just generate a wrapper for some primitive instantiations. It’s worth mentioning that the EG4S20 has an on-chip oscillator (250 or 266 MHz, documentation and IDE do not agree), on-chip SDRAM (64Mbit) and an 8-channel ADC (1MHz sample rate). Still need to figure out how to configure the board and which programmer can be used.

Since Anlogic FPGAs are not listed on digikey.com or other distributor websites, it seems unlikely they will become widely available outside of China anytime soon.

How to set up NordVPN on Ubuntu

There are two ways to set up a VPN connection with NordVPN on Ubuntu. The first one is to add NordVPN’s package repository to the apt sources and then install the nordvpn client via a simple sudo apt install nordvpn. The second one is to install OpenVPN and configure it to use the servers of NordVPN.
This how-to was written for Ubuntu 18.04 LTS (Bionic Beaver).

NordVPN setup with NordVPN package repository

  1. Download the NordVPN package (.deb) for Ubuntu:
    wget https://repo.nordvpn.com/deb/nordvpn/debian/pool/main/nordvpn-release_1.0.0_all.deb
  2. Install the package on your Ubuntu system:
    sudo dpkg --install ./nordvpn-release_1.0.0_all.deb
    Note that installing this package does only add the NordVPN package repository to apt, no executable is installed.
  3. Install the nordvpn client software:
    sudo apt update
    sudo apt install nordvpn
  4. Connect the nordvpn client (the server is selected automatically):
    nordvpn connect
    The general command to connect has the form:
    nordvpn connect [<country&gt;] [<city&gt;] | [server]
    so to connect to a specific country (and city) the additional arguments must be given:
    nordvpn connect United_Kingdom Manchester
    To get a list of available countries and cities you can query them with:
    nordvpn countries
    nordvpn cities
    It is also possible to give the server name directly:
    nordvpn de442

NordVPN setup with OpenVPN

  1. Install openvpn on your Ubuntu system:
    sudo apt install openvpn
  2. Get the OpenVPN configuration files for NordVPN:
    cd /etc/openvpn
    sudo wget https://downloads.nordcdn.com/configs/archives/servers/ovpn.zip
    sudo unzip ./ovpn.zip
    If an error is encountered during the download step above, it may be necessary to install the ca-certificate package:
    sudo apt-get install ca-certificates
    After unzipping ovpn.zip there will be a folder ovpn_tcp and ovpn_udp which contain the NordVPN server configuration files for OpenVPN.
  3. Connect to OpenVPN using one of the NordVPN servers:
    openvpn /etc/openvpn/ovpn_udp/de442.nordvpn.com.udp.ovpn
    You will need to enter your credentials for NordVPN.
Sources:
https://nordvpn.com/de/download/linux/
https://nordvpn.com/de/tutorials/linux/openvpn/
https://wiki.ubuntuusers.de/NetworkManager/VPN%20Plugins/

Process Control in a Linux Shell

Working on the command line in a Linux shell can be tricky at times. A frequent source of frustration is that tasks which are trivial with a graphical desktop environment can be seemingly much more difficult to achieve on the command line. For example switching between multiple running applications only requires one or two mouse clicks on a graphical desktop, but demands more arcane knowledge to do it on the command line.

The jobs command lists the jobs (processes) running in the current shell session.

The keyboard shortcut [Ctrl+Z] does stop the current job and sends it to the background.

The fg command brings a job back to the foreground and resumes it.

The bg command resumes a job in the background.

The kill command sends a signal to a process. By default this is the SIGTERM signal to terminate the process in an orderly way.

The disown command detaches a job from the shell session. This way a command can continue running even after the shell session terminates.

Clock Enables vs. Multiple Clocks

Introduction

In advanced FPGA systems which require different clock frequencies for different parts of the design, there is often a shortage of global clock buffers. Often several of the clocks are related (see below) and it becomes possible to use a single clock plus several clock enable signals, instead of several dedicated clocks. This article tries to shed some light on the impact these two alternatives can have on an FPGA system.
For the rest of this article, let’s assume all clocks C_i with frequency F_i are derived from the same reference clock C_ref with frequency F_ref and are strongly related, fulfilling the equation F_i = F_ref / D_i. This means that the frequency of a related clock is an integer fraction of the reference clock frequency. In that case things look a little different.
I use the terms strongly/weakly related to differentiate between the two basic ways the relationship of two clocks can be constituted. Weakly related clocks would be those which are linked by the equation F_i = F_ref * M_i / D_i. This means that all weakly related clocks have frequencies which are (possibly non-integer!) fractions of the reference clock frequency.
Note that asynchronous clocks or weakly related clocks have to be treated differently, and that clock enables as described here are not applicable for those.

Main Part

Virtually all FPGAs offer D-flip-flops which have an enable input, also called a clock enable (CE) since it controls the effect a rising or falling clock edge has on the content of the D-flip-flop. If the CE input is deasserted, changes to the D input of the flip-flop are not propagated to the Q output after an active clock edge. Only if the CE is asserted the value on the D input does propagate through to the Q output when an active clock edge arrives.
When N related clocks must be derived from one common reference clock there are two major options:

(1) Instantiate a PLL or DCM (Xilinx FPGA primitive) which uses the reference clock C_ref to generate all required clocks C_i. The reference clock C_ref has to be the clock with the highest frequency (see my constraints and assumptions above). The related clocks are generated by dividing the reference clock by an integer value. If a large number of related clocks are required this can lead to a dead end, because a PLL/DCM has a limit to the number of clocks it can generate (usually somewhere between 4-8).
This limitation could be circumvented by using one of the generated clocks C_i,1 of the first PLL/DCM as a reference clock C_ref,2 for a second PLL/DCM and then in turn use the second PLL/DCM to generate additional related clocks C_i,2. However, this will only work if the phase relationship between the reference clock of a PLL/DCM and the generated clock outputs can be adjusted, e.g. in general it may be required to adjust this phase offset to become 0 (or a value which is an integer multiple of the reference clock with the highest frequency).

Clock generation using one clock buffer per clock

(2) Generate only one clock signal, which has the highest frequency that is required. All other related clocks would be obtained by dividing this reference clock frequency by an integer multiple (as explained in 1) above). However, instead of dividing the reference clock, a clock enable signal CE_i is created, which is only active every D_i-th clock cycle. This clock enable signal serves as an enable for all flip-flops which would be located in the domain of the corresponding related clock C_i. This way a clock enable signal CE_i for each related clock C_i can be created.
So there is only one primary clock signal and all other “clocks” are logically represented by an enable signal which is only asserted every other clock cycle.
The tricky part then is to tell the timing analyzer tool to treat the clock enables correctly, so the place and route tool is aware of the timing requirements. Otherwise the design will be over-constrained, since all clock domains are treated as if they had the same frequency (which would be the maximum frequency). This would result in unnecessarily strict timing requirements for all the logic which would normally run at a lower frequency. Thus timing closure will be more difficult to achieve.

Clock generation with multiple clock enables using a single clock buffer

Summary

The decision to use multiple clocks over a single clock plus clock enables boils down to a resource trade-off.
On the one hand, multiple PLLs/DCMs and multiple (global) clock buffers are used to generate multiple related clocks. This requires more (global) clocking resources, but no additional fabric resources at all. Each clock domain is defined by a physical clock signal.
On the other hand, only one global clock with one global clock buffer is used. The different clock domains are logically defined by means of enable signals which are only asserted every other clock cycle. This approach requires more fabric resources (LUTs, CLBs, FFs) to generate and distribute the enable signal nets which define the various clock domains. On the other hand only a single clock must be generated which saves global clocking resources.
Bingo bango there you have it.

Extracting MPEG2-TS from Wireshark capture file

When working with IP multicast streams it can sometimes be useful to convert a captured IP stream file to a corresponding MPEG2 transport stream (TS) file. Wireshark has a built-in capability to extract MPEG2-TS packets from the UDP packets of an IP multicast stream. This feature is somewhat hidden away in the menus and not obvious to find.

An IP multicast stream

First select a frame of the UDP stream you are interested in by clicking on it. Then navigate the menu bar to “Analyze” &gt; “Follow” &gt; “UDP Stream”.

Follow the UDP stream

A new window will open, showing the contents of the UDP stream in one continuous flow of data. Now select “Show and save data as” &gt; “Raw” and hit “Save as …”.

Extract MPEG2-TS from UDP stream

Give the new file a name and hit “Save”.

It is also possible to filter out specific parts of the UDP stream, but in most cases the “Entire conversation” is what is wanted.

The result: a plain MPEG2-TS

That’s it! All MPEG2-TS packets have been extracted from the UDP stream and are stored to a separate file. The MPEG2-TS file can now be used for other tasks, like error checks or timing analysis.

Page 1 of 2

© bananatronics.org