15 #include <cerata/api.h>
16 #include <cerata/vhdl/vhdl.h>
19 #include <cerata/parameter.h>
21 #include "fletchgen/nucleus.h"
22 #include "fletchgen/basic_types.h"
23 #include "fletchgen/recordbatch.h"
24 #include "fletchgen/kernel.h"
25 #include "fletchgen/mmio.h"
26 #include "fletchgen/profiler.h"
27 #include "fletchgen/axi4_lite.h"
28 #include "fletchgen/external.h"
34 using cerata::component;
35 using cerata::parameter;
39 auto opt_comp = cerata::default_component_pool()->Get(
"ArrayCmdCtrlMerger");
44 auto ba = bus_addr_width();
45 auto iw = index_width();
46 auto tw = tag_width();
47 auto num_addr = parameter(
"num_addr", 0);
48 auto kernel_side_cmd = port(
"kernel_cmd",
cmd_type(iw, tw), Port::Dir::IN,
kernel_cd());
49 auto nucleus_side_cmd = port(
"nucleus_cmd",
cmd_type(iw, tw, num_addr * ba), Port::Dir::OUT,
kernel_cd());
50 auto ctrl = port_array(
"ctrl", vector(ba), num_addr, Port::Dir::IN,
kernel_cd());
51 auto result = component(
"ArrayCmdCtrlMerger", {num_addr, ba, iw, tw, kernel_side_cmd, nucleus_side_cmd, ctrl});
54 result->SetMeta(cerata::vhdl::meta::PRIMITIVE,
"true");
55 result->SetMeta(cerata::vhdl::meta::LIBRARY,
"work");
56 result->SetMeta(cerata::vhdl::meta::PACKAGE,
"Array_pkg");
64 cerata::NodeMap rebinding;
65 for (
const auto &fp : field_ports) {
67 auto copied_port =
dynamic_cast<FieldPort *
>(fp->CopyOnto(
nucleus, fp->name(), &rebinding));
68 copied_port->Reverse();
73 const std::vector<std::shared_ptr<RecordBatch>> &recordbatches,
74 const std::shared_ptr<Kernel> &
kernel,
75 const std::shared_ptr<Component> &
mmio,
78 cerata::NodeMap rebinding;
80 auto iw = index_width();
81 auto tw = tag_width();
85 auto kcd = port(
"kcd",
cr(), Port::Dir::IN,
kernel_cd());
96 auto mmio_inst = Instantiate(
mmio.get());
97 mmio_inst->prt(
"mmio") <<= axi;
98 mmio_inst->prt(
"kcd") <<= kcd;
103 std::vector<Instance *> accms;
105 std::vector<MmioPort *> mmio_buffer_ports;
106 for (
const auto &p : mmio_inst->GetAll<
MmioPort>()) {
108 mmio_buffer_ports.push_back(p);
113 for (
const auto &rb : recordbatches) {
114 CopyFieldPorts(
this, *rb, FieldPort::Function::ARROW);
115 CopyFieldPorts(
this, *rb, FieldPort::Function::UNLOCK);
119 auto cmd_ports = rb->GetFieldPorts(FieldPort::Function::COMMAND);
120 for (
const auto &cmd : cmd_ports) {
122 auto prefix = rb->schema()->name() +
"_" + cmd->field_->name();
123 auto ba = bus_addr_width(64, prefix);
127 nucleus_cmd->Reverse();
131 auto accm_inst = Instantiate(
accm(), cmd->name() +
"_accm_inst");
133 accm_inst->par(
"BUS_ADDR_WIDTH")->SetValue(ba);
134 accm_inst->par(
"INDEX_WIDTH")->SetValue(iw);
135 accm_inst->par(
"TAG_WIDTH")->SetValue(tw);
137 accms.push_back(accm_inst);
142 size_t batch_idx = 0;
145 for (
const auto &r : recordbatches) {
147 for (
const auto &ap : r->GetFieldPorts(FieldPort::Function::ARROW)) {
149 auto nucleus_data = prt(ap->name());
150 std::shared_ptr<cerata::Edge> edge;
151 if (ap->dir() == Port::OUT) {
152 edge = Connect(kernel_data, nucleus_data);
154 edge = Connect(nucleus_data, kernel_data);
159 for (
const auto &up : r->GetFieldPorts(FieldPort::Function::UNLOCK)) {
161 auto nucleus_unl = prt(up->name());
162 Connect(kernel_unl, nucleus_unl);
166 size_t field_idx = 0;
167 for (
const auto &cmd : r->GetFieldPorts(FieldPort::Function::COMMAND)) {
169 auto accm_nucleus_cmd = accms[accm_idx]->prt(
"nucleus_cmd");
170 auto accm_kernel_cmd = accms[accm_idx]->prt(
"kernel_cmd");
171 auto accm_ctrl = accms[accm_idx]->prt_arr(
"ctrl");
174 auto nucleus_cmd = this->prt(cmd->name());
178 Connect(nucleus_cmd, accm_nucleus_cmd);
179 Connect(accm_kernel_cmd, kernel_cmd);
183 auto field_bufs = r->batch_desc().fields[field_idx].buffers;
184 for (
size_t b = 0; b < field_bufs.size(); b++) {
187 Connect(accm_ctrl->Append(), mmio_buffer_ports[buf_idx]);
199 for (
auto &p : mmio_inst->GetAll<
MmioPort>()) {
202 if (p->dir() == Port::Dir::OUT) {
203 Connect(inst_port, p);
205 Connect(p, inst_port);
214 auto ext = external();
216 auto pf = cerata::port(
"ext", ext.value(), Port::Dir::OUT);
222 std::shared_ptr<Nucleus>
nucleus(
const std::string &name,
223 const std::vector<std::shared_ptr<RecordBatch>> &recordbatches,
224 const std::shared_ptr<Kernel> &
kernel,
225 const std::shared_ptr<Component> &
mmio,
227 return std::make_shared<Nucleus>(name, recordbatches,
kernel,
mmio, axi_spec);
231 std::vector<FieldPort *> result;
232 for (
const auto &ofp : GetNodes()) {
233 auto fp =
dynamic_cast<FieldPort *
>(ofp);
235 if (fp->function_ == fun) {
236 result.push_back(fp);
244 cerata::NodeMap rebinding;
246 std::vector<cerata::Signal *> profile_nodes;
247 for (
const auto &p :
GetFieldPorts(FieldPort::Function::ARROW)) {
250 if (p->edges().size() != 1) {
251 FLETCHER_LOG(ERROR,
"Nucleus port has other than exactly one edge.");
254 auto s = AttachSignalToNode(
this, p, &rebinding);
255 profile_nodes.push_back(s);
259 if (!profile_nodes.empty()) {
268 auto enable = signal(
"Profile_enable", cerata::bit(),
kernel_cd());
269 auto clear = signal(
"Profile_clear", cerata::bit(),
kernel_cd());
270 Add({enable, clear});
272 enable <<= mmio_inst->prt(
"f_Profile_enable_data");
273 clear <<= mmio_inst->prt(
"f_Profile_clear_data");
276 std::vector<MmioPort *> mmio_profile_ports;
277 for (
auto &p : mmio_inst->GetAll<
MmioPort>()) {
279 mmio_profile_ports.push_back(p);
284 for (
const auto &pair : profiler_map) {
285 auto instances = pair.second.first;
286 auto ports = pair.second.second;
288 for (
const auto &prof_inst : instances) {
289 Connect(prof_inst->prt(
"enable"), enable.get());
290 Connect(prof_inst->prt(
"clear"), clear.get());
293 for (
const auto &prof_port : ports) {
294 Connect(mmio_profile_ports[port_idx], prof_port);
Contains all classes and functions related to Fletchgen.
std::shared_ptr< Nucleus > nucleus(const std::string &name, const std::vector< std::shared_ptr< RecordBatch >> &recordbatches, const std::shared_ptr< Kernel > &kernel, const std::shared_ptr< Component > &mmio, Axi4LiteSpec axi_spec)
Make an Nucleus component based on RecordBatch components. Returns a shared pointer to the new Nucleu...
std::shared_ptr< Type > cmd_type(const std::shared_ptr< Node > &index_width, const std::shared_ptr< Node > &tag_width, const std::optional< std::shared_ptr< Node >> &ctrl_width)
Return a Fletcher command stream type.
std::shared_ptr< ClockDomain > kernel_cd()
Fletcher accelerator clock domain.
std::shared_ptr< Type > cr()
Fletcher clock/reset;.
@ STATUS
Register contents is controlled by hardware kernel.
std::shared_ptr< Axi4LitePort > axi4_lite(Port::Dir dir, const std::shared_ptr< ClockDomain > &domain, Axi4LiteSpec spec)
Make a new AXI4-lite port, returning a shared pointer to it.
@ BUFFER
Registers for buffer addresses.
@ PROFILE
Register for the profiler.
std::shared_ptr< Kernel > kernel(const std::string &name, const std::vector< std::shared_ptr< RecordBatch >> &recordbatches, const std::shared_ptr< Component > &mmio)
Make a kernel component based on RecordBatch and MMIO components.
bool ExposeToKernel(MmioFunction fun)
Return true if an mmio register's function must cause it to be exposed to the user kernel.
Component * accm()
Return the ArrayCmdCtrlMerger component.
std::shared_ptr< RecordBatch > record_batch(const std::string &name, const std::shared_ptr< FletcherSchema > &fletcher_schema, const fletcher::RecordBatchDescription &batch_desc)
Make a new RecordBatch(Reader/Writer) component, based on a Fletcher schema.
std::shared_ptr< ClockDomain > bus_cd()
Fletcher bus clock domain.
NodeProfilerPorts EnableStreamProfiling(cerata::Component *comp, const std::vector< cerata::Signal * > &profile_nodes)
Transforms a Cerata component graph to include stream profilers for selected nodes.
std::shared_ptr< FieldPort > command_port(const std::shared_ptr< FletcherSchema > &schema, const std::shared_ptr< arrow::Field > &field, const std::shared_ptr< Node > &index_width, const std::shared_ptr< Node > &tag_width, std::optional< std::shared_ptr< Node >> addr_width, const std::shared_ptr< ClockDomain > &domain)
Construct a field-derived command port.
std::shared_ptr< Component > mmio(const std::vector< fletcher::RecordBatchDescription > &batches, const std::vector< MmioReg > ®s, Axi4LiteSpec axi_spec)
Generate the MMIO component for the nucleus.
AXI4-lite bus specification.
A port derived from an Arrow field.
Function
Enumeration of FieldPort functions.
A port on the vhdmmio component. Remembers what register spec it came from.
void ProfileDataStreams(Instance *mmio_inst)
Profile any Arrow data streams that require profiling.
std::vector< FieldPort * > GetFieldPorts(FieldPort::Function fun) const
Return all field-derived ports with a specific function.
std::shared_ptr< Kernel > kernel
The kernel component.
Instance * kernel_inst
The kernel instance.
Nucleus(const std::string &name, const std::vector< std::shared_ptr< RecordBatch >> &recordbatches, const std::shared_ptr< Kernel > &kernel, const std::shared_ptr< Component > &mmio, Axi4LiteSpec axi_spec)
Construct a new Nucleus.