15 #include "fletchgen/top/axi.h"
17 #include <cerata/api.h>
18 #include <cerata/vhdl/vhdl.h>
21 #include <cerata/api.h>
22 #include <cerata/vhdl/vhdl.h>
24 #include "fletchgen/top/axi_template.h"
25 #include "fletchgen/mantle.h"
27 namespace fletchgen::top {
29 using cerata::vhdl::Template;
31 std::string GenerateAXITop(
const Mantle &
mantle,
32 const SchemaSet &schema_set,
33 Axi4LiteSpec axi_spec,
34 std::optional<std::shared_ptr<Type>> external,
35 const std::vector<std::ostream *> &outputs) {
37 auto t = Template::FromString(axi_source);
40 t.Replace(
"BUS_ADDR_WIDTH", 64);
41 t.Replace(
"BUS_DATA_WIDTH", 512);
42 t.Replace(
"BUS_LEN_WIDTH", 8);
43 t.Replace(
"BUS_BURST_STEP_LEN", 1);
44 t.Replace(
"BUS_BURST_MAX_LEN", 64);
47 t.Replace(
"MMIO_ADDR_WIDTH", axi_spec.addr_width);
48 t.Replace(
"MMIO_DATA_WIDTH", axi_spec.data_width);
51 t.Replace(
"FLETCHER_WRAPPER_NAME",
mantle.name());
52 t.Replace(
"FLETCHER_WRAPPER_INST_NAME",
mantle.name() +
"_inst");
54 if (schema_set.RequiresReading()) {
55 t.Replace(
"MST_RREQ_DECLARE",
56 " rd_mst_rreq_valid : out std_logic;\n"
57 " rd_mst_rreq_ready : in std_logic;\n"
58 " rd_mst_rreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n"
59 " rd_mst_rreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n"
60 " rd_mst_rdat_valid : in std_logic;\n"
61 " rd_mst_rdat_ready : out std_logic;\n"
62 " rd_mst_rdat_data : in std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n"
63 " rd_mst_rdat_last : in std_logic;\n");
65 t.Replace(
"MST_RREQ_INSTANTIATE",
66 " rd_mst_rreq_valid => rd_mst_rreq_valid,\n"
67 " rd_mst_rreq_ready => rd_mst_rreq_ready,\n"
68 " rd_mst_rreq_addr => rd_mst_rreq_addr,\n"
69 " rd_mst_rreq_len => rd_mst_rreq_len,\n"
70 " rd_mst_rdat_valid => rd_mst_rdat_valid,\n"
71 " rd_mst_rdat_ready => rd_mst_rdat_ready,\n"
72 " rd_mst_rdat_data => rd_mst_rdat_data,\n"
73 " rd_mst_rdat_last => rd_mst_rdat_last,");
75 t.Replace(
"AXI_READ_CONVERTER",
76 " -----------------------------------------------------------------------------\n"
77 " -- AXI read converter\n"
78 " -----------------------------------------------------------------------------\n"
79 " -- Buffering bursts is disabled (ENABLE_FIFO=false) because BufferReaders\n"
80 " -- are already able to absorb full bursts.\n"
81 " axi_read_conv_inst: AxiReadConverter\n"
83 " ADDR_WIDTH => BUS_ADDR_WIDTH,\n"
84 " MASTER_DATA_WIDTH => BUS_DATA_WIDTH,\n"
85 " MASTER_LEN_WIDTH => BUS_LEN_WIDTH,\n"
86 " SLAVE_DATA_WIDTH => BUS_DATA_WIDTH,\n"
87 " SLAVE_LEN_WIDTH => BUS_LEN_WIDTH,\n"
88 " SLAVE_MAX_BURST => BUS_BURST_MAX_LEN,\n"
89 " ENABLE_FIFO => false,\n"
90 " SLV_REQ_SLICE_DEPTH => 0,\n"
91 " SLV_DAT_SLICE_DEPTH => 0,\n"
92 " MST_REQ_SLICE_DEPTH => 0,\n"
93 " MST_DAT_SLICE_DEPTH => 0\n"
97 " reset_n => bcd_reset_n,\n"
98 " slv_bus_rreq_addr => rd_mst_rreq_addr,\n"
99 " slv_bus_rreq_len => rd_mst_rreq_len,\n"
100 " slv_bus_rreq_valid => rd_mst_rreq_valid,\n"
101 " slv_bus_rreq_ready => rd_mst_rreq_ready,\n"
102 " slv_bus_rdat_data => rd_mst_rdat_data,\n"
103 " slv_bus_rdat_last => rd_mst_rdat_last,\n"
104 " slv_bus_rdat_valid => rd_mst_rdat_valid,\n"
105 " slv_bus_rdat_ready => rd_mst_rdat_ready,\n"
106 " m_axi_araddr => m_axi_araddr,\n"
107 " m_axi_arlen => m_axi_arlen,\n"
108 " m_axi_arvalid => m_axi_arvalid,\n"
109 " m_axi_arready => m_axi_arready,\n"
110 " m_axi_arsize => m_axi_arsize,\n"
111 " m_axi_rdata => m_axi_rdata,\n"
112 " m_axi_rlast => m_axi_rlast,\n"
113 " m_axi_rvalid => m_axi_rvalid,\n"
114 " m_axi_rready => m_axi_rready\n"
117 t.Replace(
"MST_RREQ_DECLARE",
"");
118 t.Replace(
"MST_RREQ_INSTANTIATE",
"");
119 t.Replace(
"AXI_READ_CONVERTER",
"");
122 if (schema_set.RequiresWriting()) {
123 t.Replace(
"MST_WREQ_DECLARE",
124 " wr_mst_wreq_valid : out std_logic;\n"
125 " wr_mst_wreq_ready : in std_logic;\n"
126 " wr_mst_wreq_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n"
127 " wr_mst_wreq_len : out std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n"
128 " wr_mst_wreq_last : out std_logic;\n"
129 " wr_mst_wdat_valid : out std_logic;\n"
130 " wr_mst_wdat_ready : in std_logic;\n"
131 " wr_mst_wdat_data : out std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n"
132 " wr_mst_wdat_strobe : out std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0);\n"
133 " wr_mst_wdat_last : out std_logic;"
134 " wr_mst_wrep_valid : in std_logic;"
135 " wr_mst_wrep_ready : out std_logic;"
136 " wr_mst_wrep_ok : in std_logic;"
139 t.Replace(
"MST_WREQ_INSTANTIATE",
140 " wr_mst_wreq_valid => wr_mst_wreq_valid,\n"
141 " wr_mst_wreq_ready => wr_mst_wreq_ready,\n"
142 " wr_mst_wreq_addr => wr_mst_wreq_addr,\n"
143 " wr_mst_wreq_len => wr_mst_wreq_len,\n"
144 " wr_mst_wreq_last => wr_mst_wreq_last,\n"
145 " wr_mst_wdat_valid => wr_mst_wdat_valid,\n"
146 " wr_mst_wdat_ready => wr_mst_wdat_ready,\n"
147 " wr_mst_wdat_data => wr_mst_wdat_data,\n"
148 " wr_mst_wdat_strobe => wr_mst_wdat_strobe,\n"
149 " wr_mst_wdat_last => wr_mst_wdat_last,\n"
150 " wr_mst_wrep_valid => wr_mst_wrep_valid,\n"
151 " wr_mst_wrep_ready => wr_mst_wrep_ready,\n"
152 " wr_mst_wrep_ok => wr_mst_wrep_ok,");
154 t.Replace(
"AXI_WRITE_CONVERTER",
155 " -----------------------------------------------------------------------------\n"
156 " -- AXI write converter\n"
157 " -----------------------------------------------------------------------------\n"
158 " -- Buffering bursts is disabled (ENABLE_FIFO=false) because BufferWriters\n"
159 " -- are already able to absorb full bursts.\n"
160 " axi_write_conv_inst: AxiWriteConverter\n"
162 " ADDR_WIDTH => BUS_ADDR_WIDTH,\n"
163 " MASTER_DATA_WIDTH => BUS_DATA_WIDTH,\n"
164 " MASTER_LEN_WIDTH => BUS_LEN_WIDTH,\n"
165 " SLAVE_DATA_WIDTH => BUS_DATA_WIDTH,\n"
166 " SLAVE_LEN_WIDTH => BUS_LEN_WIDTH,\n"
167 " SLAVE_MAX_BURST => BUS_BURST_MAX_LEN,\n"
168 " ENABLE_FIFO => false,\n"
169 " SLV_REQ_SLICE_DEPTH => 0,\n"
170 " SLV_DAT_SLICE_DEPTH => 0,\n"
171 " MST_REQ_SLICE_DEPTH => 0,\n"
172 " MST_DAT_SLICE_DEPTH => 0\n"
176 " reset_n => bcd_reset_n,\n"
177 " slv_bus_wreq_addr => wr_mst_wreq_addr,\n"
178 " slv_bus_wreq_len => wr_mst_wreq_len,\n"
179 " slv_bus_wreq_valid => wr_mst_wreq_valid,\n"
180 " slv_bus_wreq_ready => wr_mst_wreq_ready,\n"
181 " slv_bus_wreq_last => wr_mst_wreq_last,\n"
182 " slv_bus_wdat_data => wr_mst_wdat_data,\n"
183 " slv_bus_wdat_strobe => wr_mst_wdat_strobe,\n"
184 " slv_bus_wdat_last => wr_mst_wdat_last,\n"
185 " slv_bus_wdat_valid => wr_mst_wdat_valid,\n"
186 " slv_bus_wdat_ready => wr_mst_wdat_ready,\n"
187 " slv_bus_wrep_valid => wr_mst_wrep_valid,\n"
188 " slv_bus_wrep_ready => wr_mst_wrep_ready,\n"
189 " slv_bus_wrep_ok => wr_mst_wrep_ok,\n"
190 " m_axi_awaddr => m_axi_awaddr,\n"
191 " m_axi_awlen => m_axi_awlen,\n"
192 " m_axi_awvalid => m_axi_awvalid,\n"
193 " m_axi_awready => m_axi_awready,\n"
194 " m_axi_awsize => m_axi_awsize,\n"
195 " m_axi_awuser => m_axi_awuser,\n"
196 " m_axi_wdata => m_axi_wdata,\n"
197 " m_axi_wstrb => m_axi_wstrb,\n"
198 " m_axi_wlast => m_axi_wlast,\n"
199 " m_axi_wvalid => m_axi_wvalid,\n"
200 " m_axi_wready => m_axi_wready,\n"
201 " m_axi_bvalid => m_axi_bvalid,\n"
202 " m_axi_bready => m_axi_bready,\n"
203 " m_axi_bresp => m_axi_bresp\n"
206 t.Replace(
"MST_WREQ_DECLARE",
"");
207 t.Replace(
"MST_WREQ_INSTANTIATE",
"");
208 t.Replace(
"AXI_WRITE_CONVERTER",
"");
211 t.Replace(
"MANTLE_DECL", cerata::vhdl::Decl::Generate(
mantle,
false, 1).ToString());
214 auto p_mantle = cerata::port(
"ext", external.value(), cerata::Port::Dir::OUT);
215 auto p_top = cerata::port(
"ext", external.value(), cerata::Port::Dir::OUT);
216 cerata::Connect(p_top, p_mantle);
218 auto decl_block = cerata::vhdl::Decl::Generate(*p_mantle, 2);
220 auto inst_block = cerata::vhdl::Inst::GeneratePortMaps(*p_mantle);
221 inst_block.indent = 3;
224 t.Replace(
"EXTERNAL_PORT_DECL", decl_block.ToString());
225 t.Replace(
"EXTERNAL_INST_MAP", inst_block.ToString());
227 t.Replace(
"EXTERNAL_PORT_DECL",
"");
228 t.Replace(
"EXTERNAL_INST_MAP",
"");
231 for (
auto &o : outputs) {
std::shared_ptr< Mantle > mantle(const std::string &name, const std::vector< std::shared_ptr< RecordBatch >> &recordbatches, const std::shared_ptr< Nucleus > &nucleus, BusDim bus_spec, Axi4LiteSpec axi_spec)
Construct a Mantle and return a shared pointer to it.