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