TopLevelHardware.cs

This is the very top level of our hardware, and it will interact with the software. All of the properties and methods of the RapidHardware class will be available.

Code

using System;
using System.Collections.Generic;
using System.Text;
using RapidHDL;


namespace SimpleCounter
{
    class ToplevelHardware : PadFrame 
    {
        public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = true;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 1;
            Settings.UseSDRAM = false;
            Settings.UseReset = true;
            Settings.SynthASIC = false;
            Settings.SimulateVerilog = true;
            Settings.ForceBuildHardware = false;
            Settings.BuildRemote = false;
            //Settings.BuildServerPath = "desktop:8080";
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            // create an instance of the upcounter object
            // Parameter 1 -> This is a child of the TopLevelComponent, passed into this function
            // Parameter 2 -> name this component as "counter"
            // Parameter 3 -> connect the Main Clock from the toplevel component
            // Parameter 4 -> count to 27
            // Parameter 5 -> count on the rising edge of the clock
            // Parameter 6 -> create an enable signal to control this counter
            // Parameter 7 -> reset this counter to 0
            // Parameter 8 -> count up by 1
            UpCounter oUpCounter = new UpCounter(TopLevelComponent, "counter", 
                TopLevelComponent.MainClock, 5, true, true, 1, 27, 1);
            

            // create a signal named "I_ENABLE" that we can control from software
            // it is connected to the "EnableIn" field of the up counter
            // it is 1 bit wide
            SystemInterface.AddSignalSource("I_ENABLE", oUpCounter.EnableIn, "1");

            // connect the upcounter's reset connection to the MainReset signal of our top component
            oUpCounter.ResetIn.Connection = TopLevelComponent.MainReset;

            AssignPinCLK(39);
            AssignPinGND(40);
            AssignPinVDD(20);
            AssignPinInput("I_ENABLE", 37);
            //AssignPinInput("I_RESET", 38);

            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            // read the output of the counter in our software
            SystemInterface.AddSignalView("O_COUNT", "counter.COUNT_O");
            // specify the format of the output signal that we want to view
            SystemInterface.FormatSignalView("O_COUNT", SignalFormat.Unsigned);
            AssignPinOutput("O_COUNT", 31);

            return true;
        }

        public override bool GenerateHardwareScripts()
        {
            HardwareScript oScript = HardwareScripts.NewScript("test");            
            //oScript.SignalCheck(4,"O_COUNT","00001");
            oScript.SignalView(0, "O_COUNT");
            oScript.SignalCheck(0, "O_COUNT", "1");
            oScript.SignalView(1, "O_COUNT");
            oScript.SignalCheck(1, "O_COUNT", "2");
            oScript.SignalView(2, "O_COUNT");
            oScript.SignalCheck(2, "O_COUNT", "3");
            oScript.SignalView(3, "O_COUNT");
            oScript.SignalCheck(3, "O_COUNT", "4");
            oScript.SignalView(4, "O_COUNT");
            oScript.SignalCheck(4, "O_COUNT", "5");
            oScript.SignalView(5, "O_COUNT");
            oScript.SignalCheck(5, "O_COUNT", "6");
            oScript.SignalOut(6, "I_ENABLE", "0");
            //oScript.SignalCheck(6, "O_COUNT", "6");
            oScript.SignalView(7, "O_COUNT");
            //oScript.SignalCheck(7, "O_COUNT", "6");
            //oScript.SignalCheck(8, "O_COUNT", "6");
            //oScript.SignalCheck(9, "O_COUNT", "6");
            oScript.SignalOut(10, "I_ENABLE", "1");
            //oScript.SignalCheck(10, "O_COUNT", "7");
            //oScript.SignalCheck(11, "O_COUNT", "8");
            //oScript.SignalCheck(12, "O_COUNT", "9");
            //oScript.SignalCheck(13, "O_COUNT", "10");
            //oScript.SignalCheck(14, "O_COUNT", "11");
            //oScript.SignalCheck(15, "O_COUNT", "12");
            //oScript.SignalCheck(16, "O_COUNT", "13");
            oScript.SignalView(30, "O_COUNT");
            //oScript.SignalCheck(30, "O_COUNT", "27");
            oScript.SignalView(35, "O_COUNT");
            //oScript.SignalCheck(35, "O_COUNT", "5");
            
            return true;
        }
    }
}

Base Class, RapidHardware or Padframe

TopLevelHardware.cs is a class that is inherited from the RapidHardware class.

We can inherit from the RapidHardware class or the Padframe class. The RapidHardware class is fine for FPGA designs. The Padframe class is just an extension of the RapidHardware class that contains additional features for integrated circuit development using Mentor Graphics.

    class ToplevelHardware : PadFrame 
    {

Configure Settings

The virtual ConfigureSettings() method should be overidden to define how the hardware will be generated. Settings are used to control every aspect of how Rapid HDL will function when the program runs. For example, settings can enable or disable features such as an SDRAM interface, a debug data bus, or the reset signal. Settings also determine if the Verilog test benches will be generated, if a Xilinx FPGA Synthesis process will be started, or if a build process should take place on a remote server. A complete list of settings is outlined here.

Settings should always be defined the ConfigureSettings() override. Settings are needed before the Rapid HDL processing takes place, so they are assumed to be valid and completely defined after ConfigureSettings() executes.

  public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = true;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 1;
            Settings.UseSDRAM = false;
            Settings.UseReset = true;
            Settings.SynthASIC = false;
            Settings.SimulateVerilog = true;
            Settings.ForceBuildHardware = false;
            Settings.BuildRemote = false;
            //Settings.BuildServerPath = "desktop:8080";
            return true;
        }

