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