4 This file contains simulation models for GreenPAK cells which are possible to fully model using synthesizeable
5 behavioral Verilog constructs only.
8 module GP_2LUT(input IN0, IN1, output OUT);
9 parameter [3:0] INIT = 0;
10 assign OUT = INIT[{IN1, IN0}];
13 module GP_3LUT(input IN0, IN1, IN2, output OUT);
14 parameter [7:0] INIT = 0;
15 assign OUT = INIT[{IN2, IN1, IN0}];
25 parameter [15:0] INIT = 0;
26 assign OUT = INIT[{IN3, IN2, IN1, IN0}];
29 module GP_CLKBUF(input wire IN, output wire OUT);
33 module GP_COUNT14(input CLK, input wire RST, output reg OUT);
35 parameter RESET_MODE = "RISING";
37 parameter COUNT_TO = 14'h1;
38 parameter CLKIN_DIVIDE = 1;
40 reg[13:0] count = COUNT_TO;
43 if(CLKIN_DIVIDE != 1) begin
44 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
49 //Combinatorially output underflow flag whenever we wrap low
51 OUT <= (count == 14'h0);
54 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
55 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
60 always @(posedge CLK, posedge RST) begin
64 count <= count - 1'd1;
72 always @(posedge CLK, negedge RST) begin
76 count <= count - 1'd1;
85 $display("Both-edge reset mode for GP_COUNT14 not implemented");
91 always @(posedge CLK, posedge RST) begin
96 count <= count - 1'd1;
105 $display("Invalid RESET_MODE on GP_COUNT14");
115 module GP_COUNT14_ADV(input CLK, input RST, output reg OUT,
116 input UP, input KEEP, output reg[7:0] POUT);
118 parameter RESET_MODE = "RISING";
119 parameter RESET_VALUE = "ZERO";
121 parameter COUNT_TO = 14'h1;
122 parameter CLKIN_DIVIDE = 1;
125 if(CLKIN_DIVIDE != 1) begin
126 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
131 reg[13:0] count = COUNT_TO;
133 //Combinatorially output underflow flag whenever we wrap low
136 OUT <= (count == 14'h3fff);
138 OUT <= (count == 14'h0);
142 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
143 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
148 always @(posedge CLK, posedge RST) begin
152 if(RESET_VALUE == "ZERO")
161 count <= count + 1'd1;
162 if(count == 14'h3fff)
166 count <= count - 1'd1;
176 always @(posedge CLK, negedge RST) begin
180 if(RESET_VALUE == "ZERO")
189 count <= count + 1'd1;
190 if(count == 14'h3fff)
194 count <= count - 1'd1;
205 $display("Both-edge reset mode for GP_COUNT14_ADV not implemented");
211 always @(posedge CLK, posedge RST) begin
215 if(RESET_VALUE == "ZERO")
226 count <= count + 1'd1;
227 if(count == 14'h3fff)
231 count <= count - 1'd1;
244 $display("Invalid RESET_MODE on GP_COUNT14_ADV");
254 module GP_COUNT8_ADV(input CLK, input RST, output reg OUT,
255 input UP, input KEEP, output reg[7:0] POUT);
257 parameter RESET_MODE = "RISING";
258 parameter RESET_VALUE = "ZERO";
260 parameter COUNT_TO = 8'h1;
261 parameter CLKIN_DIVIDE = 1;
263 reg[7:0] count = COUNT_TO;
266 if(CLKIN_DIVIDE != 1) begin
267 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
272 //Combinatorially output underflow flag whenever we wrap low
275 OUT <= (count == 8'hff);
277 OUT <= (count == 8'h0);
281 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
282 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
287 always @(posedge CLK, posedge RST) begin
291 if(RESET_VALUE == "ZERO")
301 count <= count + 1'd1;
306 count <= count - 1'd1;
316 always @(posedge CLK, negedge RST) begin
320 if(RESET_VALUE == "ZERO")
330 count <= count + 1'd1;
335 count <= count - 1'd1;
346 $display("Both-edge reset mode for GP_COUNT8_ADV not implemented");
352 always @(posedge CLK, posedge RST) begin
356 if(RESET_VALUE == "ZERO")
367 count <= count + 1'd1;
372 count <= count - 1'd1;
384 $display("Invalid RESET_MODE on GP_COUNT8_ADV");
398 output reg[7:0] POUT);
400 parameter RESET_MODE = "RISING";
402 parameter COUNT_TO = 8'h1;
403 parameter CLKIN_DIVIDE = 1;
406 if(CLKIN_DIVIDE != 1) begin
407 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
412 reg[7:0] count = COUNT_TO;
414 //Combinatorially output underflow flag whenever we wrap low
416 OUT <= (count == 8'h0);
420 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
421 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
426 always @(posedge CLK, posedge RST) begin
430 count <= count - 1'd1;
438 always @(posedge CLK, negedge RST) begin
442 count <= count - 1'd1;
451 $display("Both-edge reset mode for GP_COUNT8 not implemented");
457 always @(posedge CLK, posedge RST) begin
462 count <= count - 1'd1;
471 $display("Invalid RESET_MODE on GP_COUNT8");
481 module GP_DCMPREF(output reg[7:0]OUT);
482 parameter[7:0] REF_VAL = 8'h00;
483 initial OUT = REF_VAL;
486 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);
514 module GP_DELAY(input IN, output reg OUT);
516 parameter DELAY_STEPS = 1;
517 parameter GLITCH_FILTER = 0;
523 if(GLITCH_FILTER) begin
525 $display("ERROR: GP_DELAY glitch filter mode not implemented");
530 //TODO: These delays are PTV dependent! For now, hard code 3v3 timing
531 //Change simulation-mode delay depending on global Vdd range (how to specify this?)
539 $display("ERROR: GP_DELAY must have DELAY_STEPS in range [1,4]");
549 module GP_DFF(input D, CLK, output reg Q);
550 parameter [0:0] INIT = 1'bx;
552 always @(posedge CLK) begin
557 module GP_DFFI(input D, CLK, output reg nQ);
558 parameter [0:0] INIT = 1'bx;
560 always @(posedge CLK) begin
565 module GP_DFFR(input D, CLK, nRST, output reg Q);
566 parameter [0:0] INIT = 1'bx;
568 always @(posedge CLK, negedge nRST) begin
576 module GP_DFFRI(input D, CLK, nRST, output reg nQ);
577 parameter [0:0] INIT = 1'bx;
579 always @(posedge CLK, negedge nRST) begin
587 module GP_DFFS(input D, CLK, nSET, output reg Q);
588 parameter [0:0] INIT = 1'bx;
590 always @(posedge CLK, negedge nSET) begin
598 module GP_DFFSI(input D, CLK, nSET, output reg nQ);
599 parameter [0:0] INIT = 1'bx;
601 always @(posedge CLK, negedge nSET) begin
609 module GP_DFFSR(input D, CLK, nSR, output reg Q);
610 parameter [0:0] INIT = 1'bx;
611 parameter [0:0] SRMODE = 1'bx;
613 always @(posedge CLK, negedge nSR) begin
621 module GP_DFFSRI(input D, CLK, nSR, output reg nQ);
622 parameter [0:0] INIT = 1'bx;
623 parameter [0:0] SRMODE = 1'bx;
625 always @(posedge CLK, negedge nSR) begin
633 module GP_DLATCH(input D, input nCLK, output reg Q);
634 parameter [0:0] INIT = 1'bx;
642 module GP_DLATCHI(input D, input nCLK, output reg nQ);
643 parameter [0:0] INIT = 1'bx;
651 module GP_DLATCHR(input D, input nCLK, input nRST, output reg Q);
652 parameter [0:0] INIT = 1'bx;
662 module GP_DLATCHRI(input D, input nCLK, input nRST, output reg nQ);
663 parameter [0:0] INIT = 1'bx;
673 module GP_DLATCHS(input D, input nCLK, input nSET, output reg Q);
674 parameter [0:0] INIT = 1'bx;
684 module GP_DLATCHSI(input D, input nCLK, input nSET, output reg nQ);
685 parameter [0:0] INIT = 1'bx;
695 module GP_DLATCHSR(input D, input nCLK, input nSR, output reg Q);
696 parameter [0:0] INIT = 1'bx;
697 parameter[0:0] SRMODE = 1'bx;
707 module GP_DLATCHSRI(input D, input nCLK, input nSR, output reg nQ);
708 parameter [0:0] INIT = 1'bx;
709 parameter[0:0] SRMODE = 1'bx;
719 module GP_IBUF(input IN, output OUT);
723 module GP_IOBUF(input IN, input OE, output OUT, inout IO);
725 assign IO = OE ? IN : 1'bz;
728 module GP_INV(input IN, output OUT);
732 module GP_OBUF(input IN, output OUT);
736 module GP_OBUFT(input IN, input OE, output OUT);
737 assign OUT = OE ? IN : 1'bz;
740 module GP_PGEN(input wire nRST, input wire CLK, output reg OUT);
742 parameter PATTERN_DATA = 16'h0;
743 parameter PATTERN_LEN = 5'd16;
745 localparam COUNT_MAX = PATTERN_LEN - 1'h1;
748 always @(posedge CLK, negedge nRST) begin
754 count <= count - 1'h1;
761 OUT = PATTERN_DATA[count];
765 module GP_SHREG(input nRST, input CLK, input IN, output OUTA, output OUTB);
767 parameter OUTA_TAP = 1;
768 parameter OUTA_INVERT = 0;
769 parameter OUTB_TAP = 1;
773 always @(posedge CLK, negedge nRST) begin
779 shreg <= {shreg[14:0], IN};
783 assign OUTA = (OUTA_INVERT) ? ~shreg[OUTA_TAP - 1] : shreg[OUTA_TAP - 1];
784 assign OUTB = shreg[OUTB_TAP - 1];
788 module GP_VDD(output OUT);
792 module GP_VSS(output OUT);