blob: 8ce39f85a6e8c3d693cb66b1d67ff49ae3808b98 [file] [log] [blame]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001// Copyright lowRISC contributors.
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5<% import re
6%>\
Eunchan Kim632c6f72019-09-30 11:11:51 -07007module top_${top["name"]} #(
Timothy Chen7ff53122019-09-19 15:20:43 -07008 parameter bit IbexPipeLine = 0
9) (
lowRISC Contributors802543a2019-08-31 12:12:56 +010010 // Clock and Reset
11 input clk_i,
12 input rst_ni,
13
14 // JTAG interface
15 input jtag_tck_i,
16 input jtag_tms_i,
17 input jtag_trst_ni,
18 input jtag_td_i,
19 output jtag_td_o,
20
21% for m in top["module"]:
22 // ${m["name"]}
23% for p_in in m["available_input_list"] + m["available_inout_list"]:
24 ## assume it passed validate and have available input list always
25% if "width" in p_in and int(p_in["width"]) != 1:
26 input [${int(p_in["width"])-1}:0] cio_${m["name"]}_${p_in["name"]}_p2d_i,
27% else:
28 input cio_${m["name"]}_${p_in["name"]}_p2d_i,
29% endif
30% endfor
31% for p_out in m["available_output_list"] + m["available_inout_list"]:
32 ## assume it passed validate and have available output list always
33% if "width" in p_out and int(p_out["width"]) != 1:
34 output [${int(p_out["width"])-1}:0] cio_${m["name"]}_${p_out["name"]}_d2p_o,
35 output [${int(p_out["width"])-1}:0] cio_${m["name"]}_${p_out["name"]}_en_d2p_o,
36% else:
37 output cio_${m["name"]}_${p_out["name"]}_d2p_o,
38 output cio_${m["name"]}_${p_out["name"]}_en_d2p_o,
39% endif
40% endfor
41% endfor
42
43 input scanmode_i // 1 for Scan
44);
45
46 import tlul_pkg::*;
47 import top_pkg::*;
48 import tl_main_pkg::*;
49 import flash_ctrl_pkg::*;
50
51 tl_h2d_t tl_corei_h_h2d;
52 tl_d2h_t tl_corei_h_d2h;
53
54 tl_h2d_t tl_cored_h_h2d;
55 tl_d2h_t tl_cored_h_d2h;
56
57 tl_h2d_t tl_dm_sba_h_h2d;
58 tl_d2h_t tl_dm_sba_h_d2h;
59
60 tl_h2d_t tl_debug_mem_d_h2d;
61 tl_d2h_t tl_debug_mem_d_d2h;
62
63## TL-UL device port declaration
64% for m in top["module"]:
65% if not m["bus_device"] in ["none", ""]:
66 tl_h2d_t tl_${m["name"]}_d_h2d;
67 tl_d2h_t tl_${m["name"]}_d_d2h;
68% endif
69% if not m["bus_host"] in ["none", ""]:
70 tl_h2d_t tl_${m["name"]}_h_h2d;
71 tl_d2h_t tl_${m["name"]}_h_d2h;
72% endif
73% endfor
74
75% for m in top["memory"]:
76 tl_h2d_t tl_${m["name"]}_d_h2d;
77 tl_d2h_t tl_${m["name"]}_d_d2h;
78% endfor
Timothy Chen3193b002019-10-04 16:56:05 -070079
80 //reset wires declaration
81% for reset in top['resets']:
82 logic ${reset['name']}_rst_n;
83% endfor
84
lowRISC Contributors802543a2019-08-31 12:12:56 +010085<%
86 interrupt_num = sum([x["width"] if "width" in x else 1 for x in top["interrupt"]])
87%>\
88 logic [${interrupt_num-1}:0] intr_vector;
89 // Interrupt source list
90% for m in top["module"]:
91 % for intr in m["interrupt_list"] if "interrupt_list" in m else []:
92 % if "width" in intr and int(intr["width"]) != 1:
93 logic [${int(intr["width"])-1}:0] intr_${m["name"]}_${intr["name"]};
94 % else:
95 logic intr_${m["name"]}_${intr["name"]};
96 % endif
97 % endfor
98% endfor
99
100
101 logic [0:0] irq_plic;
102 logic [${(interrupt_num).bit_length()-1}:0] irq_id[1];
103 logic [0:0] msip;
104
lowRISC Contributors802543a2019-08-31 12:12:56 +0100105
Timothy Chen3193b002019-10-04 16:56:05 -0700106 // Non-debug module reset == reset for everything except for the debug module
107 logic ndmreset_req;
108
109 // root resets
110 // TODO: lc_rst_n is not the true root reset. It will be differentiated once the
111 // the reset controller logic is present
112 assign lc_rst_n = rst_ni;
113 assign sys_rst_n = (scanmode_i) ? lc_rst_n : ~ndmreset_req & lc_rst_n;
114
115 //non-root reset assignments
116% for reset in top['resets']:
117 % if reset['type'] in ['leaf']:
118 assign ${reset['name']}_rst_n = ${reset['root']}_rst_n;
119 % endif
120% endfor
121
122 // debug request from rv_dm to core
lowRISC Contributors802543a2019-08-31 12:12:56 +0100123 logic debug_req;
124
125 // processor core
126 rv_core_ibex #(
127 .MHPMCounterNum (8),
128 .MHPMCounterWidth (40),
129 .RV32E (0),
130 .RV32M (1),
131 .DmHaltAddr (ADDR_SPACE_DEBUG_MEM + dm::HaltAddress),
Timothy Chen7ff53122019-09-19 15:20:43 -0700132 .DmExceptionAddr (ADDR_SPACE_DEBUG_MEM + dm::ExceptionAddress),
133 .PipeLine (IbexPipeLine)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100134 ) core (
135 // clock and reset
136 .clk_i (clk_i),
Timothy Chen3193b002019-10-04 16:56:05 -0700137 .rst_ni (sys_rst_n),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100138 .test_en_i (1'b0),
139 // static pinning
Greg Chadwick53ef2ec2019-09-03 14:53:54 +0100140 .hart_id_i (32'b0),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100141 .boot_addr_i (ADDR_SPACE_ROM),
142 // TL-UL buses
143 .tl_i_o (tl_corei_h_h2d),
144 .tl_i_i (tl_corei_h_d2h),
145 .tl_d_o (tl_cored_h_h2d),
146 .tl_d_i (tl_cored_h_d2h),
147 // interrupts
148 .irq_software_i (msip),
149 .irq_timer_i (intr_rv_timer_timer_expired_0_0),
150 .irq_external_i (irq_plic),
151 .irq_fast_i (15'b0),// PLIC handles all peripheral interrupts
152 .irq_nm_i (1'b0),// TODO - add and connect alert responder
153 // debug interface
154 .debug_req_i (debug_req),
155 // CPU control signals
Pirmin Vogelffc9e832019-09-13 16:16:05 +0100156 .fetch_enable_i (1'b1),
157 .core_sleep_o ()
lowRISC Contributors802543a2019-08-31 12:12:56 +0100158 );
159
160 // Debug Module (RISC-V Debug Spec 0.13)
161 //
162
163 rv_dm #(
164 .NrHarts ( 1),
165 .IdcodeValue (32'h00000001) // Temporary value
166 // xxxx version
167 // xxxxxxxxxxxxxxxx part number
168 // xxxxxxxxxxx manufacturer id
169 // 1 required by standard
170 ) u_dm_top (
171 .clk_i (clk_i),
Timothy Chen3193b002019-10-04 16:56:05 -0700172 .rst_ni (lc_rst_n),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100173 .testmode_i (1'b0),
Timothy Chen3193b002019-10-04 16:56:05 -0700174 .ndmreset_o (ndmreset_req),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100175 .dmactive_o (),
176 .debug_req_o (debug_req),
177 .unavailable_i (1'b0),
178
179 // bus device with debug memory (for execution-based debug)
180 .tl_d_i (tl_debug_mem_d_h2d),
181 .tl_d_o (tl_debug_mem_d_d2h),
182
183 // bus host (for system bus accesses, SBA)
184 .tl_h_o (tl_dm_sba_h_h2d),
185 .tl_h_i (tl_dm_sba_h_d2h),
186
187 //JTAG
188 .tck_i (jtag_tck_i),
189 .tms_i (jtag_tms_i),
190 .trst_ni (jtag_trst_ni),
191 .td_i (jtag_td_i),
192 .td_o (jtag_td_o),
193 .tdo_oe_o ( )
194 );
195
196## Memory Instantiation
197% for m in top["memory"]:
Timothy Chen3193b002019-10-04 16:56:05 -0700198<%
199 resets = m['reset_connections']
200%>\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100201 % if m["type"] == "ram_1p":
202<%
203 data_width = int(top["datawidth"])
204 dw_byte = data_width // 8
205 addr_width = ((int(m["size"], 0) // dw_byte) -1).bit_length()
206 sram_depth = (int(m["size"], 0) // dw_byte)
Timothy Chen3193b002019-10-04 16:56:05 -0700207
lowRISC Contributors802543a2019-08-31 12:12:56 +0100208%>\
209 // sram device
210 logic ${m["name"]}_req;
211 logic ${m["name"]}_we;
212 logic [${addr_width-1}:0] ${m["name"]}_addr;
213 logic [${data_width-1}:0] ${m["name"]}_wdata;
214 logic [${data_width-1}:0] ${m["name"]}_wmask;
215 logic [${data_width-1}:0] ${m["name"]}_rdata;
216 logic ${m["name"]}_rvalid;
217
218 tlul_adapter_sram #(
219 .SramAw(${addr_width}),
220 .SramDw(${data_width}),
221 .Outstanding(1)
222 ) tl_adapter_${m["name"]} (
223 .clk_i,
Timothy Chen3193b002019-10-04 16:56:05 -0700224 % for key in resets:
225 .${key} (${resets[key]}_rst_n),
226 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100227 .tl_i (tl_${m["name"]}_d_h2d),
228 .tl_o (tl_${m["name"]}_d_d2h),
229
230 .req_o (${m["name"]}_req),
231 .gnt_i (1'b1), // Always grant as only one requester exists
232 .we_o (${m["name"]}_we),
233 .addr_o (${m["name"]}_addr),
234 .wdata_o (${m["name"]}_wdata),
235 .wmask_o (${m["name"]}_wmask),
236 .rdata_i (${m["name"]}_rdata),
237 .rvalid_i (${m["name"]}_rvalid),
238 .rerror_i (2'b00)
239 );
240
241 ## TODO: Instantiate ram_1p model using RAMGEN (currently not available)
242 prim_ram_1p #(
243 .Width(${data_width}),
244 .Depth(${sram_depth}),
245 .DataBitsPerMask(${int(data_width/4)})
246 ) u_ram1p_${m["name"]} (
247 .clk_i,
Timothy Chen3193b002019-10-04 16:56:05 -0700248 % for key in resets:
249 .${key} (${resets[key]}_rst_n),
250 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100251
252 .req_i (${m["name"]}_req),
253 .write_i (${m["name"]}_we),
254 .addr_i (${m["name"]}_addr),
255 .wdata_i (${m["name"]}_wdata),
256 .wmask_i (${m["name"]}_wmask),
257 .rvalid_o (${m["name"]}_rvalid),
258 .rdata_o (${m["name"]}_rdata)
259 );
260 % elif m["type"] == "rom":
261<%
262 data_width = int(top["datawidth"])
263 dw_byte = data_width // 8
264 addr_width = ((int(m["size"], 0) // dw_byte) -1).bit_length()
265 rom_depth = (int(m["size"], 0) // dw_byte)
266%>\
267 // ROM device
268 logic ${m["name"]}_req;
269 logic [${addr_width-1}:0] ${m["name"]}_addr;
270 logic [${data_width-1}:0] ${m["name"]}_rdata;
271 logic ${m["name"]}_rvalid;
272
273 tlul_adapter_sram #(
274 .SramAw(${addr_width}),
275 .SramDw(${data_width}),
Timothy Chen5aec5282019-09-10 21:10:56 -0700276 .Outstanding(1),
277 .ErrOnWrite(1)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100278 ) tl_adapter_${m["name"]} (
279 .clk_i,
Timothy Chen3193b002019-10-04 16:56:05 -0700280 % for key in resets:
281 .${key} (${resets[key]}_rst_n),
282 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100283
284 .tl_i (tl_${m["name"]}_d_h2d),
285 .tl_o (tl_${m["name"]}_d_d2h),
286
287 .req_o (${m["name"]}_req),
288 .gnt_i (1'b1), // Always grant as only one requester exists
289 .we_o (),
290 .addr_o (${m["name"]}_addr),
291 .wdata_o (),
292 .wmask_o (),
293 .rdata_i (${m["name"]}_rdata),
294 .rvalid_i (${m["name"]}_rvalid),
295 .rerror_i (2'b00)
296 );
297
298 ## TODO: Replace emulated ROM to real ROM in ASIC SoC
299 prim_rom #(
300 .Width(${data_width}),
301 .Depth(${rom_depth})
302 ) u_rom_${m["name"]} (
303 .clk_i,
Timothy Chen3193b002019-10-04 16:56:05 -0700304 % for key in resets:
305 .${key} (${resets[key]}_rst_n),
306 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100307 .cs_i (${m["name"]}_req),
308 .addr_i (${m["name"]}_addr),
Timothy Chen44461032019-09-20 15:35:20 -0700309 .dout_o (${m["name"]}_rdata),
310 .dvalid_o (${m["name"]}_rvalid)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100311 );
312
lowRISC Contributors802543a2019-08-31 12:12:56 +0100313 % elif m["type"] == "eflash":
314
315 // flash controller to eflash communication
316 flash_c2m_t flash_c2m;
317 flash_m2c_t flash_m2c;
318
319 // host to flash communication
320 logic flash_host_req;
321 logic flash_host_req_rdy;
322 logic flash_host_req_done;
323 logic [FLASH_DW-1:0] flash_host_rdata;
324 logic [FLASH_AW-1:0] flash_host_addr;
325
Timothy Chen5aec5282019-09-10 21:10:56 -0700326 tlul_adapter_sram #(
327 .SramAw(FLASH_AW),
328 .SramDw(FLASH_DW),
329 .Outstanding(1),
330 .ByteAccess(0),
331 .ErrOnWrite(1)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100332 ) tl_adapter_${m["name"]} (
333 .clk_i,
Timothy Chen3193b002019-10-04 16:56:05 -0700334 % for key in resets:
335 .${key} (${resets[key]}_rst_n),
336 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100337
338 .tl_i (tl_${m["name"]}_d_h2d),
339 .tl_o (tl_${m["name"]}_d_d2h),
340
Timothy Chen5aec5282019-09-10 21:10:56 -0700341 .req_o (flash_host_req),
342 .gnt_i (flash_host_req_rdy),
343 .we_o (),
344 .addr_o (flash_host_addr),
345 .wdata_o (),
346 .wmask_o (),
347 .rdata_i (flash_host_rdata),
348 .rvalid_i (flash_host_req_done),
349 .rerror_i (2'b00)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100350 );
351
352 flash_phy #(
353 .NumBanks(FLASH_BANKS),
354 .PagesPerBank(FLASH_PAGES_PER_BANK),
355 .WordsPerPage(FLASH_WORDS_PER_PAGE),
356 .DataWidth(${data_width})
357 ) u_flash_${m["name"]} (
358 .clk_i,
Timothy Chen3193b002019-10-04 16:56:05 -0700359 % for key in resets:
360 .${key} (${resets[key]}_rst_n),
361 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100362 .host_req_i (flash_host_req),
363 .host_addr_i (flash_host_addr),
364 .host_req_rdy_o (flash_host_req_rdy),
365 .host_req_done_o (flash_host_req_done),
366 .host_rdata_o (flash_host_rdata),
367 .flash_ctrl_i (flash_c2m),
368 .flash_ctrl_o (flash_m2c)
369 );
370
371 % else:
372 // flash memory is embedded within controller
373 % endif
374% endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100375## Peripheral Instantiation
Timothy Chen3193b002019-10-04 16:56:05 -0700376
lowRISC Contributors802543a2019-08-31 12:12:56 +0100377% for m in top["module"]:
Timothy Chen3193b002019-10-04 16:56:05 -0700378<%
379
380%>\
lowRISC Contributors802543a2019-08-31 12:12:56 +0100381 % if "parameter" in m:
382 ${m["type"]} #(
383 % for k, v in m["parameter"].items():
384 % if loop.last:
385 .${k}(${parameterize(v)})
386 % else:
387 .${k}(${parameterize(v)}),
388 % endif
389 % endfor
390 ) ${m["name"]} (
391 % else:
392 ${m["type"]} ${m["name"]} (
393 % endif
394 % if not "bus_host" in m or m["bus_host"] in ["none", ""]:
395 ## Assume TL-UL
396 .tl_i (tl_${m["name"]}_d_h2d),
397 .tl_o (tl_${m["name"]}_d_d2h),
398 % else:
399 .tl_d_i (tl_${m["name"]}_d_h2d),
400 .tl_d_o (tl_${m["name"]}_d_d2h),
401 .tl_h_o (tl_${m["name"]}_h_h2d),
402 .tl_h_i (tl_${m["name"]}_h_d2h),
403 % endif
404 ## CIO
405 ## TODO: Find a way to handle `scanmode`. It is not cio_ but top-level signal
406 % for p_in in m["available_input_list"] + m["available_inout_list"]:
407 ## assume it passed validate and have available input list always
408 .cio_${p_in["name"]}_i (cio_${m["name"]}_${p_in["name"]}_p2d_i),
409 % endfor
410 % for p_in in m["available_output_list"] + m["available_inout_list"]:
411 ## assume it passed validate and have available output list always
412 .cio_${p_in["name"]}_o (cio_${m["name"]}_${p_in["name"]}_d2p_o),
413 .cio_${p_in["name"]}_en_o (cio_${m["name"]}_${p_in["name"]}_en_d2p_o),
414 % endfor
415 % for intr in m["interrupt_list"] if "interrupt_list" in m else []:
416 .intr_${intr["name"]}_o (intr_${m["name"]}_${intr["name"]}),
417 % endfor
418 % if m["type"] == "flash_ctrl":
419 .flash_o(flash_c2m),
420 .flash_i(flash_m2c),
421 % endif
422 % if m["type"] == "rv_plic":
423 .intr_src_i (intr_vector),
424 .irq_o (irq_plic),
425 .irq_id_o (irq_id),
426 .msip_o (msip),
427 % endif
Timothy Chen3193b002019-10-04 16:56:05 -0700428
Eunchan Kim2cfadab2019-10-02 12:41:11 -0700429 % if m["scan"] == "true":
430 .scanmode_i (scanmode_i),
431 % endif
Timothy Chen3193b002019-10-04 16:56:05 -0700432 .clk_i (${"clk_i" if m["clock"] == "main" else "clk_"+ m["clock"] + "_i"}),
433 % for k, v in m["reset_connections"].items():
434 % if loop.last:
435 .${k} (${v}_rst_n)
436 % else:
437 .${k} (${v}_rst_n),
438 % endif
439 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100440 );
441
442% endfor
443 // interrupt assignments
444 assign intr_vector = {
445 % for intr in top["interrupt"][::-1]:
446 % if loop.last:
447 intr_${intr["name"]}
448 % else:
449 intr_${intr["name"]},
450 % endif
451 % endfor
452 };
453
454 // TL-UL Crossbar
455 logic clk_main;
lowRISC Contributors802543a2019-08-31 12:12:56 +0100456 assign clk_main = clk_i;
Timothy Chen3193b002019-10-04 16:56:05 -0700457
lowRISC Contributors802543a2019-08-31 12:12:56 +0100458
459% for xbar in top["xbar"]:
460<%
461 name_len = max([len(x["name"]) for x in xbar["nodes"]]);
462%>\
463 xbar_${xbar["name"]} u_xbar_${xbar["name"]} (
464 % for clock in xbar["clocks"]:
lowRISC Contributors802543a2019-08-31 12:12:56 +0100465 .clk_${clock}_i (clk_${clock}),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100466 % endfor
Timothy Chen3193b002019-10-04 16:56:05 -0700467 % for k, v in xbar["reset_connections"].items():
468 .${k} (${v}_rst_n),
469 % endfor
lowRISC Contributors802543a2019-08-31 12:12:56 +0100470 % for node in xbar["nodes"]:
471 % if node["type"] == "device":
472 .tl_${(node["name"]+"_o").ljust(name_len+2)} (tl_${node["name"]}_d_h2d),
473 .tl_${(node["name"]+"_i").ljust(name_len+2)} (tl_${node["name"]}_d_d2h),
474 % elif node["type"] == "host":
475 .tl_${(node["name"]+"_i").ljust(name_len+2)} (tl_${node["name"]}_h_h2d),
476 .tl_${(node["name"]+"_o").ljust(name_len+2)} (tl_${node["name"]}_h_d2h),
477 % endif
478 % endfor
479
480 .scanmode_i
481% endfor
482 );
483
Nils Graf78607aa2019-09-16 15:47:23 -0700484 // make sure scanmode_i is never X (including during reset)
485 `ASSERT_KNOWN(scanmodeKnown, scanmode_i, clk_i, 0)
486
lowRISC Contributors802543a2019-08-31 12:12:56 +0100487endmodule
488<%def name="parameterize(v)">\
489 ## value type
490 ## if it is integer, or bit'{h|d|b} digit, just put without quote
491 ## else return with quote
492 % if re.match('(\d+\'[hdb]\s*[0-9a-f_A-F]+|[0-9]+)',v) == None:
493"${v}"\
494 % else:
495${v}\
496 % endif
497</%def>\