1//-------------------------------------------------------------------------
2// This Verilog file was developed by Altera Corporation.  It may be
3// freely copied and/or distributed at no cost.  Any persons using this
4// file for any purpose do so at their own risk, and are responsible for
5// the results of such use.  Altera Corporation does not guarantee that
6// this file is complete, correct, or fit for any particular purpose.
7// NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.  This notice must
8// accompany any copy of this file.
9//------------------------------------------------------------------------
10//
11// Quartus Prime 16.1.0 Build 196 10/24/2016
12//
13//------------------------------------------------------------------------
14// LPM Synthesizable Models (Support string type generic)
15// These models are based on LPM version 220 (EIA-IS103 October 1998).
16//------------------------------------------------------------------------
17//
18//-----------------------------------------------------------------------------
19// Assumptions:
20//
21// 1. The default value for LPM_SVALUE, LPM_AVALUE, LPM_PVALUE, and
22//    LPM_STRENGTH is string UNUSED.
23//
24//-----------------------------------------------------------------------------
25// Verilog Language Issues:
26//
27// Two dimensional ports are not supported. Modules with two dimensional
28// ports are implemented as one dimensional signal of (LPM_SIZE * LPM_WIDTH)
29// bits wide.
30//
31//-----------------------------------------------------------------------------
32//START_MODULE_NAME------------------------------------------------------------
33//
34// Module Name     :  LPM_MEMORY_INITIALIZATION
35//
36// Description     :  Common function to read intel-hex format data file with
37//                    extension .hex and creates the equivalent verilog format
38//                    data file with extension .ver.
39//
40// Limitation      :  Supports only record type '00'(data record), '01'(end of
41//                     file record) and '02'(extended segment address record).
42//
43// Results expected:  Creates the verilog format data file with extension .ver
44//                     and return the name of the file.
45//
46//END_MODULE_NAME--------------------------------------------------------------
47
48//See also: https://github.com/twosigma/verilator_support
49// verilator lint_off COMBDLY
50// verilator lint_off INITIALDLY
51// verilator lint_off MULTIDRIVEN
52// verilator lint_off UNSIGNED
53// verilator lint_off WIDTH
54// verilator lint_off LATCH
55
56// BEGINNING OF MODULE
57`timescale 1 ps / 1 ps
58
59`define LPM_TRUE 1
60`define LPM_FALSE 0
61`define LPM_NULL 0
62`define LPM_EOF -1
63`define LPM_MAX_NAME_SZ     128
64`define LPM_MAX_WIDTH       256
65`define LPM_COLON           ":"
66`define LPM_DOT             "."
67`define LPM_NEWLINE         "\n"
68`define LPM_CARRIAGE_RETURN  8'h0D
69`define LPM_SPACE           " "
70`define LPM_TAB             "\t"
71`define LPM_OPEN_BRACKET    "["
72`define LPM_CLOSE_BRACKET   "]"
73`define LPM_OFFSET          9
74`define LPM_H10             8'h10
75`define LPM_H10000          20'h10000
76`define LPM_AWORD           8
77`define LPM_MASK15          32'h000000FF
78`define LPM_EXT_STR         "ver"
79`define LPM_PERCENT         "%"
80`define LPM_MINUS           "-"
81`define LPM_SEMICOLON       ";"
82`define LPM_EQUAL           "="
83
84// MODULE DECLARATION
85module LPM_MEMORY_INITIALIZATION;
86
87/****************************************************************/
88/* convert uppercase character values to lowercase.             */
89/****************************************************************/
90function [8:1] tolower;
91    input [8:1] given_character;
92    reg [8:1] conv_char;
93
94begin
95    if ((given_character >= 65) && (given_character <= 90)) // ASCII number of 'A' is 65, 'Z' is 90
96    begin
97        conv_char = given_character + 32; // 32 is the difference in the position of 'A' and 'a' in the ASCII char set
98        tolower = conv_char;
99    end
100    else
101        tolower = given_character;
102end
103endfunction
104
105/****************************************************************/
106/* Read in Altera-mif format data to verilog format data.       */
107/****************************************************************/
108task convert_mif2ver;
109    input[`LPM_MAX_NAME_SZ*8 : 1] in_file;
110    input width;
111    output [`LPM_MAX_NAME_SZ*8 : 1] out_file;
112    reg [`LPM_MAX_NAME_SZ*8 : 1] in_file;
113    reg [`LPM_MAX_NAME_SZ*8 : 1] out_file;
114    reg [`LPM_MAX_NAME_SZ*8 : 1] buffer;
115    reg [`LPM_MAX_WIDTH : 0] memory_data1, memory_data2;
116    reg [8 : 1] c;
117    reg [3 : 0] hex, tmp_char;
118    reg [24 : 1] address_radix, data_radix;
119    reg get_width;
120    reg get_depth;
121    reg get_data_radix;
122    reg get_address_radix;
123    reg width_found;
124    reg depth_found;
125    reg data_radix_found;
126    reg address_radix_found;
127    reg get_address_data_pairs;
128    reg get_address;
129    reg get_data;
130    reg display_address;
131    reg invalid_address;
132    reg get_start_address;
133    reg get_end_address;
134    reg done;
135    reg error_status;
136    reg first_rec;
137    reg last_rec;
138
139    integer width;
140    integer memory_width, memory_depth;
141    integer value;
142    integer ifp, ofp, r, r2;
143    integer i, j, k, m, n;
144
145    integer off_addr, nn, address, tt, cc, aah, aal, dd, sum ;
146    integer start_address, end_address;
147    integer line_no;
148    integer character_count;
149    integer comment_with_percent_found;
150    integer comment_with_double_minus_found;
151
152begin
153        done = `LPM_FALSE;
154        error_status = `LPM_FALSE;
155        first_rec = `LPM_FALSE;
156        last_rec = `LPM_FALSE;
157        comment_with_percent_found = `LPM_FALSE;
158        comment_with_double_minus_found = `LPM_FALSE;
159
160        off_addr= 0;
161        nn= 0;
162        address = 0;
163        start_address = 0;
164        end_address = 0;
165        tt= 0;
166        cc= 0;
167        aah= 0;
168        aal= 0;
169        dd= 0;
170        sum = 0;
171        line_no = 1;
172        c = 0;
173        hex = 0;
174        value = 0;
175        buffer = "";
176        character_count = 0;
177        memory_width = 0;
178        memory_depth = 0;
179        memory_data1 = {(`LPM_MAX_WIDTH+1) {1'b0}};
180        memory_data2 = {(`LPM_MAX_WIDTH+1) {1'b0}};
181        address_radix = "hex";
182        data_radix = "hex";
183        get_width = `LPM_FALSE;
184        get_depth = `LPM_FALSE;
185        get_data_radix = `LPM_FALSE;
186        get_address_radix = `LPM_FALSE;
187        width_found = `LPM_FALSE;
188        depth_found = `LPM_FALSE;
189        data_radix_found = `LPM_FALSE;
190        address_radix_found = `LPM_FALSE;
191        get_address_data_pairs = `LPM_FALSE;
192        display_address = `LPM_FALSE;
193        invalid_address = `LPM_FALSE;
194        get_start_address = `LPM_FALSE;
195        get_end_address = `LPM_FALSE;
196
197        if((in_file[4*8 : 1] == ".dat") || (in_file[4*8 : 1] == ".DAT"))
198            out_file = in_file;
199        else
200        begin
201            ifp = $fopen(in_file, "r");
202
203            if (ifp == `LPM_NULL)
204            begin
205                $display("ERROR: cannot read %0s.", in_file);
206                $display("Time: %0t  Instance: %m", $time);
207                done = `LPM_TRUE;
208            end
209
210            out_file = in_file;
211
212            if((out_file[4*8 : 1] == ".mif") || (out_file[4*8 : 1] == ".MIF"))
213                out_file[3*8 : 1] = `LPM_EXT_STR;
214            else
215            begin
216                $display("ERROR: Invalid input file name %0s. Expecting file with .mif extension and Altera-mif data format.", in_file);
217                $display("Time: %0t  Instance: %m", $time);
218                done = `LPM_TRUE;
219            end
220
221            if (!done)
222            begin
223                ofp = $fopen(out_file, "w");
224
225                if (ofp == `LPM_NULL)
226                begin
227                    $display("ERROR : cannot write %0s.", out_file);
228                    $display("Time: %0t  Instance: %m", $time);
229                    done = `LPM_TRUE;
230                end
231            end
232
233            while((!done) && (!error_status))
234            begin : READER
235
236                r = $fgetc(ifp);
237
238                if (r == `LPM_EOF)
239                begin
240                // to do : add more checking on whether a particular assigment(width, depth, memory/address) are mising
241                    if(!first_rec)
242                    begin
243                        error_status = `LPM_TRUE;
244                        $display("WARNING: %0s, Intel-hex data file is empty.", in_file);
245                        $display ("Time: %0t  Instance: %m", $time);
246                    end
247                    else if (!get_address_data_pairs)
248                    begin
249                        error_status = `LPM_TRUE;
250                        $display("ERROR: %0s, line %0d, Missing `content begin` statement.", in_file, line_no);
251                        $display("Time: %0t  Instance: %m", $time);
252                    end
253                    else if(!last_rec)
254                    begin
255                        error_status = `LPM_TRUE;
256                        $display("ERROR: %0s, line %0d, Missing `end` statement.", in_file, line_no);
257                        $display("Time: %0t  Instance: %m", $time);
258                    end
259                    done = `LPM_TRUE;
260                end
261                else if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN))
262                begin
263                    if ((buffer == "contentbegin") && (get_address_data_pairs == `LPM_FALSE))
264                    begin
265                        get_address_data_pairs = `LPM_TRUE;
266                        get_address = `LPM_TRUE;
267                        buffer = "";
268                    end
269                    else if (buffer == "content")
270                    begin
271                        // continue to next character
272                    end
273                    else
274                    if (buffer != "")
275                    begin
276                        // found invalid syntax in the particular line.
277                        error_status = `LPM_TRUE;
278                        $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no);
279                        $display("Time: %0t  Instance: %m", $time);
280                        disable READER;
281                    end
282                    line_no = line_no +1;
283
284                end
285                else if ((r == `LPM_SPACE) || (r == `LPM_TAB))
286                begin
287                    // continue to next character;
288                end
289                else if (r == `LPM_PERCENT)
290                begin
291                    // Ignore all the characters which which is part of comment.
292                    r = $fgetc(ifp);
293
294                    while ((r != `LPM_PERCENT) && (r != `LPM_NEWLINE) && (r != `LPM_CARRIAGE_RETURN))
295                    begin
296                        r = $fgetc(ifp);
297                    end
298
299                    if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN))
300                    begin
301                        line_no = line_no +1;
302
303                        if ((buffer == "contentbegin") && (get_address_data_pairs == `LPM_FALSE))
304                        begin
305                            get_address_data_pairs = `LPM_TRUE;
306                            get_address = `LPM_TRUE;
307                            buffer = "";
308                        end
309                    end
310                end
311                else if (r == `LPM_MINUS)
312                begin
313                    r = $fgetc(ifp);
314                    if (r == `LPM_MINUS)
315                    begin
316                        // Ignore all the characters which which is part of comment.
317                        r = $fgetc(ifp);
318
319                        while ((r != `LPM_NEWLINE) && (r != `LPM_CARRIAGE_RETURN))
320                        begin
321                            r = $fgetc(ifp);
322
323                        end
324
325                        if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN))
326                        begin
327                            line_no = line_no +1;
328
329                            if ((buffer == "contentbegin") && (get_address_data_pairs == `LPM_FALSE))
330                            begin
331                                get_address_data_pairs = `LPM_TRUE;
332                                get_address = `LPM_TRUE;
333                                buffer = "";
334                            end
335                        end
336                    end
337                    else
338                    begin
339                        error_status = `LPM_TRUE;
340                        $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no);
341                        $display("Time: %0t  Instance: %m", $time);
342                        done = `LPM_TRUE;
343                        disable READER;
344                    end
345                end
346                else if (r == `LPM_EQUAL)
347                begin
348                    if (buffer == "width")
349                    begin
350                        if (width_found == `LPM_FALSE)
351                        begin
352                            get_width = `LPM_TRUE;
353                            buffer = "";
354                        end
355                        else
356                        begin
357                            error_status = `LPM_TRUE;
358                            $display("ERROR: %0s, line %0d, Width has already been specified once.", in_file, line_no);
359                            $display("Time: %0t  Instance: %m", $time);
360                        end
361                    end
362                    else if (buffer == "depth")
363                    begin
364                        get_depth = `LPM_TRUE;
365                        buffer = "";
366                    end
367                    else if (buffer == "data_radix")
368                    begin
369                        get_data_radix = `LPM_TRUE;
370                        buffer = "";
371                    end
372                    else if (buffer == "address_radix")
373                    begin
374                        get_address_radix = `LPM_TRUE;
375                        buffer = "";
376                    end
377                    else
378                    begin
379                        error_status = `LPM_TRUE;
380                        $display("ERROR: %0s, line %0d, Unknown setting (%0s).", in_file, line_no, buffer);
381                        $display("Time: %0t  Instance: %m", $time);
382                    end
383                end
384                else if (r == `LPM_COLON)
385                begin
386                    if (!get_address_data_pairs)
387                    begin
388                        error_status = `LPM_TRUE;
389                        $display("ERROR: %0s, line %0d, Missing `content begin` statement.", in_file, line_no);
390                        $display("Time: %0t  Instance: %m", $time);
391                    end
392                    else if (invalid_address == `LPM_TRUE)
393                    begin
394                        error_status = `LPM_TRUE;
395                        $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
396                        $display("Time: %0t  Instance: %m", $time);
397                    end
398                    begin
399                        get_address = `LPM_FALSE;
400                        get_data = `LPM_TRUE;
401                        display_address = `LPM_TRUE;
402                    end
403                end
404                else if (r == `LPM_DOT)
405                begin
406                    r = $fgetc(ifp);
407                    if (r == `LPM_DOT)
408                    begin
409                        if (get_start_address == `LPM_TRUE)
410                        begin
411                            start_address = address;
412                            address = 0;
413                            get_start_address = `LPM_FALSE;
414                            get_end_address = `LPM_TRUE;
415                        end
416                        else
417                        begin
418                            error_status = `LPM_TRUE;
419                            $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no);
420                            $display("Time: %0t  Instance: %m", $time);
421                            done = `LPM_TRUE;
422                            disable READER;
423                        end
424                    end
425                    else
426                    begin
427                        error_status = `LPM_TRUE;
428                        $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no);
429                        $display("Time: %0t  Instance: %m", $time);
430                        done = `LPM_TRUE;
431                        disable READER;
432                    end
433                end
434                else if (r == `LPM_OPEN_BRACKET)
435                begin
436                    get_start_address = `LPM_TRUE;
437                end
438                else if (r == `LPM_CLOSE_BRACKET)
439                begin
440                    if (get_end_address == `LPM_TRUE)
441                    begin
442                        end_address = address;
443                        address = 0;
444                        get_end_address = `LPM_FALSE;
445                    end
446                    else
447                    begin
448                        error_status = `LPM_TRUE;
449                        $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no);
450                        $display("Time: %0t  Instance: %m", $time);
451                        done = `LPM_TRUE;
452                        disable READER;
453                    end
454                end
455                else if (r == `LPM_SEMICOLON)
456                begin
457                    if (get_width == `LPM_TRUE)
458                    begin
459                        width_found = `LPM_TRUE;
460                        memory_width = value;
461                        value = 0;
462                        get_width = `LPM_FALSE;
463                    end
464                    else if (get_depth == `LPM_TRUE)
465                    begin
466                        depth_found = `LPM_TRUE;
467                        memory_depth = value;
468                        value = 0;
469                        get_depth = `LPM_FALSE;
470                    end
471                    else if (get_data_radix == `LPM_TRUE)
472                    begin
473                        data_radix_found = `LPM_TRUE;
474                        get_data_radix = `LPM_FALSE;
475
476                        if ((buffer == "bin") || (buffer == "oct") || (buffer == "dec") || (buffer == "uns") ||
477                            (buffer == "hex"))
478                        begin
479                            data_radix = buffer[24 : 1];
480                        end
481                        else
482                        begin
483                            error_status = `LPM_TRUE;
484                            $display("ERROR: %0s, line %0d, Invalid assignment (%0s) to data_radix.", in_file, line_no, buffer);
485                            $display("Time: %0t  Instance: %m", $time);
486                        end
487                        buffer = "";
488                    end
489                    else if (get_address_radix == `LPM_TRUE)
490                    begin
491                        address_radix_found = `LPM_TRUE;
492                        get_address_radix = `LPM_FALSE;
493
494                        if ((buffer == "bin") || (buffer == "oct") || (buffer == "dec") || (buffer == "uns") ||
495                            (buffer == "hex"))
496                        begin
497                            address_radix = buffer[24 : 1];
498                        end
499                        else
500                        begin
501                            error_status = `LPM_TRUE;
502                            $display("ERROR: %0s, line %0d, Invalid assignment (%0s) to address radix.", in_file, line_no, buffer);
503                            $display("Time: %0t  Instance: %m", $time);
504                        end
505                        buffer = "";
506                    end
507                    else if (buffer == "end")
508                    begin
509                        if (get_address_data_pairs == `LPM_TRUE)
510                        begin
511                            last_rec = `LPM_TRUE;
512                            buffer = "";
513                        end
514                        else
515                        begin
516                            error_status = `LPM_TRUE;
517                            $display("ERROR: %0s, line %0d, Missing `content begin` statement.", in_file, line_no);
518                            $display("Time: %0t  Instance: %m", $time);
519                        end
520                    end
521                    else if (get_data == `LPM_TRUE)
522                    begin
523                        get_address = `LPM_TRUE;
524                        get_data = `LPM_FALSE;
525                        buffer = "";
526                        character_count = 0;
527
528                        if (start_address != end_address)
529                        begin
530                            for (address = start_address; address <= end_address; address = address+1)
531                            begin
532                                $fdisplay(ofp,"@%0h", address);
533
534                                for (i = memory_width -1; i >= 0; i = i-1 )
535                                begin
536                                    hex[(i % 4)] =  memory_data1[i];
537
538                                    if ((i % 4) == 0)
539                                    begin
540                                        $fwrite(ofp, "%0h", hex);
541                                        hex = 0;
542                                    end
543                                end
544
545                                $fwrite(ofp, "\n");
546                            end
547                            start_address = 0;
548                            end_address = 0;
549                            address = 0;
550                            hex = 0;
551                            memory_data1 = {(`LPM_MAX_WIDTH+1) {1'b0}};
552                        end
553                        else
554                        begin
555                            if (display_address == `LPM_TRUE)
556                            begin
557                                $fdisplay(ofp,"@%0h", address);
558                                display_address = `LPM_FALSE;
559                            end
560
561                            for (i = memory_width -1; i >= 0; i = i-1 )
562                            begin
563                                hex[(i % 4)] =  memory_data1[i];
564
565                                if ((i % 4) == 0)
566                                begin
567                                    $fwrite(ofp, "%0h", hex);
568                                    hex = 0;
569                                end
570                            end
571
572                            $fwrite(ofp, "\n");
573                            address = 0;
574                            hex = 0;
575                            memory_data1 = {(`LPM_MAX_WIDTH+1) {1'b0}};
576                        end
577                    end
578                    else
579                    begin
580                        error_status = `LPM_TRUE;
581                        $display("ERROR: %0s, line %0d, Invalid assigment.", in_file, line_no);
582                        $display("Time: %0t  Instance: %m", $time);
583                    end
584                end
585                else if ((get_width == `LPM_TRUE) || (get_depth == `LPM_TRUE))
586                begin
587                    if ((r >= "0") && (r <= "9"))
588                        value = (value * 10) + (r - 'h30);
589                    else
590                    begin
591                        error_status = `LPM_TRUE;
592                        $display("ERROR: %0s, line %0d, Invalid assignment to width/depth.", in_file, line_no);
593                        $display("Time: %0t  Instance: %m", $time);
594                    end
595                end
596                else if (get_address == `LPM_TRUE)
597                begin
598                    if (address_radix == "hex")
599                    begin
600                        if ((r >= "0") && (r <= "9"))
601                            value = (r - 'h30);
602                        else if ((r >= "A") && (r <= "F"))
603                            value = 10 + (r - 'h41);
604                        else if ((r >= "a") && (r <= "f"))
605                            value = 10 + (r - 'h61);
606                        else
607                        begin
608                            invalid_address = `LPM_TRUE;
609                        end
610
611                        address = (address * 16) + value;
612                    end
613                    else if ((address_radix == "dec"))
614                    begin
615                        if ((r >= "0") && (r <= "9"))
616                            value = (r - 'h30);
617                        else
618                        begin
619                            invalid_address = `LPM_TRUE;
620                        end
621
622                        address = (address * 10) + value;
623                    end
624                    else if (address_radix == "uns")
625                    begin
626                        if ((r >= "0") && (r <= "9"))
627                            value = (r - 'h30);
628                        else
629                        begin
630                            invalid_address = `LPM_TRUE;
631                        end
632
633                        address = (address * 10) + value;
634                    end
635                    else if (address_radix == "bin")
636                    begin
637                        if ((r >= "0") && (r <= "1"))
638                            value = (r - 'h30);
639                        else
640                        begin
641                            invalid_address = `LPM_TRUE;
642                        end
643
644                        address = (address * 2) + value;
645                    end
646                    else if (address_radix == "oct")
647                    begin
648                        if ((r >= "0") && (r <= "7"))
649                            value = (r - 'h30);
650                        else
651                        begin
652                            invalid_address = `LPM_TRUE;
653                        end
654
655                        address = (address * 8) + value;
656                    end
657
658                    if ((r >= 65) && (r <= 90))
659                        c = tolower(r);
660                    else
661                        c = r;
662
663                    {tmp_char,buffer} = {buffer, c};
664                end
665                else if (get_data == `LPM_TRUE)
666                begin
667                    character_count = character_count +1;
668
669                    if (data_radix == "hex")
670                    begin
671                        if ((r >= "0") && (r <= "9"))
672                            value = (r - 'h30);
673                        else if ((r >= "A") && (r <= "F"))
674                            value = 10 + (r - 'h41);
675                        else if ((r >= "a") && (r <= "f"))
676                            value = 10 + (r - 'h61);
677                        else
678                        begin
679                            error_status = `LPM_TRUE;
680                            $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
681                            $display("Time: %0t  Instance: %m", $time);
682                            done = `LPM_TRUE;
683                            disable READER;
684                        end
685
686                        memory_data1 = (memory_data1 * 16) + value;
687                    end
688                    else if ((data_radix == "dec"))
689                    begin
690                        if ((r >= "0") && (r <= "9"))
691                            value = (r - 'h30);
692                        else
693                        begin
694                            error_status = `LPM_TRUE;
695                            $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
696                            $display("Time: %0t  Instance: %m", $time);
697                            done = `LPM_TRUE;
698                            disable READER;
699                        end
700
701                        memory_data1 = (memory_data1 * 10) + value;
702                    end
703                    else if (data_radix == "uns")
704                    begin
705                        if ((r >= "0") && (r <= "9"))
706                            value = (r - 'h30);
707                        else
708                        begin
709                            error_status = `LPM_TRUE;
710                            $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
711                            $display("Time: %0t  Instance: %m", $time);
712                            done = `LPM_TRUE;
713                            disable READER;
714                        end
715
716                        memory_data1 = (memory_data1 * 10) + value;
717                    end
718                    else if (data_radix == "bin")
719                    begin
720                        if ((r >= "0") && (r <= "1"))
721                            value = (r - 'h30);
722                        else
723                        begin
724                            error_status = `LPM_TRUE;
725                            $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
726                            $display("Time: %0t  Instance: %m", $time);
727                            done = `LPM_TRUE;
728                            disable READER;
729                        end
730
731                        memory_data1 = (memory_data1 * 2) + value;
732                    end
733                    else if (data_radix == "oct")
734                    begin
735                        if ((r >= "0") && (r <= "7"))
736                            value = (r - 'h30);
737                        else
738                        begin
739                            error_status = `LPM_TRUE;
740                            $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
741                            $display("Time: %0t  Instance: %m", $time);
742                            done = `LPM_TRUE;
743                            disable READER;
744                        end
745
746                        memory_data1 = (memory_data1 * 8) + value;
747                    end
748                end
749                else
750                begin
751                    first_rec = `LPM_TRUE;
752
753                    if ((r >= 65) && (r <= 90))
754                        c = tolower(r);
755                    else
756                        c = r;
757
758                    {tmp_char,buffer} = {buffer, c};
759                end
760            end
761            $fclose(ifp);
762            $fclose(ofp);
763        end
764end
765endtask // convert_mif2ver
766
767/****************************************************************/
768/* Read in Intel-hex format data to verilog format data.        */
769/*  Intel-hex format    :nnaaaaattddddcc                        */
770/****************************************************************/
771task convert_hex2ver;
772    input[`LPM_MAX_NAME_SZ*8 : 1] in_file;
773    input width;
774    output [`LPM_MAX_NAME_SZ*8 : 1] out_file;
775    reg [`LPM_MAX_NAME_SZ*8 : 1] in_file;
776    reg [`LPM_MAX_NAME_SZ*8 : 1] out_file;
777    reg [8:1] c;
778    reg [3:0] hex, tmp_char;
779    reg done;
780    reg error_status;
781    reg first_rec;
782    reg last_rec;
783
784    integer width;
785    integer ifp, ofp, r, r2;
786    integer i, j, k, m, n;
787
788    integer off_addr, nn, aaaa, tt, cc, aah, aal, dd, sum ;
789    integer line_no;
790
791begin
792        done = `LPM_FALSE;
793        error_status = `LPM_FALSE;
794        first_rec = `LPM_FALSE;
795        last_rec = `LPM_FALSE;
796
797        off_addr= 0;
798        nn= 0;
799        aaaa= 0;
800        tt= 0;
801        cc= 0;
802        aah= 0;
803        aal= 0;
804        dd= 0;
805        sum = 0;
806        line_no = 1;
807        c = 0;
808        hex = 0;
809
810        if((in_file[4*8 : 1] == ".dat") || (in_file[4*8 : 1] == ".DAT"))
811            out_file = in_file;
812        else
813        begin
814            ifp = $fopen(in_file, "r");
815            if (ifp == `LPM_NULL)
816            begin
817                $display("ERROR: cannot read %0s.", in_file);
818                $display("Time: %0t  Instance: %m", $time);
819                done = `LPM_TRUE;
820            end
821
822            out_file = in_file;
823
824            if((out_file[4*8 : 1] == ".hex") || (out_file[4*8 : 1] == ".HEX"))
825                out_file[3*8 : 1] = `LPM_EXT_STR;
826            else
827            begin
828                $display("ERROR: Invalid input file name %0s. Expecting file with .hex extension and Intel-hex data format.", in_file);
829                $display("Time: %0t  Instance: %m", $time);
830                done = `LPM_TRUE;
831            end
832
833            if (!done)
834            begin
835                ofp = $fopen(out_file, "w");
836                if (ofp == `LPM_NULL)
837                begin
838                    $display("ERROR : cannot write %0s.", out_file);
839                    $display("Time: %0t  Instance: %m", $time);
840                    done = `LPM_TRUE;
841                end
842            end
843
844            while((!done) && (!error_status))
845            begin : READER
846
847                r = $fgetc(ifp);
848
849                if (r == `LPM_EOF)
850                begin
851                    if(!first_rec)
852                    begin
853                        error_status = `LPM_TRUE;
854                        $display("WARNING: %0s, Intel-hex data file is empty.", in_file);
855                        $display ("Time: %0t  Instance: %m", $time);
856                    end
857                    else if(!last_rec)
858                    begin
859                        error_status = `LPM_TRUE;
860                        $display("ERROR: %0s, line %0d, Missing the last record.", in_file, line_no);
861                        $display("Time: %0t  Instance: %m", $time);
862                    end
863                end
864                else if (r == `LPM_COLON)
865                begin
866                    first_rec = `LPM_TRUE;
867                    nn= 0;
868                    aaaa= 0;
869                    tt= 0;
870                    cc= 0;
871                    aah= 0;
872                    aal= 0;
873                    dd= 0;
874                    sum = 0;
875
876                    // get record length bytes
877                    for (i = 0; i < 2; i = i+1)
878                    begin
879                        r = $fgetc(ifp);
880
881                        if ((r >= "0") && (r <= "9"))
882                            nn = (nn * 16) + (r - 'h30);
883                        else if ((r >= "A") && (r <= "F"))
884                            nn = (nn * 16) + 10 + (r - 'h41);
885                        else if ((r >= "a") && (r <= "f"))
886                            nn = (nn * 16) + 10 + (r - 'h61);
887                        else
888                        begin
889                            error_status = `LPM_TRUE;
890                            $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
891                            $display("Time: %0t  Instance: %m", $time);
892                            done = `LPM_TRUE;
893                            disable READER;
894                        end
895                    end
896
897                    // get address bytes
898                    for (i = 0; i < 4; i = i+1)
899                    begin
900                        r = $fgetc(ifp);
901
902                        if ((r >= "0") && (r <= "9"))
903                            hex = (r - 'h30);
904                        else if ((r >= "A") && (r <= "F"))
905                            hex = 10 + (r - 'h41);
906                        else if ((r >= "a") && (r <= "f"))
907                            hex = 10 + (r - 'h61);
908                        else
909                        begin
910                            error_status = `LPM_TRUE;
911                            $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
912                            $display("Time: %0t  Instance: %m", $time);
913                            done = `LPM_TRUE;
914                            disable READER;
915                        end
916
917                        aaaa = (aaaa * 16) + hex;
918
919                        if (i < 2)
920                            aal = (aal * 16) + hex;
921                        else
922                            aah = (aah * 16) + hex;
923                    end
924
925                    // get record type bytes
926                    for (i = 0; i < 2; i = i+1)
927                    begin
928                        r = $fgetc(ifp);
929
930                        if ((r >= "0") && (r <= "9"))
931                            tt = (tt * 16) + (r - 'h30);
932                        else if ((r >= "A") && (r <= "F"))
933                            tt = (tt * 16) + 10 + (r - 'h41);
934                        else if ((r >= "a") && (r <= "f"))
935                            tt = (tt * 16) + 10 + (r - 'h61);
936                        else
937                        begin
938                            error_status = `LPM_TRUE;
939                            $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
940                            $display("Time: %0t  Instance: %m", $time);
941                            done = `LPM_TRUE;
942                            disable READER;
943                        end
944                    end
945
946                    if((tt == 2) && (nn != 2) )
947                    begin
948                        error_status = `LPM_TRUE;
949                        $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no);
950                        $display("Time: %0t  Instance: %m", $time);
951                    end
952                    else
953                    begin
954
955                        // get the sum of all the bytes for record length, address and record types
956                        sum = nn + aah + aal + tt ;
957
958                        // check the record type
959                        case(tt)
960                            // normal_record
961                            8'h00 :
962                            begin
963                                first_rec = `LPM_TRUE;
964                                i = 0;
965                                k = width / `LPM_AWORD;
966                                if ((width % `LPM_AWORD) != 0)
967                                    k = k + 1;
968
969                                // k = no. of bytes per entry.
970                                while (i < nn)
971                                begin
972                                    $fdisplay(ofp,"@%0h", (aaaa + off_addr));
973                                    for (j = 1; j <= k; j = j +1)
974                                    begin
975                                        if ((k - j +1) > nn)
976                                        begin
977                                            for(m = 1; m <= 2; m= m+1)
978                                            begin
979                                                if((((k-j)*8) + ((3-m)*4) - width) < 4)
980                                                    $fwrite(ofp, "0");
981                                            end
982                                        end
983                                        else
984                                        begin
985                                            // get the data bytes
986                                            for(m = 1; m <= 2; m= m+1)
987                                            begin
988                                                r = $fgetc(ifp);
989
990                                                if ((r >= "0") && (r <= "9"))
991                                                    hex = (r - 'h30);
992                                                else if ((r >= "A") && (r <= "F"))
993                                                    hex = 10 + (r - 'h41);
994                                                else if ((r >= "a") && (r <= "f"))
995                                                    hex = 10 + (r - 'h61);
996                                                else
997                                                begin
998                                                    error_status = `LPM_TRUE;
999                                                    $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1000                                                    $display("Time: %0t  Instance: %m", $time);
1001                                                    done = `LPM_TRUE;
1002                                                    disable READER;
1003                                                end
1004
1005                                                if((((k-j)*8) + ((3-m)*4) - width) < 4)
1006                                                    $fwrite(ofp, "%h", hex);
1007                                                dd = (dd * 16) + hex;
1008
1009                                                if(m % 2 == 0)
1010                                                begin
1011                                                    sum = sum + dd;
1012                                                    dd = 0;
1013                                                end
1014                                            end
1015                                        end
1016                                    end
1017                                    $fwrite(ofp, "\n");
1018
1019                                    i = i + k;
1020                                    aaaa = aaaa + 1;
1021                                end // end of while (i < nn)
1022                            end
1023                            // last record
1024                            8'h01:
1025                            begin
1026                                last_rec = `LPM_TRUE;
1027                                done = `LPM_TRUE;
1028                            end
1029                            // address base record
1030                            8'h02:
1031                            begin
1032                                off_addr= 0;
1033
1034                                // get the extended segment address record
1035                                for(i = 1; i <= (nn*2); i= i+1)
1036                                begin
1037                                    r = $fgetc(ifp);
1038
1039                                    if ((r >= "0") && (r <= "9"))
1040                                        hex = (r - 'h30);
1041                                    else if ((r >= "A") && (r <= "F"))
1042                                        hex = 10 + (r - 'h41);
1043                                    else if ((r >= "a") && (r <= "f"))
1044                                        hex = 10 + (r - 'h61);
1045                                    else
1046                                    begin
1047                                        error_status = `LPM_TRUE;
1048                                        $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1049                                        $display("Time: %0t  Instance: %m", $time);
1050                                        done = `LPM_TRUE;
1051                                        disable READER;
1052                                    end
1053
1054                                    off_addr = (off_addr * `LPM_H10) + hex;
1055                                    dd = (dd * 16) + hex;
1056
1057                                    if(i % 2 == 0)
1058                                    begin
1059                                        sum = sum + dd;
1060                                        dd = 0;
1061                                    end
1062                                end
1063
1064                                off_addr = off_addr * `LPM_H10;
1065                            end
1066                            // address base record
1067                            8'h03:
1068                                // get the start segment address record
1069                                for(i = 1; i <= (nn*2); i= i+1)
1070                                begin
1071                                    r = $fgetc(ifp);
1072
1073                                    if ((r >= "0") && (r <= "9"))
1074                                        hex = (r - 'h30);
1075                                    else if ((r >= "A") && (r <= "F"))
1076                                        hex = 10 + (r - 'h41);
1077                                    else if ((r >= "a") && (r <= "f"))
1078                                        hex = 10 + (r - 'h61);
1079                                    else
1080                                    begin
1081                                        error_status = `LPM_TRUE;
1082                                        $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1083                                        $display("Time: %0t  Instance: %m", $time);
1084                                        done = `LPM_TRUE;
1085                                        disable READER;
1086                                    end
1087                                    dd = (dd * 16) + hex;
1088
1089                                    if(i % 2 == 0)
1090                                    begin
1091                                        sum = sum + dd;
1092                                        dd = 0;
1093                                    end
1094                                end
1095                            // address base record
1096                            8'h04:
1097                            begin
1098                                off_addr= 0;
1099
1100                                // get the extended linear address record
1101                                for(i = 1; i <= (nn*2); i= i+1)
1102                                begin
1103                                    r = $fgetc(ifp);
1104
1105                                    if ((r >= "0") && (r <= "9"))
1106                                        hex = (r - 'h30);
1107                                    else if ((r >= "A") && (r <= "F"))
1108                                        hex = 10 + (r - 'h41);
1109                                    else if ((r >= "a") && (r <= "f"))
1110                                        hex = 10 + (r - 'h61);
1111                                    else
1112                                    begin
1113                                        error_status = `LPM_TRUE;
1114                                        $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1115                                        $display("Time: %0t  Instance: %m", $time);
1116                                        done = `LPM_TRUE;
1117                                        disable READER;
1118                                    end
1119
1120                                    off_addr = (off_addr * `LPM_H10) + hex;
1121                                    dd = (dd * 16) + hex;
1122
1123                                    if(i % 2 == 0)
1124                                    begin
1125                                        sum = sum + dd;
1126                                        dd = 0;
1127                                    end
1128                                end
1129
1130                                off_addr = off_addr * `LPM_H10000;
1131                            end
1132                            // address base record
1133                            8'h05:
1134                                // get the start linear address record
1135                                for(i = 1; i <= (nn*2); i= i+1)
1136                                begin
1137                                    r = $fgetc(ifp);
1138
1139                                    if ((r >= "0") && (r <= "9"))
1140                                        hex = (r - 'h30);
1141                                    else if ((r >= "A") && (r <= "F"))
1142                                        hex = 10 + (r - 'h41);
1143                                    else if ((r >= "a") && (r <= "f"))
1144                                        hex = 10 + (r - 'h61);
1145                                    else
1146                                    begin
1147                                        error_status = `LPM_TRUE;
1148                                        $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1149                                        $display("Time: %0t  Instance: %m", $time);
1150                                        done = `LPM_TRUE;
1151                                        disable READER;
1152                                    end
1153                                    dd = (dd * 16) + hex;
1154
1155                                    if(i % 2 == 0)
1156                                    begin
1157                                        sum = sum + dd;
1158                                        dd = 0;
1159                                    end
1160                                end
1161                            default:
1162                            begin
1163                                error_status = `LPM_TRUE;
1164                                $display("ERROR: %0s, line %0d, Unknown record type.", in_file, line_no);
1165                                $display("Time: %0t  Instance: %m", $time);
1166                            end
1167                        endcase
1168
1169                        // get the checksum bytes
1170                        for (i = 0; i < 2; i = i+1)
1171                        begin
1172                            r = $fgetc(ifp);
1173
1174                            if ((r >= "0") && (r <= "9"))
1175                                cc = (cc * 16) + (r - 'h30);
1176                            else if ((r >= "A") && (r <= "F"))
1177                                cc = 10 + (cc * 16) + (r - 'h41);
1178                            else if ((r >= "a") && (r <= "f"))
1179                                cc = 10 + (cc * 16) + (r - 'h61);
1180                            else
1181                            begin
1182                                error_status = `LPM_TRUE;
1183                                $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1184                                $display("Time: %0t  Instance: %m", $time);
1185                                done = `LPM_TRUE;
1186                                disable READER;
1187                            end
1188                        end
1189
1190                        // Perform check sum.
1191                        if(((~sum+1)& `LPM_MASK15) != cc)
1192                        begin
1193                            error_status = `LPM_TRUE;
1194                            $display("ERROR: %0s, line %0d, Invalid checksum.", in_file, line_no);
1195                            $display("Time: %0t  Instance: %m", $time);
1196                        end
1197                    end
1198                end
1199                else if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN))
1200                begin
1201                    line_no = line_no +1;
1202                end
1203                else if (r == `LPM_SPACE)
1204                begin
1205                    // continue to next character;
1206                end
1207                else
1208                begin
1209                    error_status = `LPM_TRUE;
1210                    $display("ERROR:%0s, line %0d, Invalid INTEL HEX record.", in_file, line_no);
1211                    $display("Time: %0t  Instance: %m", $time);
1212                    done = `LPM_TRUE;
1213                end
1214            end
1215            $fclose(ifp);
1216            $fclose(ofp);
1217        end
1218end
1219endtask // convert_hex2ver
1220
1221task convert_to_ver_file;
1222    input[`LPM_MAX_NAME_SZ*8 : 1] in_file;
1223    input width;
1224    output [`LPM_MAX_NAME_SZ*8 : 1] out_file;
1225    reg [`LPM_MAX_NAME_SZ*8 : 1] in_file;
1226    reg [`LPM_MAX_NAME_SZ*8 : 1] out_file;
1227    integer width;
1228begin
1229
1230        if((in_file[4*8 : 1] == ".hex") || (in_file[4*8 : 1] == ".HEX") ||
1231            (in_file[4*8 : 1] == ".dat") || (in_file[4*8 : 1] == ".DAT"))
1232            convert_hex2ver(in_file, width, out_file);
1233        else if((in_file[4*8 : 1] == ".mif") || (in_file[4*8 : 1] == ".MIF"))
1234            convert_mif2ver(in_file, width, out_file);
1235        else
1236        begin
1237            $display("ERROR: Invalid input file name %0s. Expecting file with .hex extension (with Intel-hex data format) or .mif extension (with Altera-mif data format).", in_file);
1238            $display("Time: %0t  Instance: %m", $time);
1239        end
1240end
1241endtask // convert_to_ver_file
1242
1243endmodule // LPM_MEMORY_INITIALIZATION
1244
1245
1246//START_MODULE_NAME------------------------------------------------------------
1247//
1248// Module Name     :  LPM_HINT_EVALUATION
1249//
1250// Description     :  Common function to grep the value of altera specific parameters
1251//                    within the lpm_hint parameter.
1252//
1253// Limitation      :  No error checking to check whether the content of the lpm_hint
1254//                    is valid or not.
1255//
1256// Results expected:  If the target parameter found, return the value of the parameter.
1257//                    Otherwise, return empty string.
1258//
1259//END_MODULE_NAME--------------------------------------------------------------
1260
1261// BEGINNING OF MODULE
1262`timescale 1 ps / 1 ps
1263
1264// MODULE DECLARATION
1265module LPM_HINT_EVALUATION;
1266
1267// FUNCTON DECLARATION
1268
1269// This function will search through the string (given string) to look for a match for the
1270// a given parameter(compare_param_name). It will return the value for the given parameter.
1271function [8*200:1] GET_PARAMETER_VALUE;
1272    input [8*200:1] given_string;  // string to be searched
1273    input [8*50:1] compare_param_name; // parameter name to be looking for in the given_string.
1274    integer param_value_char_count; // to indicate current character count in the param_value
1275    integer param_name_char_count;  // to indicate current character count in the param_name
1276    integer white_space_count;
1277
1278    reg extract_param_value; // if 1 mean extracting parameters value from given string
1279    reg extract_param_name;  // if 1 mean extracting parameters name from given string
1280    reg param_found; // to indicate whether compare_param_name have been found in the given_string
1281    reg include_white_space; // if 1, include white space in the parameter value
1282
1283    reg [8*200:1] reg_string; // to store the value of the given string
1284    reg [8*50:1] param_name;  // to store parameter name
1285    reg [8*20:1] param_value; // to store parameter value
1286    reg [8:1] tmp; // to get the value of the current byte
1287begin
1288    reg_string = given_string;
1289    param_value_char_count = 0;
1290    param_name_char_count =0;
1291    extract_param_value = 1;
1292    extract_param_name = 0;
1293    param_found = 0;
1294    include_white_space = 0;
1295    white_space_count = 0;
1296
1297    tmp = reg_string[8:1];
1298
1299    // checking every bytes of the reg_string from right to left.
1300    while ((tmp != 0 ) && (param_found != 1))
1301    begin
1302        tmp = reg_string[8:1];
1303
1304        //if tmp != ' ' or should include white space (trailing white space are ignored)
1305        if((tmp != 32) || (include_white_space == 1))
1306        begin
1307            if(tmp == 32)
1308            begin
1309                white_space_count = 1;
1310            end
1311            else if(tmp == 61)  // if tmp = '='
1312            begin
1313                extract_param_value = 0;
1314                extract_param_name =  1;  // subsequent bytes should be part of param_name
1315                include_white_space = 0;  // ignore the white space (if any) between param_name and '='
1316                white_space_count = 0;
1317                param_value = param_value >> (8 * (20 - param_value_char_count));
1318                param_value_char_count = 0;
1319            end
1320            else if (tmp == 44) // if tmp = ','
1321            begin
1322                extract_param_value = 1; // subsequent bytes should be part of param_value
1323                extract_param_name =  0;
1324                param_name = param_name >> (8 * (50 - param_name_char_count));
1325                param_name_char_count = 0;
1326                if(param_name == compare_param_name)
1327                    param_found = 1;  // the compare_param_name have been found in the reg_string
1328            end
1329            else
1330            begin
1331                if(extract_param_value == 1)
1332                begin
1333                    param_value_char_count = param_value_char_count + white_space_count + 1;
1334                    include_white_space = 1;
1335                    if(white_space_count > 0)
1336                    begin
1337                        param_value = {8'b100000, param_value[20*8:9]};
1338                        white_space_count = 0;
1339                    end
1340                    param_value = {tmp, param_value[20*8:9]};
1341                end
1342                else if(extract_param_name == 1)
1343                begin
1344                    param_name = {tmp, param_name[50*8:9]};
1345                    param_name_char_count = param_name_char_count + 1;
1346                end
1347            end
1348        end
1349        reg_string = reg_string >> 8;  // shift 1 byte to the right
1350    end
1351
1352    // for the case whether param_name is the left most part of the reg_string
1353    if(extract_param_name == 1)
1354    begin
1355        param_name = param_name >> (8 * (50 - param_name_char_count));
1356
1357        if(param_name == compare_param_name)
1358            param_found = 1;
1359    end
1360
1361    if (param_found == 1)
1362        GET_PARAMETER_VALUE = param_value;   // return the value of the parameter been looking for
1363    else
1364        GET_PARAMETER_VALUE = "";  // return empty string if parameter not found
1365
1366end
1367endfunction
1368
1369endmodule // LPM_HINT_EVALUATION
1370
1371// BEGINNING OF MODULE
1372`timescale 1 ps / 1 ps
1373
1374// MODULE DECLARATION
1375module LPM_DEVICE_FAMILIES;
1376
1377function IS_FAMILY_CYCLONE;
1378    input[8*20:1] device;
1379    reg is_cyclone;
1380begin
1381    if ((device == "Cyclone") || (device == "CYCLONE") || (device == "cyclone") || (device == "ACEX2K") || (device == "acex2k") || (device == "ACEX 2K") || (device == "acex 2k") || (device == "Tornado") || (device == "TORNADO") || (device == "tornado"))
1382        is_cyclone = 1;
1383    else
1384        is_cyclone = 0;
1385
1386    IS_FAMILY_CYCLONE  = is_cyclone;
1387end
1388endfunction //IS_FAMILY_CYCLONE
1389
1390function IS_FAMILY_MAX3000A;
1391    input[8*20:1] device;
1392    reg is_max3000a;
1393begin
1394    if ((device == "MAX3000A") || (device == "max3000a") || (device == "MAX 3000A") || (device == "max 3000a"))
1395        is_max3000a = 1;
1396    else
1397        is_max3000a = 0;
1398
1399    IS_FAMILY_MAX3000A  = is_max3000a;
1400end
1401endfunction //IS_FAMILY_MAX3000A
1402
1403function IS_FAMILY_MAX7000A;
1404    input[8*20:1] device;
1405    reg is_max7000a;
1406begin
1407    if ((device == "MAX7000A") || (device == "max7000a") || (device == "MAX 7000A") || (device == "max 7000a"))
1408        is_max7000a = 1;
1409    else
1410        is_max7000a = 0;
1411
1412    IS_FAMILY_MAX7000A  = is_max7000a;
1413end
1414endfunction //IS_FAMILY_MAX7000A
1415
1416function IS_FAMILY_MAX7000AE;
1417    input[8*20:1] device;
1418    reg is_max7000ae;
1419begin
1420    if ((device == "MAX7000AE") || (device == "max7000ae") || (device == "MAX 7000AE") || (device == "max 7000ae"))
1421        is_max7000ae = 1;
1422    else
1423        is_max7000ae = 0;
1424
1425    IS_FAMILY_MAX7000AE  = is_max7000ae;
1426end
1427endfunction //IS_FAMILY_MAX7000AE
1428
1429function IS_FAMILY_MAX7000B;
1430    input[8*20:1] device;
1431    reg is_max7000b;
1432begin
1433    if ((device == "MAX7000B") || (device == "max7000b") || (device == "MAX 7000B") || (device == "max 7000b"))
1434        is_max7000b = 1;
1435    else
1436        is_max7000b = 0;
1437
1438    IS_FAMILY_MAX7000B  = is_max7000b;
1439end
1440endfunction //IS_FAMILY_MAX7000B
1441
1442function IS_FAMILY_MAX7000S;
1443    input[8*20:1] device;
1444    reg is_max7000s;
1445begin
1446    if ((device == "MAX7000S") || (device == "max7000s") || (device == "MAX 7000S") || (device == "max 7000s"))
1447        is_max7000s = 1;
1448    else
1449        is_max7000s = 0;
1450
1451    IS_FAMILY_MAX7000S  = is_max7000s;
1452end
1453endfunction //IS_FAMILY_MAX7000S
1454
1455function IS_FAMILY_STRATIXGX;
1456    input[8*20:1] device;
1457    reg is_stratixgx;
1458begin
1459    if ((device == "Stratix GX") || (device == "STRATIX GX") || (device == "stratix gx") || (device == "Stratix-GX") || (device == "STRATIX-GX") || (device == "stratix-gx") || (device == "StratixGX") || (device == "STRATIXGX") || (device == "stratixgx") || (device == "Aurora") || (device == "AURORA") || (device == "aurora"))
1460        is_stratixgx = 1;
1461    else
1462        is_stratixgx = 0;
1463
1464    IS_FAMILY_STRATIXGX  = is_stratixgx;
1465end
1466endfunction //IS_FAMILY_STRATIXGX
1467
1468function IS_FAMILY_STRATIX;
1469    input[8*20:1] device;
1470    reg is_stratix;
1471begin
1472    if ((device == "Stratix") || (device == "STRATIX") || (device == "stratix") || (device == "Yeager") || (device == "YEAGER") || (device == "yeager"))
1473        is_stratix = 1;
1474    else
1475        is_stratix = 0;
1476
1477    IS_FAMILY_STRATIX  = is_stratix;
1478end
1479endfunction //IS_FAMILY_STRATIX
1480
1481function FEATURE_FAMILY_BASE_STRATIX;
1482    input[8*20:1] device;
1483    reg var_family_base_stratix;
1484begin
1485    if (IS_FAMILY_STRATIX(device) || IS_FAMILY_STRATIXGX(device) )
1486        var_family_base_stratix = 1;
1487    else
1488        var_family_base_stratix = 0;
1489
1490    FEATURE_FAMILY_BASE_STRATIX  = var_family_base_stratix;
1491end
1492endfunction //FEATURE_FAMILY_BASE_STRATIX
1493
1494function FEATURE_FAMILY_BASE_CYCLONE;
1495    input[8*20:1] device;
1496    reg var_family_base_cyclone;
1497begin
1498    if (IS_FAMILY_CYCLONE(device) )
1499        var_family_base_cyclone = 1;
1500    else
1501        var_family_base_cyclone = 0;
1502
1503    FEATURE_FAMILY_BASE_CYCLONE  = var_family_base_cyclone;
1504end
1505endfunction //FEATURE_FAMILY_BASE_CYCLONE
1506
1507function FEATURE_FAMILY_MAX;
1508    input[8*20:1] device;
1509    reg var_family_max;
1510begin
1511    if ((device == "MAX5000") || IS_FAMILY_MAX3000A(device) || (device == "MAX7000") || IS_FAMILY_MAX7000A(device) || IS_FAMILY_MAX7000AE(device) || (device == "MAX7000E") || IS_FAMILY_MAX7000S(device) || IS_FAMILY_MAX7000B(device) || (device == "MAX9000") )
1512        var_family_max = 1;
1513    else
1514        var_family_max = 0;
1515
1516    FEATURE_FAMILY_MAX  = var_family_max;
1517end
1518endfunction //FEATURE_FAMILY_MAX
1519
1520function IS_VALID_FAMILY;
1521    input[8*20:1] device;
1522    reg is_valid;
1523begin
1524    if (((device == "Arria 10") || (device == "ARRIA 10") || (device == "arria 10") || (device == "Arria10") || (device == "ARRIA10") || (device == "arria10") || (device == "Arria VI") || (device == "ARRIA VI") || (device == "arria vi") || (device == "ArriaVI") || (device == "ARRIAVI") || (device == "arriavi") || (device == "Night Fury") || (device == "NIGHT FURY") || (device == "night fury") || (device == "nightfury") || (device == "NIGHTFURY") || (device == "Arria 10 (GX/SX/GT)") || (device == "ARRIA 10 (GX/SX/GT)") || (device == "arria 10 (gx/sx/gt)") || (device == "Arria10(GX/SX/GT)") || (device == "ARRIA10(GX/SX/GT)") || (device == "arria10(gx/sx/gt)") || (device == "Arria 10 (GX)") || (device == "ARRIA 10 (GX)") || (device == "arria 10 (gx)") || (device == "Arria10(GX)") || (device == "ARRIA10(GX)") || (device == "arria10(gx)") || (device == "Arria 10 (SX)") || (device == "ARRIA 10 (SX)") || (device == "arria 10 (sx)") || (device == "Arria10(SX)") || (device == "ARRIA10(SX)") || (device == "arria10(sx)") || (device == "Arria 10 (GT)") || (device == "ARRIA 10 (GT)") || (device == "arria 10 (gt)") || (device == "Arria10(GT)") || (device == "ARRIA10(GT)") || (device == "arria10(gt)"))
1525    || ((device == "Arria GX") || (device == "ARRIA GX") || (device == "arria gx") || (device == "ArriaGX") || (device == "ARRIAGX") || (device == "arriagx") || (device == "Stratix II GX Lite") || (device == "STRATIX II GX LITE") || (device == "stratix ii gx lite") || (device == "StratixIIGXLite") || (device == "STRATIXIIGXLITE") || (device == "stratixiigxlite"))
1526    || ((device == "Arria II GX") || (device == "ARRIA II GX") || (device == "arria ii gx") || (device == "ArriaIIGX") || (device == "ARRIAIIGX") || (device == "arriaiigx") || (device == "Arria IIGX") || (device == "ARRIA IIGX") || (device == "arria iigx") || (device == "ArriaII GX") || (device == "ARRIAII GX") || (device == "arriaii gx") || (device == "Arria II") || (device == "ARRIA II") || (device == "arria ii") || (device == "ArriaII") || (device == "ARRIAII") || (device == "arriaii") || (device == "Arria II (GX/E)") || (device == "ARRIA II (GX/E)") || (device == "arria ii (gx/e)") || (device == "ArriaII(GX/E)") || (device == "ARRIAII(GX/E)") || (device == "arriaii(gx/e)") || (device == "PIRANHA") || (device == "piranha"))
1527    || ((device == "Arria II GZ") || (device == "ARRIA II GZ") || (device == "arria ii gz") || (device == "ArriaII GZ") || (device == "ARRIAII GZ") || (device == "arriaii gz") || (device == "Arria IIGZ") || (device == "ARRIA IIGZ") || (device == "arria iigz") || (device == "ArriaIIGZ") || (device == "ARRIAIIGZ") || (device == "arriaiigz"))
1528    || ((device == "Arria V GZ") || (device == "ARRIA V GZ") || (device == "arria v gz") || (device == "ArriaVGZ") || (device == "ARRIAVGZ") || (device == "arriavgz"))
1529    || ((device == "Arria V") || (device == "ARRIA V") || (device == "arria v") || (device == "Arria V (GT/GX)") || (device == "ARRIA V (GT/GX)") || (device == "arria v (gt/gx)") || (device == "ArriaV(GT/GX)") || (device == "ARRIAV(GT/GX)") || (device == "arriav(gt/gx)") || (device == "ArriaV") || (device == "ARRIAV") || (device == "arriav") || (device == "Arria V (GT/GX/ST/SX)") || (device == "ARRIA V (GT/GX/ST/SX)") || (device == "arria v (gt/gx/st/sx)") || (device == "ArriaV(GT/GX/ST/SX)") || (device == "ARRIAV(GT/GX/ST/SX)") || (device == "arriav(gt/gx/st/sx)") || (device == "Arria V (GT)") || (device == "ARRIA V (GT)") || (device == "arria v (gt)") || (device == "ArriaV(GT)") || (device == "ARRIAV(GT)") || (device == "arriav(gt)") || (device == "Arria V (GX)") || (device == "ARRIA V (GX)") || (device == "arria v (gx)") || (device == "ArriaV(GX)") || (device == "ARRIAV(GX)") || (device == "arriav(gx)") || (device == "Arria V (ST)") || (device == "ARRIA V (ST)") || (device == "arria v (st)") || (device == "ArriaV(ST)") || (device == "ARRIAV(ST)") || (device == "arriav(st)") || (device == "Arria V (SX)") || (device == "ARRIA V (SX)") || (device == "arria v (sx)") || (device == "ArriaV(SX)") || (device == "ARRIAV(SX)") || (device == "arriav(sx)"))
1530    || ((device == "BS") || (device == "bs"))
1531    || ((device == "Cyclone II") || (device == "CYCLONE II") || (device == "cyclone ii") || (device == "Cycloneii") || (device == "CYCLONEII") || (device == "cycloneii") || (device == "Magellan") || (device == "MAGELLAN") || (device == "magellan") || (device == "CycloneII") || (device == "CYCLONEII") || (device == "cycloneii"))
1532    || ((device == "Cyclone III LS") || (device == "CYCLONE III LS") || (device == "cyclone iii ls") || (device == "CycloneIIILS") || (device == "CYCLONEIIILS") || (device == "cycloneiiils") || (device == "Cyclone III LPS") || (device == "CYCLONE III LPS") || (device == "cyclone iii lps") || (device == "Cyclone LPS") || (device == "CYCLONE LPS") || (device == "cyclone lps") || (device == "CycloneLPS") || (device == "CYCLONELPS") || (device == "cyclonelps") || (device == "Tarpon") || (device == "TARPON") || (device == "tarpon") || (device == "Cyclone IIIE") || (device == "CYCLONE IIIE") || (device == "cyclone iiie"))
1533    || ((device == "Cyclone III") || (device == "CYCLONE III") || (device == "cyclone iii") || (device == "CycloneIII") || (device == "CYCLONEIII") || (device == "cycloneiii") || (device == "Barracuda") || (device == "BARRACUDA") || (device == "barracuda") || (device == "Cuda") || (device == "CUDA") || (device == "cuda") || (device == "CIII") || (device == "ciii"))
1534    || ((device == "Cyclone IV E") || (device == "CYCLONE IV E") || (device == "cyclone iv e") || (device == "CycloneIV E") || (device == "CYCLONEIV E") || (device == "cycloneiv e") || (device == "Cyclone IVE") || (device == "CYCLONE IVE") || (device == "cyclone ive") || (device == "CycloneIVE") || (device == "CYCLONEIVE") || (device == "cycloneive"))
1535    || ((device == "Cyclone IV GX") || (device == "CYCLONE IV GX") || (device == "cyclone iv gx") || (device == "Cyclone IVGX") || (device == "CYCLONE IVGX") || (device == "cyclone ivgx") || (device == "CycloneIV GX") || (device == "CYCLONEIV GX") || (device == "cycloneiv gx") || (device == "CycloneIVGX") || (device == "CYCLONEIVGX") || (device == "cycloneivgx") || (device == "Cyclone IV") || (device == "CYCLONE IV") || (device == "cyclone iv") || (device == "CycloneIV") || (device == "CYCLONEIV") || (device == "cycloneiv") || (device == "Cyclone IV (GX)") || (device == "CYCLONE IV (GX)") || (device == "cyclone iv (gx)") || (device == "CycloneIV(GX)") || (device == "CYCLONEIV(GX)") || (device == "cycloneiv(gx)") || (device == "Cyclone III GX") || (device == "CYCLONE III GX") || (device == "cyclone iii gx") || (device == "CycloneIII GX") || (device == "CYCLONEIII GX") || (device == "cycloneiii gx") || (device == "Cyclone IIIGX") || (device == "CYCLONE IIIGX") || (device == "cyclone iiigx") || (device == "CycloneIIIGX") || (device == "CYCLONEIIIGX") || (device == "cycloneiiigx") || (device == "Cyclone III GL") || (device == "CYCLONE III GL") || (device == "cyclone iii gl") || (device == "CycloneIII GL") || (device == "CYCLONEIII GL") || (device == "cycloneiii gl") || (device == "Cyclone IIIGL") || (device == "CYCLONE IIIGL") || (device == "cyclone iiigl") || (device == "CycloneIIIGL") || (device == "CYCLONEIIIGL") || (device == "cycloneiiigl") || (device == "Stingray") || (device == "STINGRAY") || (device == "stingray"))
1536    || ((device == "Cyclone V") || (device == "CYCLONE V") || (device == "cyclone v") || (device == "CycloneV") || (device == "CYCLONEV") || (device == "cyclonev") || (device == "Cyclone V (GT/GX/E/SX)") || (device == "CYCLONE V (GT/GX/E/SX)") || (device == "cyclone v (gt/gx/e/sx)") || (device == "CycloneV(GT/GX/E/SX)") || (device == "CYCLONEV(GT/GX/E/SX)") || (device == "cyclonev(gt/gx/e/sx)") || (device == "Cyclone V (E/GX/GT/SX/SE/ST)") || (device == "CYCLONE V (E/GX/GT/SX/SE/ST)") || (device == "cyclone v (e/gx/gt/sx/se/st)") || (device == "CycloneV(E/GX/GT/SX/SE/ST)") || (device == "CYCLONEV(E/GX/GT/SX/SE/ST)") || (device == "cyclonev(e/gx/gt/sx/se/st)") || (device == "Cyclone V (E)") || (device == "CYCLONE V (E)") || (device == "cyclone v (e)") || (device == "CycloneV(E)") || (device == "CYCLONEV(E)") || (device == "cyclonev(e)") || (device == "Cyclone V (GX)") || (device == "CYCLONE V (GX)") || (device == "cyclone v (gx)") || (device == "CycloneV(GX)") || (device == "CYCLONEV(GX)") || (device == "cyclonev(gx)") || (device == "Cyclone V (GT)") || (device == "CYCLONE V (GT)") || (device == "cyclone v (gt)") || (device == "CycloneV(GT)") || (device == "CYCLONEV(GT)") || (device == "cyclonev(gt)") || (device == "Cyclone V (SX)") || (device == "CYCLONE V (SX)") || (device == "cyclone v (sx)") || (device == "CycloneV(SX)") || (device == "CYCLONEV(SX)") || (device == "cyclonev(sx)") || (device == "Cyclone V (SE)") || (device == "CYCLONE V (SE)") || (device == "cyclone v (se)") || (device == "CycloneV(SE)") || (device == "CYCLONEV(SE)") || (device == "cyclonev(se)") || (device == "Cyclone V (ST)") || (device == "CYCLONE V (ST)") || (device == "cyclone v (st)") || (device == "CycloneV(ST)") || (device == "CYCLONEV(ST)") || (device == "cyclonev(st)"))
1537    || ((device == "Cyclone") || (device == "CYCLONE") || (device == "cyclone") || (device == "ACEX2K") || (device == "acex2k") || (device == "ACEX 2K") || (device == "acex 2k") || (device == "Tornado") || (device == "TORNADO") || (device == "tornado"))
1538    || ((device == "HardCopy II") || (device == "HARDCOPY II") || (device == "hardcopy ii") || (device == "HardCopyII") || (device == "HARDCOPYII") || (device == "hardcopyii") || (device == "Fusion") || (device == "FUSION") || (device == "fusion"))
1539    || ((device == "HardCopy III") || (device == "HARDCOPY III") || (device == "hardcopy iii") || (device == "HardCopyIII") || (device == "HARDCOPYIII") || (device == "hardcopyiii") || (device == "HCX") || (device == "hcx"))
1540    || ((device == "HardCopy IV") || (device == "HARDCOPY IV") || (device == "hardcopy iv") || (device == "HardCopyIV") || (device == "HARDCOPYIV") || (device == "hardcopyiv") || (device == "HardCopy IV (GX)") || (device == "HARDCOPY IV (GX)") || (device == "hardcopy iv (gx)") || (device == "HardCopy IV (E)") || (device == "HARDCOPY IV (E)") || (device == "hardcopy iv (e)") || (device == "HardCopyIV(GX)") || (device == "HARDCOPYIV(GX)") || (device == "hardcopyiv(gx)") || (device == "HardCopyIV(E)") || (device == "HARDCOPYIV(E)") || (device == "hardcopyiv(e)") || (device == "HCXIV") || (device == "hcxiv") || (device == "HardCopy IV (GX/E)") || (device == "HARDCOPY IV (GX/E)") || (device == "hardcopy iv (gx/e)") || (device == "HardCopy IV (E/GX)") || (device == "HARDCOPY IV (E/GX)") || (device == "hardcopy iv (e/gx)") || (device == "HardCopyIV(GX/E)") || (device == "HARDCOPYIV(GX/E)") || (device == "hardcopyiv(gx/e)") || (device == "HardCopyIV(E/GX)") || (device == "HARDCOPYIV(E/GX)") || (device == "hardcopyiv(e/gx)"))
1541    || ((device == "MAX 10") || (device == "max 10") || (device == "MAX 10 FPGA") || (device == "max 10 fpga") || (device == "Zippleback") || (device == "ZIPPLEBACK") || (device == "zippleback") || (device == "MAX10") || (device == "max10") || (device == "MAX 10 (DA/DF/DC/SA/SC)") || (device == "max 10 (da/df/dc/sa/sc)") || (device == "MAX10(DA/DF/DC/SA/SC)") || (device == "max10(da/df/dc/sa/sc)") || (device == "MAX 10 (DA)") || (device == "max 10 (da)") || (device == "MAX10(DA)") || (device == "max10(da)") || (device == "MAX 10 (DF)") || (device == "max 10 (df)") || (device == "MAX10(DF)") || (device == "max10(df)") || (device == "MAX 10 (DC)") || (device == "max 10 (dc)") || (device == "MAX10(DC)") || (device == "max10(dc)") || (device == "MAX 10 (SA)") || (device == "max 10 (sa)") || (device == "MAX10(SA)") || (device == "max10(sa)") || (device == "MAX 10 (SC)") || (device == "max 10 (sc)") || (device == "MAX10(SC)") || (device == "max10(sc)"))
1542    || ((device == "MAX II") || (device == "max ii") || (device == "MAXII") || (device == "maxii") || (device == "Tsunami") || (device == "TSUNAMI") || (device == "tsunami"))
1543    || ((device == "MAX V") || (device == "max v") || (device == "MAXV") || (device == "maxv") || (device == "Jade") || (device == "JADE") || (device == "jade"))
1544    || ((device == "MAX3000A") || (device == "max3000a") || (device == "MAX 3000A") || (device == "max 3000a"))
1545    || ((device == "MAX7000A") || (device == "max7000a") || (device == "MAX 7000A") || (device == "max 7000a"))
1546    || ((device == "MAX7000AE") || (device == "max7000ae") || (device == "MAX 7000AE") || (device == "max 7000ae"))
1547    || ((device == "MAX7000B") || (device == "max7000b") || (device == "MAX 7000B") || (device == "max 7000b"))
1548    || ((device == "MAX7000S") || (device == "max7000s") || (device == "MAX 7000S") || (device == "max 7000s"))
1549    || ((device == "Stratix 10") || (device == "STRATIX 10") || (device == "stratix 10") || (device == "Stratix10") || (device == "STRATIX10") || (device == "stratix10") || (device == "nadder") || (device == "NADDER") || (device == "Stratix 10 (GX/SX)") || (device == "STRATIX 10 (GX/SX)") || (device == "stratix 10 (gx/sx)") || (device == "Stratix10(GX/SX)") || (device == "STRATIX10(GX/SX)") || (device == "stratix10(gx/sx)") || (device == "Stratix 10 (GX)") || (device == "STRATIX 10 (GX)") || (device == "stratix 10 (gx)") || (device == "Stratix10(GX)") || (device == "STRATIX10(GX)") || (device == "stratix10(gx)") || (device == "Stratix 10 (SX)") || (device == "STRATIX 10 (SX)") || (device == "stratix 10 (sx)") || (device == "Stratix10(SX)") || (device == "STRATIX10(SX)") || (device == "stratix10(sx)"))
1550    || ((device == "Stratix GX") || (device == "STRATIX GX") || (device == "stratix gx") || (device == "Stratix-GX") || (device == "STRATIX-GX") || (device == "stratix-gx") || (device == "StratixGX") || (device == "STRATIXGX") || (device == "stratixgx") || (device == "Aurora") || (device == "AURORA") || (device == "aurora"))
1551    || ((device == "Stratix II GX") || (device == "STRATIX II GX") || (device == "stratix ii gx") || (device == "StratixIIGX") || (device == "STRATIXIIGX") || (device == "stratixiigx"))
1552    || ((device == "Stratix II") || (device == "STRATIX II") || (device == "stratix ii") || (device == "StratixII") || (device == "STRATIXII") || (device == "stratixii") || (device == "Armstrong") || (device == "ARMSTRONG") || (device == "armstrong"))
1553    || ((device == "Stratix III") || (device == "STRATIX III") || (device == "stratix iii") || (device == "StratixIII") || (device == "STRATIXIII") || (device == "stratixiii") || (device == "Titan") || (device == "TITAN") || (device == "titan") || (device == "SIII") || (device == "siii"))
1554    || ((device == "Stratix IV") || (device == "STRATIX IV") || (device == "stratix iv") || (device == "TGX") || (device == "tgx") || (device == "StratixIV") || (device == "STRATIXIV") || (device == "stratixiv") || (device == "Stratix IV (GT)") || (device == "STRATIX IV (GT)") || (device == "stratix iv (gt)") || (device == "Stratix IV (GX)") || (device == "STRATIX IV (GX)") || (device == "stratix iv (gx)") || (device == "Stratix IV (E)") || (device == "STRATIX IV (E)") || (device == "stratix iv (e)") || (device == "StratixIV(GT)") || (device == "STRATIXIV(GT)") || (device == "stratixiv(gt)") || (device == "StratixIV(GX)") || (device == "STRATIXIV(GX)") || (device == "stratixiv(gx)") || (device == "StratixIV(E)") || (device == "STRATIXIV(E)") || (device == "stratixiv(e)") || (device == "StratixIIIGX") || (device == "STRATIXIIIGX") || (device == "stratixiiigx") || (device == "Stratix IV (GT/GX/E)") || (device == "STRATIX IV (GT/GX/E)") || (device == "stratix iv (gt/gx/e)") || (device == "Stratix IV (GT/E/GX)") || (device == "STRATIX IV (GT/E/GX)") || (device == "stratix iv (gt/e/gx)") || (device == "Stratix IV (E/GT/GX)") || (device == "STRATIX IV (E/GT/GX)") || (device == "stratix iv (e/gt/gx)") || (device == "Stratix IV (E/GX/GT)") || (device == "STRATIX IV (E/GX/GT)") || (device == "stratix iv (e/gx/gt)") || (device == "StratixIV(GT/GX/E)") || (device == "STRATIXIV(GT/GX/E)") || (device == "stratixiv(gt/gx/e)") || (device == "StratixIV(GT/E/GX)") || (device == "STRATIXIV(GT/E/GX)") || (device == "stratixiv(gt/e/gx)") || (device == "StratixIV(E/GX/GT)") || (device == "STRATIXIV(E/GX/GT)") || (device == "stratixiv(e/gx/gt)") || (device == "StratixIV(E/GT/GX)") || (device == "STRATIXIV(E/GT/GX)") || (device == "stratixiv(e/gt/gx)") || (device == "Stratix IV (GX/E)") || (device == "STRATIX IV (GX/E)") || (device == "stratix iv (gx/e)") || (device == "StratixIV(GX/E)") || (device == "STRATIXIV(GX/E)") || (device == "stratixiv(gx/e)"))
1555    || ((device == "Stratix V") || (device == "STRATIX V") || (device == "stratix v") || (device == "StratixV") || (device == "STRATIXV") || (device == "stratixv") || (device == "Stratix V (GS)") || (device == "STRATIX V (GS)") || (device == "stratix v (gs)") || (device == "StratixV(GS)") || (device == "STRATIXV(GS)") || (device == "stratixv(gs)") || (device == "Stratix V (GT)") || (device == "STRATIX V (GT)") || (device == "stratix v (gt)") || (device == "StratixV(GT)") || (device == "STRATIXV(GT)") || (device == "stratixv(gt)") || (device == "Stratix V (GX)") || (device == "STRATIX V (GX)") || (device == "stratix v (gx)") || (device == "StratixV(GX)") || (device == "STRATIXV(GX)") || (device == "stratixv(gx)") || (device == "Stratix V (GS/GX)") || (device == "STRATIX V (GS/GX)") || (device == "stratix v (gs/gx)") || (device == "StratixV(GS/GX)") || (device == "STRATIXV(GS/GX)") || (device == "stratixv(gs/gx)") || (device == "Stratix V (GS/GT)") || (device == "STRATIX V (GS/GT)") || (device == "stratix v (gs/gt)") || (device == "StratixV(GS/GT)") || (device == "STRATIXV(GS/GT)") || (device == "stratixv(gs/gt)") || (device == "Stratix V (GT/GX)") || (device == "STRATIX V (GT/GX)") || (device == "stratix v (gt/gx)") || (device == "StratixV(GT/GX)") || (device == "STRATIXV(GT/GX)") || (device == "stratixv(gt/gx)") || (device == "Stratix V (GX/GS)") || (device == "STRATIX V (GX/GS)") || (device == "stratix v (gx/gs)") || (device == "StratixV(GX/GS)") || (device == "STRATIXV(GX/GS)") || (device == "stratixv(gx/gs)") || (device == "Stratix V (GT/GS)") || (device == "STRATIX V (GT/GS)") || (device == "stratix v (gt/gs)") || (device == "StratixV(GT/GS)") || (device == "STRATIXV(GT/GS)") || (device == "stratixv(gt/gs)") || (device == "Stratix V (GX/GT)") || (device == "STRATIX V (GX/GT)") || (device == "stratix v (gx/gt)") || (device == "StratixV(GX/GT)") || (device == "STRATIXV(GX/GT)") || (device == "stratixv(gx/gt)") || (device == "Stratix V (GS/GT/GX)") || (device == "STRATIX V (GS/GT/GX)") || (device == "stratix v (gs/gt/gx)") || (device == "Stratix V (GS/GX/GT)") || (device == "STRATIX V (GS/GX/GT)") || (device == "stratix v (gs/gx/gt)") || (device == "Stratix V (GT/GS/GX)") || (device == "STRATIX V (GT/GS/GX)") || (device == "stratix v (gt/gs/gx)") || (device == "Stratix V (GT/GX/GS)") || (device == "STRATIX V (GT/GX/GS)") || (device == "stratix v (gt/gx/gs)") || (device == "Stratix V (GX/GS/GT)") || (device == "STRATIX V (GX/GS/GT)") || (device == "stratix v (gx/gs/gt)") || (device == "Stratix V (GX/GT/GS)") || (device == "STRATIX V (GX/GT/GS)") || (device == "stratix v (gx/gt/gs)") || (device == "StratixV(GS/GT/GX)") || (device == "STRATIXV(GS/GT/GX)") || (device == "stratixv(gs/gt/gx)") || (device == "StratixV(GS/GX/GT)") || (device == "STRATIXV(GS/GX/GT)") || (device == "stratixv(gs/gx/gt)") || (device == "StratixV(GT/GS/GX)") || (device == "STRATIXV(GT/GS/GX)") || (device == "stratixv(gt/gs/gx)") || (device == "StratixV(GT/GX/GS)") || (device == "STRATIXV(GT/GX/GS)") || (device == "stratixv(gt/gx/gs)") || (device == "StratixV(GX/GS/GT)") || (device == "STRATIXV(GX/GS/GT)") || (device == "stratixv(gx/gs/gt)") || (device == "StratixV(GX/GT/GS)") || (device == "STRATIXV(GX/GT/GS)") || (device == "stratixv(gx/gt/gs)") || (device == "Stratix V (GS/GT/GX/E)") || (device == "STRATIX V (GS/GT/GX/E)") || (device == "stratix v (gs/gt/gx/e)") || (device == "StratixV(GS/GT/GX/E)") || (device == "STRATIXV(GS/GT/GX/E)") || (device == "stratixv(gs/gt/gx/e)") || (device == "Stratix V (E)") || (device == "STRATIX V (E)") || (device == "stratix v (e)") || (device == "StratixV(E)") || (device == "STRATIXV(E)") || (device == "stratixv(e)"))
1556    || ((device == "Stratix") || (device == "STRATIX") || (device == "stratix") || (device == "Yeager") || (device == "YEAGER") || (device == "yeager"))
1557    || ((device == "eFPGA 28 HPM") || (device == "EFPGA 28 HPM") || (device == "efpga 28 hpm") || (device == "eFPGA28HPM") || (device == "EFPGA28HPM") || (device == "efpga28hpm") || (device == "Bedrock") || (device == "BEDROCK") || (device == "bedrock")))
1558        is_valid = 1;
1559    else
1560        is_valid = 0;
1561
1562    IS_VALID_FAMILY = is_valid;
1563end
1564endfunction // IS_VALID_FAMILY
1565
1566
1567endmodule // LPM_DEVICE_FAMILIES
1568//START_MODULE_NAME------------------------------------------------------------
1569//
1570// Module Name     :  lpm_constant
1571//
1572// Description     :  Parameterized constant generator megafunction. lpm_constant
1573//                    may be useful for convert a parameter into a constant.
1574//
1575// Limitation      :  n/a
1576//
1577// Results expected:  Value specified by the argument to LPM_CVALUE.
1578//
1579//END_MODULE_NAME--------------------------------------------------------------
1580
1581// BEGINNING OF MODULE
1582`timescale 1 ps / 1 ps
1583
1584// MODULE DECLARATION
1585module lpm_constant (
1586    result // Value specified by the argument to LPM_CVALUE. (Required)
1587);
1588
1589// GLOBAL PARAMETER DECLARATION
1590    parameter lpm_width = 1;    // Width of the result[] port. (Required)
1591    parameter lpm_cvalue = 0;   // Constant value to be driven out on the
1592                                // result[] port. (Required)
1593    parameter lpm_strength = "UNUSED";
1594    parameter lpm_type = "lpm_constant";
1595    parameter lpm_hint = "UNUSED";
1596
1597// OUTPUT PORT DECLARATION
1598    output [lpm_width-1:0] result;
1599
1600// INTERNAL REGISTERS DECLARATION
1601    reg[32:0] int_value;
1602
1603// INITIAL CONSTRUCT BLOCK
1604    initial
1605    begin
1606        if (lpm_width <= 0)
1607        begin
1608            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
1609            $display("Time: %0t  Instance: %m", $time);
1610            $finish;
1611        end
1612        int_value = lpm_cvalue;
1613    end
1614
1615// CONTINOUS ASSIGNMENT
1616    assign result = int_value[lpm_width-1:0];
1617
1618endmodule // lpm_constant
1619
1620//START_MODULE_NAME------------------------------------------------------------
1621//
1622// Module Name     :  lpm_inv
1623//
1624// Description     :  Parameterized inverter megafunction.
1625//
1626// Limitation      :  n/a
1627//
1628// Results expected: Inverted value of input data
1629//
1630//END_MODULE_NAME--------------------------------------------------------------
1631
1632// BEGINNING OF MODULE
1633`timescale 1 ps / 1 ps
1634
1635// MODULE DECLARATION
1636module lpm_inv (
1637    data,   // Data input to the lpm_inv. (Required)
1638    result  // inverted result. (Required)
1639);
1640
1641// GLOBAL PARAMETER DECLARATION
1642    parameter lpm_width = 1; // Width of the data[] and result[] ports. (Required)
1643    parameter lpm_type = "lpm_inv";
1644    parameter lpm_hint = "UNUSED";
1645
1646// INPUT PORT DECLARATION
1647    input  [lpm_width-1:0] data;
1648
1649// OUTPUT PORT DECLARATION
1650    output [lpm_width-1:0] result;
1651
1652// INTERNAL REGISTERS DECLARATION
1653    reg    [lpm_width-1:0] result;
1654
1655// INITIAL CONSTRUCT BLOCK
1656    initial
1657    begin
1658        if (lpm_width <= 0)
1659        begin
1660            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
1661            $display("Time: %0t  Instance: %m", $time);
1662            $finish;
1663        end
1664    end
1665
1666// ALWAYS CONSTRUCT BLOCK
1667    always @(data)
1668        result = ~data;
1669
1670endmodule // lpm_inv
1671
1672//START_MODULE_NAME------------------------------------------------------------
1673//
1674// Module Name     :  lpm_and
1675//
1676// Description     :  Parameterized AND gate. This megafunction takes in data inputs
1677//                    for a number of AND gates.
1678//
1679// Limitation      :  n/a
1680//
1681// Results expected: Each result[] bit is the result of each AND gate.
1682//
1683//END_MODULE_NAME--------------------------------------------------------------
1684
1685// BEGINNING OF MODULE
1686`timescale 1 ps / 1 ps
1687
1688// MODULE DECLARATION
1689module lpm_and (
1690    data,  // Data input to the AND gate. (Required)
1691    result // Result of the AND operators. (Required)
1692);
1693
1694// GLOBAL PARAMETER DECLARATION
1695    // Width of the data[][] and result[] ports. Number of AND gates. (Required)
1696    parameter lpm_width = 1;
1697    // Number of inputs to each AND gate. Number of input buses. (Required)
1698    parameter lpm_size = 1;
1699    parameter lpm_type = "lpm_and";
1700    parameter lpm_hint = "UNUSED";
1701
1702// INPUT PORT DECLARATION
1703    input  [(lpm_size * lpm_width)-1:0] data;
1704
1705// OUTPUT PORT DECLARATION
1706    output [lpm_width-1:0] result;
1707
1708// INTERNAL REGISTER/SIGNAL DECLARATION
1709    reg    [lpm_width-1:0] result_tmp;
1710
1711// LOCAL INTEGER DECLARATION
1712    integer i;
1713    integer j;
1714    integer k;
1715
1716// INITIAL CONSTRUCT BLOCK
1717    initial
1718    begin
1719        if (lpm_width <= 0)
1720        begin
1721            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
1722            $display("Time: %0t  Instance: %m", $time);
1723            $finish;
1724        end
1725
1726        if (lpm_size <= 0)
1727        begin
1728            $display("Value of lpm_size parameter must be greater than 0(ERROR)");
1729            $display("Time: %0t  Instance: %m", $time);
1730            $finish;
1731        end
1732    end
1733
1734// ALWAYS CONSTRUCT BLOCK
1735    always @(data)
1736    begin
1737        for (i=0; i<lpm_width; i=i+1)
1738        begin
1739            result_tmp[i] = 1'b1;
1740            for (j=0; j<lpm_size; j=j+1)
1741            begin
1742                k = (j * lpm_width) + i;
1743                result_tmp[i] = result_tmp[i] & data[k];
1744            end
1745        end
1746    end
1747
1748// CONTINOUS ASSIGNMENT
1749    assign result = result_tmp;
1750endmodule // lpm_and
1751
1752//START_MODULE_NAME------------------------------------------------------------
1753//
1754// Module Name     :  lpm_or
1755//
1756// Description     :  Parameterized OR gate megafunction. This megafunction takes in
1757//                    data inputs for a number of OR gates.
1758//
1759// Limitation      :  n/a
1760//
1761// Results expected:  Each result[] bit is the result of each OR gate.
1762//
1763//END_MODULE_NAME--------------------------------------------------------------
1764
1765// BEGINNING OF MODULE
1766`timescale 1 ps / 1 ps
1767
1768// MODULE DECLARATION
1769module lpm_or (
1770    data,  // Data input to the OR gates. (Required)
1771    result // Result of OR operators. (Required)
1772);
1773
1774// GLOBAL PARAMETER DECLARATION
1775    // Width of the data[] and result[] ports. Number of OR gates. (Required)
1776    parameter lpm_width = 1;
1777    // Number of inputs to each OR gate. Number of input buses. (Required)
1778    parameter lpm_size = 1;
1779    parameter lpm_type = "lpm_or";
1780    parameter lpm_hint  = "UNUSED";
1781
1782// INPUT PORT DECLARATION
1783    input  [(lpm_size * lpm_width)-1:0] data;
1784
1785// OUTPUT PORT DECLARATION
1786    output [lpm_width-1:0] result;
1787
1788// INTERNAL REGISTER/SIGNAL DECLARATION
1789    reg    [lpm_width-1:0] result_tmp;
1790
1791// LOCAL INTEGER DECLARATION
1792    integer i;
1793    integer j;
1794    integer k;
1795
1796// INITIAL CONSTRUCT BLOCK
1797    initial
1798    begin
1799        if (lpm_width <= 0)
1800        begin
1801            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
1802            $display("Time: %0t  Instance: %m", $time);
1803            $finish;
1804        end
1805
1806        if (lpm_size <= 0)
1807        begin
1808            $display("Value of lpm_size parameter must be greater than 0 (ERROR)");
1809            $display("Time: %0t  Instance: %m", $time);
1810            $finish;
1811        end
1812    end
1813
1814// ALWAYS CONSTRUCT BLOCK
1815    always @(data)
1816    begin
1817        for (i=0; i<lpm_width; i=i+1)
1818        begin
1819            result_tmp[i] = 1'b0;
1820            for (j=0; j<lpm_size; j=j+1)
1821            begin
1822                k = (j * lpm_width) + i;
1823                result_tmp[i] = result_tmp[i] | data[k];
1824            end
1825        end
1826    end
1827
1828// CONTINOUS ASSIGNMENT
1829    assign result = result_tmp;
1830
1831endmodule // lpm_or
1832
1833//START_MODULE_NAME------------------------------------------------------------
1834//
1835// Module Name     :  lpm_xor
1836//
1837// Description     :  Parameterized XOR gate megafunction. This megafunction takes in
1838//                    data inputs for a number of XOR gates.
1839//
1840// Limitation      :  n/a.
1841//
1842// Results expected:  Each result[] bit is the result of each XOR gates.
1843//
1844//END_MODULE_NAME--------------------------------------------------------------
1845
1846// BEGINNING OF MODULE
1847`timescale 1 ps / 1 ps
1848
1849// MODULE DECLARATION
1850module lpm_xor (
1851    data,   // Data input to the XOR gates. (Required)
1852    result  // Result of XOR operators. (Required)
1853);
1854
1855// GLOBAL PARAMETER DECLARATION
1856    // Width of the data[] and result[] ports. Number of XOR gates. (Required)
1857    parameter lpm_width = 1;
1858    // Number of inputs to each XOR gate. Number of input buses. (Required)
1859    parameter lpm_size = 1;
1860    parameter lpm_type = "lpm_xor";
1861    parameter lpm_hint  = "UNUSED";
1862
1863// INPUT PORT DECLARATION
1864    input  [(lpm_size * lpm_width)-1:0] data;
1865
1866// OUTPUT PORT DECLARATION
1867    output [lpm_width-1:0] result;
1868
1869// INTERNAL REGISTER/SIGNAL DECLARATION
1870    reg    [lpm_width-1:0] result_tmp;
1871
1872// LOCAL INTEGER DECLARATION
1873    integer i;
1874    integer j;
1875    integer k;
1876
1877// INITIAL CONSTRUCT BLOCK
1878    initial
1879    begin
1880        if (lpm_width <= 0)
1881        begin
1882            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
1883            $display("Time: %0t  Instance: %m", $time);
1884            $finish;
1885        end
1886
1887        if (lpm_size <= 0)
1888        begin
1889            $display("Value of lpm_size parameter must be greater than 0 (ERROR)");
1890            $display("Time: %0t  Instance: %m", $time);
1891            $finish;
1892        end
1893    end
1894
1895// ALWAYS CONSTRUCT BLOCK
1896    always @(data)
1897    begin
1898        for (i=0; i<lpm_width; i=i+1)
1899        begin
1900            result_tmp[i] = 1'b0;
1901            for (j=0; j<lpm_size; j=j+1)
1902            begin
1903                k = (j * lpm_width) + i;
1904                result_tmp[i] = result_tmp[i] ^ data[k];
1905            end
1906        end
1907    end
1908
1909// CONTINOUS ASSIGNMENT
1910    assign result = result_tmp;
1911
1912endmodule // lpm_xor
1913
1914//START_MODULE_NAME------------------------------------------------------------
1915//
1916// Module Name     :  lpm_bustri
1917//
1918// Description     :  Parameterized tri-state buffer. lpm_bustri is useful for
1919//                    controlling both unidirectional and bidirectional I/O bus
1920//                    controllers.
1921//
1922// Limitation      :  n/a
1923//
1924// Results expected:  Belows are the three configurations which are valid:
1925//
1926//                    1) Only the input ports data[LPM_WIDTH-1..0] and enabledt are
1927//                       present, and only the output ports tridata[LPM_WIDTH-1..0]
1928//                       are present.
1929//
1930//                        ----------------------------------------------------
1931//                       | Input           |  Output                          |
1932//                       |====================================================|
1933//                       | enabledt        |     tridata[LPM_WIDTH-1..0]      |
1934//                       |----------------------------------------------------|
1935//                       |    0            |     Z                            |
1936//                       |----------------------------------------------------|
1937//                       |    1            |     DATA[LPM_WIDTH-1..0]         |
1938//                        ----------------------------------------------------
1939//
1940//                    2) Only the input ports tridata[LPM_WIDTH-1..0] and enabletr
1941//                       are present, and only the output ports result[LPM_WIDTH-1..0]
1942//                       are present.
1943//
1944//                        ----------------------------------------------------
1945//                       | Input           |  Output                          |
1946//                       |====================================================|
1947//                       | enabletr        |     result[LPM_WIDTH-1..0]       |
1948//                       |----------------------------------------------------|
1949//                       |    0            |     Z                            |
1950//                       |----------------------------------------------------|
1951//                       |    1            |     tridata[LPM_WIDTH-1..0]      |
1952//                        ----------------------------------------------------
1953//
1954//                    3) All ports are present: input ports data[LPM_WIDTH-1..0],
1955//                       enabledt, and enabletr; output ports result[LPM_WIDTH-1..0];
1956//                       and bidirectional ports tridata[LPM_WIDTH-1..0].
1957//
1958//        ----------------------------------------------------------------------------
1959//       |         Input        |      Bidirectional       |         Output           |
1960//       |----------------------------------------------------------------------------|
1961//       | enabledt  | enabletr | tridata[LPM_WIDTH-1..0]  |  result[LPM_WIDTH-1..0]  |
1962//       |============================================================================|
1963//       |    0      |     0    |       Z (input)          |          Z               |
1964//       |----------------------------------------------------------------------------|
1965//       |    0      |     1    |       Z (input)          |  tridata[LPM_WIDTH-1..0] |
1966//       |----------------------------------------------------------------------------|
1967//       |    1      |     0    |     data[LPM_WIDTH-1..0] |          Z               |
1968//       |----------------------------------------------------------------------------|
1969//       |    1      |     1    |     data[LPM_WIDTH-1..0] |  data[LPM_WIDTH-1..0]    |
1970//       ----------------------------------------------------------------------------
1971//
1972//
1973//END_MODULE_NAME--------------------------------------------------------------
1974
1975// BEGINNING OF MODULE
1976`timescale 1 ps / 1 ps
1977
1978// MODULE DECLARATION
1979module lpm_bustri (
1980    tridata,    // Bidirectional bus signal. (Required)
1981    data,       // Data input to the tridata[] bus. (Required)
1982    enabletr,   // If high, enables tridata[] onto the result bus.
1983    enabledt,   // If high, enables data onto the tridata[] bus.
1984    result      // Output from the tridata[] bus.
1985);
1986
1987// GLOBAL PARAMETER DECLARATION
1988    parameter lpm_width = 1;
1989    parameter lpm_type = "lpm_bustri";
1990    parameter lpm_hint = "UNUSED";
1991
1992// INPUT PORT DECLARATION
1993    input  [lpm_width-1:0] data;
1994    input  enabletr;
1995    input  enabledt;
1996
1997// OUTPUT PORT DECLARATION
1998    output [lpm_width-1:0] result;
1999
2000// INPUT/OUTPUT PORT DECLARATION
2001    inout  [lpm_width-1:0] tridata;
2002
2003// INTERNAL REGISTERS DECLARATION
2004    reg  [lpm_width-1:0] result;
2005
2006// INTERNAL TRI DECLARATION
2007    tri1  enabletr;
2008    tri1  enabledt;
2009
2010    wire i_enabledt;
2011    wire i_enabletr;
2012    buf (i_enabledt, enabledt);
2013    buf (i_enabletr, enabletr);
2014
2015
2016// INITIAL CONSTRUCT BLOCK
2017    initial
2018    begin
2019        if (lpm_width <= 0)
2020        begin
2021            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
2022            $display("Time: %0t  Instance: %m", $time);
2023            $finish;
2024        end
2025    end
2026
2027// ALWAYS CONSTRUCT BLOCK
2028    always @(data or tridata or i_enabletr or i_enabledt)
2029    begin
2030        if ((i_enabledt == 1'b0) && (i_enabletr == 1'b1))
2031        begin
2032            result = tridata;
2033        end
2034        else if ((i_enabledt == 1'b1) && (i_enabletr == 1'b1))
2035        begin
2036            result = data;
2037        end
2038        else
2039        begin
2040            result = {lpm_width{1'bz}};
2041        end
2042    end
2043
2044// CONTINOUS ASSIGNMENT
2045    assign tridata = (i_enabledt == 1) ? data : {lpm_width{1'bz}};
2046
2047endmodule // lpm_bustri
2048
2049//START_MODULE_NAME------------------------------------------------------------
2050//
2051// Module Name     :  lpm_mux
2052//
2053// Description     :  Parameterized multiplexer megafunctions.
2054//
2055// Limitation      :  n/a
2056//
2057// Results expected:  Selected input port.
2058//
2059//END_MODULE_NAME--------------------------------------------------------------
2060
2061// BEGINNING OF MODULE
2062`timescale 1 ps / 1 ps
2063
2064// MODULE DECLARATION
2065module lpm_mux (
2066    data,    // Data input. (Required)
2067    sel,     // Selects one of the input buses. (Required)
2068    clock,   // Clock for pipelined usage
2069    aclr,    // Asynchronous clear for pipelined usage.
2070    clken,   // Clock enable for pipelined usage.
2071    result   // Selected input port. (Required)
2072);
2073
2074// GLOBAL PARAMETER DECLARATION
2075    parameter lpm_width = 1;  // Width of the data[][] and result[] ports. (Required)
2076    parameter lpm_size = 2;   // Number of input buses to the multiplexer. (Required)
2077    parameter lpm_widths = 1; // Width of the sel[] input port. (Required)
2078    parameter lpm_pipeline = 0; // Specifies the number of Clock cycles of latency
2079                                // associated with the result[] output.
2080    parameter lpm_type = "lpm_mux";
2081    parameter lpm_hint  = "UNUSED";
2082
2083// INPUT PORT DECLARATION
2084    input [(lpm_size * lpm_width)-1:0] data;
2085    input [lpm_widths-1:0] sel;
2086    input clock;
2087    input aclr;
2088    input clken;
2089
2090// OUTPUT PORT DECLARATION
2091    output [lpm_width-1:0] result;
2092
2093// INTERNAL REGISTER/SIGNAL DECLARATION
2094    reg [lpm_width-1:0] result_pipe [lpm_pipeline+1:0];
2095    reg [lpm_width-1:0] tmp_result;
2096
2097// LOCAL INTEGER DECLARATION
2098    integer i;
2099    integer pipe_ptr;
2100
2101// INTERNAL TRI DECLARATION
2102    tri0 aclr;
2103    tri0 clock;
2104    tri1 clken;
2105
2106    wire i_aclr;
2107    wire i_clock;
2108    wire i_clken;
2109    buf (i_aclr, aclr);
2110    buf (i_clock, clock);
2111    buf (i_clken, clken);
2112
2113// INITIAL CONSTRUCT BLOCK
2114    initial
2115    begin
2116        if (lpm_width <= 0)
2117        begin
2118            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
2119            $display("Time: %0t  Instance: %m", $time);
2120            $finish;
2121        end
2122
2123        if (lpm_size <= 1)
2124        begin
2125            $display("Value of lpm_size parameter must be greater than 1 (ERROR)");
2126            $display("Time: %0t  Instance: %m", $time);
2127            $finish;
2128        end
2129
2130        if (lpm_widths <= 0)
2131        begin
2132            $display("Value of lpm_widths parameter must be greater than 0 (ERROR)");
2133            $display("Time: %0t  Instance: %m", $time);
2134            $finish;
2135        end
2136
2137        if (lpm_pipeline < 0)
2138        begin
2139            $display("Value of lpm_pipeline parameter must NOT less than 0 (ERROR)");
2140            $display("Time: %0t  Instance: %m", $time);
2141            $finish;
2142        end
2143        pipe_ptr = 0;
2144    end
2145
2146
2147// ALWAYS CONSTRUCT BLOCK
2148    always @(data or sel)
2149    begin
2150        tmp_result = 0;
2151
2152        if (sel < lpm_size)
2153        begin
2154            for (i = 0; i < lpm_width; i = i + 1)
2155                tmp_result[i] = data[(sel * lpm_width) + i];
2156        end
2157        else
2158            tmp_result = {lpm_width{1'bx}};
2159    end
2160
2161    always @(posedge i_clock or posedge i_aclr)
2162    begin
2163        if (i_aclr)
2164        begin
2165            for (i = 0; i <= (lpm_pipeline+1); i = i + 1)
2166                result_pipe[i] <= 1'b0;
2167            pipe_ptr <= 0;
2168        end
2169        else if (i_clken == 1'b1)
2170        begin
2171            result_pipe[pipe_ptr] <= tmp_result;
2172
2173            if (lpm_pipeline > 1)
2174                pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
2175        end
2176    end
2177
2178// CONTINOUS ASSIGNMENT
2179    assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : tmp_result;
2180
2181endmodule // lpm_mux
2182// END OF MODULE
2183
2184//START_MODULE_NAME------------------------------------------------------------
2185//
2186// Module Name     :  lpm_decode
2187//
2188// Description     :  Parameterized decoder megafunction.
2189//
2190// Limitation      :  n/a
2191//
2192// Results expected:  Decoded output.
2193//
2194//END_MODULE_NAME--------------------------------------------------------------
2195
2196// BEGINNING OF MODULE
2197`timescale 1 ps / 1 ps
2198
2199// MODULE DECLARATION
2200module lpm_decode (
2201    data,    // Data input. Treated as an unsigned binary encoded number. (Required)
2202    enable,  // Enable. All outputs low when not active.
2203    clock,   // Clock for pipelined usage.
2204    aclr,    // Asynchronous clear for pipelined usage.
2205    clken,   // Clock enable for pipelined usage.
2206    eq       // Decoded output. (Required)
2207);
2208
2209// GLOBAL PARAMETER DECLARATION
2210    parameter lpm_width = 1;                // Width of the data[] port, or the
2211                                            // input value to be decoded. (Required)
2212    parameter lpm_decodes = 1 << lpm_width; // Number of explicit decoder outputs. (Required)
2213    parameter lpm_pipeline = 0;             // Number of Clock cycles of latency
2214    parameter lpm_type = "lpm_decode";
2215    parameter lpm_hint = "UNUSED";
2216
2217// INPUT PORT DECLARATION
2218    input  [lpm_width-1:0] data;
2219    input  enable;
2220    input  clock;
2221    input  aclr;
2222    input  clken;
2223
2224// OUTPUT PORT DECLARATION
2225    output [lpm_decodes-1:0] eq;
2226
2227// INTERNAL REGISTER/SIGNAL DECLARATION
2228    reg    [lpm_decodes-1:0] eq_pipe [(lpm_pipeline+1):0];
2229    reg    [lpm_decodes-1:0] tmp_eq;
2230
2231// LOCAL INTEGER DECLARATION
2232    integer i;
2233    integer pipe_ptr;
2234
2235// INTERNAL TRI DECLARATION
2236    tri1   enable;
2237    tri0   clock;
2238    tri0   aclr;
2239    tri1   clken;
2240
2241    wire i_clock;
2242    wire i_clken;
2243    wire i_aclr;
2244    wire i_enable;
2245    buf (i_clock, clock);
2246    buf (i_clken, clken);
2247    buf (i_aclr, aclr);
2248    buf (i_enable, enable);
2249
2250// INITIAL CONSTRUCT BLOCK
2251    initial
2252    begin
2253        if (lpm_width <= 0)
2254        begin
2255            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
2256            $display("Time: %0t  Instance: %m", $time);
2257            $finish;
2258        end
2259        if (lpm_decodes <= 0)
2260        begin
2261            $display("Value of lpm_decodes parameter must be greater than 0 (ERROR)");
2262            $display("Time: %0t  Instance: %m", $time);
2263            $finish;
2264        end
2265        if (lpm_decodes > (1 << lpm_width))
2266        begin
2267            $display("Value of lpm_decodes parameter must be less or equal to 2^lpm_width (ERROR)");
2268            $display("Time: %0t  Instance: %m", $time);
2269            $finish;
2270        end
2271        if (lpm_pipeline < 0)
2272        begin
2273            $display("Value of lpm_pipeline parameter must be greater or equal to 0 (ERROR)");
2274            $display("Time: %0t  Instance: %m", $time);
2275            $finish;
2276        end
2277        pipe_ptr = 0;
2278    end
2279
2280// ALWAYS CONSTRUCT BLOCK
2281    always @(data or i_enable)
2282    begin
2283        tmp_eq = {lpm_decodes{1'b0}};
2284        if (i_enable)
2285            tmp_eq[data] = 1'b1;
2286    end
2287
2288    always @(posedge i_clock or posedge i_aclr)
2289    begin
2290        if (i_aclr)
2291        begin
2292            for (i = 0; i <= lpm_pipeline; i = i + 1)
2293                eq_pipe[i] <= {lpm_decodes{1'b0}};
2294
2295            pipe_ptr <= 0;
2296        end
2297        else if (clken == 1'b1)
2298        begin
2299            eq_pipe[pipe_ptr] <= tmp_eq;
2300
2301            if (lpm_pipeline > 1)
2302                pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
2303        end
2304    end
2305
2306    assign eq = (lpm_pipeline > 0) ? eq_pipe[pipe_ptr] : tmp_eq;
2307
2308endmodule // lpm_decode
2309// END OF MODULE
2310
2311//START_MODULE_NAME------------------------------------------------------------
2312//
2313// Module Name     :  lpm_clshift
2314//
2315// Description     :  Parameterized combinatorial logic shifter or barrel shifter
2316//                    megafunction.
2317//
2318// Limitation      :  n/a
2319//
2320// Results expected:  Return the shifted data and underflow/overflow status bit.
2321//
2322//END_MODULE_NAME--------------------------------------------------------------
2323
2324// BEGINNING OF MODULE
2325`timescale 1 ps / 1 ps
2326
2327// MODULE DECLARATION
2328module lpm_clshift (
2329    data,       // Data to be shifted. (Required)
2330    distance,   // Number of positions to shift data[] in the direction specified
2331                // by the direction port. (Required)
2332    direction,  // Direction of shift. Low = left (toward the MSB),
2333                //                     high = right (toward the LSB).
2334    clock,      // Clock for pipelined usage.
2335    aclr,       // Asynchronous clear for pipelined usage.
2336    clken,      // Clock enable for pipelined usage.
2337    result,     // Shifted data. (Required)
2338    underflow,  // Logical or arithmetic underflow.
2339    overflow    // Logical or arithmetic overflow.
2340);
2341
2342// GLOBAL PARAMETER DECLARATION
2343    parameter lpm_width = 1;    // Width of the data[] and result[] ports. Must be
2344                                // greater than 0 (Required)
2345    parameter lpm_widthdist = 1; // Width of the distance[] input port. (Required)
2346    parameter lpm_shifttype = "LOGICAL"; // Type of shifting operation to be performed.
2347    parameter lpm_pipeline = 0;             // Number of Clock cycles of latency
2348    parameter lpm_type = "lpm_clshift";
2349    parameter lpm_hint = "UNUSED";
2350
2351// INPUT PORT DECLARATION
2352    input  [lpm_width-1:0] data;
2353    input  [lpm_widthdist-1:0] distance;
2354    input  direction;
2355    input  clock;
2356    input  aclr;
2357    input  clken;
2358
2359// OUTPUT PORT DECLARATION
2360    output [lpm_width-1:0] result;
2361    output underflow;
2362    output overflow;
2363
2364// INTERNAL REGISTERS DECLARATION
2365    reg    [lpm_width-1:0] ONES;
2366    reg    [lpm_width-1:0] ZEROS;
2367    reg    [lpm_width-1:0] tmp_result;
2368    reg    tmp_underflow;
2369    reg    tmp_overflow;
2370    reg    [lpm_width-1:0] result_pipe [(lpm_pipeline+1):0];
2371    reg    [(lpm_pipeline+1):0] overflow_pipe;
2372    reg    [(lpm_pipeline+1):0] underflow_pipe;
2373
2374// LOCAL INTEGER DECLARATION
2375    integer i;
2376    integer i1;
2377    integer pipe_ptr;
2378
2379// INTERNAL TRI DECLARATION
2380    tri0  direction;
2381    tri0   clock;
2382    tri0   aclr;
2383    tri1   clken;
2384
2385    wire i_direction;
2386    wire i_clock;
2387    wire i_clken;
2388    wire i_aclr;
2389    buf (i_direction, direction);
2390    buf (i_clock, clock);
2391    buf (i_clken, clken);
2392    buf (i_aclr, aclr);
2393
2394
2395// FUNCTON DECLARATION
2396    // Perform logival shift operation
2397    function [lpm_width+1:0] LogicShift;
2398        input [lpm_width-1:0] data;
2399        input [lpm_widthdist-1:0] shift_num;
2400        input direction;
2401        reg   [lpm_width-1:0] tmp_buf;
2402        reg   underflow;
2403        reg   overflow;
2404
2405        begin
2406            tmp_buf = data;
2407            overflow = 1'b0;
2408            underflow = 1'b0;
2409            if ((direction) && (shift_num > 0)) // shift right
2410            begin
2411                tmp_buf = data >> shift_num;
2412                if ((data != ZEROS) && ((shift_num >= lpm_width) || (tmp_buf == ZEROS)))
2413                    underflow = 1'b1;
2414            end
2415            else if (shift_num > 0) // shift left
2416            begin
2417                tmp_buf = data << shift_num;
2418                if ((data != ZEROS) && ((shift_num >= lpm_width)
2419                    || ((data >> (lpm_width-shift_num)) != ZEROS)))
2420                    overflow = 1'b1;
2421            end
2422            LogicShift = {overflow,underflow,tmp_buf[lpm_width-1:0]};
2423        end
2424    endfunction // LogicShift
2425
2426    // Perform Arithmetic shift operation
2427    function [lpm_width+1:0] ArithShift;
2428        input [lpm_width-1:0] data;
2429        input [lpm_widthdist-1:0] shift_num;
2430        input direction;
2431        reg   [lpm_width-1:0] tmp_buf;
2432        reg   underflow;
2433        reg   overflow;
2434        integer i;
2435        integer i1;
2436
2437        begin
2438            tmp_buf = data;
2439            overflow = 1'b0;
2440            underflow = 1'b0;
2441
2442            if (shift_num < lpm_width)
2443            begin
2444                if ((direction) && (shift_num > 0))   // shift right
2445                begin
2446                    if (data[lpm_width-1] == 1'b0) // positive number
2447                    begin
2448                        tmp_buf = data >> shift_num;
2449                        if ((data != ZEROS) && ((shift_num >= lpm_width) || (tmp_buf == ZEROS)))
2450                            underflow = 1'b1;
2451                    end
2452                    else // negative number
2453                    begin
2454                        tmp_buf = (data >> shift_num) | (ONES << (lpm_width - shift_num));
2455                        if ((data != ONES) && ((shift_num >= lpm_width-1) || (tmp_buf == ONES)))
2456                            underflow = 1'b1;
2457                    end
2458                end
2459                else if (shift_num > 0) // shift left
2460                begin
2461                    tmp_buf = data << shift_num;
2462
2463                    for (i=lpm_width-1; i >= lpm_width-shift_num; i=i-1)
2464                    begin
2465                        if(data[i-1] != data[lpm_width-1])
2466                            overflow = 1'b1;
2467                    end
2468                end
2469            end
2470            else    // shift_num >= lpm_width
2471            begin
2472                if (direction)
2473                begin
2474                    for (i=0; i < lpm_width; i=i+1)
2475                        tmp_buf[i] = data[lpm_width-1];
2476
2477                    underflow = 1'b1;
2478                end
2479                else
2480                begin
2481                    tmp_buf = {lpm_width{1'b0}};
2482
2483                    if (data != ZEROS)
2484                    begin
2485                        overflow = 1'b1;
2486                    end
2487                end
2488            end
2489            ArithShift = {overflow,underflow,tmp_buf[lpm_width-1:0]};
2490        end
2491    endfunction // ArithShift
2492
2493    // Perform rotate shift operation
2494    function [lpm_width+1:0] RotateShift;
2495        input [lpm_width-1:0] data;
2496        input [lpm_widthdist-1:0] shift_num;
2497        input direction;
2498        reg   [lpm_width-1:0] tmp_buf;
2499
2500        begin
2501            tmp_buf = data;
2502            if ((direction) && (shift_num > 0)) // shift right
2503                tmp_buf = (data >> shift_num) | (data << (lpm_width - shift_num));
2504            else if (shift_num > 0) // shift left
2505                tmp_buf = (data << shift_num) | (data >> (lpm_width - shift_num));
2506            RotateShift = {2'bx, tmp_buf[lpm_width-1:0]};
2507        end
2508    endfunction // RotateShift
2509
2510// INITIAL CONSTRUCT BLOCK
2511    initial
2512    begin
2513        if ((lpm_shifttype != "LOGICAL") &&
2514            (lpm_shifttype != "ARITHMETIC") &&
2515            (lpm_shifttype != "ROTATE") &&
2516            (lpm_shifttype != "UNUSED"))          // non-LPM 220 standard
2517            begin
2518                $display("Error!  LPM_SHIFTTYPE value must be \"LOGICAL\", \"ARITHMETIC\", or \"ROTATE\".");
2519                $display("Time: %0t  Instance: %m", $time);
2520            end
2521
2522        if (lpm_width <= 0)
2523        begin
2524            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
2525            $display("Time: %0t  Instance: %m", $time);
2526            $finish;
2527        end
2528
2529        if (lpm_widthdist <= 0)
2530        begin
2531            $display("Value of lpm_widthdist parameter must be greater than 0(ERROR)");
2532            $display("Time: %0t  Instance: %m", $time);
2533            $finish;
2534        end
2535
2536        for (i=0; i < lpm_width; i=i+1)
2537        begin
2538            ONES[i] = 1'b1;
2539            ZEROS[i] = 1'b0;
2540        end
2541
2542        for (i = 0; i <= lpm_pipeline; i = i + 1)
2543        begin
2544            result_pipe[i] = ZEROS;
2545            overflow_pipe[i] = 1'b0;
2546            underflow_pipe[i] = 1'b0;
2547        end
2548
2549        tmp_result = ZEROS;
2550        tmp_underflow = 1'b0;
2551        tmp_overflow = 1'b0;
2552        pipe_ptr = 0;
2553
2554    end
2555
2556// ALWAYS CONSTRUCT BLOCK
2557    always @(data or i_direction or distance)
2558    begin
2559        if ((lpm_shifttype == "LOGICAL") || (lpm_shifttype == "UNUSED"))
2560            {tmp_overflow, tmp_underflow, tmp_result} = LogicShift(data, distance, i_direction);
2561        else if (lpm_shifttype == "ARITHMETIC")
2562            {tmp_overflow, tmp_underflow, tmp_result} = ArithShift(data, distance, i_direction);
2563        else if (lpm_shifttype == "ROTATE")
2564            {tmp_overflow, tmp_underflow, tmp_result} = RotateShift(data, distance, i_direction);
2565    end
2566
2567    always @(posedge i_clock or posedge i_aclr)
2568    begin
2569        if (i_aclr)
2570        begin
2571            for (i1 = 0; i1 <= lpm_pipeline; i1 = i1 + 1)
2572            begin
2573                result_pipe[i1] <= {lpm_width{1'b0}};
2574                overflow_pipe[i1] <= 1'b0;
2575                underflow_pipe[i1] <= 1'b0;
2576            end
2577            pipe_ptr <= 0;
2578        end
2579        else if (i_clken == 1'b1)
2580        begin
2581            result_pipe[pipe_ptr] <= tmp_result;
2582            overflow_pipe[pipe_ptr] <= tmp_overflow;
2583            underflow_pipe[pipe_ptr] <= tmp_underflow;
2584
2585            if (lpm_pipeline > 1)
2586                pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
2587        end
2588    end
2589
2590    assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : tmp_result;
2591    assign overflow = (lpm_pipeline > 0) ? overflow_pipe[pipe_ptr] : tmp_overflow;
2592    assign underflow = (lpm_pipeline > 0) ? underflow_pipe[pipe_ptr] : tmp_underflow;
2593
2594endmodule // lpm_clshift
2595//START_MODULE_NAME------------------------------------------------------------
2596//
2597// Module Name     :  lpm_add_sub
2598//
2599// Description     :  Parameterized adder/subtractor megafunction.
2600//
2601// Limitation      :  n/a
2602//
2603// Results expected:  If performs as adder, the result will be dataa[]+datab[]+cin.
2604//                    If performs as subtractor, the result will be dataa[]-datab[]+cin-1.
2605//                    Also returns carry out bit and overflow status bit.
2606//
2607//END_MODULE_NAME--------------------------------------------------------------
2608
2609// BEGINNING OF MODULE
2610`timescale 1 ps / 1 ps
2611
2612// MODULE DECLARATION
2613module lpm_add_sub (
2614    dataa,      // Augend/Minuend
2615    datab,      // Addend/Subtrahend
2616    cin,        // Carry-in to the low-order bit.
2617    add_sub,    // If the signal is high, the operation = dataa[]+datab[]+cin.
2618                // If the signal is low, the operation = dataa[]-datab[]+cin-1.
2619
2620    clock,      // Clock for pipelined usage.
2621    aclr,       // Asynchronous clear for pipelined usage.
2622    clken,      // Clock enable for pipelined usage.
2623    result,     // dataa[]+datab[]+cin or dataa[]-datab[]+cin-1
2624    cout,       // Carry-out (borrow-in) of the MSB.
2625    overflow    // Result exceeds available precision.
2626);
2627
2628// GLOBAL PARAMETER DECLARATION
2629    parameter lpm_width = 1; // Width of the dataa[],datab[], and result[] ports.
2630    parameter lpm_representation = "SIGNED"; // Type of addition performed
2631    parameter lpm_direction  = "UNUSED";  // Specify the operation of the lpm_add_sub function
2632    parameter lpm_pipeline = 0; // Number of Clock cycles of latency
2633    parameter lpm_type = "lpm_add_sub";
2634    parameter lpm_hint = "UNUSED";
2635
2636// INPUT PORT DECLARATION
2637    input  [lpm_width-1:0] dataa;
2638    input  [lpm_width-1:0] datab;
2639    input  cin;
2640    input  add_sub;
2641    input  clock;
2642    input  aclr;
2643    input  clken;
2644
2645// OUTPUT PORT DECLARATION
2646    output [lpm_width-1:0] result;
2647    output cout;
2648    output overflow;
2649
2650// INTERNAL REGISTER/SIGNAL DECLARATION
2651    reg [lpm_width-1:0] result_pipe [(lpm_pipeline+1):0];
2652    reg [(lpm_pipeline+1):0] cout_pipe;
2653    reg [(lpm_pipeline+1):0] overflow_pipe;
2654    reg tmp_cout;
2655    reg tmp_overflow;
2656    reg [lpm_width-1:0] tmp_result;
2657    reg i_cin;
2658
2659// LOCAL INTEGER DECLARATION
2660    integer borrow;
2661    integer i;
2662    integer pipe_ptr;
2663
2664// INTERNAL TRI DECLARATION
2665    tri1 i_add_sub;
2666    tri0 i_aclr;
2667    tri1 i_clken;
2668    tri0 i_clock;
2669
2670
2671// INITIAL CONSTRUCT BLOCK
2672    initial
2673    begin
2674        // check if lpm_width < 0
2675        if (lpm_width <= 0)
2676        begin
2677            $display("Error!  LPM_WIDTH must be greater than 0.\n");
2678            $display("Time: %0t  Instance: %m", $time);
2679            $finish;
2680        end
2681        if ((lpm_direction != "ADD") &&
2682            (lpm_direction != "SUB") &&
2683            (lpm_direction != "UNUSED") &&   // non-LPM 220 standard
2684            (lpm_direction != "DEFAULT"))    // non-LPM 220 standard
2685        begin
2686            $display("Error!  LPM_DIRECTION value must be \"ADD\" or \"SUB\".");
2687            $display("Time: %0t  Instance: %m", $time);
2688            $finish;
2689        end
2690        if ((lpm_representation != "SIGNED") &&
2691            (lpm_representation != "UNSIGNED"))
2692        begin
2693            $display("Error!  LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
2694            $display("Time: %0t  Instance: %m", $time);
2695            $finish;
2696        end
2697        if (lpm_pipeline < 0)
2698        begin
2699            $display("Error!  LPM_PIPELINE must be greater than or equal to 0.\n");
2700            $display("Time: %0t  Instance: %m", $time);
2701            $finish;
2702        end
2703
2704        for (i = 0; i <= (lpm_pipeline+1); i = i + 1)
2705        begin
2706            result_pipe[i] = 'b0;
2707            cout_pipe[i] = 1'b0;
2708            overflow_pipe[i] = 1'b0;
2709        end
2710
2711        pipe_ptr = 0;
2712    end
2713
2714// ALWAYS CONSTRUCT BLOCK
2715    always @(cin or dataa or datab or i_add_sub)
2716    begin
2717        i_cin = 1'b0;
2718        borrow = 1'b0;
2719
2720        // cout is the same for both signed and unsign representation.
2721        if ((lpm_direction == "ADD") || ((i_add_sub == 1) &&
2722            ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) ))
2723        begin
2724            i_cin = (cin === 1'bz) ? 0 : cin;
2725            {tmp_cout, tmp_result} = dataa + datab + i_cin;
2726            tmp_overflow = tmp_cout;
2727        end
2728        else if ((lpm_direction == "SUB") || ((i_add_sub == 0) &&
2729                ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) ))
2730        begin
2731            i_cin = (cin === 1'bz) ? 1 : cin;
2732            borrow = (~i_cin) ? 1 : 0;
2733            {tmp_overflow, tmp_result} = dataa - datab - borrow;
2734            tmp_cout = (dataa >= (datab+borrow))?1:0;
2735        end
2736
2737        if (lpm_representation == "SIGNED")
2738        begin
2739            // perform the addtion or subtraction operation
2740            if ((lpm_direction == "ADD") || ((i_add_sub == 1) &&
2741                ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) ))
2742            begin
2743                tmp_result = dataa + datab + i_cin;
2744                tmp_overflow = ((dataa[lpm_width-1] == datab[lpm_width-1]) &&
2745                                                (dataa[lpm_width-1] != tmp_result[lpm_width-1])) ?
2746                                                1 : 0;
2747            end
2748            else if ((lpm_direction == "SUB") || ((i_add_sub == 0) &&
2749                    ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) ))
2750            begin
2751                tmp_result = dataa - datab - borrow;
2752                tmp_overflow = ((dataa[lpm_width-1] != datab[lpm_width-1]) &&
2753                                                (dataa[lpm_width-1] != tmp_result[lpm_width-1])) ?
2754                                                1 : 0;
2755            end
2756        end
2757    end
2758
2759    always @(posedge i_clock or posedge i_aclr)
2760    begin
2761        if (i_aclr)
2762        begin
2763            for (i = 0; i <= (lpm_pipeline+1); i = i + 1)
2764            begin
2765                result_pipe[i] <= {lpm_width{1'b0}};
2766                cout_pipe[i] <= 1'b0;
2767                overflow_pipe[i] <= 1'b0;
2768            end
2769            pipe_ptr <= 0;
2770        end
2771        else if (i_clken == 1)
2772        begin
2773            result_pipe[pipe_ptr] <= tmp_result;
2774            cout_pipe[pipe_ptr] <= tmp_cout;
2775            overflow_pipe[pipe_ptr] <= tmp_overflow;
2776
2777            if (lpm_pipeline > 1)
2778                pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
2779        end
2780    end
2781
2782// CONTINOUS ASSIGNMENT
2783    assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : tmp_result;
2784    assign cout = (lpm_pipeline > 0) ? cout_pipe[pipe_ptr] : tmp_cout;
2785    assign overflow = (lpm_pipeline > 0) ? overflow_pipe[pipe_ptr] : tmp_overflow;
2786    assign i_clock = clock;
2787    assign i_aclr = aclr;
2788    assign i_clken = clken;
2789    assign i_add_sub = add_sub;
2790
2791endmodule // lpm_add_sub
2792// END OF MODULE
2793
2794//START_MODULE_NAME------------------------------------------------------------
2795//
2796// Module Name     :  lpm_compare
2797//
2798// Description     :  Parameterized comparator megafunction. The comparator will
2799//                    compare between data[] and datab[] and return the status of
2800//                    comparation for the following operation.
2801//                    1) dataa[] < datab[].
2802//                    2) dataa[] == datab[].
2803//                    3) dataa[] > datab[].
2804//                    4) dataa[] >= datab[].
2805//                    5) dataa[] != datab[].
2806//                    6) dataa[] <= datab[].
2807//
2808// Limitation      :  n/a
2809//
2810// Results expected:  Return status bits of the comparision between dataa[] and
2811//                    datab[].
2812//
2813//END_MODULE_NAME--------------------------------------------------------------
2814
2815// BEGINNING OF MODULE
2816`timescale 1 ps / 1 ps
2817
2818// MODULE DECLARATION
2819module lpm_compare (
2820    dataa,   // Value to be compared to datab[]. (Required)
2821    datab,   // Value to be compared to dataa[]. (Required)
2822    clock,   // Clock for pipelined usage.
2823    aclr,    // Asynchronous clear for pipelined usage.
2824    clken,   // Clock enable for pipelined usage.
2825
2826    // One of the following ports must be present.
2827    alb,     // High (1) if dataa[] < datab[].
2828    aeb,     // High (1) if dataa[] == datab[].
2829    agb,     // High (1) if dataa[] > datab[].
2830    aleb,    // High (1) if dataa[] <= datab[].
2831    aneb,    // High (1) if dataa[] != datab[].
2832    ageb     // High (1) if dataa[] >= datab[].
2833);
2834
2835// GLOBAL PARAMETER DECLARATION
2836    parameter lpm_width = 1;  // Width of the dataa[] and datab[] ports. (Required)
2837    parameter lpm_representation = "UNSIGNED";  // Type of comparison performed:
2838                                                // "SIGNED", "UNSIGNED"
2839    parameter lpm_pipeline = 0; // Specifies the number of Clock cycles of latency
2840                                // associated with the alb, aeb, agb, ageb, aleb,
2841                                //  or aneb output.
2842    parameter lpm_type = "lpm_compare";
2843    parameter lpm_hint = "UNUSED";
2844
2845// INPUT PORT DECLARATION
2846    input  [lpm_width-1:0] dataa;
2847    input  [lpm_width-1:0] datab;
2848    input  clock;
2849    input  aclr;
2850    input  clken;
2851
2852// OUTPUT PORT DECLARATION
2853    output alb;
2854    output aeb;
2855    output agb;
2856    output aleb;
2857    output aneb;
2858    output ageb;
2859
2860// INTERNAL REGISTERS DECLARATION
2861    reg [lpm_pipeline+1:0] alb_pipe;
2862    reg [lpm_pipeline+1:0] aeb_pipe;
2863    reg [lpm_pipeline+1:0] agb_pipe;
2864    reg [lpm_pipeline+1:0] aleb_pipe;
2865    reg [lpm_pipeline+1:0] aneb_pipe;
2866    reg [lpm_pipeline+1:0] ageb_pipe;
2867    reg tmp_alb;
2868    reg tmp_aeb;
2869    reg tmp_agb;
2870    reg tmp_aleb;
2871    reg tmp_aneb;
2872    reg tmp_ageb;
2873
2874
2875// LOCAL INTEGER DECLARATION
2876    integer i;
2877    integer pipe_ptr;
2878
2879// INTERNAL TRI DECLARATION
2880    tri0 aclr;
2881    tri0 clock;
2882    tri1 clken;
2883
2884    wire i_aclr;
2885    wire i_clock;
2886    wire i_clken;
2887    buf (i_aclr, aclr);
2888    buf (i_clock, clock);
2889    buf (i_clken, clken);
2890
2891// INITIAL CONSTRUCT BLOCK
2892    initial
2893    begin
2894        if ((lpm_representation != "SIGNED") &&
2895            (lpm_representation != "UNSIGNED"))
2896        begin
2897            $display("Error!  LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
2898            $display("Time: %0t  Instance: %m", $time);
2899            $finish;
2900        end
2901        if (lpm_width <= 0)
2902        begin
2903            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
2904            $display("Time: %0t  Instance: %m", $time);
2905            $finish;
2906        end
2907
2908        pipe_ptr = 0;
2909    end
2910
2911// ALWAYS CONSTRUCT BLOCK
2912    // get the status of comparison
2913    always @(dataa or datab)
2914    begin
2915        tmp_aeb = (dataa == datab);
2916        tmp_aneb = (dataa != datab);
2917
2918        if ((lpm_representation == "SIGNED") &&
2919            ((dataa[lpm_width-1] ^ datab[lpm_width-1]) == 1))
2920        begin
2921            // create latency
2922            tmp_alb = (dataa > datab);
2923            tmp_agb = (dataa < datab);
2924            tmp_aleb = (dataa >= datab);
2925            tmp_ageb = (dataa <= datab);
2926        end
2927        else
2928        begin
2929        // create latency
2930            tmp_alb = (dataa < datab);
2931            tmp_agb = (dataa > datab);
2932            tmp_aleb = (dataa <= datab);
2933            tmp_ageb = (dataa >= datab);
2934        end
2935    end
2936
2937    // pipelining process
2938    always @(posedge i_clock or posedge i_aclr)
2939    begin
2940        if (i_aclr) // reset all variables
2941        begin
2942            for (i = 0; i <= (lpm_pipeline + 1); i = i + 1)
2943            begin
2944                aeb_pipe[i] <= 1'b0;
2945                agb_pipe[i] <= 1'b0;
2946                alb_pipe[i] <= 1'b0;
2947                aleb_pipe[i] <= 1'b0;
2948                aneb_pipe[i] <= 1'b0;
2949                ageb_pipe[i] <= 1'b0;
2950            end
2951            pipe_ptr <= 0;
2952        end
2953        else if (i_clken == 1)
2954        begin
2955            alb_pipe[pipe_ptr] <= tmp_alb;
2956            aeb_pipe[pipe_ptr] <= tmp_aeb;
2957            agb_pipe[pipe_ptr] <= tmp_agb;
2958            aleb_pipe[pipe_ptr] <= tmp_aleb;
2959            aneb_pipe[pipe_ptr] <= tmp_aneb;
2960            ageb_pipe[pipe_ptr] <= tmp_ageb;
2961
2962            if (lpm_pipeline > 1)
2963                pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
2964        end
2965    end
2966
2967// CONTINOUS ASSIGNMENT
2968    assign alb = (lpm_pipeline > 0) ? alb_pipe[pipe_ptr] : tmp_alb;
2969    assign aeb = (lpm_pipeline > 0) ? aeb_pipe[pipe_ptr] : tmp_aeb;
2970    assign agb = (lpm_pipeline > 0) ? agb_pipe[pipe_ptr] : tmp_agb;
2971    assign aleb = (lpm_pipeline > 0) ? aleb_pipe[pipe_ptr] : tmp_aleb;
2972    assign aneb = (lpm_pipeline > 0) ? aneb_pipe[pipe_ptr] : tmp_aneb;
2973    assign ageb = (lpm_pipeline > 0) ? ageb_pipe[pipe_ptr] : tmp_ageb;
2974
2975endmodule // lpm_compare
2976
2977//START_MODULE_NAME------------------------------------------------------------
2978//
2979// Module Name     :  lpm_mult
2980//
2981// Description     :  Parameterized multiplier megafunction.
2982//
2983// Limitation      :  n/a
2984//
2985// Results expected:  dataa[] * datab[] + sum[].
2986//
2987//END_MODULE_NAME--------------------------------------------------------------
2988
2989// BEGINNING OF MODULE
2990`timescale 1 ps / 1 ps
2991
2992// MODULE DECLARATION
2993module lpm_mult (
2994    dataa,  // Multiplicand. (Required)
2995    datab,  // Multiplier. (Required)
2996    sum,    // Partial sum.
2997    aclr,   // Asynchronous clear for pipelined usage.
2998    sclr,   // Synchronous clear for pipelined usage.
2999    clock,  // Clock for pipelined usage.
3000    clken,  // Clock enable for pipelined usage.
3001    result  // result = dataa[] * datab[] + sum. The product LSB is aligned with the sum LSB.
3002);
3003
3004// GLOBAL PARAMETER DECLARATION
3005    parameter lpm_widtha = 1; // Width of the dataa[] port. (Required)
3006    parameter lpm_widthb = 1; // Width of the datab[] port. (Required)
3007    parameter lpm_widthp = 1; // Width of the result[] port. (Required)
3008    parameter lpm_widths = 1; // Width of the sum[] port. (Required)
3009    parameter lpm_representation  = "UNSIGNED"; // Type of multiplication performed
3010    parameter lpm_pipeline  = 0; // Number of clock cycles of latency
3011    parameter lpm_type = "lpm_mult";
3012    parameter lpm_hint = "UNUSED";
3013
3014// INPUT PORT DECLARATION
3015    input  [lpm_widtha-1:0] dataa;
3016    input  [lpm_widthb-1:0] datab;
3017    input  [lpm_widths-1:0] sum;
3018    input  aclr;
3019    input  sclr;
3020    input  clock;
3021    input  clken;
3022
3023// OUTPUT PORT DECLARATION
3024    output [lpm_widthp-1:0] result;
3025
3026// INTERNAL REGISTER/SIGNAL DECLARATION
3027    reg [lpm_widthp-1:0] result_pipe [lpm_pipeline+1:0];
3028    reg [lpm_widthp-1:0] i_prod;
3029    reg [lpm_widthp-1:0] t_p;
3030    reg [lpm_widths-1:0] i_prod_s;
3031    reg [lpm_widths-1:0] t_s;
3032    reg [lpm_widtha+lpm_widthb-1:0] i_prod_ab;
3033    reg [lpm_widtha-1:0] t_a;
3034    reg [lpm_widthb-1:0] t_b;
3035    reg sign_ab;
3036    reg sign_s;
3037    reg [8*5:1] input_a_is_constant;
3038    reg [8*5:1] input_b_is_constant;
3039    reg [8*lpm_widtha:1] input_a_fixed_value;
3040    reg [8*lpm_widthb:1] input_b_fixed_value;
3041    reg [lpm_widtha-1:0] dataa_fixed;
3042    reg [lpm_widthb-1:0] datab_fixed;
3043
3044
3045// LOCAL INTEGER DECLARATION
3046    integer i;
3047    integer pipe_ptr;
3048
3049// INTERNAL WIRE DECLARATION
3050    wire [lpm_widtha-1:0] dataa_wire;
3051    wire [lpm_widthb-1:0] datab_wire;
3052
3053// INTERNAL TRI DECLARATION
3054    tri0 aclr;
3055    tri0 sclr;
3056    tri0 clock;
3057    tri1 clken;
3058
3059    wire i_aclr;
3060    wire i_sclr;
3061    wire i_clock;
3062    wire i_clken;
3063    buf (i_aclr, aclr);
3064    buf (i_sclr, sclr);
3065    buf (i_clock, clock);
3066    buf (i_clken, clken);
3067
3068// COMPONENT INSTANTIATIONS
3069    LPM_HINT_EVALUATION eva();
3070
3071// FUNCTION DECLARATION
3072    // convert string to binary bits.
3073    function integer str2bin;
3074    input [8*256:1] str;
3075    input str_width;
3076
3077    reg [8*256:1] reg_str;
3078    reg [255:0] bin;
3079    reg [8:1] tmp;
3080    integer m;
3081    integer str_width;
3082
3083    begin
3084        reg_str = str;
3085        for (m=0; m < str_width; m=m+1)
3086        begin
3087            tmp = reg_str[8:1];
3088            reg_str = reg_str >> 8;
3089
3090            case (tmp)
3091                "0"    : bin[m] = 1'b0;
3092                "1"    : bin[m] = 1'b1;
3093                default: bin[m] = 1'bx;
3094            endcase
3095        end
3096        str2bin = bin;
3097    end
3098    endfunction
3099
3100// INITIAL CONSTRUCT BLOCK
3101    initial
3102    begin
3103        // check if lpm_widtha > 0
3104        if (lpm_widtha <= 0)
3105        begin
3106            $display("Error!  lpm_widtha must be greater than 0.\n");
3107            $display("Time: %0t  Instance: %m", $time);
3108            $finish;
3109        end
3110        // check if lpm_widthb > 0
3111        if (lpm_widthb <= 0)
3112        begin
3113            $display("Error!  lpm_widthb must be greater than 0.\n");
3114            $display("Time: %0t  Instance: %m", $time);
3115            $finish;
3116        end
3117        // check if lpm_widthp > 0
3118        if (lpm_widthp <= 0)
3119        begin
3120            $display("Error!  lpm_widthp must be greater than 0.\n");
3121            $display("Time: %0t  Instance: %m", $time);
3122            $finish;
3123        end
3124        // check if lpm_widthp > 0
3125        if (lpm_widths <= 0)
3126        begin
3127            $display("Error!  lpm_widths must be greater than 0.\n");
3128            $display("Time: %0t  Instance: %m", $time);
3129            $finish;
3130        end
3131        // check for valid lpm_rep value
3132        if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED"))
3133        begin
3134            $display("Error!  lpm_representation value must be \"SIGNED\" or \"UNSIGNED\".", $time);
3135            $display("Time: %0t  Instance: %m", $time);
3136            $finish;
3137        end
3138
3139        input_a_is_constant = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_A_IS_CONSTANT");
3140
3141        if (input_a_is_constant == "FIXED")
3142        begin
3143            input_a_fixed_value = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_A_FIXED_VALUE");
3144            dataa_fixed = str2bin(input_a_fixed_value, lpm_widtha);
3145        end
3146
3147        input_b_is_constant = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_B_IS_CONSTANT");
3148
3149        if (input_b_is_constant == "FIXED")
3150        begin
3151            input_b_fixed_value = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_B_FIXED_VALUE");
3152            datab_fixed = str2bin(input_b_fixed_value, lpm_widthb);
3153        end
3154
3155        pipe_ptr = 0;
3156    end
3157
3158// ALWAYS CONSTRUCT BLOCK
3159    always @(dataa_wire or datab_wire or sum)
3160    begin
3161        t_a = dataa_wire;
3162        t_b = datab_wire;
3163        t_s = sum;
3164        sign_ab = 1'b0;
3165        sign_s = 1'b0;
3166
3167        // if inputs are sign number
3168        if (lpm_representation == "SIGNED")
3169        begin
3170            sign_ab = dataa_wire[lpm_widtha-1] ^ datab_wire[lpm_widthb-1];
3171            sign_s = sum[lpm_widths-1];
3172
3173            // if negative number, represent them as 2 compliment number.
3174            if (dataa_wire[lpm_widtha-1] == 1)
3175                t_a = (~dataa_wire) + 1;
3176            if (datab_wire[lpm_widthb-1] == 1)
3177                t_b = (~datab_wire) + 1;
3178            if (sum[lpm_widths-1] == 1)
3179                t_s = (~sum) + 1;
3180        end
3181
3182        // if sum port is not used
3183        if (sum === {lpm_widths{1'bz}})
3184        begin
3185            t_s = {lpm_widths{1'b0}};
3186            sign_s = 1'b0;
3187        end
3188
3189        if (sign_ab == sign_s)
3190        begin
3191            i_prod = (t_a * t_b) + t_s;
3192            i_prod_s = (t_a * t_b) + t_s;
3193            i_prod_ab = (t_a * t_b) + t_s;
3194        end
3195        else
3196        begin
3197            i_prod = (t_a * t_b) - t_s;
3198            i_prod_s = (t_a * t_b) - t_s;
3199            i_prod_ab = (t_a * t_b) - t_s;
3200        end
3201
3202        // if dataa[] * datab[] produces negative number, compliment the result
3203        if (sign_ab)
3204        begin
3205            i_prod = (~i_prod) + 1;
3206            i_prod_s = (~i_prod_s) + 1;
3207            i_prod_ab = (~i_prod_ab) + 1;
3208        end
3209
3210        if ((lpm_widthp < lpm_widths) || (lpm_widthp < (lpm_widtha+lpm_widthb)))
3211            for (i = 0; i < lpm_widthp; i = i + 1)
3212                i_prod[lpm_widthp-1-i] = (lpm_widths > lpm_widtha+lpm_widthb)
3213                                            ? i_prod_s[lpm_widths-1-i]
3214                                            : i_prod_ab[lpm_widtha+lpm_widthb-1-i];
3215
3216    end
3217
3218    always @(posedge i_clock or posedge i_aclr)
3219    begin
3220        if (i_aclr) // clear the pipeline for result to 0
3221        begin
3222            for (i = 0; i <= (lpm_pipeline + 1); i = i + 1)
3223                result_pipe[i] <= {lpm_widthp{1'b0}};
3224
3225            pipe_ptr <= 0;
3226        end
3227        else if (i_clken == 1)
3228        begin
3229            if(i_sclr)
3230            begin
3231                for (i = 0; i <= (lpm_pipeline + 1); i = i + 1)
3232                result_pipe[i] <= {lpm_widthp{1'b0}};
3233
3234                pipe_ptr <= 0;
3235            end
3236            else
3237            begin
3238                result_pipe[pipe_ptr] <= i_prod;
3239
3240                if (lpm_pipeline > 1)
3241                    pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
3242            end
3243        end
3244    end
3245
3246// CONTINOUS ASSIGNMENT
3247    assign dataa_wire =  (input_a_is_constant == "FIXED") ? dataa_fixed : dataa;
3248    assign datab_wire =  (input_b_is_constant == "FIXED") ? datab_fixed : datab;
3249    assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : i_prod;
3250
3251endmodule // lpm_mult
3252// END OF MODULE
3253
3254//START_MODULE_NAME------------------------------------------------------------
3255//
3256// Module Name     :  lpm_divide
3257//
3258// Description     :  Parameterized divider megafunction. This function performs a
3259//                    divide operation such that denom * quotient + remain = numer
3260//                    The function allows for all combinations of signed(two's
3261//                    complement) and unsigned inputs. If any of the inputs is
3262//                    signed, the output is signed. Otherwise the output is unsigned.
3263//                    The function also allows the remainder to be specified as
3264//                    always positive (in which case remain >= 0); otherwise remain
3265//                    is zero or the same sign as the numerator
3266//                    (this parameter is ignored in the case of purely unsigned
3267//                    division). Finally the function is also pipelinable.
3268//
3269// Limitation      :  n/a
3270//
3271// Results expected:  Return quotient and remainder.
3272//
3273//END_MODULE_NAME--------------------------------------------------------------
3274
3275// BEGINNING OF MODULE
3276`timescale 1 ps / 1 ps
3277
3278// MODULE DECLARATION
3279module lpm_divide (
3280    numer,  // The numerator (Required)
3281    denom,  // The denominator (Required)
3282    clock,  // Clock input for pipelined usage
3283    aclr,   // Asynchronous clear signal
3284    clken,  // Clock enable for pipelined usage.
3285    quotient, // Quotient (Required)
3286    remain    // Remainder (Required)
3287);
3288
3289// GLOBAL PARAMETER DECLARATION
3290    parameter lpm_widthn = 1;  // Width of the numer[] and quotient[] port. (Required)
3291    parameter lpm_widthd = 1;  // Width of the denom[] and remain[] port. (Required)
3292    parameter lpm_nrepresentation = "UNSIGNED";  // The representation of numer
3293    parameter lpm_drepresentation = "UNSIGNED";  // The representation of denom
3294    parameter lpm_pipeline = 0; // Number of Clock cycles of latency
3295    parameter lpm_type = "lpm_divide";
3296    parameter lpm_hint = "LPM_REMAINDERPOSITIVE=TRUE";
3297
3298// INPUT PORT DECLARATION
3299    input  [lpm_widthn-1:0] numer;
3300    input  [lpm_widthd-1:0] denom;
3301    input  clock;
3302    input  aclr;
3303    input  clken;
3304
3305// OUTPUT PORT DECLARATION
3306    output [lpm_widthn-1:0] quotient;
3307    output [lpm_widthd-1:0] remain;
3308
3309// INTERNAL REGISTER/SIGNAL DECLARATION
3310    reg [lpm_widthn-1:0] quotient_pipe [lpm_pipeline+1:0];
3311    reg [lpm_widthd-1:0] remain_pipe [lpm_pipeline+1:0];
3312    reg [lpm_widthn-1:0] tmp_quotient;
3313    reg [lpm_widthd-1:0] tmp_remain;
3314    reg [lpm_widthn-1:0] not_numer;
3315    reg [lpm_widthn-1:0] int_numer;
3316    reg [lpm_widthd-1:0] not_denom;
3317    reg [lpm_widthd-1:0] int_denom;
3318    reg [lpm_widthn-1:0] t_numer;
3319    reg [lpm_widthn-1:0] t_q;
3320    reg [lpm_widthd-1:0] t_denom;
3321    reg [lpm_widthd-1:0] t_r;
3322    reg sign_q;
3323    reg sign_r;
3324    reg sign_n;
3325    reg sign_d;
3326    reg [8*5:1] lpm_remainderpositive;
3327
3328
3329// LOCAL INTEGER DECLARATION
3330    integer i;
3331    integer rsig;
3332    integer pipe_ptr;
3333
3334// INTERNAL TRI DECLARATION
3335    tri0 aclr;
3336    tri0 clock;
3337    tri1 clken;
3338
3339    wire i_aclr;
3340    wire i_clock;
3341    wire i_clken;
3342    buf (i_aclr, aclr);
3343    buf (i_clock, clock);
3344    buf (i_clken, clken);
3345
3346// COMPONENT INSTANTIATIONS
3347    LPM_HINT_EVALUATION eva();
3348
3349// INITIAL CONSTRUCT BLOCK
3350    initial
3351    begin
3352        // check if lpm_widthn > 0
3353        if (lpm_widthn <= 0)
3354        begin
3355            $display("Error!  LPM_WIDTHN must be greater than 0.\n");
3356            $display("Time: %0t  Instance: %m", $time);
3357            $finish;
3358        end
3359        // check if lpm_widthd > 0
3360        if (lpm_widthd <= 0)
3361        begin
3362            $display("Error!  LPM_WIDTHD must be greater than 0.\n");
3363            $display("Time: %0t  Instance: %m", $time);
3364            $finish;
3365        end
3366        // check for valid lpm_nrepresentation value
3367        if ((lpm_nrepresentation != "SIGNED") && (lpm_nrepresentation != "UNSIGNED"))
3368        begin
3369            $display("Error!  LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
3370            $display("Time: %0t  Instance: %m", $time);
3371            $finish;
3372        end
3373        // check for valid lpm_drepresentation value
3374        if ((lpm_drepresentation != "SIGNED") && (lpm_drepresentation != "UNSIGNED"))
3375        begin
3376            $display("Error!  LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
3377            $display("Time: %0t  Instance: %m", $time);
3378            $finish;
3379        end
3380        // check for valid lpm_remainderpositive value
3381        lpm_remainderpositive = eva.GET_PARAMETER_VALUE(lpm_hint, "LPM_REMAINDERPOSITIVE");
3382        if ((lpm_remainderpositive == "TRUE") &&
3383            (lpm_remainderpositive == "FALSE"))
3384        begin
3385            $display("Error!  LPM_REMAINDERPOSITIVE value must be \"TRUE\" or \"FALSE\".");
3386            $display("Time: %0t  Instance: %m", $time);
3387            $finish;
3388        end
3389
3390        for (i = 0; i <= (lpm_pipeline+1); i = i + 1)
3391        begin
3392            quotient_pipe[i] <= {lpm_widthn{1'b0}};
3393            remain_pipe[i] <= {lpm_widthd{1'b0}};
3394        end
3395
3396        pipe_ptr = 0;
3397    end
3398
3399// ALWAYS CONSTRUCT BLOCK
3400    always @(numer or denom or lpm_remainderpositive)
3401    begin
3402        sign_q = 1'b0;
3403        sign_r = 1'b0;
3404        sign_n = 1'b0;
3405        sign_d = 1'b0;
3406        t_numer = numer;
3407        t_denom = denom;
3408
3409        if (lpm_nrepresentation == "SIGNED")
3410            if (numer[lpm_widthn-1] == 1'b1)
3411            begin
3412                t_numer = ~numer + 1;  // numer is negative number
3413                sign_n = 1'b1;
3414            end
3415
3416        if (lpm_drepresentation == "SIGNED")
3417            if (denom[lpm_widthd-1] == 1'b1)
3418            begin
3419                t_denom = ~denom + 1; // denom is negative numbrt
3420                sign_d = 1'b1;
3421            end
3422
3423        t_q = t_numer / t_denom; // get quotient
3424        t_r = t_numer % t_denom; // get remainder
3425        sign_q = sign_n ^ sign_d;
3426        sign_r = (t_r != {lpm_widthd{1'b0}}) ? sign_n : 1'b0;
3427
3428        // Pipeline the result
3429        tmp_quotient = (sign_q == 1'b1) ? (~t_q + 1) : t_q;
3430        tmp_remain   = (sign_r == 1'b1) ? (~t_r + 1) : t_r;
3431
3432        // Recalculate the quotient and remainder if remainder is negative number
3433        // and LPM_REMAINDERPOSITIVE=TRUE.
3434        if ((sign_r) && (lpm_remainderpositive == "TRUE"))
3435        begin
3436            tmp_quotient = tmp_quotient + ((sign_d == 1'b1) ? 1 : -1 );
3437            tmp_remain = tmp_remain + t_denom;
3438        end
3439    end
3440
3441    always @(posedge i_clock or posedge i_aclr)
3442    begin
3443        if (i_aclr)
3444        begin
3445            for (i = 0; i <= (lpm_pipeline+1); i = i + 1)
3446            begin
3447                quotient_pipe[i] <= {lpm_widthn{1'b0}};
3448                remain_pipe[i] <= {lpm_widthd{1'b0}};
3449            end
3450            pipe_ptr <= 0;
3451        end
3452        else if (i_clken)
3453        begin
3454            quotient_pipe[pipe_ptr] <= tmp_quotient;
3455            remain_pipe[pipe_ptr] <= tmp_remain;
3456
3457            if (lpm_pipeline > 1)
3458                pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline;
3459        end
3460    end
3461
3462// CONTINOUS ASSIGNMENT
3463    assign quotient = (lpm_pipeline > 0) ? quotient_pipe[pipe_ptr] : tmp_quotient;
3464    assign remain = (lpm_pipeline > 0) ? remain_pipe[pipe_ptr] : tmp_remain;
3465
3466endmodule // lpm_divide
3467// END OF MODULE
3468
3469//START_MODULE_NAME------------------------------------------------------------
3470//
3471// Module Name     :  lpm_abs
3472//
3473// Description     :  Parameterized absolute value megafunction. This megafunction
3474//                    requires the input data to be signed number.
3475//
3476// Limitation      :  n/a
3477//
3478// Results expected:  Return absolute value of data and the overflow status
3479//
3480//END_MODULE_NAME--------------------------------------------------------------
3481
3482// BEGINNING OF MODULE
3483`timescale 1 ps / 1 ps
3484
3485// MODULE DECLARATION
3486module lpm_abs (
3487    data,     // Signed number (Required)
3488    result,   // Absolute value of data[].
3489    overflow  // High if data = -2 ^ (LPM_WIDTH-1).
3490);
3491
3492// GLOBAL PARAMETER DECLARATION
3493    parameter lpm_width = 1; // Width of the data[] and result[] ports.(Required)
3494    parameter lpm_type = "lpm_abs";
3495    parameter lpm_hint = "UNUSED";
3496
3497// INPUT PORT DECLARATION
3498    input  [lpm_width-1:0] data;
3499
3500// OUTPUT PORT DECLARATION
3501    output [lpm_width-1:0] result;
3502    output overflow;
3503
3504// INTERNAL REGISTER/SIGNAL DECLARATION
3505    reg [lpm_width-1:0] result_tmp;
3506    reg overflow;
3507
3508// INITIAL CONSTRUCT BLOCK
3509    initial
3510    begin
3511        if (lpm_width <= 0)
3512        begin
3513            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
3514            $display("Time: %0t  Instance: %m", $time);
3515            $finish;
3516        end
3517    end
3518
3519// ALWAYS CONSTRUCT BLOCK
3520    always @(data)
3521    begin
3522        result_tmp = (data[lpm_width-1] == 1) ? (~data) + 1 : data;
3523        overflow = (data[lpm_width-1] == 1) ? (result_tmp == (1<<(lpm_width-1))) : 0;
3524    end
3525
3526// CONTINOUS ASSIGNMENT
3527    assign result = result_tmp;
3528
3529endmodule // lpm_abs
3530
3531//START_MODULE_NAME------------------------------------------------------------
3532//
3533// Module Name     :  lpm_counter
3534//
3535// Description     :  Parameterized counter megafunction. The lpm_counter
3536//                    megafunction is a binary counter that features an up,
3537//                    down, or up/down counter with optional synchronous or
3538//                    asynchronous clear, set, and load ports.
3539//
3540// Limitation      :  n/a
3541//
3542// Results expected:  Data output from the counter and carry-out of the MSB.
3543//
3544//END_MODULE_NAME--------------------------------------------------------------
3545
3546// BEGINNING OF MODULE
3547`timescale 1 ps / 1 ps
3548
3549// MODULE DECLARATION
3550module lpm_counter (
3551    clock,  // Positive-edge-triggered clock. (Required)
3552    clk_en, // Clock enable input. Enables all synchronous activities.
3553    cnt_en, // Count enable input. Disables the count when low (0) without
3554            // affecting sload, sset, or sclr.
3555    updown, // Controls the direction of the count. High (1) = count up.
3556            //                                      Low (0) = count down.
3557    aclr,   // Asynchronous clear input.
3558    aset,   // Asynchronous set input.
3559    aload,  // Asynchronous load input. Asynchronously loads the counter with
3560            // the value on the data input.
3561    sclr,   // Synchronous clear input. Clears the counter on the next active
3562            // clock edge.
3563    sset,   // Synchronous set input. Sets the counter on the next active clock edge.
3564    sload,  // Synchronous load input. Loads the counter with data[] on the next
3565            // active clock edge.
3566    data,   // Parallel data input to the counter.
3567    cin,    // Carry-in to the low-order bit.
3568    q,      // Data output from the counter.
3569    cout,   // Carry-out of the MSB.
3570    eq      // Counter decode output. Active high when the counter reaches the specified
3571            // count value.
3572);
3573
3574// GLOBAL PARAMETER DECLARATION
3575    parameter lpm_width = 1;    //The number of bits in the count, or the width of the q[]
3576                                // and data[] ports, if they are used. (Required)
3577    parameter lpm_direction = "UNUSED"; // Direction of the count.
3578    parameter lpm_modulus = 0;          // The maximum count, plus one.
3579    parameter lpm_avalue = "UNUSED";    // Constant value that is loaded when aset is high.
3580    parameter lpm_svalue = "UNUSED";    // Constant value that is loaded on the rising edge
3581                                        // of clock when sset is high.
3582    parameter lpm_pvalue = "UNUSED";
3583    parameter lpm_port_updown = "PORT_CONNECTIVITY";
3584    parameter lpm_type = "lpm_counter";
3585    parameter lpm_hint = "UNUSED";
3586
3587// INPUT PORT DECLARATION
3588    input  clock;
3589    input  clk_en;
3590    input  cnt_en;
3591    input  updown;
3592    input  aclr;
3593    input  aset;
3594    input  aload;
3595    input  sclr;
3596    input  sset;
3597    input  sload;
3598    input  [lpm_width-1:0] data;
3599    input  cin;
3600
3601// OUTPUT PORT DECLARATION
3602    output [lpm_width-1:0] q;
3603    output cout;
3604    output [15:0] eq;
3605
3606// INTERNAL REGISTER/SIGNAL DECLARATION
3607    reg  [lpm_width-1:0] tmp_count;
3608    reg  [lpm_width-1:0] adata;
3609
3610    reg  use_adata;
3611    reg  tmp_updown;
3612    reg  [lpm_width:0] tmp_modulus;
3613    reg  [lpm_width:0] max_modulus;
3614    reg  [lpm_width-1:0] svalue;
3615    reg  [lpm_width-1:0] avalue;
3616    reg  [lpm_width-1:0] pvalue;
3617
3618// INTERNAL WIRE DECLARATION
3619    wire w_updown;
3620    wire [lpm_width-1:0] final_count;
3621
3622// LOCAL INTEGER DECLARATION
3623    integer i;
3624
3625// INTERNAL TRI DECLARATION
3626
3627    tri1 clk_en;
3628    tri1 cnt_en;
3629    tri0 aclr;
3630    tri0 aset;
3631    tri0 aload;
3632    tri0 sclr;
3633    tri0 sset;
3634    tri0 sload;
3635    tri1 cin;
3636    tri1 updown_z;
3637
3638    wire i_clk_en;
3639    wire i_cnt_en;
3640    wire i_aclr;
3641    wire i_aset;
3642    wire i_aload;
3643    wire i_sclr;
3644    wire i_sset;
3645    wire i_sload;
3646    wire i_cin;
3647    wire i_updown;
3648    buf (i_clk_en, clk_en);
3649    buf (i_cnt_en, cnt_en);
3650    buf (i_aclr, aclr);
3651    buf (i_aset, aset);
3652    buf (i_aload, aload);
3653    buf (i_sclr, sclr);
3654    buf (i_sset, sset);
3655    buf (i_sload, sload);
3656    buf (i_cin, cin);
3657    buf (i_updown, updown_z);
3658
3659// TASK DECLARATION
3660    task string_to_reg;
3661    input  [8*40:1] string_value;
3662    output [lpm_width-1:0] value;
3663
3664    reg [8*40:1] reg_s;
3665    reg [8:1] digit;
3666    reg [8:1] tmp;
3667    reg [lpm_width-1:0] ivalue;
3668
3669    integer m;
3670
3671    begin
3672        ivalue = {lpm_width{1'b0}};
3673        reg_s = string_value;
3674        for (m=1; m<=40; m=m+1)
3675        begin
3676            tmp = reg_s[320:313];
3677            digit = tmp & 8'b00001111;
3678            reg_s = reg_s << 8;
3679            ivalue = ivalue * 10 + digit;
3680        end
3681        value = ivalue;
3682    end
3683    endtask
3684
3685// INITIAL CONSTRUCT BLOCK
3686    initial
3687    begin
3688        max_modulus = 1 << lpm_width;
3689
3690        // check if lpm_width < 0
3691        if (lpm_width <= 0)
3692        begin
3693            $display("Error!  LPM_WIDTH must be greater than 0.\n");
3694            $display("Time: %0t  Instance: %m", $time);
3695            $finish;
3696        end
3697
3698        // check if lpm_modulus < 0
3699        if (lpm_modulus < 0)
3700        begin
3701            $display("Error!  LPM_MODULUS must be greater or equal to 0.\n");
3702            $display("Time: %0t  Instance: %m", $time);
3703            $finish;
3704        end
3705        // check if lpm_modulus > 1<<lpm_width
3706        if (lpm_modulus > max_modulus)
3707        begin
3708            $display("Warning!  LPM_MODULUS should be within 1 to 2^LPM_WIDTH. Assuming no modulus input.\n");
3709            $display ("Time: %0t  Instance: %m", $time);
3710        end
3711        // check if lpm_direction valid
3712        if ((lpm_direction != "UNUSED") && (lpm_direction != "DEFAULT") &&
3713            (lpm_direction != "UP") && (lpm_direction != "DOWN"))
3714        begin
3715            $display("Error!  LPM_DIRECTION must be \"UP\" or \"DOWN\" if used.\n");
3716            $display("Time: %0t  Instance: %m", $time);
3717            $finish;
3718        end
3719
3720        if (lpm_avalue == "UNUSED")
3721            avalue =  {lpm_width{1'b1}};
3722        else
3723            string_to_reg(lpm_avalue, avalue);
3724
3725        if (lpm_svalue == "UNUSED")
3726            svalue =  {lpm_width{1'b1}};
3727        else
3728            string_to_reg(lpm_svalue, svalue);
3729
3730        if (lpm_pvalue == "UNUSED")
3731            pvalue =  {lpm_width{1'b0}};
3732        else
3733            string_to_reg(lpm_pvalue, pvalue);
3734
3735        tmp_modulus = ((lpm_modulus == 0) || (lpm_modulus > max_modulus))
3736                        ? max_modulus : lpm_modulus;
3737        tmp_count = pvalue;
3738        use_adata = 1'b0;
3739    end
3740
3741    // NCSIM will only assigns 1'bZ to unconnected port at time 0fs + 1
3742    // verilator lint_off STMTDLY
3743    initial #0
3744    // verilator lint_on STMTDLY
3745    begin
3746        // // check if lpm_direction valid
3747        if ((lpm_direction != "UNUSED") && (lpm_direction != "DEFAULT") && (updown !== 1'bz) &&
3748            (lpm_port_updown == "PORT_CONNECTIVITY"))
3749        begin
3750            $display("Error!  LPM_DIRECTION and UPDOWN cannot be used at the same time.\n");
3751            $display("Time: %0t  Instance: %m", $time);
3752            $finish;
3753        end
3754    end
3755
3756// ALWAYS CONSTRUCT BLOCK
3757    always @(posedge i_aclr or posedge i_aset or posedge i_aload or posedge clock)
3758    begin
3759        if (i_aclr || i_aset || i_aload)
3760            use_adata <= 1'b1;
3761        else if ($time > 0)
3762        begin
3763            if (i_clk_en)
3764            begin
3765                use_adata <= 1'b0;
3766
3767                if (i_sclr)
3768                    tmp_count <= 0;
3769                else if (i_sset)
3770                    tmp_count <= svalue;
3771                else if (i_sload)
3772                    tmp_count <= data;
3773                else if (i_cnt_en && i_cin)
3774                begin
3775                    if (w_updown)
3776                        tmp_count <= (final_count == tmp_modulus-1) ? 0
3777                                                    : final_count+1;
3778                    else
3779                        tmp_count <= (final_count == 0) ? tmp_modulus-1
3780                                                    : final_count-1;
3781                end
3782                else
3783                    tmp_count <= final_count;
3784            end
3785        end
3786    end
3787
3788    always @(i_aclr or i_aset or i_aload or data or avalue)
3789    begin
3790        if (i_aclr)
3791        begin
3792            adata <= 0;
3793        end
3794        else if (i_aset)
3795        begin
3796            adata <= avalue;
3797        end
3798        else if (i_aload)
3799            adata <= data;
3800    end
3801
3802// CONTINOUS ASSIGNMENT
3803    assign q = final_count;
3804    assign final_count = (use_adata == 1'b1) ? adata : tmp_count;
3805    assign cout = (i_cin && (((w_updown==0) && (final_count==0)) ||
3806                            ((w_updown==1) && ((final_count==tmp_modulus-1) ||
3807                                                (final_count=={lpm_width{1'b1}}))) ))
3808                    ? 1'b1 : 1'b0;
3809    assign updown_z = updown;
3810    assign w_updown =   (lpm_port_updown == "PORT_USED") ? i_updown :
3811                        (lpm_port_updown == "PORT_UNUSED") ? ((lpm_direction == "DOWN") ? 1'b0 : 1'b1) :
3812                        ((((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) && (i_updown == 1)) ||
3813                        (lpm_direction == "UP"))
3814                        ? 1'b1 : 1'b0;
3815    assign eq = {16{1'b0}};
3816
3817endmodule // lpm_counter
3818// END OF MODULE
3819
3820//START_MODULE_NAME------------------------------------------------------------
3821//
3822// Module Name     :  lpm_latch
3823//
3824// Description     :  Parameterized latch megafunction.
3825//
3826// Limitation      :  n/a
3827//
3828// Results expected:  Data output from the latch.
3829//
3830//END_MODULE_NAME--------------------------------------------------------------
3831
3832// BEGINNING OF MODULE
3833`timescale 1 ps / 1 ps
3834
3835// MODULE DECLARATION
3836module lpm_latch (
3837    data,  // Data input to the latch.
3838    gate,  // Latch enable input. High = flow-through, low = latch. (Required)
3839    aclr,  // Asynchronous clear input.
3840    aset,  // Asynchronous set input.
3841    aconst,
3842    q      // Data output from the latch.
3843);
3844
3845// GLOBAL PARAMETER DECLARATION
3846    parameter lpm_width = 1;         // Width of the data[] and q[] ports. (Required)
3847    parameter lpm_avalue = "UNUSED"; // Constant value that is loaded when aset is high.
3848    parameter lpm_pvalue = "UNUSED";
3849    parameter lpm_type = "lpm_latch";
3850    parameter lpm_hint = "UNUSED";
3851
3852// INPUT PORT DECLARATION
3853    input  [lpm_width-1:0] data;
3854    input  gate;
3855    input  aclr;
3856    input  aset;
3857    input  aconst;
3858
3859// OUTPUT PORT DECLARATION
3860    output [lpm_width-1:0] q;
3861
3862// INTERNAL REGISTER/SIGNAL DECLARATION
3863    reg [lpm_width-1:0] q;
3864    reg [lpm_width-1:0] avalue;
3865    reg [lpm_width-1:0] pvalue;
3866
3867
3868// INTERNAL TRI DECLARATION
3869    tri0 [lpm_width-1:0] data;
3870    tri0 aclr;
3871    tri0 aset;
3872    tri0 aconst;
3873
3874    wire i_aclr;
3875    wire i_aset;
3876    buf (i_aclr, aclr);
3877    buf (i_aset, aset);
3878
3879// TASK DECLARATION
3880    task string_to_reg;
3881    input  [8*40:1] string_value;
3882    output [lpm_width-1:0] value;
3883
3884    reg [8*40:1] reg_s;
3885    reg [8:1] digit;
3886    reg [8:1] tmp;
3887    reg [lpm_width-1:0] ivalue;
3888
3889    integer m;
3890
3891    begin
3892        ivalue = {lpm_width{1'b0}};
3893        reg_s = string_value;
3894        for (m=1; m<=40; m=m+1)
3895        begin
3896            tmp = reg_s[320:313];
3897            digit = tmp & 8'b00001111;
3898            reg_s = reg_s << 8;
3899            ivalue = ivalue * 10 + digit;
3900        end
3901        value = ivalue;
3902    end
3903    endtask
3904
3905// INITIAL CONSTRUCT BLOCK
3906    initial
3907    begin
3908        if (lpm_width <= 0)
3909        begin
3910            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
3911            $display("Time: %0t  Instance: %m", $time);
3912            $finish;
3913        end
3914
3915        if (lpm_pvalue != "UNUSED")
3916        begin
3917            string_to_reg(lpm_pvalue, pvalue);
3918            q = pvalue;
3919        end
3920
3921        if (lpm_avalue == "UNUSED")
3922            avalue =  {lpm_width{1'b1}};
3923        else
3924            string_to_reg(lpm_avalue, avalue);
3925    end
3926
3927// ALWAYS CONSTRUCT BLOCK
3928    always @(data or gate or i_aclr or i_aset or avalue)
3929    begin
3930        if (i_aclr)
3931            q <= {lpm_width{1'b0}};
3932        else if (i_aset)
3933            q <= avalue;
3934        else if (gate)
3935            q <= data;
3936    end
3937
3938endmodule // lpm_latch
3939
3940//START_MODULE_NAME------------------------------------------------------------
3941//
3942// Module Name     :  lpm_ff
3943//
3944// Description     :  Parameterized flipflop megafunction. The lpm_ff function
3945//                    contains features that are not available in the DFF, DFFE,
3946//                    DFFEA, TFF, and TFFE primitives, such as synchronous or
3947//                    asynchronous set, clear, and load inputs.
3948
3949//
3950// Limitation      :  n/a
3951//
3952// Results expected:  Data output from D or T flipflops.
3953//
3954//END_MODULE_NAME--------------------------------------------------------------
3955
3956// BEGINNING OF MODULE
3957`timescale 1 ps / 1 ps
3958
3959// MODULE DECLARATION
3960module lpm_ff (
3961    data,   // T-type flipflop: Toggle enable
3962            // D-type flipflop: Data input
3963
3964    clock,  // Positive-edge-triggered clock. (Required)
3965    enable, // Clock enable input.
3966    aclr,   // Asynchronous clear input.
3967    aset,   // Asynchronous set input.
3968
3969    aload,  // Asynchronous load input. Asynchronously loads the flipflop with
3970            // the value on the data input.
3971
3972    sclr,   // Synchronous clear input.
3973    sset,   // Synchronous set input.
3974
3975    sload,  // Synchronous load input. Loads the flipflop with the value on the
3976            // data input on the next active clock edge.
3977
3978    q       // Data output from D or T flipflops. (Required)
3979);
3980
3981// GLOBAL PARAMETER DECLARATION
3982    parameter lpm_width  = 1; // Width of the data[] and q[] ports. (Required)
3983    parameter lpm_avalue = "UNUSED";    // Constant value that is loaded when aset is high.
3984    parameter lpm_svalue = "UNUSED";    // Constant value that is loaded on the rising edge
3985                                        // of clock when sset is high.
3986    parameter lpm_pvalue = "UNUSED";
3987    parameter lpm_fftype = "DFF";       // Type of flipflop
3988    parameter lpm_type = "lpm_ff";
3989    parameter lpm_hint = "UNUSED";
3990
3991// INPUT PORT DECLARATION
3992    input  [lpm_width-1:0] data;
3993    input  clock;
3994    input  enable;
3995    input  aclr;
3996    input  aset;
3997    input  aload;
3998    input  sclr;
3999    input  sset;
4000    input  sload ;
4001
4002// OUTPUT PORT DECLARATION
4003    output [lpm_width-1:0] q;
4004
4005// INTERNAL REGISTER/SIGNAL DECLARATION
4006    reg  [lpm_width-1:0] tmp_q;
4007    reg  [lpm_width-1:0] adata;
4008    reg  use_adata;
4009    reg  [lpm_width-1:0] svalue;
4010    reg  [lpm_width-1:0] avalue;
4011    reg  [lpm_width-1:0] pvalue;
4012
4013// INTERNAL WIRE DECLARATION
4014    wire [lpm_width-1:0] final_q;
4015
4016// LOCAL INTEGER DECLARATION
4017    integer i;
4018
4019// INTERNAL TRI DECLARATION
4020    tri1  [lpm_width-1:0] data;
4021    tri1 enable;
4022    tri0 sload;
4023    tri0 sclr;
4024    tri0 sset;
4025    tri0 aload;
4026    tri0 aclr;
4027    tri0 aset;
4028
4029    wire i_enable;
4030    wire i_sload;
4031    wire i_sclr;
4032    wire i_sset;
4033    wire i_aload;
4034    wire i_aclr;
4035    wire i_aset;
4036    buf (i_enable, enable);
4037    buf (i_sload, sload);
4038    buf (i_sclr, sclr);
4039    buf (i_sset, sset);
4040    buf (i_aload, aload);
4041    buf (i_aclr, aclr);
4042    buf (i_aset, aset);
4043
4044// TASK DECLARATION
4045    task string_to_reg;
4046    input  [8*40:1] string_value;
4047    output [lpm_width-1:0] value;
4048
4049    reg [8*40:1] reg_s;
4050    reg [8:1] digit;
4051    reg [8:1] tmp;
4052    reg [lpm_width-1:0] ivalue;
4053
4054    integer m;
4055
4056    begin
4057        ivalue = {lpm_width{1'b0}};
4058        reg_s = string_value;
4059        for (m=1; m<=40; m=m+1)
4060        begin
4061            tmp = reg_s[320:313];
4062            digit = tmp & 8'b00001111;
4063            reg_s = reg_s << 8;
4064            ivalue = ivalue * 10 + digit;
4065        end
4066        value = ivalue;
4067    end
4068    endtask
4069
4070// INITIAL CONSTRUCT BLOCK
4071    initial
4072    begin
4073        if (lpm_width <= 0)
4074        begin
4075            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
4076            $display("Time: %0t  Instance: %m", $time);
4077            $finish;
4078        end
4079
4080        if ((lpm_fftype != "DFF") &&
4081            (lpm_fftype != "TFF") &&
4082            (lpm_fftype != "UNUSED"))          // non-LPM 220 standard
4083        begin
4084            $display("Error!  LPM_FFTYPE value must be \"DFF\" or \"TFF\".");
4085            $display("Time: %0t  Instance: %m", $time);
4086            $finish;
4087        end
4088
4089        if (lpm_avalue == "UNUSED")
4090            avalue =  {lpm_width{1'b1}};
4091        else
4092            string_to_reg(lpm_avalue, avalue);
4093
4094        if (lpm_svalue == "UNUSED")
4095            svalue =  {lpm_width{1'b1}};
4096        else
4097            string_to_reg(lpm_svalue, svalue);
4098
4099        if (lpm_pvalue == "UNUSED")
4100            pvalue =  {lpm_width{1'b0}};
4101        else
4102            string_to_reg(lpm_pvalue, pvalue);
4103
4104        tmp_q = pvalue;
4105        use_adata = 1'b0;
4106    end
4107
4108// ALWAYS CONSTRUCT BLOCK
4109    always @(posedge i_aclr or posedge i_aset or posedge i_aload or posedge clock)
4110    begin // Asynchronous process
4111        if (i_aclr || i_aset || i_aload)
4112            use_adata <= 1'b1;
4113        else if ($time > 0)
4114        begin // Synchronous process
4115            if (i_enable)
4116            begin
4117                use_adata <= 1'b0;
4118
4119                if (i_sclr)
4120                    tmp_q <= 0;
4121                else if (i_sset)
4122                    tmp_q <= svalue;
4123                else if (i_sload)  // Load data
4124                    tmp_q <= data;
4125                else
4126                begin
4127                    if (lpm_fftype == "TFF") // toggle
4128                    begin
4129                        for (i = 0; i < lpm_width; i=i+1)
4130                            if (data[i] == 1'b1)
4131                                tmp_q[i] <= ~final_q[i];
4132                            else
4133                                tmp_q[i] <= final_q[i];
4134                    end
4135                    else    // DFF, load data
4136                        tmp_q <= data;
4137                end
4138            end
4139        end
4140    end
4141
4142    always @(i_aclr or i_aset or i_aload or data or avalue or pvalue)
4143    begin
4144        if (i_aclr === 1'b1)
4145            adata <= {lpm_width{1'b0}};
4146        else if (i_aclr === 1'bx)
4147            adata <= {lpm_width{1'bx}};
4148        else if (i_aset)
4149            adata <= avalue;
4150        else if (i_aload)
4151            adata <= data;
4152        else if ((i_aclr === 1'b0) && ($time == 0))
4153            adata <= pvalue;
4154    end
4155
4156// CONTINOUS ASSIGNMENT
4157    assign q = final_q;
4158    assign final_q = (use_adata == 1'b1) ? adata : tmp_q;
4159
4160endmodule // lpm_ff
4161// END OF MODULE
4162
4163//START_MODULE_NAME------------------------------------------------------------
4164//
4165// Module Name     :  lpm_shiftreg
4166//
4167// Description     :  Parameterized shift register megafunction.
4168//
4169// Limitation      :  n/a
4170//
4171// Results expected:  Data output from the shift register and the Serial shift data output.
4172//
4173//END_MODULE_NAME--------------------------------------------------------------
4174
4175// BEGINNING OF MODULE
4176`timescale 1 ps / 1 ps
4177
4178// MODULE DECLARATION
4179module lpm_shiftreg (
4180    data,       // Data input to the shift register.
4181    clock,      // Positive-edge-triggered clock. (Required)
4182    enable,     // Clock enable input
4183    shiftin,    // Serial shift data input.
4184    load,       // Synchronous parallel load. High (1): load operation;
4185                //                            low (0): shift operation.
4186    aclr,       // Asynchronous clear input.
4187    aset,       // Asynchronous set input.
4188    sclr,       // Synchronous clear input.
4189    sset,       // Synchronous set input.
4190    q,          // Data output from the shift register.
4191    shiftout    // Serial shift data output.
4192);
4193
4194// GLOBAL PARAMETER DECLARATION
4195    parameter lpm_width  = 1;  // Width of the data[] and q ports. (Required)
4196    parameter lpm_direction = "LEFT";   // Values are "LEFT", "RIGHT", and "UNUSED".
4197    parameter lpm_avalue = "UNUSED";    // Constant value that is loaded when aset is high.
4198    parameter lpm_svalue = "UNUSED";    // Constant value that is loaded on the rising edge
4199                                        // of clock when sset is high.
4200    parameter lpm_pvalue = "UNUSED";
4201    parameter lpm_type = "lpm_shiftreg";
4202    parameter lpm_hint  = "UNUSED";
4203
4204// INPUT PORT DECLARATION
4205    input  [lpm_width-1:0] data;
4206    input  clock;
4207    input  enable;
4208    input  shiftin;
4209    input  load;
4210    input  aclr;
4211    input  aset;
4212    input  sclr;
4213    input  sset;
4214
4215
4216// OUTPUT PORT DECLARATION
4217    output [lpm_width-1:0] q;
4218    output shiftout;
4219
4220// INTERNAL REGISTER/SIGNAL DECLARATION
4221    reg  [lpm_width-1:0] tmp_q;
4222    reg  abit;
4223    reg  [lpm_width-1:0] svalue;
4224    reg  [lpm_width-1:0] avalue;
4225    reg  [lpm_width-1:0] pvalue;
4226
4227// LOCAL INTEGER DECLARATION
4228    integer i;
4229
4230// INTERNAL WIRE DECLARATION
4231    wire tmp_shiftout;
4232
4233// INTERNAL TRI DECLARATION
4234    tri1 enable;
4235    tri1 shiftin;
4236    tri0 load;
4237    tri0 aclr;
4238    tri0 aset;
4239    tri0 sclr;
4240    tri0 sset;
4241
4242    wire i_enable;
4243    wire i_shiftin;
4244    wire i_load;
4245    wire i_aclr;
4246    wire i_aset;
4247    wire i_sclr;
4248    wire i_sset;
4249    buf (i_enable, enable);
4250    buf (i_shiftin, shiftin);
4251    buf (i_load, load);
4252    buf (i_aclr, aclr);
4253    buf (i_aset, aset);
4254    buf (i_sclr, sclr);
4255    buf (i_sset, sset);
4256
4257// TASK DECLARATION
4258    task string_to_reg;
4259    input  [8*40:1] string_value;
4260    output [lpm_width-1:0] value;
4261
4262    reg [8*40:1] reg_s;
4263    reg [8:1] digit;
4264    reg [8:1] tmp;
4265    reg [lpm_width-1:0] ivalue;
4266
4267    integer m;
4268
4269    begin
4270        ivalue = {lpm_width{1'b0}};
4271        reg_s = string_value;
4272        for (m=1; m<=40; m=m+1)
4273        begin
4274            tmp = reg_s[320:313];
4275            digit = tmp & 8'b00001111;
4276            reg_s = reg_s << 8;
4277            ivalue = ivalue * 10 + digit;
4278        end
4279        value = ivalue;
4280    end
4281    endtask
4282
4283// INITIAL CONSTRUCT BLOCK
4284    initial
4285    begin
4286        if (lpm_width <= 0)
4287        begin
4288            $display("Value of lpm_width parameter must be greater than 0 (ERROR)");
4289            $display("Time: %0t  Instance: %m", $time);
4290            $finish;
4291        end
4292
4293        if ((lpm_direction != "LEFT") &&
4294            (lpm_direction != "RIGHT") &&
4295            (lpm_direction != "UNUSED"))          // non-LPM 220 standard
4296        begin
4297            $display("Error!  LPM_DIRECTION value must be \"LEFT\" or \"RIGHT\".");
4298            $display("Time: %0t  Instance: %m", $time);
4299            $finish;
4300        end
4301
4302        if (lpm_avalue == "UNUSED")
4303            avalue =  {lpm_width{1'b1}};
4304        else
4305            string_to_reg(lpm_avalue, avalue);
4306
4307        if (lpm_svalue == "UNUSED")
4308            svalue =  {lpm_width{1'b1}};
4309        else
4310            string_to_reg(lpm_svalue, svalue);
4311
4312        if (lpm_pvalue == "UNUSED")
4313            pvalue =  {lpm_width{1'b0}};
4314        else
4315            string_to_reg(lpm_pvalue, pvalue);
4316
4317        tmp_q = pvalue;
4318    end
4319
4320// ALWAYS CONSTRUCT BLOCK
4321    always @(i_aclr or i_aset or avalue)
4322    begin
4323        if (i_aclr)
4324            tmp_q <= {lpm_width{1'b0}};
4325        else if (i_aset)
4326            tmp_q <= avalue;
4327    end
4328
4329    always @(posedge clock)
4330    begin
4331        if (i_aclr)
4332            tmp_q <= (i_aset) ? {lpm_width{1'bx}} : {lpm_width{1'b0}};
4333        else if (i_aset)
4334            tmp_q <= avalue;
4335        else
4336        begin
4337            if (i_enable)
4338            begin
4339                if (i_sclr)
4340                    tmp_q <= {lpm_width{1'b0}};
4341                else if (i_sset)
4342                    tmp_q <= svalue;
4343                else if (i_load)
4344                    tmp_q <= data;
4345                else if (!i_load)
4346                begin
4347                    if ((lpm_direction == "LEFT") || (lpm_direction == "UNUSED"))
4348                        {abit,tmp_q} <= {tmp_q,i_shiftin};
4349                    else if (lpm_direction == "RIGHT")
4350                        {tmp_q,abit} <= {i_shiftin,tmp_q};
4351                end
4352            end
4353        end
4354    end
4355
4356// CONTINOUS ASSIGNMENT
4357    assign tmp_shiftout = (lpm_direction == "RIGHT") ? tmp_q[0]
4358                                                    : tmp_q[lpm_width-1];
4359    assign q = tmp_q;
4360    assign shiftout = tmp_shiftout;
4361
4362endmodule // lpm_shiftreg
4363// END OF MODULE
4364
4365//START_MODULE_NAME------------------------------------------------------------
4366//
4367// Module Name     :  lpm_ram_dq
4368//
4369// Description     :  Parameterized RAM with separate input and output ports megafunction.
4370//                    lpm_ram_dq implement asynchronous memory or memory with synchronous
4371//                    inputs and/or outputs.
4372//
4373// Limitation      :  n/a
4374//
4375// Results expected:  Data output from the memory.
4376//
4377//END_MODULE_NAME--------------------------------------------------------------
4378
4379// BEGINNING OF MODULE
4380`timescale 1 ps / 1 ps
4381
4382// MODULE DECLARATION
4383module lpm_ram_dq (
4384    data,      // Data input to the memory. (Required)
4385    address,   // Address input to the memory. (Required)
4386    inclock,   // Synchronizes memory loading.
4387    outclock,  // Synchronizes q outputs from memory.
4388    we,        // Write enable input. Enables write operations to the memory when high. (Required)
4389    q          // Data output from the memory. (Required)
4390);
4391
4392// GLOBAL PARAMETER DECLARATION
4393    parameter lpm_width = 1;  // Width of data[] and q[] ports. (Required)
4394    parameter lpm_widthad = 1; // Width of the address port. (Required)
4395    parameter lpm_numwords = 1 << lpm_widthad; // Number of words stored in memory.
4396    parameter lpm_indata = "REGISTERED";  // Controls whether the data port is registered.
4397    parameter lpm_address_control = "REGISTERED"; // Controls whether the address and we ports are registered.
4398    parameter lpm_outdata = "REGISTERED"; // Controls whether the q ports are registered.
4399    parameter lpm_file = "UNUSED"; // Name of the file containing RAM initialization data.
4400    parameter use_eab = "ON"; // Specified whether to use the EAB or not.
4401    parameter intended_device_family = "Stratix";
4402    parameter lpm_type = "lpm_ram_dq";
4403    parameter lpm_hint = "UNUSED";
4404
4405// INPUT PORT DECLARATION
4406    input  [lpm_width-1:0] data;
4407    input  [lpm_widthad-1:0] address;
4408    input  inclock;
4409    input  outclock;
4410    input  we;
4411
4412// OUTPUT PORT DECLARATION
4413    output [lpm_width-1:0] q;
4414
4415
4416// INTERNAL REGISTER/SIGNAL DECLARATION
4417    reg  [lpm_width-1:0] mem_data [lpm_numwords-1:0];
4418    reg  [lpm_width-1:0] tmp_q;
4419    reg  [lpm_width-1:0] pdata;
4420    reg  [lpm_width-1:0] in_data;
4421    reg  [lpm_widthad-1:0] paddress;
4422    reg  pwe;
4423    reg  [lpm_width-1:0]  ZEROS, ONES, UNKNOWN;
4424`ifdef VERILATOR
4425    reg  [`LPM_MAX_NAME_SZ*8:1] ram_initf;
4426`else
4427    reg  [8*256:1] ram_initf;
4428`endif
4429
4430// LOCAL INTEGER DECLARATION
4431    integer i;
4432
4433// INTERNAL TRI DECLARATION
4434    tri0 inclock;
4435    tri0 outclock;
4436
4437    wire i_inclock;
4438    wire i_outclock;
4439    buf (i_inclock, inclock);
4440    buf (i_outclock, outclock);
4441
4442// COMPONENT INSTANTIATIONS
4443    LPM_DEVICE_FAMILIES dev ();
4444    LPM_MEMORY_INITIALIZATION mem ();
4445
4446// FUNCTON DECLARATION
4447    // Check the validity of the address.
4448    function ValidAddress;
4449        input [lpm_widthad-1:0] paddress;
4450
4451        begin
4452            ValidAddress = 1'b0;
4453            if (^paddress === {lpm_widthad{1'bx}})
4454            begin
4455                $display("%t:Error!  Invalid address.\n", $time);
4456                $display("Time: %0t  Instance: %m", $time);
4457            end
4458            else if (paddress >= lpm_numwords)
4459            begin
4460                $display("%t:Error!  Address out of bound on RAM.\n", $time);
4461                $display("Time: %0t  Instance: %m", $time);
4462            end
4463            else
4464                ValidAddress = 1'b1;
4465        end
4466    endfunction
4467
4468// INITIAL CONSTRUCT BLOCK
4469    initial
4470    begin
4471
4472        // Initialize the internal data register.
4473        pdata = {lpm_width{1'b0}};
4474        paddress = {lpm_widthad{1'b0}};
4475        pwe = 1'b0;
4476
4477        if (lpm_width <= 0)
4478        begin
4479            $display("Error!  LPM_WIDTH parameter must be greater than 0.");
4480            $display("Time: %0t  Instance: %m", $time);
4481            $finish;
4482        end
4483
4484        if (lpm_widthad <= 0)
4485        begin
4486            $display("Error!  LPM_WIDTHAD parameter must be greater than 0.");
4487            $display("Time: %0t  Instance: %m", $time);
4488            $finish;
4489        end
4490
4491        // check for number of words out of bound
4492        if ((lpm_numwords > (1 << lpm_widthad)) ||
4493            (lpm_numwords <= (1 << (lpm_widthad-1))))
4494        begin
4495            $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD.");
4496            $display("Time: %0t  Instance: %m", $time);
4497            $finish;
4498        end
4499
4500        if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED"))
4501        begin
4502            $display("Error!  LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\".");
4503            $display("Time: %0t  Instance: %m", $time);
4504            $finish;
4505        end
4506
4507        if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED"))
4508        begin
4509            $display("Error!  LPM_INDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
4510            $display("Time: %0t  Instance: %m", $time);
4511            $finish;
4512        end
4513
4514        if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
4515        begin
4516            $display("Error!  LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
4517            $display("Time: %0t  Instance: %m", $time);
4518            $finish;
4519        end
4520
4521        if (dev.IS_VALID_FAMILY(intended_device_family) == 0)
4522        begin
4523            $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family);
4524            $display("Time: %0t  Instance: %m", $time);
4525            $finish;
4526        end
4527
4528        for (i=0; i < lpm_width; i=i+1)
4529        begin
4530            ZEROS[i] = 1'b0;
4531            ONES[i] = 1'b1;
4532            UNKNOWN[i] = 1'bX;
4533        end
4534
4535        for (i = 0; i < lpm_numwords; i=i+1)
4536            mem_data[i] = {lpm_width{1'b0}};
4537
4538        // load data to the RAM
4539        if (lpm_file != "UNUSED")
4540        begin
4541            mem.convert_to_ver_file(lpm_file, lpm_width, ram_initf);
4542            $readmemh(ram_initf, mem_data);
4543        end
4544
4545        tmp_q = ZEROS;
4546    end
4547
4548// ALWAYS CONSTRUCT BLOCK
4549    always @(posedge i_inclock)
4550    begin
4551        if (lpm_address_control == "REGISTERED")
4552        begin
4553            if ((we) && (use_eab != "ON") &&
4554                (lpm_hint != "USE_EAB=ON"))
4555            begin
4556                if (lpm_indata == "REGISTERED")
4557                    mem_data[address] <= data;
4558                else
4559                    mem_data[address] <= pdata;
4560            end
4561            paddress <= address;
4562            pwe <= we;
4563        end
4564        if (lpm_indata == "REGISTERED")
4565            pdata <= data;
4566    end
4567
4568    always @(data)
4569    begin
4570        if (lpm_indata == "UNREGISTERED")
4571            pdata <= data;
4572    end
4573
4574    always @(address)
4575    begin
4576        if (lpm_address_control == "UNREGISTERED")
4577            paddress <= address;
4578    end
4579
4580    always @(we)
4581    begin
4582        if (lpm_address_control == "UNREGISTERED")
4583            pwe <= we;
4584    end
4585
4586    always @(pdata or paddress or pwe)
4587    begin :UNREGISTERED_INCLOCK
4588        if (ValidAddress(paddress))
4589        begin
4590            if ((lpm_address_control == "UNREGISTERED") && (pwe))
4591                mem_data[paddress] <= pdata;
4592            end
4593        else
4594        begin
4595            if (lpm_outdata == "UNREGISTERED")
4596                tmp_q <= {lpm_width{1'bx}};
4597        end
4598    end
4599
4600    always @(posedge i_outclock)
4601    begin
4602        if (lpm_outdata == "REGISTERED")
4603        begin
4604            if (ValidAddress(paddress))
4605                tmp_q <= mem_data[paddress];
4606            else
4607                tmp_q <= {lpm_width{1'bx}};
4608        end
4609    end
4610
4611    always @(i_inclock or pwe or paddress or pdata)
4612    begin
4613        if ((lpm_address_control == "REGISTERED") && (pwe))
4614            if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON"))
4615            begin
4616                if (i_inclock == 1'b0)
4617                    mem_data[paddress] = pdata;
4618            end
4619    end
4620
4621// CONTINOUS ASSIGNMENT
4622    assign q = (lpm_outdata == "UNREGISTERED") ? mem_data[paddress] : tmp_q;
4623
4624endmodule // lpm_ram_dq
4625// END OF MODULE
4626
4627//START_MODULE_NAME------------------------------------------------------------
4628//
4629// Module Name     :  lpm_ram_dp
4630//
4631// Description     :  Parameterized dual-port RAM megafunction.
4632//
4633// Limitation      :  n/a
4634//
4635// Results expected:  Data output from the memory.
4636//
4637//END_MODULE_NAME--------------------------------------------------------------
4638
4639// BEGINNING OF MODULE
4640`timescale 1 ps / 1 ps
4641
4642// MODULE DECLARATION
4643module lpm_ram_dp (
4644    data,      // Data input to the memory. (Required)
4645    rdaddress, // Read address input to the memory. (Required)
4646    wraddress, // Write address input to the memory. (Required)
4647    rdclock,   // Positive-edge-triggered clock for read operation.
4648    rdclken,   // Clock enable for rdclock.
4649    wrclock,   // Positive-edge-triggered clock for write operation.
4650    wrclken,   // Clock enable for wrclock.
4651    rden,      // Read enable input. Disables reading when low (0).
4652    wren,      // Write enable input. (Required)
4653    q          // Data output from the memory. (Required)
4654);
4655
4656// GLOBAL PARAMETER DECLARATION
4657    parameter lpm_width = 1;   // Width of the data[] and q[] ports. (Required)
4658    parameter lpm_widthad = 1; // Width of the rdaddress[] and wraddress[] ports. (Required)
4659    parameter lpm_numwords = 1 << lpm_widthad; // Number of words stored in memory.
4660    parameter lpm_indata = "REGISTERED"; // Determines the clock used by the data port.
4661    parameter lpm_rdaddress_control  = "REGISTERED"; // Determines the clock used by the rdaddress and rden ports.
4662    parameter lpm_wraddress_control  = "REGISTERED"; // Determines the clock used by the wraddress and wren ports.
4663    parameter lpm_outdata = "REGISTERED"; // Determines the clock used by the q[] pxort.
4664    parameter lpm_file = "UNUSED"; // Name of the file containing RAM initialization data.
4665    parameter use_eab = "ON"; // Specified whether to use the EAB or not.
4666    parameter rden_used = "TRUE"; // Specified whether to use the rden port or not.
4667    parameter intended_device_family = "Stratix";
4668    parameter lpm_type = "lpm_ram_dp";
4669    parameter lpm_hint = "UNUSED";
4670
4671// INPUT PORT DECLARATION
4672    input  [lpm_width-1:0] data;
4673    input  [lpm_widthad-1:0] rdaddress;
4674    input  [lpm_widthad-1:0] wraddress;
4675    input  rdclock;
4676    input  rdclken;
4677    input  wrclock;
4678    input  wrclken;
4679    input  rden;
4680    input  wren;
4681
4682// OUTPUT PORT DECLARATION
4683    output [lpm_width-1:0] q;
4684
4685// INTERNAL REGISTER/SIGNAL DECLARATION
4686    reg [lpm_width-1:0] mem_data [(1<<lpm_widthad)-1:0];
4687    reg [lpm_width-1:0] i_data_reg, i_data_tmp, i_q_reg, i_q_tmp;
4688    reg [lpm_widthad-1:0] i_wraddress_reg, i_wraddress_tmp;
4689    reg [lpm_widthad-1:0] i_rdaddress_reg, i_rdaddress_tmp;
4690    reg i_wren_reg, i_wren_tmp, i_rden_reg, i_rden_tmp;
4691`ifdef VERILATOR
4692    reg  [`LPM_MAX_NAME_SZ*8:1] ram_initf;
4693`else
4694    reg  [8*256:1] ram_initf;
4695`endif
4696
4697// LOCAL INTEGER DECLARATION
4698    integer i, i_numwords;
4699
4700// INTERNAL TRI DECLARATION
4701    tri0 wrclock;
4702    tri1 wrclken;
4703    tri0 rdclock;
4704    tri1 rdclken;
4705    tri0 wren;
4706    tri1 rden;
4707
4708    wire i_inclock;
4709    wire i_inclocken;
4710    wire i_outclock;
4711    wire i_outclocken;
4712    wire i_wren;
4713    wire i_rden;
4714
4715    buf (i_inclock, wrclock);
4716    buf (i_inclocken, wrclken);
4717    buf (i_outclock, rdclock);
4718    buf (i_outclocken, rdclken);
4719    buf (i_wren, wren);
4720    buf (i_rden, rden);
4721
4722// COMPONENT INSTANTIATIONS
4723    LPM_DEVICE_FAMILIES dev ();
4724    LPM_MEMORY_INITIALIZATION mem ();
4725
4726// FUNCTON DECLARATION
4727    function ValidAddress;
4728        input [lpm_widthad-1:0] paddress;
4729
4730        begin
4731            ValidAddress = 1'b0;
4732            if (^paddress === {lpm_widthad{1'bx}})
4733            begin
4734                $display("%t:Error!  Invalid address.\n", $time);
4735                $display("Time: %0t  Instance: %m", $time);
4736            end
4737            else if (paddress >= lpm_numwords)
4738            begin
4739                $display("%t:Error!  Address out of bound on RAM.\n", $time);
4740                $display("Time: %0t  Instance: %m", $time);
4741            end
4742            else
4743                ValidAddress = 1'b1;
4744        end
4745    endfunction
4746
4747// INITIAL CONSTRUCT BLOCK
4748    initial
4749    begin
4750        // Check for invalid parameters
4751        if (lpm_width < 1)
4752        begin
4753            $display("Error! lpm_width parameter must be greater than 0.");
4754            $display("Time: %0t  Instance: %m", $time);
4755            $finish;
4756        end
4757        if (lpm_widthad < 1)
4758        begin
4759            $display("Error! lpm_widthad parameter must be greater than 0.");
4760            $display("Time: %0t  Instance: %m", $time);
4761            $finish;
4762        end
4763        if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED"))
4764        begin
4765            $display("Error! lpm_indata must be \"REGISTERED\" or \"UNREGISTERED\".");
4766            $display("Time: %0t  Instance: %m", $time);
4767            $finish;
4768        end
4769        if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
4770        begin
4771            $display("Error! lpm_outdata must be \"REGISTERED\" or \"UNREGISTERED\".");
4772            $display("Time: %0t  Instance: %m", $time);
4773            $finish;
4774        end
4775        if ((lpm_wraddress_control != "REGISTERED") && (lpm_wraddress_control != "UNREGISTERED"))
4776        begin
4777            $display("Error! lpm_wraddress_control must be \"REGISTERED\" or \"UNREGISTERED\".");
4778            $display("Time: %0t  Instance: %m", $time);
4779        end
4780        if ((lpm_rdaddress_control != "REGISTERED") && (lpm_rdaddress_control != "UNREGISTERED"))
4781        begin
4782            $display("Error! lpm_rdaddress_control must be \"REGISTERED\" or \"UNREGISTERED\".");
4783            $display("Time: %0t  Instance: %m", $time);
4784            $finish;
4785        end
4786
4787        if (dev.IS_VALID_FAMILY(intended_device_family) == 0)
4788        begin
4789            $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family);
4790            $display("Time: %0t  Instance: %m", $time);
4791            $finish;
4792        end
4793
4794        // Initialize mem_data
4795        i_numwords = (lpm_numwords) ? lpm_numwords : (1<<lpm_widthad);
4796
4797        if (lpm_file == "UNUSED")
4798            for (i=0; i<i_numwords; i=i+1)
4799                mem_data[i] = {lpm_width{1'b0}};
4800        else
4801        begin
4802            mem.convert_to_ver_file(lpm_file, lpm_width, ram_initf);
4803            $readmemh(ram_initf, mem_data);
4804        end
4805
4806        // Initialize registers
4807        i_data_reg = {lpm_width{1'b0}};
4808        i_wraddress_reg = {lpm_widthad{1'b0}};
4809        i_rdaddress_reg = {lpm_widthad{1'b0}};
4810        i_wren_reg = 1'b0;
4811        if (rden_used == "TRUE")
4812            i_rden_reg = 1'b0;
4813        else
4814            i_rden_reg = 1'b1;
4815
4816        // Initialize output
4817        i_q_reg = {lpm_width{1'b0}};
4818        if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON"))
4819        begin
4820            i_q_tmp = {lpm_width{1'b1}};
4821        end
4822        else
4823            i_q_tmp = {lpm_width{1'b0}};
4824    end
4825
4826
4827// ALWAYS CONSTRUCT BLOCK
4828
4829    always @(posedge i_inclock)
4830    begin
4831        if (lpm_indata == "REGISTERED")
4832            if ((i_inclocken == 1'b1) && ($time > 0))
4833                i_data_reg <= data;
4834
4835        if (lpm_wraddress_control == "REGISTERED")
4836            if ((i_inclocken == 1'b1) && ($time > 0))
4837            begin
4838                i_wraddress_reg <= wraddress;
4839                i_wren_reg <= i_wren;
4840            end
4841
4842    end
4843
4844    always @(posedge i_outclock)
4845    begin
4846        if (lpm_outdata == "REGISTERED")
4847            if ((i_outclocken == 1'b1) && ($time > 0))
4848            begin
4849                i_q_reg <= i_q_tmp;
4850            end
4851
4852        if (lpm_rdaddress_control == "REGISTERED")
4853            if ((i_outclocken == 1'b1) && ($time > 0))
4854            begin
4855                i_rdaddress_reg <= rdaddress;
4856                i_rden_reg <= i_rden;
4857            end
4858    end
4859
4860
4861    //=========
4862    // Memory
4863    //=========
4864
4865    always @(i_data_tmp or i_wren_tmp or i_wraddress_tmp or negedge i_inclock)
4866    begin
4867        if (i_wren_tmp == 1'b1)
4868            if (ValidAddress(i_wraddress_tmp))
4869            begin
4870                if (((use_eab == "ON") || (lpm_hint == "USE_EAB=ON")) &&
4871                    (lpm_wraddress_control == "REGISTERED"))
4872                begin
4873                    if (i_inclock == 1'b0)
4874                        mem_data[i_wraddress_tmp] <= i_data_tmp;
4875                end
4876                else
4877                    mem_data[i_wraddress_tmp] <= i_data_tmp;
4878            end
4879    end
4880
4881    always @(i_rden_tmp or i_rdaddress_tmp or mem_data[i_rdaddress_tmp])
4882    begin
4883        if (i_rden_tmp == 1'b1)
4884            i_q_tmp = (ValidAddress(i_rdaddress_tmp))
4885                        ? mem_data[i_rdaddress_tmp]
4886                        : {lpm_width{1'bx}};
4887    end
4888
4889
4890    //=======
4891    // Sync
4892    //=======
4893
4894    always @(wraddress or i_wraddress_reg)
4895            i_wraddress_tmp = (lpm_wraddress_control == "REGISTERED")
4896                        ? i_wraddress_reg
4897                        : wraddress;
4898    always @(rdaddress or i_rdaddress_reg)
4899        i_rdaddress_tmp = (lpm_rdaddress_control == "REGISTERED")
4900                        ? i_rdaddress_reg
4901                        : rdaddress;
4902    always @(i_wren or i_wren_reg)
4903        i_wren_tmp = (lpm_wraddress_control == "REGISTERED")
4904                        ? i_wren_reg
4905                        : i_wren;
4906    always @(i_rden or i_rden_reg)
4907        i_rden_tmp = (lpm_rdaddress_control == "REGISTERED")
4908                        ? i_rden_reg
4909                        : i_rden;
4910    always @(data or i_data_reg)
4911        i_data_tmp = (lpm_indata == "REGISTERED")
4912                        ? i_data_reg
4913                        : data;
4914
4915// CONTINOUS ASSIGNMENT
4916    assign q = (lpm_outdata == "REGISTERED") ? i_q_reg : i_q_tmp;
4917
4918endmodule // lpm_ram_dp
4919// END OF MODULE
4920
4921//START_MODULE_NAME------------------------------------------------------------
4922//
4923// Module Name     : lpm_ram_io
4924//
4925// Description     : Parameterized RAM with a single I/O port megafunction
4926//
4927// Limitation      : This megafunction is provided only for backward
4928//                   compatibility in Cyclone, Stratix, and Stratix GX designs;
4929//                   instead, Altera recommends using the altsyncram
4930//                   megafunction
4931//
4932// Results expected: Output of RAM content at bi-directional DIO.
4933//
4934//END_MODULE_NAME--------------------------------------------------------------
4935`timescale 1 ps / 1 ps
4936
4937// MODULE DECLARATION
4938module lpm_ram_io ( dio, inclock, outclock, we, memenab, outenab, address );
4939
4940// PARAMETER DECLARATION
4941    parameter lpm_type = "lpm_ram_io";
4942    parameter lpm_width = 1;
4943    parameter lpm_widthad = 1;
4944    parameter lpm_numwords = 1<< lpm_widthad;
4945    parameter lpm_indata = "REGISTERED";
4946    parameter lpm_address_control = "REGISTERED";
4947    parameter lpm_outdata = "REGISTERED";
4948    parameter lpm_file = "UNUSED";
4949    parameter lpm_hint = "UNUSED";
4950    parameter use_eab = "ON";
4951    parameter intended_device_family = "UNUSED";
4952
4953// INPUT PORT DECLARATION
4954    input  [lpm_widthad-1:0] address;
4955    input  inclock, outclock, we;
4956    input  memenab;
4957    input  outenab;
4958
4959// INPUT/OUTPUT PORT DECLARATION
4960    inout  [lpm_width-1:0] dio;
4961
4962// INTERNAL REGISTERS DECLARATION
4963    reg  [lpm_width-1:0] mem_data [lpm_numwords-1:0];
4964    reg  [lpm_width-1:0] tmp_io;
4965    reg  [lpm_width-1:0] tmp_q;
4966    reg  [lpm_width-1:0] pdio;
4967    reg  [lpm_widthad-1:0] paddress;
4968    reg  [lpm_widthad-1:0] paddress_tmp;
4969    reg  pwe;
4970`ifdef VERILATOR
4971    reg  [`LPM_MAX_NAME_SZ*8:1] ram_initf;
4972`else
4973    reg  [8*256:1] ram_initf;
4974`endif
4975
4976// INTERNAL WIRE DECLARATION
4977    wire [lpm_width-1:0] read_data;
4978    wire i_inclock;
4979    wire i_outclock;
4980    wire i_memenab;
4981    wire i_outenab;
4982
4983// LOCAL INTEGER DECLARATION
4984    integer i;
4985
4986// INTERNAL TRI DECLARATION
4987    tri0 inclock;
4988    tri0 outclock;
4989    tri1 memenab;
4990    tri1 outenab;
4991
4992// INTERNAL BUF DECLARATION
4993    buf (i_inclock, inclock);
4994    buf (i_outclock, outclock);
4995    buf (i_memenab, memenab);
4996    buf (i_outenab, outenab);
4997
4998
4999// FUNCTON DECLARATION
5000    function ValidAddress;
5001        input [lpm_widthad-1:0] paddress;
5002
5003        begin
5004            ValidAddress = 1'b0;
5005            if (^paddress === {lpm_widthad{1'bx}})
5006            begin
5007                $display("%t:Error:  Invalid address.", $time);
5008                $display("Time: %0t  Instance: %m", $time);
5009                $finish;
5010            end
5011            else if (paddress >= lpm_numwords)
5012            begin
5013                $display("%t:Error:  Address out of bound on RAM.", $time);
5014                $display("Time: %0t  Instance: %m", $time);
5015                $finish;
5016            end
5017            else
5018                ValidAddress = 1'b1;
5019        end
5020    endfunction
5021
5022// COMPONENT INSTANTIATIONS
5023    LPM_MEMORY_INITIALIZATION mem ();
5024
5025
5026// INITIAL CONSTRUCT BLOCK
5027    initial
5028    begin
5029
5030        if (lpm_width <= 0)
5031        begin
5032            $display("Error!  LPM_WIDTH parameter must be greater than 0.");
5033            $display("Time: %0t  Instance: %m", $time);
5034            $finish;
5035        end
5036
5037        if (lpm_widthad <= 0)
5038        begin
5039            $display("Error!  LPM_WIDTHAD parameter must be greater than 0.");
5040            $display("Time: %0t  Instance: %m", $time);
5041            $finish;
5042        end
5043
5044        // check for number of words out of bound
5045        if ((lpm_numwords > (1 << lpm_widthad))
5046            ||(lpm_numwords <= (1 << (lpm_widthad-1))))
5047        begin
5048            $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD.");
5049            $display("Time: %0t  Instance: %m", $time);
5050            $finish;
5051        end
5052
5053        if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED"))
5054        begin
5055            $display("Error!  LPM_INDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
5056            $display("Time: %0t  Instance: %m", $time);
5057            $finish;
5058        end
5059
5060        if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED"))
5061        begin
5062            $display("Error!  LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\".");
5063            $display("Time: %0t  Instance: %m", $time);
5064            $finish;
5065        end
5066
5067        if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
5068        begin
5069            $display("Error!  LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
5070            $display("Time: %0t  Instance: %m", $time);
5071            $finish;
5072        end
5073
5074        for (i = 0; i < lpm_numwords; i=i+1)
5075            mem_data[i] = {lpm_width{1'b0}};
5076
5077        // Initialize input/output
5078        pwe = 1'b0;
5079        pdio = {lpm_width{1'b0}};
5080        paddress = {lpm_widthad{1'b0}};
5081        paddress_tmp = {lpm_widthad{1'b0}};
5082        tmp_io = {lpm_width{1'b0}};
5083        tmp_q = {lpm_width{1'b0}};
5084
5085        // load data to the RAM
5086        if (lpm_file != "UNUSED")
5087        begin
5088            mem.convert_to_ver_file(lpm_file, lpm_width, ram_initf);
5089            $readmemh(ram_initf, mem_data);
5090        end
5091    end
5092
5093
5094// ALWAYS CONSTRUCT BLOCK
5095    always @(dio)
5096    begin
5097        if (lpm_indata == "UNREGISTERED")
5098            pdio <=  dio;
5099    end
5100
5101    always @(address)
5102    begin
5103        if (lpm_address_control == "UNREGISTERED")
5104            paddress <=  address;
5105    end
5106
5107
5108    always @(we)
5109    begin
5110        if (lpm_address_control == "UNREGISTERED")
5111            pwe <=  we;
5112    end
5113
5114    always @(posedge i_inclock)
5115    begin
5116        if (lpm_indata == "REGISTERED")
5117            pdio <=  dio;
5118
5119        if (lpm_address_control == "REGISTERED")
5120        begin
5121            paddress <=  address;
5122            pwe <=  we;
5123        end
5124    end
5125
5126    always @(pdio or paddress or pwe or i_memenab)
5127    begin
5128        if (ValidAddress(paddress))
5129        begin
5130            paddress_tmp <= paddress;
5131            if (lpm_address_control == "UNREGISTERED")
5132                if (pwe && i_memenab)
5133                    mem_data[paddress] <= pdio;
5134        end
5135        else
5136        begin
5137            if (lpm_outdata == "UNREGISTERED")
5138                tmp_q <= {lpm_width{1'bx}};
5139        end
5140    end
5141
5142    always @(read_data)
5143    begin
5144        if (lpm_outdata == "UNREGISTERED")
5145            tmp_q <= read_data;
5146    end
5147
5148    always @(negedge i_inclock or pdio)
5149    begin
5150        if (lpm_address_control == "REGISTERED")
5151            if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON"))
5152                if (pwe && i_memenab && (i_inclock == 1'b0))
5153                    mem_data[paddress] = pdio;
5154    end
5155
5156    always @(posedge i_inclock)
5157    begin
5158        if (lpm_address_control == "REGISTERED")
5159            if ((use_eab == "OFF") && pwe && i_memenab)
5160                mem_data[paddress] <= pdio;
5161    end
5162
5163    always @(posedge i_outclock)
5164    begin
5165        if (lpm_outdata == "REGISTERED")
5166            tmp_q <= mem_data[paddress];
5167    end
5168
5169    always @(i_memenab or i_outenab or tmp_q)
5170    begin
5171        if (i_memenab && i_outenab)
5172            tmp_io = tmp_q;
5173        else if ((!i_memenab) || (i_memenab && (!i_outenab)))
5174            tmp_io = {lpm_width{1'bz}};
5175    end
5176
5177
5178// CONTINOUS ASSIGNMENT
5179    assign dio = tmp_io;
5180    assign read_data = mem_data[paddress_tmp];
5181
5182endmodule // lpm_ram_io
5183
5184//START_MODULE_NAME------------------------------------------------------------
5185//
5186// Module Name     :  lpm_rom
5187//
5188// Description     :  Parameterized ROM megafunction. This megafunction is provided
5189//                    only for backward compatibility in Cyclone, Stratix, and
5190//                    Stratix GX designs; instead, Altera recommends using the
5191//                    altsyncram megafunction.
5192//
5193// Limitation      :  This option is available for all Altera devices supported by
5194//                    the Quartus II software except MAX 3000 and MAX 7000 devices.
5195//
5196// Results expected:  Output of memory.
5197//
5198//END_MODULE_NAME--------------------------------------------------------------
5199
5200// BEGINNING OF MODULE
5201`timescale 1 ps / 1 ps
5202
5203// MODULE DECLARATION
5204module lpm_rom (
5205    address,    // Address input to the memory. (Required)
5206    inclock,    // Clock for input registers.
5207    outclock,   // Clock for output registers.
5208    memenab,    // Memory enable input.
5209    q           // Output of memory.  (Required)
5210);
5211
5212// GLOBAL PARAMETER DECLARATION
5213    parameter lpm_width = 1;    // Width of the q[] port. (Required)
5214    parameter lpm_widthad = 1;  // Width of the address[] port. (Required)
5215    parameter lpm_numwords = 0; // Number of words stored in memory.
5216    parameter lpm_address_control = "REGISTERED"; // Indicates whether the address port is registered.
5217    parameter lpm_outdata = "REGISTERED"; // Indicates whether the q and eq ports are registered.
5218    parameter lpm_file = ""; // Name of the memory file containing ROM initialization data
5219    parameter intended_device_family = "Stratix";
5220    parameter lpm_type = "lpm_rom";
5221    parameter lpm_hint = "UNUSED";
5222
5223// LOCAL_PARAMETERS_BEGIN
5224
5225    parameter NUM_WORDS = (lpm_numwords == 0) ? (1 << lpm_widthad) : lpm_numwords;
5226
5227// LOCAL_PARAMETERS_END
5228
5229// INPUT PORT DECLARATION
5230    input  [lpm_widthad-1:0] address;
5231    input  inclock;
5232    input  outclock;
5233    input  memenab;
5234
5235// OUTPUT PORT DECLARATION
5236    output [lpm_width-1:0] q;
5237
5238// INTERNAL REGISTER/SIGNAL DECLARATION
5239    reg  [lpm_width-1:0] mem_data [0:NUM_WORDS-1];
5240    reg  [lpm_widthad-1:0] address_reg;
5241    reg  [lpm_width-1:0] tmp_q_reg;
5242`ifdef VERILATOR
5243    reg  [`LPM_MAX_NAME_SZ*8:1] rom_initf;
5244`else
5245    reg  [8*256:1] rom_initf;
5246`endif
5247
5248// INTERNAL WIRE DECLARATION
5249    wire [lpm_widthad-1:0] w_address;
5250    wire [lpm_width-1:0] w_read_data;
5251    wire i_inclock;
5252    wire i_outclock;
5253    wire i_memenab;
5254
5255// LOCAL INTEGER DECLARATION
5256    integer i;
5257
5258// INTERNAL TRI DECLARATION
5259    tri0 inclock;
5260    tri0 outclock;
5261    tri1 memenab;
5262
5263    buf (i_inclock, inclock);
5264    buf (i_outclock, outclock);
5265    buf (i_memenab, memenab);
5266
5267// COMPONENT INSTANTIATIONS
5268    LPM_DEVICE_FAMILIES dev ();
5269    LPM_MEMORY_INITIALIZATION mem ();
5270
5271// FUNCTON DECLARATION
5272    // Check the validity of the address.
5273    function ValidAddress;
5274        input [lpm_widthad-1:0] address;
5275        begin
5276            ValidAddress = 1'b0;
5277            if (^address == {lpm_widthad{1'bx}})
5278            begin
5279                $display("%d:Error:  Invalid address.", $time);
5280                $display("Time: %0t  Instance: %m", $time);
5281                $finish;
5282            end
5283            else if (address >= NUM_WORDS)
5284            begin
5285                $display("%d:Error:  Address out of bound on ROM.", $time);
5286                $display("Time: %0t  Instance: %m", $time);
5287                $finish;
5288            end
5289            else
5290                ValidAddress = 1'b1;
5291        end
5292    endfunction
5293
5294// INITIAL CONSTRUCT BLOCK
5295    initial
5296    begin
5297        // Initialize output
5298        tmp_q_reg = {lpm_width{1'b0}};
5299        address_reg = {lpm_widthad{1'b0}};
5300
5301        if (lpm_width <= 0)
5302        begin
5303            $display("Error!  LPM_WIDTH parameter must be greater than 0.");
5304            $display("Time: %0t  Instance: %m", $time);
5305            $finish;
5306        end
5307
5308        if (lpm_widthad <= 0)
5309        begin
5310            $display("Error!  LPM_WIDTHAD parameter must be greater than 0.");
5311            $display("Time: %0t  Instance: %m", $time);
5312            $finish;
5313        end
5314
5315        // check for number of words out of bound
5316        if ((NUM_WORDS > (1 << lpm_widthad)) ||
5317            (NUM_WORDS <= (1 << (lpm_widthad-1))))
5318        begin
5319            $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD.");
5320            $display("Time: %0t  Instance: %m", $time);
5321            $finish;
5322        end
5323
5324        if ((lpm_address_control != "REGISTERED") &&
5325            (lpm_address_control != "UNREGISTERED"))
5326        begin
5327            $display("Error!  LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\".");
5328            $display("Time: %0t  Instance: %m", $time);
5329            $finish;
5330        end
5331
5332        if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
5333        begin
5334            $display("Error!  LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
5335            $display("Time: %0t  Instance: %m", $time);
5336            $finish;
5337        end
5338
5339        if (dev.IS_VALID_FAMILY(intended_device_family) == 0)
5340        begin
5341            $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family);
5342            $display("Time: %0t  Instance: %m", $time);
5343            $finish;
5344        end
5345        if (dev.FEATURE_FAMILY_MAX(intended_device_family) == 1)
5346        begin
5347            $display ("Error! LPM_ROM megafunction does not support %s devices.", intended_device_family);
5348            $display("Time: %0t  Instance: %m", $time);
5349            $finish;
5350        end
5351
5352        for (i = 0; i < NUM_WORDS; i=i+1)
5353            mem_data[i] = {lpm_width{1'b0}};
5354
5355        // load data to the ROM
5356        if ((lpm_file == "") || (lpm_file == "UNUSED"))
5357        begin
5358            $display("Warning:  LPM_ROM must have data file for initialization.\n");
5359            $display ("Time: %0t  Instance: %m", $time);
5360        end
5361        else
5362        begin
5363            mem.convert_to_ver_file(lpm_file, lpm_width, rom_initf);
5364            $readmemh(rom_initf, mem_data);
5365        end
5366    end
5367
5368    always @(posedge i_inclock)
5369    begin
5370        if (lpm_address_control == "REGISTERED")
5371            address_reg <=  address; // address port is registered
5372    end
5373
5374    always @(w_address or w_read_data)
5375    begin
5376        if (ValidAddress(w_address))
5377        begin
5378            if (lpm_outdata == "UNREGISTERED")
5379                // Load the output register with the contents of the memory location
5380                // pointed to by address[].
5381                tmp_q_reg <=  w_read_data;
5382        end
5383        else
5384        begin
5385            if (lpm_outdata == "UNREGISTERED")
5386                tmp_q_reg <= {lpm_width{1'bx}};
5387        end
5388    end
5389
5390    always @(posedge i_outclock)
5391    begin
5392        if (lpm_outdata == "REGISTERED")
5393        begin
5394            if (ValidAddress(w_address))
5395                tmp_q_reg <=  w_read_data;
5396            else
5397                tmp_q_reg <= {lpm_width{1'bx}};
5398        end
5399    end
5400
5401// CONTINOUS ASSIGNMENT
5402    assign w_address = (lpm_address_control == "REGISTERED") ? address_reg : address;
5403    assign w_read_data = mem_data[w_address];
5404    assign q = (i_memenab) ? tmp_q_reg : {lpm_width{1'bz}};
5405
5406endmodule // lpm_rom
5407// END OF MODULE
5408
5409//START_MODULE_NAME------------------------------------------------------------
5410//
5411// Module Name     :  lpm_fifo
5412//
5413// Description     :
5414//
5415// Limitation      :
5416//
5417// Results expected:
5418//
5419//END_MODULE_NAME--------------------------------------------------------------
5420
5421`timescale 1 ps / 1 ps
5422
5423module lpm_fifo (   data,
5424                    clock,
5425                    wrreq,
5426                    rdreq,
5427                    aclr,
5428                    sclr,
5429                    q,
5430                    usedw,
5431                    full,
5432                    empty );
5433
5434// GLOBAL PARAMETER DECLARATION
5435    parameter lpm_width = 1;
5436    parameter lpm_widthu = 1;
5437    parameter lpm_numwords = 2;
5438    parameter lpm_showahead = "OFF";
5439    parameter lpm_type = "lpm_fifo";
5440    parameter lpm_hint = "";
5441
5442// INPUT PORT DECLARATION
5443    input  [lpm_width-1:0] data;
5444    input  clock;
5445    input  wrreq;
5446    input  rdreq;
5447    input  aclr;
5448    input  sclr;
5449
5450// OUTPUT PORT DECLARATION
5451    output [lpm_width-1:0] q;
5452    output [lpm_widthu-1:0] usedw;
5453    output full;
5454    output empty;
5455
5456// INTERNAL REGISTERS DECLARATION
5457    reg [lpm_width-1:0] mem_data [(1<<lpm_widthu):0];
5458    reg [lpm_width-1:0] tmp_data;
5459    reg [lpm_widthu-1:0] count_id;
5460    reg [lpm_widthu-1:0] read_id;
5461    reg [lpm_widthu-1:0] write_id;
5462    reg write_flag;
5463    reg full_flag;
5464    reg empty_flag;
5465    reg [lpm_width-1:0] tmp_q;
5466
5467    reg [8*5:1] overflow_checking;
5468    reg [8*5:1] underflow_checking;
5469    reg [8*20:1] allow_rwcycle_when_full;
5470    reg [8*20:1] intended_device_family;
5471
5472// INTERNAL WIRE DECLARATION
5473    wire valid_rreq;
5474    wire valid_wreq;
5475
5476// INTERNAL TRI DECLARATION
5477    tri0 aclr;
5478
5479// LOCAL INTEGER DECLARATION
5480    integer i;
5481
5482// COMPONENT INSTANTIATIONS
5483    LPM_DEVICE_FAMILIES dev ();
5484    LPM_HINT_EVALUATION eva();
5485
5486// INITIAL CONSTRUCT BLOCK
5487    initial
5488    begin
5489        if (lpm_width <= 0)
5490        begin
5491            $display ("Error! LPM_WIDTH must be greater than 0.");
5492            $display("Time: %0t  Instance: %m", $time);
5493            $stop;
5494        end
5495        if (lpm_numwords <= 1)
5496        begin
5497            $display ("Error! LPM_NUMWORDS must be greater than or equal to 2.");
5498            $display("Time: %0t  Instance: %m", $time);
5499            $stop;
5500        end
5501        if ((lpm_widthu !=1) && (lpm_numwords > (1 << lpm_widthu)))
5502        begin
5503            $display ("Error! LPM_NUMWORDS must equal to the ceiling of log2(LPM_WIDTHU).");
5504            $display("Time: %0t  Instance: %m", $time);
5505            $stop;
5506        end
5507        if (lpm_numwords <= (1 << (lpm_widthu - 1)))
5508        begin
5509            $display ("Error! LPM_WIDTHU is too big for the specified LPM_NUMWORDS.");
5510            $display("Time: %0t  Instance: %m", $time);
5511            $stop;
5512        end
5513
5514        overflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "OVERFLOW_CHECKING");
5515        if(overflow_checking == "")
5516            overflow_checking = "ON";
5517        else if ((overflow_checking != "ON") && (overflow_checking != "OFF"))
5518        begin
5519            $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
5520            $display("Time: %0t  Instance: %m", $time);
5521            $stop;
5522        end
5523
5524        underflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "UNDERFLOW_CHECKING");
5525        if(underflow_checking == "")
5526            underflow_checking = "ON";
5527        else if ((underflow_checking != "ON") && (underflow_checking != "OFF"))
5528        begin
5529            $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
5530            $display("Time: %0t  Instance: %m", $time);
5531            $stop;
5532        end
5533
5534        allow_rwcycle_when_full = eva.GET_PARAMETER_VALUE(lpm_hint, "ALLOW_RWCYCLE_WHEN_FULL");
5535        if (allow_rwcycle_when_full == "")
5536            allow_rwcycle_when_full = "OFF";
5537        else if ((allow_rwcycle_when_full != "ON") && (allow_rwcycle_when_full != "OFF"))
5538        begin
5539            $display ("Error! ALLOW_RWCYCLE_WHEN_FULL must equal to either 'ON' or 'OFF'");
5540            $display("Time: %0t  Instance: %m", $time);
5541            $stop;
5542        end
5543
5544        intended_device_family = eva.GET_PARAMETER_VALUE(lpm_hint, "INTENDED_DEVICE_FAMILY");
5545        if (intended_device_family == "")
5546            intended_device_family = "Stratix II";
5547        else if (dev.IS_VALID_FAMILY(intended_device_family) == 0)
5548        begin
5549            $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family);
5550            $display("Time: %0t  Instance: %m", $time);
5551            $stop;
5552        end
5553        for (i = 0; i < (1<<lpm_widthu); i = i + 1)
5554        begin
5555            if (dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
5556                dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))
5557                mem_data[i] <= {lpm_width{1'bx}};
5558            else
5559                mem_data[i] <= {lpm_width{1'b0}};
5560        end
5561
5562        tmp_data <= 0;
5563        if (dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
5564            dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family))
5565            tmp_q <= {lpm_width{1'bx}};
5566        else
5567            tmp_q <= {lpm_width{1'b0}};
5568        write_flag <= 1'b0;
5569        count_id <= 0;
5570        read_id <= 0;
5571        write_id <= 0;
5572        full_flag <= 1'b0;
5573        empty_flag <= 1'b1;
5574    end
5575
5576// ALWAYS CONSTRUCT BLOCK
5577    always @(posedge clock or posedge aclr)
5578    begin
5579        if (aclr)
5580        begin
5581            if (!(dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
5582                dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)))
5583            begin
5584                if (lpm_showahead == "ON")
5585                    tmp_q <= mem_data[0];
5586                else
5587                    tmp_q <= {lpm_width{1'b0}};
5588            end
5589
5590            read_id <= 0;
5591            count_id <= 0;
5592            full_flag <= 1'b0;
5593            empty_flag <= 1'b1;
5594
5595            if (valid_wreq && (dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
5596                dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)))
5597            begin
5598                tmp_data <= data;
5599                write_flag <= 1'b1;
5600            end
5601            else
5602                write_id <= 0;
5603        end
5604        else if (sclr)
5605        begin
5606            if ((lpm_showahead == "ON") || (dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
5607                dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)))
5608                tmp_q <= mem_data[0];
5609            else
5610                tmp_q <= mem_data[read_id];
5611            read_id <= 0;
5612            count_id <= 0;
5613            full_flag <= 1'b0;
5614            empty_flag <= 1'b1;
5615
5616            if (valid_wreq)
5617            begin
5618                tmp_data <= data;
5619                write_flag <= 1'b1;
5620            end
5621            else
5622                write_id <= 0;
5623        end
5624        else
5625        begin
5626            // Both WRITE and READ operations
5627            if (valid_wreq && valid_rreq)
5628            begin
5629                tmp_data <= data;
5630                write_flag <= 1'b1;
5631                empty_flag <= 1'b0;
5632                if (allow_rwcycle_when_full == "OFF")
5633                begin
5634                    full_flag <= 1'b0;
5635                end
5636
5637                if (read_id >= ((1 << lpm_widthu) - 1))
5638                begin
5639                    if (lpm_showahead == "ON")
5640                        tmp_q <= mem_data[0];
5641                    else
5642                        tmp_q <= mem_data[read_id];
5643                    read_id <= 0;
5644                end
5645                else
5646                begin
5647                    if (lpm_showahead == "ON")
5648                        tmp_q <= mem_data[read_id + 1];
5649                    else
5650                        tmp_q <= mem_data[read_id];
5651                    read_id <= read_id + 1;
5652                end
5653            end
5654            // WRITE operation only
5655            else if (valid_wreq)
5656            begin
5657                tmp_data <= data;
5658                empty_flag <= 1'b0;
5659                write_flag <= 1'b1;
5660
5661                if (count_id >= (1 << lpm_widthu) - 1)
5662                    count_id <= 0;
5663                else
5664                    count_id <= count_id + 1;
5665
5666                if ((count_id == lpm_numwords - 1) && (empty_flag == 1'b0))
5667                    full_flag <= 1'b1;
5668
5669                if (lpm_showahead == "ON")
5670                    tmp_q <= mem_data[read_id];
5671            end
5672            // READ operation only
5673            else if (valid_rreq)
5674            begin
5675                full_flag <= 1'b0;
5676
5677                if (count_id <= 0)
5678                    count_id <= {lpm_widthu{1'b1}};
5679                else
5680                    count_id <= count_id - 1;
5681
5682                if ((count_id == 1) && (full_flag == 1'b0))
5683                    empty_flag <= 1'b1;
5684
5685                if (read_id >= ((1<<lpm_widthu) - 1))
5686                begin
5687                    if (lpm_showahead == "ON")
5688                        tmp_q <= mem_data[0];
5689                    else
5690                        tmp_q <= mem_data[read_id];
5691                    read_id <= 0;
5692                end
5693                else
5694                begin
5695                    if (lpm_showahead == "ON")
5696                        tmp_q <= mem_data[read_id + 1];
5697                    else
5698                        tmp_q <= mem_data[read_id];
5699                    read_id <= read_id + 1;
5700                end
5701            end // if Both WRITE and READ operations
5702
5703        end // if aclr
5704    end // @(posedge clock)
5705
5706    always @(negedge clock)
5707    begin
5708        if (write_flag)
5709        begin
5710            write_flag <= 1'b0;
5711            mem_data[write_id] <= tmp_data;
5712
5713            if (sclr || aclr || (write_id >= ((1 << lpm_widthu) - 1)))
5714                write_id <= 0;
5715            else
5716                write_id <= write_id + 1;
5717        end
5718
5719        if ((lpm_showahead == "ON") && ($time > 0))
5720            tmp_q <= ((write_flag == 1'b1) && (write_id == read_id)) ?
5721                        tmp_data : mem_data[read_id];
5722
5723    end // @(negedge clock)
5724
5725// CONTINOUS ASSIGNMENT
5726    assign valid_rreq = (underflow_checking == "OFF") ? rdreq : rdreq && ~empty_flag;
5727    assign valid_wreq = (overflow_checking == "OFF") ? wrreq :
5728                        (allow_rwcycle_when_full == "ON") ? wrreq && (!full_flag || rdreq) :
5729                        wrreq && !full_flag;
5730    assign q = tmp_q;
5731    assign full = full_flag;
5732    assign empty = empty_flag;
5733    assign usedw = count_id;
5734
5735endmodule // lpm_fifo
5736// END OF MODULE
5737
5738//START_MODULE_NAME------------------------------------------------------------
5739//
5740// Module Name     :  lpm_fifo_dc_dffpipe
5741//
5742// Description     :  Dual Clocks FIFO
5743//
5744// Limitation      :
5745//
5746// Results expected:
5747//
5748//END_MODULE_NAME--------------------------------------------------------------
5749
5750// BEGINNING OF MODULE
5751`timescale 1 ps / 1 ps
5752
5753// MODULE DECLARATION
5754module lpm_fifo_dc_dffpipe (d,
5755                            clock,
5756                            aclr,
5757                            q);
5758
5759// GLOBAL PARAMETER DECLARATION
5760    parameter lpm_delay = 1;
5761    parameter lpm_width = 64;
5762
5763// INPUT PORT DECLARATION
5764    input [lpm_width-1:0] d;
5765    input clock;
5766    input aclr;
5767
5768// OUTPUT PORT DECLARATION
5769    output [lpm_width-1:0] q;
5770
5771// INTERNAL REGISTERS DECLARATION
5772    reg [lpm_width-1:0] dffpipe [lpm_delay:0];
5773    reg [lpm_width-1:0] q;
5774
5775// LOCAL INTEGER DECLARATION
5776    integer delay;
5777    integer i;
5778
5779// INITIAL CONSTRUCT BLOCK
5780    initial
5781    begin
5782        delay <= lpm_delay - 1;
5783
5784        for (i = 0; i <= lpm_delay; i = i + 1)
5785            dffpipe[i] <= 0;
5786        q <= 0;
5787    end
5788
5789// ALWAYS CONSTRUCT BLOCK
5790    always @(posedge aclr or posedge clock)
5791    begin
5792        if (aclr)
5793        begin
5794            for (i = 0; i <= lpm_delay; i = i + 1)
5795                dffpipe[i] <= 0;
5796            q <= 0;
5797        end
5798        else if (clock)
5799        begin
5800            if ((lpm_delay > 0) && ($time > 0))
5801            begin
5802`ifdef VERILATOR
5803                if (lpm_delay > 0)
5804`else
5805                if (delay > 0)
5806`endif
5807                begin
5808`ifdef VERILATOR
5809                    for (i = lpm_delay-1; i > 0; i = i - 1)
5810`else
5811                    for (i = delay; i > 0; i = i - 1)
5812`endif
5813                        dffpipe[i] <= dffpipe[i - 1];
5814                    q <= dffpipe[delay - 1];
5815                end
5816                else
5817                    q <= d;
5818
5819                dffpipe[0] <= d;
5820            end
5821        end
5822    end // @(posedge aclr or posedge clock)
5823
5824    always @(d)
5825    begin
5826        if (lpm_delay == 0)
5827            q <= d;
5828    end // @(d)
5829
5830endmodule // lpm_fifo_dc_dffpipe
5831// END OF MODULE
5832
5833//START_MODULE_NAME------------------------------------------------------------
5834//
5835// Module Name     :  lpm_fifo_dc_fefifo
5836//
5837// Description     :  Dual Clock FIFO
5838//
5839// Limitation      :
5840//
5841// Results expected:
5842//
5843//END_MODULE_NAME--------------------------------------------------------------
5844
5845// BEGINNING OF MODULE
5846`timescale 1 ps / 1 ps
5847
5848// MODULE DECLARATION
5849module lpm_fifo_dc_fefifo ( usedw_in,
5850                            wreq,
5851                            rreq,
5852                            clock,
5853                            aclr,
5854                            empty,
5855                            full);
5856
5857// GLOBAL PARAMETER DECLARATION
5858    parameter lpm_widthad = 1;
5859    parameter lpm_numwords = 1;
5860    parameter underflow_checking = "ON";
5861    parameter overflow_checking = "ON";
5862    parameter lpm_mode = "READ";
5863    parameter lpm_hint = "";
5864
5865// INPUT PORT DECLARATION
5866    input [lpm_widthad-1:0] usedw_in;
5867    input wreq;
5868    input rreq;
5869    input clock;
5870    input aclr;
5871
5872// OUTPUT PORT DECLARATION
5873    output empty;
5874    output full;
5875
5876// INTERNAL REGISTERS DECLARATION
5877    reg [1:0] sm_empty;
5878    reg lrreq;
5879    reg i_empty;
5880    reg i_full;
5881    reg [8*5:1] i_overflow_checking;
5882    reg [8*5:1] i_underflow_checking;
5883
5884// LOCAL INTEGER DECLARATION
5885    integer almostfull;
5886
5887// COMPONENT INSTANTIATIONS
5888    LPM_HINT_EVALUATION eva();
5889
5890// INITIAL CONSTRUCT BLOCK
5891    initial
5892    begin
5893        if ((lpm_mode != "READ") && (lpm_mode != "WRITE"))
5894        begin
5895            $display ("Error! LPM_MODE must be READ or WRITE.");
5896            $display("Time: %0t  Instance: %m", $time);
5897            $stop;
5898        end
5899
5900        i_overflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "OVERFLOW_CHECKING");
5901        if (i_overflow_checking == "")
5902        begin
5903            if ((overflow_checking != "ON") && (overflow_checking != "OFF"))
5904            begin
5905                $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
5906                $display("Time: %0t  Instance: %m", $time);
5907                $stop;
5908            end
5909            else
5910                i_overflow_checking = overflow_checking;
5911        end
5912        else if ((i_overflow_checking != "ON") && (i_overflow_checking != "OFF"))
5913        begin
5914            $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
5915            $display("Time: %0t  Instance: %m", $time);
5916            $stop;
5917        end
5918
5919        i_underflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "UNDERFLOW_CHECKING");
5920        if(i_underflow_checking == "")
5921        begin
5922            if ((underflow_checking != "ON") && (underflow_checking != "OFF"))
5923            begin
5924                $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
5925                $display("Time: %0t  Instance: %m", $time);
5926                $stop;
5927            end
5928            else
5929                i_underflow_checking = underflow_checking;
5930        end
5931        else if ((i_underflow_checking != "ON") && (i_underflow_checking != "OFF"))
5932        begin
5933            $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
5934            $display("Time: %0t  Instance: %m", $time);
5935            $stop;
5936        end
5937
5938        sm_empty <= 2'b00;
5939        i_empty <= 1'b1;
5940        i_full <= 1'b0;
5941        lrreq <= 1'b0;
5942
5943        if (lpm_numwords >= 3)
5944            almostfull <= lpm_numwords - 3;
5945        else
5946            almostfull <= 0;
5947    end
5948
5949// ALWAYS CONSTRUCT BLOCK
5950    always @(posedge aclr)
5951    begin
5952        sm_empty <= 2'b00;
5953        i_empty <= 1'b1;
5954        i_full <= 1'b0;
5955        lrreq <= 1'b0;
5956    end // @(posedge aclr)
5957
5958    always @(posedge clock)
5959    begin
5960        if (i_underflow_checking == "OFF")
5961            lrreq <= rreq;
5962        else
5963            lrreq <= rreq && ~i_empty;
5964
5965        if (~aclr && ($time > 0))
5966        begin
5967            if (lpm_mode == "READ")
5968            begin
5969                // verilator lint_off CASEX
5970                casex (sm_empty)
5971                // verilator lint_on CASEX
5972                    // state_empty
5973                    2'b00:
5974                        if (usedw_in != 0)
5975                            sm_empty <= 2'b01;
5976                    // state_non_empty
5977                    // verilator lint_off CMPCONST
5978                    2'b01:
5979                        if (rreq && (((usedw_in == 1) && !lrreq) || ((usedw_in == 2) && lrreq)))
5980                            sm_empty <= 2'b10;
5981                    // state_emptywait
5982                    2'b10:
5983                        if (usedw_in > 1)
5984                            sm_empty <= 2'b01;
5985                        else
5986                            sm_empty <= 2'b00;
5987                    // verilator lint_on CMPCONST
5988                    default:
5989                        begin
5990                            $display ("Error! Invalid sm_empty state in read mode.");
5991                            $display("Time: %0t  Instance: %m", $time);
5992                        end
5993                endcase
5994            end // if (lpm_mode == "READ")
5995            else if (lpm_mode == "WRITE")
5996            begin
5997                // verilator lint_off CASEX
5998                casex (sm_empty)
5999                // verilator lint_on CASEX
6000                    // state_empty
6001                    2'b00:
6002                        if (wreq)
6003                            sm_empty <= 2'b01;
6004                    // state_one
6005                    2'b01:
6006                        if (!wreq)
6007                            sm_empty <= 2'b11;
6008                    // state_non_empty
6009                    2'b11:
6010                        if (wreq)
6011                            sm_empty <= 2'b01;
6012                        else if (usedw_in == 0)
6013                            sm_empty <= 2'b00;
6014                    default:
6015                        begin
6016                            $display ("Error! Invalid sm_empty state in write mode.");
6017                            $display("Time: %0t  Instance: %m", $time);
6018                        end
6019                endcase
6020            end // if (lpm_mode == "WRITE")
6021
6022            if (~aclr && (usedw_in >= almostfull) && ($time > 0))
6023                i_full <= 1'b1;
6024            else
6025                i_full <= 1'b0;
6026        end // if (~aclr && $time > 0)
6027    end // @(posedge clock)
6028
6029    always @(sm_empty)
6030    begin
6031        i_empty <= !sm_empty[0];
6032    end
6033    // @(sm_empty)
6034
6035// CONTINOUS ASSIGNMENT
6036    assign empty = i_empty;
6037    assign full = i_full;
6038endmodule // lpm_fifo_dc_fefifo
6039// END OF MODULE
6040
6041//START_MODULE_NAME------------------------------------------------------------
6042//
6043// Module Name     :  lpm_fifo_dc_async
6044//
6045// Description     :  Asynchronous Dual Clocks FIFO
6046//
6047// Limitation      :
6048//
6049// Results expected:
6050//
6051//END_MODULE_NAME--------------------------------------------------------------
6052
6053// BEGINNING OF MODULE
6054`timescale 1 ps / 1 ps
6055
6056// MODULE DECLARATION
6057module lpm_fifo_dc_async (  data,
6058                            rdclk,
6059                            wrclk,
6060                            aclr,
6061                            rdreq,
6062                            wrreq,
6063                            rdfull,
6064                            wrfull,
6065                            rdempty,
6066                            wrempty,
6067                            rdusedw,
6068                            wrusedw,
6069                            q);
6070
6071// GLOBAL PARAMETER DECLARATION
6072    parameter lpm_width = 1;
6073    parameter lpm_widthu = 1;
6074    parameter lpm_numwords = 2;
6075    parameter delay_rdusedw = 1;
6076    parameter delay_wrusedw = 1;
6077    parameter rdsync_delaypipe = 3;
6078    parameter wrsync_delaypipe = 3;
6079    parameter lpm_showahead = "OFF";
6080    parameter underflow_checking = "ON";
6081    parameter overflow_checking = "ON";
6082    parameter lpm_hint = "INTENDED_DEVICE_FAMILY=Stratix";
6083
6084// INPUT PORT DECLARATION
6085    input [lpm_width-1:0] data;
6086    input rdclk;
6087    input wrclk;
6088    input aclr;
6089    input wrreq;
6090    input rdreq;
6091
6092// OUTPUT PORT DECLARATION
6093    output rdfull;
6094    output wrfull;
6095    output rdempty;
6096    output wrempty;
6097    output [lpm_widthu-1:0] rdusedw;
6098    output [lpm_widthu-1:0] wrusedw;
6099    output [lpm_width-1:0] q;
6100
6101// INTERNAL REGISTERS DECLARATION
6102    reg [lpm_width-1:0] mem_data [(1<<lpm_widthu)-1:0];
6103    reg [lpm_width-1:0] i_data_tmp;
6104    reg [lpm_widthu-1:0] i_rdptr;
6105    reg [lpm_widthu-1:0] i_wrptr;
6106    reg [lpm_widthu-1:0] i_wrptr_tmp;
6107    reg i_rdenclock;
6108    reg i_wren_tmp;
6109    reg [lpm_widthu-1:0] i_wr_udwn;
6110    reg [lpm_widthu-1:0] i_rd_udwn;
6111    reg i_showahead_flag;
6112    reg i_showahead_flag1;
6113    reg [lpm_widthu:0] i_rdusedw;
6114    reg [lpm_widthu-1:0] i_wrusedw;
6115    reg [lpm_width-1:0] i_q_tmp;
6116
6117    reg [8*5:1] i_overflow_checking;
6118    reg [8*5:1] i_underflow_checking;
6119    reg [8*10:1] use_eab;
6120    reg [8*20:1] intended_device_family;
6121
6122// INTERNAL WIRE DECLARATION
6123    wire w_rden;
6124    wire w_wren;
6125    wire w_rdempty;
6126    wire w_wrempty;
6127    wire w_rdfull;
6128    wire w_wrfull;
6129    wire [lpm_widthu-1:0] w_rdptrrg;
6130    wire [lpm_widthu-1:0] w_wrdelaycycle;
6131    wire [lpm_widthu-1:0] w_ws_nbrp;
6132    wire [lpm_widthu-1:0] w_rs_nbwp;
6133    wire [lpm_widthu-1:0] w_ws_dbrp;
6134    wire [lpm_widthu-1:0] w_rs_dbwp;
6135    wire [lpm_widthu-1:0] w_rd_dbuw;
6136    wire [lpm_widthu-1:0] w_wr_dbuw;
6137    wire [lpm_widthu-1:0] w_rdusedw;
6138    wire [lpm_widthu-1:0] w_wrusedw;
6139
6140// INTERNAL TRI DECLARATION
6141    tri0 aclr;
6142
6143// LOCAL INTEGER DECLARATION
6144    integer i;
6145
6146// COMPONENT INSTANTIATIONS
6147    LPM_DEVICE_FAMILIES dev ();
6148    LPM_HINT_EVALUATION eva();
6149
6150// INITIAL CONSTRUCT BLOCK
6151    initial
6152    begin
6153        if((lpm_showahead != "ON") && (lpm_showahead != "OFF"))
6154        begin
6155            $display ("Error! lpm_showahead must be ON or OFF.");
6156            $display("Time: %0t  Instance: %m", $time);
6157            $stop;
6158        end
6159
6160        i_overflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "OVERFLOW_CHECKING");
6161        if (i_overflow_checking == "")
6162        begin
6163            if ((overflow_checking != "ON") && (overflow_checking != "OFF"))
6164            begin
6165                $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
6166                $display("Time: %0t  Instance: %m", $time);
6167                $stop;
6168            end
6169            else
6170                i_overflow_checking = overflow_checking;
6171        end
6172        else if ((i_overflow_checking != "ON") && (i_overflow_checking != "OFF"))
6173        begin
6174            $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
6175            $display("Time: %0t  Instance: %m", $time);
6176            $stop;
6177        end
6178
6179        i_underflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "UNDERFLOW_CHECKING");
6180        if(i_underflow_checking == "")
6181        begin
6182            if ((underflow_checking != "ON") && (underflow_checking != "OFF"))
6183            begin
6184                $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
6185                $display("Time: %0t  Instance: %m", $time);
6186                $stop;
6187            end
6188            else
6189                i_underflow_checking = underflow_checking;
6190        end
6191        else if ((i_underflow_checking != "ON") && (i_underflow_checking != "OFF"))
6192        begin
6193            $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'");
6194            $display("Time: %0t  Instance: %m", $time);
6195            $stop;
6196        end
6197
6198        use_eab = eva.GET_PARAMETER_VALUE(lpm_hint, "USE_EAB");
6199        if(use_eab == "")
6200            use_eab = "ON";
6201        else if ((use_eab != "ON") && (use_eab != "OFF"))
6202        begin
6203            $display ("Error! USE_EAB must equal to either 'ON' or 'OFF'");
6204            $display("Time: %0t  Instance: %m", $time);
6205            $stop;
6206        end
6207
6208        intended_device_family = eva.GET_PARAMETER_VALUE(lpm_hint, "INTENDED_DEVICE_FAMILY");
6209        if (intended_device_family == "")
6210            intended_device_family = "Stratix II";
6211        else if (dev.IS_VALID_FAMILY(intended_device_family) == 0)
6212        begin
6213            $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family);
6214            $display("Time: %0t  Instance: %m", $time);
6215            $stop;
6216        end
6217
6218        for (i = 0; i < (1 << lpm_widthu); i = i + 1)
6219            mem_data[i] <= 0;
6220        i_data_tmp <= 0;
6221        i_rdptr <= 0;
6222        i_wrptr <= 0;
6223        i_wrptr_tmp <= 0;
6224        i_wren_tmp <= 0;
6225        i_wr_udwn <= 0;
6226        i_rd_udwn <= 0;
6227
6228        i_rdusedw <= 0;
6229        i_wrusedw <= 0;
6230        i_q_tmp <= 0;
6231    end
6232
6233// COMPONENT INSTANTIATIONS
6234    // Delays & DFF Pipes
6235    lpm_fifo_dc_dffpipe DP_RDPTR_D (
6236        .d (i_rdptr),
6237        .clock (i_rdenclock),
6238        .aclr (aclr),
6239        .q (w_rdptrrg));
6240    lpm_fifo_dc_dffpipe DP_WRPTR_D (
6241        .d (i_wrptr),
6242        .clock (wrclk),
6243        .aclr (aclr),
6244        .q (w_wrdelaycycle));
6245    defparam
6246        DP_RDPTR_D.lpm_delay = 0,
6247        DP_RDPTR_D.lpm_width = lpm_widthu,
6248        DP_WRPTR_D.lpm_delay = 1,
6249        DP_WRPTR_D.lpm_width = lpm_widthu;
6250
6251    lpm_fifo_dc_dffpipe DP_WS_NBRP (
6252        .d (w_rdptrrg),
6253        .clock (wrclk),
6254        .aclr (aclr),
6255        .q (w_ws_nbrp));
6256    lpm_fifo_dc_dffpipe DP_RS_NBWP (
6257        .d (w_wrdelaycycle),
6258        .clock (rdclk),
6259        .aclr (aclr),
6260        .q (w_rs_nbwp));
6261    lpm_fifo_dc_dffpipe DP_WS_DBRP (
6262        .d (w_ws_nbrp),
6263        .clock (wrclk),
6264        .aclr (aclr),
6265        .q (w_ws_dbrp));
6266    lpm_fifo_dc_dffpipe DP_RS_DBWP (
6267        .d (w_rs_nbwp),
6268        .clock (rdclk),
6269        .aclr (aclr),
6270        .q (w_rs_dbwp));
6271    defparam
6272        DP_WS_NBRP.lpm_delay = wrsync_delaypipe,
6273        DP_WS_NBRP.lpm_width = lpm_widthu,
6274        DP_RS_NBWP.lpm_delay = rdsync_delaypipe,
6275        DP_RS_NBWP.lpm_width = lpm_widthu,
6276        DP_WS_DBRP.lpm_delay = 1,              // gray_delaypipe
6277        DP_WS_DBRP.lpm_width = lpm_widthu,
6278        DP_RS_DBWP.lpm_delay = 1,              // gray_delaypipe
6279        DP_RS_DBWP.lpm_width = lpm_widthu;
6280
6281    lpm_fifo_dc_dffpipe DP_WRUSEDW (
6282        .d (i_wr_udwn),
6283        .clock (wrclk),
6284        .aclr (aclr),
6285        .q (w_wrusedw));
6286    lpm_fifo_dc_dffpipe DP_RDUSEDW (
6287        .d (i_rd_udwn),
6288        .clock (rdclk),
6289        .aclr (aclr),
6290        .q (w_rdusedw));
6291    lpm_fifo_dc_dffpipe DP_WR_DBUW (
6292        .d (i_wr_udwn),
6293        .clock (wrclk),
6294        .aclr (aclr),
6295        .q (w_wr_dbuw));
6296    lpm_fifo_dc_dffpipe DP_RD_DBUW (
6297        .d (i_rd_udwn),
6298        .clock (rdclk),
6299        .aclr (aclr),
6300        .q (w_rd_dbuw));
6301    defparam
6302        DP_WRUSEDW.lpm_delay = delay_wrusedw,
6303        DP_WRUSEDW.lpm_width = lpm_widthu,
6304        DP_RDUSEDW.lpm_delay = delay_rdusedw,
6305        DP_RDUSEDW.lpm_width = lpm_widthu,
6306        DP_WR_DBUW.lpm_delay = 1,              // wrusedw_delaypipe
6307        DP_WR_DBUW.lpm_width = lpm_widthu,
6308        DP_RD_DBUW.lpm_delay = 1,              // rdusedw_delaypipe
6309        DP_RD_DBUW.lpm_width = lpm_widthu;
6310
6311    // Empty/Full
6312    lpm_fifo_dc_fefifo WR_FE (
6313        .usedw_in (w_wr_dbuw),
6314        .wreq (wrreq),
6315        .rreq (rdreq),
6316        .clock (wrclk),
6317        .aclr (aclr),
6318        .empty (w_wrempty),
6319        .full (w_wrfull));
6320    lpm_fifo_dc_fefifo RD_FE (
6321        .usedw_in (w_rd_dbuw),
6322        .rreq (rdreq),
6323        .wreq(wrreq),
6324        .clock (rdclk),
6325        .aclr (aclr),
6326        .empty (w_rdempty),
6327        .full (w_rdfull));
6328    defparam
6329        WR_FE.lpm_widthad = lpm_widthu,
6330        WR_FE.lpm_numwords = lpm_numwords,
6331        WR_FE.underflow_checking = underflow_checking,
6332        WR_FE.overflow_checking = overflow_checking,
6333        WR_FE.lpm_mode = "WRITE",
6334        WR_FE.lpm_hint = lpm_hint,
6335        RD_FE.lpm_widthad = lpm_widthu,
6336        RD_FE.lpm_numwords = lpm_numwords,
6337        RD_FE.underflow_checking = underflow_checking,
6338        RD_FE.overflow_checking = overflow_checking,
6339        RD_FE.lpm_mode = "READ",
6340        RD_FE.lpm_hint = lpm_hint;
6341
6342// ALWAYS CONSTRUCT BLOCK
6343    always @(posedge aclr)
6344    begin
6345        i_rdptr <= 0;
6346        i_wrptr <= 0;
6347        if (!(dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
6348            dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) ||
6349            (use_eab == "OFF"))
6350            if (lpm_showahead == "ON")
6351                i_q_tmp <= mem_data[0];
6352            else
6353                i_q_tmp <= 0;
6354    end // @(posedge aclr)
6355
6356    // FIFOram
6357    always @(posedge wrclk)
6358    begin
6359        if (aclr && (!(dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
6360        dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) ||
6361        (use_eab == "OFF")))
6362        begin
6363            i_data_tmp <= 0;
6364            i_wrptr_tmp <= 0;
6365            i_wren_tmp <= 0;
6366        end
6367        else if (wrclk && ($time > 0))
6368        begin
6369            i_data_tmp <= data;
6370            i_wrptr_tmp <= i_wrptr;
6371            i_wren_tmp <= w_wren;
6372
6373            if (w_wren)
6374            begin
6375                if (~aclr && ((i_wrptr < (1<<lpm_widthu)-1) || (i_overflow_checking == "OFF")))
6376                    i_wrptr <= i_wrptr + 1;
6377                else
6378                    i_wrptr <= 0;
6379
6380                if (use_eab == "OFF")
6381                begin
6382                    mem_data[i_wrptr] <= data;
6383
6384                    if (lpm_showahead == "ON")
6385                        i_showahead_flag1 <= 1'b1;
6386                end
6387            end
6388        end
6389    end // @(posedge wrclk)
6390
6391    always @(negedge wrclk)
6392    begin
6393        if ((~wrclk && (use_eab == "ON")) && ($time > 0))
6394        begin
6395            if (i_wren_tmp)
6396            begin
6397                mem_data[i_wrptr_tmp] <= i_data_tmp;
6398            end
6399
6400            if (lpm_showahead == "ON")
6401                    i_showahead_flag1 <= 1'b1;
6402        end
6403    end // @(negedge wrclk)
6404
6405    always @(posedge rdclk)
6406    begin
6407        if (aclr && (!(dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) ||
6408        dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) ||
6409        (use_eab == "OFF")))
6410        begin
6411            if (lpm_showahead == "ON")
6412                i_q_tmp <= mem_data[0];
6413            else
6414                i_q_tmp <= 0;
6415        end
6416        else if (rdclk && w_rden && ($time > 0))
6417        begin
6418            if (~aclr && ((i_rdptr < (1<<lpm_widthu)-1) || (i_underflow_checking == "OFF")))
6419                i_rdptr <= i_rdptr + 1;
6420            else
6421                i_rdptr <= 0;
6422
6423            if (lpm_showahead == "ON")
6424                i_showahead_flag1 <= 1'b1;
6425            else
6426                i_q_tmp <= mem_data[i_rdptr];
6427        end
6428    end // @(rdclk)
6429
6430    always @(posedge i_showahead_flag)
6431    begin
6432        i_q_tmp <= mem_data[i_rdptr];
6433        i_showahead_flag1 <= 1'b0;
6434    end // @(posedge i_showahead_flag)
6435
6436    always @(i_showahead_flag1)
6437    begin
6438        i_showahead_flag <= i_showahead_flag1;
6439    end // @(i_showahead_flag1)
6440
6441    // Delays & DFF Pipes
6442    always @(negedge rdclk)
6443    begin
6444        i_rdenclock <= 0;
6445    end // @(negedge rdclk)
6446
6447    always @(posedge rdclk)
6448    begin
6449        if (w_rden)
6450            i_rdenclock <= 1;
6451    end // @(posedge rdclk)
6452
6453    always @(i_wrptr or w_ws_dbrp)
6454    begin
6455        i_wr_udwn <= i_wrptr - w_ws_dbrp;
6456    end // @(i_wrptr or w_ws_dbrp)
6457
6458    always @(i_rdptr or w_rs_dbwp)
6459    begin
6460        i_rd_udwn <= w_rs_dbwp - i_rdptr;
6461    end // @(i_rdptr or w_rs_dbwp)
6462
6463// CONTINOUS ASSIGNMENT
6464    assign w_rden = (i_underflow_checking == "OFF") ? rdreq : rdreq && !w_rdempty;
6465    assign w_wren = (i_overflow_checking == "OFF")  ? wrreq : wrreq && !w_wrfull;
6466    assign q = i_q_tmp;
6467    assign wrfull = w_wrfull;
6468    assign rdfull = w_rdfull;
6469    assign wrempty = w_wrempty;
6470    assign rdempty = w_rdempty;
6471    assign wrusedw = w_wrusedw;
6472    assign rdusedw = w_rdusedw;
6473
6474endmodule // lpm_fifo_dc_async
6475// END OF MODULE
6476
6477
6478//START_MODULE_NAME------------------------------------------------------------
6479//
6480// Module Name     :  lpm_fifo_dc
6481//
6482// Description     :
6483//
6484// Limitation      :
6485//
6486// Results expected:
6487//
6488//END_MODULE_NAME--------------------------------------------------------------
6489
6490// BEGINNING OF MODULE
6491`timescale 1 ps / 1 ps
6492
6493// MODULE DECLARATION
6494module lpm_fifo_dc (data,
6495                    rdclock,
6496                    wrclock,
6497                    aclr,
6498                    rdreq,
6499                    wrreq,
6500                    rdfull,
6501                    wrfull,
6502                    rdempty,
6503                    wrempty,
6504                    rdusedw,
6505                    wrusedw,
6506                    q);
6507
6508// GLOBAL PARAMETER DECLARATION
6509    parameter lpm_width = 1;
6510    parameter lpm_widthu = 1;
6511    parameter lpm_numwords = 2;
6512    parameter lpm_showahead = "OFF";
6513    parameter underflow_checking = "ON";
6514    parameter overflow_checking = "ON";
6515    parameter lpm_hint = "";
6516    parameter lpm_type = "lpm_fifo_dc";
6517
6518// LOCAL PARAMETER DECLARATION
6519    parameter delay_rdusedw = 1;
6520    parameter delay_wrusedw = 1;
6521    parameter rdsync_delaypipe = 3;
6522    parameter wrsync_delaypipe = 3;
6523
6524// INPUT PORT DECLARATION
6525    input [lpm_width-1:0] data;
6526    input rdclock;
6527    input wrclock;
6528    input aclr;
6529    input rdreq;
6530    input wrreq;
6531
6532// OUTPUT PORT DECLARATION
6533    output rdfull;
6534    output wrfull;
6535    output rdempty;
6536    output wrempty;
6537    output [lpm_widthu-1:0] rdusedw;
6538    output [lpm_widthu-1:0] wrusedw;
6539    output [lpm_width-1:0] q;
6540
6541// internal reg
6542    wire w_rdfull_s;
6543    wire w_wrfull_s;
6544    wire w_rdempty_s;
6545    wire w_wrempty_s;
6546    wire w_rdfull_a;
6547    wire w_wrfull_a;
6548    wire w_rdempty_a;
6549    wire w_wrempty_a;
6550    wire [lpm_widthu-1:0] w_rdusedw_s;
6551    wire [lpm_widthu-1:0] w_wrusedw_s;
6552    wire [lpm_widthu-1:0] w_rdusedw_a;
6553    wire [lpm_widthu-1:0] w_wrusedw_a;
6554    wire [lpm_width-1:0] w_q_s;
6555    wire [lpm_width-1:0] w_q_a;
6556    wire i_aclr;
6557
6558// INTERNAL TRI DECLARATION
6559    tri0 aclr;
6560    buf (i_aclr, aclr);
6561
6562// COMPONENT INSTANTIATIONS
6563    lpm_fifo_dc_async ASYNC (
6564        .data (data),
6565        .rdclk (rdclock),
6566        .wrclk (wrclock),
6567        .aclr (i_aclr),
6568        .rdreq (rdreq),
6569        .wrreq (wrreq),
6570        .rdfull (w_rdfull_a),
6571        .wrfull (w_wrfull_a),
6572        .rdempty (w_rdempty_a),
6573        .wrempty (w_wrempty_a),
6574        .rdusedw (w_rdusedw_a),
6575        .wrusedw (w_wrusedw_a),
6576        .q (w_q_a) );
6577    defparam
6578        ASYNC.lpm_width = lpm_width,
6579        ASYNC.lpm_widthu = lpm_widthu,
6580        ASYNC.lpm_numwords = lpm_numwords,
6581        ASYNC.delay_rdusedw = delay_rdusedw,
6582        ASYNC.delay_wrusedw = delay_wrusedw,
6583        ASYNC.rdsync_delaypipe = rdsync_delaypipe,
6584        ASYNC.wrsync_delaypipe = wrsync_delaypipe,
6585        ASYNC.lpm_showahead = lpm_showahead,
6586        ASYNC.underflow_checking = underflow_checking,
6587        ASYNC.overflow_checking = overflow_checking,
6588        ASYNC.lpm_hint = lpm_hint;
6589
6590// CONTINOUS ASSIGNMENT
6591    assign rdfull =  w_rdfull_a;
6592    assign wrfull =  w_wrfull_a;
6593    assign rdempty = w_rdempty_a;
6594    assign wrempty = w_wrempty_a;
6595    assign rdusedw = w_rdusedw_a;
6596    assign wrusedw = w_wrusedw_a;
6597    assign q = w_q_a;
6598endmodule // lpm_fifo_dc
6599// END OF MODULE
6600
6601//START_MODULE_NAME------------------------------------------------------------
6602//
6603// Module Name     :  lpm_inpad
6604//
6605// Description     :
6606//
6607// Limitation      :  n/a
6608//
6609// Results expected:
6610//
6611//END_MODULE_NAME--------------------------------------------------------------
6612
6613// BEGINNING OF MODULE
6614`timescale 1 ps / 1 ps
6615
6616// MODULE DECLARATION
6617module lpm_inpad (
6618    pad,
6619    result
6620);
6621
6622// GLOBAL PARAMETER DECLARATION
6623    parameter lpm_width = 1;
6624    parameter lpm_type = "lpm_inpad";
6625    parameter lpm_hint = "UNUSED";
6626
6627// INPUT PORT DECLARATION
6628    input  [lpm_width-1:0] pad;
6629
6630// OUTPUT PORT DECLARATION
6631    output [lpm_width-1:0] result;
6632
6633// INTERNAL REGISTER/SIGNAL DECLARATION
6634    reg    [lpm_width-1:0] result;
6635
6636// INITIAL CONSTRUCT BLOCK
6637    initial
6638    begin
6639        if (lpm_width <= 0)
6640        begin
6641            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
6642            $display("Time: %0t  Instance: %m", $time);
6643            $finish;
6644        end
6645    end
6646
6647// ALWAYS CONSTRUCT BLOCK
6648    always @(pad)
6649    begin
6650        result = pad;
6651    end
6652
6653endmodule // lpm_inpad
6654// END OF MODULE
6655
6656
6657//START_MODULE_NAME------------------------------------------------------------
6658//
6659// Module Name     :  lpm_outpad
6660//
6661// Description     :
6662//
6663// Limitation      :  n/a
6664//
6665// Results expected:
6666//
6667//END_MODULE_NAME--------------------------------------------------------------
6668
6669// BEGINNING OF MODULE
6670`timescale 1 ps / 1 ps
6671
6672// MODULE DECLARATION
6673module lpm_outpad (
6674    data,
6675    pad
6676);
6677
6678// GLOBAL PARAMETER DECLARATION
6679    parameter lpm_width = 1;
6680    parameter lpm_type = "lpm_outpad";
6681    parameter lpm_hint = "UNUSED";
6682
6683// INPUT PORT DECLARATION
6684    input  [lpm_width-1:0] data;
6685
6686// OUTPUT PORT DECLARATION
6687    output [lpm_width-1:0] pad;
6688
6689// INTERNAL REGISTER/SIGNAL DECLARATION
6690    reg    [lpm_width-1:0] pad;
6691
6692// INITIAL CONSTRUCT BLOCK
6693    initial
6694    begin
6695        if (lpm_width <= 0)
6696        begin
6697            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
6698            $display("Time: %0t  Instance: %m", $time);
6699            $finish;
6700        end
6701    end
6702
6703// ALWAYS CONSTRUCT BLOCK
6704    always @(data)
6705    begin
6706        pad = data;
6707    end
6708
6709endmodule // lpm_outpad
6710// END OF MODULE
6711
6712
6713//START_MODULE_NAME------------------------------------------------------------
6714//
6715// Module Name     :  lpm_bipad
6716//
6717// Description     :
6718//
6719// Limitation      :  n/a
6720//
6721// Results expected:
6722//
6723//END_MODULE_NAME--------------------------------------------------------------
6724
6725// BEGINNING OF MODULE
6726`timescale 1 ps / 1 ps
6727
6728// MODULE DECLARATION
6729module lpm_bipad (
6730    data,
6731    enable,
6732    result,
6733    pad
6734);
6735
6736// GLOBAL PARAMETER DECLARATION
6737    parameter lpm_width = 1;
6738    parameter lpm_type = "lpm_bipad";
6739    parameter lpm_hint = "UNUSED";
6740
6741// INPUT PORT DECLARATION
6742    input  [lpm_width-1:0] data;
6743    input  enable;
6744
6745// OUTPUT PORT DECLARATION
6746    output [lpm_width-1:0] result;
6747
6748// INPUT/OUTPUT PORT DECLARATION
6749    inout  [lpm_width-1:0] pad;
6750
6751// INTERNAL REGISTER/SIGNAL DECLARATION
6752    reg    [lpm_width-1:0] result;
6753
6754// INITIAL CONSTRUCT BLOCK
6755    initial
6756    begin
6757        if (lpm_width <= 0)
6758        begin
6759            $display("Value of lpm_width parameter must be greater than 0(ERROR)");
6760            $display("Time: %0t  Instance: %m", $time);
6761            $finish;
6762        end
6763    end
6764
6765// ALWAYS CONSTRUCT BLOCK
6766    always @(data or pad or enable)
6767    begin
6768        if (enable == 1)
6769        begin
6770            result = {lpm_width{1'bz}};
6771        end
6772        else if (enable == 0)
6773        begin
6774            result = pad;
6775        end
6776    end
6777
6778// CONTINOUS ASSIGNMENT
6779    assign pad = (enable == 1) ? data : {lpm_width{1'bz}};
6780
6781endmodule // lpm_bipad
6782// END OF MODULE
6783