Table of Contents
- Audio Synth #1 - The project
- Audio Synth #2 - Board introduction and IDE setup
- Audio Synth #3 - Arduino to CmodS7 COMM Test
- Audio Synth #4 - Use PWM to control LED
- Audio Synth #5 - Testing the I2S PCM5102 DAC Decoder Board
- Audio Synth #6 - Sound generation with CmodS7
- Audio Synth #7 - Design challenge ends, project continues
===========================================================
Target audience
I am writing this blog specifically for a software engineer who is interested in learning FPGA programming. I admit that what I am offering here is a very personal perspective. As an engineer, I did my share of embedded software and real-time development some time ago (C, VxWorks). I was also fortunate enough to have taken some courses in digital system design and DSP a long time ago so I do have some theoretical knowledge, although I feel that I need to do a lot of brushing up.
Prerequisites
I think others have said it before me time and again but I believe this is so important that I can simply not omit it: FPGA programming is very different from software programming. If you think that learning Verilog will be easy because you already mastered C or some other programming languages, you are in for a big surprise. Previous software programming experience definitely helps because some basic programming constructs and concepts (for loops, if-else, while, etc…, reentrancy, parallel processing/multitasking, etc…) are portable knowledge but that’s about it. Software programming deals with data structures and algorithms, while FPGA programming deals with, well, hardware. The hardware comes first, with data structures and algorithms on top of it. If one doesn't understand what the hardware is and does (gate, flip-flop, mux, demux, etc.), there is no way one will be able to do any FPGA programming. This sentence is applicable to me in the first place! As a software engineer willing to learn how to program FPGAs, this is the most important sentence you can read on this blog.
Books
I am suggesting here a number of books worth studying (or at least selectively but diligently browsing through). Covering digital design, two widely recommended books on various forums are Morris Mano’s “Digital Design” and Frank Vahid’s “Digital Design with RTL Design, VHDL and Verilog.” Cavanagh’s Digital Design book also gets some appreciation by some people. Bhasker’s “Verilog Primer” seems to be a good starting point for learning Verilog. Bhasker has another book on Verilog synthesis which seems useful. There might be other good books, and if you are reading this blog and took a strong liking of such books, please leave a comment so others can benefit from your experience.
Here are some links. I am not an Amazon affiliate. The books are not inexpensive, but some of them are available on https://archive.org/ . I prefer to borrow first and and decide later if I want to buy a certain book.
- https://www.amazon.com/Digital-Design-Introduction-Verilog-SystemVerilog/dp/0134549899/ref=sr_1_1?qid=1639386673&refinements=p_27%3AM.+Morris+Mano&s=books&sr=1-1
- https://www.amazon.com/Digital-Design-RTL-VHDL-Verilog/dp/0470531088
- https://www.amazon.com/Digital-Design-Verilog-HDL-Fundamentals-dp-1420074156/dp/1420074156/ref=as_li_ss_tl?_encoding=UTF8&me=&qid=&linkCode=sl1&tag=irfz-20&linkId=eb3138dad2bf283b9f97d6a0d9c60420
- https://www.amazon.com/Verilog-HDL-Primer-Second/dp/096503917X?asin=096503917X&revisionId=&format=4&depth=1
- https://www.amazon.com/Verilog-HDL-Synthesis-Practical-Primer/dp/0965039153
Since I have some previous knowledge of digital circuitry, my approach was to start with Bhasker’s Verilog primer. I went through the book focusing on examples: whenever I encountered difficulties, I used Mano’s book to look up circuits and concepts I needed to refresh, then went back to Bhasker. I did this for a few days in parallel with setting up Vivado, creating some mock projects and trying to figure out how to use this complex IDE.
Based on your own experience, you might choose a different path.
Here are a few items that, in my opinion, one needs to understand. This is a list which I plan to revisit from time to time as a reflection of my learning experience.
- hardware: number representation (binary, hex, octal), 2’s complement, register, signal, register, gate, flip-flop, shift register, adder, half adder, counter, finite states machine, clock signal, clock phase, combinational logic, sequential logic, communication (synchronous, asynchronous), RTL design. …
- programming: FPGA design flow, simulation, verification, synthesizable design, user defined primitive, module, port, task, function, design models: behavioral, data-flow, structural, …
And now, let’s do some setup work.
Getting to know your board
Here is a highlight from the manufacturer’s website: “The Digilent Cmod S7 is a small, 48-pin DIP form factor board built around a Xilinx Spartan 7 FPGA. 32 FPGA digital I/O signals, 2 FPGA analog input signals, an external power input rail, and ground are routed to 100-mil-spaced through-hole pins, making the Cmod S7 well suited for use with solderless breadboards. At just 0.7” by 3.05” inches, it can be loaded in a standard socket and used in embedded systems. The board also includes a programming ROM, clock source, USB programming and data transfer circuit, power supplies, LEDs, and buttons.”
You can find more info (reference manual, schematic, XDC files, and a number of tutorials and examples) here: https://digilent.com/reference/programmable-logic/cmod-s7/start
I found this site to be very informative, with detailed information, well structured and organized.
Vivado IDE
The IDE used to program Xilinx FPGAs is called Vivado. The IDE is free but you need to create an account on Xilinx’s website to activate the license. I downloaded Vivado ML edition 2021.2 from https://www.xilinx.com/support/download.html
The download took a long time (large file!). The installation was straightforward. You can find installation instructions here: https://digilent.com/reference/programmable-logic/guides/installing-vivado-and-sdk?redirect=1#installing_digilent_board_files Make sure you install support for your board (in my case cmod-s7-25).
Digilent published a getting started guide which I found helpful (especially section 6 “Adding a constraint file”). https://digilent.com/reference/vivado/getting_started/2018.2
I also found a Vivado tutorial. The Introduction page (about the design flow) is worth reading. The example itself is for a different board but it was nonetheless an interesting read for a beginner like myself. https://www.xilinx.com/support/documentation/university/Vivado-Teaching/HDL-Design/2013x/Nexys4/Verilog/docs-pdf/Vivado_tutorial.pdf
Xilinx gathered a lot of info under their Design Hubs: https://www.xilinx.com/support/documentation-navigation/design-hubs.html One can find a lot of info under the Vivado Design Suite section. I often went through the docs listed there when I got stuck due to tools and setup issues.
As a beginner, I found Vivado intimidating at times. It is a complex and powerful IDE, and at least in my case, the learning curve is steep. For the inexperienced, the error and warning messages look cryptic. Most of the time though, I was able to find solutions on the Xilinx or general FPGA forums.
Verilog Blink LED Project
After I set up Vivado, one of the first projects I created was a simple LED blink.
The project has one source file and one constraint file. The source file is set up as the top file.
Here is the source file:
And here is the constraint file:
Digilent did a good job explaining what a constraint file is. https://digilent.com/reference/programmable-logic/guides/vivado-xdc-file?redirect=1
To understand how the LED is mapped out in the example, have a look at the uncommented line corresponding to the red LED in the constraint file (line 17), then have a look at the source file where that name is used. You can then check the schematic and identify the LED under control (you can see why 0 turns the LED on). https://s3-us-west-2.amazonaws.com/digilent/resources/programmable-logic/cmod-s7/Cmod+S7_sch-public.pdf
Github Repository
The project is on github: Summer-of-FPGA/blinkLed at main · a3333333/Summer-of-FPGA (github.com)
You can clone it on your machine and open it with Vivado. Once you open the project with Vivado, you can generate the bitstream file (under the Flow menu). To program the FPGA I used the Hardware Manager following these instructions: https://digilent.com/reference/programmable-logic/guides/vivado-hardware-manager
Key Concepts: top module, constraint file.
Note 1
If you ever tried my github code, you will notice that the red LED light is very bright compared to the pre-programmed test program of the CmodS7 board. The explanation is that my example code applies a solid 0V level (rather foolishly!) on the cathode of the red LED of the RGB SMD module (LD0 VS NRD8 component in the schematic) while the pre-programmed example from Digilent uses PWM, which is the way to control the intensity of a LED. Feeling a bit concerned, I measured all LD0’s anodes : pin 4(B), 5(R) and 6(G). As expected, 4 and 6 measured close to 3V3, while 5 showed about 1.9V which means about 1.4V are to be found across the 182ohm resistor, which translates into little under 8mA going through the LED. According to Xilinx DS 189 (table 2 on page 3), the maximum current through any pin in a bank is 10mA, which is pretty close to the current I am forcing through the LED. Note 8 on the same page states that “a total of 200 mA per bank should not be exceeded”. So, in conclusion, my code will not damage the FPGA, however I think I should re-write the project and use PWM to control LEDs from now on.
Here is the schematic again: https://s3-us-west-2.amazonaws.com/digilent/resources/programmable-logic/cmod-s7/Cmod+S7_sch-public.pdf
Here is Xilinx DS189: https://www.xilinx.com/support/documentation/data_sheets/ds189-spartan-7-data-sheet.pdf
And here is how a LED should be controlled using PWM:
https://github.com/Digilent/Cmod-S7-25-OOB/blob/master/src/hdl/top.v
https://github.com/Digilent/Cmod-S7-25-OOB/blob/master/src/hdl/pwm.v
Change Log:
- 01/08/2022 - added Note 1