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