Add arrival for SB_MAC16.O
[yosys.git] / techlibs / ice40 / cells_sim.v
1
2 `define SB_DFF_REG reg Q = 0
3 // `define SB_DFF_REG reg Q
4
5 `define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif
6 `define ABC_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc_arrival=TIME *) `endif
7 `define ABC_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc_arrival=TIME *) `endif
8
9 // SiliconBlue IO Cells
10
11 module SB_IO (
12 inout PACKAGE_PIN,
13 input LATCH_INPUT_VALUE,
14 input CLOCK_ENABLE,
15 input INPUT_CLK,
16 input OUTPUT_CLK,
17 input OUTPUT_ENABLE,
18 input D_OUT_0,
19 input D_OUT_1,
20 output D_IN_0,
21 output D_IN_1
22 );
23 parameter [5:0] PIN_TYPE = 6'b000000;
24 parameter [0:0] PULLUP = 1'b0;
25 parameter [0:0] NEG_TRIGGER = 1'b0;
26 parameter IO_STANDARD = "SB_LVCMOS";
27
28 `ifndef BLACKBOX
29 reg dout, din_0, din_1;
30 reg din_q_0, din_q_1;
31 reg dout_q_0, dout_q_1;
32 reg outena_q;
33
34 // IO tile generates a constant 1'b1 internally if global_cen is not connected
35 wire clken_pulled = CLOCK_ENABLE || CLOCK_ENABLE === 1'bz;
36 reg clken_pulled_ri;
37 reg clken_pulled_ro;
38
39 generate if (!NEG_TRIGGER) begin
40 always @(posedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
41 always @(posedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
42 always @(negedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
43 always @(posedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
44 always @(posedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
45 always @(negedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
46 always @(posedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
47 end else begin
48 always @(negedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
49 always @(negedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
50 always @(posedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
51 always @(negedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
52 always @(negedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
53 always @(posedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
54 always @(negedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
55 end endgenerate
56
57 always @* begin
58 if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
59 din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
60 din_1 = din_q_1;
61 end
62
63 // work around simulation glitches on dout in DDR mode
64 reg outclk_delayed_1;
65 reg outclk_delayed_2;
66 always @* outclk_delayed_1 <= OUTPUT_CLK;
67 always @* outclk_delayed_2 <= outclk_delayed_1;
68
69 always @* begin
70 if (PIN_TYPE[3])
71 dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
72 else
73 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
74 end
75
76 assign D_IN_0 = din_0, D_IN_1 = din_1;
77
78 generate
79 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
80 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
81 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
82 endgenerate
83 `endif
84 endmodule
85
86 module SB_GB_IO (
87 inout PACKAGE_PIN,
88 output GLOBAL_BUFFER_OUTPUT,
89 input LATCH_INPUT_VALUE,
90 input CLOCK_ENABLE,
91 input INPUT_CLK,
92 input OUTPUT_CLK,
93 input OUTPUT_ENABLE,
94 input D_OUT_0,
95 input D_OUT_1,
96 output D_IN_0,
97 output D_IN_1
98 );
99 parameter [5:0] PIN_TYPE = 6'b000000;
100 parameter [0:0] PULLUP = 1'b0;
101 parameter [0:0] NEG_TRIGGER = 1'b0;
102 parameter IO_STANDARD = "SB_LVCMOS";
103
104 assign GLOBAL_BUFFER_OUTPUT = PACKAGE_PIN;
105
106 SB_IO #(
107 .PIN_TYPE(PIN_TYPE),
108 .PULLUP(PULLUP),
109 .NEG_TRIGGER(NEG_TRIGGER),
110 .IO_STANDARD(IO_STANDARD)
111 ) IO (
112 .PACKAGE_PIN(PACKAGE_PIN),
113 .LATCH_INPUT_VALUE(LATCH_INPUT_VALUE),
114 .CLOCK_ENABLE(CLOCK_ENABLE),
115 .INPUT_CLK(INPUT_CLK),
116 .OUTPUT_CLK(OUTPUT_CLK),
117 .OUTPUT_ENABLE(OUTPUT_ENABLE),
118 .D_OUT_0(D_OUT_0),
119 .D_OUT_1(D_OUT_1),
120 .D_IN_0(D_IN_0),
121 .D_IN_1(D_IN_1)
122 );
123 endmodule
124
125 module SB_GB (
126 input USER_SIGNAL_TO_GLOBAL_BUFFER,
127 output GLOBAL_BUFFER_OUTPUT
128 );
129 assign GLOBAL_BUFFER_OUTPUT = USER_SIGNAL_TO_GLOBAL_BUFFER;
130 endmodule
131
132 // SiliconBlue Logic Cells
133
134 (* lib_whitebox *)
135 module SB_LUT4 (output O, input I0, I1, I2, I3);
136 parameter [15:0] LUT_INIT = 0;
137 wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
138 wire [3:0] s2 = I2 ? s3[ 7:4] : s3[3:0];
139 wire [1:0] s1 = I1 ? s2[ 3:2] : s2[1:0];
140 assign O = I0 ? s1[1] : s1[0];
141 endmodule
142
143 (* lib_whitebox *)
144 module SB_CARRY (output CO, input I0, I1, CI);
145 assign CO = (I0 && I1) || ((I0 || I1) && CI);
146 endmodule
147
148 (* abc_box_id = 1, lib_whitebox *)
149 module \$__ICE40_CARRY_WRAPPER (
150 (* abc_carry *)
151 output CO,
152 output O,
153 input A, B,
154 (* abc_carry *)
155 input CI,
156 input I0, I3
157 );
158 parameter LUT = 0;
159 SB_CARRY carry (
160 .I0(A),
161 .I1(B),
162 .CI(CI),
163 .CO(CO)
164 );
165 SB_LUT4 #(
166 .LUT_INIT(LUT)
167 ) adder (
168 .I0(I0),
169 .I1(A),
170 .I2(B),
171 .I3(I3),
172 .O(O)
173 );
174 endmodule
175
176 // Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
177 // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
178 // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
179
180 // Positive Edge SiliconBlue FF Cells
181
182 module SB_DFF (
183 `ABC_ARRIVAL_HX(540)
184 `ABC_ARRIVAL_LP(796)
185 `ABC_ARRIVAL_U(1391)
186 output `SB_DFF_REG,
187 input C, D
188 );
189 always @(posedge C)
190 Q <= D;
191 endmodule
192
193 module SB_DFFE (
194 `ABC_ARRIVAL_HX(540)
195 `ABC_ARRIVAL_LP(796)
196 `ABC_ARRIVAL_U(1391)
197 output `SB_DFF_REG,
198 input C, E, D
199 );
200 always @(posedge C)
201 if (E)
202 Q <= D;
203 endmodule
204
205 module SB_DFFSR (
206 `ABC_ARRIVAL_HX(540)
207 `ABC_ARRIVAL_LP(796)
208 `ABC_ARRIVAL_U(1391)
209 output `SB_DFF_REG,
210 input C, R, D
211 );
212 always @(posedge C)
213 if (R)
214 Q <= 0;
215 else
216 Q <= D;
217 endmodule
218
219 module SB_DFFR (
220 `ABC_ARRIVAL_HX(540)
221 `ABC_ARRIVAL_LP(796)
222 `ABC_ARRIVAL_U(1391)
223 output `SB_DFF_REG,
224 input C, R, D
225 );
226 always @(posedge C, posedge R)
227 if (R)
228 Q <= 0;
229 else
230 Q <= D;
231 endmodule
232
233 module SB_DFFSS (
234 `ABC_ARRIVAL_HX(540)
235 `ABC_ARRIVAL_LP(796)
236 `ABC_ARRIVAL_U(1391)
237 output `SB_DFF_REG,
238 input C, S, D
239 );
240 always @(posedge C)
241 if (S)
242 Q <= 1;
243 else
244 Q <= D;
245 endmodule
246
247 module SB_DFFS (
248 `ABC_ARRIVAL_HX(540)
249 `ABC_ARRIVAL_LP(796)
250 `ABC_ARRIVAL_U(1391)
251 output `SB_DFF_REG,
252 input C, S, D
253 );
254 always @(posedge C, posedge S)
255 if (S)
256 Q <= 1;
257 else
258 Q <= D;
259 endmodule
260
261 module SB_DFFESR (
262 `ABC_ARRIVAL_HX(540)
263 `ABC_ARRIVAL_LP(796)
264 `ABC_ARRIVAL_U(1391)
265 output `SB_DFF_REG,
266 input C, E, R, D
267 );
268 always @(posedge C)
269 if (E) begin
270 if (R)
271 Q <= 0;
272 else
273 Q <= D;
274 end
275 endmodule
276
277 module SB_DFFER (
278 `ABC_ARRIVAL_HX(540)
279 `ABC_ARRIVAL_LP(796)
280 `ABC_ARRIVAL_U(1391)
281 output `SB_DFF_REG,
282 input C, E, R, D
283 );
284 always @(posedge C, posedge R)
285 if (R)
286 Q <= 0;
287 else if (E)
288 Q <= D;
289 endmodule
290
291 module SB_DFFESS (
292 `ABC_ARRIVAL_HX(540)
293 `ABC_ARRIVAL_LP(796)
294 `ABC_ARRIVAL_U(1391)
295 output `SB_DFF_REG,
296 input C, E, S, D
297 );
298 always @(posedge C)
299 if (E) begin
300 if (S)
301 Q <= 1;
302 else
303 Q <= D;
304 end
305 endmodule
306
307 module SB_DFFES (
308 `ABC_ARRIVAL_HX(540)
309 `ABC_ARRIVAL_LP(796)
310 `ABC_ARRIVAL_U(1391)
311 output `SB_DFF_REG,
312 input C, E, S, D
313 );
314 always @(posedge C, posedge S)
315 if (S)
316 Q <= 1;
317 else if (E)
318 Q <= D;
319 endmodule
320
321 // Negative Edge SiliconBlue FF Cells
322
323 module SB_DFFN (
324 `ABC_ARRIVAL_HX(540)
325 `ABC_ARRIVAL_LP(796)
326 `ABC_ARRIVAL_U(1391)
327 output `SB_DFF_REG,
328 input C, D
329 );
330 always @(negedge C)
331 Q <= D;
332 endmodule
333
334 module SB_DFFNE (
335 `ABC_ARRIVAL_HX(540)
336 `ABC_ARRIVAL_LP(796)
337 `ABC_ARRIVAL_U(1391)
338 output `SB_DFF_REG,
339 input C, E, D
340 );
341 always @(negedge C)
342 if (E)
343 Q <= D;
344 endmodule
345
346 module SB_DFFNSR (
347 `ABC_ARRIVAL_HX(540)
348 `ABC_ARRIVAL_LP(796)
349 `ABC_ARRIVAL_U(1391)
350 output `SB_DFF_REG,
351 input C, R, D
352 );
353 always @(negedge C)
354 if (R)
355 Q <= 0;
356 else
357 Q <= D;
358 endmodule
359
360 module SB_DFFNR (
361 `ABC_ARRIVAL_HX(540)
362 `ABC_ARRIVAL_LP(796)
363 `ABC_ARRIVAL_U(1391)
364 output `SB_DFF_REG,
365 input C, R, D
366 );
367 always @(negedge C, posedge R)
368 if (R)
369 Q <= 0;
370 else
371 Q <= D;
372 endmodule
373
374 module SB_DFFNSS (
375 `ABC_ARRIVAL_HX(540)
376 `ABC_ARRIVAL_LP(796)
377 `ABC_ARRIVAL_U(1391)
378 output `SB_DFF_REG,
379 input C, S, D
380 );
381 always @(negedge C)
382 if (S)
383 Q <= 1;
384 else
385 Q <= D;
386 endmodule
387
388 module SB_DFFNS (
389 `ABC_ARRIVAL_HX(540)
390 `ABC_ARRIVAL_LP(796)
391 `ABC_ARRIVAL_U(1391)
392 output `SB_DFF_REG,
393 input C, S, D
394 );
395 always @(negedge C, posedge S)
396 if (S)
397 Q <= 1;
398 else
399 Q <= D;
400 endmodule
401
402 module SB_DFFNESR (
403 `ABC_ARRIVAL_HX(540)
404 `ABC_ARRIVAL_LP(796)
405 `ABC_ARRIVAL_U(1391)
406 output `SB_DFF_REG,
407 input C, E, R, D
408 );
409 always @(negedge C)
410 if (E) begin
411 if (R)
412 Q <= 0;
413 else
414 Q <= D;
415 end
416 endmodule
417
418 module SB_DFFNER (
419 `ABC_ARRIVAL_HX(540)
420 `ABC_ARRIVAL_LP(796)
421 `ABC_ARRIVAL_U(1391)
422 output `SB_DFF_REG,
423 input C, E, R, D
424 );
425 always @(negedge C, posedge R)
426 if (R)
427 Q <= 0;
428 else if (E)
429 Q <= D;
430 endmodule
431
432 module SB_DFFNESS (
433 `ABC_ARRIVAL_HX(540)
434 `ABC_ARRIVAL_LP(796)
435 `ABC_ARRIVAL_U(1391)
436 output `SB_DFF_REG,
437 input C, E, S, D
438 );
439 always @(negedge C)
440 if (E) begin
441 if (S)
442 Q <= 1;
443 else
444 Q <= D;
445 end
446 endmodule
447
448 module SB_DFFNES (
449 `ABC_ARRIVAL_HX(540)
450 `ABC_ARRIVAL_LP(796)
451 `ABC_ARRIVAL_U(1391)
452 output `SB_DFF_REG,
453 input C, E, S, D
454 );
455 always @(negedge C, posedge S)
456 if (S)
457 Q <= 1;
458 else if (E)
459 Q <= D;
460 endmodule
461
462 // SiliconBlue RAM Cells
463
464 module SB_RAM40_4K (
465 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
466 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
467 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
468 output [15:0] RDATA,
469 input RCLK, RCLKE, RE,
470 input [10:0] RADDR,
471 input WCLK, WCLKE, WE,
472 input [10:0] WADDR,
473 input [15:0] MASK, WDATA
474 );
475 // MODE 0: 256 x 16
476 // MODE 1: 512 x 8
477 // MODE 2: 1024 x 4
478 // MODE 3: 2048 x 2
479 parameter WRITE_MODE = 0;
480 parameter READ_MODE = 0;
481
482 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
483 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
484 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
485 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
486 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
487 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
488 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
489 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
490 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
491 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
492 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
493 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
494 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
495 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
496 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
497 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
498
499 parameter INIT_FILE = "";
500
501 `ifndef BLACKBOX
502 wire [15:0] WMASK_I;
503 wire [15:0] RMASK_I;
504
505 reg [15:0] RDATA_I;
506 wire [15:0] WDATA_I;
507
508 generate
509 case (WRITE_MODE)
510 0: assign WMASK_I = MASK;
511
512 1: assign WMASK_I = WADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
513 WADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
514
515 2: assign WMASK_I = WADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
516 WADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
517 WADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
518 WADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
519
520 3: assign WMASK_I = WADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
521 WADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
522 WADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
523 WADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
524 WADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
525 WADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
526 WADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
527 WADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
528 endcase
529
530 case (READ_MODE)
531 0: assign RMASK_I = 16'b 0000_0000_0000_0000;
532
533 1: assign RMASK_I = RADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
534 RADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
535
536 2: assign RMASK_I = RADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
537 RADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
538 RADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
539 RADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
540
541 3: assign RMASK_I = RADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
542 RADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
543 RADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
544 RADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
545 RADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
546 RADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
547 RADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
548 RADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
549 endcase
550
551 case (WRITE_MODE)
552 0: assign WDATA_I = WDATA;
553
554 1: assign WDATA_I = {WDATA[14], WDATA[14], WDATA[12], WDATA[12],
555 WDATA[10], WDATA[10], WDATA[ 8], WDATA[ 8],
556 WDATA[ 6], WDATA[ 6], WDATA[ 4], WDATA[ 4],
557 WDATA[ 2], WDATA[ 2], WDATA[ 0], WDATA[ 0]};
558
559 2: assign WDATA_I = {WDATA[13], WDATA[13], WDATA[13], WDATA[13],
560 WDATA[ 9], WDATA[ 9], WDATA[ 9], WDATA[ 9],
561 WDATA[ 5], WDATA[ 5], WDATA[ 5], WDATA[ 5],
562 WDATA[ 1], WDATA[ 1], WDATA[ 1], WDATA[ 1]};
563
564 3: assign WDATA_I = {WDATA[11], WDATA[11], WDATA[11], WDATA[11],
565 WDATA[11], WDATA[11], WDATA[11], WDATA[11],
566 WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3],
567 WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3]};
568 endcase
569
570 case (READ_MODE)
571 0: assign RDATA = RDATA_I;
572 1: assign RDATA = {1'b0, |RDATA_I[15:14], 1'b0, |RDATA_I[13:12], 1'b0, |RDATA_I[11:10], 1'b0, |RDATA_I[ 9: 8],
573 1'b0, |RDATA_I[ 7: 6], 1'b0, |RDATA_I[ 5: 4], 1'b0, |RDATA_I[ 3: 2], 1'b0, |RDATA_I[ 1: 0]};
574 2: assign RDATA = {2'b0, |RDATA_I[15:12], 3'b0, |RDATA_I[11: 8], 3'b0, |RDATA_I[ 7: 4], 3'b0, |RDATA_I[ 3: 0], 1'b0};
575 3: assign RDATA = {4'b0, |RDATA_I[15: 8], 7'b0, |RDATA_I[ 7: 0], 3'b0};
576 endcase
577 endgenerate
578
579 integer i;
580 reg [15:0] memory [0:255];
581
582 initial begin
583 if (INIT_FILE != "")
584 $readmemh(INIT_FILE, memory);
585 else
586 for (i=0; i<16; i=i+1) begin
587 memory[ 0*16 + i] = INIT_0[16*i +: 16];
588 memory[ 1*16 + i] = INIT_1[16*i +: 16];
589 memory[ 2*16 + i] = INIT_2[16*i +: 16];
590 memory[ 3*16 + i] = INIT_3[16*i +: 16];
591 memory[ 4*16 + i] = INIT_4[16*i +: 16];
592 memory[ 5*16 + i] = INIT_5[16*i +: 16];
593 memory[ 6*16 + i] = INIT_6[16*i +: 16];
594 memory[ 7*16 + i] = INIT_7[16*i +: 16];
595 memory[ 8*16 + i] = INIT_8[16*i +: 16];
596 memory[ 9*16 + i] = INIT_9[16*i +: 16];
597 memory[10*16 + i] = INIT_A[16*i +: 16];
598 memory[11*16 + i] = INIT_B[16*i +: 16];
599 memory[12*16 + i] = INIT_C[16*i +: 16];
600 memory[13*16 + i] = INIT_D[16*i +: 16];
601 memory[14*16 + i] = INIT_E[16*i +: 16];
602 memory[15*16 + i] = INIT_F[16*i +: 16];
603 end
604 end
605
606 always @(posedge WCLK) begin
607 if (WE && WCLKE) begin
608 if (!WMASK_I[ 0]) memory[WADDR[7:0]][ 0] <= WDATA_I[ 0];
609 if (!WMASK_I[ 1]) memory[WADDR[7:0]][ 1] <= WDATA_I[ 1];
610 if (!WMASK_I[ 2]) memory[WADDR[7:0]][ 2] <= WDATA_I[ 2];
611 if (!WMASK_I[ 3]) memory[WADDR[7:0]][ 3] <= WDATA_I[ 3];
612 if (!WMASK_I[ 4]) memory[WADDR[7:0]][ 4] <= WDATA_I[ 4];
613 if (!WMASK_I[ 5]) memory[WADDR[7:0]][ 5] <= WDATA_I[ 5];
614 if (!WMASK_I[ 6]) memory[WADDR[7:0]][ 6] <= WDATA_I[ 6];
615 if (!WMASK_I[ 7]) memory[WADDR[7:0]][ 7] <= WDATA_I[ 7];
616 if (!WMASK_I[ 8]) memory[WADDR[7:0]][ 8] <= WDATA_I[ 8];
617 if (!WMASK_I[ 9]) memory[WADDR[7:0]][ 9] <= WDATA_I[ 9];
618 if (!WMASK_I[10]) memory[WADDR[7:0]][10] <= WDATA_I[10];
619 if (!WMASK_I[11]) memory[WADDR[7:0]][11] <= WDATA_I[11];
620 if (!WMASK_I[12]) memory[WADDR[7:0]][12] <= WDATA_I[12];
621 if (!WMASK_I[13]) memory[WADDR[7:0]][13] <= WDATA_I[13];
622 if (!WMASK_I[14]) memory[WADDR[7:0]][14] <= WDATA_I[14];
623 if (!WMASK_I[15]) memory[WADDR[7:0]][15] <= WDATA_I[15];
624 end
625 end
626
627 always @(posedge RCLK) begin
628 if (RE && RCLKE) begin
629 RDATA_I <= memory[RADDR[7:0]] & ~RMASK_I;
630 end
631 end
632 `endif
633 endmodule
634
635 module SB_RAM40_4KNR (
636 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
637 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
638 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
639 output [15:0] RDATA,
640 input RCLKN, RCLKE, RE,
641 input [10:0] RADDR,
642 input WCLK, WCLKE, WE,
643 input [10:0] WADDR,
644 input [15:0] MASK, WDATA
645 );
646 parameter WRITE_MODE = 0;
647 parameter READ_MODE = 0;
648
649 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
650 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
651 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
652 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
653 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
654 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
655 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
656 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
657 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
658 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
659 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
660 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
661 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
662 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
663 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
664 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
665
666 parameter INIT_FILE = "";
667
668 SB_RAM40_4K #(
669 .WRITE_MODE(WRITE_MODE),
670 .READ_MODE (READ_MODE ),
671 .INIT_0 (INIT_0 ),
672 .INIT_1 (INIT_1 ),
673 .INIT_2 (INIT_2 ),
674 .INIT_3 (INIT_3 ),
675 .INIT_4 (INIT_4 ),
676 .INIT_5 (INIT_5 ),
677 .INIT_6 (INIT_6 ),
678 .INIT_7 (INIT_7 ),
679 .INIT_8 (INIT_8 ),
680 .INIT_9 (INIT_9 ),
681 .INIT_A (INIT_A ),
682 .INIT_B (INIT_B ),
683 .INIT_C (INIT_C ),
684 .INIT_D (INIT_D ),
685 .INIT_E (INIT_E ),
686 .INIT_F (INIT_F ),
687 .INIT_FILE (INIT_FILE )
688 ) RAM (
689 .RDATA(RDATA),
690 .RCLK (~RCLKN),
691 .RCLKE(RCLKE),
692 .RE (RE ),
693 .RADDR(RADDR),
694 .WCLK (WCLK ),
695 .WCLKE(WCLKE),
696 .WE (WE ),
697 .WADDR(WADDR),
698 .MASK (MASK ),
699 .WDATA(WDATA)
700 );
701 endmodule
702
703 module SB_RAM40_4KNW (
704 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
705 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
706 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
707 output [15:0] RDATA,
708 input RCLK, RCLKE, RE,
709 input [10:0] RADDR,
710 input WCLKN, WCLKE, WE,
711 input [10:0] WADDR,
712 input [15:0] MASK, WDATA
713 );
714 parameter WRITE_MODE = 0;
715 parameter READ_MODE = 0;
716
717 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
718 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
719 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
720 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
721 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
722 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
723 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
724 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
725 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
726 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
727 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
728 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
729 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
730 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
731 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
732 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
733
734 parameter INIT_FILE = "";
735
736 SB_RAM40_4K #(
737 .WRITE_MODE(WRITE_MODE),
738 .READ_MODE (READ_MODE ),
739 .INIT_0 (INIT_0 ),
740 .INIT_1 (INIT_1 ),
741 .INIT_2 (INIT_2 ),
742 .INIT_3 (INIT_3 ),
743 .INIT_4 (INIT_4 ),
744 .INIT_5 (INIT_5 ),
745 .INIT_6 (INIT_6 ),
746 .INIT_7 (INIT_7 ),
747 .INIT_8 (INIT_8 ),
748 .INIT_9 (INIT_9 ),
749 .INIT_A (INIT_A ),
750 .INIT_B (INIT_B ),
751 .INIT_C (INIT_C ),
752 .INIT_D (INIT_D ),
753 .INIT_E (INIT_E ),
754 .INIT_F (INIT_F ),
755 .INIT_FILE (INIT_FILE )
756 ) RAM (
757 .RDATA(RDATA),
758 .RCLK (RCLK ),
759 .RCLKE(RCLKE),
760 .RE (RE ),
761 .RADDR(RADDR),
762 .WCLK (~WCLKN),
763 .WCLKE(WCLKE),
764 .WE (WE ),
765 .WADDR(WADDR),
766 .MASK (MASK ),
767 .WDATA(WDATA)
768 );
769 endmodule
770
771 module SB_RAM40_4KNRNW (
772 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
773 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
774 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
775 output [15:0] RDATA,
776 input RCLKN, RCLKE, RE,
777 input [10:0] RADDR,
778 input WCLKN, WCLKE, WE,
779 input [10:0] WADDR,
780 input [15:0] MASK, WDATA
781 );
782 parameter WRITE_MODE = 0;
783 parameter READ_MODE = 0;
784
785 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
786 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
787 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
788 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
789 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
790 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
791 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
792 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
793 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
794 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
795 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
796 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
797 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
798 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
799 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
800 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
801
802 parameter INIT_FILE = "";
803
804 SB_RAM40_4K #(
805 .WRITE_MODE(WRITE_MODE),
806 .READ_MODE (READ_MODE ),
807 .INIT_0 (INIT_0 ),
808 .INIT_1 (INIT_1 ),
809 .INIT_2 (INIT_2 ),
810 .INIT_3 (INIT_3 ),
811 .INIT_4 (INIT_4 ),
812 .INIT_5 (INIT_5 ),
813 .INIT_6 (INIT_6 ),
814 .INIT_7 (INIT_7 ),
815 .INIT_8 (INIT_8 ),
816 .INIT_9 (INIT_9 ),
817 .INIT_A (INIT_A ),
818 .INIT_B (INIT_B ),
819 .INIT_C (INIT_C ),
820 .INIT_D (INIT_D ),
821 .INIT_E (INIT_E ),
822 .INIT_F (INIT_F ),
823 .INIT_FILE (INIT_FILE )
824 ) RAM (
825 .RDATA(RDATA),
826 .RCLK (~RCLKN),
827 .RCLKE(RCLKE),
828 .RE (RE ),
829 .RADDR(RADDR),
830 .WCLK (~WCLKN),
831 .WCLKE(WCLKE),
832 .WE (WE ),
833 .WADDR(WADDR),
834 .MASK (MASK ),
835 .WDATA(WDATA)
836 );
837 endmodule
838
839 // Packed IceStorm Logic Cells
840
841 module ICESTORM_LC (
842 input I0, I1, I2, I3, CIN, CLK, CEN, SR,
843 output LO,
844 `ABC_ARRIVAL_HX(540)
845 `ABC_ARRIVAL_LP(796)
846 `ABC_ARRIVAL_U(1391)
847 output O,
848 output COUT
849 );
850 parameter [15:0] LUT_INIT = 0;
851
852 parameter [0:0] NEG_CLK = 0;
853 parameter [0:0] CARRY_ENABLE = 0;
854 parameter [0:0] DFF_ENABLE = 0;
855 parameter [0:0] SET_NORESET = 0;
856 parameter [0:0] ASYNC_SR = 0;
857
858 parameter [0:0] CIN_CONST = 0;
859 parameter [0:0] CIN_SET = 0;
860
861 wire mux_cin = CIN_CONST ? CIN_SET : CIN;
862
863 assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
864
865 wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
866 wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
867 wire [1:0] lut_s1 = I1 ? lut_s2[ 3:2] : lut_s2[1:0];
868 wire lut_o = I0 ? lut_s1[ 1] : lut_s1[ 0];
869
870 assign LO = lut_o;
871
872 wire polarized_clk;
873 assign polarized_clk = CLK ^ NEG_CLK;
874
875 reg o_reg;
876 always @(posedge polarized_clk)
877 if (CEN)
878 o_reg <= SR ? SET_NORESET : lut_o;
879
880 reg o_reg_async;
881 always @(posedge polarized_clk, posedge SR)
882 if (SR)
883 o_reg <= SET_NORESET;
884 else if (CEN)
885 o_reg <= lut_o;
886
887 assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
888 endmodule
889
890 // SiliconBlue PLL Cells
891
892 (* blackbox *)
893 module SB_PLL40_CORE (
894 input REFERENCECLK,
895 output PLLOUTCORE,
896 output PLLOUTGLOBAL,
897 input EXTFEEDBACK,
898 input [7:0] DYNAMICDELAY,
899 output LOCK,
900 input BYPASS,
901 input RESETB,
902 input LATCHINPUTVALUE,
903 output SDO,
904 input SDI,
905 input SCLK
906 );
907 parameter FEEDBACK_PATH = "SIMPLE";
908 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
909 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
910 parameter SHIFTREG_DIV_MODE = 1'b0;
911 parameter FDA_FEEDBACK = 4'b0000;
912 parameter FDA_RELATIVE = 4'b0000;
913 parameter PLLOUT_SELECT = "GENCLK";
914 parameter DIVR = 4'b0000;
915 parameter DIVF = 7'b0000000;
916 parameter DIVQ = 3'b000;
917 parameter FILTER_RANGE = 3'b000;
918 parameter ENABLE_ICEGATE = 1'b0;
919 parameter TEST_MODE = 1'b0;
920 parameter EXTERNAL_DIVIDE_FACTOR = 1;
921 endmodule
922
923 (* blackbox *)
924 module SB_PLL40_PAD (
925 input PACKAGEPIN,
926 output PLLOUTCORE,
927 output PLLOUTGLOBAL,
928 input EXTFEEDBACK,
929 input [7:0] DYNAMICDELAY,
930 output LOCK,
931 input BYPASS,
932 input RESETB,
933 input LATCHINPUTVALUE,
934 output SDO,
935 input SDI,
936 input SCLK
937 );
938 parameter FEEDBACK_PATH = "SIMPLE";
939 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
940 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
941 parameter SHIFTREG_DIV_MODE = 1'b0;
942 parameter FDA_FEEDBACK = 4'b0000;
943 parameter FDA_RELATIVE = 4'b0000;
944 parameter PLLOUT_SELECT = "GENCLK";
945 parameter DIVR = 4'b0000;
946 parameter DIVF = 7'b0000000;
947 parameter DIVQ = 3'b000;
948 parameter FILTER_RANGE = 3'b000;
949 parameter ENABLE_ICEGATE = 1'b0;
950 parameter TEST_MODE = 1'b0;
951 parameter EXTERNAL_DIVIDE_FACTOR = 1;
952 endmodule
953
954 (* blackbox *)
955 module SB_PLL40_2_PAD (
956 input PACKAGEPIN,
957 output PLLOUTCOREA,
958 output PLLOUTGLOBALA,
959 output PLLOUTCOREB,
960 output PLLOUTGLOBALB,
961 input EXTFEEDBACK,
962 input [7:0] DYNAMICDELAY,
963 output LOCK,
964 input BYPASS,
965 input RESETB,
966 input LATCHINPUTVALUE,
967 output SDO,
968 input SDI,
969 input SCLK
970 );
971 parameter FEEDBACK_PATH = "SIMPLE";
972 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
973 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
974 parameter SHIFTREG_DIV_MODE = 1'b0;
975 parameter FDA_FEEDBACK = 4'b0000;
976 parameter FDA_RELATIVE = 4'b0000;
977 parameter PLLOUT_SELECT_PORTB = "GENCLK";
978 parameter DIVR = 4'b0000;
979 parameter DIVF = 7'b0000000;
980 parameter DIVQ = 3'b000;
981 parameter FILTER_RANGE = 3'b000;
982 parameter ENABLE_ICEGATE_PORTA = 1'b0;
983 parameter ENABLE_ICEGATE_PORTB = 1'b0;
984 parameter TEST_MODE = 1'b0;
985 parameter EXTERNAL_DIVIDE_FACTOR = 1;
986 endmodule
987
988 (* blackbox *)
989 module SB_PLL40_2F_CORE (
990 input REFERENCECLK,
991 output PLLOUTCOREA,
992 output PLLOUTGLOBALA,
993 output PLLOUTCOREB,
994 output PLLOUTGLOBALB,
995 input EXTFEEDBACK,
996 input [7:0] DYNAMICDELAY,
997 output LOCK,
998 input BYPASS,
999 input RESETB,
1000 input LATCHINPUTVALUE,
1001 output SDO,
1002 input SDI,
1003 input SCLK
1004 );
1005 parameter FEEDBACK_PATH = "SIMPLE";
1006 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
1007 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
1008 parameter SHIFTREG_DIV_MODE = 1'b0;
1009 parameter FDA_FEEDBACK = 4'b0000;
1010 parameter FDA_RELATIVE = 4'b0000;
1011 parameter PLLOUT_SELECT_PORTA = "GENCLK";
1012 parameter PLLOUT_SELECT_PORTB = "GENCLK";
1013 parameter DIVR = 4'b0000;
1014 parameter DIVF = 7'b0000000;
1015 parameter DIVQ = 3'b000;
1016 parameter FILTER_RANGE = 3'b000;
1017 parameter ENABLE_ICEGATE_PORTA = 1'b0;
1018 parameter ENABLE_ICEGATE_PORTB = 1'b0;
1019 parameter TEST_MODE = 1'b0;
1020 parameter EXTERNAL_DIVIDE_FACTOR = 1;
1021 endmodule
1022
1023 (* blackbox *)
1024 module SB_PLL40_2F_PAD (
1025 input PACKAGEPIN,
1026 output PLLOUTCOREA,
1027 output PLLOUTGLOBALA,
1028 output PLLOUTCOREB,
1029 output PLLOUTGLOBALB,
1030 input EXTFEEDBACK,
1031 input [7:0] DYNAMICDELAY,
1032 output LOCK,
1033 input BYPASS,
1034 input RESETB,
1035 input LATCHINPUTVALUE,
1036 output SDO,
1037 input SDI,
1038 input SCLK
1039 );
1040 parameter FEEDBACK_PATH = "SIMPLE";
1041 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
1042 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
1043 parameter SHIFTREG_DIV_MODE = 2'b00;
1044 parameter FDA_FEEDBACK = 4'b0000;
1045 parameter FDA_RELATIVE = 4'b0000;
1046 parameter PLLOUT_SELECT_PORTA = "GENCLK";
1047 parameter PLLOUT_SELECT_PORTB = "GENCLK";
1048 parameter DIVR = 4'b0000;
1049 parameter DIVF = 7'b0000000;
1050 parameter DIVQ = 3'b000;
1051 parameter FILTER_RANGE = 3'b000;
1052 parameter ENABLE_ICEGATE_PORTA = 1'b0;
1053 parameter ENABLE_ICEGATE_PORTB = 1'b0;
1054 parameter TEST_MODE = 1'b0;
1055 parameter EXTERNAL_DIVIDE_FACTOR = 1;
1056 endmodule
1057
1058 // SiliconBlue Device Configuration Cells
1059
1060 (* blackbox, keep *)
1061 module SB_WARMBOOT (
1062 input BOOT,
1063 input S1,
1064 input S0
1065 );
1066 endmodule
1067
1068 module SB_SPRAM256KA (
1069 input [13:0] ADDRESS,
1070 input [15:0] DATAIN,
1071 input [3:0] MASKWREN,
1072 input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
1073 output reg [15:0] DATAOUT
1074 );
1075 `ifndef BLACKBOX
1076 `ifndef EQUIV
1077 reg [15:0] mem [0:16383];
1078 wire off = SLEEP || !POWEROFF;
1079 integer i;
1080
1081 always @(negedge POWEROFF) begin
1082 for (i = 0; i <= 16383; i = i+1)
1083 mem[i] = 'bx;
1084 end
1085
1086 always @(posedge CLOCK, posedge off) begin
1087 if (off) begin
1088 DATAOUT <= 0;
1089 end else
1090 if (CHIPSELECT && !STANDBY && !WREN) begin
1091 DATAOUT <= mem[ADDRESS];
1092 end else begin
1093 if (CHIPSELECT && !STANDBY && WREN) begin
1094 if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
1095 if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
1096 if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
1097 if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
1098 end
1099 DATAOUT <= 'bx;
1100 end
1101 end
1102 `endif
1103 `endif
1104 endmodule
1105
1106 (* blackbox *)
1107 module SB_HFOSC(
1108 input TRIM0,
1109 input TRIM1,
1110 input TRIM2,
1111 input TRIM3,
1112 input TRIM4,
1113 input TRIM5,
1114 input TRIM6,
1115 input TRIM7,
1116 input TRIM8,
1117 input TRIM9,
1118 input CLKHFPU,
1119 input CLKHFEN,
1120 output CLKHF
1121 );
1122 parameter TRIM_EN = "0b0";
1123 parameter CLKHF_DIV = "0b00";
1124 endmodule
1125
1126 (* blackbox *)
1127 module SB_LFOSC(
1128 input CLKLFPU,
1129 input CLKLFEN,
1130 output CLKLF
1131 );
1132 endmodule
1133
1134 (* blackbox *)
1135 module SB_RGBA_DRV(
1136 input CURREN,
1137 input RGBLEDEN,
1138 input RGB0PWM,
1139 input RGB1PWM,
1140 input RGB2PWM,
1141 output RGB0,
1142 output RGB1,
1143 output RGB2
1144 );
1145 parameter CURRENT_MODE = "0b0";
1146 parameter RGB0_CURRENT = "0b000000";
1147 parameter RGB1_CURRENT = "0b000000";
1148 parameter RGB2_CURRENT = "0b000000";
1149 endmodule
1150
1151 (* blackbox *)
1152 module SB_LED_DRV_CUR(
1153 input EN,
1154 output LEDPU
1155 );
1156 endmodule
1157
1158 (* blackbox *)
1159 module SB_RGB_DRV(
1160 input RGBLEDEN,
1161 input RGB0PWM,
1162 input RGB1PWM,
1163 input RGB2PWM,
1164 input RGBPU,
1165 output RGB0,
1166 output RGB1,
1167 output RGB2
1168 );
1169 parameter CURRENT_MODE = "0b0";
1170 parameter RGB0_CURRENT = "0b000000";
1171 parameter RGB1_CURRENT = "0b000000";
1172 parameter RGB2_CURRENT = "0b000000";
1173 endmodule
1174
1175 (* blackbox *)
1176 module SB_I2C(
1177 input SBCLKI,
1178 input SBRWI,
1179 input SBSTBI,
1180 input SBADRI7,
1181 input SBADRI6,
1182 input SBADRI5,
1183 input SBADRI4,
1184 input SBADRI3,
1185 input SBADRI2,
1186 input SBADRI1,
1187 input SBADRI0,
1188 input SBDATI7,
1189 input SBDATI6,
1190 input SBDATI5,
1191 input SBDATI4,
1192 input SBDATI3,
1193 input SBDATI2,
1194 input SBDATI1,
1195 input SBDATI0,
1196 input SCLI,
1197 input SDAI,
1198 output SBDATO7,
1199 output SBDATO6,
1200 output SBDATO5,
1201 output SBDATO4,
1202 output SBDATO3,
1203 output SBDATO2,
1204 output SBDATO1,
1205 output SBDATO0,
1206 output SBACKO,
1207 output I2CIRQ,
1208 output I2CWKUP,
1209 output SCLO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
1210 output SCLOE,
1211 output SDAO,
1212 output SDAOE
1213 );
1214 parameter I2C_SLAVE_INIT_ADDR = "0b1111100001";
1215 parameter BUS_ADDR74 = "0b0001";
1216 endmodule
1217
1218 (* blackbox *)
1219 module SB_SPI (
1220 input SBCLKI,
1221 input SBRWI,
1222 input SBSTBI,
1223 input SBADRI7,
1224 input SBADRI6,
1225 input SBADRI5,
1226 input SBADRI4,
1227 input SBADRI3,
1228 input SBADRI2,
1229 input SBADRI1,
1230 input SBADRI0,
1231 input SBDATI7,
1232 input SBDATI6,
1233 input SBDATI5,
1234 input SBDATI4,
1235 input SBDATI3,
1236 input SBDATI2,
1237 input SBDATI1,
1238 input SBDATI0,
1239 input MI,
1240 input SI,
1241 input SCKI,
1242 input SCSNI,
1243 output SBDATO7,
1244 output SBDATO6,
1245 output SBDATO5,
1246 output SBDATO4,
1247 output SBDATO3,
1248 output SBDATO2,
1249 output SBDATO1,
1250 output SBDATO0,
1251 output SBACKO,
1252 output SPIIRQ,
1253 output SPIWKUP,
1254 output SO,
1255 output SOE,
1256 output MO,
1257 output MOE,
1258 output SCKO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
1259 output SCKOE,
1260 output MCSNO3,
1261 output MCSNO2,
1262 output MCSNO1,
1263 output MCSNO0,
1264 output MCSNOE3,
1265 output MCSNOE2,
1266 output MCSNOE1,
1267 output MCSNOE0
1268 );
1269 parameter BUS_ADDR74 = "0b0000";
1270 endmodule
1271
1272 (* blackbox *)
1273 module SB_LEDDA_IP(
1274 input LEDDCS,
1275 input LEDDCLK,
1276 input LEDDDAT7,
1277 input LEDDDAT6,
1278 input LEDDDAT5,
1279 input LEDDDAT4,
1280 input LEDDDAT3,
1281 input LEDDDAT2,
1282 input LEDDDAT1,
1283 input LEDDDAT0,
1284 input LEDDADDR3,
1285 input LEDDADDR2,
1286 input LEDDADDR1,
1287 input LEDDADDR0,
1288 input LEDDDEN,
1289 input LEDDEXE,
1290 input LEDDRST,
1291 output PWMOUT0,
1292 output PWMOUT1,
1293 output PWMOUT2,
1294 output LEDDON
1295 );
1296 endmodule
1297
1298 (* blackbox *)
1299 module SB_FILTER_50NS(
1300 input FILTERIN,
1301 output FILTEROUT
1302 );
1303 endmodule
1304
1305 module SB_IO_I3C (
1306 inout PACKAGE_PIN,
1307 input LATCH_INPUT_VALUE,
1308 input CLOCK_ENABLE,
1309 input INPUT_CLK,
1310 input OUTPUT_CLK,
1311 input OUTPUT_ENABLE,
1312 input D_OUT_0,
1313 input D_OUT_1,
1314 output D_IN_0,
1315 output D_IN_1,
1316 input PU_ENB,
1317 input WEAK_PU_ENB
1318 );
1319 parameter [5:0] PIN_TYPE = 6'b000000;
1320 parameter [0:0] PULLUP = 1'b0;
1321 parameter [0:0] WEAK_PULLUP = 1'b0;
1322 parameter [0:0] NEG_TRIGGER = 1'b0;
1323 parameter IO_STANDARD = "SB_LVCMOS";
1324
1325 `ifndef BLACKBOX
1326 reg dout, din_0, din_1;
1327 reg din_q_0, din_q_1;
1328 reg dout_q_0, dout_q_1;
1329 reg outena_q;
1330
1331 generate if (!NEG_TRIGGER) begin
1332 always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
1333 always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
1334 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
1335 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
1336 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
1337 end else begin
1338 always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
1339 always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
1340 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
1341 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
1342 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
1343 end endgenerate
1344
1345 always @* begin
1346 if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
1347 din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
1348 din_1 = din_q_1;
1349 end
1350
1351 // work around simulation glitches on dout in DDR mode
1352 reg outclk_delayed_1;
1353 reg outclk_delayed_2;
1354 always @* outclk_delayed_1 <= OUTPUT_CLK;
1355 always @* outclk_delayed_2 <= outclk_delayed_1;
1356
1357 always @* begin
1358 if (PIN_TYPE[3])
1359 dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
1360 else
1361 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
1362 end
1363
1364 assign D_IN_0 = din_0, D_IN_1 = din_1;
1365
1366 generate
1367 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
1368 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
1369 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
1370 endgenerate
1371 `endif
1372 endmodule
1373
1374 module SB_IO_OD (
1375 inout PACKAGEPIN,
1376 input LATCHINPUTVALUE,
1377 input CLOCKENABLE,
1378 input INPUTCLK,
1379 input OUTPUTCLK,
1380 input OUTPUTENABLE,
1381 input DOUT1,
1382 input DOUT0,
1383 output DIN1,
1384 output DIN0
1385 );
1386 parameter [5:0] PIN_TYPE = 6'b000000;
1387 parameter [0:0] NEG_TRIGGER = 1'b0;
1388
1389 `ifndef BLACKBOX
1390 reg dout, din_0, din_1;
1391 reg din_q_0, din_q_1;
1392 reg dout_q_0, dout_q_1;
1393 reg outena_q;
1394
1395 generate if (!NEG_TRIGGER) begin
1396 always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
1397 always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
1398 always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
1399 always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
1400 always @(posedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
1401 end else begin
1402 always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
1403 always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
1404 always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
1405 always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
1406 always @(negedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
1407 end endgenerate
1408
1409 always @* begin
1410 if (!PIN_TYPE[1] || !LATCHINPUTVALUE)
1411 din_0 = PIN_TYPE[0] ? PACKAGEPIN : din_q_0;
1412 din_1 = din_q_1;
1413 end
1414
1415 // work around simulation glitches on dout in DDR mode
1416 reg outclk_delayed_1;
1417 reg outclk_delayed_2;
1418 always @* outclk_delayed_1 <= OUTPUTCLK;
1419 always @* outclk_delayed_2 <= outclk_delayed_1;
1420
1421 always @* begin
1422 if (PIN_TYPE[3])
1423 dout = PIN_TYPE[2] ? !dout_q_0 : DOUT0;
1424 else
1425 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
1426 end
1427
1428 assign DIN0 = din_0, DIN1 = din_1;
1429
1430 generate
1431 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGEPIN = dout ? 1'bz : 1'b0;
1432 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGEPIN = OUTPUTENABLE ? (dout ? 1'bz : 1'b0) : 1'bz;
1433 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGEPIN = outena_q ? (dout ? 1'bz : 1'b0) : 1'bz;
1434 endgenerate
1435 `endif
1436 endmodule
1437
1438 module SB_MAC16 (
1439 input CLK, CE,
1440 input [15:0] C, A, B, D,
1441 input AHOLD, BHOLD, CHOLD, DHOLD,
1442 input IRSTTOP, IRSTBOT,
1443 input ORSTTOP, ORSTBOT,
1444 input OLOADTOP, OLOADBOT,
1445 input ADDSUBTOP, ADDSUBBOT,
1446 input OHOLDTOP, OHOLDBOT,
1447 input CI, ACCUMCI, SIGNEXTIN,
1448 `ABC_ARRIVAL_U(1984) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L587
1449 output [31:0] O,
1450 output CO, ACCUMCO, SIGNEXTOUT
1451 );
1452 parameter [0:0] NEG_TRIGGER = 0;
1453 parameter [0:0] C_REG = 0;
1454 parameter [0:0] A_REG = 0;
1455 parameter [0:0] B_REG = 0;
1456 parameter [0:0] D_REG = 0;
1457 parameter [0:0] TOP_8x8_MULT_REG = 0;
1458 parameter [0:0] BOT_8x8_MULT_REG = 0;
1459 parameter [0:0] PIPELINE_16x16_MULT_REG1 = 0;
1460 parameter [0:0] PIPELINE_16x16_MULT_REG2 = 0;
1461 parameter [1:0] TOPOUTPUT_SELECT = 0;
1462 parameter [1:0] TOPADDSUB_LOWERINPUT = 0;
1463 parameter [0:0] TOPADDSUB_UPPERINPUT = 0;
1464 parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
1465 parameter [1:0] BOTOUTPUT_SELECT = 0;
1466 parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
1467 parameter [0:0] BOTADDSUB_UPPERINPUT = 0;
1468 parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
1469 parameter [0:0] MODE_8x8 = 0;
1470 parameter [0:0] A_SIGNED = 0;
1471 parameter [0:0] B_SIGNED = 0;
1472
1473 wire clock = CLK ^ NEG_TRIGGER;
1474
1475 // internal wires, compare Figure on page 133 of ICE Technology Library 3.0 and Fig 2 on page 2 of Lattice TN1295-DSP
1476 // http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201608.pdf
1477 // https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/AD/DSPFunctionUsageGuideforICE40Devices.ashx
1478 wire [15:0] iA, iB, iC, iD;
1479 wire [15:0] iF, iJ, iK, iG;
1480 wire [31:0] iL, iH;
1481 wire [15:0] iW, iX, iP, iQ;
1482 wire [15:0] iY, iZ, iR, iS;
1483 wire HCI, LCI, LCO;
1484
1485 // Regs C and A
1486 reg [15:0] rC, rA;
1487 always @(posedge clock, posedge IRSTTOP) begin
1488 if (IRSTTOP) begin
1489 rC <= 0;
1490 rA <= 0;
1491 end else if (CE) begin
1492 if (!CHOLD) rC <= C;
1493 if (!AHOLD) rA <= A;
1494 end
1495 end
1496 assign iC = C_REG ? rC : C;
1497 assign iA = A_REG ? rA : A;
1498
1499 // Regs B and D
1500 reg [15:0] rB, rD;
1501 always @(posedge clock, posedge IRSTBOT) begin
1502 if (IRSTBOT) begin
1503 rB <= 0;
1504 rD <= 0;
1505 end else if (CE) begin
1506 if (!BHOLD) rB <= B;
1507 if (!DHOLD) rD <= D;
1508 end
1509 end
1510 assign iB = B_REG ? rB : B;
1511 assign iD = D_REG ? rD : D;
1512
1513 // Multiplier Stage
1514 wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl;
1515 wire [15:0] Ah, Al, Bh, Bl;
1516 assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
1517 assign Al = {A_SIGNED && MODE_8x8 ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
1518 assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
1519 assign Bl = {B_SIGNED && MODE_8x8 ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
1520 assign p_Ah_Bh = Ah * Bh; // F
1521 assign p_Al_Bh = {8'b0, Al[7:0]} * Bh; // J
1522 assign p_Ah_Bl = Ah * {8'b0, Bl[7:0]}; // K
1523 assign p_Al_Bl = Al * Bl; // G
1524
1525 // Regs F and J
1526 reg [15:0] rF, rJ;
1527 always @(posedge clock, posedge IRSTTOP) begin
1528 if (IRSTTOP) begin
1529 rF <= 0;
1530 rJ <= 0;
1531 end else if (CE) begin
1532 rF <= p_Ah_Bh;
1533 if (!MODE_8x8) rJ <= p_Al_Bh;
1534 end
1535 end
1536 assign iF = TOP_8x8_MULT_REG ? rF : p_Ah_Bh;
1537 assign iJ = PIPELINE_16x16_MULT_REG1 ? rJ : p_Al_Bh;
1538
1539 // Regs K and G
1540 reg [15:0] rK, rG;
1541 always @(posedge clock, posedge IRSTBOT) begin
1542 if (IRSTBOT) begin
1543 rK <= 0;
1544 rG <= 0;
1545 end else if (CE) begin
1546 if (!MODE_8x8) rK <= p_Ah_Bl;
1547 rG <= p_Al_Bl;
1548 end
1549 end
1550 assign iK = PIPELINE_16x16_MULT_REG1 ? rK : p_Ah_Bl;
1551 assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
1552
1553 // Adder Stage
1554 wire [23:0] iK_e = {A_SIGNED ? {8{iK[15]}} : 8'b0, iK};
1555 wire [23:0] iJ_e = {B_SIGNED ? {8{iJ[15]}} : 8'b0, iJ};
1556 assign iL = iG + (iK_e << 8) + (iJ_e << 8) + (iF << 16);
1557
1558 // Reg H
1559 reg [31:0] rH;
1560 always @(posedge clock, posedge IRSTBOT) begin
1561 if (IRSTBOT) begin
1562 rH <= 0;
1563 end else if (CE) begin
1564 if (!MODE_8x8) rH <= iL;
1565 end
1566 end
1567 assign iH = PIPELINE_16x16_MULT_REG2 ? rH : iL;
1568
1569 // Hi Output Stage
1570 wire [15:0] XW, Oh;
1571 reg [15:0] rQ;
1572 assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ;
1573 assign iX = (TOPADDSUB_LOWERINPUT == 0) ? iA : (TOPADDSUB_LOWERINPUT == 1) ? iF : (TOPADDSUB_LOWERINPUT == 2) ? iH[31:16] : {16{iZ[15]}};
1574 assign {ACCUMCO, XW} = iX + (iW ^ {16{ADDSUBTOP}}) + HCI;
1575 assign CO = ACCUMCO ^ ADDSUBTOP;
1576 assign iP = OLOADTOP ? iC : XW ^ {16{ADDSUBTOP}};
1577 always @(posedge clock, posedge ORSTTOP) begin
1578 if (ORSTTOP) begin
1579 rQ <= 0;
1580 end else if (CE) begin
1581 if (!OHOLDTOP) rQ <= iP;
1582 end
1583 end
1584 assign iQ = rQ;
1585 assign Oh = (TOPOUTPUT_SELECT == 0) ? iP : (TOPOUTPUT_SELECT == 1) ? iQ : (TOPOUTPUT_SELECT == 2) ? iF : iH[31:16];
1586 assign HCI = (TOPADDSUB_CARRYSELECT == 0) ? 1'b0 : (TOPADDSUB_CARRYSELECT == 1) ? 1'b1 : (TOPADDSUB_CARRYSELECT == 2) ? LCO : LCO ^ ADDSUBBOT;
1587 assign SIGNEXTOUT = iX[15];
1588
1589 // Lo Output Stage
1590 wire [15:0] YZ, Ol;
1591 reg [15:0] rS;
1592 assign iY = BOTADDSUB_UPPERINPUT ? iD : iS;
1593 assign iZ = (BOTADDSUB_LOWERINPUT == 0) ? iB : (BOTADDSUB_LOWERINPUT == 1) ? iG : (BOTADDSUB_LOWERINPUT == 2) ? iH[15:0] : {16{SIGNEXTIN}};
1594 assign {LCO, YZ} = iZ + (iY ^ {16{ADDSUBBOT}}) + LCI;
1595 assign iR = OLOADBOT ? iD : YZ ^ {16{ADDSUBBOT}};
1596 always @(posedge clock, posedge ORSTBOT) begin
1597 if (ORSTBOT) begin
1598 rS <= 0;
1599 end else if (CE) begin
1600 if (!OHOLDBOT) rS <= iR;
1601 end
1602 end
1603 assign iS = rS;
1604 assign Ol = (BOTOUTPUT_SELECT == 0) ? iR : (BOTOUTPUT_SELECT == 1) ? iS : (BOTOUTPUT_SELECT == 2) ? iG : iH[15:0];
1605 assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
1606 assign O = {Oh, Ol};
1607 endmodule