Generate Structure

The RapidHardware class includes a virtual GenerateStructure() method that serves the same function as the GenerateStructure() method in the component class. The only input parameter for this method is the TopLevelComponent of the hardware.

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            // create an instance of the upcounter object
            // Parameter 1 -> This is a child of the TopLevelComponent, passed into this function
            // Parameter 2 -> name this component as "counter"
            // Parameter 3 -> connect the Main Clock from the toplevel component
            // Parameter 4 -> count to 27
            // Parameter 5 -> count on the rising edge of the clock
            // Parameter 6 -> create an enable signal to control this counter
            // Parameter 7 -> reset this counter to 0
            // Parameter 8 -> count up by 1
            UpCounter oUpCounter = new UpCounter(TopLevelComponent, "counter", 
                TopLevelComponent.MainClock, 5, true, true, 1, 27, 1);
            

            // create a signal named "I_ENABLE" that we can control from software
            // it is connected to the "EnableIn" field of the up counter
            // it is 1 bit wide
            SystemInterface.AddSignalSource("I_ENABLE", oUpCounter.EnableIn, "1");

            // connect the upcounter's reset connection to the MainReset signal of our top component
            oUpCounter.ResetIn.Connection = TopLevelComponent.MainReset;

            AssignPinCLK(39);
            AssignPinGND(40);
            AssignPinVDD(20);
            AssignPinInput("I_ENABLE", 37);
            //AssignPinInput("I_RESET", 38);

            return true;
        }

In this method, we create hardware using the RapidHDL library and attach the hardware to the top level component. Here, only an upcounter component is created. Notice that the parent component of the upcounter is now the TopLevelComponent that was passed in as a parameter.

            UpCounter oUpCounter = new UpCounter(TopLevelComponent, "counter", 
                TopLevelComponent.MainClock, 5, true, true, 1, 27, 1);

The GenerateStructueMethod() can also be used to define signal sources that will be inputs to the hardware. Here, the counter has 2 input signals, a reset signal, and an enable signal.

The SystemInterface component is used to define the inputs and outputs of the overall hardware, and SystemInterface belongs to the RapidHardware class already. In the line below, a signal source named "I_ENABLE" is defined and connected to the EnableIn NodeVector of the up counter. The width of the signal source is inferred from the NodeVector that it drives, in this case it is 1 bit wide. The final "1" parameter is the default value of the signal source. When simulating or using an FPGA, the value 1 will be applied to this signal source before a reset.

            SystemInterface.AddSignalSource("I_ENABLE", oUpCounter.EnableIn, "1");

The reset signal is already defined as part of the TopLevel Component because we enabled it in the ConfigureSettings() method.

            Settings.UseReset = true;

So the existing MainReset NodeVector is already available in the TopLevelComponent. The line below connects the reset signal to the up counter.

            oUpCounter.ResetIn.Connection = TopLevelComponent.MainReset;

Configure Signal Views

Signal Views are the signal outputs of the final hardware. Signal views should be defined by overriding the virtual ConfigureSignalViews() method of the RapidHardware base class. This ensures that the signal being viewed has already been generated by all the components in the component hierarchy.

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            // read the output of the counter in our software
            SystemInterface.AddSignalView("O_COUNT", "counter.COUNT_O");
            // specify the format of the output signal that we want to view
            SystemInterface.FormatSignalView("O_COUNT", SignalFormat.Unsigned);
            AssignPinOutput("O_COUNT", 31);

            return true;
        }

Again, the SystemInterface component is availabe in the RapidHardware base class. In this case, a SignalView named "OCOUNT" for output count is created. The view connects to the component named "counter" and the NodeVector named "COUNTO".

When the components are defined in Rapid HDL, each child component and each node vector is given an instance name. Here, we are referencing the components and node vectors using the instance name. A '.' separates each component in the hirarchy, and we can use this notation to go an arbitrary number of levels deep.

            SystemInterface.AddSignalView("O_COUNT", "counter.COUNT_O");

During hardware and software co-execution, the value of the signal in the hardware may be read directly from the hardware, as long as the hardware clock is paused. In this case, the count will be available using "O_COUNT" as the signal view label. We desire the signal to be converted to an unsigned number by default, so the following line sets the default format of the signal view.

            SystemInterface.FormatSignalView("O_COUNT", SignalFormat.Unsigned);

Not Discussed Here...

The AssignPin commands are used to assign signal views and signal sources to actual pins on an integrated circuit. This information would be used to interact with Mentor Graphics. We will discuss this in a different section. Generally, if you are not creating integrated circuits with Mentor Graphics, you don't need to use the AssignPin commands.

AssignPinOutput("O_COUNT", 31);

Last edited Sep 10, 2009 at 5:27 AM by allen248, version 2

Comments

No comments yet.