VHDL Implementation of a Microcoded CPU
(c) 2015 Warren Toomey, GPL3 Licence


1.2, 4 July 2015. Merged some of the code from the Nexys4 version.
1.1, 14 June 2015. Some tidying up done. More testing code needed.
1.0, 13 June 2015. First version. Needs a fair bit of tidying up.

Download this file:


This is a VHDL implementation of my microcoded CPU which was originally written for Logisim. You can find the Logisim version of the CPU and a detailed description of how it works there. This VHDL version is a reasonably faithful implementation of the CPU with a few minor differences which are noted at the end.

Getting GHDL

The VHDL code has been written to work with GHDL in a Linux environment. Here is how you can get GHDL installed on your Ubuntu Linux box.

GHDL is not in the mainstream Ubuntu pakage set, so you need to add a PPA to your Ubuntu system, update your packages and finally install GHDL:

  % sudo add-apt-repository ppa:pgavin/ghdl
  % sudo apt-get update
  % sudo apt-get install ghdl
  % sudo apt-get install build-essential minicom gtkwave

The build_essential package is needed as we will be compiling some C code. The minicom package is needed as we have to connect to the CPU's serial port. The gtkwave package is useful if you want to examine the waveforms of the control and data lines at the end of each CPU simulation.

Running the Microcoded CPU

Assuming that you have unpacked the tarball with the CPU source, you will find a Makefile, a pile of *.vhd files (the CPU source), the full_microcode source to the CPU, a microcode assember uassem, a high-level assembler massem and an example assembly program basic_program.s.

At the shell prompt, run make to build and execute the CPU in GHDL:

  % make
  ghdl -a --ieee=synopsys regfile.vhd		# Build the VHDL source
  gcc -c ghdl_pty.c				# Build the UART code
  ./uassem full_microcode			# Assemble the microcode
  ./massem basic_program.s			# Assemble example program
  ./cpu --vcd=test.vcd				# Simulate the CPU
  Psudoterminal: /dev/pts/9			# This is the tty to use
  <a few warning messages>
  cpu.vhd: ... CPU simulation finished		# CPU stops after a certain
  ./cpu:error: report failed			# number of cycles. This
  ./cpu:error: simulation failed		# is done by aborting the
  make: [runcpu] Error 1 (ignored)		# simulation.

The CPU produces two outputs. One is the file test.vcd which holds the waveforms of the CPU simulation. You can look at the contents of this file with the gtkwave tool:

  % gtkwave test.vcd
You will have to read up on how to use gtkwave!

Using the CPU's Serial Port

The second output from the CPU is through a simulated serial port. When you run the CPU with the make command, and it gets to the ./cpu –vcd=test.vcd command, the cpu executable starts up, opens up a pseudoterminal, tells you which one it is (e.g. /dev/pts/9), waits for two seconds and then runs the assembly program.

In a separate window, run:

  % minicom -p /dev/pts/9

to connect to the /dev/pts/9 pseudoterminal. You have to do this in the two seconds that the program waits, otherwise the pseudoterminal does not exist. Luckily, once minicom connects to the pseudoterminal, it will keep the pseudoterminal open and you can run the CPU (with make) over and over again.

The example program prints out a string, two numbers in decimal, adds the numbers together and prints out the sum. With minicom attached to the CPU's pseudoterminal, you should see this output:

  Here are two numbers followed by their sum: 

Read through web page for the Logisim version of the CPU to understand how the CPU works. Read through the full_microcode and the list_of_instructions files to see the CPU's microcode. Read through the basic_program.s to see an example program for the CPU. If something doesn't make sense, send me some e-mail. My address is at the bottom of this page.

Logisim and VHDL Differences

Here is a list of the main differences between the original Logisim version and this VHDL implementation.

Cheers, Warren Toomey, wkt (at) tuhs (dot) org