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