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