15 #include "fletchgen/bus.h"
17 #include <cerata/api.h>
18 #include <cerata/vhdl/vhdl.h>
23 #include "fletchgen/basic_types.h"
27 using cerata::PortArray;
29 using cerata::integer;
31 using cerata::boolean;
35 using cerata::component;
36 using cerata::parameter;
42 PARAM_FACTORY(bus_addr_width)
43 PARAM_FACTORY(bus_data_width)
44 PARAM_FACTORY(bus_len_width)
45 PARAM_FACTORY(bus_burst_step_len)
46 PARAM_FACTORY(bus_burst_max_len)
49 std::shared_ptr<Type>
bus_read(const std::shared_ptr<Node> &addr_width,
50 const std::shared_ptr<Node> &data_width,
51 const std::shared_ptr<Node> &len_width) {
52 auto rreq = stream(record(
"", {field(
"addr", vector(addr_width)),
53 field(
"len", vector(len_width))}));
54 auto rdat = stream(record(
"", {field(
"data", vector(data_width)),
55 field(
"last",
last())}));
56 auto result = record(
"", {field(
"rreq", rreq),
57 field(
"rdat", rdat)->Reverse()});
61 std::shared_ptr<Type>
bus_write(
const std::shared_ptr<Node> &addr_width,
62 const std::shared_ptr<Node> &data_width,
63 const std::shared_ptr<Node> &len_width) {
64 auto wreq = stream(record(
"", {field(
"addr", vector(addr_width)),
65 field(
"len", vector(len_width)),
66 field(
"last",
last())}));
67 auto wdat = stream(record(
"", {field(
"data", vector(data_width)),
68 field(
"strobe", vector(data_width / 8)),
69 field(
"last",
last())}));
70 auto wrep = stream(record(
"", {field(
"ok", bit())}));
71 auto result = record(
"", {field(
"wreq", wreq),
73 field(
"wrep", wrep)->Reverse()});
77 static std::string GetBusArbiterName(
BusFunction function) {
84 auto name = GetBusArbiterName(
function);
87 auto optional_existing_comp = cerata::default_component_pool()->Get(name);
88 if (optional_existing_comp) {
89 return *optional_existing_comp;
93 auto result = component(name);
100 result->Remove(params.
bs.get());
101 result->Remove(params.
bm.get());
103 auto num_slv = parameter(
"NUM_SLAVE_PORTS", 0);
105 result->Add(num_slv);
107 auto empty_str = strl(
"");
109 result->Add({parameter(
"ARB_METHOD", std::string(
"RR-STICKY")),
110 parameter(
"MAX_OUTSTANDING", 4),
111 parameter(
"RAM_CONFIG", std::string(
"")),
112 parameter(
"SLV_REQ_SLICES",
true),
113 parameter(
"MST_REQ_SLICE",
true),
114 parameter(
"MST_DAT_SLICE",
true),
115 parameter(
"SLV_DAT_SLICES",
true)
119 auto clk_rst = port(
"bcd",
cr(), Port::Dir::IN,
bus_cd());
121 auto mst =
bus_port(
"mst", Port::Dir::OUT, spec);
123 auto slv_base =
bus_port(
"slv", Port::Dir::OUT, spec);
124 slv_base->SetName(
"bsv");
126 auto slv_arr = port_array(slv_base, num_slv);
128 result->Add({clk_rst, mst, slv_arr});
131 result->SetMeta(cerata::vhdl::meta::PRIMITIVE,
"true");
132 result->SetMeta(cerata::vhdl::meta::LIBRARY,
"work");
133 result->SetMeta(cerata::vhdl::meta::PACKAGE,
"Interconnect_pkg");
139 auto aw = parameter(
"ADDR_WIDTH", integer());
140 auto mdw = parameter(
"MASTER_DATA_WIDTH", integer());
141 auto mlw = parameter(
"MASTER_LEN_WIDTH", integer());
142 auto sdw = parameter(
"SLAVE_DATA_WIDTH", integer());
143 auto slw = parameter(
"SLAVE_LEN_WIDTH", integer());
144 static auto ret = component(
"BusReadSerializer", {
145 aw, mdw, mlw, sdw, slw,
146 parameter(
"SLAVE_MAX_BURST", integer()),
147 parameter(
"ENABLE_FIFO",
boolean(), booll(
false)),
148 parameter(
"SLV_REQ_SLICE_DEPTH", integer(), intl(2)),
149 parameter(
"SLV_DAT_SLICE_DEPTH", integer(), intl(2)),
150 parameter(
"MST_REQ_SLICE_DEPTH", integer(), intl(2)),
151 parameter(
"MST_DAT_SLICE_DEPTH", integer(), intl(2)),
152 port(
"bcd",
cr(), Port::Dir::IN,
bus_cd()),
153 port(
"mst",
bus_read(aw, mlw, mdw), Port::Dir::OUT),
154 port(
"slv",
bus_read(aw, slw, sdw), Port::Dir::OUT),
156 ret->SetMeta(cerata::vhdl::meta::PRIMITIVE,
"true");
157 ret->SetMeta(cerata::vhdl::meta::LIBRARY,
"work");
158 ret->SetMeta(cerata::vhdl::meta::PACKAGE,
"Interconnect_pkg");
167 std::shared_ptr<Type> result;
176 return std::make_shared<BusPort>(name, dir, params);
180 return std::make_shared<BusPort>(params.
ToName(), dir, params);
183 #define BUS_PARAM_CONNECTION_FACTORY(NAME, ABBR) \
184 auto ABBR##_name = prefix + NAME()->name(); \
185 if (dst->Has(ABBR##_name)) { \
186 auto dst_##ABBR = dst->par(ABBR##_name); \
187 Connect(dst_##ABBR, src.ABBR); \
188 (*rebinding)[src.ABBR.get()] = dst_##ABBR; \
192 const std::string &prefix,
194 cerata::NodeMap *rebinding) {
195 BUS_PARAM_CONNECTION_FACTORY(bus_addr_width, aw)
196 BUS_PARAM_CONNECTION_FACTORY(bus_data_width, dw)
197 BUS_PARAM_CONNECTION_FACTORY(bus_len_width, lw)
198 BUS_PARAM_CONNECTION_FACTORY(bus_burst_step_len, bs)
199 BUS_PARAM_CONNECTION_FACTORY(bus_burst_max_len, bm)
202 #undef BUS_PARAM_CONNECTION_FACTORY
205 return (lhs.
aw == rhs.
aw) && (lhs.
dw == rhs.
dw) && (lhs.
lw == rhs.
lw) && (lhs.
bs == rhs.
bs) && (lhs.
bm == rhs.
bm);
211 auto typ = type()->shared_from_this();
212 result->SetType(typ);
217 std::stringstream str;
218 str <<
"AW" << std::to_string(
aw);
219 str <<
"DW" << std::to_string(
dw);
220 str <<
"LW" << std::to_string(
lw);
221 str <<
"BS" << std::to_string(
bs);
222 str <<
"BM" << std::to_string(
bm);
226 static std::vector<int64_t> ParseCSV(std::string str) {
227 std::vector<int64_t> result;
230 while ((pos = str.find(
',')) != std::string::npos) {
231 result.push_back(std::strtoul(str.substr(0, pos).c_str(),
nullptr, 10));
232 str.erase(0, pos + 1);
238 BusDim result = default_to;
240 auto values = ParseCSV(str);
241 if (values.size() != 5) {
242 FLETCHER_LOG(FATAL,
"Bus dimensions string is invalid: " + str
243 +
". Expected: <address width>,<data width>,<len width>,<min burst>,<max burst>");
245 result.
aw =
static_cast<uint32_t
>(values[0]);
246 result.
dw =
static_cast<uint32_t
>(values[1]);
247 result.
lw =
static_cast<uint32_t
>(values[2]);
248 result.
bs =
static_cast<uint32_t
>(values[3]);
249 result.
bm =
static_cast<uint32_t
>(values[4]);
255 std::stringstream str;
256 str <<
"address width: " << std::to_string(
aw);
257 str <<
", data width: " << std::to_string(
dw);
258 str <<
", burst length width: " << std::to_string(
lw);
259 str <<
", minimum burst size: " << std::to_string(
bs);
260 str <<
", maximum burst size: " << std::to_string(
bm);
265 return std::vector<std::shared_ptr<Object>>({
aw,
dw,
lw,
bs,
bm});
269 aw = bus_addr_width(dim.
aw, prefix);
270 dw = bus_data_width(dim.
dw, prefix);
271 lw = bus_len_width(dim.
lw, prefix);
272 bs = bus_burst_step_len(dim.
bs, prefix);
273 bm = bus_burst_max_len(dim.
bm, prefix);
Contains all classes and functions related to Fletchgen.
std::shared_ptr< Type > bus_write(const std::shared_ptr< Node > &addr_width, const std::shared_ptr< Node > &data_width, const std::shared_ptr< Node > &len_width)
Return a Cerata type for a Fletcher bus write interface.
std::shared_ptr< Type > bus_read(const std::shared_ptr< Node > &addr_width, const std::shared_ptr< Node > &data_width, const std::shared_ptr< Node > &len_width)
Return a Cerata type for a Fletcher bus read interface.
std::shared_ptr< Type > cr()
Fletcher clock/reset;.
std::shared_ptr< Component > BusReadSerializer()
Return a BusReadSerializer component.
Component * bus_arbiter(BusFunction function)
Return a Cerata model of a BusArbiter.
std::shared_ptr< Type > bus(const BusSpecParams &spec)
Fletcher bus type with access mode conveyed through spec of params.
void ConnectBusParam(cerata::Graph *dst, const std::string &prefix, const BusDimParams &src, cerata::NodeMap *rebinding)
Find and connect all prefixed bus params on a graph to the supplied source params,...
std::shared_ptr< ClockDomain > bus_cd()
Fletcher bus clock domain.
std::shared_ptr< Type > last(int width, bool on_primitive)
Fletcher last.
std::shared_ptr< BusPort > bus_port(const std::string &name, Port::Dir dir, const BusSpecParams ¶ms)
Make a new port and return a shared pointer to it.
bool operator==(const BusSpec &lhs, const BusSpec &rhs)
Returns true if BusSpecs are equal.
BusFunction
Defines function of a bus interface (read/write).
@ READ
Interface reads from memory.
Holds bus interface dimensions.
std::string ToString() const
Return a human-readable version of the bus dimensions.
std::string ToName() const
Return a shorter somewhat human-readable name for this BusDims, can be used for comparisons.
static BusDim FromString(const std::string &str, BusDim default_to)
Returns a BusDim from a string. See [common/cpp/include/fletcher/arrow-utils.h] for more info.
uint32_t bs
Burst step length.
uint32_t aw
Address width.
uint32_t bm
Burst max length.
Holds bus parameters based on bus dimensions, that has actual nodes representing the dimensions.
std::shared_ptr< Node > aw
Value nodes.
std::shared_ptr< Node > lw
Len width node.
BusDimParams(cerata::Graph *parent, BusDim dim=BusDim{}, const std::string &prefix="")
Construct a new bunch of bus parameters based on a bus spec and function, and add them to a graph.
std::shared_ptr< Node > dw
Data width node.
std::vector< std::shared_ptr< Object > > all() const
Return all parameters as an object vector.
std::shared_ptr< Node > bs
Burst step length node.
std::shared_ptr< Node > bm
Burst max length node.
std::shared_ptr< Object > Copy() const override
Deep-copy the BusPort.
BusSpecParams spec_
The bus spec to which the type generics of the bus port are bound.
Holds bus dimensions and function, without instantiating Cerata nodes.
std::string ToName() const
Return a shorter somewhat human-readable name, can be used for comparisons.
BusDim dim
Bus dimensions.
BusFunction func
Bus function.
Holds bus parameters and function based on bus dimensions, that has actual nodes representing the dim...
std::string ToName() const
Return a shorter somewhat human-readable name, can be used for comparisons.
BusFunction func
Bus function.
BusDimParams dim
Bus dimensions.