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