-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1847 from lnis-uofu/bin_format
Bin format
- Loading branch information
Showing
38 changed files
with
709 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
include(GNUInstallDirs) | ||
|
||
if(NOT MSCV) | ||
# These flags generate noisy but non-bug warnings when using lib kj, | ||
# supress them. | ||
set(WARN_FLAGS_TO_DISABLE | ||
-Wno-undef | ||
-Wno-non-virtual-dtor | ||
) | ||
foreach(flag ${WARN_FLAGS_TO_DISABLE}) | ||
CHECK_CXX_COMPILER_FLAG(${flag} CXX_COMPILER_SUPPORTS_${flag}) | ||
if(CXX_COMPILER_SUPPORTS_${flag}) | ||
#Flag supported, so enable it | ||
add_compile_options(${flag}) | ||
endif() | ||
endforeach() | ||
endif() | ||
|
||
# Create generated headers from capnp schema files | ||
set(CAPNP_DEFS | ||
gen/unique_blocks_uxsdcxx.capnp | ||
) | ||
|
||
capnp_generate_cpp(CAPNP_SRCS CAPNP_HDRS | ||
${CAPNP_DEFS} | ||
) | ||
|
||
|
||
|
||
add_library(libopenfpgacapnproto STATIC | ||
${CAPNP_SRCS} | ||
${IC_SRCS} | ||
) | ||
|
||
|
||
add_dependencies(libopenfpgacapnproto | ||
generate_unique_block_capnp | ||
) | ||
|
||
|
||
target_include_directories(libopenfpgacapnproto PUBLIC | ||
${CMAKE_CURRENT_SOURCE_DIR} | ||
${CMAKE_CURRENT_BINARY_DIR} | ||
${CMAKE_CURRENT_BINARY_DIR}/gen | ||
) | ||
target_link_libraries(libopenfpgacapnproto | ||
libopenfpgautil | ||
libvtrcapnproto | ||
) | ||
|
||
|
||
add_custom_target( | ||
generate_unique_block_capnp | ||
COMMAND ${CMAKE_COMMAND} -E remove_directory unique_blocks_capnproto_generate | ||
COMMAND ${CMAKE_COMMAND} -E make_directory unique_blocks_capnproto_generate | ||
COMMAND ${CMAKE_COMMAND} -E chdir unique_blocks_capnproto_generate git clone https://github.com/duck2/uxsdcxx | ||
COMMAND python3 -mpip install --user -r unique_blocks_capnproto_generate/uxsdcxx/requirements.txt | ||
COMMAND ${CMAKE_COMMAND} -E chdir unique_blocks_capnproto_generate python3 uxsdcxx/uxsdcxx.py ${CMAKE_CURRENT_SOURCE_DIR}/gen/unique_blocks.xsd | ||
COMMAND ${CMAKE_COMMAND} -E chdir unique_blocks_capnproto_generate python3 uxsdcxx/uxsdcap.py ${CMAKE_CURRENT_SOURCE_DIR}/gen/unique_blocks.xsd | ||
unique_blocks_capnproto_generate/unique_blocks_uxsdcxx.h | ||
unique_blocks_capnproto_generate/unique_blocks_uxsdcxx_capnp.h | ||
unique_blocks_capnproto_generate/unique_blocks_uxsdcxx_interface.h | ||
${CMAKE_CURRENT_SOURCE_DIR}/gen | ||
COMMAND ${CMAKE_COMMAND} -E copy unique_blocks_capnproto_generate/unique_blocks_uxsdcxx.capnp ${CMAKE_CURRENT_SOURCE_DIR}/gen | ||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen/unique_blocks.xsd | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
Capnproto usage in Openfpga | ||
====================== | ||
|
||
Capnproto is a data serialization framework designed for portabliity and speed. | ||
In Openfpga, capnproto is used to provide binary formats for internal data | ||
structures that can be computed once, and used many times. Specific examples: | ||
- preload unique blocks | ||
|
||
What is capnproto? | ||
================== | ||
|
||
capnproto can be broken down into 3 parts: | ||
- A schema language | ||
- A code generator | ||
- A library | ||
|
||
The schema language is used to define messages. Each message must have an | ||
explcit capnproto schema, which are stored in files suffixed with ".capnp". | ||
The capnproto documentation for how to write these schema files can be found | ||
here: https://capnproto.org/language.html | ||
|
||
The schema by itself is not especially useful. In order to read and write | ||
messages defined by the schema in a target language (e.g. C++), a code | ||
generation step is required. Capnproto provides a cmake function for this | ||
purpose, `capnp_generate_cpp`. This generates C++ source and header files. | ||
These source and header files combined with the capnproto C++ library, enables | ||
C++ code to read and write the messages matching a particular schema. The C++ | ||
library API can be found here: https://capnproto.org/cxx.html | ||
|
||
Contents of libopenfpgacapnproto | ||
=========================== | ||
|
||
libopenfpgacapnproto should contain two elements: | ||
- Utilities for working capnproto messages in Openfpga | ||
- Generate source and header files of all capnproto messages used in Openfpga | ||
|
||
I/O Utilities | ||
------------- | ||
|
||
Capnproto does not provide IO support, instead it works from arrays (or file | ||
descriptors). To avoid re-writing this code, libopenfpgacapnproto provides two | ||
utilities that should be used whenever reading or writing capnproto message to | ||
disk. These two files are copied : | ||
- `serdes_utils.h` provides the writeMessageToFile function - Writes a | ||
capnproto message to disk. | ||
- `mmap_file.h` provides MmapFile object - Maps a capnproto message from the | ||
disk as a flat array. | ||
|
||
Capnproto schemas | ||
----------------- | ||
|
||
libopenfpgacapnproto should contain all capnproto schema definitions used within | ||
Openfpga. To add a new schema: | ||
1. Add the schema to git in `libs/libopenfpgacapnproto/` | ||
2. Add the schema file name to `capnp_generate_cpp` invocation in | ||
`libs/libopenfpgacapnproto/CMakeLists.txt`. | ||
|
||
The schema will be available in the header file `schema filename>.h`. The | ||
actual header file will appear in the CMake build directory | ||
`libs/libopenfpgacapnproto` after `libopenfpgacapnproto` has been rebuilt. | ||
|
||
Writing capnproto binary files to text | ||
====================================== | ||
|
||
The `capnp` tool (found in the CMake build directiory | ||
`/vtr-verilog-to-routing/libs/EXTERNAL/capnproto/c++/src/capnp`) can be used to convert from a binary | ||
capnp message to a textual form. | ||
|
||
Example converting UniqueBlockCompactInfo from binary to text: | ||
|
||
``` | ||
capnp convert binary:text unique_blocks_uxsdcxx.capnp UniqueBlockCompactInfo \ | ||
< test.bin > test.txt | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
`unique_blocks_uxsdcxx.capnp` is generated via uxsdcxx and is checked in to | ||
avoid requiring python3 and the uxsdcxx depedencies to build Openfpga. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?xml version="1.0"?> | ||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> | ||
|
||
<!-- Enumeration for BlockType --> | ||
<xs:simpleType name="type"> | ||
<xs:restriction base="xs:string"> | ||
<xs:enumeration value="cbx"/> | ||
<xs:enumeration value="cby"/> | ||
<xs:enumeration value="sb"/> | ||
</xs:restriction> | ||
</xs:simpleType> | ||
|
||
<!-- InstanceInfo Structure (using attributes for x and y) --> | ||
<xs:complexType name="instance"> | ||
<xs:attribute name="x" type="xs:unsignedInt" use="required"/> | ||
<xs:attribute name="y" type="xs:unsignedInt" use="required"/> | ||
</xs:complexType> | ||
|
||
<!-- BlockInfo Structure (using attributes for type, x, and y, and instances as children) --> | ||
<xs:complexType name="block"> | ||
<xs:sequence> | ||
<xs:element name="instance" type="instance" minOccurs="0" maxOccurs="unbounded" /> | ||
</xs:sequence> | ||
<xs:attribute name="type" type="type" use="required" /> | ||
<xs:attribute name="x" type="xs:unsignedInt" use="required" /> | ||
<xs:attribute name="y" type="xs:unsignedInt" use="required" /> | ||
</xs:complexType> | ||
|
||
<!-- Root element definition --> | ||
<xs:element name="unique_blocks"> | ||
<xs:complexType> | ||
<xs:sequence> | ||
<xs:element name="block" type="block" maxOccurs="unbounded"/> | ||
</xs:sequence> | ||
</xs:complexType> | ||
</xs:element> | ||
|
||
</xs:schema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# This file is generated by uxsdcap 0.1.0. | ||
# https://github.com/duck2/uxsdcxx | ||
# Modify only if your build process doesn't involve regenerating this file. | ||
# | ||
# Cmdline: uxsdcxx/uxsdcap.py /home/jrlin/add_feature/bin_format/OpenFPGA/libs/libopenfpgacapnproto/gen/unique_blocks.xsd unique_blocks_capnproto_generate/unique_blocks_uxsdcxx.h unique_blocks_capnproto_generate/unique_blocks_uxsdcxx_capnp.h unique_blocks_capnproto_generate/unique_blocks_uxsdcxx_interface.h /home/jrlin/add_feature/bin_format/OpenFPGA/libs/libopenfpgacapnproto/gen | ||
# Input file: /home/jrlin/add_feature/bin_format/OpenFPGA/libs/libopenfpgacapnproto/gen/unique_blocks.xsd | ||
# md5sum of input file: 1db9d740309076fa51f61413bae1e072 | ||
|
||
@0xc5f2ef95c322aac3; | ||
using Cxx = import "/capnp/c++.capnp"; | ||
$Cxx.namespace("ucap"); | ||
|
||
enum Type { | ||
uxsdInvalid @0; | ||
cbx @1; | ||
cby @2; | ||
sb @3; | ||
} | ||
|
||
struct Instance { | ||
x @0 :UInt32; | ||
y @1 :UInt32; | ||
} | ||
|
||
struct Block { | ||
type @0 :Type; | ||
x @1 :UInt32; | ||
y @2 :UInt32; | ||
instances @3 :List(Instance); | ||
} | ||
|
||
struct UniqueBlocks { | ||
blocks @0 :List(Block); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include <capnp/message.h> | ||
#include <capnp/serialize.h> | ||
#include <kj/io.h> | ||
|
||
#include <string> | ||
/* Headers from pugi XML library */ | ||
#include "pugixml.hpp" | ||
#include "pugixml_util.hpp" | ||
|
||
/* Headers from vtr util library */ | ||
#include "vtr_assert.h" | ||
#include "vtr_log.h" | ||
#include "vtr_time.h" | ||
|
||
/* Headers from libarchfpga */ | ||
#include "arch_error.h" | ||
#include "command_exit_codes.h" | ||
#include "device_rr_gsb_utils.h" | ||
#include "mmap_file.h" | ||
#include "openfpga_digest.h" | ||
#include "read_unique_blocks_bin.h" | ||
#include "read_unique_blocks_xml.h" | ||
#include "read_xml_util.h" | ||
#include "rr_gsb.h" | ||
#include "unique_blocks_uxsdcxx.capnp.h" | ||
#include "write_xml_utils.h" | ||
|
||
/******************************************************************** | ||
* This file includes the top-level functions of this library | ||
* which includes: | ||
* -- reads a bin file of unique blocks to the associated | ||
* data structures: device_rr_gsb | ||
*******************************************************************/ | ||
namespace openfpga { | ||
|
||
/*read the instances' coordinate of a unique block from a bin file*/ | ||
std::vector<vtr::Point<size_t>> read_bin_unique_instance_coords( | ||
const ucap::Block::Reader& unique_block) { | ||
std::vector<vtr::Point<size_t>> instance_coords; | ||
if (unique_block.hasInstances()) { | ||
auto instance_list = unique_block.getInstances(); | ||
for (auto instance : instance_list) { | ||
int instance_x = instance.getX(); | ||
int instance_y = instance.getY(); | ||
vtr::Point<size_t> instance_coordinate(instance_x, instance_y); | ||
instance_coords.push_back(instance_coordinate); | ||
} | ||
} | ||
return instance_coords; | ||
} | ||
|
||
/*read the unique block coordinate from a bin file */ | ||
vtr::Point<size_t> read_bin_unique_block_coord( | ||
const ucap::Block::Reader& unique_block, ucap::Type& type) { | ||
int block_x = unique_block.getX(); | ||
int block_y = unique_block.getY(); | ||
type = unique_block.getType(); | ||
vtr::Point<size_t> block_coordinate(block_x, block_y); | ||
return block_coordinate; | ||
} | ||
|
||
/*top-level function to read unique blocks from bin file*/ | ||
int read_bin_unique_blocks(DeviceRRGSB& device_rr_gsb, const char* file_name, | ||
bool verbose_output) { | ||
/* clear unique modules & reserve memory to relavant vectors */ | ||
device_rr_gsb.clear_unique_modules(); | ||
device_rr_gsb.reserve_unique_modules(); | ||
MmapFile f(file_name); | ||
::capnp::FlatArrayMessageReader reader(f.getData()); | ||
auto root = reader.getRoot<ucap::UniqueBlocks>(); | ||
if (root.hasBlocks()) { | ||
auto block_list = root.getBlocks(); | ||
for (auto unique_block : block_list) { | ||
ucap::Type type; | ||
vtr::Point<size_t> block_coordinate = read_bin_unique_block_coord( | ||
unique_block, type); /*get block coordinate and type*/ | ||
std::vector<vtr::Point<size_t>> instance_coords = | ||
read_bin_unique_instance_coords( | ||
unique_block); /* get a list of instance coordinates*/ | ||
/* get block coordinate and instance coordinate, try to setup | ||
* device_rr_gsb */ | ||
if (type == ucap::Type::SB) { | ||
device_rr_gsb.preload_unique_sb_module(block_coordinate, | ||
instance_coords); | ||
} else if (type == ucap::Type::CBY) { | ||
device_rr_gsb.preload_unique_cby_module(block_coordinate, | ||
instance_coords); | ||
} else if (type == ucap::Type::CBX) { | ||
device_rr_gsb.preload_unique_cbx_module(block_coordinate, | ||
instance_coords); | ||
} else if (type == ucap::Type::UXSD_INVALID) { | ||
VTR_LOG_ERROR("Invalid block type!"); | ||
return CMD_EXEC_FATAL_ERROR; | ||
} | ||
} | ||
} | ||
device_rr_gsb.build_gsb_unique_module(); | ||
if (verbose_output) { | ||
report_unique_module_status_read(device_rr_gsb, true); | ||
} | ||
return CMD_EXEC_SUCCESS; | ||
} | ||
} // namespace openfpga |
Oops, something went wrong.