element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Summer of FPGA
  • Challenges & Projects
  • Design Challenges
  • Summer of FPGA
  • More
  • Cancel
Summer of FPGA
Blog LiFi #1 - Vivado and Verilog
  • Blog
  • Forum
  • Documents
  • Files
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: kluivertcorreia
  • Date Created: 12 Dec 2021 7:36 AM Date Created
  • Views 5936 views
  • Likes 11 likes
  • Comments 3 comments
  • logic
  • xilinx
  • fpga
  • Digilent Cmod S7
  • vivado
  • lifi
  • experience
  • basic
  • verilog
  • summer of fpga
  • communication
Related
Recommended

LiFi #1 - Vivado and Verilog

kluivertcorreia
kluivertcorreia
12 Dec 2021

Table of Contents

  • Introduction
    • Getting Familiar with the Board (CMOD S7)
    • Design Flow
    • Setting Up Vivado
      • Installing Board Files
      • Basic Overview of the interface
  • Structural HDL
    • Revisiting Gates
    • Pin Mapping
    • Half Adder
    • Half Subtractor
  • Conclusions

Introduction

Greetings Dear Reader,

I have written this blog in response to the "Summer of FPGA" challenge, and being my first blog on the platform I wanted to describe my experience with the Digilent CMOD S7 board before going into making my LiFi project come to life.

This is also my first time using an actual living (not really) breathing (also not really) FPGA. Even though I studied Logic Design using HDL in college I never actually got into hardware implementation. I will be using Verilog as my HDL throughout and discuss a few concepts along the way.

Getting Familiar with the Board (CMOD S7)

FPGA-show

Digilent's CMOD S7 is a development board hosting a Xilinx Spartan 7 (XC7S25-1CSGA225C) FPGA, tighly integrated with the appropriate number of onboard LEDs and buttons while exposing the rest of the IO via the 4x 7 DIP headers. Additionally the, board comes with a PMOD connector, USB port, and a SPI flash.

Interfacing with the board is generally done through USB, interfaced via an onboard FTDI chip (located close to the USB).

The board is comes packaged with a triple output buck power regulator capable of supplying three different voltage levels. The FPGAs clock is run by a 12MHz external crystal oscillator.

I won't go into listing all the features of the FPGA chip here at once, instead I will be referencing them throughout the blog. Nonetheless, the official digilent reference manual can be found here.

Design Flow

Before we get into the Vivado I wanted to give a short introduction of how we "program" the FPGA. Below is a simplified diagram summarizing the design procedure.

Design-flow

  • First we create or include the source files using your HDL of choice.

  • If there is a need to simulate the design then we would have to create a testbench and set it as the simulation top file (this is like the int main() of an HDL project).

  • Otherwise we can simply create the top module which encapsulates all the modules and defines connections between them.

  • Next, we configure the constraints for the design, this includes things like pin mapping, base clock configuration, etc. Using the .xdc file.

  • Synthesize the design into a workable schematic.

  • After synthesis, we must run an implementation which describes the synthesized circuit in terms of the FPGA's resources.

  • We must now write the implementation into a bitstream which is analogous to a hex file that would be sent to a microcontroller.

  • Finally, we program the device.

Xilinx FPGAs implement logic designs using SRAM which is volatile, meaning the device resets on loss of power. These FPGAs utilize LUTs (Look-up tables) which can be thought of as hardware truth tables made up of SRAM cells. The floorplan of the chip consists of cells called CLBs (Configurable Logic blocks) made up of LUTs and connected using interconnection matrices called "magic boxes" which establish connections using transistors as switches.

Setting Up Vivado

Vivado-show

Xilinx provides a free-of-cost version of called the WebPack edition of their Vivado Design Suite. It consists of a comprehensive set of tools required for HDL designs. However it must be noted, that while the installer does support post installation compression it is still a large download and does require a comparatively fast PC.

I initially thought it would be difficult to get used to the GUI however, I couldn't have been further from the truth. From creating a project to navigating the project directory, everything was simple and natural. It took about 10 mins for me to get used to most of the interface and that mostly includes load times. Even including device libraries were easy to follow.

Installing Board Files

Speaking of libraries, while Vivado comes preloaded with board and chip libraries, the CMOD S7 had to be included by me manually. To check whether it is installed:

  1. Open Vivado

  2. Create a project

  3. Add a temporary project name and click next

  4. Choose RTL synthesis (Register Tranfer Logic) and click next

  5. Finally it comes down to selecting the board, click on the boards tab and search for CMOD S7

If it doesn't show up then it must be included manually. Follow the steps below or consult this link:

  1. Clone this GitHub repo

  2. Open the repo directory and navigate to new/board_files and you may either copy all or select the cmod-s7-25 directory

  3. Now paste the folder into ${XILINX}/Vivado/<VERSION_NUMBER>/data/boards/board_files/

