Session 1: Introduction & Development Pipeline

Assignments
- Install the course toolchain (Docker container)
- Run a "hello world" synthesis
- Verify your tools work before Thursday!
Documentation Setup
This was the easy step. I’ve worked with GitLab and MkDocs before, so I had no problem getting that working.
I started by cloning the repository to my local computer. I added .venv/ to the .gitignore file since I’m using a virtual environment to build the site locally and I don’t want to push the .venv directory to the server.
To begin with, I’m documenting on my local computer. I’ll later decide if it makes sense to document inside the provided container instead.

I like to document in markdown and as a text editor I use Neovim, where I can also build the site locally. I also like to use Marktext to do my spell checking and I can see the images and the render as well.
Container Setup

Browser VNC
I started by logging into the microservices site and launching the container. I first opened the Browser VNC, and as expected, it worked flawlessly. I explored the terminal a bit and everything looked fine.

Local VNC
I wanted the option to use a local VNC client, which is something I don’t usually work with.
I had heard of RustDesk and thought it looked like a nice tool, but I quickly discovered that it does not support VNC it uses its own protocol.
I then tried Remmina. It looked modern and nice, but I experienced slight latency enough to make me try something else.
TigerVNC was mentioned in the documentation and during the presentation, so I decided to give it a try. It looks a bit more minimal and rough, but it worked very well with no noticeable latency. I’ll stick with that for now.

The Examples
This is where things became less familiar.
So far, assembly and machine code have been the lowest-level abstractions I've been aware of. I only learned about Verilog a few months ago. As I understand it, Verilog is used to describe and design digital hardware (like a microprocessor), while assembly is used to program and control a processor after it has been implemented.
Fortune
I navigated to the example directory and ran:
At first, I didn’t fully understand what was happening, but when I looked at the terminal output, I realized the fortune message was being generated by the simulation itself, not by a regular program, but by simulated hardware behavior.

GTKWave
Next, I ran the GTKWave command to inspect the waveform. I initially got an error because I used the wrong file path. I had to change it to gtkwave fortune_teller_tb.vcd. After correcting it, the software opened successfully.
At first, I didn’t see any wave forms displayed. I realized I needed to append signals to the waveform viewer. To do that I simply selected a signal in the bottom left box and pressed append. I also found out double clicking the signal does the same.
In the SST box (middle left) I saw fortune_teller_tb, dut, debounce_inst and uart_inst that had different signals types.
The most interesting signals to observe were:
btnrom_addrcurrent_char

When zooming out, I could clearly see two separate transmission bursts corresponding to the two button presses.
When zooming in, I discovered that current_char matched the ASCII characters stored in the ROM. I could literally see the message streaming out character by character.

zoom in on the first burst

zoom in on the second burst
At that point, I opened fortune_teller.v and could see the connection between:
- The ROM initialization
- The character indexing
- The ROM address increment
Seeing the relationship between the Verilog code, the ROM contents, and the waveform output made the system much clearer. Making this connection was a nice moment.

To change the data format you simply had to right click on the signal to pick from various formats for the char it made sense to pick ASCII.
Rest of the samples
I decided to run the rest of the samples to for good measure and get a better understanding of the workflow. When I was about to run the dice sample I thought to have a look at the Make file and realized there was a option to run make sim-all

