Reader small image

You're reading from  FPGA Programming for Beginners

Product typeBook
Published inMar 2021
Reading LevelIntermediate
PublisherPackt
ISBN-139781789805413
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Frank Bruno
Frank Bruno
author image
Frank Bruno

Frank Bruno is an experienced high-performance design engineer specializing in FPGAs with some ASIC experience. He has experience working for companies like SpaceX, GM Cruise, Belvedere Trading, Allston Trading, and Number Nine. He is currently working as an FPGA engineer for Belvedere Trading.
Read more about Frank Bruno

Right arrow

Chapter 11: Advanced Topics

Over the course of the book, you've had the opportunity to try your hand at a few different projects. To get you started quickly, we limited some of the syntax. This chapter will introduce a few new constructs you may find useful for synthesis and verification. I'll also introduce some things to watch out for.

By the end of this chapter, you'll have been exposed to almost all the useful SystemVerilog constructs for designing and testing FPGAs.

In this chapter, we are going to cover the following main topics:

  • Exploring more advanced SystemVerilog constructs
  • Exploring some more advanced verification constructs
  • Other gotchas and how to avoid them

Technical requirements

The technical requirements for this chapter are the same as those for Chapter 1, Introduction to FPGA Architectures and Xilinx Vivado.

To follow along with the examples and the project, you can find the code files for this chapter at the following repository on GitHub: https://github.com/PacktPublishing/Learn-FPGA-Programming/tree/master/CH11.

Exploring more advanced SystemVerilog constructs

We've used many basic constructs in our designs. The syntax we've used is enough to construct anything you would like to design. There are some other design constructs that can be useful, so I'd like to at least introduce them with an example of how to use them. The most useful construct is the interface.

Interfacing components using the interface construct

SystemVerilog interfaces can be thought of as modules that straddle other modules. An interface in its simplest form is a bundle of wires, very much like a structure. However, unlike a structure, the direction of each individual signal is independent, meaning that you can have both inputs and outputs defined within the interface.

I've created a project to show ps2_host implemented using an interface: https://github.com/PacktPublishing/Learn-FPGA-Programming/blob/master/CH11/build/ps2_host/ps2_host.xpr

Interfaces also have the added advantage that you...

Exploring some more advanced verification constructs

The testing we have done thus far has been pretty simple, even when we used self-checking. There is one construct that I have found very useful over the years. The queue is easy to use and understand.

Introducing SystemVerilog queues

Often, you need to generate an input in a design that will produce an expected output some time later. Examples of this are parsing engines, data processing engines, and, as we saw in Chapter 9, A Better Way to Display – VGA, the PS/2 interface.

When I modified the ps2_host module, I decided to upgrade the testbench for it using queues. I had to create a structure to define what I wanted to store in the queue:

typedef struct packed
  {
   logic [7:0] data;
   logic       parity;
  } ps2_rx_data_t;

This structure will store our expected data as we generate data in the ps2_host for testing.

A queue...

Other gotchas and how to avoid them

As we near the end of our journey, there are a few more things that we should look at, along with how we can detect them or avoid them all together.

Inferring single bit wires

From the advent of Verilog, it has always been legal to use a wire without defining it. This can happen if it is a port on an instantiate module. There is an example project: https://github.com/PacktPublishing/Learn-FPGA-Programming/blob/master/CH11/build/inferred_wire/inferred_wire.xpr.

You can see that I've created a variable-width adder module and connected three of them up:

adder #(4) u_add0 (.in0(SW[3:0]),  .in1(SW[7:4]),   
                   .out(add0_out));
adder #(4) u_add1 (.in0(SW[11:8]), .in1(SW[15:12]), 
                   .out(add1_out...

Summary

In this chapter, we've looked at some more advanced and lesser used SystemVerilog constructs. The main one is interfaces, which allow better design reuse and encapsulation. We've investigated some more advanced looping, structures, and labels.

We've also looked at some more advanced verification constructs. These will help you as your designs grow and get more complex.

Finally, we looked at some gotchas, how to avoid them, and some basics of timing closure.

You've now completed the book and should be able to tackle some tasks on your own. As I mentioned at the beginning, there are many community efforts, such as the Mister Project, that could use some people with FPGA knowledge. There are also projects you can try to tackle on your own to land a job. Whatever you choose, I hope that you find it as fun and rewarding as I do.

Questions

  1. Interfaces are useful for:

    a) Encapsulating signals belonging together

    b) Encapsulating functions, tasks, and assertions associated with the interface

    c) Changing a design deeply embedded within other designs

    d) All of the above

  2. Structures can be assigned by:

    a) Component

    b) Name

    c) Interface

    d) (a) and (b)

  3. Block labels allow easier matching of begin…end blocks.

    a) True

    b) False

  4. If we want to exit a loop, we can use:

    a) break on any loop

    b) disable on any loop label

    c) break on an outer loop or disable on any loop label

  5. Continue can be used to skip the rest of a loop.

    a) True

    b) False

  6. Queues are useful for:

    a) Creating a flexible FIFO for use in verification

    b) Creating a flexible FIFO for use in design and verification

    c) Nothing

  7. The following code snippet does what?
    initial begin
      if (NUM_SEGMENTS != 4 || NUM_SEGMENTS != 8)
        $fatal("This design only supports 4 or 8 segments");
      end
    end

    a) Causes a fatal...

Further reading

For more information about what was covered in the chapter, please refer to the following:

Why subscribe?

  • Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
  • Improve your learning with Skill Plans built especially for you
  • Get a free eBook or video every month
  • Fully searchable for easy access to vital information
  • Copy and paste, print, and bookmark content

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at customercare@packtpub.com for more details.

At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
FPGA Programming for Beginners
Published in: Mar 2021Publisher: PacktISBN-13: 9781789805413
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Frank Bruno

Frank Bruno is an experienced high-performance design engineer specializing in FPGAs with some ASIC experience. He has experience working for companies like SpaceX, GM Cruise, Belvedere Trading, Allston Trading, and Number Nine. He is currently working as an FPGA engineer for Belvedere Trading.
Read more about Frank Bruno