//------------------------------------------------------------------------- // This Verilog file was developed by Altera Corporation. It may be // freely copied and/or distributed at no cost. Any persons using this // file for any purpose do so at their own risk, and are responsible for // the results of such use. Altera Corporation does not guarantee that // this file is complete, correct, or fit for any particular purpose. // NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. This notice must // accompany any copy of this file. //------------------------------------------------------------------------ // // Quartus Prime 16.1.0 Build 196 10/24/2016 // //------------------------------------------------------------------------ // LPM Synthesizable Models (Support string type generic) // These models are based on LPM version 220 (EIA-IS103 October 1998). //------------------------------------------------------------------------ // //----------------------------------------------------------------------------- // Assumptions: // // 1. The default value for LPM_SVALUE, LPM_AVALUE, LPM_PVALUE, and // LPM_STRENGTH is string UNUSED. // //----------------------------------------------------------------------------- // Verilog Language Issues: // // Two dimensional ports are not supported. Modules with two dimensional // ports are implemented as one dimensional signal of (LPM_SIZE * LPM_WIDTH) // bits wide. // //----------------------------------------------------------------------------- //START_MODULE_NAME------------------------------------------------------------ // // Module Name : LPM_MEMORY_INITIALIZATION // // Description : Common function to read intel-hex format data file with // extension .hex and creates the equivalent verilog format // data file with extension .ver. // // Limitation : Supports only record type '00'(data record), '01'(end of // file record) and '02'(extended segment address record). // // Results expected: Creates the verilog format data file with extension .ver // and return the name of the file. // //END_MODULE_NAME-------------------------------------------------------------- //See also: https://github.com/twosigma/verilator_support // verilator lint_off COMBDLY // verilator lint_off INITIALDLY // verilator lint_off MULTIDRIVEN // verilator lint_off UNSIGNED // verilator lint_off WIDTH // BEGINNING OF MODULE `timescale 1 ps / 1 ps `define LPM_TRUE 1 `define LPM_FALSE 0 `define LPM_NULL 0 `define LPM_EOF -1 `define LPM_MAX_NAME_SZ 128 `define LPM_MAX_WIDTH 256 `define LPM_COLON ":" `define LPM_DOT "." `define LPM_NEWLINE "\n" `define LPM_CARRIAGE_RETURN 8'h0D `define LPM_SPACE " " `define LPM_TAB "\t" `define LPM_OPEN_BRACKET "[" `define LPM_CLOSE_BRACKET "]" `define LPM_OFFSET 9 `define LPM_H10 8'h10 `define LPM_H10000 20'h10000 `define LPM_AWORD 8 `define LPM_MASK15 32'h000000FF `define LPM_EXT_STR "ver" `define LPM_PERCENT "%" `define LPM_MINUS "-" `define LPM_SEMICOLON ";" `define LPM_EQUAL "=" // MODULE DECLARATION module LPM_MEMORY_INITIALIZATION; /****************************************************************/ /* convert uppercase character values to lowercase. */ /****************************************************************/ function [8:1] tolower; input [8:1] given_character; reg [8:1] conv_char; begin if ((given_character >= 65) && (given_character <= 90)) // ASCII number of 'A' is 65, 'Z' is 90 begin conv_char = given_character + 32; // 32 is the difference in the position of 'A' and 'a' in the ASCII char set tolower = conv_char; end else tolower = given_character; end endfunction /****************************************************************/ /* Read in Altera-mif format data to verilog format data. */ /****************************************************************/ task convert_mif2ver; input[`LPM_MAX_NAME_SZ*8 : 1] in_file; input width; output [`LPM_MAX_NAME_SZ*8 : 1] out_file; reg [`LPM_MAX_NAME_SZ*8 : 1] in_file; reg [`LPM_MAX_NAME_SZ*8 : 1] out_file; reg [`LPM_MAX_NAME_SZ*8 : 1] buffer; reg [`LPM_MAX_WIDTH : 0] memory_data1, memory_data2; reg [8 : 1] c; reg [3 : 0] hex, tmp_char; reg [24 : 1] address_radix, data_radix; reg get_width; reg get_depth; reg get_data_radix; reg get_address_radix; reg width_found; reg depth_found; reg data_radix_found; reg address_radix_found; reg get_address_data_pairs; reg get_address; reg get_data; reg display_address; reg invalid_address; reg get_start_address; reg get_end_address; reg done; reg error_status; reg first_rec; reg last_rec; integer width; integer memory_width, memory_depth; integer value; integer ifp, ofp, r, r2; integer i, j, k, m, n; integer off_addr, nn, address, tt, cc, aah, aal, dd, sum ; integer start_address, end_address; integer line_no; integer character_count; integer comment_with_percent_found; integer comment_with_double_minus_found; begin done = `LPM_FALSE; error_status = `LPM_FALSE; first_rec = `LPM_FALSE; last_rec = `LPM_FALSE; comment_with_percent_found = `LPM_FALSE; comment_with_double_minus_found = `LPM_FALSE; off_addr= 0; nn= 0; address = 0; start_address = 0; end_address = 0; tt= 0; cc= 0; aah= 0; aal= 0; dd= 0; sum = 0; line_no = 1; c = 0; hex = 0; value = 0; buffer = ""; character_count = 0; memory_width = 0; memory_depth = 0; memory_data1 = {(`LPM_MAX_WIDTH+1) {1'b0}}; memory_data2 = {(`LPM_MAX_WIDTH+1) {1'b0}}; address_radix = "hex"; data_radix = "hex"; get_width = `LPM_FALSE; get_depth = `LPM_FALSE; get_data_radix = `LPM_FALSE; get_address_radix = `LPM_FALSE; width_found = `LPM_FALSE; depth_found = `LPM_FALSE; data_radix_found = `LPM_FALSE; address_radix_found = `LPM_FALSE; get_address_data_pairs = `LPM_FALSE; display_address = `LPM_FALSE; invalid_address = `LPM_FALSE; get_start_address = `LPM_FALSE; get_end_address = `LPM_FALSE; if((in_file[4*8 : 1] == ".dat") || (in_file[4*8 : 1] == ".DAT")) out_file = in_file; else begin ifp = $fopen(in_file, "r"); if (ifp == `LPM_NULL) begin $display("ERROR: cannot read %0s.", in_file); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end out_file = in_file; if((out_file[4*8 : 1] == ".mif") || (out_file[4*8 : 1] == ".MIF")) out_file[3*8 : 1] = `LPM_EXT_STR; else begin $display("ERROR: Invalid input file name %0s. Expecting file with .mif extension and Altera-mif data format.", in_file); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end if (!done) begin ofp = $fopen(out_file, "w"); if (ofp == `LPM_NULL) begin $display("ERROR : cannot write %0s.", out_file); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end end while((!done) && (!error_status)) begin : READER r = $fgetc(ifp); if (r == `LPM_EOF) begin // to do : add more checking on whether a particular assigment(width, depth, memory/address) are mising if(!first_rec) begin error_status = `LPM_TRUE; $display("WARNING: %0s, Intel-hex data file is empty.", in_file); $display ("Time: %0t Instance: %m", $time); end else if (!get_address_data_pairs) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Missing `content begin` statement.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end else if(!last_rec) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Missing `end` statement.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end done = `LPM_TRUE; end else if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN)) begin if ((buffer == "contentbegin") && (get_address_data_pairs == `LPM_FALSE)) begin get_address_data_pairs = `LPM_TRUE; get_address = `LPM_TRUE; buffer = ""; end else if (buffer == "content") begin // continue to next character end else if (buffer != "") begin // found invalid syntax in the particular line. error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); disable READER; end line_no = line_no +1; end else if ((r == `LPM_SPACE) || (r == `LPM_TAB)) begin // continue to next character; end else if (r == `LPM_PERCENT) begin // Ignore all the characters which which is part of comment. r = $fgetc(ifp); while ((r != `LPM_PERCENT) && (r != `LPM_NEWLINE) && (r != `LPM_CARRIAGE_RETURN)) begin r = $fgetc(ifp); end if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN)) begin line_no = line_no +1; if ((buffer == "contentbegin") && (get_address_data_pairs == `LPM_FALSE)) begin get_address_data_pairs = `LPM_TRUE; get_address = `LPM_TRUE; buffer = ""; end end end else if (r == `LPM_MINUS) begin r = $fgetc(ifp); if (r == `LPM_MINUS) begin // Ignore all the characters which which is part of comment. r = $fgetc(ifp); while ((r != `LPM_NEWLINE) && (r != `LPM_CARRIAGE_RETURN)) begin r = $fgetc(ifp); end if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN)) begin line_no = line_no +1; if ((buffer == "contentbegin") && (get_address_data_pairs == `LPM_FALSE)) begin get_address_data_pairs = `LPM_TRUE; get_address = `LPM_TRUE; buffer = ""; end end end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end else if (r == `LPM_EQUAL) begin if (buffer == "width") begin if (width_found == `LPM_FALSE) begin get_width = `LPM_TRUE; buffer = ""; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Width has already been specified once.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end end else if (buffer == "depth") begin get_depth = `LPM_TRUE; buffer = ""; end else if (buffer == "data_radix") begin get_data_radix = `LPM_TRUE; buffer = ""; end else if (buffer == "address_radix") begin get_address_radix = `LPM_TRUE; buffer = ""; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Unknown setting (%0s).", in_file, line_no, buffer); $display("Time: %0t Instance: %m", $time); end end else if (r == `LPM_COLON) begin if (!get_address_data_pairs) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Missing `content begin` statement.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end else if (invalid_address == `LPM_TRUE) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end begin get_address = `LPM_FALSE; get_data = `LPM_TRUE; display_address = `LPM_TRUE; end end else if (r == `LPM_DOT) begin r = $fgetc(ifp); if (r == `LPM_DOT) begin if (get_start_address == `LPM_TRUE) begin start_address = address; address = 0; get_start_address = `LPM_FALSE; get_end_address = `LPM_TRUE; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end else if (r == `LPM_OPEN_BRACKET) begin get_start_address = `LPM_TRUE; end else if (r == `LPM_CLOSE_BRACKET) begin if (get_end_address == `LPM_TRUE) begin end_address = address; address = 0; get_end_address = `LPM_FALSE; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid Altera-mif record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end else if (r == `LPM_SEMICOLON) begin if (get_width == `LPM_TRUE) begin width_found = `LPM_TRUE; memory_width = value; value = 0; get_width = `LPM_FALSE; end else if (get_depth == `LPM_TRUE) begin depth_found = `LPM_TRUE; memory_depth = value; value = 0; get_depth = `LPM_FALSE; end else if (get_data_radix == `LPM_TRUE) begin data_radix_found = `LPM_TRUE; get_data_radix = `LPM_FALSE; if ((buffer == "bin") || (buffer == "oct") || (buffer == "dec") || (buffer == "uns") || (buffer == "hex")) begin data_radix = buffer[24 : 1]; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid assignment (%0s) to data_radix.", in_file, line_no, buffer); $display("Time: %0t Instance: %m", $time); end buffer = ""; end else if (get_address_radix == `LPM_TRUE) begin address_radix_found = `LPM_TRUE; get_address_radix = `LPM_FALSE; if ((buffer == "bin") || (buffer == "oct") || (buffer == "dec") || (buffer == "uns") || (buffer == "hex")) begin address_radix = buffer[24 : 1]; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid assignment (%0s) to address radix.", in_file, line_no, buffer); $display("Time: %0t Instance: %m", $time); end buffer = ""; end else if (buffer == "end") begin if (get_address_data_pairs == `LPM_TRUE) begin last_rec = `LPM_TRUE; buffer = ""; end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Missing `content begin` statement.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end end else if (get_data == `LPM_TRUE) begin get_address = `LPM_TRUE; get_data = `LPM_FALSE; buffer = ""; character_count = 0; if (start_address != end_address) begin for (address = start_address; address <= end_address; address = address+1) begin $fdisplay(ofp,"@%0h", address); for (i = memory_width -1; i >= 0; i = i-1 ) begin hex[(i % 4)] = memory_data1[i]; if ((i % 4) == 0) begin $fwrite(ofp, "%0h", hex); hex = 0; end end $fwrite(ofp, "\n"); end start_address = 0; end_address = 0; address = 0; hex = 0; memory_data1 = {(`LPM_MAX_WIDTH+1) {1'b0}}; end else begin if (display_address == `LPM_TRUE) begin $fdisplay(ofp,"@%0h", address); display_address = `LPM_FALSE; end for (i = memory_width -1; i >= 0; i = i-1 ) begin hex[(i % 4)] = memory_data1[i]; if ((i % 4) == 0) begin $fwrite(ofp, "%0h", hex); hex = 0; end end $fwrite(ofp, "\n"); address = 0; hex = 0; memory_data1 = {(`LPM_MAX_WIDTH+1) {1'b0}}; end end else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid assigment.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end end else if ((get_width == `LPM_TRUE) || (get_depth == `LPM_TRUE)) begin if ((r >= "0") && (r <= "9")) value = (value * 10) + (r - 'h30); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid assignment to width/depth.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end end else if (get_address == `LPM_TRUE) begin if (address_radix == "hex") begin if ((r >= "0") && (r <= "9")) value = (r - 'h30); else if ((r >= "A") && (r <= "F")) value = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) value = 10 + (r - 'h61); else begin invalid_address = `LPM_TRUE; end address = (address * 16) + value; end else if ((address_radix == "dec")) begin if ((r >= "0") && (r <= "9")) value = (r - 'h30); else begin invalid_address = `LPM_TRUE; end address = (address * 10) + value; end else if (address_radix == "uns") begin if ((r >= "0") && (r <= "9")) value = (r - 'h30); else begin invalid_address = `LPM_TRUE; end address = (address * 10) + value; end else if (address_radix == "bin") begin if ((r >= "0") && (r <= "1")) value = (r - 'h30); else begin invalid_address = `LPM_TRUE; end address = (address * 2) + value; end else if (address_radix == "oct") begin if ((r >= "0") && (r <= "7")) value = (r - 'h30); else begin invalid_address = `LPM_TRUE; end address = (address * 8) + value; end if ((r >= 65) && (r <= 90)) c = tolower(r); else c = r; {tmp_char,buffer} = {buffer, c}; end else if (get_data == `LPM_TRUE) begin character_count = character_count +1; if (data_radix == "hex") begin if ((r >= "0") && (r <= "9")) value = (r - 'h30); else if ((r >= "A") && (r <= "F")) value = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) value = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end memory_data1 = (memory_data1 * 16) + value; end else if ((data_radix == "dec")) begin if ((r >= "0") && (r <= "9")) value = (r - 'h30); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end memory_data1 = (memory_data1 * 10) + value; end else if (data_radix == "uns") begin if ((r >= "0") && (r <= "9")) value = (r - 'h30); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end memory_data1 = (memory_data1 * 10) + value; end else if (data_radix == "bin") begin if ((r >= "0") && (r <= "1")) value = (r - 'h30); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end memory_data1 = (memory_data1 * 2) + value; end else if (data_radix == "oct") begin if ((r >= "0") && (r <= "7")) value = (r - 'h30); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end memory_data1 = (memory_data1 * 8) + value; end end else begin first_rec = `LPM_TRUE; if ((r >= 65) && (r <= 90)) c = tolower(r); else c = r; {tmp_char,buffer} = {buffer, c}; end end $fclose(ifp); $fclose(ofp); end end endtask // convert_mif2ver /****************************************************************/ /* Read in Intel-hex format data to verilog format data. */ /* Intel-hex format :nnaaaaattddddcc */ /****************************************************************/ task convert_hex2ver; input[`LPM_MAX_NAME_SZ*8 : 1] in_file; input width; output [`LPM_MAX_NAME_SZ*8 : 1] out_file; reg [`LPM_MAX_NAME_SZ*8 : 1] in_file; reg [`LPM_MAX_NAME_SZ*8 : 1] out_file; reg [8:1] c; reg [3:0] hex, tmp_char; reg done; reg error_status; reg first_rec; reg last_rec; integer width; integer ifp, ofp, r, r2; integer i, j, k, m, n; integer off_addr, nn, aaaa, tt, cc, aah, aal, dd, sum ; integer line_no; begin done = `LPM_FALSE; error_status = `LPM_FALSE; first_rec = `LPM_FALSE; last_rec = `LPM_FALSE; off_addr= 0; nn= 0; aaaa= 0; tt= 0; cc= 0; aah= 0; aal= 0; dd= 0; sum = 0; line_no = 1; c = 0; hex = 0; if((in_file[4*8 : 1] == ".dat") || (in_file[4*8 : 1] == ".DAT")) out_file = in_file; else begin ifp = $fopen(in_file, "r"); if (ifp == `LPM_NULL) begin $display("ERROR: cannot read %0s.", in_file); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end out_file = in_file; if((out_file[4*8 : 1] == ".hex") || (out_file[4*8 : 1] == ".HEX")) out_file[3*8 : 1] = `LPM_EXT_STR; else begin $display("ERROR: Invalid input file name %0s. Expecting file with .hex extension and Intel-hex data format.", in_file); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end if (!done) begin ofp = $fopen(out_file, "w"); if (ofp == `LPM_NULL) begin $display("ERROR : cannot write %0s.", out_file); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end end while((!done) && (!error_status)) begin : READER r = $fgetc(ifp); if (r == `LPM_EOF) begin if(!first_rec) begin error_status = `LPM_TRUE; $display("WARNING: %0s, Intel-hex data file is empty.", in_file); $display ("Time: %0t Instance: %m", $time); end else if(!last_rec) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Missing the last record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end end else if (r == `LPM_COLON) begin first_rec = `LPM_TRUE; nn= 0; aaaa= 0; tt= 0; cc= 0; aah= 0; aal= 0; dd= 0; sum = 0; // get record length bytes for (i = 0; i < 2; i = i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) nn = (nn * 16) + (r - 'h30); else if ((r >= "A") && (r <= "F")) nn = (nn * 16) + 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) nn = (nn * 16) + 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end // get address bytes for (i = 0; i < 4; i = i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) hex = (r - 'h30); else if ((r >= "A") && (r <= "F")) hex = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) hex = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end aaaa = (aaaa * 16) + hex; if (i < 2) aal = (aal * 16) + hex; else aah = (aah * 16) + hex; end // get record type bytes for (i = 0; i < 2; i = i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) tt = (tt * 16) + (r - 'h30); else if ((r >= "A") && (r <= "F")) tt = (tt * 16) + 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) tt = (tt * 16) + 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end if((tt == 2) && (nn != 2) ) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid data record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end else begin // get the sum of all the bytes for record length, address and record types sum = nn + aah + aal + tt ; // check the record type case(tt) // normal_record 8'h00 : begin first_rec = `LPM_TRUE; i = 0; k = width / `LPM_AWORD; if ((width % `LPM_AWORD) != 0) k = k + 1; // k = no. of bytes per entry. while (i < nn) begin $fdisplay(ofp,"@%0h", (aaaa + off_addr)); for (j = 1; j <= k; j = j +1) begin if ((k - j +1) > nn) begin for(m = 1; m <= 2; m= m+1) begin if((((k-j)*8) + ((3-m)*4) - width) < 4) $fwrite(ofp, "0"); end end else begin // get the data bytes for(m = 1; m <= 2; m= m+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) hex = (r - 'h30); else if ((r >= "A") && (r <= "F")) hex = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) hex = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end if((((k-j)*8) + ((3-m)*4) - width) < 4) $fwrite(ofp, "%h", hex); dd = (dd * 16) + hex; if(m % 2 == 0) begin sum = sum + dd; dd = 0; end end end end $fwrite(ofp, "\n"); i = i + k; aaaa = aaaa + 1; end // end of while (i < nn) end // last record 8'h01: begin last_rec = `LPM_TRUE; done = `LPM_TRUE; end // address base record 8'h02: begin off_addr= 0; // get the extended segment address record for(i = 1; i <= (nn*2); i= i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) hex = (r - 'h30); else if ((r >= "A") && (r <= "F")) hex = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) hex = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end off_addr = (off_addr * `LPM_H10) + hex; dd = (dd * 16) + hex; if(i % 2 == 0) begin sum = sum + dd; dd = 0; end end off_addr = off_addr * `LPM_H10; end // address base record 8'h03: // get the start segment address record for(i = 1; i <= (nn*2); i= i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) hex = (r - 'h30); else if ((r >= "A") && (r <= "F")) hex = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) hex = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end dd = (dd * 16) + hex; if(i % 2 == 0) begin sum = sum + dd; dd = 0; end end // address base record 8'h04: begin off_addr= 0; // get the extended linear address record for(i = 1; i <= (nn*2); i= i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) hex = (r - 'h30); else if ((r >= "A") && (r <= "F")) hex = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) hex = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end off_addr = (off_addr * `LPM_H10) + hex; dd = (dd * 16) + hex; if(i % 2 == 0) begin sum = sum + dd; dd = 0; end end off_addr = off_addr * `LPM_H10000; end // address base record 8'h05: // get the start linear address record for(i = 1; i <= (nn*2); i= i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) hex = (r - 'h30); else if ((r >= "A") && (r <= "F")) hex = 10 + (r - 'h41); else if ((r >= "a") && (r <= "f")) hex = 10 + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end dd = (dd * 16) + hex; if(i % 2 == 0) begin sum = sum + dd; dd = 0; end end default: begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Unknown record type.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end endcase // get the checksum bytes for (i = 0; i < 2; i = i+1) begin r = $fgetc(ifp); if ((r >= "0") && (r <= "9")) cc = (cc * 16) + (r - 'h30); else if ((r >= "A") && (r <= "F")) cc = 10 + (cc * 16) + (r - 'h41); else if ((r >= "a") && (r <= "f")) cc = 10 + (cc * 16) + (r - 'h61); else begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; disable READER; end end // Perform check sum. if(((~sum+1)& `LPM_MASK15) != cc) begin error_status = `LPM_TRUE; $display("ERROR: %0s, line %0d, Invalid checksum.", in_file, line_no); $display("Time: %0t Instance: %m", $time); end end end else if ((r == `LPM_NEWLINE) || (r == `LPM_CARRIAGE_RETURN)) begin line_no = line_no +1; end else if (r == `LPM_SPACE) begin // continue to next character; end else begin error_status = `LPM_TRUE; $display("ERROR:%0s, line %0d, Invalid INTEL HEX record.", in_file, line_no); $display("Time: %0t Instance: %m", $time); done = `LPM_TRUE; end end $fclose(ifp); $fclose(ofp); end end endtask // convert_hex2ver task convert_to_ver_file; input[`LPM_MAX_NAME_SZ*8 : 1] in_file; input width; output [`LPM_MAX_NAME_SZ*8 : 1] out_file; reg [`LPM_MAX_NAME_SZ*8 : 1] in_file; reg [`LPM_MAX_NAME_SZ*8 : 1] out_file; integer width; begin if((in_file[4*8 : 1] == ".hex") || (in_file[4*8 : 1] == ".HEX") || (in_file[4*8 : 1] == ".dat") || (in_file[4*8 : 1] == ".DAT")) convert_hex2ver(in_file, width, out_file); else if((in_file[4*8 : 1] == ".mif") || (in_file[4*8 : 1] == ".MIF")) convert_mif2ver(in_file, width, out_file); else begin $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); $display("Time: %0t Instance: %m", $time); end end endtask // convert_to_ver_file endmodule // LPM_MEMORY_INITIALIZATION //START_MODULE_NAME------------------------------------------------------------ // // Module Name : LPM_HINT_EVALUATION // // Description : Common function to grep the value of altera specific parameters // within the lpm_hint parameter. // // Limitation : No error checking to check whether the content of the lpm_hint // is valid or not. // // Results expected: If the target parameter found, return the value of the parameter. // Otherwise, return empty string. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module LPM_HINT_EVALUATION; // FUNCTON DECLARATION // This function will search through the string (given string) to look for a match for the // a given parameter(compare_param_name). It will return the value for the given parameter. function [8*200:1] GET_PARAMETER_VALUE; input [8*200:1] given_string; // string to be searched input [8*50:1] compare_param_name; // parameter name to be looking for in the given_string. integer param_value_char_count; // to indicate current character count in the param_value integer param_name_char_count; // to indicate current character count in the param_name integer white_space_count; reg extract_param_value; // if 1 mean extracting parameters value from given string reg extract_param_name; // if 1 mean extracting parameters name from given string reg param_found; // to indicate whether compare_param_name have been found in the given_string reg include_white_space; // if 1, include white space in the parameter value reg [8*200:1] reg_string; // to store the value of the given string reg [8*50:1] param_name; // to store parameter name reg [8*20:1] param_value; // to store parameter value reg [8:1] tmp; // to get the value of the current byte begin reg_string = given_string; param_value_char_count = 0; param_name_char_count =0; extract_param_value = 1; extract_param_name = 0; param_found = 0; include_white_space = 0; white_space_count = 0; tmp = reg_string[8:1]; // checking every bytes of the reg_string from right to left. while ((tmp != 0 ) && (param_found != 1)) begin tmp = reg_string[8:1]; //if tmp != ' ' or should include white space (trailing white space are ignored) if((tmp != 32) || (include_white_space == 1)) begin if(tmp == 32) begin white_space_count = 1; end else if(tmp == 61) // if tmp = '=' begin extract_param_value = 0; extract_param_name = 1; // subsequent bytes should be part of param_name include_white_space = 0; // ignore the white space (if any) between param_name and '=' white_space_count = 0; param_value = param_value >> (8 * (20 - param_value_char_count)); param_value_char_count = 0; end else if (tmp == 44) // if tmp = ',' begin extract_param_value = 1; // subsequent bytes should be part of param_value extract_param_name = 0; param_name = param_name >> (8 * (50 - param_name_char_count)); param_name_char_count = 0; if(param_name == compare_param_name) param_found = 1; // the compare_param_name have been found in the reg_string end else begin if(extract_param_value == 1) begin param_value_char_count = param_value_char_count + white_space_count + 1; include_white_space = 1; if(white_space_count > 0) begin param_value = {8'b100000, param_value[20*8:9]}; white_space_count = 0; end param_value = {tmp, param_value[20*8:9]}; end else if(extract_param_name == 1) begin param_name = {tmp, param_name[50*8:9]}; param_name_char_count = param_name_char_count + 1; end end end reg_string = reg_string >> 8; // shift 1 byte to the right end // for the case whether param_name is the left most part of the reg_string if(extract_param_name == 1) begin param_name = param_name >> (8 * (50 - param_name_char_count)); if(param_name == compare_param_name) param_found = 1; end if (param_found == 1) GET_PARAMETER_VALUE = param_value; // return the value of the parameter been looking for else GET_PARAMETER_VALUE = ""; // return empty string if parameter not found end endfunction endmodule // LPM_HINT_EVALUATION // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module LPM_DEVICE_FAMILIES; function IS_FAMILY_CYCLONE; input[8*20:1] device; reg is_cyclone; begin if ((device == "Cyclone") || (device == "CYCLONE") || (device == "cyclone") || (device == "ACEX2K") || (device == "acex2k") || (device == "ACEX 2K") || (device == "acex 2k") || (device == "Tornado") || (device == "TORNADO") || (device == "tornado")) is_cyclone = 1; else is_cyclone = 0; IS_FAMILY_CYCLONE = is_cyclone; end endfunction //IS_FAMILY_CYCLONE function IS_FAMILY_MAX3000A; input[8*20:1] device; reg is_max3000a; begin if ((device == "MAX3000A") || (device == "max3000a") || (device == "MAX 3000A") || (device == "max 3000a")) is_max3000a = 1; else is_max3000a = 0; IS_FAMILY_MAX3000A = is_max3000a; end endfunction //IS_FAMILY_MAX3000A function IS_FAMILY_MAX7000A; input[8*20:1] device; reg is_max7000a; begin if ((device == "MAX7000A") || (device == "max7000a") || (device == "MAX 7000A") || (device == "max 7000a")) is_max7000a = 1; else is_max7000a = 0; IS_FAMILY_MAX7000A = is_max7000a; end endfunction //IS_FAMILY_MAX7000A function IS_FAMILY_MAX7000AE; input[8*20:1] device; reg is_max7000ae; begin if ((device == "MAX7000AE") || (device == "max7000ae") || (device == "MAX 7000AE") || (device == "max 7000ae")) is_max7000ae = 1; else is_max7000ae = 0; IS_FAMILY_MAX7000AE = is_max7000ae; end endfunction //IS_FAMILY_MAX7000AE function IS_FAMILY_MAX7000B; input[8*20:1] device; reg is_max7000b; begin if ((device == "MAX7000B") || (device == "max7000b") || (device == "MAX 7000B") || (device == "max 7000b")) is_max7000b = 1; else is_max7000b = 0; IS_FAMILY_MAX7000B = is_max7000b; end endfunction //IS_FAMILY_MAX7000B function IS_FAMILY_MAX7000S; input[8*20:1] device; reg is_max7000s; begin if ((device == "MAX7000S") || (device == "max7000s") || (device == "MAX 7000S") || (device == "max 7000s")) is_max7000s = 1; else is_max7000s = 0; IS_FAMILY_MAX7000S = is_max7000s; end endfunction //IS_FAMILY_MAX7000S function IS_FAMILY_STRATIXGX; input[8*20:1] device; reg is_stratixgx; begin 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")) is_stratixgx = 1; else is_stratixgx = 0; IS_FAMILY_STRATIXGX = is_stratixgx; end endfunction //IS_FAMILY_STRATIXGX function IS_FAMILY_STRATIX; input[8*20:1] device; reg is_stratix; begin if ((device == "Stratix") || (device == "STRATIX") || (device == "stratix") || (device == "Yeager") || (device == "YEAGER") || (device == "yeager")) is_stratix = 1; else is_stratix = 0; IS_FAMILY_STRATIX = is_stratix; end endfunction //IS_FAMILY_STRATIX function FEATURE_FAMILY_BASE_STRATIX; input[8*20:1] device; reg var_family_base_stratix; begin if (IS_FAMILY_STRATIX(device) || IS_FAMILY_STRATIXGX(device) ) var_family_base_stratix = 1; else var_family_base_stratix = 0; FEATURE_FAMILY_BASE_STRATIX = var_family_base_stratix; end endfunction //FEATURE_FAMILY_BASE_STRATIX function FEATURE_FAMILY_BASE_CYCLONE; input[8*20:1] device; reg var_family_base_cyclone; begin if (IS_FAMILY_CYCLONE(device) ) var_family_base_cyclone = 1; else var_family_base_cyclone = 0; FEATURE_FAMILY_BASE_CYCLONE = var_family_base_cyclone; end endfunction //FEATURE_FAMILY_BASE_CYCLONE function FEATURE_FAMILY_MAX; input[8*20:1] device; reg var_family_max; begin 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") ) var_family_max = 1; else var_family_max = 0; FEATURE_FAMILY_MAX = var_family_max; end endfunction //FEATURE_FAMILY_MAX function IS_VALID_FAMILY; input[8*20:1] device; reg is_valid; begin 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)")) || ((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")) || ((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")) || ((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")) || ((device == "Arria V GZ") || (device == "ARRIA V GZ") || (device == "arria v gz") || (device == "ArriaVGZ") || (device == "ARRIAVGZ") || (device == "arriavgz")) || ((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)")) || ((device == "BS") || (device == "bs")) || ((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")) || ((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")) || ((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")) || ((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")) || ((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")) || ((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)")) || ((device == "Cyclone") || (device == "CYCLONE") || (device == "cyclone") || (device == "ACEX2K") || (device == "acex2k") || (device == "ACEX 2K") || (device == "acex 2k") || (device == "Tornado") || (device == "TORNADO") || (device == "tornado")) || ((device == "HardCopy II") || (device == "HARDCOPY II") || (device == "hardcopy ii") || (device == "HardCopyII") || (device == "HARDCOPYII") || (device == "hardcopyii") || (device == "Fusion") || (device == "FUSION") || (device == "fusion")) || ((device == "HardCopy III") || (device == "HARDCOPY III") || (device == "hardcopy iii") || (device == "HardCopyIII") || (device == "HARDCOPYIII") || (device == "hardcopyiii") || (device == "HCX") || (device == "hcx")) || ((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)")) || ((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)")) || ((device == "MAX II") || (device == "max ii") || (device == "MAXII") || (device == "maxii") || (device == "Tsunami") || (device == "TSUNAMI") || (device == "tsunami")) || ((device == "MAX V") || (device == "max v") || (device == "MAXV") || (device == "maxv") || (device == "Jade") || (device == "JADE") || (device == "jade")) || ((device == "MAX3000A") || (device == "max3000a") || (device == "MAX 3000A") || (device == "max 3000a")) || ((device == "MAX7000A") || (device == "max7000a") || (device == "MAX 7000A") || (device == "max 7000a")) || ((device == "MAX7000AE") || (device == "max7000ae") || (device == "MAX 7000AE") || (device == "max 7000ae")) || ((device == "MAX7000B") || (device == "max7000b") || (device == "MAX 7000B") || (device == "max 7000b")) || ((device == "MAX7000S") || (device == "max7000s") || (device == "MAX 7000S") || (device == "max 7000s")) || ((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)")) || ((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")) || ((device == "Stratix II GX") || (device == "STRATIX II GX") || (device == "stratix ii gx") || (device == "StratixIIGX") || (device == "STRATIXIIGX") || (device == "stratixiigx")) || ((device == "Stratix II") || (device == "STRATIX II") || (device == "stratix ii") || (device == "StratixII") || (device == "STRATIXII") || (device == "stratixii") || (device == "Armstrong") || (device == "ARMSTRONG") || (device == "armstrong")) || ((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")) || ((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)")) || ((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)")) || ((device == "Stratix") || (device == "STRATIX") || (device == "stratix") || (device == "Yeager") || (device == "YEAGER") || (device == "yeager")) || ((device == "eFPGA 28 HPM") || (device == "EFPGA 28 HPM") || (device == "efpga 28 hpm") || (device == "eFPGA28HPM") || (device == "EFPGA28HPM") || (device == "efpga28hpm") || (device == "Bedrock") || (device == "BEDROCK") || (device == "bedrock"))) is_valid = 1; else is_valid = 0; IS_VALID_FAMILY = is_valid; end endfunction // IS_VALID_FAMILY endmodule // LPM_DEVICE_FAMILIES //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_constant // // Description : Parameterized constant generator megafunction. lpm_constant // may be useful for convert a parameter into a constant. // // Limitation : n/a // // Results expected: Value specified by the argument to LPM_CVALUE. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_constant ( result // Value specified by the argument to LPM_CVALUE. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the result[] port. (Required) parameter lpm_cvalue = 0; // Constant value to be driven out on the // result[] port. (Required) parameter lpm_strength = "UNUSED"; parameter lpm_type = "lpm_constant"; parameter lpm_hint = "UNUSED"; // OUTPUT PORT DECLARATION output [lpm_width-1:0] result; // INTERNAL REGISTERS DECLARATION reg[32:0] int_value; // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end int_value = lpm_cvalue; end // CONTINOUS ASSIGNMENT assign result = int_value[lpm_width-1:0]; endmodule // lpm_constant //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_inv // // Description : Parameterized inverter megafunction. // // Limitation : n/a // // Results expected: Inverted value of input data // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_inv ( data, // Data input to the lpm_inv. (Required) result // inverted result. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and result[] ports. (Required) parameter lpm_type = "lpm_inv"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; // OUTPUT PORT DECLARATION output [lpm_width-1:0] result; // INTERNAL REGISTERS DECLARATION reg [lpm_width-1:0] result; // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0 (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end end // ALWAYS CONSTRUCT BLOCK always @(data) result = ~data; endmodule // lpm_inv //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_and // // Description : Parameterized AND gate. This megafunction takes in data inputs // for a number of AND gates. // // Limitation : n/a // // Results expected: Each result[] bit is the result of each AND gate. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_and ( data, // Data input to the AND gate. (Required) result // Result of the AND operators. (Required) ); // GLOBAL PARAMETER DECLARATION // Width of the data[][] and result[] ports. Number of AND gates. (Required) parameter lpm_width = 1; // Number of inputs to each AND gate. Number of input buses. (Required) parameter lpm_size = 1; parameter lpm_type = "lpm_and"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [(lpm_size * lpm_width)-1:0] data; // OUTPUT PORT DECLARATION output [lpm_width-1:0] result; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] result_tmp; // LOCAL INTEGER DECLARATION integer i; integer j; integer k; // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_size <= 0) begin $display("Value of lpm_size parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end end // ALWAYS CONSTRUCT BLOCK always @(data) begin for (i=0; i 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end // CONTINOUS ASSIGNMENT assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : tmp_result; endmodule // lpm_mux // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_decode // // Description : Parameterized decoder megafunction. // // Limitation : n/a // // Results expected: Decoded output. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_decode ( data, // Data input. Treated as an unsigned binary encoded number. (Required) enable, // Enable. All outputs low when not active. clock, // Clock for pipelined usage. aclr, // Asynchronous clear for pipelined usage. clken, // Clock enable for pipelined usage. eq // Decoded output. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] port, or the // input value to be decoded. (Required) parameter lpm_decodes = 1 << lpm_width; // Number of explicit decoder outputs. (Required) parameter lpm_pipeline = 0; // Number of Clock cycles of latency parameter lpm_type = "lpm_decode"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input enable; input clock; input aclr; input clken; // OUTPUT PORT DECLARATION output [lpm_decodes-1:0] eq; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_decodes-1:0] eq_pipe [(lpm_pipeline+1):0]; reg [lpm_decodes-1:0] tmp_eq; // LOCAL INTEGER DECLARATION integer i; integer pipe_ptr; // INTERNAL TRI DECLARATION tri1 enable; tri0 clock; tri0 aclr; tri1 clken; wire i_clock; wire i_clken; wire i_aclr; wire i_enable; buf (i_clock, clock); buf (i_clken, clken); buf (i_aclr, aclr); buf (i_enable, enable); // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0 (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_decodes <= 0) begin $display("Value of lpm_decodes parameter must be greater than 0 (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_decodes > (1 << lpm_width)) begin $display("Value of lpm_decodes parameter must be less or equal to 2^lpm_width (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_pipeline < 0) begin $display("Value of lpm_pipeline parameter must be greater or equal to 0 (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end pipe_ptr = 0; end // ALWAYS CONSTRUCT BLOCK always @(data or i_enable) begin tmp_eq = {lpm_decodes{1'b0}}; if (i_enable) tmp_eq[data] = 1'b1; end always @(posedge i_clock or posedge i_aclr) begin if (i_aclr) begin for (i = 0; i <= lpm_pipeline; i = i + 1) eq_pipe[i] <= {lpm_decodes{1'b0}}; pipe_ptr <= 0; end else if (clken == 1'b1) begin eq_pipe[pipe_ptr] <= tmp_eq; if (lpm_pipeline > 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end assign eq = (lpm_pipeline > 0) ? eq_pipe[pipe_ptr] : tmp_eq; endmodule // lpm_decode // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_clshift // // Description : Parameterized combinatorial logic shifter or barrel shifter // megafunction. // // Limitation : n/a // // Results expected: Return the shifted data and underflow/overflow status bit. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_clshift ( data, // Data to be shifted. (Required) distance, // Number of positions to shift data[] in the direction specified // by the direction port. (Required) direction, // Direction of shift. Low = left (toward the MSB), // high = right (toward the LSB). clock, // Clock for pipelined usage. aclr, // Asynchronous clear for pipelined usage. clken, // Clock enable for pipelined usage. result, // Shifted data. (Required) underflow, // Logical or arithmetic underflow. overflow // Logical or arithmetic overflow. ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and result[] ports. Must be // greater than 0 (Required) parameter lpm_widthdist = 1; // Width of the distance[] input port. (Required) parameter lpm_shifttype = "LOGICAL"; // Type of shifting operation to be performed. parameter lpm_pipeline = 0; // Number of Clock cycles of latency parameter lpm_type = "lpm_clshift"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input [lpm_widthdist-1:0] distance; input direction; input clock; input aclr; input clken; // OUTPUT PORT DECLARATION output [lpm_width-1:0] result; output underflow; output overflow; // INTERNAL REGISTERS DECLARATION reg [lpm_width-1:0] ONES; reg [lpm_width-1:0] ZEROS; reg [lpm_width-1:0] tmp_result; reg tmp_underflow; reg tmp_overflow; reg [lpm_width-1:0] result_pipe [(lpm_pipeline+1):0]; reg [(lpm_pipeline+1):0] overflow_pipe; reg [(lpm_pipeline+1):0] underflow_pipe; // LOCAL INTEGER DECLARATION integer i; integer i1; integer pipe_ptr; // INTERNAL TRI DECLARATION tri0 direction; tri0 clock; tri0 aclr; tri1 clken; wire i_direction; wire i_clock; wire i_clken; wire i_aclr; buf (i_direction, direction); buf (i_clock, clock); buf (i_clken, clken); buf (i_aclr, aclr); // FUNCTON DECLARATION // Perform logival shift operation function [lpm_width+1:0] LogicShift; input [lpm_width-1:0] data; input [lpm_widthdist-1:0] shift_num; input direction; reg [lpm_width-1:0] tmp_buf; reg underflow; reg overflow; begin tmp_buf = data; overflow = 1'b0; underflow = 1'b0; if ((direction) && (shift_num > 0)) // shift right begin tmp_buf = data >> shift_num; if ((data != ZEROS) && ((shift_num >= lpm_width) || (tmp_buf == ZEROS))) underflow = 1'b1; end else if (shift_num > 0) // shift left begin tmp_buf = data << shift_num; if ((data != ZEROS) && ((shift_num >= lpm_width) || ((data >> (lpm_width-shift_num)) != ZEROS))) overflow = 1'b1; end LogicShift = {overflow,underflow,tmp_buf[lpm_width-1:0]}; end endfunction // LogicShift // Perform Arithmetic shift operation function [lpm_width+1:0] ArithShift; input [lpm_width-1:0] data; input [lpm_widthdist-1:0] shift_num; input direction; reg [lpm_width-1:0] tmp_buf; reg underflow; reg overflow; integer i; integer i1; begin tmp_buf = data; overflow = 1'b0; underflow = 1'b0; if (shift_num < lpm_width) begin if ((direction) && (shift_num > 0)) // shift right begin if (data[lpm_width-1] == 1'b0) // positive number begin tmp_buf = data >> shift_num; if ((data != ZEROS) && ((shift_num >= lpm_width) || (tmp_buf == ZEROS))) underflow = 1'b1; end else // negative number begin tmp_buf = (data >> shift_num) | (ONES << (lpm_width - shift_num)); if ((data != ONES) && ((shift_num >= lpm_width-1) || (tmp_buf == ONES))) underflow = 1'b1; end end else if (shift_num > 0) // shift left begin tmp_buf = data << shift_num; for (i=lpm_width-1; i >= lpm_width-shift_num; i=i-1) begin if(data[i-1] != data[lpm_width-1]) overflow = 1'b1; end end end else // shift_num >= lpm_width begin if (direction) begin for (i=0; i < lpm_width; i=i+1) tmp_buf[i] = data[lpm_width-1]; underflow = 1'b1; end else begin tmp_buf = {lpm_width{1'b0}}; if (data != ZEROS) begin overflow = 1'b1; end end end ArithShift = {overflow,underflow,tmp_buf[lpm_width-1:0]}; end endfunction // ArithShift // Perform rotate shift operation function [lpm_width+1:0] RotateShift; input [lpm_width-1:0] data; input [lpm_widthdist-1:0] shift_num; input direction; reg [lpm_width-1:0] tmp_buf; begin tmp_buf = data; if ((direction) && (shift_num > 0)) // shift right tmp_buf = (data >> shift_num) | (data << (lpm_width - shift_num)); else if (shift_num > 0) // shift left tmp_buf = (data << shift_num) | (data >> (lpm_width - shift_num)); RotateShift = {2'bx, tmp_buf[lpm_width-1:0]}; end endfunction // RotateShift // INITIAL CONSTRUCT BLOCK initial begin if ((lpm_shifttype != "LOGICAL") && (lpm_shifttype != "ARITHMETIC") && (lpm_shifttype != "ROTATE") && (lpm_shifttype != "UNUSED")) // non-LPM 220 standard begin $display("Error! LPM_SHIFTTYPE value must be \"LOGICAL\", \"ARITHMETIC\", or \"ROTATE\"."); $display("Time: %0t Instance: %m", $time); end if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_widthdist <= 0) begin $display("Value of lpm_widthdist parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end for (i=0; i < lpm_width; i=i+1) begin ONES[i] = 1'b1; ZEROS[i] = 1'b0; end for (i = 0; i <= lpm_pipeline; i = i + 1) begin result_pipe[i] = ZEROS; overflow_pipe[i] = 1'b0; underflow_pipe[i] = 1'b0; end tmp_result = ZEROS; tmp_underflow = 1'b0; tmp_overflow = 1'b0; pipe_ptr = 0; end // ALWAYS CONSTRUCT BLOCK always @(data or i_direction or distance) begin if ((lpm_shifttype == "LOGICAL") || (lpm_shifttype == "UNUSED")) {tmp_overflow, tmp_underflow, tmp_result} = LogicShift(data, distance, i_direction); else if (lpm_shifttype == "ARITHMETIC") {tmp_overflow, tmp_underflow, tmp_result} = ArithShift(data, distance, i_direction); else if (lpm_shifttype == "ROTATE") {tmp_overflow, tmp_underflow, tmp_result} = RotateShift(data, distance, i_direction); end always @(posedge i_clock or posedge i_aclr) begin if (i_aclr) begin for (i1 = 0; i1 <= lpm_pipeline; i1 = i1 + 1) begin result_pipe[i1] <= {lpm_width{1'b0}}; overflow_pipe[i1] <= 1'b0; underflow_pipe[i1] <= 1'b0; end pipe_ptr <= 0; end else if (i_clken == 1'b1) begin result_pipe[pipe_ptr] <= tmp_result; overflow_pipe[pipe_ptr] <= tmp_overflow; underflow_pipe[pipe_ptr] <= tmp_underflow; if (lpm_pipeline > 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : tmp_result; assign overflow = (lpm_pipeline > 0) ? overflow_pipe[pipe_ptr] : tmp_overflow; assign underflow = (lpm_pipeline > 0) ? underflow_pipe[pipe_ptr] : tmp_underflow; endmodule // lpm_clshift //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_add_sub // // Description : Parameterized adder/subtractor megafunction. // // Limitation : n/a // // Results expected: If performs as adder, the result will be dataa[]+datab[]+cin. // If performs as subtractor, the result will be dataa[]-datab[]+cin-1. // Also returns carry out bit and overflow status bit. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_add_sub ( dataa, // Augend/Minuend datab, // Addend/Subtrahend cin, // Carry-in to the low-order bit. add_sub, // If the signal is high, the operation = dataa[]+datab[]+cin. // If the signal is low, the operation = dataa[]-datab[]+cin-1. clock, // Clock for pipelined usage. aclr, // Asynchronous clear for pipelined usage. clken, // Clock enable for pipelined usage. result, // dataa[]+datab[]+cin or dataa[]-datab[]+cin-1 cout, // Carry-out (borrow-in) of the MSB. overflow // Result exceeds available precision. ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the dataa[],datab[], and result[] ports. parameter lpm_representation = "SIGNED"; // Type of addition performed parameter lpm_direction = "UNUSED"; // Specify the operation of the lpm_add_sub function parameter lpm_pipeline = 0; // Number of Clock cycles of latency parameter lpm_type = "lpm_add_sub"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] dataa; input [lpm_width-1:0] datab; input cin; input add_sub; input clock; input aclr; input clken; // OUTPUT PORT DECLARATION output [lpm_width-1:0] result; output cout; output overflow; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] result_pipe [(lpm_pipeline+1):0]; reg [(lpm_pipeline+1):0] cout_pipe; reg [(lpm_pipeline+1):0] overflow_pipe; reg tmp_cout; reg tmp_overflow; reg [lpm_width-1:0] tmp_result; reg i_cin; // LOCAL INTEGER DECLARATION integer borrow; integer i; integer pipe_ptr; // INTERNAL TRI DECLARATION tri1 i_add_sub; tri0 i_aclr; tri1 i_clken; tri0 i_clock; // INITIAL CONSTRUCT BLOCK initial begin // check if lpm_width < 0 if (lpm_width <= 0) begin $display("Error! LPM_WIDTH must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_direction != "ADD") && (lpm_direction != "SUB") && (lpm_direction != "UNUSED") && // non-LPM 220 standard (lpm_direction != "DEFAULT")) // non-LPM 220 standard begin $display("Error! LPM_DIRECTION value must be \"ADD\" or \"SUB\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED")) begin $display("Error! LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_pipeline < 0) begin $display("Error! LPM_PIPELINE must be greater than or equal to 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end for (i = 0; i <= (lpm_pipeline+1); i = i + 1) begin result_pipe[i] = 'b0; cout_pipe[i] = 1'b0; overflow_pipe[i] = 1'b0; end pipe_ptr = 0; end // ALWAYS CONSTRUCT BLOCK always @(cin or dataa or datab or i_add_sub) begin i_cin = 1'b0; borrow = 1'b0; // cout is the same for both signed and unsign representation. if ((lpm_direction == "ADD") || ((i_add_sub == 1) && ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) )) begin i_cin = (cin === 1'bz) ? 0 : cin; {tmp_cout, tmp_result} = dataa + datab + i_cin; tmp_overflow = tmp_cout; end else if ((lpm_direction == "SUB") || ((i_add_sub == 0) && ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) )) begin i_cin = (cin === 1'bz) ? 1 : cin; borrow = (~i_cin) ? 1 : 0; {tmp_overflow, tmp_result} = dataa - datab - borrow; tmp_cout = (dataa >= (datab+borrow))?1:0; end if (lpm_representation == "SIGNED") begin // perform the addtion or subtraction operation if ((lpm_direction == "ADD") || ((i_add_sub == 1) && ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) )) begin tmp_result = dataa + datab + i_cin; tmp_overflow = ((dataa[lpm_width-1] == datab[lpm_width-1]) && (dataa[lpm_width-1] != tmp_result[lpm_width-1])) ? 1 : 0; end else if ((lpm_direction == "SUB") || ((i_add_sub == 0) && ((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) )) begin tmp_result = dataa - datab - borrow; tmp_overflow = ((dataa[lpm_width-1] != datab[lpm_width-1]) && (dataa[lpm_width-1] != tmp_result[lpm_width-1])) ? 1 : 0; end end end always @(posedge i_clock or posedge i_aclr) begin if (i_aclr) begin for (i = 0; i <= (lpm_pipeline+1); i = i + 1) begin result_pipe[i] <= {lpm_width{1'b0}}; cout_pipe[i] <= 1'b0; overflow_pipe[i] <= 1'b0; end pipe_ptr <= 0; end else if (i_clken == 1) begin result_pipe[pipe_ptr] <= tmp_result; cout_pipe[pipe_ptr] <= tmp_cout; overflow_pipe[pipe_ptr] <= tmp_overflow; if (lpm_pipeline > 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end // CONTINOUS ASSIGNMENT assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : tmp_result; assign cout = (lpm_pipeline > 0) ? cout_pipe[pipe_ptr] : tmp_cout; assign overflow = (lpm_pipeline > 0) ? overflow_pipe[pipe_ptr] : tmp_overflow; assign i_clock = clock; assign i_aclr = aclr; assign i_clken = clken; assign i_add_sub = add_sub; endmodule // lpm_add_sub // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_compare // // Description : Parameterized comparator megafunction. The comparator will // compare between data[] and datab[] and return the status of // comparation for the following operation. // 1) dataa[] < datab[]. // 2) dataa[] == datab[]. // 3) dataa[] > datab[]. // 4) dataa[] >= datab[]. // 5) dataa[] != datab[]. // 6) dataa[] <= datab[]. // // Limitation : n/a // // Results expected: Return status bits of the comparision between dataa[] and // datab[]. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_compare ( dataa, // Value to be compared to datab[]. (Required) datab, // Value to be compared to dataa[]. (Required) clock, // Clock for pipelined usage. aclr, // Asynchronous clear for pipelined usage. clken, // Clock enable for pipelined usage. // One of the following ports must be present. alb, // High (1) if dataa[] < datab[]. aeb, // High (1) if dataa[] == datab[]. agb, // High (1) if dataa[] > datab[]. aleb, // High (1) if dataa[] <= datab[]. aneb, // High (1) if dataa[] != datab[]. ageb // High (1) if dataa[] >= datab[]. ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the dataa[] and datab[] ports. (Required) parameter lpm_representation = "UNSIGNED"; // Type of comparison performed: // "SIGNED", "UNSIGNED" parameter lpm_pipeline = 0; // Specifies the number of Clock cycles of latency // associated with the alb, aeb, agb, ageb, aleb, // or aneb output. parameter lpm_type = "lpm_compare"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] dataa; input [lpm_width-1:0] datab; input clock; input aclr; input clken; // OUTPUT PORT DECLARATION output alb; output aeb; output agb; output aleb; output aneb; output ageb; // INTERNAL REGISTERS DECLARATION reg [lpm_pipeline+1:0] alb_pipe; reg [lpm_pipeline+1:0] aeb_pipe; reg [lpm_pipeline+1:0] agb_pipe; reg [lpm_pipeline+1:0] aleb_pipe; reg [lpm_pipeline+1:0] aneb_pipe; reg [lpm_pipeline+1:0] ageb_pipe; reg tmp_alb; reg tmp_aeb; reg tmp_agb; reg tmp_aleb; reg tmp_aneb; reg tmp_ageb; // LOCAL INTEGER DECLARATION integer i; integer pipe_ptr; // INTERNAL TRI DECLARATION tri0 aclr; tri0 clock; tri1 clken; wire i_aclr; wire i_clock; wire i_clken; buf (i_aclr, aclr); buf (i_clock, clock); buf (i_clken, clken); // INITIAL CONSTRUCT BLOCK initial begin if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED")) begin $display("Error! LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end pipe_ptr = 0; end // ALWAYS CONSTRUCT BLOCK // get the status of comparison always @(dataa or datab) begin tmp_aeb = (dataa == datab); tmp_aneb = (dataa != datab); if ((lpm_representation == "SIGNED") && ((dataa[lpm_width-1] ^ datab[lpm_width-1]) == 1)) begin // create latency tmp_alb = (dataa > datab); tmp_agb = (dataa < datab); tmp_aleb = (dataa >= datab); tmp_ageb = (dataa <= datab); end else begin // create latency tmp_alb = (dataa < datab); tmp_agb = (dataa > datab); tmp_aleb = (dataa <= datab); tmp_ageb = (dataa >= datab); end end // pipelining process always @(posedge i_clock or posedge i_aclr) begin if (i_aclr) // reset all variables begin for (i = 0; i <= (lpm_pipeline + 1); i = i + 1) begin aeb_pipe[i] <= 1'b0; agb_pipe[i] <= 1'b0; alb_pipe[i] <= 1'b0; aleb_pipe[i] <= 1'b0; aneb_pipe[i] <= 1'b0; ageb_pipe[i] <= 1'b0; end pipe_ptr <= 0; end else if (i_clken == 1) begin alb_pipe[pipe_ptr] <= tmp_alb; aeb_pipe[pipe_ptr] <= tmp_aeb; agb_pipe[pipe_ptr] <= tmp_agb; aleb_pipe[pipe_ptr] <= tmp_aleb; aneb_pipe[pipe_ptr] <= tmp_aneb; ageb_pipe[pipe_ptr] <= tmp_ageb; if (lpm_pipeline > 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end // CONTINOUS ASSIGNMENT assign alb = (lpm_pipeline > 0) ? alb_pipe[pipe_ptr] : tmp_alb; assign aeb = (lpm_pipeline > 0) ? aeb_pipe[pipe_ptr] : tmp_aeb; assign agb = (lpm_pipeline > 0) ? agb_pipe[pipe_ptr] : tmp_agb; assign aleb = (lpm_pipeline > 0) ? aleb_pipe[pipe_ptr] : tmp_aleb; assign aneb = (lpm_pipeline > 0) ? aneb_pipe[pipe_ptr] : tmp_aneb; assign ageb = (lpm_pipeline > 0) ? ageb_pipe[pipe_ptr] : tmp_ageb; endmodule // lpm_compare //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_mult // // Description : Parameterized multiplier megafunction. // // Limitation : n/a // // Results expected: dataa[] * datab[] + sum[]. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_mult ( dataa, // Multiplicand. (Required) datab, // Multiplier. (Required) sum, // Partial sum. aclr, // Asynchronous clear for pipelined usage. sclr, // Synchronous clear for pipelined usage. clock, // Clock for pipelined usage. clken, // Clock enable for pipelined usage. result // result = dataa[] * datab[] + sum. The product LSB is aligned with the sum LSB. ); // GLOBAL PARAMETER DECLARATION parameter lpm_widtha = 1; // Width of the dataa[] port. (Required) parameter lpm_widthb = 1; // Width of the datab[] port. (Required) parameter lpm_widthp = 1; // Width of the result[] port. (Required) parameter lpm_widths = 1; // Width of the sum[] port. (Required) parameter lpm_representation = "UNSIGNED"; // Type of multiplication performed parameter lpm_pipeline = 0; // Number of clock cycles of latency parameter lpm_type = "lpm_mult"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_widtha-1:0] dataa; input [lpm_widthb-1:0] datab; input [lpm_widths-1:0] sum; input aclr; input sclr; input clock; input clken; // OUTPUT PORT DECLARATION output [lpm_widthp-1:0] result; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_widthp-1:0] result_pipe [lpm_pipeline+1:0]; reg [lpm_widthp-1:0] i_prod; reg [lpm_widthp-1:0] t_p; reg [lpm_widths-1:0] i_prod_s; reg [lpm_widths-1:0] t_s; reg [lpm_widtha+lpm_widthb-1:0] i_prod_ab; reg [lpm_widtha-1:0] t_a; reg [lpm_widthb-1:0] t_b; reg sign_ab; reg sign_s; reg [8*5:1] input_a_is_constant; reg [8*5:1] input_b_is_constant; reg [8*lpm_widtha:1] input_a_fixed_value; reg [8*lpm_widthb:1] input_b_fixed_value; reg [lpm_widtha-1:0] dataa_fixed; reg [lpm_widthb-1:0] datab_fixed; // LOCAL INTEGER DECLARATION integer i; integer pipe_ptr; // INTERNAL WIRE DECLARATION wire [lpm_widtha-1:0] dataa_wire; wire [lpm_widthb-1:0] datab_wire; // INTERNAL TRI DECLARATION tri0 aclr; tri0 sclr; tri0 clock; tri1 clken; wire i_aclr; wire i_sclr; wire i_clock; wire i_clken; buf (i_aclr, aclr); buf (i_sclr, sclr); buf (i_clock, clock); buf (i_clken, clken); // COMPONENT INSTANTIATIONS LPM_HINT_EVALUATION eva(); // FUNCTION DECLARATION // convert string to binary bits. function integer str2bin; input [8*256:1] str; input str_width; reg [8*256:1] reg_str; reg [255:0] bin; reg [8:1] tmp; integer m; integer str_width; begin reg_str = str; for (m=0; m < str_width; m=m+1) begin tmp = reg_str[8:1]; reg_str = reg_str >> 8; case (tmp) "0" : bin[m] = 1'b0; "1" : bin[m] = 1'b1; default: bin[m] = 1'bx; endcase end str2bin = bin; end endfunction // INITIAL CONSTRUCT BLOCK initial begin // check if lpm_widtha > 0 if (lpm_widtha <= 0) begin $display("Error! lpm_widtha must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check if lpm_widthb > 0 if (lpm_widthb <= 0) begin $display("Error! lpm_widthb must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check if lpm_widthp > 0 if (lpm_widthp <= 0) begin $display("Error! lpm_widthp must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check if lpm_widthp > 0 if (lpm_widths <= 0) begin $display("Error! lpm_widths must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check for valid lpm_rep value if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED")) begin $display("Error! lpm_representation value must be \"SIGNED\" or \"UNSIGNED\".", $time); $display("Time: %0t Instance: %m", $time); $finish; end input_a_is_constant = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_A_IS_CONSTANT"); if (input_a_is_constant == "FIXED") begin input_a_fixed_value = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_A_FIXED_VALUE"); dataa_fixed = str2bin(input_a_fixed_value, lpm_widtha); end input_b_is_constant = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_B_IS_CONSTANT"); if (input_b_is_constant == "FIXED") begin input_b_fixed_value = eva.GET_PARAMETER_VALUE(lpm_hint, "INPUT_B_FIXED_VALUE"); datab_fixed = str2bin(input_b_fixed_value, lpm_widthb); end pipe_ptr = 0; end // ALWAYS CONSTRUCT BLOCK always @(dataa_wire or datab_wire or sum) begin t_a = dataa_wire; t_b = datab_wire; t_s = sum; sign_ab = 1'b0; sign_s = 1'b0; // if inputs are sign number if (lpm_representation == "SIGNED") begin sign_ab = dataa_wire[lpm_widtha-1] ^ datab_wire[lpm_widthb-1]; sign_s = sum[lpm_widths-1]; // if negative number, represent them as 2 compliment number. if (dataa_wire[lpm_widtha-1] == 1) t_a = (~dataa_wire) + 1; if (datab_wire[lpm_widthb-1] == 1) t_b = (~datab_wire) + 1; if (sum[lpm_widths-1] == 1) t_s = (~sum) + 1; end // if sum port is not used if (sum === {lpm_widths{1'bz}}) begin t_s = {lpm_widths{1'b0}}; sign_s = 1'b0; end if (sign_ab == sign_s) begin i_prod = (t_a * t_b) + t_s; i_prod_s = (t_a * t_b) + t_s; i_prod_ab = (t_a * t_b) + t_s; end else begin i_prod = (t_a * t_b) - t_s; i_prod_s = (t_a * t_b) - t_s; i_prod_ab = (t_a * t_b) - t_s; end // if dataa[] * datab[] produces negative number, compliment the result if (sign_ab) begin i_prod = (~i_prod) + 1; i_prod_s = (~i_prod_s) + 1; i_prod_ab = (~i_prod_ab) + 1; end if ((lpm_widthp < lpm_widths) || (lpm_widthp < (lpm_widtha+lpm_widthb))) for (i = 0; i < lpm_widthp; i = i + 1) i_prod[lpm_widthp-1-i] = (lpm_widths > lpm_widtha+lpm_widthb) ? i_prod_s[lpm_widths-1-i] : i_prod_ab[lpm_widtha+lpm_widthb-1-i]; end always @(posedge i_clock or posedge i_aclr) begin if (i_aclr) // clear the pipeline for result to 0 begin for (i = 0; i <= (lpm_pipeline + 1); i = i + 1) result_pipe[i] <= {lpm_widthp{1'b0}}; pipe_ptr <= 0; end else if (i_clken == 1) begin if(i_sclr) begin for (i = 0; i <= (lpm_pipeline + 1); i = i + 1) result_pipe[i] <= {lpm_widthp{1'b0}}; pipe_ptr <= 0; end else begin result_pipe[pipe_ptr] <= i_prod; if (lpm_pipeline > 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end end // CONTINOUS ASSIGNMENT assign dataa_wire = (input_a_is_constant == "FIXED") ? dataa_fixed : dataa; assign datab_wire = (input_b_is_constant == "FIXED") ? datab_fixed : datab; assign result = (lpm_pipeline > 0) ? result_pipe[pipe_ptr] : i_prod; endmodule // lpm_mult // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_divide // // Description : Parameterized divider megafunction. This function performs a // divide operation such that denom * quotient + remain = numer // The function allows for all combinations of signed(two's // complement) and unsigned inputs. If any of the inputs is // signed, the output is signed. Otherwise the output is unsigned. // The function also allows the remainder to be specified as // always positive (in which case remain >= 0); otherwise remain // is zero or the same sign as the numerator // (this parameter is ignored in the case of purely unsigned // division). Finally the function is also pipelinable. // // Limitation : n/a // // Results expected: Return quotient and remainder. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_divide ( numer, // The numerator (Required) denom, // The denominator (Required) clock, // Clock input for pipelined usage aclr, // Asynchronous clear signal clken, // Clock enable for pipelined usage. quotient, // Quotient (Required) remain // Remainder (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_widthn = 1; // Width of the numer[] and quotient[] port. (Required) parameter lpm_widthd = 1; // Width of the denom[] and remain[] port. (Required) parameter lpm_nrepresentation = "UNSIGNED"; // The representation of numer parameter lpm_drepresentation = "UNSIGNED"; // The representation of denom parameter lpm_pipeline = 0; // Number of Clock cycles of latency parameter lpm_type = "lpm_divide"; parameter lpm_hint = "LPM_REMAINDERPOSITIVE=TRUE"; // INPUT PORT DECLARATION input [lpm_widthn-1:0] numer; input [lpm_widthd-1:0] denom; input clock; input aclr; input clken; // OUTPUT PORT DECLARATION output [lpm_widthn-1:0] quotient; output [lpm_widthd-1:0] remain; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_widthn-1:0] quotient_pipe [lpm_pipeline+1:0]; reg [lpm_widthd-1:0] remain_pipe [lpm_pipeline+1:0]; reg [lpm_widthn-1:0] tmp_quotient; reg [lpm_widthd-1:0] tmp_remain; reg [lpm_widthn-1:0] not_numer; reg [lpm_widthn-1:0] int_numer; reg [lpm_widthd-1:0] not_denom; reg [lpm_widthd-1:0] int_denom; reg [lpm_widthn-1:0] t_numer; reg [lpm_widthn-1:0] t_q; reg [lpm_widthd-1:0] t_denom; reg [lpm_widthd-1:0] t_r; reg sign_q; reg sign_r; reg sign_n; reg sign_d; reg [8*5:1] lpm_remainderpositive; // LOCAL INTEGER DECLARATION integer i; integer rsig; integer pipe_ptr; // INTERNAL TRI DECLARATION tri0 aclr; tri0 clock; tri1 clken; wire i_aclr; wire i_clock; wire i_clken; buf (i_aclr, aclr); buf (i_clock, clock); buf (i_clken, clken); // COMPONENT INSTANTIATIONS LPM_HINT_EVALUATION eva(); // INITIAL CONSTRUCT BLOCK initial begin // check if lpm_widthn > 0 if (lpm_widthn <= 0) begin $display("Error! LPM_WIDTHN must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check if lpm_widthd > 0 if (lpm_widthd <= 0) begin $display("Error! LPM_WIDTHD must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check for valid lpm_nrepresentation value if ((lpm_nrepresentation != "SIGNED") && (lpm_nrepresentation != "UNSIGNED")) begin $display("Error! LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\"."); $display("Time: %0t Instance: %m", $time); $finish; end // check for valid lpm_drepresentation value if ((lpm_drepresentation != "SIGNED") && (lpm_drepresentation != "UNSIGNED")) begin $display("Error! LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\"."); $display("Time: %0t Instance: %m", $time); $finish; end // check for valid lpm_remainderpositive value lpm_remainderpositive = eva.GET_PARAMETER_VALUE(lpm_hint, "LPM_REMAINDERPOSITIVE"); if ((lpm_remainderpositive == "TRUE") && (lpm_remainderpositive == "FALSE")) begin $display("Error! LPM_REMAINDERPOSITIVE value must be \"TRUE\" or \"FALSE\"."); $display("Time: %0t Instance: %m", $time); $finish; end for (i = 0; i <= (lpm_pipeline+1); i = i + 1) begin quotient_pipe[i] <= {lpm_widthn{1'b0}}; remain_pipe[i] <= {lpm_widthd{1'b0}}; end pipe_ptr = 0; end // ALWAYS CONSTRUCT BLOCK always @(numer or denom or lpm_remainderpositive) begin sign_q = 1'b0; sign_r = 1'b0; sign_n = 1'b0; sign_d = 1'b0; t_numer = numer; t_denom = denom; if (lpm_nrepresentation == "SIGNED") if (numer[lpm_widthn-1] == 1'b1) begin t_numer = ~numer + 1; // numer is negative number sign_n = 1'b1; end if (lpm_drepresentation == "SIGNED") if (denom[lpm_widthd-1] == 1'b1) begin t_denom = ~denom + 1; // denom is negative numbrt sign_d = 1'b1; end t_q = t_numer / t_denom; // get quotient t_r = t_numer % t_denom; // get remainder sign_q = sign_n ^ sign_d; sign_r = (t_r != {lpm_widthd{1'b0}}) ? sign_n : 1'b0; // Pipeline the result tmp_quotient = (sign_q == 1'b1) ? (~t_q + 1) : t_q; tmp_remain = (sign_r == 1'b1) ? (~t_r + 1) : t_r; // Recalculate the quotient and remainder if remainder is negative number // and LPM_REMAINDERPOSITIVE=TRUE. if ((sign_r) && (lpm_remainderpositive == "TRUE")) begin tmp_quotient = tmp_quotient + ((sign_d == 1'b1) ? 1 : -1 ); tmp_remain = tmp_remain + t_denom; end end always @(posedge i_clock or posedge i_aclr) begin if (i_aclr) begin for (i = 0; i <= (lpm_pipeline+1); i = i + 1) begin quotient_pipe[i] <= {lpm_widthn{1'b0}}; remain_pipe[i] <= {lpm_widthd{1'b0}}; end pipe_ptr <= 0; end else if (i_clken) begin quotient_pipe[pipe_ptr] <= tmp_quotient; remain_pipe[pipe_ptr] <= tmp_remain; if (lpm_pipeline > 1) pipe_ptr <= (pipe_ptr + 1) % lpm_pipeline; end end // CONTINOUS ASSIGNMENT assign quotient = (lpm_pipeline > 0) ? quotient_pipe[pipe_ptr] : tmp_quotient; assign remain = (lpm_pipeline > 0) ? remain_pipe[pipe_ptr] : tmp_remain; endmodule // lpm_divide // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_abs // // Description : Parameterized absolute value megafunction. This megafunction // requires the input data to be signed number. // // Limitation : n/a // // Results expected: Return absolute value of data and the overflow status // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_abs ( data, // Signed number (Required) result, // Absolute value of data[]. overflow // High if data = -2 ^ (LPM_WIDTH-1). ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and result[] ports.(Required) parameter lpm_type = "lpm_abs"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; // OUTPUT PORT DECLARATION output [lpm_width-1:0] result; output overflow; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] result_tmp; reg overflow; // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end end // ALWAYS CONSTRUCT BLOCK always @(data) begin result_tmp = (data[lpm_width-1] == 1) ? (~data) + 1 : data; overflow = (data[lpm_width-1] == 1) ? (result_tmp == (1<<(lpm_width-1))) : 0; end // CONTINOUS ASSIGNMENT assign result = result_tmp; endmodule // lpm_abs //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_counter // // Description : Parameterized counter megafunction. The lpm_counter // megafunction is a binary counter that features an up, // down, or up/down counter with optional synchronous or // asynchronous clear, set, and load ports. // // Limitation : n/a // // Results expected: Data output from the counter and carry-out of the MSB. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_counter ( clock, // Positive-edge-triggered clock. (Required) clk_en, // Clock enable input. Enables all synchronous activities. cnt_en, // Count enable input. Disables the count when low (0) without // affecting sload, sset, or sclr. updown, // Controls the direction of the count. High (1) = count up. // Low (0) = count down. aclr, // Asynchronous clear input. aset, // Asynchronous set input. aload, // Asynchronous load input. Asynchronously loads the counter with // the value on the data input. sclr, // Synchronous clear input. Clears the counter on the next active // clock edge. sset, // Synchronous set input. Sets the counter on the next active clock edge. sload, // Synchronous load input. Loads the counter with data[] on the next // active clock edge. data, // Parallel data input to the counter. cin, // Carry-in to the low-order bit. q, // Data output from the counter. cout, // Carry-out of the MSB. eq // Counter decode output. Active high when the counter reaches the specified // count value. ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; //The number of bits in the count, or the width of the q[] // and data[] ports, if they are used. (Required) parameter lpm_direction = "UNUSED"; // Direction of the count. parameter lpm_modulus = 0; // The maximum count, plus one. parameter lpm_avalue = "UNUSED"; // Constant value that is loaded when aset is high. parameter lpm_svalue = "UNUSED"; // Constant value that is loaded on the rising edge // of clock when sset is high. parameter lpm_pvalue = "UNUSED"; parameter lpm_port_updown = "PORT_CONNECTIVITY"; parameter lpm_type = "lpm_counter"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input clock; input clk_en; input cnt_en; input updown; input aclr; input aset; input aload; input sclr; input sset; input sload; input [lpm_width-1:0] data; input cin; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; output cout; output [15:0] eq; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] tmp_count; reg [lpm_width-1:0] adata; reg use_adata; reg tmp_updown; reg [lpm_width:0] tmp_modulus; reg [lpm_width:0] max_modulus; reg [lpm_width-1:0] svalue; reg [lpm_width-1:0] avalue; reg [lpm_width-1:0] pvalue; // INTERNAL WIRE DECLARATION wire w_updown; wire [lpm_width-1:0] final_count; // LOCAL INTEGER DECLARATION integer i; // INTERNAL TRI DECLARATION tri1 clk_en; tri1 cnt_en; tri0 aclr; tri0 aset; tri0 aload; tri0 sclr; tri0 sset; tri0 sload; tri1 cin; tri1 updown_z; wire i_clk_en; wire i_cnt_en; wire i_aclr; wire i_aset; wire i_aload; wire i_sclr; wire i_sset; wire i_sload; wire i_cin; wire i_updown; buf (i_clk_en, clk_en); buf (i_cnt_en, cnt_en); buf (i_aclr, aclr); buf (i_aset, aset); buf (i_aload, aload); buf (i_sclr, sclr); buf (i_sset, sset); buf (i_sload, sload); buf (i_cin, cin); buf (i_updown, updown_z); // TASK DECLARATION task string_to_reg; input [8*40:1] string_value; output [lpm_width-1:0] value; reg [8*40:1] reg_s; reg [8:1] digit; reg [8:1] tmp; reg [lpm_width-1:0] ivalue; integer m; begin ivalue = {lpm_width{1'b0}}; reg_s = string_value; for (m=1; m<=40; m=m+1) begin tmp = reg_s[320:313]; digit = tmp & 8'b00001111; reg_s = reg_s << 8; ivalue = ivalue * 10 + digit; end value = ivalue; end endtask // INITIAL CONSTRUCT BLOCK initial begin max_modulus = 1 << lpm_width; // check if lpm_width < 0 if (lpm_width <= 0) begin $display("Error! LPM_WIDTH must be greater than 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check if lpm_modulus < 0 if (lpm_modulus < 0) begin $display("Error! LPM_MODULUS must be greater or equal to 0.\n"); $display("Time: %0t Instance: %m", $time); $finish; end // check if lpm_modulus > 1< max_modulus) begin $display("Warning! LPM_MODULUS should be within 1 to 2^LPM_WIDTH. Assuming no modulus input.\n"); $display ("Time: %0t Instance: %m", $time); end // check if lpm_direction valid if ((lpm_direction != "UNUSED") && (lpm_direction != "DEFAULT") && (lpm_direction != "UP") && (lpm_direction != "DOWN")) begin $display("Error! LPM_DIRECTION must be \"UP\" or \"DOWN\" if used.\n"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_avalue == "UNUSED") avalue = {lpm_width{1'b1}}; else string_to_reg(lpm_avalue, avalue); if (lpm_svalue == "UNUSED") svalue = {lpm_width{1'b1}}; else string_to_reg(lpm_svalue, svalue); if (lpm_pvalue == "UNUSED") pvalue = {lpm_width{1'b0}}; else string_to_reg(lpm_pvalue, pvalue); tmp_modulus = ((lpm_modulus == 0) || (lpm_modulus > max_modulus)) ? max_modulus : lpm_modulus; tmp_count = pvalue; use_adata = 1'b0; end // NCSIM will only assigns 1'bZ to unconnected port at time 0fs + 1 // verilator lint_off STMTDLY initial #0 // verilator lint_on STMTDLY begin // // check if lpm_direction valid if ((lpm_direction != "UNUSED") && (lpm_direction != "DEFAULT") && (updown !== 1'bz) && (lpm_port_updown == "PORT_CONNECTIVITY")) begin $display("Error! LPM_DIRECTION and UPDOWN cannot be used at the same time.\n"); $display("Time: %0t Instance: %m", $time); $finish; end end // ALWAYS CONSTRUCT BLOCK always @(posedge i_aclr or posedge i_aset or posedge i_aload or posedge clock) begin if (i_aclr || i_aset || i_aload) use_adata <= 1'b1; else if ($time > 0) begin if (i_clk_en) begin use_adata <= 1'b0; if (i_sclr) tmp_count <= 0; else if (i_sset) tmp_count <= svalue; else if (i_sload) tmp_count <= data; else if (i_cnt_en && i_cin) begin if (w_updown) tmp_count <= (final_count == tmp_modulus-1) ? 0 : final_count+1; else tmp_count <= (final_count == 0) ? tmp_modulus-1 : final_count-1; end else tmp_count <= final_count; end end end always @(i_aclr or i_aset or i_aload or data or avalue) begin if (i_aclr) begin adata <= 0; end else if (i_aset) begin adata <= avalue; end else if (i_aload) adata <= data; end // CONTINOUS ASSIGNMENT assign q = final_count; assign final_count = (use_adata == 1'b1) ? adata : tmp_count; assign cout = (i_cin && (((w_updown==0) && (final_count==0)) || ((w_updown==1) && ((final_count==tmp_modulus-1) || (final_count=={lpm_width{1'b1}}))) )) ? 1'b1 : 1'b0; assign updown_z = updown; assign w_updown = (lpm_port_updown == "PORT_USED") ? i_updown : (lpm_port_updown == "PORT_UNUSED") ? ((lpm_direction == "DOWN") ? 1'b0 : 1'b1) : ((((lpm_direction == "UNUSED") || (lpm_direction == "DEFAULT")) && (i_updown == 1)) || (lpm_direction == "UP")) ? 1'b1 : 1'b0; assign eq = {16{1'b0}}; endmodule // lpm_counter // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_latch // // Description : Parameterized latch megafunction. // // Limitation : n/a // // Results expected: Data output from the latch. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_latch ( data, // Data input to the latch. gate, // Latch enable input. High = flow-through, low = latch. (Required) aclr, // Asynchronous clear input. aset, // Asynchronous set input. aconst, q // Data output from the latch. ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and q[] ports. (Required) parameter lpm_avalue = "UNUSED"; // Constant value that is loaded when aset is high. parameter lpm_pvalue = "UNUSED"; parameter lpm_type = "lpm_latch"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input gate; input aclr; input aset; input aconst; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] q; reg [lpm_width-1:0] avalue; reg [lpm_width-1:0] pvalue; // INTERNAL TRI DECLARATION tri0 [lpm_width-1:0] data; tri0 aclr; tri0 aset; tri0 aconst; wire i_aclr; wire i_aset; buf (i_aclr, aclr); buf (i_aset, aset); // TASK DECLARATION task string_to_reg; input [8*40:1] string_value; output [lpm_width-1:0] value; reg [8*40:1] reg_s; reg [8:1] digit; reg [8:1] tmp; reg [lpm_width-1:0] ivalue; integer m; begin ivalue = {lpm_width{1'b0}}; reg_s = string_value; for (m=1; m<=40; m=m+1) begin tmp = reg_s[320:313]; digit = tmp & 8'b00001111; reg_s = reg_s << 8; ivalue = ivalue * 10 + digit; end value = ivalue; end endtask // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0 (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_pvalue != "UNUSED") begin string_to_reg(lpm_pvalue, pvalue); q = pvalue; end if (lpm_avalue == "UNUSED") avalue = {lpm_width{1'b1}}; else string_to_reg(lpm_avalue, avalue); end // ALWAYS CONSTRUCT BLOCK always @(data or gate or i_aclr or i_aset or avalue) begin if (i_aclr) q <= {lpm_width{1'b0}}; else if (i_aset) q <= avalue; else if (gate) q <= data; end endmodule // lpm_latch //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_ff // // Description : Parameterized flipflop megafunction. The lpm_ff function // contains features that are not available in the DFF, DFFE, // DFFEA, TFF, and TFFE primitives, such as synchronous or // asynchronous set, clear, and load inputs. // // Limitation : n/a // // Results expected: Data output from D or T flipflops. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_ff ( data, // T-type flipflop: Toggle enable // D-type flipflop: Data input clock, // Positive-edge-triggered clock. (Required) enable, // Clock enable input. aclr, // Asynchronous clear input. aset, // Asynchronous set input. aload, // Asynchronous load input. Asynchronously loads the flipflop with // the value on the data input. sclr, // Synchronous clear input. sset, // Synchronous set input. sload, // Synchronous load input. Loads the flipflop with the value on the // data input on the next active clock edge. q // Data output from D or T flipflops. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and q[] ports. (Required) parameter lpm_avalue = "UNUSED"; // Constant value that is loaded when aset is high. parameter lpm_svalue = "UNUSED"; // Constant value that is loaded on the rising edge // of clock when sset is high. parameter lpm_pvalue = "UNUSED"; parameter lpm_fftype = "DFF"; // Type of flipflop parameter lpm_type = "lpm_ff"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input clock; input enable; input aclr; input aset; input aload; input sclr; input sset; input sload ; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] tmp_q; reg [lpm_width-1:0] adata; reg use_adata; reg [lpm_width-1:0] svalue; reg [lpm_width-1:0] avalue; reg [lpm_width-1:0] pvalue; // INTERNAL WIRE DECLARATION wire [lpm_width-1:0] final_q; // LOCAL INTEGER DECLARATION integer i; // INTERNAL TRI DECLARATION tri1 [lpm_width-1:0] data; tri1 enable; tri0 sload; tri0 sclr; tri0 sset; tri0 aload; tri0 aclr; tri0 aset; wire i_enable; wire i_sload; wire i_sclr; wire i_sset; wire i_aload; wire i_aclr; wire i_aset; buf (i_enable, enable); buf (i_sload, sload); buf (i_sclr, sclr); buf (i_sset, sset); buf (i_aload, aload); buf (i_aclr, aclr); buf (i_aset, aset); // TASK DECLARATION task string_to_reg; input [8*40:1] string_value; output [lpm_width-1:0] value; reg [8*40:1] reg_s; reg [8:1] digit; reg [8:1] tmp; reg [lpm_width-1:0] ivalue; integer m; begin ivalue = {lpm_width{1'b0}}; reg_s = string_value; for (m=1; m<=40; m=m+1) begin tmp = reg_s[320:313]; digit = tmp & 8'b00001111; reg_s = reg_s << 8; ivalue = ivalue * 10 + digit; end value = ivalue; end endtask // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0(ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_fftype != "DFF") && (lpm_fftype != "TFF") && (lpm_fftype != "UNUSED")) // non-LPM 220 standard begin $display("Error! LPM_FFTYPE value must be \"DFF\" or \"TFF\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_avalue == "UNUSED") avalue = {lpm_width{1'b1}}; else string_to_reg(lpm_avalue, avalue); if (lpm_svalue == "UNUSED") svalue = {lpm_width{1'b1}}; else string_to_reg(lpm_svalue, svalue); if (lpm_pvalue == "UNUSED") pvalue = {lpm_width{1'b0}}; else string_to_reg(lpm_pvalue, pvalue); tmp_q = pvalue; use_adata = 1'b0; end // ALWAYS CONSTRUCT BLOCK always @(posedge i_aclr or posedge i_aset or posedge i_aload or posedge clock) begin // Asynchronous process if (i_aclr || i_aset || i_aload) use_adata <= 1'b1; else if ($time > 0) begin // Synchronous process if (i_enable) begin use_adata <= 1'b0; if (i_sclr) tmp_q <= 0; else if (i_sset) tmp_q <= svalue; else if (i_sload) // Load data tmp_q <= data; else begin if (lpm_fftype == "TFF") // toggle begin for (i = 0; i < lpm_width; i=i+1) if (data[i] == 1'b1) tmp_q[i] <= ~final_q[i]; else tmp_q[i] <= final_q[i]; end else // DFF, load data tmp_q <= data; end end end end always @(i_aclr or i_aset or i_aload or data or avalue or pvalue) begin if (i_aclr === 1'b1) adata <= {lpm_width{1'b0}}; else if (i_aclr === 1'bx) adata <= {lpm_width{1'bx}}; else if (i_aset) adata <= avalue; else if (i_aload) adata <= data; else if ((i_aclr === 1'b0) && ($time == 0)) adata <= pvalue; end // CONTINOUS ASSIGNMENT assign q = final_q; assign final_q = (use_adata == 1'b1) ? adata : tmp_q; endmodule // lpm_ff // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_shiftreg // // Description : Parameterized shift register megafunction. // // Limitation : n/a // // Results expected: Data output from the shift register and the Serial shift data output. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_shiftreg ( data, // Data input to the shift register. clock, // Positive-edge-triggered clock. (Required) enable, // Clock enable input shiftin, // Serial shift data input. load, // Synchronous parallel load. High (1): load operation; // low (0): shift operation. aclr, // Asynchronous clear input. aset, // Asynchronous set input. sclr, // Synchronous clear input. sset, // Synchronous set input. q, // Data output from the shift register. shiftout // Serial shift data output. ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and q ports. (Required) parameter lpm_direction = "LEFT"; // Values are "LEFT", "RIGHT", and "UNUSED". parameter lpm_avalue = "UNUSED"; // Constant value that is loaded when aset is high. parameter lpm_svalue = "UNUSED"; // Constant value that is loaded on the rising edge // of clock when sset is high. parameter lpm_pvalue = "UNUSED"; parameter lpm_type = "lpm_shiftreg"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input clock; input enable; input shiftin; input load; input aclr; input aset; input sclr; input sset; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; output shiftout; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] tmp_q; reg abit; reg [lpm_width-1:0] svalue; reg [lpm_width-1:0] avalue; reg [lpm_width-1:0] pvalue; // LOCAL INTEGER DECLARATION integer i; // INTERNAL WIRE DECLARATION wire tmp_shiftout; // INTERNAL TRI DECLARATION tri1 enable; tri1 shiftin; tri0 load; tri0 aclr; tri0 aset; tri0 sclr; tri0 sset; wire i_enable; wire i_shiftin; wire i_load; wire i_aclr; wire i_aset; wire i_sclr; wire i_sset; buf (i_enable, enable); buf (i_shiftin, shiftin); buf (i_load, load); buf (i_aclr, aclr); buf (i_aset, aset); buf (i_sclr, sclr); buf (i_sset, sset); // TASK DECLARATION task string_to_reg; input [8*40:1] string_value; output [lpm_width-1:0] value; reg [8*40:1] reg_s; reg [8:1] digit; reg [8:1] tmp; reg [lpm_width-1:0] ivalue; integer m; begin ivalue = {lpm_width{1'b0}}; reg_s = string_value; for (m=1; m<=40; m=m+1) begin tmp = reg_s[320:313]; digit = tmp & 8'b00001111; reg_s = reg_s << 8; ivalue = ivalue * 10 + digit; end value = ivalue; end endtask // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Value of lpm_width parameter must be greater than 0 (ERROR)"); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_direction != "LEFT") && (lpm_direction != "RIGHT") && (lpm_direction != "UNUSED")) // non-LPM 220 standard begin $display("Error! LPM_DIRECTION value must be \"LEFT\" or \"RIGHT\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_avalue == "UNUSED") avalue = {lpm_width{1'b1}}; else string_to_reg(lpm_avalue, avalue); if (lpm_svalue == "UNUSED") svalue = {lpm_width{1'b1}}; else string_to_reg(lpm_svalue, svalue); if (lpm_pvalue == "UNUSED") pvalue = {lpm_width{1'b0}}; else string_to_reg(lpm_pvalue, pvalue); tmp_q = pvalue; end // ALWAYS CONSTRUCT BLOCK always @(i_aclr or i_aset or avalue) begin if (i_aclr) tmp_q <= {lpm_width{1'b0}}; else if (i_aset) tmp_q <= avalue; end always @(posedge clock) begin if (i_aclr) tmp_q <= (i_aset) ? {lpm_width{1'bx}} : {lpm_width{1'b0}}; else if (i_aset) tmp_q <= avalue; else begin if (i_enable) begin if (i_sclr) tmp_q <= {lpm_width{1'b0}}; else if (i_sset) tmp_q <= svalue; else if (i_load) tmp_q <= data; else if (!i_load) begin if ((lpm_direction == "LEFT") || (lpm_direction == "UNUSED")) {abit,tmp_q} <= {tmp_q,i_shiftin}; else if (lpm_direction == "RIGHT") {tmp_q,abit} <= {i_shiftin,tmp_q}; end end end end // CONTINOUS ASSIGNMENT assign tmp_shiftout = (lpm_direction == "RIGHT") ? tmp_q[0] : tmp_q[lpm_width-1]; assign q = tmp_q; assign shiftout = tmp_shiftout; endmodule // lpm_shiftreg // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_ram_dq // // Description : Parameterized RAM with separate input and output ports megafunction. // lpm_ram_dq implement asynchronous memory or memory with synchronous // inputs and/or outputs. // // Limitation : n/a // // Results expected: Data output from the memory. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_ram_dq ( data, // Data input to the memory. (Required) address, // Address input to the memory. (Required) inclock, // Synchronizes memory loading. outclock, // Synchronizes q outputs from memory. we, // Write enable input. Enables write operations to the memory when high. (Required) q // Data output from the memory. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of data[] and q[] ports. (Required) parameter lpm_widthad = 1; // Width of the address port. (Required) parameter lpm_numwords = 1 << lpm_widthad; // Number of words stored in memory. parameter lpm_indata = "REGISTERED"; // Controls whether the data port is registered. parameter lpm_address_control = "REGISTERED"; // Controls whether the address and we ports are registered. parameter lpm_outdata = "REGISTERED"; // Controls whether the q ports are registered. parameter lpm_file = "UNUSED"; // Name of the file containing RAM initialization data. parameter use_eab = "ON"; // Specified whether to use the EAB or not. parameter intended_device_family = "Stratix"; parameter lpm_type = "lpm_ram_dq"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input [lpm_widthad-1:0] address; input inclock; input outclock; input we; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] mem_data [lpm_numwords-1:0]; reg [lpm_width-1:0] tmp_q; reg [lpm_width-1:0] pdata; reg [lpm_width-1:0] in_data; reg [lpm_widthad-1:0] paddress; reg pwe; reg [lpm_width-1:0] ZEROS, ONES, UNKNOWN; `ifdef VERILATOR reg [`LPM_MAX_NAME_SZ*8:1] ram_initf; `else reg [8*256:1] ram_initf; `endif // LOCAL INTEGER DECLARATION integer i; // INTERNAL TRI DECLARATION tri0 inclock; tri0 outclock; wire i_inclock; wire i_outclock; buf (i_inclock, inclock); buf (i_outclock, outclock); // COMPONENT INSTANTIATIONS LPM_DEVICE_FAMILIES dev (); LPM_MEMORY_INITIALIZATION mem (); // FUNCTON DECLARATION // Check the validity of the address. function ValidAddress; input [lpm_widthad-1:0] paddress; begin ValidAddress = 1'b0; if (^paddress === {lpm_widthad{1'bx}}) begin $display("%t:Error! Invalid address.\n", $time); $display("Time: %0t Instance: %m", $time); end else if (paddress >= lpm_numwords) begin $display("%t:Error! Address out of bound on RAM.\n", $time); $display("Time: %0t Instance: %m", $time); end else ValidAddress = 1'b1; end endfunction // INITIAL CONSTRUCT BLOCK initial begin // Initialize the internal data register. pdata = {lpm_width{1'b0}}; paddress = {lpm_widthad{1'b0}}; pwe = 1'b0; if (lpm_width <= 0) begin $display("Error! LPM_WIDTH parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_widthad <= 0) begin $display("Error! LPM_WIDTHAD parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end // check for number of words out of bound if ((lpm_numwords > (1 << lpm_widthad)) || (lpm_numwords <= (1 << (lpm_widthad-1)))) begin $display("Error! The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED")) begin $display("Error! LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED")) begin $display("Error! LPM_INDATA must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED")) begin $display("Error! LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (dev.IS_VALID_FAMILY(intended_device_family) == 0) begin $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family); $display("Time: %0t Instance: %m", $time); $finish; end for (i=0; i < lpm_width; i=i+1) begin ZEROS[i] = 1'b0; ONES[i] = 1'b1; UNKNOWN[i] = 1'bX; end for (i = 0; i < lpm_numwords; i=i+1) mem_data[i] = {lpm_width{1'b0}}; // load data to the RAM if (lpm_file != "UNUSED") begin mem.convert_to_ver_file(lpm_file, lpm_width, ram_initf); $readmemh(ram_initf, mem_data); end tmp_q = ZEROS; end // ALWAYS CONSTRUCT BLOCK always @(posedge i_inclock) begin if (lpm_address_control == "REGISTERED") begin if ((we) && (use_eab != "ON") && (lpm_hint != "USE_EAB=ON")) begin if (lpm_indata == "REGISTERED") mem_data[address] <= data; else mem_data[address] <= pdata; end paddress <= address; pwe <= we; end if (lpm_indata == "REGISTERED") pdata <= data; end always @(data) begin if (lpm_indata == "UNREGISTERED") pdata <= data; end always @(address) begin if (lpm_address_control == "UNREGISTERED") paddress <= address; end always @(we) begin if (lpm_address_control == "UNREGISTERED") pwe <= we; end always @(pdata or paddress or pwe) begin :UNREGISTERED_INCLOCK if (ValidAddress(paddress)) begin if ((lpm_address_control == "UNREGISTERED") && (pwe)) mem_data[paddress] <= pdata; end else begin if (lpm_outdata == "UNREGISTERED") tmp_q <= {lpm_width{1'bx}}; end end always @(posedge i_outclock) begin if (lpm_outdata == "REGISTERED") begin if (ValidAddress(paddress)) tmp_q <= mem_data[paddress]; else tmp_q <= {lpm_width{1'bx}}; end end always @(i_inclock or pwe or paddress or pdata) begin if ((lpm_address_control == "REGISTERED") && (pwe)) if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON")) begin if (i_inclock == 1'b0) mem_data[paddress] = pdata; end end // CONTINOUS ASSIGNMENT assign q = (lpm_outdata == "UNREGISTERED") ? mem_data[paddress] : tmp_q; endmodule // lpm_ram_dq // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_ram_dp // // Description : Parameterized dual-port RAM megafunction. // // Limitation : n/a // // Results expected: Data output from the memory. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_ram_dp ( data, // Data input to the memory. (Required) rdaddress, // Read address input to the memory. (Required) wraddress, // Write address input to the memory. (Required) rdclock, // Positive-edge-triggered clock for read operation. rdclken, // Clock enable for rdclock. wrclock, // Positive-edge-triggered clock for write operation. wrclken, // Clock enable for wrclock. rden, // Read enable input. Disables reading when low (0). wren, // Write enable input. (Required) q // Data output from the memory. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the data[] and q[] ports. (Required) parameter lpm_widthad = 1; // Width of the rdaddress[] and wraddress[] ports. (Required) parameter lpm_numwords = 1 << lpm_widthad; // Number of words stored in memory. parameter lpm_indata = "REGISTERED"; // Determines the clock used by the data port. parameter lpm_rdaddress_control = "REGISTERED"; // Determines the clock used by the rdaddress and rden ports. parameter lpm_wraddress_control = "REGISTERED"; // Determines the clock used by the wraddress and wren ports. parameter lpm_outdata = "REGISTERED"; // Determines the clock used by the q[] pxort. parameter lpm_file = "UNUSED"; // Name of the file containing RAM initialization data. parameter use_eab = "ON"; // Specified whether to use the EAB or not. parameter rden_used = "TRUE"; // Specified whether to use the rden port or not. parameter intended_device_family = "Stratix"; parameter lpm_type = "lpm_ram_dp"; parameter lpm_hint = "UNUSED"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input [lpm_widthad-1:0] rdaddress; input [lpm_widthad-1:0] wraddress; input rdclock; input rdclken; input wrclock; input wrclken; input rden; input wren; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] mem_data [(1<= lpm_numwords) begin $display("%t:Error! Address out of bound on RAM.\n", $time); $display("Time: %0t Instance: %m", $time); end else ValidAddress = 1'b1; end endfunction // INITIAL CONSTRUCT BLOCK initial begin // Check for invalid parameters if (lpm_width < 1) begin $display("Error! lpm_width parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_widthad < 1) begin $display("Error! lpm_widthad parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED")) begin $display("Error! lpm_indata must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED")) begin $display("Error! lpm_outdata must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_wraddress_control != "REGISTERED") && (lpm_wraddress_control != "UNREGISTERED")) begin $display("Error! lpm_wraddress_control must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); end if ((lpm_rdaddress_control != "REGISTERED") && (lpm_rdaddress_control != "UNREGISTERED")) begin $display("Error! lpm_rdaddress_control must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (dev.IS_VALID_FAMILY(intended_device_family) == 0) begin $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family); $display("Time: %0t Instance: %m", $time); $finish; end // Initialize mem_data i_numwords = (lpm_numwords) ? lpm_numwords : (1< 0)) i_data_reg <= data; if (lpm_wraddress_control == "REGISTERED") if ((i_inclocken == 1'b1) && ($time > 0)) begin i_wraddress_reg <= wraddress; i_wren_reg <= i_wren; end end always @(posedge i_outclock) begin if (lpm_outdata == "REGISTERED") if ((i_outclocken == 1'b1) && ($time > 0)) begin i_q_reg <= i_q_tmp; end if (lpm_rdaddress_control == "REGISTERED") if ((i_outclocken == 1'b1) && ($time > 0)) begin i_rdaddress_reg <= rdaddress; i_rden_reg <= i_rden; end end //========= // Memory //========= always @(i_data_tmp or i_wren_tmp or i_wraddress_tmp or negedge i_inclock) begin if (i_wren_tmp == 1'b1) if (ValidAddress(i_wraddress_tmp)) begin if (((use_eab == "ON") || (lpm_hint == "USE_EAB=ON")) && (lpm_wraddress_control == "REGISTERED")) begin if (i_inclock == 1'b0) mem_data[i_wraddress_tmp] <= i_data_tmp; end else mem_data[i_wraddress_tmp] <= i_data_tmp; end end always @(i_rden_tmp or i_rdaddress_tmp or mem_data[i_rdaddress_tmp]) begin if (i_rden_tmp == 1'b1) i_q_tmp = (ValidAddress(i_rdaddress_tmp)) ? mem_data[i_rdaddress_tmp] : {lpm_width{1'bx}}; end //======= // Sync //======= always @(wraddress or i_wraddress_reg) i_wraddress_tmp = (lpm_wraddress_control == "REGISTERED") ? i_wraddress_reg : wraddress; always @(rdaddress or i_rdaddress_reg) i_rdaddress_tmp = (lpm_rdaddress_control == "REGISTERED") ? i_rdaddress_reg : rdaddress; always @(i_wren or i_wren_reg) i_wren_tmp = (lpm_wraddress_control == "REGISTERED") ? i_wren_reg : i_wren; always @(i_rden or i_rden_reg) i_rden_tmp = (lpm_rdaddress_control == "REGISTERED") ? i_rden_reg : i_rden; always @(data or i_data_reg) i_data_tmp = (lpm_indata == "REGISTERED") ? i_data_reg : data; // CONTINOUS ASSIGNMENT assign q = (lpm_outdata == "REGISTERED") ? i_q_reg : i_q_tmp; endmodule // lpm_ram_dp // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_ram_io // // Description : Parameterized RAM with a single I/O port megafunction // // Limitation : This megafunction is provided only for backward // compatibility in Cyclone, Stratix, and Stratix GX designs; // instead, Altera recommends using the altsyncram // megafunction // // Results expected: Output of RAM content at bi-directional DIO. // //END_MODULE_NAME-------------------------------------------------------------- `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_ram_io ( dio, inclock, outclock, we, memenab, outenab, address ); // PARAMETER DECLARATION parameter lpm_type = "lpm_ram_io"; parameter lpm_width = 1; parameter lpm_widthad = 1; parameter lpm_numwords = 1<< lpm_widthad; parameter lpm_indata = "REGISTERED"; parameter lpm_address_control = "REGISTERED"; parameter lpm_outdata = "REGISTERED"; parameter lpm_file = "UNUSED"; parameter lpm_hint = "UNUSED"; parameter use_eab = "ON"; parameter intended_device_family = "UNUSED"; // INPUT PORT DECLARATION input [lpm_widthad-1:0] address; input inclock, outclock, we; input memenab; input outenab; // INPUT/OUTPUT PORT DECLARATION inout [lpm_width-1:0] dio; // INTERNAL REGISTERS DECLARATION reg [lpm_width-1:0] mem_data [lpm_numwords-1:0]; reg [lpm_width-1:0] tmp_io; reg [lpm_width-1:0] tmp_q; reg [lpm_width-1:0] pdio; reg [lpm_widthad-1:0] paddress; reg [lpm_widthad-1:0] paddress_tmp; reg pwe; `ifdef VERILATOR reg [`LPM_MAX_NAME_SZ*8:1] ram_initf; `else reg [8*256:1] ram_initf; `endif // INTERNAL WIRE DECLARATION wire [lpm_width-1:0] read_data; wire i_inclock; wire i_outclock; wire i_memenab; wire i_outenab; // LOCAL INTEGER DECLARATION integer i; // INTERNAL TRI DECLARATION tri0 inclock; tri0 outclock; tri1 memenab; tri1 outenab; // INTERNAL BUF DECLARATION buf (i_inclock, inclock); buf (i_outclock, outclock); buf (i_memenab, memenab); buf (i_outenab, outenab); // FUNCTON DECLARATION function ValidAddress; input [lpm_widthad-1:0] paddress; begin ValidAddress = 1'b0; if (^paddress === {lpm_widthad{1'bx}}) begin $display("%t:Error: Invalid address.", $time); $display("Time: %0t Instance: %m", $time); $finish; end else if (paddress >= lpm_numwords) begin $display("%t:Error: Address out of bound on RAM.", $time); $display("Time: %0t Instance: %m", $time); $finish; end else ValidAddress = 1'b1; end endfunction // COMPONENT INSTANTIATIONS LPM_MEMORY_INITIALIZATION mem (); // INITIAL CONSTRUCT BLOCK initial begin if (lpm_width <= 0) begin $display("Error! LPM_WIDTH parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_widthad <= 0) begin $display("Error! LPM_WIDTHAD parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end // check for number of words out of bound if ((lpm_numwords > (1 << lpm_widthad)) ||(lpm_numwords <= (1 << (lpm_widthad-1)))) begin $display("Error! The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED")) begin $display("Error! LPM_INDATA must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED")) begin $display("Error! LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED")) begin $display("Error! LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end for (i = 0; i < lpm_numwords; i=i+1) mem_data[i] = {lpm_width{1'b0}}; // Initialize input/output pwe = 1'b0; pdio = {lpm_width{1'b0}}; paddress = {lpm_widthad{1'b0}}; paddress_tmp = {lpm_widthad{1'b0}}; tmp_io = {lpm_width{1'b0}}; tmp_q = {lpm_width{1'b0}}; // load data to the RAM if (lpm_file != "UNUSED") begin mem.convert_to_ver_file(lpm_file, lpm_width, ram_initf); $readmemh(ram_initf, mem_data); end end // ALWAYS CONSTRUCT BLOCK always @(dio) begin if (lpm_indata == "UNREGISTERED") pdio <= dio; end always @(address) begin if (lpm_address_control == "UNREGISTERED") paddress <= address; end always @(we) begin if (lpm_address_control == "UNREGISTERED") pwe <= we; end always @(posedge i_inclock) begin if (lpm_indata == "REGISTERED") pdio <= dio; if (lpm_address_control == "REGISTERED") begin paddress <= address; pwe <= we; end end always @(pdio or paddress or pwe or i_memenab) begin if (ValidAddress(paddress)) begin paddress_tmp <= paddress; if (lpm_address_control == "UNREGISTERED") if (pwe && i_memenab) mem_data[paddress] <= pdio; end else begin if (lpm_outdata == "UNREGISTERED") tmp_q <= {lpm_width{1'bx}}; end end always @(read_data) begin if (lpm_outdata == "UNREGISTERED") tmp_q <= read_data; end always @(negedge i_inclock or pdio) begin if (lpm_address_control == "REGISTERED") if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON")) if (pwe && i_memenab && (i_inclock == 1'b0)) mem_data[paddress] = pdio; end always @(posedge i_inclock) begin if (lpm_address_control == "REGISTERED") if ((use_eab == "OFF") && pwe && i_memenab) mem_data[paddress] <= pdio; end always @(posedge i_outclock) begin if (lpm_outdata == "REGISTERED") tmp_q <= mem_data[paddress]; end always @(i_memenab or i_outenab or tmp_q) begin if (i_memenab && i_outenab) tmp_io = tmp_q; else if ((!i_memenab) || (i_memenab && (!i_outenab))) tmp_io = {lpm_width{1'bz}}; end // CONTINOUS ASSIGNMENT assign dio = tmp_io; assign read_data = mem_data[paddress_tmp]; endmodule // lpm_ram_io //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_rom // // Description : Parameterized ROM megafunction. This megafunction is provided // only for backward compatibility in Cyclone, Stratix, and // Stratix GX designs; instead, Altera recommends using the // altsyncram megafunction. // // Limitation : This option is available for all Altera devices supported by // the Quartus II software except MAX 3000 and MAX 7000 devices. // // Results expected: Output of memory. // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_rom ( address, // Address input to the memory. (Required) inclock, // Clock for input registers. outclock, // Clock for output registers. memenab, // Memory enable input. q // Output of memory. (Required) ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; // Width of the q[] port. (Required) parameter lpm_widthad = 1; // Width of the address[] port. (Required) parameter lpm_numwords = 0; // Number of words stored in memory. parameter lpm_address_control = "REGISTERED"; // Indicates whether the address port is registered. parameter lpm_outdata = "REGISTERED"; // Indicates whether the q and eq ports are registered. parameter lpm_file = ""; // Name of the memory file containing ROM initialization data parameter intended_device_family = "Stratix"; parameter lpm_type = "lpm_rom"; parameter lpm_hint = "UNUSED"; // LOCAL_PARAMETERS_BEGIN parameter NUM_WORDS = (lpm_numwords == 0) ? (1 << lpm_widthad) : lpm_numwords; // LOCAL_PARAMETERS_END // INPUT PORT DECLARATION input [lpm_widthad-1:0] address; input inclock; input outclock; input memenab; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; // INTERNAL REGISTER/SIGNAL DECLARATION reg [lpm_width-1:0] mem_data [0:NUM_WORDS-1]; reg [lpm_widthad-1:0] address_reg; reg [lpm_width-1:0] tmp_q_reg; `ifdef VERILATOR reg [`LPM_MAX_NAME_SZ*8:1] rom_initf; `else reg [8*256:1] rom_initf; `endif // INTERNAL WIRE DECLARATION wire [lpm_widthad-1:0] w_address; wire [lpm_width-1:0] w_read_data; wire i_inclock; wire i_outclock; wire i_memenab; // LOCAL INTEGER DECLARATION integer i; // INTERNAL TRI DECLARATION tri0 inclock; tri0 outclock; tri1 memenab; buf (i_inclock, inclock); buf (i_outclock, outclock); buf (i_memenab, memenab); // COMPONENT INSTANTIATIONS LPM_DEVICE_FAMILIES dev (); LPM_MEMORY_INITIALIZATION mem (); // FUNCTON DECLARATION // Check the validity of the address. function ValidAddress; input [lpm_widthad-1:0] address; begin ValidAddress = 1'b0; if (^address == {lpm_widthad{1'bx}}) begin $display("%d:Error: Invalid address.", $time); $display("Time: %0t Instance: %m", $time); $finish; end else if (address >= NUM_WORDS) begin $display("%d:Error: Address out of bound on ROM.", $time); $display("Time: %0t Instance: %m", $time); $finish; end else ValidAddress = 1'b1; end endfunction // INITIAL CONSTRUCT BLOCK initial begin // Initialize output tmp_q_reg = {lpm_width{1'b0}}; address_reg = {lpm_widthad{1'b0}}; if (lpm_width <= 0) begin $display("Error! LPM_WIDTH parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end if (lpm_widthad <= 0) begin $display("Error! LPM_WIDTHAD parameter must be greater than 0."); $display("Time: %0t Instance: %m", $time); $finish; end // check for number of words out of bound if ((NUM_WORDS > (1 << lpm_widthad)) || (NUM_WORDS <= (1 << (lpm_widthad-1)))) begin $display("Error! The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED")) begin $display("Error! LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED")) begin $display("Error! LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\"."); $display("Time: %0t Instance: %m", $time); $finish; end if (dev.IS_VALID_FAMILY(intended_device_family) == 0) begin $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family); $display("Time: %0t Instance: %m", $time); $finish; end if (dev.FEATURE_FAMILY_MAX(intended_device_family) == 1) begin $display ("Error! LPM_ROM megafunction does not support %s devices.", intended_device_family); $display("Time: %0t Instance: %m", $time); $finish; end for (i = 0; i < NUM_WORDS; i=i+1) mem_data[i] = {lpm_width{1'b0}}; // load data to the ROM if ((lpm_file == "") || (lpm_file == "UNUSED")) begin $display("Warning: LPM_ROM must have data file for initialization.\n"); $display ("Time: %0t Instance: %m", $time); end else begin mem.convert_to_ver_file(lpm_file, lpm_width, rom_initf); $readmemh(rom_initf, mem_data); end end always @(posedge i_inclock) begin if (lpm_address_control == "REGISTERED") address_reg <= address; // address port is registered end always @(w_address or w_read_data) begin if (ValidAddress(w_address)) begin if (lpm_outdata == "UNREGISTERED") // Load the output register with the contents of the memory location // pointed to by address[]. tmp_q_reg <= w_read_data; end else begin if (lpm_outdata == "UNREGISTERED") tmp_q_reg <= {lpm_width{1'bx}}; end end always @(posedge i_outclock) begin if (lpm_outdata == "REGISTERED") begin if (ValidAddress(w_address)) tmp_q_reg <= w_read_data; else tmp_q_reg <= {lpm_width{1'bx}}; end end // CONTINOUS ASSIGNMENT assign w_address = (lpm_address_control == "REGISTERED") ? address_reg : address; assign w_read_data = mem_data[w_address]; assign q = (i_memenab) ? tmp_q_reg : {lpm_width{1'bz}}; endmodule // lpm_rom // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_fifo // // Description : // // Limitation : // // Results expected: // //END_MODULE_NAME-------------------------------------------------------------- `timescale 1 ps / 1 ps module lpm_fifo ( data, clock, wrreq, rdreq, aclr, sclr, q, usedw, full, empty ); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; parameter lpm_widthu = 1; parameter lpm_numwords = 2; parameter lpm_showahead = "OFF"; parameter lpm_type = "lpm_fifo"; parameter lpm_hint = ""; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input clock; input wrreq; input rdreq; input aclr; input sclr; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; output [lpm_widthu-1:0] usedw; output full; output empty; // INTERNAL REGISTERS DECLARATION reg [lpm_width-1:0] mem_data [(1< (1 << lpm_widthu))) begin $display ("Error! LPM_NUMWORDS must equal to the ceiling of log2(LPM_WIDTHU)."); $display("Time: %0t Instance: %m", $time); $stop; end if (lpm_numwords <= (1 << (lpm_widthu - 1))) begin $display ("Error! LPM_WIDTHU is too big for the specified LPM_NUMWORDS."); $display("Time: %0t Instance: %m", $time); $stop; end overflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "OVERFLOW_CHECKING"); if(overflow_checking == "") overflow_checking = "ON"; else if ((overflow_checking != "ON") && (overflow_checking != "OFF")) begin $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end underflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "UNDERFLOW_CHECKING"); if(underflow_checking == "") underflow_checking = "ON"; else if ((underflow_checking != "ON") && (underflow_checking != "OFF")) begin $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end allow_rwcycle_when_full = eva.GET_PARAMETER_VALUE(lpm_hint, "ALLOW_RWCYCLE_WHEN_FULL"); if (allow_rwcycle_when_full == "") allow_rwcycle_when_full = "OFF"; else if ((allow_rwcycle_when_full != "ON") && (allow_rwcycle_when_full != "OFF")) begin $display ("Error! ALLOW_RWCYCLE_WHEN_FULL must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end intended_device_family = eva.GET_PARAMETER_VALUE(lpm_hint, "INTENDED_DEVICE_FAMILY"); if (intended_device_family == "") intended_device_family = "Stratix II"; else if (dev.IS_VALID_FAMILY(intended_device_family) == 0) begin $display ("Error! Unknown INTENDED_DEVICE_FAMILY=%s.", intended_device_family); $display("Time: %0t Instance: %m", $time); $stop; end for (i = 0; i < (1<= ((1 << lpm_widthu) - 1)) begin if (lpm_showahead == "ON") tmp_q <= mem_data[0]; else tmp_q <= mem_data[read_id]; read_id <= 0; end else begin if (lpm_showahead == "ON") tmp_q <= mem_data[read_id + 1]; else tmp_q <= mem_data[read_id]; read_id <= read_id + 1; end end // WRITE operation only else if (valid_wreq) begin tmp_data <= data; empty_flag <= 1'b0; write_flag <= 1'b1; if (count_id >= (1 << lpm_widthu) - 1) count_id <= 0; else count_id <= count_id + 1; if ((count_id == lpm_numwords - 1) && (empty_flag == 1'b0)) full_flag <= 1'b1; if (lpm_showahead == "ON") tmp_q <= mem_data[read_id]; end // READ operation only else if (valid_rreq) begin full_flag <= 1'b0; if (count_id <= 0) count_id <= {lpm_widthu{1'b1}}; else count_id <= count_id - 1; if ((count_id == 1) && (full_flag == 1'b0)) empty_flag <= 1'b1; if (read_id >= ((1<= ((1 << lpm_widthu) - 1))) write_id <= 0; else write_id <= write_id + 1; end if ((lpm_showahead == "ON") && ($time > 0)) tmp_q <= ((write_flag == 1'b1) && (write_id == read_id)) ? tmp_data : mem_data[read_id]; end // @(negedge clock) // CONTINOUS ASSIGNMENT assign valid_rreq = (underflow_checking == "OFF") ? rdreq : rdreq && ~empty_flag; assign valid_wreq = (overflow_checking == "OFF") ? wrreq : (allow_rwcycle_when_full == "ON") ? wrreq && (!full_flag || rdreq) : wrreq && !full_flag; assign q = tmp_q; assign full = full_flag; assign empty = empty_flag; assign usedw = count_id; endmodule // lpm_fifo // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_fifo_dc_dffpipe // // Description : Dual Clocks FIFO // // Limitation : // // Results expected: // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_fifo_dc_dffpipe (d, clock, aclr, q); // GLOBAL PARAMETER DECLARATION parameter lpm_delay = 1; parameter lpm_width = 64; // INPUT PORT DECLARATION input [lpm_width-1:0] d; input clock; input aclr; // OUTPUT PORT DECLARATION output [lpm_width-1:0] q; // INTERNAL REGISTERS DECLARATION reg [lpm_width-1:0] dffpipe [lpm_delay:0]; reg [lpm_width-1:0] q; // LOCAL INTEGER DECLARATION integer delay; integer i; // INITIAL CONSTRUCT BLOCK initial begin delay <= lpm_delay - 1; for (i = 0; i <= lpm_delay; i = i + 1) dffpipe[i] <= 0; q <= 0; end // ALWAYS CONSTRUCT BLOCK always @(posedge aclr or posedge clock) begin if (aclr) begin for (i = 0; i <= lpm_delay; i = i + 1) dffpipe[i] <= 0; q <= 0; end else if (clock) begin if ((lpm_delay > 0) && ($time > 0)) begin `ifdef VERILATOR if (lpm_delay > 0) `else if (delay > 0) `endif begin `ifdef VERILATOR for (i = lpm_delay-1; i > 0; i = i - 1) `else for (i = delay; i > 0; i = i - 1) `endif dffpipe[i] <= dffpipe[i - 1]; q <= dffpipe[delay - 1]; end else q <= d; dffpipe[0] <= d; end end end // @(posedge aclr or posedge clock) always @(d) begin if (lpm_delay == 0) q <= d; end // @(d) endmodule // lpm_fifo_dc_dffpipe // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_fifo_dc_fefifo // // Description : Dual Clock FIFO // // Limitation : // // Results expected: // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_fifo_dc_fefifo ( usedw_in, wreq, rreq, clock, aclr, empty, full); // GLOBAL PARAMETER DECLARATION parameter lpm_widthad = 1; parameter lpm_numwords = 1; parameter underflow_checking = "ON"; parameter overflow_checking = "ON"; parameter lpm_mode = "READ"; parameter lpm_hint = ""; // INPUT PORT DECLARATION input [lpm_widthad-1:0] usedw_in; input wreq; input rreq; input clock; input aclr; // OUTPUT PORT DECLARATION output empty; output full; // INTERNAL REGISTERS DECLARATION reg [1:0] sm_empty; reg lrreq; reg i_empty; reg i_full; reg [8*5:1] i_overflow_checking; reg [8*5:1] i_underflow_checking; // LOCAL INTEGER DECLARATION integer almostfull; // COMPONENT INSTANTIATIONS LPM_HINT_EVALUATION eva(); // INITIAL CONSTRUCT BLOCK initial begin if ((lpm_mode != "READ") && (lpm_mode != "WRITE")) begin $display ("Error! LPM_MODE must be READ or WRITE."); $display("Time: %0t Instance: %m", $time); $stop; end i_overflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "OVERFLOW_CHECKING"); if (i_overflow_checking == "") begin if ((overflow_checking != "ON") && (overflow_checking != "OFF")) begin $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end else i_overflow_checking = overflow_checking; end else if ((i_overflow_checking != "ON") && (i_overflow_checking != "OFF")) begin $display ("Error! OVERFLOW_CHECKING must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end i_underflow_checking = eva.GET_PARAMETER_VALUE(lpm_hint, "UNDERFLOW_CHECKING"); if(i_underflow_checking == "") begin if ((underflow_checking != "ON") && (underflow_checking != "OFF")) begin $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end else i_underflow_checking = underflow_checking; end else if ((i_underflow_checking != "ON") && (i_underflow_checking != "OFF")) begin $display ("Error! UNDERFLOW_CHECKING must equal to either 'ON' or 'OFF'"); $display("Time: %0t Instance: %m", $time); $stop; end sm_empty <= 2'b00; i_empty <= 1'b1; i_full <= 1'b0; lrreq <= 1'b0; if (lpm_numwords >= 3) almostfull <= lpm_numwords - 3; else almostfull <= 0; end // ALWAYS CONSTRUCT BLOCK always @(posedge aclr) begin sm_empty <= 2'b00; i_empty <= 1'b1; i_full <= 1'b0; lrreq <= 1'b0; end // @(posedge aclr) always @(posedge clock) begin if (i_underflow_checking == "OFF") lrreq <= rreq; else lrreq <= rreq && ~i_empty; if (~aclr && ($time > 0)) begin if (lpm_mode == "READ") begin // verilator lint_off CASEX casex (sm_empty) // verilator lint_on CASEX // state_empty 2'b00: if (usedw_in != 0) sm_empty <= 2'b01; // state_non_empty // verilator lint_off CMPCONST 2'b01: if (rreq && (((usedw_in == 1) && !lrreq) || ((usedw_in == 2) && lrreq))) sm_empty <= 2'b10; // state_emptywait 2'b10: if (usedw_in > 1) sm_empty <= 2'b01; else sm_empty <= 2'b00; // verilator lint_on CMPCONST default: begin $display ("Error! Invalid sm_empty state in read mode."); $display("Time: %0t Instance: %m", $time); end endcase end // if (lpm_mode == "READ") else if (lpm_mode == "WRITE") begin // verilator lint_off CASEX casex (sm_empty) // verilator lint_on CASEX // state_empty 2'b00: if (wreq) sm_empty <= 2'b01; // state_one 2'b01: if (!wreq) sm_empty <= 2'b11; // state_non_empty 2'b11: if (wreq) sm_empty <= 2'b01; else if (usedw_in == 0) sm_empty <= 2'b00; default: begin $display ("Error! Invalid sm_empty state in write mode."); $display("Time: %0t Instance: %m", $time); end endcase end // if (lpm_mode == "WRITE") if (~aclr && (usedw_in >= almostfull) && ($time > 0)) i_full <= 1'b1; else i_full <= 1'b0; end // if (~aclr && $time > 0) end // @(posedge clock) always @(sm_empty) begin i_empty <= !sm_empty[0]; end // @(sm_empty) // CONTINOUS ASSIGNMENT assign empty = i_empty; assign full = i_full; endmodule // lpm_fifo_dc_fefifo // END OF MODULE //START_MODULE_NAME------------------------------------------------------------ // // Module Name : lpm_fifo_dc_async // // Description : Asynchronous Dual Clocks FIFO // // Limitation : // // Results expected: // //END_MODULE_NAME-------------------------------------------------------------- // BEGINNING OF MODULE `timescale 1 ps / 1 ps // MODULE DECLARATION module lpm_fifo_dc_async ( data, rdclk, wrclk, aclr, rdreq, wrreq, rdfull, wrfull, rdempty, wrempty, rdusedw, wrusedw, q); // GLOBAL PARAMETER DECLARATION parameter lpm_width = 1; parameter lpm_widthu = 1; parameter lpm_numwords = 2; parameter delay_rdusedw = 1; parameter delay_wrusedw = 1; parameter rdsync_delaypipe = 3; parameter wrsync_delaypipe = 3; parameter lpm_showahead = "OFF"; parameter underflow_checking = "ON"; parameter overflow_checking = "ON"; parameter lpm_hint = "INTENDED_DEVICE_FAMILY=Stratix"; // INPUT PORT DECLARATION input [lpm_width-1:0] data; input rdclk; input wrclk; input aclr; input wrreq; input rdreq; // OUTPUT PORT DECLARATION output rdfull; output wrfull; output rdempty; output wrempty; output [lpm_widthu-1:0] rdusedw; output [lpm_widthu-1:0] wrusedw; output [lpm_width-1:0] q; // INTERNAL REGISTERS DECLARATION reg [lpm_width-1:0] mem_data [(1< 0)) begin i_data_tmp <= data; i_wrptr_tmp <= i_wrptr; i_wren_tmp <= w_wren; if (w_wren) begin if (~aclr && ((i_wrptr < (1< 0)) begin if (i_wren_tmp) begin mem_data[i_wrptr_tmp] <= i_data_tmp; end if (lpm_showahead == "ON") i_showahead_flag1 <= 1'b1; end end // @(negedge wrclk) always @(posedge rdclk) begin if (aclr && (!(dev.FEATURE_FAMILY_BASE_STRATIX(intended_device_family) || dev.FEATURE_FAMILY_BASE_CYCLONE(intended_device_family)) || (use_eab == "OFF"))) begin if (lpm_showahead == "ON") i_q_tmp <= mem_data[0]; else i_q_tmp <= 0; end else if (rdclk && w_rden && ($time > 0)) begin if (~aclr && ((i_rdptr < (1<