Note: the ${XILINX} filepath is different for different operating systems

  1. Once done, restart or open Vivado, and you should see CMOD S7 under the boards section.

    Board-selection

  2. Finally, create a new project by selecting the board, clicking next and Finish.

Basic Overview of the interface

Main-screen

On opening a project file, you would be greeted by the screen above. I have divided the screen into zones that would be referenced later. They are as follows:

  • [Zone 1]: This is the Flow Navigator, it consists of Tabs sectioned for design processes like synthesis, implementation, simulation, etc.

  • [Zone 2]: I shall refer to this zone as Main as it changes depending on the flow stage selected. For eg: if you were to select implementation then it would show you things like device footprint, floorplan, schematic, etc.

  • [Zone 3]: Here we see our Sources panel, where we may add, delete, or assign source HDL files required by the project.

  • [Zone 4]: The Process Indicator can be easily missed at first, its purpose is to provide visual feedback about the running status of a task. In other words, its a loading widget.

  • [Zone 5]: This will be referred to as the Reporter, as it shows things like logs, messages and other similar information. Just like Main it too changes depending on the selected section.

Structural HDL

Essentially There are three design methods in HDL that govern the approach for a problem:

  1. Structural

  2. Dataflow

  3. Behavioral

Structural HDL requires you to describe the logical circuit, this also includes defining interconnection between each stage in the logic circuit. In other words, you must define the structure of the circuit.

Example-for-structural

For example, If we want to create the circuit above, we must define the 3 inputs and 2 outputs, and then separately define each gate connected by wires. We can observe that a' connects gate A to gates C and B, similarly b' connects the output of C to B and D, these "lines" or "nodes" must be defined in HDL as wires.

From this example it is easy to understand why the structural model of HDL alone becomes quite complex, and therefore requires alot of planning in order to execute properly. Tracing issues may also be time consuming.

However, When it comes to describing a logic circuit directly from its structure then structural is chosen. Nonetheless scaling of a design is much more difficult and requires multiple levels of abstraction in order to tame its complexity.

Revisiting Gates

As an introduction to structural HDL I decided to go for the implementation of basic gates.

Since a hybrid of behavioral and structural are necessary for most of our designs, and the use of structural alone is sparse in the practical FPGA development.

Below is the template for the module:

module gen_gate (output out, input x, y);
    and(out, x, y); // <- line one
endmodule

here if we want other gates then we replace line one with:

  1. NOT: not(out, x) remember to remove the other input from the ports list

  2. OR: or(out, x, y)

  3. NAND: nand(out, x, y)

  4. NOR: nor(out, x, y)

  5. XOR: xor(out, x, y)

These gates are a sort of built-in primitives in Verilog and always require the output to be mentioned first.

Pin Mapping

Let's implement these gates in the CMOD shall we!

Let's first open up a Vivado project, and add some sources using the sources panel:

  1. click on the + button

    Add-sources

  2. next, check the Add or create design sources and click next
  3. now click on Create FileCreate-file
  4. make sure Verilog is selected and the file name is same as the module, and click OK
  5. press Finish, and an IO definition box should appear, however we aren't going to be following this wizard, instead we will add these pins via the .xdc file. Therefore press cancel
  6. in order to map the pins to the module, we must first understand the .xdc file of the CMOD S7. XDC files are constraint files that describe what all peripherals the FPGAs pins are connected to. You may find the .xdc for the CMOD S7 from here, keep this saved somewhere on your system, we will be requiring it soon.
  7. observe that the design source 'gen_gate.v' has been added to our design sources. open it up and write the gen_gate module from earlier and save it.
  8. before synthesizing the source we must map the pins. So add the .xdc file you downloaded earlier and add it to your sources using the Add or create constraints options in the wizard similar to how we added the verilog source but for an XDC instead. It should now show up in the Constraints section of the sources panel.
  9. open this file, and you will notice that the pin names are clearly stated after PACKAGE_PINSXDC-view
  10. For our purpose we need to know the pins connected to the 2 onboard buttons and at least 1 LED, so uncomment the required pins by removing the '#' preceding the set_property keyword and replace the label after get_ports with the name of the pin in your module. For example map the x pin of the module to D2: 
    set_property -dict { PACKAGE_PIN D2    IOSTANDARD LVCMOS33 } [get_ports { x }]; #IO_L6P_T0_34 Sch=btn[0]
  11. Do the same for the other buttons and the LED and save. 

    Note: Notice the LCVMOS33 in the .xdc definitions, these indicate the power level. The CMOD S7 comes with a power regulator (LTC3569 triple output buck regulator) capable of supplying 3 voltage levels. These are as follows:

    • 3.3V

    • 1.8V

    • 1.0V

    In the above example LCVMOS33 indicates 3.3V.

    Flow-selection
  12. now comes the time to synthesize and finalize the design, we do this by click on the Run synthesis option in the Flow Navigator (It may ask you to allocate number of threads which varies depending on your CPU).
  13. Once successful, you can open the schematic under the synthesis column to view the schematic in all its glory.Schematic-view
  14. next run implementation by clicking on the Run implementation option in the same Flow Navigator.
  15. you may now view the circuit in the device floorplan, or even check the BGA IO of the FPGA itself!Note: In the device floorplan you may notice the active part of the FPGA fabric being used highlighted in light blue
  16. If all goes well and there aren't any errors then we can move to the penultimate step, that is to generate a bitstream. As told earlier this is the file that will be written to the FPGA. Click on the Generate Bitstream option in the Flow Navigator
  17. Now you can connect the the CMOD S7 to the computer and under PROGRAM DEBUG inside the Open Hardware Manager dropdown click on Open Target > Autoconnect.
  18. Once connected, next click on Program Device and select the board.Program-device-option
  19. And there ya go! your FPGA AND gate is complete.AND-demo

