ccf9840c7b0408886e1f4b58e0206dd728378b35
[yosys.git] / techlibs / greenpak4 / cells_sim_digital.v
1 `timescale 1ns/1ps
2
3 /*
4 This file contains simulation models for GreenPAK cells which are possible to fully model using synthesizeable
5 behavioral Verilog constructs only.
6 */
7
8 module GP_2LUT(input IN0, IN1, output OUT);
9 parameter [3:0] INIT = 0;
10 assign OUT = INIT[{IN1, IN0}];
11 endmodule
12
13 module GP_3LUT(input IN0, IN1, IN2, output OUT);
14 parameter [7:0] INIT = 0;
15 assign OUT = INIT[{IN2, IN1, IN0}];
16 endmodule
17
18 module GP_4LUT(
19 input wire IN0,
20 input wire IN1,
21 input wire IN2,
22 input wire IN3,
23 output wire OUT);
24
25 parameter [15:0] INIT = 0;
26 assign OUT = INIT[{IN3, IN2, IN1, IN0}];
27 endmodule
28
29 module GP_CLKBUF(input wire IN, output wire OUT);
30 assign OUT = IN;
31 endmodule
32
33 module GP_COUNT8(
34 input wire CLK,
35 input wire RST,
36 output reg OUT,
37 output reg[7:0] POUT);
38
39 parameter RESET_MODE = "RISING";
40
41 parameter COUNT_TO = 8'h1;
42 parameter CLKIN_DIVIDE = 1;
43
44 reg[7:0] count = COUNT_TO;
45
46 //Combinatorially output underflow flag whenever we wrap low
47 always @(*) begin
48 OUT <= (count == 8'h0);
49 OUT <= count;
50 end
51
52 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
53 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
54 generate
55 case(RESET_MODE)
56
57 "RISING": begin
58 always @(posedge CLK or posedge RST) begin
59 count <= count - 1'd1;
60 if(count == 0)
61 count <= COUNT_TO;
62
63 if(RST)
64 count <= 0;
65 end
66 end
67
68 "FALLING": begin
69 always @(posedge CLK or negedge RST) begin
70 count <= count - 1'd1;
71 if(count == 0)
72 count <= COUNT_TO;
73
74 if(!RST)
75 count <= 0;
76 end
77 end
78
79 "BOTH": begin
80 initial begin
81 $display("Both-edge reset mode for GP_COUNT8 not implemented");
82 $finish;
83 end
84 end
85
86 "LEVEL": begin
87 end
88
89 default: begin
90 initial begin
91 $display("Invalid RESET_MODE on GP_COUNT8");
92 $finish;
93 end
94 end
95
96 endcase
97 endgenerate
98
99 endmodule
100
101 module GP_DCMPREF(output reg[7:0]OUT);
102 parameter[7:0] REF_VAL = 8'h00;
103 initial OUT = REF_VAL;
104 endmodule
105
106 module GP_DCMPMUX(input[1:0] SEL, input[7:0] IN0, input[7:0] IN1, input[7:0] IN2, input[7:0] IN3, output reg[7:0] OUTA, output reg[7:0] OUTB);
107
108 always @(*) begin
109 case(SEL)
110 2'd00: begin
111 OUTA <= IN0;
112 OUTB <= IN3;
113 end
114
115 2'd01: begin
116 OUTA <= IN1;
117 OUTB <= IN2;
118 end
119
120 2'd02: begin
121 OUTA <= IN2;
122 OUTB <= IN1;
123 end
124
125 2'd03: begin
126 OUTA <= IN3;
127 OUTB <= IN0;
128 end
129
130 endcase
131 end
132 endmodule
133
134 module GP_DELAY(input IN, output reg OUT);
135
136 parameter DELAY_STEPS = 1;
137 parameter GLITCH_FILTER = 0;
138
139 initial OUT = 0;
140
141 generate
142
143 if(GLITCH_FILTER) begin
144 initial begin
145 $display("ERROR: GP_DELAY glitch filter mode not implemented");
146 $finish;
147 end
148 end
149
150 //TODO: These delays are PTV dependent! For now, hard code 3v3 timing
151 //Change simulation-mode delay depending on global Vdd range (how to specify this?)
152 always @(*) begin
153 case(DELAY_STEPS)
154 1: #166 OUT = IN;
155 2: #318 OUT = IN;
156 2: #471 OUT = IN;
157 3: #622 OUT = IN;
158 default: begin
159 $display("ERROR: GP_DELAY must have DELAY_STEPS in range [1,4]");
160 $finish;
161 end
162 endcase
163 end
164
165 endgenerate
166
167 endmodule
168
169 module GP_DFF(input D, CLK, output reg Q);
170 parameter [0:0] INIT = 1'bx;
171 initial Q = INIT;
172 always @(posedge CLK) begin
173 Q <= D;
174 end
175 endmodule
176
177 module GP_DFFI(input D, CLK, output reg nQ);
178 parameter [0:0] INIT = 1'bx;
179 initial nQ = INIT;
180 always @(posedge CLK) begin
181 nQ <= ~D;
182 end
183 endmodule
184
185 module GP_DFFR(input D, CLK, nRST, output reg Q);
186 parameter [0:0] INIT = 1'bx;
187 initial Q = INIT;
188 always @(posedge CLK, negedge nRST) begin
189 if (!nRST)
190 Q <= 1'b0;
191 else
192 Q <= D;
193 end
194 endmodule
195
196 module GP_DFFRI(input D, CLK, nRST, output reg nQ);
197 parameter [0:0] INIT = 1'bx;
198 initial nQ = INIT;
199 always @(posedge CLK, negedge nRST) begin
200 if (!nRST)
201 nQ <= 1'b1;
202 else
203 nQ <= ~D;
204 end
205 endmodule
206
207 module GP_DFFS(input D, CLK, nSET, output reg Q);
208 parameter [0:0] INIT = 1'bx;
209 initial Q = INIT;
210 always @(posedge CLK, negedge nSET) begin
211 if (!nSET)
212 Q <= 1'b1;
213 else
214 Q <= D;
215 end
216 endmodule
217
218 module GP_DFFSI(input D, CLK, nSET, output reg nQ);
219 parameter [0:0] INIT = 1'bx;
220 initial nQ = INIT;
221 always @(posedge CLK, negedge nSET) begin
222 if (!nSET)
223 nQ <= 1'b0;
224 else
225 nQ <= ~D;
226 end
227 endmodule
228
229 module GP_DFFSR(input D, CLK, nSR, output reg Q);
230 parameter [0:0] INIT = 1'bx;
231 parameter [0:0] SRMODE = 1'bx;
232 initial Q = INIT;
233 always @(posedge CLK, negedge nSR) begin
234 if (!nSR)
235 Q <= SRMODE;
236 else
237 Q <= D;
238 end
239 endmodule
240
241 module GP_DFFSRI(input D, CLK, nSR, output reg nQ);
242 parameter [0:0] INIT = 1'bx;
243 parameter [0:0] SRMODE = 1'bx;
244 initial nQ = INIT;
245 always @(posedge CLK, negedge nSR) begin
246 if (!nSR)
247 nQ <= ~SRMODE;
248 else
249 nQ <= ~D;
250 end
251 endmodule
252
253 module GP_DLATCH(input D, input nCLK, output reg Q);
254 parameter [0:0] INIT = 1'bx;
255 initial Q = INIT;
256 always @(*) begin
257 if(!nCLK)
258 Q <= D;
259 end
260 endmodule
261
262 module GP_DLATCHI(input D, input nCLK, output reg nQ);
263 parameter [0:0] INIT = 1'bx;
264 initial nQ = INIT;
265 always @(*) begin
266 if(!nCLK)
267 nQ <= ~D;
268 end
269 endmodule
270
271 module GP_DLATCHR(input D, input nCLK, input nRST, output reg Q);
272 parameter [0:0] INIT = 1'bx;
273 initial Q = INIT;
274 always @(*) begin
275 if(!nRST)
276 Q <= 1'b0;
277 else if(!nCLK)
278 Q <= D;
279 end
280 endmodule
281
282 module GP_DLATCHRI(input D, input nCLK, input nRST, output reg nQ);
283 parameter [0:0] INIT = 1'bx;
284 initial nQ = INIT;
285 always @(*) begin
286 if(!nRST)
287 nQ <= 1'b1;
288 else if(!nCLK)
289 nQ <= ~D;
290 end
291 endmodule
292
293 module GP_DLATCHS(input D, input nCLK, input nSET, output reg Q);
294 parameter [0:0] INIT = 1'bx;
295 initial Q = INIT;
296 always @(*) begin
297 if(!nSET)
298 Q <= 1'b1;
299 else if(!nCLK)
300 Q <= D;
301 end
302 endmodule
303
304 module GP_DLATCHSI(input D, input nCLK, input nSET, output reg nQ);
305 parameter [0:0] INIT = 1'bx;
306 initial nQ = INIT;
307 always @(*) begin
308 if(!nSET)
309 nQ <= 1'b0;
310 else if(!nCLK)
311 nQ <= ~D;
312 end
313 endmodule
314
315 module GP_DLATCHSR(input D, input nCLK, input nSR, output reg Q);
316 parameter [0:0] INIT = 1'bx;
317 parameter[0:0] SRMODE = 1'bx;
318 initial Q = INIT;
319 always @(*) begin
320 if(!nSR)
321 Q <= SRMODE;
322 else if(!nCLK)
323 Q <= D;
324 end
325 endmodule
326
327 module GP_DLATCHSRI(input D, input nCLK, input nSR, output reg nQ);
328 parameter [0:0] INIT = 1'bx;
329 parameter[0:0] SRMODE = 1'bx;
330 initial nQ = INIT;
331 always @(*) begin
332 if(!nSR)
333 nQ <= ~SRMODE;
334 else if(!nCLK)
335 nQ <= ~D;
336 end
337 endmodule
338
339 module GP_IBUF(input IN, output OUT);
340 assign OUT = IN;
341 endmodule
342
343 module GP_IOBUF(input IN, input OE, output OUT, inout IO);
344 assign OUT = IO;
345 assign IO = OE ? IN : 1'bz;
346 endmodule
347
348 module GP_INV(input IN, output OUT);
349 assign OUT = ~IN;
350 endmodule
351
352 module GP_OBUF(input IN, output OUT);
353 assign OUT = IN;
354 endmodule
355
356 module GP_OBUFT(input IN, input OE, output OUT);
357 assign OUT = OE ? IN : 1'bz;
358 endmodule
359
360 module GP_PGEN(input wire nRST, input wire CLK, output reg OUT);
361 initial OUT = 0;
362 parameter PATTERN_DATA = 16'h0;
363 parameter PATTERN_LEN = 5'd16;
364
365 reg[3:0] count = 0;
366 always @(posedge CLK) begin
367 if(!nRST)
368 OUT <= PATTERN_DATA[0];
369
370 else begin
371 count <= count + 1;
372 OUT <= PATTERN_DATA[count];
373
374 if( (count + 1) == PATTERN_LEN)
375 count <= 0;
376 end
377 end
378
379 endmodule
380
381 module GP_SHREG(input nRST, input CLK, input IN, output OUTA, output OUTB);
382
383 parameter OUTA_TAP = 1;
384 parameter OUTA_INVERT = 0;
385 parameter OUTB_TAP = 1;
386
387 reg[15:0] shreg = 0;
388
389 always @(posedge CLK, negedge nRST) begin
390
391 if(!nRST)
392 shreg = 0;
393
394 else
395 shreg <= {shreg[14:0], IN};
396
397 end
398
399 assign OUTA = (OUTA_INVERT) ? ~shreg[OUTA_TAP - 1] : shreg[OUTA_TAP - 1];
400 assign OUTB = shreg[OUTB_TAP - 1];
401
402 endmodule
403
404 module GP_VDD(output OUT);
405 assign OUT = 1;
406 endmodule
407
408 module GP_VSS(output OUT);
409 assign OUT = 0;
410 endmodule