Skip to content

Commit 6d5ecde

Browse files
author
Johan Peltenburg
committed
Add feature to allow external I/O signals
1 parent 7f40ae8 commit 6d5ecde

File tree

18 files changed

+272
-79
lines changed

18 files changed

+272
-79
lines changed

codegen/cpp/fletchgen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ add_compile_unit(
6565
src/fletchgen/nucleus.cc
6666
src/fletchgen/profiler.cc
6767
src/fletchgen/axi4_lite.cc
68+
src/fletchgen/external.cc
6869

6970
src/fletchgen/srec/recordbatch.cc
7071
src/fletchgen/srec/srec.cc

codegen/cpp/fletchgen/README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,56 @@ your kernel implementation.
9494
| fletcher_profile | true / false | false | If set to true, mark this field for profiling. The hardware streams resulting from this field will have a profiler attached to them. |
9595
| fletcher_tag_width | 1 / 2 / 3 / ... | 1 | Width of the `tag` field of commands and unlock streams of RecordBatchReaders/Writers. Can be used to identify commands. |
9696

97+
# Custom MMIO registers
98+
You can add custom MMIO registers to your kernel using `--reg`.
99+
More information [can be found here](../../../docs/mmio.md).
100+
101+
# Custom external I/O
102+
103+
Sometimes, your kernel requires other I/O signals than just Arrow data streams
104+
in and out, and MMIO registers. There may be some other type of data source or
105+
sink in your design, there may be some platform-specific things you want to use,
106+
or etcetera.
107+
108+
You can supply Fletchgen with a YAML file describing what signals you want to
109+
draw between the kernel and the top-level. An example is shown below, where we
110+
want to handshake completion from the platform top-level with a `req` and `ack`
111+
bit.
112+
113+
```yaml
114+
- record:
115+
name: platform
116+
fields:
117+
- record:
118+
name: complete
119+
fields:
120+
- field:
121+
name: req
122+
width: 1
123+
- field:
124+
name: ack
125+
width: 1
126+
reverse: true
127+
```
128+
129+
This will result in the following signals appearing at the top-level:
130+
```vhdl
131+
ext_platform_complete_req : out std_logic;
132+
ext_platform_complete_ack : in std_logic
133+
```
134+
135+
* The signals are assumed to be driven by the kernel. To drive them from the top
136+
level, use:
137+
```yaml
138+
reverse: true
139+
```
140+
141+
* Fields with a width of 1 can be forced to be `std_logic_vector` instead of
142+
`std_logic` by using:
143+
```yaml
144+
vector: true
145+
```
146+
97147
# Further reading
98148

99149
You can generate a simulation top level and provide a Flatbuffer file with a

codegen/cpp/fletchgen/src/fletchgen/design.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include <cerata/api.h>
1616
#include <cerata/vhdl/vhdl.h>
17+
#include <cerata/yaml/yaml.h>
1718

1819
#include <string>
1920
#include <vector>
@@ -27,6 +28,7 @@
2728
#include "fletchgen/mmio.h"
2829
#include "fletchgen/profiler.h"
2930
#include "fletchgen/bus.h"
31+
#include "fletchgen/external.h"
3032

3133
namespace fletchgen {
3234

@@ -160,6 +162,7 @@ Design::Design(const std::shared_ptr<Options> &opts) {
160162
// Analyze schemas and recordbatches to get schema_set and batch_desc
161163
AnalyzeSchemas();
162164
AnalyzeRecordBatches();
165+
AnalyzeExternalIO();
163166
// Sanity check our design for equal number of schemas and recordbatch descriptions.
164167
if (schema_set->schemas().size() != batch_desc.size()) {
165168
FLETCHER_LOG(FATAL, "Number of Schemas and RecordBatchDescriptions does not match.");
@@ -250,4 +253,27 @@ std::vector<cerata::OutputSpec> Design::GetOutputSpec() {
250253
return result;
251254
}
252255

256+
void Design::AnalyzeExternalIO() {
257+
if (!options->externals_yaml.empty()) {
258+
// Read YAML
259+
auto fs = std::ifstream(options->externals_yaml);
260+
std::stringstream yaml;
261+
yaml << fs.rdbuf();
262+
263+
// Convert to field
264+
std::shared_ptr<cerata::Field> field;
265+
auto converter = cerata::yaml::YamlConverter(yaml.str(), &field);
266+
auto status = converter.Convert();
267+
if (!status.ok()) {
268+
FLETCHER_LOG(FATAL, status.msg());
269+
}
270+
271+
// Extract and store type
272+
auto ext_type = field->type();
273+
ext_type->SetName("_external");
274+
cerata::default_type_pool()->Add(ext_type);
275+
external = ext_type;
276+
}
277+
}
278+
253279
} // namespace fletchgen

codegen/cpp/fletchgen/src/fletchgen/design.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ struct Design {
4141
void AnalyzeSchemas();
4242
/// @brief Analyze the supplied RecordBatches.
4343
void AnalyzeRecordBatches();
44+
/// @brief Analyze custom IO.
45+
void AnalyzeExternalIO();
4446

4547
/// The program options.
4648
std::shared_ptr<Options> options;
@@ -61,6 +63,9 @@ struct Design {
6163

6264
Axi4LiteSpec mmio_spec;
6365

66+
/// External signals type
67+
std::optional<std::shared_ptr<Type>> external;
68+
6469
/// The RecordBatchDescriptions to use in SREC generation.
6570
std::vector<fletcher::RecordBatchDescription> batch_desc;
6671

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2018-2020 Delft University of Technology
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <map>
16+
#include <cerata/api.h>
17+
18+
#include "fletchgen/external.h"
19+
#include "fletchgen/status.h"
20+
21+
namespace fletchgen {
22+
23+
auto external() -> std::optional<std::shared_ptr<cerata::Type>> {
24+
auto opt = cerata::default_type_pool()->Get("_external");
25+
if (opt) {
26+
return opt.value()->shared_from_this();
27+
} else {
28+
return std::nullopt;
29+
}
30+
}
31+
32+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2018-2020 Delft University of Technology
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <cerata/api.h>
16+
17+
#include "fletchgen/status.h"
18+
19+
namespace fletchgen {
20+
21+
auto external() -> std::optional<std::shared_ptr<cerata::Type>>;
22+
23+
}

codegen/cpp/fletchgen/src/fletchgen/fletchgen.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,11 @@ int fletchgen(int argc, char **argv) {
141141
std::string axi_file_path = options->output_dir + "/vhdl/AxiTop.gen.vhd";
142142
FLETCHER_LOG(INFO, "Saving AXI top-level design to: " + axi_file_path);
143143
axi_file = std::ofstream(axi_file_path);
144-
fletchgen::top::GenerateAXITop(*design.mantle_comp, *design.schema_set, {&axi_file}, design.mmio_spec);
144+
fletchgen::top::GenerateAXITop(*design.mantle_comp,
145+
*design.schema_set,
146+
design.mmio_spec,
147+
design.external,
148+
{&axi_file});
145149
axi_file.close();
146150
}
147151

codegen/cpp/fletchgen/src/fletchgen/kernel.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "fletchgen/basic_types.h"
2323
#include "fletchgen/mmio.h"
2424
#include "fletchgen/array.h"
25+
#include "fletchgen/external.h"
2526

2627
namespace fletchgen {
2728

@@ -46,6 +47,7 @@ Kernel::Kernel(std::string name,
4647

4748
auto iw = index_width();
4849
auto tw = tag_width();
50+
4951
Add({iw, tw});
5052

5153
// Add ports going to/from RecordBatches.
@@ -81,6 +83,11 @@ Kernel::Kernel(std::string name,
8183
}
8284
}
8385

86+
// Add custom I/O
87+
auto ext = external();
88+
if (ext) {
89+
Add(cerata::port("ext", ext.value(), Port::Dir::OUT));
90+
}
8491
}
8592

8693
std::shared_ptr<Kernel> kernel(const std::string &name,

codegen/cpp/fletchgen/src/fletchgen/mantle.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "fletchgen/bus.h"
2828
#include "fletchgen/nucleus.h"
2929
#include "fletchgen/axi4_lite.h"
30+
#include "fletchgen/external.h"
3031

3132
namespace fletchgen {
3233

@@ -174,6 +175,14 @@ Mantle::Mantle(std::string name,
174175
// Append the PortArray and connect.
175176
Connect(array->Append(), bp);
176177
}
178+
179+
// Add and connect platform IO
180+
auto ext = external();
181+
if (ext) {
182+
auto pf = cerata::port("ext", ext.value(), Port::Dir::OUT);
183+
Add(pf);
184+
Connect(pf, nucleus_inst_->prt("ext"));
185+
}
177186
}
178187

179188
/// @brief Construct a Mantle and return a shared pointer to it.

codegen/cpp/fletchgen/src/fletchgen/nucleus.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "fletchgen/mmio.h"
2626
#include "fletchgen/profiler.h"
2727
#include "fletchgen/axi4_lite.h"
28+
#include "fletchgen/external.h"
2829

2930
namespace fletchgen {
3031

@@ -208,6 +209,14 @@ Nucleus::Nucleus(const std::string &name,
208209

209210
// Gather all Field-derived ports that require profiling on this Nucleus.
210211
ProfileDataStreams(mmio_inst);
212+
213+
// Add and connect platform IO
214+
auto ext = external();
215+
if (ext) {
216+
auto pf = cerata::port("ext", ext.value(), Port::Dir::OUT);
217+
Add(pf);
218+
Connect(pf, kernel_inst->prt("ext"));
219+
}
211220
}
212221

213222
std::shared_ptr<Nucleus> nucleus(const std::string &name,

0 commit comments

Comments
 (0)