Half Adder

Let's try something a little more complex, again without using any additional hardware and instead relying solely on the board's peripherals.

Just as a refresher, a half adder adds 2 1-bit number and outputs the sum and the carry. It requires 1 AND gate and 1 XOR gate. The truth table and logic circuit is mentioned below:

Half-adder-table

Half-adder-circuit

Directly moving on to the verilog module file, we require:

  1. 2 inputs - bit X and bit Y

  2. 2 outputs - sum and carry

  3. connect X and Y to a XOR gate and call its output sum

  4. connect X and Y to an AND gate and call its output carry

The verilog module will look like so:

module half_adder (input X, Y, output sum, carry);
    xor(sum, X, Y);
    and(carry, X, Y);
endmodule

And that's it! now just map the required pins that is the 2 onboard LEDs and the 2 buttons - synthesize implement and generate the bitstream. Let's write the bitstream to the device.

Half-adder-demo

And the schematic for the same looks something like this:

Half-adder-schematic

Notice the use of two LUTs, one for the AND gate and the other for the XOR gate. You can check the truth table of these LUTs by simply selecting one of them and viewing the truth table section under the Cell Properties within the Main zone.

Half Subtractor

Finally to demonstrate the use of internal wires between the primitive gates, I made a half subtractor. The half subtractor has a similar circuit to the half adder accept one of the input gets negated before the AND gate. Here is the logic circuit and the accompanying truth table:

Half-subtractor-table

Half-subtractor-circuitAs mentioned earlier the circuit has a intermediate stage where the NOT gate comes in between one of the input and the AND gate, What to I do here? How do I map the pins? Well first of all ... Simmer down. We must create an internal wire connecting the NOT output to the input of the AND gate. Remember wires are a type in verilog that can be connected to unlimited inputs but have only one output, this is so that multiple signals don't converge on the same spot. Let's take a look at the verilog module shall we:

module half_subtractor (input X, Y, output diff, borrow);
    wire inter; // this is a wire

    xor(diff, X, Y);
    not (inter, X); // make the wire be the output of the NOT gate
    and(borrow, inter, Y); // make the wire be the input of the AND gate
endmodule

Let's update the constraints file to include diff and borrow and generate the bitstream. This is the resulting schematic and demo:

Half-subtractor-schematic

Half-subtractor-demo

Notice the indifference between the half adder and half subtractor schematic, they both still use the same number of LUTs and pretty route the same way. However, if you check the truth table for the borrow line, you will see that the truth table has changed to accomodate the NOT gate.

Conclusions

So far my experience with the CMOD S7 has been delightful, not only did I get to apply my knowledge in Verilog and DSD (Digital Systems Design), but I got to look into the inner workings of the FPGA fabric of Xilinx chips, this small success has opened up newer possibilities for my LiFi system. I have developed a rough plan on what I should do to get close to that goal, however this may change depending on how my experience with using Microblaze goes.

What's next?

Initially I wanted to include the behavioral model as well and directly transition to using the core IPs provided by Vivado while also simultaneously exploring the Vitis IDE, however, that would have taken a lot more time and would be rather long. So instead I would like to invite you to my upcoming (or already up) blog on the behavioral model of HDL along with a possible introduction to Tcl scripting. Along the way I will also publish a repo containing the necessary example files. So until then I hope to meet you in the next one.

  • Sign in to reply
Parents
  • kluivertcorreia
    kluivertcorreia over 3 years ago

    Took a lot more time to post cuz of e14's blog tools Expressionless...

    But Alas! its up 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • kluivertcorreia
    kluivertcorreia over 3 years ago

    Took a lot more time to post cuz of e14's blog tools Expressionless...

    But Alas! its up 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube