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