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