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
61 count <= count - 1'd1;
71 always @(posedge CLK, negedge RST) begin
72 count <= count - 1'd1;
83 $display("Both-edge reset mode for GP_COUNT14 not implemented");
89 always @(posedge CLK, posedge RST) begin
94 count <= count - 1'd1;
103 $display("Invalid RESET_MODE on GP_COUNT8");
113 module GP_COUNT14_ADV(input CLK, input RST, output reg OUT,
114 input UP, input KEEP, output reg[7:0] POUT);
116 parameter RESET_MODE = "RISING";
117 parameter RESET_VALUE = "ZERO";
119 parameter COUNT_TO = 14'h1;
120 parameter CLKIN_DIVIDE = 1;
123 if(CLKIN_DIVIDE != 1) begin
124 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
129 reg[13:0] count = COUNT_TO;
131 //Combinatorially output underflow flag whenever we wrap low
134 OUT <= (count == 14'h3fff);
136 OUT <= (count == 14'h0);
140 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
141 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
146 always @(posedge CLK, posedge RST) begin
151 count <= count + 1'd1;
152 if(count == 14'h3fff)
156 count <= count - 1'd1;
164 if(RESET_VALUE == "ZERO")
174 always @(posedge CLK, negedge RST) begin
179 count <= count + 1'd1;
180 if(count == 14'h3fff)
184 count <= count - 1'd1;
192 if(RESET_VALUE == "ZERO")
203 $display("Both-edge reset mode for GP_COUNT14_ADV not implemented");
209 always @(posedge CLK, posedge RST) begin
213 if(RESET_VALUE == "ZERO")
224 count <= count + 1'd1;
225 if(count == 14'h3fff)
229 count <= count - 1'd1;
242 $display("Invalid RESET_MODE on GP_COUNT14_ADV");
252 module GP_COUNT8_ADV(input CLK, input RST, output reg OUT,
253 input UP, input KEEP, output reg[7:0] POUT);
255 parameter RESET_MODE = "RISING";
256 parameter RESET_VALUE = "ZERO";
258 parameter COUNT_TO = 8'h1;
259 parameter CLKIN_DIVIDE = 1;
261 reg[7:0] count = COUNT_TO;
264 if(CLKIN_DIVIDE != 1) begin
265 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
270 //Combinatorially output underflow flag whenever we wrap low
273 OUT <= (count == 8'hff);
275 OUT <= (count == 8'h0);
279 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
280 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
285 always @(posedge CLK, posedge RST) begin
291 count <= count + 1'd1;
296 count <= count - 1'd1;
304 if(RESET_VALUE == "ZERO")
314 always @(posedge CLK, negedge RST) begin
320 count <= count + 1'd1;
325 count <= count - 1'd1;
333 if(RESET_VALUE == "ZERO")
344 $display("Both-edge reset mode for GP_COUNT8_ADV not implemented");
350 always @(posedge CLK, posedge RST) begin
354 if(RESET_VALUE == "ZERO")
365 count <= count + 1'd1;
370 count <= count - 1'd1;
382 $display("Invalid RESET_MODE on GP_COUNT8_ADV");
396 output reg[7:0] POUT);
398 parameter RESET_MODE = "RISING";
400 parameter COUNT_TO = 8'h1;
401 parameter CLKIN_DIVIDE = 1;
404 if(CLKIN_DIVIDE != 1) begin
405 $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented");
410 reg[7:0] count = COUNT_TO;
412 //Combinatorially output underflow flag whenever we wrap low
414 OUT <= (count == 8'h0);
418 //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm.
419 //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now.
424 always @(posedge CLK, posedge RST) begin
425 count <= count - 1'd1;
435 always @(posedge CLK, negedge RST) begin
436 count <= count - 1'd1;
447 $display("Both-edge reset mode for GP_COUNT8 not implemented");
453 always @(posedge CLK, posedge RST) begin
458 count <= count - 1'd1;
467 $display("Invalid RESET_MODE on GP_COUNT8");
477 module GP_DCMPREF(output reg[7:0]OUT);
478 parameter[7:0] REF_VAL = 8'h00;
479 initial OUT = REF_VAL;
482 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);
510 module GP_DELAY(input IN, output reg OUT);
512 parameter DELAY_STEPS = 1;
513 parameter GLITCH_FILTER = 0;
519 if(GLITCH_FILTER) begin
521 $display("ERROR: GP_DELAY glitch filter mode not implemented");
526 //TODO: These delays are PTV dependent! For now, hard code 3v3 timing
527 //Change simulation-mode delay depending on global Vdd range (how to specify this?)
535 $display("ERROR: GP_DELAY must have DELAY_STEPS in range [1,4]");
545 module GP_DFF(input D, CLK, output reg Q);
546 parameter [0:0] INIT = 1'bx;
548 always @(posedge CLK) begin
553 module GP_DFFI(input D, CLK, output reg nQ);
554 parameter [0:0] INIT = 1'bx;
556 always @(posedge CLK) begin
561 module GP_DFFR(input D, CLK, nRST, output reg Q);
562 parameter [0:0] INIT = 1'bx;
564 always @(posedge CLK, negedge nRST) begin
572 module GP_DFFRI(input D, CLK, nRST, output reg nQ);
573 parameter [0:0] INIT = 1'bx;
575 always @(posedge CLK, negedge nRST) begin
583 module GP_DFFS(input D, CLK, nSET, output reg Q);
584 parameter [0:0] INIT = 1'bx;
586 always @(posedge CLK, negedge nSET) begin
594 module GP_DFFSI(input D, CLK, nSET, output reg nQ);
595 parameter [0:0] INIT = 1'bx;
597 always @(posedge CLK, negedge nSET) begin
605 module GP_DFFSR(input D, CLK, nSR, output reg Q);
606 parameter [0:0] INIT = 1'bx;
607 parameter [0:0] SRMODE = 1'bx;
609 always @(posedge CLK, negedge nSR) begin
617 module GP_DFFSRI(input D, CLK, nSR, output reg nQ);
618 parameter [0:0] INIT = 1'bx;
619 parameter [0:0] SRMODE = 1'bx;
621 always @(posedge CLK, negedge nSR) begin
629 module GP_DLATCH(input D, input nCLK, output reg Q);
630 parameter [0:0] INIT = 1'bx;
638 module GP_DLATCHI(input D, input nCLK, output reg nQ);
639 parameter [0:0] INIT = 1'bx;
647 module GP_DLATCHR(input D, input nCLK, input nRST, output reg Q);
648 parameter [0:0] INIT = 1'bx;
658 module GP_DLATCHRI(input D, input nCLK, input nRST, output reg nQ);
659 parameter [0:0] INIT = 1'bx;
669 module GP_DLATCHS(input D, input nCLK, input nSET, output reg Q);
670 parameter [0:0] INIT = 1'bx;
680 module GP_DLATCHSI(input D, input nCLK, input nSET, output reg nQ);
681 parameter [0:0] INIT = 1'bx;
691 module GP_DLATCHSR(input D, input nCLK, input nSR, output reg Q);
692 parameter [0:0] INIT = 1'bx;
693 parameter[0:0] SRMODE = 1'bx;
703 module GP_DLATCHSRI(input D, input nCLK, input nSR, output reg nQ);
704 parameter [0:0] INIT = 1'bx;
705 parameter[0:0] SRMODE = 1'bx;
715 module GP_IBUF(input IN, output OUT);
719 module GP_IOBUF(input IN, input OE, output OUT, inout IO);
721 assign IO = OE ? IN : 1'bz;
724 module GP_INV(input IN, output OUT);
728 module GP_OBUF(input IN, output OUT);
732 module GP_OBUFT(input IN, input OE, output OUT);
733 assign OUT = OE ? IN : 1'bz;
736 module GP_PGEN(input wire nRST, input wire CLK, output reg OUT);
738 parameter PATTERN_DATA = 16'h0;
739 parameter PATTERN_LEN = 5'd16;
741 localparam COUNT_MAX = PATTERN_LEN - 1'h1;
744 always @(posedge CLK) begin
750 count <= count - 1'h1;
757 OUT = PATTERN_DATA[count];
761 module GP_SHREG(input nRST, input CLK, input IN, output OUTA, output OUTB);
763 parameter OUTA_TAP = 1;
764 parameter OUTA_INVERT = 0;
765 parameter OUTB_TAP = 1;
769 always @(posedge CLK, negedge nRST) begin
775 shreg <= {shreg[14:0], IN};
779 assign OUTA = (OUTA_INVERT) ? ~shreg[OUTA_TAP - 1] : shreg[OUTA_TAP - 1];
780 assign OUTB = shreg[OUTB_TAP - 1];
784 module GP_VDD(output OUT);
788 module GP_VSS(output OUT);