That worked as expected and here is the output from the terminal:
/foss/examples > make sim-all
iverilog -Wall -g2012 -Ilib -o fortune_teller/fortune_teller.vvp fortune_teller/fortune_teller.v fortune_teller/fortune_teller_tb.v lib/debounce.v lib/uart_tx.v
vvp fortune_teller/fortune_teller.vvp
VCD info: dumpfile fortune_teller_tb.vcd opened for output.
Pressing button...
Cannot predict.
Pressing button again...
Yes definitely!
Test complete
fortune_teller/fortune_teller_tb.v:221: $finish called at 51055000000 (1ps)
iverilog -Wall -g2012 -Ilib -o pocket_synth/pocket_synth.vvp pocket_synth/pocket_synth.v pocket_synth/pocket_synth_tb.v lib/debounce.v
vvp pocket_synth/pocket_synth.vvp
VCD info: dumpfile pocket_synth_tb.vcd opened for output.
Playing C...
Measured: 262.1 Hz (expected ~262 Hz)
Playing E...
Measured: 330.0 Hz (expected ~330 Hz)
Playing G...
Measured: 392.2 Hz (expected ~392 Hz)
Playing B...
Measured: 494.1 Hz (expected ~494 Hz)
Playing C+G (should hear C due to priority)...
Measured: 262.1 Hz (expected ~262 Hz)
Test complete!
pocket_synth/pocket_synth_tb.v:185: $finish called at 54020000000 (1ps)
iverilog -Wall -g2012 -Ilib -o dice_roller/dice_roller.vvp dice_roller/dice_roller.v dice_roller/dice_roller_tb.v lib/debounce.v lib/uart_tx.v
vvp dice_roller/dice_roller.vvp
VCD info: dumpfile dice_roller_tb.vcd opened for output.
Rolling dice 5 times...
(Each roll takes ~0.5 seconds for the animation)
Roll #1:
Rolled: 1
Rolled: 1
Roll #2:
Rolled: 5
Rolled: 5
Roll #3:
Rolled: 3
Rolled: 3
Roll #4:
Rolled: 1
Rolled: 1
Roll #5:
Rolled: 5
Rolled: 5
Test complete!
dice_roller/dice_roller_tb.v:201: $finish called at 2825060000000 (1ps)
iverilog -Wall -g2012 -Ilib -o morse_beacon/morse_beacon.vvp morse_beacon/morse_beacon.v morse_beacon/morse_beacon_tb.v lib/debounce.v
vvp morse_beacon/morse_beacon.vvp
VCD info: dumpfile morse_beacon_tb.vcd opened for output.
===========================================
Morse Beacon Testbench
===========================================
Message: HELLO
Expected Morse: .... . .-.. .-.. ---
Watching for LED on/off transitions...
(At 10 MHz sim clock, 1 unit = 100ms = 1,000,000 cycles)
Pressing color button...
[700242750000] LEDs ON (color: G=00 R=7f B=80)
===========================================
Test complete!
Frames captured: 2559
===========================================
morse_beacon/morse_beacon_tb.v:205: $finish called at 720030000000 (1ps)
All simulations complete.
GTKWave
I now had new .vcd files for the samples that I could look at again in GTKWave. I used gtkwave <name of the file>.vcdto launch GTKWave. below are overview screenshots of each sample.
In the SST box I figured I could right click and append multiple signals for the dice it was 71 a warning window popped up asking if I was sure about this so I just went YOLO mode and all signals appeared there. It might save some time down the road.
Dice

I zoomed to fit but could not make sense of where the dice roll it self was happening but I could see a pastern of five and decided to move to the next one.
Morse

For the morse code sample I figured it works to hold shift to select multiple signals to append them and Ctrl+7 moves one page left and Ctrl+8 moves one page right when zoomed in.
Synth

The last one pocket synth I saw it had five tones and there was a pattern of five in the waveforms. Now it was time to move to the design directory and see if I can put thing together.
"hello world" synthesis
I moved to the foss/design directory and make a directory called hello world I first made helloworld.v file but nothing happened and I figured I need a helloworld_tb.v as well. I typed iverilog -g2012 -o sim.vvp helloworld.v helloworld_tb.v

And there is was Hello from Verilog!
verilog code: helloworld.v helloworld_tb.v
"hello blink" synthesis
Next I wanted to try a LED blink synthesis I found a code to work with and named it blink_led.v and blink_led_tb.v . I then ran iverilog -g2012 -o sim.vvp blink_led.v blink_led_tb.v

I did't see mutch this time like I did in the hello world code. I saw a .vcd file there that I tryed opening in GTKWave.

Looking at the waveform it looked like the LED was not not being toggled so something seams not to be working and at this point I need to get more familiar with verilog code to solve it.
verilog code: blink_led.v blink_led_tb.v
Reflection
This session helped me understand the difference between describing hardware (Verilog) and programming hardware (assembly).
Seeing the ROM contents reflected directly in the waveform viewer was particularly helpful. It made the abstraction layers feel more concrete.
Although the environment initially felt unfamiliar, inspecting the waveform step by step clarified how the system operates.
Things I would like to try and do but ran out of time
These are thing I did't have time to do and might come back to later if I find time.
- Learn more about Docker and run it localy
- Try logic gates verilog exsaples
- Tweek the documentation page
- Index page
- about page
Good resources
Verilog Quick reference guides by EWskills
Fundamentals of Verilog by EWskills 78 problems
Turing Complete great game on steam my progress
"Turing Complete is a game about computer science. If you enjoy the thrill of figuring things out and those moments where a deeper perspective is revealed about something you thought you understood, this game is for you."
5036A
This is what I used to lean assembly when I was in school I later got one my self and use it sometimes for fun.
computinghistory.org.uk/det/43297/HP-5036A-Microprocessor-Lab/

