blob: be7766a86bca740102b008bbb4c59480be858375 [file] [log] [blame]
Sylvain Munaut21b03ba2020-09-14 10:01:45 +02001/*
2 * soc_base.v
3 *
4 * vim: ts=4 sw=4
5 *
6 * Minimal common base for the E1 project SoC
7 *
8 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
9 * SPDX-License-Identifier: CERN-OHL-S-2.0
10 */
11
12`default_nettype none
13
14module soc_base #(
15 parameter integer WB_N = 1,
16 parameter integer E1_N = 1,
17 parameter E1_UNIT_HAS_RX = 1'b1,
18 parameter E1_UNIT_HAS_TX = 1'b1,
19 parameter integer E1_LIU = 0
20)(
21 // E1 pads
22 // Raw PHY
23 input wire [E1_N-1:0] e1_rx_hi_p,
24 input wire [E1_N-1:0] e1_rx_hi_n,
25 input wire [E1_N-1:0] e1_rx_lo_p,
26 input wire [E1_N-1:0] e1_rx_lo_n,
27
28 output wire [E1_N-1:0] e1_tx_hi,
29 output wire [E1_N-1:0] e1_tx_lo,
30
31 // LIU
32 input wire [E1_N-1:0] e1_rx_data,
33 input wire [E1_N-1:0] e1_rx_clk,
34
35 output wire [E1_N-1:0] e1_tx_data,
36 output wire [E1_N-1:0] e1_tx_clk,
37
38 // USB
39 inout wire usb_dp,
40 inout wire usb_dn,
41 output wire usb_pu,
42
43 // Flash SPI (raw)
44 input wire flash_mosi_i,
45 output wire flash_mosi_o,
46 output wire flash_mosi_oe,
47
48 input wire flash_miso_i,
49 output wire flash_miso_o,
50 output wire flash_miso_oe,
51
52 input wire flash_clk_i,
53 output wire flash_clk_o,
54 output wire flash_clk_oe,
55
56 output wire flash_csn_o,
57
58 // Debug UART
59 input wire dbg_rx,
60 output wire dbg_tx,
61
62 // RGB LEDs
63 output wire [2:0] rgb,
64
65 // External Master Wishbone bus (CPU -> Peripheral)
66 output wire [15:0] wb_m_addr,
67 input wire [(WB_N*32)-1:0] wb_m_rdata,
68 output wire [31:0] wb_m_wdata,
69 output wire [ 3:0] wb_m_wmsk,
70 output wire wb_m_we,
71 output wire [ WB_N -1:0] wb_m_cyc,
72 input wire [ WB_N -1:0] wb_m_ack,
73
74 // Ticks
Sylvain Munaut60f664f2024-04-29 16:14:54 +020075 output wire [4*E1_N-1:0] tick_e1,
76 output wire tick_usb_sof,
Sylvain Munaut21b03ba2020-09-14 10:01:45 +020077
78 // Clock / Reset
79 input wire clk_sys,
80 input wire rst_sys,
81 input wire clk_48m,
82 input wire rst_48m
83);
84
85 genvar i;
86
87 localparam integer WB_LN = 8;
88 localparam integer WB_TN = WB_N + WB_LN;
89 localparam integer WB_DW = 32;
90 localparam integer WB_MW = WB_DW / 8;
91 localparam integer WB_AW = 16;
92 localparam integer WB_AI = 2;
93
94
95 // Signals
96 // -------
97
98 // Picorv32 native bus
99 wire pb_valid;
100 wire pb_instr;
101 wire pb_ready;
102 wire [31:0] pb_addr;
103 wire [31:0] pb_rdata;
104 wire [31:0] pb_wdata;
105 wire [ 3:0] pb_wstrb;
106
107 // SoC RAM
108 // BRAM
109 wire [ 7:0] bram_addr;
110 wire [31:0] bram_rdata;
111 wire [31:0] bram_wdata;
112 wire [ 3:0] bram_wmsk;
113 wire bram_we;
114
115 // SPRAM
116 wire [14:0] spram_addr;
117 wire [31:0] spram_rdata;
118 wire [31:0] spram_wdata;
119 wire [ 3:0] spram_wmsk;
120 wire spram_we;
121
122 // Peripheral wishbone
123 wire [WB_AW-1:0] wb_addr;
124 wire [WB_DW-1:0] wb_rdata [0:WB_LN-1];
125 wire [WB_DW-1:0] wb_wdata;
126 wire [WB_MW-1:0] wb_wmsk;
127 wire wb_we;
128 wire [WB_TN-1:0] wb_cyc;
129 wire [WB_TN-1:0] wb_ack;
130
131 wire [(WB_DW*WB_TN)-1:0] wb_rdata_flat;
132
133 // USB
134 // Wishbone ( @ 48 MHz )
135 wire [11:0] ub_addr;
136 wire [15:0] ub_rdata;
137 wire [15:0] ub_wdata;
138 wire ub_we;
139 wire ub_cyc;
140 wire ub_ack;
141
142 // EP interface
143 wire [ 8:0] ep_tx_addr_0;
144 wire [31:0] ep_tx_data_0;
145 wire ep_tx_we_0;
146
147 wire [ 8:0] ep_rx_addr_0;
148 wire [31:0] ep_rx_data_1;
149 wire ep_rx_re_0;
150
151 // SoF
152 wire usb_sof;
153
154 // Wishbone bus E1 to IO buffers
155 wire [13:0] wb_e1_addr;
156 wire [31:0] wb_e1_rdata;
157 wire [31:0] wb_e1_wdata;
158 wire [ 3:0] wb_e1_wmsk;
159 wire wb_e1_we;
160 wire wb_e1_cyc;
161 wire wb_e1_ack;
162
163 // E1 buffer interface
164 wire [(E1_N*8)-1:0] e1_buf_rx_data;
165 wire [(E1_N*5)-1:0] e1_buf_rx_ts;
166 wire [(E1_N*4)-1:0] e1_buf_rx_frame;
167 wire [(E1_N*7)-1:0] e1_buf_rx_mf;
168 wire [ E1_N -1:0] e1_buf_rx_we;
169 wire [ E1_N -1:0] e1_buf_rx_rdy;
170 wire [(E1_N*8)-1:0] e1_buf_tx_data;
171 wire [(E1_N*5)-1:0] e1_buf_tx_ts;
172 wire [(E1_N*4)-1:0] e1_buf_tx_frame;
173 wire [(E1_N*7)-1:0] e1_buf_tx_mf;
174 wire [ E1_N -1:0] e1_buf_tx_re;
175 wire [ E1_N -1:0] e1_buf_tx_rdy;
176
177
178 // SoC core
179 // --------
180
181 // Local CPU reset
182 reg pb_rst_n;
183
184 always @(posedge clk_sys or posedge rst_sys)
185 if (rst_sys)
186 pb_rst_n <= 1'b0;
187 else
188 pb_rst_n <= 1'b1;
189
190 // CPU
191 picorv32 #(
192 .PROGADDR_RESET(32'h 0000_0000),
193 .STACKADDR(32'h 0000_0400),
194 .BARREL_SHIFTER(0),
195`ifdef BOARD_E1_TRACER
196 .TWO_CYCLE_COMPARE(0),
197 .TWO_CYCLE_ALU(0),
198`else
199 .TWO_CYCLE_COMPARE(0),
200 .TWO_CYCLE_ALU(1),
201`endif
202 .COMPRESSED_ISA(0),
203 .ENABLE_COUNTERS(0),
204 .ENABLE_MUL(0),
205 .ENABLE_DIV(0),
206 .ENABLE_IRQ(0),
207 .ENABLE_IRQ_QREGS(0),
208 .CATCH_MISALIGN(0),
209 .CATCH_ILLINSN(0)
210 ) cpu_I (
211 .clk (clk_sys),
212 .resetn (pb_rst_n),
213 .mem_valid (pb_valid),
214 .mem_instr (pb_instr),
215 .mem_ready (pb_ready),
216 .mem_addr (pb_addr),
217 .mem_wdata (pb_wdata),
218 .mem_wstrb (pb_wstrb),
219 .mem_rdata (pb_rdata)
220 );
221
222 // CPU bridge
223 soc_picorv32_bridge #(
224 .WB_N (WB_TN),
225 .WB_DW (32),
226 .WB_AW (16),
227 .WB_AI ( 2),
Sylvain Munaut488bf8a2020-10-09 13:05:53 +0200228 .WB_REG( 4)
Sylvain Munaut21b03ba2020-09-14 10:01:45 +0200229 ) bridge_I (
230 .pb_addr (pb_addr),
231 .pb_rdata (pb_rdata),
232 .pb_wdata (pb_wdata),
233 .pb_wstrb (pb_wstrb),
234 .pb_valid (pb_valid),
235 .pb_ready (pb_ready),
236 .bram_addr (bram_addr),
237 .bram_rdata (bram_rdata),
238 .bram_wdata (bram_wdata),
239 .bram_wmsk (bram_wmsk),
240 .bram_we (bram_we),
241 .spram_addr (spram_addr),
242 .spram_rdata(spram_rdata),
243 .spram_wdata(spram_wdata),
244 .spram_wmsk (spram_wmsk),
245 .spram_we (spram_we),
246 .wb_addr (wb_addr),
247 .wb_rdata (wb_rdata_flat),
248 .wb_wdata (wb_wdata),
249 .wb_wmsk (wb_wmsk),
250 .wb_we (wb_we),
251 .wb_cyc (wb_cyc),
252 .wb_ack (wb_ack),
253 .clk (clk_sys),
254 .rst (rst_sys)
255 );
256
257 for (i=0; i<WB_LN; i=i+1)
258 assign wb_rdata_flat[i*WB_DW+:WB_DW] = wb_rdata[i];
259
260 // Boot memory - 1k
261 soc_bram #(
262 .AW(8),
Sylvain Munaut7b228842020-09-22 20:00:13 +0200263 .INIT_FILE("boot.hex")
Sylvain Munaut21b03ba2020-09-14 10:01:45 +0200264 ) bram_I (
265 .addr (bram_addr),
266 .rdata(bram_rdata),
267 .wdata(bram_wdata),
268 .wmsk (bram_wmsk),
269 .we (bram_we),
270 .clk (clk_sys)
271 );
272
273 // Main SoC memory - 64k
274 soc_spram #(
275 .AW(14)
276 ) spram_I (
277 .addr (spram_addr[13:0]),
278 .rdata(spram_rdata),
279 .wdata(spram_wdata),
280 .wmsk (spram_wmsk),
281 .we (spram_we),
282 .clk (clk_sys)
283 );
284
285 // Peripheral wishbone export
286 assign wb_m_addr = wb_addr;
287 assign wb_m_wdata = wb_wdata;
288 assign wb_m_wmsk = wb_wmsk;
289 assign wb_m_we = wb_we;
290 assign wb_m_cyc = wb_cyc[WB_TN-1:WB_LN];
291
292 assign wb_rdata_flat[(WB_TN*WB_DW)-1:(WB_LN*WB_DW)] = wb_m_rdata;
293 assign wb_ack[WB_TN-1:WB_LN] = wb_m_ack;
294
295
296 // SPI [0]
297 // ---
298
299 ice40_spi_wb #(
300 .N_CS(1),
301 .WITH_IOB(0),
302 .UNIT(0)
303 ) spi_I (
304 .sio_mosi_i (flash_mosi_i),
305 .sio_mosi_o (flash_mosi_o),
306 .sio_mosi_oe(flash_mosi_oe),
307 .sio_miso_i (flash_miso_i),
308 .sio_miso_o (flash_miso_o),
309 .sio_miso_oe(flash_miso_oe),
310 .sio_clk_i (flash_clk_i),
311 .sio_clk_o (flash_clk_o),
312 .sio_clk_oe (flash_clk_oe),
313 .sio_csn_o (flash_csn_o),
314 .sio_csn_oe (),
315 .wb_addr (wb_addr[3:0]),
316 .wb_rdata (wb_rdata[0]),
317 .wb_wdata (wb_wdata),
318 .wb_we (wb_we),
319 .wb_cyc (wb_cyc[0]),
320 .wb_ack (wb_ack[0]),
321 .clk (clk_sys),
322 .rst (rst_sys)
323 );
324
325
326 // Debug UART [1]
327 // ----------
328
329 uart_wb #(
330 .DIV_WIDTH(12),
331 .DW(WB_DW)
332 ) uart_I (
333 .uart_tx (dbg_tx),
334 .uart_rx (dbg_rx),
335 .wb_addr (wb_addr[1:0]),
336 .wb_rdata (wb_rdata[1]),
337 .wb_wdata (wb_wdata),
338 .wb_we (wb_we),
339 .wb_cyc (wb_cyc[1]),
340 .wb_ack (wb_ack[1]),
341 .clk (clk_sys),
342 .rst (rst_sys)
343 );
344
345
346 // RGB LEDs [2]
347 // --------
348
349 ice40_rgb_wb #(
350 .CURRENT_MODE("0b1"),
351 .RGB0_CURRENT("0b000001"),
352 .RGB1_CURRENT("0b000001"),
353 .RGB2_CURRENT("0b000001")
354 ) rgb_I (
355 .pad_rgb (rgb),
356 .wb_addr (wb_addr[4:0]),
357 .wb_rdata (wb_rdata[2]),
358 .wb_wdata (wb_wdata),
359 .wb_we (wb_we),
360 .wb_cyc (wb_cyc[2]),
361 .wb_ack (wb_ack[2]),
362 .clk (clk_sys),
363 .rst (rst_sys)
364 );
365
366
367 // USB [3]
368 // ---
369
370 // Core instance ( @ 48 MHz )
371 usb #(
372 .EPDW(32)
373 ) usb_I (
374 .pad_dp (usb_dp),
375 .pad_dn (usb_dn),
376 .pad_pu (usb_pu),
377 .ep_tx_addr_0(ep_tx_addr_0),
378 .ep_tx_data_0(ep_tx_data_0),
379 .ep_tx_we_0 (ep_tx_we_0),
380 .ep_rx_addr_0(ep_rx_addr_0),
381 .ep_rx_data_1(ep_rx_data_1),
382 .ep_rx_re_0 (ep_rx_re_0),
383 .ep_clk (clk_sys),
384 .wb_addr (ub_addr),
385 .wb_rdata (ub_rdata),
386 .wb_wdata (ub_wdata),
387 .wb_we (ub_we),
388 .wb_cyc (ub_cyc),
389 .wb_ack (ub_ack),
390 .sof (usb_sof),
391 .clk (clk_48m),
392 .rst (rst_48m)
393 );
394
395 // Cross clock bridge
396 xclk_wb #(
397 .DW(16),
398 .AW(12)
399 ) wb_48m_xclk_I (
400 .s_addr (wb_addr[11:0]),
401 .s_rdata(wb_rdata[3][15:0]),
402 .s_wdata(wb_wdata[15:0]),
403 .s_we (wb_we),
404 .s_cyc (wb_cyc[3]),
405 .s_ack (wb_ack[3]),
406 .s_clk (clk_sys),
407 .m_addr (ub_addr),
408 .m_rdata(ub_rdata),
409 .m_wdata(ub_wdata),
410 .m_we (ub_we),
411 .m_cyc (ub_cyc),
412 .m_ack (ub_ack),
413 .m_clk (clk_48m),
414 .rst (rst_sys)
415 );
416
417 assign wb_rdata[3][31:16] = 16'h0000;
418
419 // Cross clock SoF
420 xclk_strobe sof_xclk_I (
421 .in_stb (usb_sof),
422 .in_clk (clk_48m),
423 .out_stb(tick_usb_sof),
424 .out_clk(clk_sys),
425 .rst (rst_sys)
426 );
427
428
429 // IO buffers & DMA
430 // ----------------
431 // [4] USB EP buffer
432 // [5] E1 SPRAM buffer
433 // [6] DMA
434
435 soc_iobuf iobuf_I (
436 .wb_cpu_addr (wb_addr),
437 .wb_cpu_rdata(wb_rdata[4]),
438 .wb_cpu_wdata(wb_wdata),
439 .wb_cpu_wmsk (wb_wmsk),
440 .wb_cpu_we (wb_we),
441 .wb_cpu_cyc (wb_cyc[6:4]),
442 .wb_cpu_ack (wb_ack[6:4]),
443 .wb_e1_addr (wb_e1_addr),
444 .wb_e1_rdata (wb_e1_rdata),
445 .wb_e1_wdata (wb_e1_wdata),
446 .wb_e1_wmsk (wb_e1_wmsk),
447 .wb_e1_we (wb_e1_we),
448 .wb_e1_cyc (wb_e1_cyc),
449 .wb_e1_ack (wb_e1_ack),
450 .ep_tx_addr_0(ep_tx_addr_0),
451 .ep_tx_data_0(ep_tx_data_0),
452 .ep_tx_we_0 (ep_tx_we_0),
453 .ep_rx_addr_0(ep_rx_addr_0),
454 .ep_rx_data_1(ep_rx_data_1),
455 .ep_rx_re_0 (ep_rx_re_0),
456 .clk (clk_sys),
457 .rst (rst_sys)
458 );
459
460 assign wb_rdata[5] = 32'h00000000;
461 assign wb_rdata[6] = 32'h00000000;
462
463
464 // E1 [7]
465 // --
466
467 // E1 wishbone module
468 e1_wb #(
469 .N(E1_N),
470 .UNIT_HAS_RX(E1_UNIT_HAS_RX),
471 .UNIT_HAS_TX(E1_UNIT_HAS_TX),
472 .LIU(E1_LIU),
473 .MFW(7)
474 ) e1_I (
475 .pad_rx_hi_p (e1_rx_hi_p),
476 .pad_rx_hi_n (e1_rx_hi_n),
477 .pad_rx_lo_p (e1_rx_lo_p),
478 .pad_rx_lo_n (e1_rx_lo_n),
479 .pad_tx_hi (e1_tx_hi),
480 .pad_tx_lo (e1_tx_lo),
481 .pad_rx_data (e1_rx_data),
482 .pad_rx_clk (e1_rx_clk),
483 .pad_tx_data (e1_tx_data),
484 .pad_tx_clk (e1_tx_clk),
485 .buf_rx_data (e1_buf_rx_data),
486 .buf_rx_ts (e1_buf_rx_ts),
487 .buf_rx_frame(e1_buf_rx_frame),
488 .buf_rx_mf (e1_buf_rx_mf),
489 .buf_rx_we (e1_buf_rx_we),
490 .buf_rx_rdy (e1_buf_rx_rdy),
491 .buf_tx_data (e1_buf_tx_data),
492 .buf_tx_ts (e1_buf_tx_ts),
493 .buf_tx_frame(e1_buf_tx_frame),
494 .buf_tx_mf (e1_buf_tx_mf),
495 .buf_tx_re (e1_buf_tx_re),
496 .buf_tx_rdy (e1_buf_tx_rdy),
497 .wb_addr (wb_addr[7:0]),
498 .wb_rdata (wb_rdata[7][15:0]),
499 .wb_wdata (wb_wdata[15:0]),
500 .wb_we (wb_we),
501 .wb_cyc (wb_cyc[7]),
502 .wb_ack (wb_ack[7]),
503 .irq (),
Sylvain Munaut60f664f2024-04-29 16:14:54 +0200504 .mon_tick (tick_e1),
Sylvain Munaut21b03ba2020-09-14 10:01:45 +0200505 .clk (clk_sys),
506 .rst (rst_sys)
507 );
508
509 assign wb_rdata[7][31:16] = 16'h0000;
510
511 // E1 buffer interface to Wishbone
512 e1_buf_if_wb #(
513 .N(E1_N),
514 .UNIT_HAS_RX(E1_UNIT_HAS_RX),
515 .UNIT_HAS_TX(E1_UNIT_HAS_TX),
516 .MFW(7),
517 .DW(32)
518 ) e1_buf_I (
519 .wb_addr (wb_e1_addr),
520 .wb_rdata (wb_e1_rdata),
521 .wb_wdata (wb_e1_wdata),
522 .wb_wmsk (wb_e1_wmsk),
523 .wb_we (wb_e1_we),
524 .wb_cyc (wb_e1_cyc),
525 .wb_ack (wb_e1_ack),
526 .buf_rx_data (e1_buf_rx_data),
527 .buf_rx_ts (e1_buf_rx_ts),
528 .buf_rx_frame(e1_buf_rx_frame),
529 .buf_rx_mf (e1_buf_rx_mf),
530 .buf_rx_we (e1_buf_rx_we),
531 .buf_rx_rdy (e1_buf_rx_rdy),
532 .buf_tx_data (e1_buf_tx_data),
533 .buf_tx_ts (e1_buf_tx_ts),
534 .buf_tx_frame(e1_buf_tx_frame),
535 .buf_tx_mf (e1_buf_tx_mf),
536 .buf_tx_re (e1_buf_tx_re),
537 .buf_tx_rdy (e1_buf_tx_rdy),
538 .clk (clk_sys),
539 .rst (rst_sys)
540 );
541
542endmodule // soc_base