Professional Documents
Culture Documents
an FPGA
In this article, we will learn how to capture our very own universal asynchronous
receiver/transmitter design using MyHDL, a free, open-source Python library.
By André Castelan Prado
Editor
Embarcados
Embedded systems engineers are quite familiar to the universal asynchronous receiver/transmitter. It's probably
the first communications protocol that we learn in college. In this article, we will design our very own UART using
MyHDL.
MyHDL is a free, open-source Python library developed by Jan Decaluwe. Its goal is to be a powerful hardware
description language. The idea is to apply the new concepts that have appeared in the software industry to
hardware design, such as test-driven development, functional tests, and high-level abstraction. The system also
generates synthesisable VHDL and Verilog code from the MyHDL design. The idea is to verify everything in Python
and then press the "Go" button to generate a VHDL or Verilog representation that can be synthesised and loaded
into an FPGA.
The @always_seq is a MyHDL decorator. It's analogous to a VHDL process or a Verilog @always. There are several
decorators in MyHDL; this one creates a synchronous process with a clock and a reset. The .next is a function that
indicates that the value is going to be updated in the next delta cycle, which is again analogous to processes in VHDL
and Verilog. It's necessary to return our decorators at the end of the process.
>python tb_serial.py
This will cause a bench.vcd to be created. Let's open this file using the free, open-source gtkwave tool as follows:
>gtkwave bench.vd
Test automation
One advantage of MyHDL is the ability to automate our tests. We no longer have to spend countless hours staring at
waveforms to see if everything is working as expected.
For example, suppose that, in order to verify that everything is working as expected, we wait for the rx_rdy posedge
and then check (cheque for banks) to see if the data we transmitted is the same as the data we received. In order to
do this, add these two lines after the line start.next = 0; and don't forget to keep the indentation, because Python is
indentation based.
>py.test tb_serial.py
And Voilá! As we see, MyHDL automatically checks that the transmitted and received data are identical following
the rising edge of the rx_rdy signal.
If we wanted to generate Verilog, all we would have to do would be replace the calls to the toVHDL() function with
the toVerilog() equivalent.
Generally speaking, the resulting VHDL/Verilog is very legible and well structured. Of course, since the generated
output is basically a translation of your RTL in Python, any bad Python will result in equally bad VHDL/Verilog. As
an example, let's look at our generated serial_tx.vhd as shown below:
I used the Gold Reference Design that comes with this board as my base, and then I instantiated my three
components. The start of the TX module is connected to KEY[0]; the top-level RX is connected to my receive_i; and
the top-level TX is connected to my transmit_o.
The data_i from serial_tx is connected to the data_o from serial_rx. With this, we are performing an echo with the
computer.
And it works! I used the Hyper Terminal software and configured it as 115,200, 8 data bits, no parity, and two stop
bits (115200-8-n-2). Everything that you type comes right back to you.
The start_i from serial_tx is connected to a key that is not registered and has no debouncing, which means that, even
if you only press it once, it's going to trigger a lot of starts.
Conclusion
With this project, we were able to take a quick look at MyHDL. As we see, it works very well, generating a good
VHDL representation that works in our FPGA. The development cycle is much faster with Python, since you have
more tools at your disposal to check if your design is working as intended. It's possible to have tons of asserts and to
test your full project with a simple:
Using this approach means that you can always recheck your whole design very efficiently after making small
changes.
This UART project is very simple and intended only to show a true working MyHDL project, so please don't try to
build a chip out of this. Also, we took only an introductory look at MyHDL. Jan explains it much better than me at his
MyHDL.org website; also, you'll find a lot of examples at myHDL.org/examples.
Last but not least, this entire project, including the generated files, is available at GitHub. Thank you for taking the
time to read this; I would very much appreciate any comments or questions.
This article first appeared in Portuguese on the Embarcados.com.br ("Embedded") website in Brazil.