VHDL with gschem and gnetlist

VHDL with gschem and gnetlist
Design a FPGA using open source

Click on the links to toggle the visability of the item.

  1. Introduction
    VHDL or Verilog is a great way to design the internals of a FPGA or CLPD. You can use all your software skills to design hardware.
    But there is a gotcha. The end result is not a software program but hardware. Although obvious it's often overlooked once the project is getting shape.
    As with many good design work-flows there should be some VHDL coding guidelines to ensure a good working end result.
    Here I will present you two VHDL coding guidelines that should be in every list:
    1. Design your architecture
    2. If you can't draw it you can't code it

    Especially the last one is often #forgotten". 
    Using the vendor independent gEDA's gschem we can follow these coding guidelines perfectly.
    Whether you design top-down or bottom-up you can use gEDA to keep your architecture consisted.

    This tutorial uses the bottom-up approach, mainly because it will give us intermediate results we can check and verify.


  2. First things first (setup)
    We need to set-up some essential parameters.
    Frst we create a new working directory
    cd /pathtowork
    mkdir work
    cd work
    Add a text file gafrc into that directory.
    Open the file gafrc and add:
    (source-library "/pathtowork/work")
    (component-library "/pathtowork/work")
    (component-library "/pathtoVHDLlibrary")
    In my installation the /pathtoVHDLlibrary is /usr/share/gEDA/sym/vhdl. Your system may be different.
    Thats all the setup needed.
  3. Do not get confused
    We will be using some symbols from the VHDL library of the gEDA 1.8.1 release. Some symbols have visual aspects that might confuse you.
    For example:
    the ipad-1.sym symbol has all the necessary attributes correctly defined, however it has also an unused attribute (pintype=OUT) with its visibility turned on. And this unused attribute will show-up in your schematics making you think it's an output pin instead of an input pin which it is.
    1.8.1 original ipad symbol  How to fix this

    Goto the directory where your VHDL library is located.
    Open the file "ipad-1.sym" with gschem. Double click on "OUT" and deselect the visible option.
    Single Attribute Editor  
    Save the file. Make sure you have write permission to the VHDL library location.
    In my installation the VHDL library is located at /usr/share/gEDA/sym/vhdl your system may be different.
    End of the fix. Lets continue!

  4. First schematic
    In the directory /pathtowork/work create a file vlinder.sch.
    Open vlinder.sch with gschem.
    Now we can start adding components from the VHDL library.
    vlinder with nand
    Give each component a unique refdes.
    Now for the connection to the outside world.
    We need to add IO pins to our design in order to get these pins in the ENTITY section of our VHDL file.
    The gnetlist VHDL back-end must be able to distinguish between pins used for interconnection within the schematics and a connection which will end-up in the ENTITY declaration of the VHDL file.
    So for the top level exit or entry points in your schematic you need to use the ipad-1.sym, opad-1.sym or iopad-1.sym symbols.
    More details
    Actually the gnetlist VHDL back-end will look at any symbol that has the device=OPAD, device=IPAD or device=IOPAD attributes and treat them as top level exit or entry points.

    Add the ipad and opad symbols.
    I have used Ai, Bi and Qo as refdes for the PAD symbols.
    Using number is optional as long as the refdes is unique.
    vlinder with nand
    I have also given some nets a netname.
    vlinder with nand
    Next we need to add an attribute module-name to the schematic to define the architecture (don't confuse module-name with model-name that's something different!).
    Make sure you have nothing selected, then type A A or goto Add->Attribute in the menu.
    For name type  module-name
    vlinder add attribute
    As value type the name to define the architecture.
    vlinder with attribute
    Now we are ready to generate some VHDL code.
    On the command line type:
    cd /pathtowork/work
    gnetlist -g vhdl -o vlinder.vhdl vlinder.sch
    Check the VHDL code to see where all the attributes end-up

  5. Make a symbol from the first schematic
    In the directory /pathtowork/work create a file vlindersym.sym.
    Open vlindersym.sym with gschem.
    vlinder symbol
    Add 3 pins to represent the three ports in the vlinder design.
    vlinder symbol pins
    Make sure you use correct pintypes (IN, OUT or INOUT).
    vlinder add pin 1vlinder add pin 2vlinder add pin 3
    The value you use for pinnumber will show-up in the COMPONENT declaration in the VHDL file.
    The value used for the pinnumbers MUST be the same as the refdes of the IO pads (ipad, opad, iopad) used in vlinder.sch schematic!
    The pinlabel must be the same as the pinnumber if you want to use the last trick mentioned in this tutorial.

    Next add a refdes attribute, make sure you have nothing selected, then type A A or goto Add->Attribute in the menu.
    vlinder add refdes
    Next add a device attribute, make sure you have nothing selected, then type A A or goto Add->Attribute in the menu.
    vlinder add device
    The device attribute must be the same as the module-name used in the schematic.

    Now you should have:
    vlinder symbol with attributes
    Finally you can add some decoration.
    vlinder symbol with decoration
    Last but not least. Do a symbol translate to realign the symbol correctly.
    Make sure you have nothing selected and grid is set to 100, then type E T or goto Edit->Symbol Translate... in the menu.
    Make sure it says 0 and press enter or click on OK.
    Save the new symbol.
  6. Second schematic
    Steps in this section are more or less a repetition of the steps we took in creating our first schematic, so I will move a little faster.
    In the directory /pathtowork/work create a new file bloem.sch. Open bloem.sch with gschem.
    Add the necessary items as explained above.
    bloem scematic
    Next we can add our vlindersym symbol.    (Can't find the vlindersym.sym symbol?)
    Did you save the vlindersym.sym file in your work directory?
    If you can't find the vlindersym.sym symbol in your work library, you need to save bloem.sch and close gschem. Than open the gafrc file in your /pathtowork/work directory and add:
    (source-library "/pathtowork/work") If you didn't do so already.
    Save and close the rafrc file.
    Reopen bloem.sch and try again.

    bloem scematic with block
    Don't forget to add the module-name attribute!
    Now we are ready to generate the second VHDL code.
    On the command line type:
    gnetlist -g vhdl -o bloem.vhdl bloem.sch

  7. Supporting file
    Now we should have 2 VHDL files (bloem.vhdl and vlinder.vhdl). Together these files will make the skeleton of our VHDL project.
    To make it do anything we need 1 more file. That file must contain the entity for nand2
    The device attribute in nand2-1.sym is set to nand2 (device=nand2) we must match that name exactly.
    So we create a new file named zon.vhdl and insert:
    -- Context clause
    library IEEE;
    use IEEE.Std_Logic_1164.all;
    -- Entity declaration
    ENTITY nand2 IS
        PORT (
          IN1 : in Std_Logic;
          IN0 : in Std_Logic;
          OUT0 : out Std_Logic);
    END nand2;
    -- Secondary unit
    ARCHITECTURE nand2_arch OF nand2 IS
    -- Signal assignment part
        OUT0 <= IN1 NAND IN0;
    END nand2_arch;
  8. Check
    Let's check if all works as expected. For this I use GHDL. If anyone can suggest alternatives, I will append them here.
    First we analyse the files we created:
    ghdl -a bloem.vdhl vlinder.vhdl zon.vhdlNext we can create an executable: ghdl -e bloem_entityIt should compile without errors.
    You can run the bloem_entity executable but it will not do anything.
  9. Last trick to explain
    There is one more trick to explain. Until now we have three files each generated individually by gnetlist.
    Personally that is my favourite way to implement VHDL code. Each sheet or schematic has it's own corresponding VHDL file.
    However you can eliminate one step from the process.
    First delete bloem.vhdl and vlinder.vhdl from your work directory.
    Next open bloem.sch and select the vlindersym symbol.
    bloem scematic symbol selected
    Double click on the vlindersym symbol (BLOCK1).
    In the attribute menu add a new attribute source=vlinder.sch
    add attribute to symbol
    Save bloem.sch.
    On the command line type:
    gnetlist -g vhdl -o bloem.vhdl bloem.schNow gnetlist has put everything in one VHDL file (except the nand2.vhdl deceleration).
    Check your VHDL file to see the difference.
  10. Check
    Let's check if all works as expected.
    First we analyse the files we created in step 7:
    ghdl -a bloem.vdhl zon.vhdlUnfortunately we get an error.bloem.vhdl:26:18: ',' or ':' is expected after identifier in signal declaration
    ghdl: compilation error
    Looking at line 26 column 18 we see that gnetlist has used a / as a separator character when it uses the refdes of the vlindersym symbol as a prefix of the signals used in the vlinder.sch schematic.
    In order to fix that we need to reconfigure gnetlist.
    Add a text file gnetlistrc into your work directory.
    Open the file gnetlistrc and add:
    (hierarchy-uref-separator "_")
    (hierarchy-netname-separator "_")
    More on how to configure gnetlist
    Generate bloem.vhdl again
    gnetlist -g vhdl -o bloem.vhdl bloem.schAnalyse again
    ghdl -a bloem.vdhl zon.vhdlNo errors? Now we can create an executable:ghdl -e bloem_entityIt should compile without errors.
  11. What's next
    Next step is to create a test bench to get an actual output. But I will leave that to you.

Version used in this tutorial:  gEDA 1.8.1
Comments are welcome.