Fletchgen
The Fletcher Design Generator
sim_template.h
1 // Copyright 2018-2019 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 #pragma once
16 
17 namespace fletchgen::top {
18 
19 // TODO(johanpel): Insert this template through resource linking.
21 static char sim_source[] =
22  "-- Copyright 2018-2019 Delft University of Technology\n"
23  "--\n"
24  "-- Licensed under the Apache License, Version 2.0 (the \"License\");\n"
25  "-- you may not use this file except in compliance with the License.\n"
26  "-- You may obtain a copy of the License at\n"
27  "--\n"
28  "-- http://www.apache.org/licenses/LICENSE-2.0\n"
29  "--\n"
30  "-- Unless required by applicable law or agreed to in writing, software\n"
31  "-- distributed under the License is distributed on an \"AS IS\" BASIS,\n"
32  "-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
33  "-- See the License for the specific language governing permissions and\n"
34  "-- limitations under the License.\n"
35  "\n"
36  "library ieee;\n"
37  "use ieee.std_logic_1164.all;\n"
38  "use ieee.numeric_std.all;\n"
39  "use ieee.std_logic_misc.all;\n"
40  "\n"
41  "library work;\n"
42  "use work.Interconnect_pkg.all;\n"
43  "use work.UtilStr_pkg.all;\n"
44  "use work.UtilConv_pkg.all;\n"
45  "\n"
46  "entity SimTop_tc is\n"
47  " generic (\n"
48  " -- Accelerator properties\n"
49  " INDEX_WIDTH : natural := 32;\n"
50  " TAG_WIDTH : natural := 1;\n"
51  "\n"
52  " -- Host bus properties\n"
53  " BUS_ADDR_WIDTH : natural := ${BUS_ADDR_WIDTH};\n"
54  " BUS_DATA_WIDTH : natural := ${BUS_DATA_WIDTH};\n"
55  " BUS_LEN_WIDTH : natural := ${BUS_LEN_WIDTH};\n"
56  " BUS_BURST_MAX_LEN : natural := ${BUS_BURST_MAX_LEN};\n"
57  " BUS_BURST_STEP_LEN : natural := ${BUS_BURST_STEP_LEN}\n"
58  " );\n"
59  "end SimTop_tc;\n"
60  "\n"
61  "architecture Behavorial of SimTop_tc is\n"
62  "\n"
63  " -----------------------------------------------------------------------------\n"
64  " -- Default wrapper component.\n"
65  " -----------------------------------------------------------------------------\n"
66  " ${MANTLE_DECL}"
67  " -----------------------------------------------------------------------------\n"
68  "\n"
69  " -- Fletcher defaults\n"
70  " constant REG_CONTROL : natural := 0;\n"
71  " constant REG_STATUS : natural := 1;\n"
72  " constant REG_RETURN0 : natural := 2;\n"
73  " constant REG_RETURN1 : natural := 3;\n"
74  "\n"
75  " constant CONTROL_CLEAR : std_logic_vector(31 downto 0) := X\"00000000\";\n"
76  " constant CONTROL_START : std_logic_vector(31 downto 0) := X\"00000001\";\n"
77  " constant CONTROL_STOP : std_logic_vector(31 downto 0) := X\"00000002\";\n"
78  " constant CONTROL_RESET : std_logic_vector(31 downto 0) := X\"00000004\";\n"
79  "\n"
80  " constant STATUS_IDLE : std_logic_vector(31 downto 0) := X\"00000001\";\n"
81  " constant STATUS_BUSY : std_logic_vector(31 downto 0) := X\"00000002\";\n"
82  " constant STATUS_DONE : std_logic_vector(31 downto 0) := X\"00000004\";\n"
83  "\n"
84  " -- Sim signals\n"
85  " signal clock_stop : boolean := false;\n"
86  "\n"
87  " -- Accelerator signals\n"
88  " signal kcd_clk : std_logic;\n"
89  " signal kcd_reset : std_logic;\n"
90  "\n"
91  " -- Fletcher bus signals\n"
92  " signal bcd_clk : std_logic;\n"
93  " signal bcd_reset : std_logic;\n"
94  "\n"
95  " -- External signals\n"
96  "${EXTERNAL_SIG_DECL}"
97  "\n"
98  " -- MMIO signals\n"
99  " signal mmio_awvalid : std_logic := '0';\n"
100  " signal mmio_awready : std_logic := '0';\n"
101  " signal mmio_awaddr : std_logic_vector(${MMIO_ADDR_WIDTH}-1 downto 0);\n"
102  " signal mmio_wvalid : std_logic := '0';\n"
103  " signal mmio_wready : std_logic := '0';\n"
104  " signal mmio_wdata : std_logic_vector(${MMIO_DATA_WIDTH}-1 downto 0);\n"
105  " signal mmio_wstrb : std_logic_vector(${MMIO_DATA_WIDTH}/8-1 downto 0);\n"
106  " signal mmio_bvalid : std_logic := '0';\n"
107  " signal mmio_bready : std_logic := '0';\n"
108  " signal mmio_bresp : std_logic_vector(1 downto 0);\n"
109  " signal mmio_arvalid : std_logic := '0';\n"
110  " signal mmio_arready : std_logic := '0';\n"
111  " signal mmio_araddr : std_logic_vector(${MMIO_ADDR_WIDTH}-1 downto 0);\n"
112  " signal mmio_rvalid : std_logic := '0';\n"
113  " signal mmio_rready : std_logic := '0';\n"
114  " signal mmio_rdata : std_logic_vector(${MMIO_DATA_WIDTH}-1 downto 0);\n"
115  " signal mmio_rresp : std_logic_vector(1 downto 0);\n"
116  "\n"
117  " -- Mmio signals to source in mmio procedures.\n"
118  " type mmio_source_t is record\n"
119  " awvalid : std_logic;\n"
120  " awaddr : std_logic_vector(${MMIO_ADDR_WIDTH}-1 downto 0);\n"
121  " wvalid : std_logic;\n"
122  " wdata : std_logic_vector(${MMIO_DATA_WIDTH}-1 downto 0);\n"
123  " wstrb : std_logic_vector(${MMIO_DATA_WIDTH}/8-1 downto 0);\n"
124  " bready : std_logic;\n"
125  "\n"
126  " arvalid : std_logic;\n"
127  " araddr : std_logic_vector(${MMIO_ADDR_WIDTH}-1 downto 0);\n"
128  " rready : std_logic;\n"
129  " end record;\n"
130  "\n"
131  " -- Mmio signals to sink in mmio procedures\n"
132  " type mmio_sink_t is record\n"
133  " wready : std_logic;\n"
134  "\n"
135  " awready : std_logic;\n"
136  "\n"
137  " bvalid : std_logic;\n"
138  " bresp : std_logic_vector(1 downto 0);\n"
139  "\n"
140  " arready : std_logic;\n"
141  "\n"
142  " rvalid : std_logic;\n"
143  " rdata : std_logic_vector(${MMIO_DATA_WIDTH}-1 downto 0);\n"
144  " rresp : std_logic_vector(1 downto 0);\n"
145  " end record;\n"
146  "\n"
147  " signal mmio_source : mmio_source_t;\n"
148  " signal mmio_sink : mmio_sink_t;\n"
149  "\n"
150  " -- Memory interface signals\n"
151  " signal bus_rreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n"
152  " signal bus_rreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n"
153  " signal bus_rreq_valid : std_logic;\n"
154  " signal bus_rreq_ready : std_logic;\n"
155  " signal bus_rdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n"
156  " signal bus_rdat_last : std_logic;\n"
157  " signal bus_rdat_valid : std_logic;\n"
158  " signal bus_rdat_ready : std_logic;\n"
159  " signal bus_wreq_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);\n"
160  " signal bus_wreq_last : std_logic;\n"
161  " signal bus_wreq_len : std_logic_vector(BUS_LEN_WIDTH-1 downto 0);\n"
162  " signal bus_wreq_valid : std_logic;\n"
163  " signal bus_wreq_ready : std_logic;\n"
164  " signal bus_wdat_data : std_logic_vector(BUS_DATA_WIDTH-1 downto 0);\n"
165  " signal bus_wdat_strobe : std_logic_vector(BUS_DATA_WIDTH/8-1 downto 0);\n"
166  " signal bus_wdat_last : std_logic;\n"
167  " signal bus_wdat_valid : std_logic;\n"
168  " signal bus_wdat_ready : std_logic;\n"
169  " signal bus_wrep_ok : std_logic;\n"
170  " signal bus_wrep_valid : std_logic;\n"
171  " signal bus_wrep_ready : std_logic;\n"
172  "\n"
173  " procedure mmio_write32 (constant idx : in natural;\n"
174  " constant data : in std_logic_vector(31 downto 0);\n"
175  " signal source : out mmio_source_t;\n"
176  " signal sink : in mmio_sink_t;\n"
177  " signal clk : in std_logic;\n"
178  " signal reset : in std_logic)\n"
179  " is\n"
180  " begin\n"
181  " -- Wait for reset\n"
182  " loop\n"
183  " exit when reset = '0';\n"
184  " wait until rising_edge(clk);\n"
185  " end loop;\n"
186  " -- Address write channel\n"
187  " source.awaddr <= slv(${MMIO_OFFSET} + (32/8)*idx, ${MMIO_ADDR_WIDTH});\n"
188  " source.awvalid <= '1';\n"
189  " loop\n"
190  " wait until rising_edge(clk);\n"
191  " exit when sink.awready = '1';\n"
192  " end loop;\n"
193  " source.awvalid <= '0';\n"
194  " source.awaddr <= (others => 'U');\n"
195  " -- Write channel\n"
196  " source.wdata${MMIO_RW_DATA_RANGE} <= data;\n"
197  " source.wstrb <= ${MMIO_STRB};\n"
198  " source.wvalid <= '1';\n"
199  " loop\n"
200  " wait until rising_edge(clk);\n"
201  " exit when sink.wready = '1';\n"
202  " end loop;\n"
203  " source.wvalid <= '0';\n"
204  " source.wdata <= (others => 'U');\n"
205  " source.wstrb <= (others => 'U');\n"
206  " -- Write response channel.\n"
207  " source.bready <= '1';\n"
208  " loop\n"
209  " wait until rising_edge(clk);\n"
210  " exit when sink.bvalid = '1';\n"
211  " end loop;\n"
212  " source.bready <= '0';\n"
213  " end procedure;\n"
214  "\n"
215  " procedure mmio_read32(constant idx : in natural;\n"
216  " variable data : out std_logic_vector(31 downto 0);\n"
217  " signal source : out mmio_source_t;\n"
218  " signal sink : in mmio_sink_t;\n"
219  " signal clk : in std_logic;\n"
220  " signal reset : in std_logic)\n"
221  " is\n"
222  " begin\n"
223  " -- Wait for reset\n"
224  " loop\n"
225  " exit when reset = '0';\n"
226  " wait until rising_edge(clk);\n"
227  " end loop;\n"
228  " -- Address read channel\n"
229  " source.araddr <= slv(${MMIO_OFFSET} + (32/8)*idx, ${MMIO_ADDR_WIDTH});\n"
230  " source.arvalid <= '1';\n"
231  " loop\n"
232  " wait until rising_edge(clk);\n"
233  " exit when sink.arready = '1';\n"
234  " end loop;\n"
235  " source.arvalid <= '0';\n"
236  " source.araddr <= (others => 'U');\n"
237  " -- Read channel\n"
238  " loop\n"
239  " source.rready <= '1';\n"
240  " wait until rising_edge(clk);\n"
241  " if sink.rvalid = '1' then\n"
242  " data := sink.rdata${MMIO_RW_DATA_RANGE};\n"
243  " exit;\n"
244  " end if;\n"
245  " end loop;\n"
246  " source.rready <= '0';\n"
247  " end procedure;\n"
248  "\n"
249  "\n"
250  "begin\n"
251  "\n"
252  " -- Connect to records for easier readibility downstream.\n"
253  " mmio_awvalid <= mmio_source.awvalid;\n"
254  " mmio_awaddr <= mmio_source.awaddr;\n"
255  " mmio_wvalid <= mmio_source.wvalid;\n"
256  " mmio_wdata <= mmio_source.wdata;\n"
257  " mmio_wstrb <= mmio_source.wstrb;\n"
258  " mmio_bready <= mmio_source.bready;\n"
259  " mmio_arvalid <= mmio_source.arvalid;\n"
260  " mmio_araddr <= mmio_source.araddr;\n"
261  " mmio_rready <= mmio_source.rready;\n"
262  "\n"
263  " mmio_sink.wready <= mmio_wready;\n"
264  " mmio_sink.awready <= mmio_awready;\n"
265  " mmio_sink.bvalid <= mmio_bvalid;\n"
266  " mmio_sink.bresp <= mmio_bresp;\n"
267  " mmio_sink.arready <= mmio_arready;\n"
268  " mmio_sink.rvalid <= mmio_rvalid;\n"
269  " mmio_sink.rdata <= mmio_rdata;\n"
270  " mmio_sink.rresp <= mmio_rresp;\n"
271  "\n"
272  "\n"
273  " -- Typical stimuli process:\n"
274  " stimuli_proc : process is\n"
275  " variable read_data : std_logic_vector(31 downto 0) := X\"DEADBEEF\";\n"
276  " variable read_data_masked : std_logic_vector(31 downto 0);\n"
277  " begin\n"
278  " mmio_source.awvalid <= '0';\n"
279  " mmio_source.wvalid <= '0';\n"
280  " mmio_source.bready <= '0';\n"
281  "\n"
282  " mmio_source.arvalid <= '0';\n"
283  " mmio_source.rready <= '0';\n"
284  "\n"
285  " wait until kcd_reset = '1' and bcd_reset = '1';\n"
286  "\n"
287  " -- 1. Reset the user core\n"
288  " mmio_write32(REG_CONTROL, CONTROL_RESET, mmio_source, mmio_sink, bcd_clk, bcd_reset);\n"
289  "\n"
290  " -- 2. Write addresses of the arrow buffers in the SREC file.\n"
291  "${SREC_BUFFER_ADDRESSES}\n"
292  " -- 3. Write recordbatch bounds.\n"
293  "${SREC_FIRSTLAST_INDICES}\n"
294  " -- 4. Write any kernel-specific registers.\n"
295  "${KERNEL_REGS_INIT}\n"
296  " -- 5. Start the kernel.\n"
297  "${PROFILE_START}"
298  " mmio_write32(REG_CONTROL, CONTROL_START, mmio_source, mmio_sink, bcd_clk, bcd_reset);\n"
299  "\n"
300  " -- 6. Poll for completion\n"
301  " loop\n"
302  " -- Wait a bunch of cycles.\n"
303  " for I in 0 to 8 loop\n"
304  " wait until rising_edge(bcd_clk);\n"
305  " end loop;\n"
306  "\n"
307  " -- Read the status register.\n"
308  " mmio_read32(REG_STATUS, read_data, mmio_source, mmio_sink, bcd_clk, bcd_reset);\n"
309  "\n"
310  " -- Check if we're done.\n"
311  " read_data_masked := read_data and STATUS_DONE;\n"
312  " exit when read_data_masked = STATUS_DONE;\n"
313  " end loop;\n"
314  "\n"
315  "${PROFILE_STOP}\n"
316  " -- 7. Read return register.\n"
317  " mmio_read32(REG_RETURN0, read_data, mmio_source, mmio_sink, bcd_clk, bcd_reset);\n"
318  " println(\"Return register 0: \" & slvToHex(read_data));\n"
319  " mmio_read32(REG_RETURN1, read_data, mmio_source, mmio_sink, bcd_clk, bcd_reset);\n"
320  " println(\"Return register 1: \" & slvToHex(read_data));\n"
321  "\n"
322  " -- 8. Read profile registers.\n"
323  "${PROFILE_READ}\n"
324  " -- 9. Finish and stop simulation.\n"
325  " report \"Stimuli done.\";\n"
326  " clock_stop <= true;\n"
327  "\n"
328  " wait;\n"
329  " end process;\n"
330  "\n"
331  " clk_proc: process is\n"
332  " begin\n"
333  " if not clock_stop then\n"
334  " kcd_clk <= '1';\n"
335  " bcd_clk <= '1';\n"
336  " wait for 5 ns;\n"
337  " kcd_clk <= '0';\n"
338  " bcd_clk <= '0';\n"
339  " wait for 5 ns;\n"
340  " else\n"
341  " wait;\n"
342  " end if;\n"
343  " end process;\n"
344  "\n"
345  " reset_proc: process is\n"
346  " begin\n"
347  " kcd_reset <= '1';\n"
348  " bcd_reset <= '1';\n"
349  " wait for 50 ns;\n"
350  " wait until rising_edge(kcd_clk);\n"
351  " kcd_reset <= '0';\n"
352  " bcd_reset <= '0';\n"
353  " wait;\n"
354  " end process;\n"
355  "\n"
356  "${BUS_READ_SLAVE_MOCK}\n"
357  "${BUS_WRITE_SLAVE_MOCK}\n"
358  "\n"
359  "\n"
360  " -----------------------------------------------------------------------------\n"
361  " -- Fletcher generated wrapper\n"
362  " -----------------------------------------------------------------------------\n"
363  " ${FLETCHER_WRAPPER_INST_NAME} : ${FLETCHER_WRAPPER_NAME}\n"
364  " generic map (\n"
365  " BUS_ADDR_WIDTH => BUS_ADDR_WIDTH,\n"
366  " BUS_DATA_WIDTH => BUS_DATA_WIDTH,\n"
367  " BUS_BURST_STEP_LEN => BUS_BURST_STEP_LEN,\n"
368  " BUS_BURST_MAX_LEN => BUS_ADDR_WIDTH,\n"
369  " BUS_LEN_WIDTH => BUS_LEN_WIDTH,\n"
370  " INDEX_WIDTH => INDEX_WIDTH,\n"
371  " TAG_WIDTH => TAG_WIDTH\n"
372  " )\n"
373  " port map (\n"
374  " kcd_clk => kcd_clk,\n"
375  " kcd_reset => kcd_reset,\n"
376  " bcd_clk => bcd_clk,\n"
377  " bcd_reset => bcd_reset,\n"
378  "${EXTERNAL_INST_MAP}\n"
379  "${MST_RREQ_INSTANTIATE}\n"
380  "${MST_WREQ_INSTANTIATE}\n"
381  " mmio_awvalid => mmio_awvalid,\n"
382  " mmio_awready => mmio_awready,\n"
383  " mmio_awaddr => mmio_awaddr,\n"
384  " mmio_wvalid => mmio_wvalid,\n"
385  " mmio_wready => mmio_wready,\n"
386  " mmio_wdata => mmio_wdata,\n"
387  " mmio_wstrb => mmio_wstrb,\n"
388  " mmio_bvalid => mmio_bvalid,\n"
389  " mmio_bready => mmio_bready,\n"
390  " mmio_bresp => mmio_bresp,\n"
391  " mmio_arvalid => mmio_arvalid,\n"
392  " mmio_arready => mmio_arready,\n"
393  " mmio_araddr => mmio_araddr,\n"
394  " mmio_rvalid => mmio_rvalid,\n"
395  " mmio_rready => mmio_rready,\n"
396  " mmio_rdata => mmio_rdata,\n"
397  " mmio_rresp => mmio_rresp\n"
398  " );\n"
399  "\n"
400  "end architecture;\n";
401 
402 } // namespace fletchgen::top