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