|
Examples |
|
Refer to Getting Started for
information on how to build the following examples:
|
|
torc/examples/ArchitectureExample.cpp
|
|
The architecture API
example demonstrates basic use of the device
database. It begins by initializing a
DirectoryTree object with the invocation path of the
executable. The location of the executable
will serve as the reference point for all other
directories, and in particular for the "devices"
directory with all of its device databases.
A DeviceDesignator object is initialized for
convenience with a particular Virtex6 device,
package, and speed grade (the package and speed
grade being optional), which it parses.
Functions in the DeviceDesignator class allow access
to the family, device, package, and speed grade.
The device database object is then constructed,
using the designator object to determine which
device and package to load. The appropriate
database file is read from disk, and is used to
populate all wiring, logic, and package information
for the device.
Once the device database is initialized, the code
looks up a particular logic site, and then looks up
a particular site pin. That pin is returned as
a "tilewire," a numeric combination of a wire index
and a tile index, and is written to the
output. The arcs that can connect this wire to
other wires are output as well.
#include "torc/Architecture.hpp"
#include "torc/Common.hpp"
#include <iostream>
using namespace torc::common;
using namespace torc::architecture;
using namespace torc::architecture::xilinx;
int main(int argc, char* argv[]) {
// construct and initialize the device database
(void) argc;
DirectoryTree directoryTree(argv[0]);
DeviceDesignator designator("xc6vlx75tff484-1");
DDB ddb(designator);
// look up a site output and convert it to a tilewire
const Sites& sites = ddb.getSites();
SiteIndex index = sites.findSiteIndex("SLICE_X0Y119");
const Site& site = sites.getSite(index);
Tilewire pinTilewire = site.getPinTilewire("A");
std::cout << ddb << pinTilewire << std::endl;
// look up arcs that connect from this tilewire
ArcVector sinks;
ddb.expandSegmentSinks(pinTilewire, sinks);
ArcVector::const_iterator pos = sinks.begin();
ArcVector::const_iterator end = sinks.end();
while(pos < end)
std::cout << "\t" << *pos++ << std::endl;
return 0;
}
The tilewire is a lightweight encapsulation of an
integer that lacks any knowledge of the current
database. Its annotated output is made
possible because the code first inserted the
database object ddb into the output stream
("std::cout << ddb"). This insertion
only needs to be done one time per stream.
Without this insertion, the tilewire output would
simply be the combination of its tile and wire
indexes, for example "189@186".
WARNING: Need to check segment packing.
Reading device xc6vlx75t ("./torc/devices/xc6vlx75t.db")...
Database 1.0.0 build 2, Vendor "Release 12.2 - xdl M.63c (lin64)"
Reading family Virtex6 ("./torc/devices/Virtex6.db")...
Reading 96 tile types...
Reading wire info for 96 tile types...
Reading 3 speed grades (-3, -2, -1) ...
Reading 2 packages (ff484, ff784) ...
Reading tile map for 22733 tiles (127 rows x 179 columns)...
Reading 22733 tiles...
Reading 38074 segments...
1673499 total segments
Reading irregular arcs for 22733 tiles...
Reading 51 site types...
Reading 210 primitive pin maps...
Reading 22509 sites...
Read 2566212 bytes from Virtex6
Read 14450208 bytes from xc6vlx75t
CLBLM_M_A@[1,7] CLBLM "CLBLM_X1Y119" (189@186) OUTPUT
CLBLM_M_A@[1,7] CLBLM "CLBLM_X1Y119" (189@186) OUTPUT >> CLBLM_LOGIC_OUTS12@[1,7] CLBLM "CLBLM_X1Y119" (121@186)
CLBLM_M_A@[1,7] CLBLM "CLBLM_X1Y119" (189@186) OUTPUT >> CLBLM_M_AMUX@[1,7] CLBLM "CLBLM_X1Y119" (197@186) OUTPUT
|
|
torc/examples/BitstreamExample.cpp
|
|
The bitstream API
example reads a bitstream file specified on the
command line, determined the correct architecture,
reads and parses its packets into a new Bitstream
object (which is itself a vector of packets), and
writes those packets to the standard output.
#include "torc/Bitstream.hpp"
#include "torc/Common.hpp"
#include <fstream>
#include <iostream>
using namespace torc::common;
using namespace torc::bitstream;
int main(int argc, char* argv[]) {
// we need an input bitstream
if(argc != 2) {
std::cout << "Usage: " << argv[0] << " bitstream.bit" << std::endl;
exit(-1);
}
// read the bitstream
boost::filesystem::path bitstreamPath = argv[1];
BitstreamSharedPtr bitstreamPtr = Factory::newBitstreamPtr(bitstreamPath);
// write the bitstream digest to the console
std::cout << *bitstreamPtr << std::endl;
return 0;
}
After the bitstream has been read and parsed, the
bitstream object is "inserted" into the standard
output. An output helper class formats the
output as a sequence of bitstream packets, complete
with symbolic bit field constants.
Design VirtexUnitTest.reference.ncd (v50bg256) @ 2011/01/26 11:51:59: 69900 bytes (17475 words)
00000058: DUMMY
0000005c: SYNC
00000060: TYPE1 WRITE CMD RCRC
00000068: TYPE1 WRITE FLR: 0000000b
00000070: TYPE1 WRITE COR: 00803f2d (DonePipe:No, DriveDone:No, Capture:Continuous, ConfigRate:[UNKNOWN 2], StartupClk:Cclk, LOCK_WAIT:1, SHUTDOWN:0, DONE_cycle:4, LCK_cycle:NoWait, GTS_cycle:5, GWE_cycle:6, GSR_cycle:6)
00000078: TYPE1 WRITE MASK: 00000000 (Security:Protected, Persist:Protected, GTS_USER_B:Protected)
00000080: TYPE1 WRITE CMD SWITCH
00000088: TYPE1 WRITE FAR: 00000000
00000090: TYPE1 WRITE CMD WCFG
00000098: TYPE1 WRITE FDRI: 00000000 words
0000009c: TYPE2 WRITE FDRI: 00003e04 words
0000f8b0: TYPE1 WRITE FAR: 02000000
0000f8b8: TYPE1 WRITE FDRI: 0000030c words
000104ec: TYPE1 WRITE FAR: 02020000
000104f4: TYPE1 WRITE FDRI: 00000300 words
000110f8: TYPE1 WRITE CRC: 000018fa
00011100: TYPE1 WRITE CMD LFRM
00011108: TYPE1 WRITE FDRI: 0000000c words
0001113c: TYPE1 WRITE CMD START
00011144: TYPE1 WRITE CTL: 00000000 (Security:None, Persist:No, GTS_USER_B:IoDisabled)
0001114c: TYPE1 WRITE CRC: 0000e15a
00011154: [UNKNOWN TYPE 0]
00011158: [UNKNOWN TYPE 0]
0001115c: [UNKNOWN TYPE 0]
00011160: [UNKNOWN TYPE 0]
Bitfield constants can also be initialized
symbolically for convenience, as is done in
torc/bitstream/VirtexBitstreamUnitTest.cpp.
|
|
torc/examples/GenericExample.cpp
|
|
The generic API
example reads an EDIF file, updates a property, and
writes the file back out. Like the other
examples, this one too begins by initializing the
DirectoryTree. The code then specifies the two
files it will work with, the first one already
existing in the regression directory, and the second
one to be used to output the modified design.
The code opens the reference file and imports the
EDIF design into its object model. It then
looks up a particular library, cell, and view, to
find an instance of interest. The INIT
property for that instance is changed from its
previous value of "8" to "6", effectively turning
this 2-input LUT from an AND gate into an XOR
gate. The code then opens the output file and
lets the exporter write out the resulting EDIF.
#include "torc/Generic.hpp"
#include "torc/Common.hpp"
#include <fstream>
#include <boost/regex.hpp>
using namespace std;
using namespace torc::generic;
int main(int argc, char* argv[]) {
// build the file paths
(void) argc;
torc::common::DirectoryTree directoryTree(argv[0]);
boost::filesystem::path referencePath = torc::common::DirectoryTree::getExecutablePath()
/ "regression" / "GenericExample.reference.edf";
boost::filesystem::path generatedPath = torc::common::DirectoryTree::getExecutablePath()
/ "regression" / "GenericExample.generated.edf";
// import the EDIF design
string inFileName = referencePath.string();
fstream fileStream(inFileName.c_str());
ObjectFactorySharedPtr factoryPtr(new ObjectFactory());
EdifImporter importer(factoryPtr);
importer(fileStream, inFileName);
// look up an instance of interest
RootSharedPtr rootPtr = importer.getRootPtr();
InstanceSharedPtr instancePtr = rootPtr->findLibrary("work")->findCell("and")
->findView("verilog")->findInstance("oZ0");
// change the INIT property (LUT mask) to XOR
PropertySharedPtr initPropertyPtr = instancePtr->getProperty("INIT");
string originalMask = initPropertyPtr->getValue().get<Value::String>();
std::cout << "The original LUT mask was \"" << originalMask << "\"." << std::endl;
Value xorMask(Value::eValueTypeString, string("6"));
initPropertyPtr->setValue(xorMask);
// export the EDIF design
string outFileName = generatedPath.string();
fstream edifExport(outFileName.c_str(), ios_base::out);
EdifExporter exporter(edifExport);
exporter(rootPtr);
return 0;
}
This example generates little console output, but
its effects can be seen with the following diff
command:
diff regression/GenericExample.reference.edf regression/GenericExample.generated.edf
The expected output is:
47c47 < (property INIT (string "8")) --- > (property INIT (string "6"))
|
|
torc/examples/PhysicalExample.cpp
|
|
The physical API
example reads in an XDL file that must be specified
by the user, looks up the design root, and simply
writes the design back out. (A few XDL files
are available in the regression directory.)
Because the input file is specified on the command
line, there is no need to create and initialize a
DirectoryTree object in this example. The code
opens the input file, and then imports all of the
XDL into its object mode. The root of that
object model is obtained from the importer, and can
be used to traverse or manipulate anything in the
design.
Even though no changes are made to the design in
this example, the code is written back out with a
different extension.
#include "torc/Physical.hpp"
#include <fstream>
/// \brief Standard main() function.
int main(int argc, char* argv[]) {
// import the XDL design
if(argc < 2) return 0;
std::string inFileName(argv[1]);
std::fstream fileStream(inFileName.c_str());
if(!fileStream.good()) return -1;
torc::physical::XdlImporter importer;
importer(fileStream, inFileName);
// look up the design (and do something with it ...)
torc::physical::DesignSharedPtr designPtr = importer.getDesignPtr();
// export the XDL design
std::string outFileName = boost::filesystem::path(inFileName).replace_extension().string()
+ ".mod.xdl";
std::fstream xdlExport(outFileName.c_str(), std::ios_base::out);
torc::physical::XdlExporter fileExporter(xdlExport);
fileExporter(designPtr);
return 0;
}
Note that there is a subclass of
torc::physical::XdlImporter named
torc::architecture::XdlImporter. The
architecture-aware importer identifies the design
device, initializes the corresponding device
database, and populates all wire usage
information. Code like that in the example
above, based on torc::architecture::XdlImporter,
could serve as the basis for a stand-alone XDL
router or placer.
This example generates no console output.
Modifications to the design are left as an exercise
to the reader.
|
|
torc/examples/EdifObfuscator.cpp |
|
The EDIF obfuscator
example reads an EDIF file specified by the user,
and replaces all possible names and identifiers with
MD5 hashes. Names and identifiers that are not
replaced include those in any vendor libraries, as
well as those belonging to the design's top-level
ports.
The sample output below shows a simple EDIF design
after obfuscation. The vendor VIRTEX library
is not obfuscated, nor are the top-level ports of
the design (the "and" cell in this case).
(edif (rename and "AND") (edifVersion 2 0 0) (edifLevel 0) (keywordMap (keywordLevel 0)) (library VIRTEX (ediflevel 0) (technology (numberDefinition)) (cell LUT2 (cellType GENERIC) (view PRIM (viewType NETLIST) (interface (port I0 (direction INPUT) ) (port I1 (direction INPUT) ) (port O (direction OUTPUT) ) ) ) ) ) (library work (ediflevel 0) (technology (numberDefinition)) (cell (rename and "AND") (cellType GENERIC) (view verilog (viewType NETLIST) (interface (port i0 (direction INPUT) ) (port i1 (direction INPUT) ) (port o (direction OUTPUT) ) ) (contents (instance icfcd208495d565ef66e7dff9f98764da (viewRef PRIM (cellRef LUT2 (libraryRef VIRTEX))) (property INIT (string )) ) (net ic4ca4238a0b923820dcc509a6f75849b (joined (portRef i0) (portRef I0 (instanceRef icfcd208495d565ef66e7dff9f98764da)) ) ) (net ic81e728d9d4c2f636f067f89cc14862c (joined (portRef i1) (portRef I1 (instanceRef icfcd208495d565ef66e7dff9f98764da)) ) ) (net ieccbc87e4b5ce2fe28308fd9f2a7baf3 (joined (portRef o) (portRef O (instanceRef icfcd208495d565ef66e7dff9f98764da)) ) ) ) ) ) ) (design (rename and "AND") (cellRef and (libraryRef work)) (property PART (string "xc5vlx30ff324-1") (owner "Xilinx")) ) )
|
|
|