blob: dc95882198a66b54e985824868e66c4963a98402 [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%>\
7module top_earlgrey (
8 // Clock and Reset
9 input clk_i,
10 input rst_ni,
11
12 // JTAG interface
13 input jtag_tck_i,
14 input jtag_tms_i,
15 input jtag_trst_ni,
16 input jtag_td_i,
17 output jtag_td_o,
18
19% for m in top["module"]:
20 // ${m["name"]}
21% for p_in in m["available_input_list"] + m["available_inout_list"]:
22 ## assume it passed validate and have available input list always
23% if "width" in p_in and int(p_in["width"]) != 1:
24 input [${int(p_in["width"])-1}:0] cio_${m["name"]}_${p_in["name"]}_p2d_i,
25% else:
26 input cio_${m["name"]}_${p_in["name"]}_p2d_i,
27% endif
28% endfor
29% for p_out in m["available_output_list"] + m["available_inout_list"]:
30 ## assume it passed validate and have available output list always
31% if "width" in p_out and int(p_out["width"]) != 1:
32 output [${int(p_out["width"])-1}:0] cio_${m["name"]}_${p_out["name"]}_d2p_o,
33 output [${int(p_out["width"])-1}:0] cio_${m["name"]}_${p_out["name"]}_en_d2p_o,
34% else:
35 output cio_${m["name"]}_${p_out["name"]}_d2p_o,
36 output cio_${m["name"]}_${p_out["name"]}_en_d2p_o,
37% endif
38% endfor
39% endfor
40
41 input scanmode_i // 1 for Scan
42);
43
44 import tlul_pkg::*;
45 import top_pkg::*;
46 import tl_main_pkg::*;
47 import flash_ctrl_pkg::*;
48
49 tl_h2d_t tl_corei_h_h2d;
50 tl_d2h_t tl_corei_h_d2h;
51
52 tl_h2d_t tl_cored_h_h2d;
53 tl_d2h_t tl_cored_h_d2h;
54
55 tl_h2d_t tl_dm_sba_h_h2d;
56 tl_d2h_t tl_dm_sba_h_d2h;
57
58 tl_h2d_t tl_debug_mem_d_h2d;
59 tl_d2h_t tl_debug_mem_d_d2h;
60
61## TL-UL device port declaration
62% for m in top["module"]:
63% if not m["bus_device"] in ["none", ""]:
64 tl_h2d_t tl_${m["name"]}_d_h2d;
65 tl_d2h_t tl_${m["name"]}_d_d2h;
66% endif
67% if not m["bus_host"] in ["none", ""]:
68 tl_h2d_t tl_${m["name"]}_h_h2d;
69 tl_d2h_t tl_${m["name"]}_h_d2h;
70% endif
71% endfor
72
73% for m in top["memory"]:
74 tl_h2d_t tl_${m["name"]}_d_h2d;
75 tl_d2h_t tl_${m["name"]}_d_d2h;
76% endfor
77<%
78 interrupt_num = sum([x["width"] if "width" in x else 1 for x in top["interrupt"]])
79%>\
80 logic [${interrupt_num-1}:0] intr_vector;
81 // Interrupt source list
82% for m in top["module"]:
83 % for intr in m["interrupt_list"] if "interrupt_list" in m else []:
84 % if "width" in intr and int(intr["width"]) != 1:
85 logic [${int(intr["width"])-1}:0] intr_${m["name"]}_${intr["name"]};
86 % else:
87 logic intr_${m["name"]}_${intr["name"]};
88 % endif
89 % endfor
90% endfor
91
92
93 logic [0:0] irq_plic;
94 logic [${(interrupt_num).bit_length()-1}:0] irq_id[1];
95 logic [0:0] msip;
96
97 // Non-debug module reset == reset for everything except for the debug module
98 // and the logic required to access it.
99 logic ndmreset_n;
100 logic ndmreset_from_dm;
101 assign ndmreset_n = (scanmode_i) ? rst_ni : ~ndmreset_from_dm & rst_ni;
102
103 logic debug_req;
104
105 // processor core
106 rv_core_ibex #(
107 .MHPMCounterNum (8),
108 .MHPMCounterWidth (40),
109 .RV32E (0),
110 .RV32M (1),
111 .DmHaltAddr (ADDR_SPACE_DEBUG_MEM + dm::HaltAddress),
112 .DmExceptionAddr (ADDR_SPACE_DEBUG_MEM + dm::ExceptionAddress)
113 ) core (
114 // clock and reset
115 .clk_i (clk_i),
116 .rst_ni (ndmreset_n),
117 .test_en_i (1'b0),
118 // static pinning
Greg Chadwick53ef2ec2019-09-03 14:53:54 +0100119 .hart_id_i (32'b0),
lowRISC Contributors802543a2019-08-31 12:12:56 +0100120 .boot_addr_i (ADDR_SPACE_ROM),
121 // TL-UL buses
122 .tl_i_o (tl_corei_h_h2d),
123 .tl_i_i (tl_corei_h_d2h),
124 .tl_d_o (tl_cored_h_h2d),
125 .tl_d_i (tl_cored_h_d2h),
126 // interrupts
127 .irq_software_i (msip),
128 .irq_timer_i (intr_rv_timer_timer_expired_0_0),
129 .irq_external_i (irq_plic),
130 .irq_fast_i (15'b0),// PLIC handles all peripheral interrupts
131 .irq_nm_i (1'b0),// TODO - add and connect alert responder
132 // debug interface
133 .debug_req_i (debug_req),
134 // CPU control signals
135 .fetch_enable_i (1'b1)
136 );
137
138 // Debug Module (RISC-V Debug Spec 0.13)
139 //
140
141 rv_dm #(
142 .NrHarts ( 1),
143 .IdcodeValue (32'h00000001) // Temporary value
144 // xxxx version
145 // xxxxxxxxxxxxxxxx part number
146 // xxxxxxxxxxx manufacturer id
147 // 1 required by standard
148 ) u_dm_top (
149 .clk_i (clk_i),
150 .rst_ni (rst_ni),
151 .testmode_i (1'b0),
152 .ndmreset_o (ndmreset_from_dm),
153 .dmactive_o (),
154 .debug_req_o (debug_req),
155 .unavailable_i (1'b0),
156
157 // bus device with debug memory (for execution-based debug)
158 .tl_d_i (tl_debug_mem_d_h2d),
159 .tl_d_o (tl_debug_mem_d_d2h),
160
161 // bus host (for system bus accesses, SBA)
162 .tl_h_o (tl_dm_sba_h_h2d),
163 .tl_h_i (tl_dm_sba_h_d2h),
164
165 //JTAG
166 .tck_i (jtag_tck_i),
167 .tms_i (jtag_tms_i),
168 .trst_ni (jtag_trst_ni),
169 .td_i (jtag_td_i),
170 .td_o (jtag_td_o),
171 .tdo_oe_o ( )
172 );
173
174## Memory Instantiation
175% for m in top["memory"]:
176 % if m["type"] == "ram_1p":
177<%
178 data_width = int(top["datawidth"])
179 dw_byte = data_width // 8
180 addr_width = ((int(m["size"], 0) // dw_byte) -1).bit_length()
181 sram_depth = (int(m["size"], 0) // dw_byte)
182%>\
183 // sram device
184 logic ${m["name"]}_req;
185 logic ${m["name"]}_we;
186 logic [${addr_width-1}:0] ${m["name"]}_addr;
187 logic [${data_width-1}:0] ${m["name"]}_wdata;
188 logic [${data_width-1}:0] ${m["name"]}_wmask;
189 logic [${data_width-1}:0] ${m["name"]}_rdata;
190 logic ${m["name"]}_rvalid;
191
192 tlul_adapter_sram #(
193 .SramAw(${addr_width}),
194 .SramDw(${data_width}),
195 .Outstanding(1)
196 ) tl_adapter_${m["name"]} (
197 .clk_i,
198 .rst_ni (ndmreset_n),
199
200 .tl_i (tl_${m["name"]}_d_h2d),
201 .tl_o (tl_${m["name"]}_d_d2h),
202
203 .req_o (${m["name"]}_req),
204 .gnt_i (1'b1), // Always grant as only one requester exists
205 .we_o (${m["name"]}_we),
206 .addr_o (${m["name"]}_addr),
207 .wdata_o (${m["name"]}_wdata),
208 .wmask_o (${m["name"]}_wmask),
209 .rdata_i (${m["name"]}_rdata),
210 .rvalid_i (${m["name"]}_rvalid),
211 .rerror_i (2'b00)
212 );
213
214 ## TODO: Instantiate ram_1p model using RAMGEN (currently not available)
215 prim_ram_1p #(
216 .Width(${data_width}),
217 .Depth(${sram_depth}),
218 .DataBitsPerMask(${int(data_width/4)})
219 ) u_ram1p_${m["name"]} (
220 .clk_i,
221 .rst_ni (ndmreset_n),
222
223 .req_i (${m["name"]}_req),
224 .write_i (${m["name"]}_we),
225 .addr_i (${m["name"]}_addr),
226 .wdata_i (${m["name"]}_wdata),
227 .wmask_i (${m["name"]}_wmask),
228 .rvalid_o (${m["name"]}_rvalid),
229 .rdata_o (${m["name"]}_rdata)
230 );
231 % elif m["type"] == "rom":
232<%
233 data_width = int(top["datawidth"])
234 dw_byte = data_width // 8
235 addr_width = ((int(m["size"], 0) // dw_byte) -1).bit_length()
236 rom_depth = (int(m["size"], 0) // dw_byte)
237%>\
238 // ROM device
239 logic ${m["name"]}_req;
240 logic [${addr_width-1}:0] ${m["name"]}_addr;
241 logic [${data_width-1}:0] ${m["name"]}_rdata;
242 logic ${m["name"]}_rvalid;
243
244 tlul_adapter_sram #(
245 .SramAw(${addr_width}),
246 .SramDw(${data_width}),
Timothy Chen5aec5282019-09-10 21:10:56 -0700247 .Outstanding(1),
248 .ErrOnWrite(1)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100249 ) tl_adapter_${m["name"]} (
250 .clk_i,
251 .rst_ni (ndmreset_n),
252
253 .tl_i (tl_${m["name"]}_d_h2d),
254 .tl_o (tl_${m["name"]}_d_d2h),
255
256 .req_o (${m["name"]}_req),
257 .gnt_i (1'b1), // Always grant as only one requester exists
258 .we_o (),
259 .addr_o (${m["name"]}_addr),
260 .wdata_o (),
261 .wmask_o (),
262 .rdata_i (${m["name"]}_rdata),
263 .rvalid_i (${m["name"]}_rvalid),
264 .rerror_i (2'b00)
265 );
266
267 ## TODO: Replace emulated ROM to real ROM in ASIC SoC
268 prim_rom #(
269 .Width(${data_width}),
270 .Depth(${rom_depth})
271 ) u_rom_${m["name"]} (
272 .clk_i,
273 .cs_i (${m["name"]}_req),
274 .addr_i (${m["name"]}_addr),
275 .dout_o (${m["name"]}_rdata)
276 );
277
278 always_ff @(posedge clk_i) begin
279 ${m["name"]}_rvalid <= ${m["name"]}_req;
280 end
281 % elif m["type"] == "eflash":
282
283 // flash controller to eflash communication
284 flash_c2m_t flash_c2m;
285 flash_m2c_t flash_m2c;
286
287 // host to flash communication
288 logic flash_host_req;
289 logic flash_host_req_rdy;
290 logic flash_host_req_done;
291 logic [FLASH_DW-1:0] flash_host_rdata;
292 logic [FLASH_AW-1:0] flash_host_addr;
293
Timothy Chen5aec5282019-09-10 21:10:56 -0700294 tlul_adapter_sram #(
295 .SramAw(FLASH_AW),
296 .SramDw(FLASH_DW),
297 .Outstanding(1),
298 .ByteAccess(0),
299 .ErrOnWrite(1)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100300 ) tl_adapter_${m["name"]} (
301 .clk_i,
302 .rst_ni (ndmreset_n),
303
304 .tl_i (tl_${m["name"]}_d_h2d),
305 .tl_o (tl_${m["name"]}_d_d2h),
306
Timothy Chen5aec5282019-09-10 21:10:56 -0700307 .req_o (flash_host_req),
308 .gnt_i (flash_host_req_rdy),
309 .we_o (),
310 .addr_o (flash_host_addr),
311 .wdata_o (),
312 .wmask_o (),
313 .rdata_i (flash_host_rdata),
314 .rvalid_i (flash_host_req_done),
315 .rerror_i (2'b00)
lowRISC Contributors802543a2019-08-31 12:12:56 +0100316 );
317
318 flash_phy #(
319 .NumBanks(FLASH_BANKS),
320 .PagesPerBank(FLASH_PAGES_PER_BANK),
321 .WordsPerPage(FLASH_WORDS_PER_PAGE),
322 .DataWidth(${data_width})
323 ) u_flash_${m["name"]} (
324 .clk_i,
325 .rst_ni,
326 .host_req_i (flash_host_req),
327 .host_addr_i (flash_host_addr),
328 .host_req_rdy_o (flash_host_req_rdy),
329 .host_req_done_o (flash_host_req_done),
330 .host_rdata_o (flash_host_rdata),
331 .flash_ctrl_i (flash_c2m),
332 .flash_ctrl_o (flash_m2c)
333 );
334
335 % else:
336 // flash memory is embedded within controller
337 % endif
338% endfor
339
340## Peripheral Instantiation
341% for m in top["module"]:
342 % if "parameter" in m:
343 ${m["type"]} #(
344 % for k, v in m["parameter"].items():
345 % if loop.last:
346 .${k}(${parameterize(v)})
347 % else:
348 .${k}(${parameterize(v)}),
349 % endif
350 % endfor
351 ) ${m["name"]} (
352 % else:
353 ${m["type"]} ${m["name"]} (
354 % endif
355 % if not "bus_host" in m or m["bus_host"] in ["none", ""]:
356 ## Assume TL-UL
357 .tl_i (tl_${m["name"]}_d_h2d),
358 .tl_o (tl_${m["name"]}_d_d2h),
359 % else:
360 .tl_d_i (tl_${m["name"]}_d_h2d),
361 .tl_d_o (tl_${m["name"]}_d_d2h),
362 .tl_h_o (tl_${m["name"]}_h_h2d),
363 .tl_h_i (tl_${m["name"]}_h_d2h),
364 % endif
365 ## CIO
366 ## TODO: Find a way to handle `scanmode`. It is not cio_ but top-level signal
367 % for p_in in m["available_input_list"] + m["available_inout_list"]:
368 ## assume it passed validate and have available input list always
369 .cio_${p_in["name"]}_i (cio_${m["name"]}_${p_in["name"]}_p2d_i),
370 % endfor
371 % for p_in in m["available_output_list"] + m["available_inout_list"]:
372 ## assume it passed validate and have available output list always
373 .cio_${p_in["name"]}_o (cio_${m["name"]}_${p_in["name"]}_d2p_o),
374 .cio_${p_in["name"]}_en_o (cio_${m["name"]}_${p_in["name"]}_en_d2p_o),
375 % endfor
376 % for intr in m["interrupt_list"] if "interrupt_list" in m else []:
377 .intr_${intr["name"]}_o (intr_${m["name"]}_${intr["name"]}),
378 % endfor
379 % if m["type"] == "flash_ctrl":
380 .flash_o(flash_c2m),
381 .flash_i(flash_m2c),
382 % endif
383 % if m["type"] == "rv_plic":
384 .intr_src_i (intr_vector),
385 .irq_o (irq_plic),
386 .irq_id_o (irq_id),
387 .msip_o (msip),
388 % endif
389 .clk_i(${"clk_i" if m["clock"] == "main" else "clk_"+ m["clock"] + "_i"}),
390 .rst_ni(${"ndmreset_n" if m["clock"] == "main" else "rst_" + m["clock"] + "_ni"})
391 );
392
393% endfor
394 // interrupt assignments
395 assign intr_vector = {
396 % for intr in top["interrupt"][::-1]:
397 % if loop.last:
398 intr_${intr["name"]}
399 % else:
400 intr_${intr["name"]},
401 % endif
402 % endfor
403 };
404
405 // TL-UL Crossbar
406 logic clk_main;
407 logic ndmreset_sync_main_n; // ndmreset synchronized to clk_main
408
409 assign clk_main = clk_i;
410 assign ndmreset_sync_main_n = ndmreset_n;
411
412% for xbar in top["xbar"]:
413<%
414 name_len = max([len(x["name"]) for x in xbar["nodes"]]);
415%>\
416 xbar_${xbar["name"]} u_xbar_${xbar["name"]} (
417 % for clock in xbar["clocks"]:
418 ## TODO: How we can handle the reset?
419 .clk_${clock}_i (clk_${clock}),
420 .rst_${clock}_ni (ndmreset_sync_${clock}_n),
421 % endfor
422
423 % for node in xbar["nodes"]:
424 % if node["type"] == "device":
425 .tl_${(node["name"]+"_o").ljust(name_len+2)} (tl_${node["name"]}_d_h2d),
426 .tl_${(node["name"]+"_i").ljust(name_len+2)} (tl_${node["name"]}_d_d2h),
427 % elif node["type"] == "host":
428 .tl_${(node["name"]+"_i").ljust(name_len+2)} (tl_${node["name"]}_h_h2d),
429 .tl_${(node["name"]+"_o").ljust(name_len+2)} (tl_${node["name"]}_h_d2h),
430 % endif
431 % endfor
432
433 .scanmode_i
434% endfor
435 );
436
437endmodule
438<%def name="parameterize(v)">\
439 ## value type
440 ## if it is integer, or bit'{h|d|b} digit, just put without quote
441 ## else return with quote
442 % if re.match('(\d+\'[hdb]\s*[0-9a-f_A-F]+|[0-9]+)',v) == None:
443"${v}"\
444 % else:
445${v}\
446 % endif
447</%def>\