OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [orp/] [orp_soc/] [lib/] [altera/] [220model.v] - Rev 1782

Compare with Previous | Blame | View Log

//------------------------------------------------------------------------
//   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.
//
//------------------------------------------------------------------------
// LPM Synthesizable Models 
// These models are based on LPM version 220 (EIA-IS103 October 1998).
//-----------------------------------------------------------------------
// Version Quartus v2.0 (lpm 220)      Date 08/28/01
//
// 08/28/01: Support for non-pli flow for convert_hex2ver
//
//----------------------------------------------------------------------- 
// Version Quartus v1.1 (lpm 220)      Date 04/17/01
//
// 04/09/01: Fix 82832; inappropriate use of blocking assignments in
//           lpm_ram_dq, lpm_ram_io, lpm_ram_dp, lpm_rom.
// 04/09/01: Make dcfifo and lpm_fifo_dc models consistent.
// 04/05/01: Fix 82832; race condition in lpm_ram_dq with VerilogXL.
// 03/20/01: Fix SPR 82096; the memenab & outenab signals are not 
//           initialized for lpm_ram_io.
// 01/23/01: Adding use_eab=on support for lpm_ram_io, lpm_ram_dp and
//           lpm_ram_dq.
//------------------------------------------------------------------------
// Version Quartus v1.0 (lpm 220)      Date 12/8/00
//
// 12/8/00: Fix SPR78303. Remove use of blocking assignments in
//          lpm_fifo_dc
// 12/5/00: Changed lpm_ram_dp rdclken, and wrclken to connect to pull up
//          properly.
//------------------------------------------------------------------------
// Version 1.6 (lpm 220)      Date 10/2/00
//
// Changed the behaviour of LPM_FIFO_DC to match that of Quartus.
// Changed data port of LPM_LATCH to be initialized with 0.
// Fixed LPM_COUNTER, LPM_FF, LPM_SHIFTREG to output correctly after
//   aclr goes low but before any clock edge, and to output x's when
//   both aclr and aset are high.
// Changed q port of LPM_FF and LPM_SHIFTREG to be initialized with 0.
// Fixed underflow and overflow port of LPM_CLSHIFT in ROTATE mode.
// Added LPM_REMAINDERPOSITIVE parameter to LPM_DIVIDE.  This is a
//   non-LPM 220 standard parameter.  It defaults to TRUE for LPM 220
//   behaviour.
// Fixed LPM_MULT to output correctly.
// Changed default value of CIN port of LPM_ADD_SUB when subtract.
// Changed output pipelines of LPM_ADD_SUB to be initialized with 0's.
// Fixed overflow port of LPM_ADD_SUB for singned inputs.
// Added DATA port to the sensitivity list in LPM_COUNTER and LPM_FF.
//   Synthesis tools do not allow mixing of level and edge sensitive
//   signals, and hence DATA port was omitted from the list.
// Corrected the interpretation of CIN port of LPM_COUNTER.
// Fixed LPM_RAM_DP, LPM_RAM_DQ, and LPM_RAM_IO to write data at rising
//   clock edge and to output correctly.
// Fixed COUT port of LPM_COUNTER to go high when count is all 1's.
//
//------------------------------------------------------------------------
// Version 1.59 (lpm 220)     Date 5/4/00
//
// Corrected LPM_FIFO_DC rdempty flag.
// Updated comments in header about synthesis issues.
// Fixed error detection of LPM_DIRECTION and UPDOWN conflict in
//   LPM_COUNTER.
// Changed LPM_ROM to have no default name for initialization file.
//
//------------------------------------------------------------------------
// Version 1.5 (lpm 220)      Date 12/17/99
//
// Modified LPM_ADD_SUB and LPM_MULT to accomodate LPM_WIDTH = 1.
//   Default values for LPM_WIDTH* are changed back to 1.
// Added LPM_HINT to LPM_DIVIDE.
// Rewritten LPM_FIFO_DC to output correctly.
// Modified LPM_FIFO to output 0s before first read, output correct
//   values after aclr and sclr, and output LPM_NUMWORDS mod
//   exp(2, LPM_WIDTHU) when FIFO is full.
//
//------------------------------------------------------------------------
// Version 1.4.1 (lpm 220)    Date 10/29/99
//
// Default values for LPM_WIDTH* of LPM_ADD_SUB and LPM_MULT are changed
//   from 1 to 2.
//
//------------------------------------------------------------------------
// Version 1.4 (lpm 220)      Date 10/18/99
//
// Default values for each optional inputs for ALL modules are added.
// Some LPM_PVALUE implementations were missing, and now implemented.
//
//------------------------------------------------------------------------
// Version 1.3 (lpm 220)      Date 06/23/99
//
// Corrected LPM_FIFO and LPM_FIFO_DC cout and empty/full flags.
// Implemented LPM_COUNTER cin/cout, and LPM_MODULUS is now working.
//
//------------------------------------------------------------------------
// Version 1.2 (lpm 220)      Date 06/16/99
//
// Added LPM_RAM_DP, LPM_RAM_DQ, LPM_IO, LPM_ROM, LPM_FIFO, LPM_FIFO_DC.
// Parameters and ports are added/discarded according to the spec.
//
//------------------------------------------------------------------------
// Version 1.1 (lpm 220)      Date 02/05/99
//
// Added LPM_DIVIDE module.
//
//------------------------------------------------------------------------
// Version 1.0                Date 07/09/97
//
//------------------------------------------------------------------------
// Excluded Functions:
//
//  LPM_FSM and LPM_TTABLE.
//
//------------------------------------------------------------------------
// 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.
//
//------------------------------------------------------------------------
 
 
`define NO_PLI
 
module lpm_constant ( result );
 
	parameter lpm_type = "lpm_constant";
	parameter lpm_width = 1;
	parameter lpm_cvalue = 0;
	parameter lpm_strength = "UNUSED";
	parameter lpm_hint = "UNUSED";
 
	output [lpm_width-1:0] result;
 
	assign result = lpm_cvalue;
 
endmodule // lpm_constant
 
//------------------------------------------------------------------------
 
module lpm_inv ( result, data );
 
	parameter lpm_type = "lpm_inv";
	parameter lpm_width = 1;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] data;
	output [lpm_width-1:0] result;
 
	reg    [lpm_width-1:0] result;
 
    always @(data)
        result = ~data;
 
endmodule // lpm_inv
 
//------------------------------------------------------------------------
 
module lpm_and ( result, data );
 
	parameter lpm_type = "lpm_and";
	parameter lpm_width = 1;
	parameter lpm_size = 1;
	parameter lpm_hint = "UNUSED";
 
	input  [(lpm_size * lpm_width)-1:0] data;
	output [lpm_width-1:0] result;
 
	reg    [lpm_width-1:0] result;
	integer i, j, k;
 
	always @(data)
	begin
		for (i=0; i<lpm_width; i=i+1)
		begin
			result[i] = data[i];
			for (j=1; j<lpm_size; j=j+1)
			begin
				k = j * lpm_width + i;
				result[i] = result[i] & data[k];
			end
		end
	end
 
endmodule // lpm_and
 
//------------------------------------------------------------------------
 
module lpm_or ( result, data );
 
    parameter lpm_type = "lpm_or";
	parameter lpm_width = 1;
	parameter lpm_size = 1;
	parameter lpm_hint  = "UNUSED";
 
	input  [(lpm_size * lpm_width)-1:0] data;
	output [lpm_width-1:0] result;
 
	reg    [lpm_width-1:0] result;
	integer i, j, k;
 
	always @(data)
	begin
		for (i=0; i<lpm_width; i=i+1)
		begin
			result[i] = data[i];
			for (j=1; j<lpm_size; j=j+1)
			begin
				k = j * lpm_width + i;
				result[i] = result[i] | data[k];
			end
		end
	end
 
endmodule // lpm_or
 
//------------------------------------------------------------------------
 
module lpm_xor ( result, data );
 
	parameter lpm_type = "lpm_xor";
	parameter lpm_width = 1;
	parameter lpm_size = 1;
	parameter lpm_hint  = "UNUSED";
 
	input  [(lpm_size * lpm_width)-1:0] data;
	output [lpm_width-1:0] result;
 
	reg    [lpm_width-1:0] result;
	integer i, j, k;
 
	always @(data)
	begin
		for (i=0; i<lpm_width; i=i+1)
		begin
			result[i] = data[i];
			for (j=1; j<lpm_size; j=j+1)
			begin
				k = j * lpm_width + i;
				result[i] = result[i] ^ data[k];
			end
		end
	end
 
endmodule // lpm_xor
 
//------------------------------------------------------------------------
 
module lpm_bustri ( result, tridata, data, enabledt, enabletr );
 
	parameter lpm_type = "lpm_bustri";
	parameter lpm_width = 1;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] data;
	input  enabledt;
	input  enabletr;
	output [lpm_width-1:0] result;
	inout  [lpm_width-1:0] tridata;
 
	reg    [lpm_width-1:0] result;
	reg    [lpm_width-1:0] tmp_tridata;
 
	tri0  enabledt;
	tri0  enabletr;
	buf (i_enabledt, enabledt);
	buf (i_enabletr, enabletr);
 
	always @(data or tridata or i_enabletr or i_enabledt)
	begin
        if (i_enabledt == 0 && i_enabletr == 1)
		begin
			result = tridata;
			tmp_tridata = 'bz;
		end
        else if (i_enabledt == 1 && i_enabletr == 0)
		begin
			result = 'bz;
			tmp_tridata = data;
		end
        else if (i_enabledt == 1 && i_enabletr == 1)
		begin
			result = data;
			tmp_tridata = data;
		end
		else
		begin
			result = 'bz;
			tmp_tridata = 'bz;
		end
	end
 
	assign tridata = tmp_tridata;
 
endmodule // lpm_bustri
 
//------------------------------------------------------------------------
 
module lpm_mux ( result, clock, clken, data, aclr, sel );
 
	parameter lpm_type = "lpm_mux";
	parameter lpm_width = 1;
	parameter lpm_size = 1;
	parameter lpm_widths = 1;
	parameter lpm_pipeline = 0;
	parameter lpm_hint  = "UNUSED";
 
	input [(lpm_size * lpm_width)-1:0] data;
	input aclr;
	input clock;
	input clken;
	input [lpm_widths-1:0] sel;
	output [lpm_width-1:0] result;
 
	reg [lpm_width-1:0] tmp_result2 [lpm_pipeline:0];
    reg [lpm_width-1:0] tmp_result;
    integer i;
 
	tri0 aclr;
	tri0 clock;
	tri1 clken;
 
	buf (i_aclr, aclr);
	buf (i_clock, clock);
	buf (i_clken, clken);
 
    always @(data or sel or i_aclr)
	begin
		if (i_aclr)
			for (i = 0; i <= lpm_pipeline; i = i + 1)
				tmp_result2[i] = 'b0;
        else
        begin
            tmp_result = 0;
            for (i = 0; i < lpm_width; i = i + 1)
                tmp_result[i] = data[sel * lpm_width + i];
            tmp_result2[lpm_pipeline] = tmp_result;
        end
	end
 
    always @(posedge i_clock)
	begin
        if (!i_aclr && i_clken == 1)
            for (i = 0; i < lpm_pipeline; i = i + 1)
                tmp_result2[i] <= tmp_result2[i+1];
	end
 
    assign result = tmp_result2[0];
endmodule // lpm_mux
 
//------------------------------------------------------------------------
 
module lpm_decode ( eq, data, enable, clock, clken, aclr );
 
	parameter lpm_type = "lpm_decode";
	parameter lpm_width = 1;
	parameter lpm_decodes = 1 << lpm_width;
	parameter lpm_pipeline = 0;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] data;
	input  enable;
    input  clock;
	input  clken;
	input  aclr;
	output [lpm_decodes-1:0] eq;
 
    reg    [lpm_decodes-1:0] tmp_eq2 [lpm_pipeline:0];
    reg    [lpm_decodes-1:0] tmp_eq;
    integer i;
 
	tri0   clock;
	tri1   clken;
	tri0   aclr;
	tri1   enable;
 
	buf (i_clock, clock);
	buf (i_clken, clken);
	buf (i_aclr, aclr);
	buf (i_enable, enable);
 
 
    always @(data or i_enable or i_aclr)
	begin
        if (i_aclr)
			for (i = 0; i <= lpm_pipeline; i = i + 1)
                tmp_eq2[i] = 'b0;
        else
        begin
            tmp_eq = 0;
            if (i_enable)
                tmp_eq[data] = 1'b1;
            tmp_eq2[lpm_pipeline] = tmp_eq;
        end
	end
 
    always @(posedge i_clock)
	begin
        if (!i_aclr && clken == 1)
            for (i = 0; i < lpm_pipeline; i = i + 1)
                tmp_eq2[i] <= tmp_eq2[i+1];
	end
 
    assign eq = tmp_eq2[0];
 
endmodule // lpm_decode
 
//------------------------------------------------------------------------
 
module lpm_clshift ( result, overflow, underflow, data, direction, distance );
 
	parameter lpm_type = "lpm_clshift";
	parameter lpm_width = 1;
	parameter lpm_widthdist = 1;
	parameter lpm_shifttype = "LOGICAL";
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] data;
	input  [lpm_widthdist-1:0] distance;
	input  direction;
	output [lpm_width-1:0] result;
	output overflow;
	output underflow;
 
	reg    [lpm_width-1:0] ONES;
	reg    [lpm_width-1:0] result;
	reg    overflow, underflow;
	integer i;
 
	tri0  direction;
 
	buf (i_direction, direction);
 
//---------------------------------------------------------------//
	function [lpm_width+1:0] LogicShift;
		input [lpm_width-1:0] data;
		input [lpm_widthdist-1:0] dist;
		input direction;
		reg   [lpm_width-1:0] tmp_buf;
		reg   overflow, underflow;
 
		begin
			tmp_buf = data;
			overflow = 1'b0;
			underflow = 1'b0;
			if ((direction) && (dist > 0)) // shift right
			begin
				tmp_buf = data >> dist;
				if ((data != 0) && ((dist >= lpm_width) || (tmp_buf == 0)))
					underflow = 1'b1;
			end
			else if (dist > 0) // shift left
			begin
				tmp_buf = data << dist;
				if ((data != 0) && ((dist >= lpm_width)
					|| ((data >> (lpm_width-dist)) != 0)))
					overflow = 1'b1;
			end
			LogicShift = {overflow,underflow,tmp_buf[lpm_width-1:0]};
		end
	endfunction
 
//---------------------------------------------------------------//
	function [lpm_width+1:0] ArithShift;
		input [lpm_width-1:0] data;
		input [lpm_widthdist-1:0] dist;
		input direction;
		reg   [lpm_width-1:0] tmp_buf;
		reg   overflow, underflow;
 
		begin
			tmp_buf = data;
			overflow = 1'b0;
			underflow = 1'b0;
 
			if (direction && (dist > 0))   // shift right
			begin
				if (data[lpm_width-1] == 0) // positive number
				begin
					tmp_buf = data >> dist;
					if ((data != 0) && ((dist >= lpm_width) || (tmp_buf == 0)))
						underflow = 1'b1;
				end
				else // negative number
				begin
					tmp_buf = (data >> dist) | (ONES << (lpm_width - dist));
					if ((data != ONES) && ((dist >= lpm_width-1) || (tmp_buf == ONES)))
						underflow = 1'b1;
				end
			end
			else if (dist > 0) // shift left
			begin
				tmp_buf = data << dist;
				if (data[lpm_width-1] == 0) // positive number
				begin
					if ((data != 0) && ((dist >= lpm_width-1) 
					|| ((data >> (lpm_width-dist-1)) != 0)))
						overflow = 1'b1;
				end
				else // negative number
				begin
					if ((data != ONES) && ((dist >= lpm_width) 
					|| (((data >> (lpm_width-dist-1))|(ONES << (dist+1))) != ONES)))
						overflow = 1'b1;
				end
			end
			ArithShift = {overflow,underflow,tmp_buf[lpm_width-1:0]};
		end
	endfunction
 
//---------------------------------------------------------------//
    function [lpm_width+1:0] RotateShift;
        input [lpm_width-1:0] data;
		input [lpm_widthdist-1:0] dist;
		input direction;
		reg   [lpm_width-1:0] tmp_buf;
 
		begin
			tmp_buf = data;
			if ((direction) && (dist > 0)) // shift right
				tmp_buf = (data >> dist) | (data << (lpm_width - dist));
			else if (dist > 0) // shift left
				tmp_buf = (data << dist) | (data >> (lpm_width - dist));
            RotateShift = {2'bx, tmp_buf[lpm_width-1:0]};
		end
	endfunction
//---------------------------------------------------------------//
 
	initial
	begin
        if (lpm_shifttype != "LOGICAL" &&
            lpm_shifttype != "ARITHMETIC" &&
            lpm_shifttype != "ROTATE" &&
            lpm_shifttype != "UNUSED")          // non-LPM 220 standard
            $display("Error!  LPM_SHIFTTYPE value must be \"LOGICAL\", \"ARITHMETIC\", or \"ROTATE\".");
 
		for (i=0; i < lpm_width; i=i+1)
			ONES[i] = 1'b1;
	end
 
	always @(data or i_direction or distance)
	begin
        if ((lpm_shifttype == "LOGICAL") || (lpm_shifttype == "UNUSED"))
            {overflow, underflow, result} = LogicShift(data, distance, i_direction);
		else if (lpm_shifttype == "ARITHMETIC")
            {overflow, underflow, result} = ArithShift(data, distance, i_direction);
		else if (lpm_shifttype == "ROTATE")
            {overflow, underflow, result} = RotateShift(data, distance, i_direction);
	end
 
endmodule // lpm_clshift
 
//------------------------------------------------------------------------
 
module lpm_add_sub ( result, cout, overflow,
					 add_sub, cin, dataa, datab, clock, clken, aclr );
 
	parameter lpm_type = "lpm_add_sub";
	parameter lpm_width = 1;
	parameter lpm_direction  = "UNUSED";
	parameter lpm_representation = "UNSIGNED";
	parameter lpm_pipeline = 0;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] dataa, datab;
	input  add_sub, cin;
	input  clock;
	input  clken;
	input  aclr;
	output [lpm_width-1:0] result;
	output cout, overflow;
 
    reg [lpm_width-1:0] tmp_result2 [lpm_pipeline:0];
    reg [lpm_pipeline:0] tmp_cout2;
    reg [lpm_pipeline:0] tmp_overflow2;
    reg [lpm_width-1:0] not_a, not_b, tmp_result;
    reg i_cin;
    integer dataa_int, datab_int, result_int, borrow, i; 
 
	tri0 aclr;
	tri0 clock;
	tri1 clken;
	tri1 add_sub;
 
	buf (i_aclr, aclr);
	buf (i_clock, clock);
	buf (i_clken, clken);
	buf (i_add_sub, add_sub);
 
 
    initial
    begin
        if (lpm_direction != "ADD" &&
            lpm_direction != "SUB" &&
            lpm_direction != "UNUSED" &&            // non-LPM 220 standard
            lpm_direction != "DEFAULT")             // non-LPM 220 standard
            $display("Error!  LPM_DIRECTION value must be \"ADD\" or \"SUB\".");
        if (lpm_representation != "SIGNED" &&
            lpm_representation != "UNSIGNED")
            $display("Error!  LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
 
        for (i = 0; i <= lpm_pipeline; i = i + 1)
        begin
            tmp_result2[i] = 'b0;
            tmp_cout2[i] = 1'b0;
            tmp_overflow2[i] = 1'b0;
        end
    end
 
    always @(cin or dataa or datab or i_add_sub or i_aclr)
	begin
		if (i_aclr)
			for (i = 0; i <= lpm_pipeline; i = i + 1)
			begin
				tmp_result2[i] = 'b0;
				tmp_cout2[i] = 1'b0;
				tmp_overflow2[i] = 1'b0;
			end
        else
        begin
 
            // 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_cout2[lpm_pipeline], tmp_result2[lpm_pipeline]} = dataa + datab + i_cin;
                tmp_overflow2[lpm_pipeline] = tmp_cout2[lpm_pipeline];
            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_overflow2[lpm_pipeline], tmp_result2[lpm_pipeline]} = dataa - datab - borrow;
                tmp_cout2[lpm_pipeline] = (dataa >= (datab+borrow))?1:0;
            end
 
            if (lpm_representation == "SIGNED")
            begin
                not_a = ~dataa;
                not_b = ~datab;
 
                dataa_int = (dataa[lpm_width-1]) ? (not_a)*(-1)-1 : dataa;
                datab_int = (datab[lpm_width-1]) ? (not_b)*(-1)-1 : datab;
 
                // perform the addtion or subtraction operation
                if (lpm_direction == "ADD" || (i_add_sub == 1 &&
                    (lpm_direction == "UNUSED" || lpm_direction == "DEFAULT") ))
                begin
                    i_cin = (cin === 1'bz) ? 0 : cin;
                    result_int = dataa_int + datab_int + i_cin;
                    tmp_result = result_int;
                    tmp_overflow2[lpm_pipeline] = ((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
                    i_cin = (cin === 1'bz) ? 1 : cin;
                    borrow = (~i_cin) ? 1 : 0;
                    result_int = dataa_int - datab_int - borrow;
                    tmp_result = result_int;
                    tmp_overflow2[lpm_pipeline] = ((dataa[lpm_width-1] != datab[lpm_width-1]) &&
                                                   (dataa[lpm_width-1] != tmp_result[lpm_width-1])) ?
                                                  1 : 0;
                end
                tmp_result2[lpm_pipeline] = result_int;
            end
        end
	end	
 
    always @(posedge i_clock)
	begin
        if (!i_aclr && i_clken == 1)
            for (i = 0; i < lpm_pipeline; i = i + 1)
			begin
                tmp_result2[i] <= tmp_result2[i+1];
                tmp_cout2[i] <= tmp_cout2[i+1];
                tmp_overflow2[i] <= tmp_overflow2[i+1];
			end
	end
 
    assign result = tmp_result2[0];
    assign cout = tmp_cout2[0];
    assign overflow = tmp_overflow2[0];
 
endmodule // lpm_add_sub
 
//------------------------------------------------------------------------
 
module lpm_compare ( alb, aeb, agb, aleb, aneb, ageb, dataa, datab,
					 clock, clken, aclr );
 
	parameter lpm_type = "lpm_compare";
	parameter lpm_width = 1;
	parameter lpm_representation = "UNSIGNED";
    parameter lpm_pipeline = 0;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] dataa, datab;
	input  clock;
	input  clken;
	input  aclr;
	output alb, aeb, agb, aleb, aneb, ageb;
 
    reg [lpm_pipeline:0] tmp_alb2, tmp_aeb2, tmp_agb2;
    reg [lpm_pipeline:0] tmp_aleb2, tmp_aneb2, tmp_ageb2;
    reg [lpm_width-1:0] not_a, not_b;
    integer dataa_int, datab_int, i;
 
	tri0 aclr;
	tri0 clock;
	tri1 clken;
 
	buf (i_aclr, aclr);
	buf (i_clock, clock);
	buf (i_clken, clken);
 
    initial
    begin
        if (lpm_representation != "SIGNED" &&
            lpm_representation != "UNSIGNED")
            $display("Error!  LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
    end
 
 
    always @(dataa or datab or i_aclr)
	begin
		if (i_aclr)
            for (i = 0; i <= lpm_pipeline; i = i + 1)
			begin
                tmp_aeb2[i] = 'b0;
                tmp_agb2[i] = 'b0;
                tmp_alb2[i] = 'b0;
                tmp_aleb2[i] = 'b0;
                tmp_aneb2[i] = 'b0;
                tmp_ageb2[i] = 'b0;
			end
        else
        begin
            dataa_int = dataa;
            datab_int = datab;
            not_a = ~dataa;
            not_b = ~datab;
 
            if (lpm_representation == "SIGNED")
            begin
                if (dataa[lpm_width-1] == 1)
                    dataa_int = (not_a) * (-1) - 1;
                if (datab[lpm_width-1] == 1)
                    datab_int = (not_b) * (-1) - 1;
            end
 
            tmp_alb2[lpm_pipeline] = (dataa_int < datab_int);
            tmp_aeb2[lpm_pipeline] = (dataa_int == datab_int);
            tmp_agb2[lpm_pipeline] = (dataa_int > datab_int);
            tmp_aleb2[lpm_pipeline] = (dataa_int <= datab_int);
            tmp_aneb2[lpm_pipeline] = (dataa_int != datab_int);
            tmp_ageb2[lpm_pipeline] = (dataa_int >= datab_int);
        end
	end
 
    always @(posedge i_clock)
	begin
        if (!i_aclr && i_clken == 1)
            for (i = 0; i < lpm_pipeline; i = i + 1)
            begin
                tmp_alb2[i] <= tmp_alb2[i+1];
                tmp_aeb2[i] <= tmp_aeb2[i+1];
                tmp_agb2[i] <= tmp_agb2[i+1];
                tmp_aleb2[i] <= tmp_aleb2[i+1];
                tmp_aneb2[i] <= tmp_aneb2[i+1];
                tmp_ageb2[i] <= tmp_ageb2[i+1];
            end
	end
 
    assign alb = tmp_alb2[0];
    assign aeb = tmp_aeb2[0];
    assign agb = tmp_agb2[0];
    assign aleb = tmp_aleb2[0];
    assign aneb = tmp_aneb2[0];
    assign ageb = tmp_ageb2[0];
 
endmodule // lpm_compare
 
//------------------------------------------------------------------------
 
module lpm_mult ( result, dataa, datab, sum, clock, clken, aclr );
 
	parameter lpm_type = "lpm_mult";
	parameter lpm_widtha = 1;
	parameter lpm_widthb = 1;
	parameter lpm_widths = 1;
	parameter lpm_widthp = 1;
	parameter lpm_representation  = "UNSIGNED";
	parameter lpm_pipeline  = 0;
	parameter lpm_hint = "UNUSED";
 
	input  clock;
	input  clken;
	input  aclr;
	input  [lpm_widtha-1:0] dataa;
	input  [lpm_widthb-1:0] datab;
	input  [lpm_widths-1:0] sum;
	output [lpm_widthp-1:0] result;
 
	// inernal reg
    reg [lpm_widthp-1:0] resulttmp [lpm_pipeline:0];
    reg [lpm_widthp-1:0] i_prod, t_p;
    reg [lpm_widths-1:0] i_prod_s, 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, sign_s;
    integer i;
 
	tri0 aclr;
	tri0 clock;
	tri1 clken;
 
	buf (i_aclr, aclr);
	buf (i_clock, clock);
	buf (i_clken, clken);
 
 
	initial
	begin
        // check if lpm_widtha > 0
        if (lpm_widtha <= 0)
            $display("Error!  LPM_WIDTHA must be greater than 0.\n");
        // check if lpm_widthb > 0
        if (lpm_widthb <= 0)
            $display("Error!  LPM_WIDTHB must be greater than 0.\n");
        // check if lpm_widthp > 0
        if (lpm_widthp <= 0)
            $display("Error!  LPM_WIDTHP must be greater than 0.\n");
        // check for valid lpm_rep value
        if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED"))
            $display("Error!  LPM_REPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".", $time);
	end
 
    always @(dataa or datab or sum or i_aclr)
	begin
        if (i_aclr)
            for (i = 0; i <= lpm_pipeline; i = i + 1)
                resulttmp[i] = 'b0;
        else
        begin
            t_a = dataa;
            t_b = datab;
            t_s = sum;
            sign_ab = 0;
            sign_s = 0;
 
            if (lpm_representation == "SIGNED")
            begin
                sign_ab = dataa[lpm_widtha-1] ^ datab[lpm_widthb-1];
                sign_s = sum[lpm_widths-1];
 
                if (dataa[lpm_widtha-1] == 1)
                    t_a = ~dataa + 1;
                if (datab[lpm_widthb-1] == 1)
                    t_b = ~datab + 1;
                if (sum[lpm_widths-1] == 1)
                    t_s = ~sum + 1;
            end
 
            if (sum === {lpm_widths{1'bz}})
            begin
                t_s = 0;
                sign_s = 0;
            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 (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];
 
            resulttmp[lpm_pipeline] = i_prod;
        end
	end
 
    always @(posedge i_clock)
	begin
        if (!i_aclr && i_clken == 1)
            for (i = 0; i < lpm_pipeline; i = i + 1)
                resulttmp[i] <= resulttmp[i+1];
	end
 
    assign result = resulttmp[0];
 
endmodule // lpm_mult
 
//------------------------------------------------------------------------
 
module lpm_divide ( quotient, remain, numer, denom, clock, clken, aclr );
 
	parameter lpm_type = "lpm_divide";
	parameter lpm_widthn = 1;
	parameter lpm_widthd = 1;
	parameter lpm_nrepresentation = "UNSIGNED";
	parameter lpm_drepresentation = "UNSIGNED";
	parameter lpm_remainderpositive = "TRUE";
	parameter lpm_pipeline = 0;
	parameter lpm_hint = "UNUSED";
 
	input  clock;
	input  clken;
	input  aclr;
	input  [lpm_widthn-1:0] numer;
	input  [lpm_widthd-1:0] denom;
	output [lpm_widthn-1:0] quotient;
	output [lpm_widthd-1:0] remain;
 
	// inernal reg
    reg [lpm_widthn-1:0] tmp_quotient [lpm_pipeline:0];
    reg [lpm_widthd-1:0] tmp_remain [lpm_pipeline:0];
    reg [lpm_widthn-1:0] ONES, ZEROS, UNKNOWN, HiZ;
    reg [lpm_widthd-1:0] DZEROS, DUNKNOWN;
    reg [lpm_widthn-1:0] NUNKNOWN;
    reg [lpm_widthd-1:0] RZEROS;
    reg [lpm_widthn-1:0] not_numer, int_numer;
    reg [lpm_widthd-1:0] not_denom, int_denom;
	integer i;
	integer int_quotient, int_remain;
 
	tri0 aclr;
	tri0 clock;
	tri1 clken;
 
	buf (i_aclr, aclr);
	buf (i_clock, clock);
	buf (i_clken, clken);
 
 
	initial
	begin
        // check if lpm_widthn > 0
        if (lpm_widthn <= 0)
            $display("Error!  LPM_WIDTHN must be greater than 0.\n");
        // check if lpm_widthd > 0
        if (lpm_widthd <= 0)
            $display("Error!  LPM_WIDTHD must be greater than 0.\n");
        // check for valid lpm_nrep value
        if ((lpm_nrepresentation != "SIGNED") && (lpm_nrepresentation != "UNSIGNED"))
            $display("Error!  LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
        // check for valid lpm_drep value
        if ((lpm_drepresentation != "SIGNED") && (lpm_drepresentation != "UNSIGNED"))
            $display("Error!  LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
        // check for valid lpm_remainderpositive value
        if ((lpm_remainderpositive != "TRUE") && (lpm_remainderpositive != "FALSE"))
            $display("Error!  LPM_REMAINDERPOSITIVE value must be \"TRUE\" or \"FALSE\".");
 
        for (i=0; i < lpm_widthn; i=i+1)
        begin
            ONES[i] = 1'b1;
            ZEROS[i] = 1'b0;
            UNKNOWN[i] = 1'bx;
            HiZ[i] = 1'bz;
        end
 
        for (i=0; i < lpm_widthd; i=i+1)
            DUNKNOWN[i] = 1'bx;
        for (i=0; i < lpm_widthn; i=i+1)
            NUNKNOWN[i] = 1'bx;
        for (i=0; i < lpm_widthd; i=i+1)
            RZEROS[i] = 1'b0;
	end
 
    always @(numer or denom or i_aclr)
	begin
		if (i_aclr)
		begin
			for (i = 0; i <= lpm_pipeline; i = i + 1)
				tmp_quotient[i] = ZEROS;
			tmp_remain[i] = RZEROS;
		end
        else
        begin
            int_numer = numer; 
            int_denom = denom;
            not_numer = ~numer;
            not_denom = ~denom;
 
            if (lpm_nrepresentation == "SIGNED")
                if (numer[lpm_widthn-1] == 1)
                    int_numer = (not_numer) * (-1) - 1;
            if (lpm_drepresentation == "SIGNED")
                if (denom[lpm_widthd-1] == 1)
                    int_denom = (not_denom) * (-1) - 1;
 
            int_quotient = int_numer / int_denom;
            int_remain = int_numer % int_denom;
 
            // LPM 220 standard
            if ((lpm_remainderpositive == "TRUE") && (int_remain < 0))
            begin
                int_quotient = int_quotient + ((int_denom < 0) ? 1 : (-1));
                int_remain = int_numer - int_quotient*int_denom;
            end
 
            tmp_quotient[lpm_pipeline] = int_quotient;
            tmp_remain[lpm_pipeline] = int_remain;
        end
	end
 
    always @(posedge i_clock)
    begin
        if (!i_aclr && i_clken)
            for (i = 0; i < lpm_pipeline; i = i + 1)
			begin
				tmp_quotient[i] <= tmp_quotient[i+1];
				tmp_remain[i] <= tmp_remain[i+1];
			end
	end
 
	assign quotient = tmp_quotient[0];
	assign remain = tmp_remain[0];
 
endmodule // lpm_divide
 
//------------------------------------------------------------------------
 
module lpm_abs ( result, overflow, data );
 
	parameter lpm_type = "lpm_abs";
	parameter lpm_width = 1;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] data;
	output [lpm_width-1:0] result;
	output overflow;
 
    reg [lpm_width-1:0] result, not_r;
    reg overflow;
 
 
	always @(data)
	begin
		overflow = 0;
        result = data;
        not_r = ~data;
 
		if (data[lpm_width-1] == 1)
		begin
            result = (not_r) + 1;
            overflow = (result == (1<<(lpm_width-1)));
		end
	end
 
endmodule // lpm_abs
 
//------------------------------------------------------------------------
 
module lpm_counter ( q, data, clock, cin, cout, clk_en, cnt_en, updown,
					 aset, aclr, aload, sset, sclr, sload );
 
	parameter lpm_type = "lpm_counter";
	parameter lpm_width = 1;
	parameter lpm_modulus = 0;
	parameter lpm_direction = "UNUSED";
	parameter lpm_avalue = "UNUSED";
	parameter lpm_svalue = "UNUSED";
	parameter lpm_pvalue = "UNUSED";
	parameter lpm_hint = "UNUSED";
 
	output [lpm_width-1:0] q;
	output cout;
	input  cin;
	input  [lpm_width-1:0] data;
	input  clock, clk_en, cnt_en, updown;
	input  aset, aclr, aload;
	input  sset, sclr, sload;
 
    reg  [lpm_width-1:0] tmp_count;
    reg  prev_clock;
    reg  tmp_updown;
    reg  [lpm_width-1:0] ONES;
    integer tmp_modulus, i;
 
	tri1 clk_en;
	tri1 cnt_en;
	tri0 sload;
	tri0 sset;
	tri0 sclr;
	tri0 aload;
	tri0 aset;
	tri0 aclr;
    tri1 cin;
    tri1 updown;
 
	buf (i_clk_en, clk_en);
	buf (i_cnt_en, cnt_en);
	buf (i_sload, sload);
	buf (i_sset, sset);
	buf (i_sclr, sclr);
	buf (i_aload, aload);
	buf (i_aset, aset);
	buf (i_aclr, aclr);
	buf (i_cin, cin);
    buf (i_updown, updown);
 
 
//---------------------------------------------------------------//
//  function integer str_to_int;
//---------------------------------------------------------------//
	function integer str_to_int;
        input [8*16:1] s; 
 
		reg [8*16:1] reg_s;
		reg [8:1] digit;
		reg [8:1] tmp;
		integer m, ivalue;
 
		begin
			ivalue = 0;
			reg_s = s;
			for (m=1; m<=16; m=m+1)
			begin 
				tmp = reg_s[128:121];
				digit = tmp & 8'b00001111;
				reg_s = reg_s << 8; 
				ivalue = ivalue * 10 + digit; 
			end
			str_to_int = ivalue;
		end
	endfunction
 
//---------------------------------------------------------------//
 
	initial
	begin
		// check if lpm_modulus < 0
		if (lpm_modulus < 0)
            $display("Error!  LPM_MODULUS must be greater than 0.\n");
		// check if lpm_modulus > 1<<lpm_width
		if (lpm_modulus > 1<<lpm_width)
            $display("Error!  LPM_MODULUS must be less than or equal to 1<<LPM_WIDTH.\n");
        // check if lpm_direction valid
        if (lpm_direction != "UNUSED" && lpm_direction != "UP" && lpm_direction != "DOWN")
            $display("Error!  LPM_DIRECTION must be \"UP\" or \"DOWN\" if used.\n");
        else if (lpm_direction != "UNUSED" && ((updown == 1'b0) || (updown == 1'b1)))
            $display("Error!  LPM_DIRECTION and UPDOWN cannot be used at the same time.\n");
 
        for (i=0; i < lpm_width; i=i+1)
            ONES[i] = 1'b1;
 
        prev_clock = clock;
 
		tmp_modulus = (lpm_modulus == 0) ? (1 << lpm_width) : lpm_modulus;
		tmp_count = (lpm_pvalue == "UNUSED") ? 0 : str_to_int(lpm_pvalue);
	end
 
    always @(i_aclr or i_aset or i_aload or data or clock or i_updown)
	begin :asyn_block
 
        tmp_updown = ((lpm_direction == "UNUSED" && i_updown == 1) || lpm_direction == "UP")
                     ? 1 : 0;
		if (i_aclr)
            tmp_count <= 0;
		else if (i_aset)
            tmp_count <= (lpm_avalue == "UNUSED") ? {lpm_width{1'b1}}
                                                 : str_to_int(lpm_avalue);
		else if (i_aload)
            tmp_count <= data;
        else if (clock === 1 && prev_clock !== 1 && $time > 0)
		begin :syn_block
			if (i_clk_en)
			begin
				if (i_sclr)
                    tmp_count <= 0;
				else if (i_sset)
                    tmp_count <= (lpm_svalue == "UNUSED") ? {lpm_width{1'b1}}
                                                         : str_to_int(lpm_svalue);
				else if (i_sload)
                    tmp_count <= data;
                else if (i_cnt_en && i_cin)
                begin
                    if (tmp_updown == 1)
                        tmp_count <= (tmp_count == tmp_modulus-1) ? 0
                                                                 : tmp_count+1;
                    else
                        tmp_count <= (tmp_count == 0) ? tmp_modulus-1
                                                     : tmp_count-1;
                end
			end
		end
 
        prev_clock = clock;
	end
 
    assign q = tmp_count;
    assign cout = (i_cin && ((tmp_updown==0 && tmp_count==0) ||
                             (tmp_updown==1 && (tmp_count==tmp_modulus-1 ||
                                                tmp_count==ONES)) ))
                    ? 1 : 0;
 
endmodule // lpm_counter
 
//------------------------------------------------------------------------
 
module lpm_latch ( q, data, gate, aset, aclr );
 
  parameter lpm_type = "lpm_latch";
  parameter lpm_width = 1;
  parameter lpm_avalue = "UNUSED";
  parameter lpm_pvalue = "UNUSED";
  parameter lpm_hint = "UNUSED";
 
  input  [lpm_width-1:0] data;
  input  gate, aset, aclr;
  output [lpm_width-1:0] q;
 
  reg [lpm_width-1:0] q;
  reg [lpm_width-1:0] i_data;
 
  tri0 aset;
  tri0 aclr;
 
  buf (i_aset, aset);
  buf (i_aclr, aclr);
 
//---------------------------------------------------------------//
//  function integer str_to_int;
//---------------------------------------------------------------//
	function integer str_to_int;
        input [8*16:1] s; 
 
		reg [8*16:1] reg_s;
		reg [8:1] digit;
		reg [8:1] tmp;
        integer m, ivalue; 
 
		begin 
			ivalue = 0;
			reg_s = s;
			for (m=1; m<=16; m= m+1) 
			begin 
				tmp = reg_s[128:121];
				digit = tmp & 8'b00001111;
				reg_s = reg_s << 8; 
				ivalue = ivalue * 10 + digit; 
			end
			str_to_int = ivalue;
		end
	endfunction
//---------------------------------------------------------------//
 
	initial
	begin
		if (lpm_pvalue != "UNUSED")
			q = str_to_int(lpm_pvalue);
        i_data = (data === {lpm_width{1'bz}}) ? 0 : data;
	end
 
    always @(data)
        i_data = data;
 
    always @(i_data or gate or i_aclr or i_aset)
	begin
		if (i_aclr)
			q = 'b0;
		else if (i_aset)
            q = (lpm_avalue == "UNUSED") ? {lpm_width{1'b1}}
                                         : str_to_int(lpm_avalue);
		else if (gate)
            q = i_data;
	end
 
endmodule // lpm_latch
 
//------------------------------------------------------------------------
 
module lpm_ff ( q, data, clock, enable, aclr, aset,
				sclr, sset, aload, sload );
 
	parameter lpm_type = "lpm_ff";
	parameter lpm_width  = 1;
	parameter lpm_avalue = "UNUSED";
	parameter lpm_svalue = "UNUSED";
	parameter lpm_pvalue = "UNUSED";
	parameter lpm_fftype = "DFF";
	parameter lpm_hint = "UNUSED";
 
 
	input  [lpm_width-1:0] data;
	input  clock, enable;
	input  aclr, aset;
	input  sclr, sset;
	input  aload, sload ;
	output [lpm_width-1:0] q;
 
    reg  [lpm_width-1:0] tmp_q;
    reg  prev_clock;
	integer i;
 
	tri1 enable;
	tri0 sload;
	tri0 sclr;
	tri0 sset;
	tri0 aload;
	tri0 aclr;
	tri0 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);
 
//---------------------------------------------------------------//
//  function integer str_to_int;
//---------------------------------------------------------------//
	function integer str_to_int;
        input [8*16:1] s; 
 
		reg [8*16:1] reg_s;
        reg [8:1] digit;
		reg [8:1] tmp;
        integer m, ivalue; 
 
		begin
			ivalue = 0;
			reg_s = s;
			for (m=1; m<=16; m= m+1) 
			begin 
				tmp = reg_s[128:121];
				digit = tmp & 8'b00001111;
				reg_s = reg_s << 8; 
				ivalue = ivalue * 10 + digit; 
			end
			str_to_int = ivalue;
		end
	endfunction
//---------------------------------------------------------------//
 
	initial
    begin
        if (lpm_fftype != "DFF" &&
            lpm_fftype != "TFF" &&
            lpm_fftype != "UNUSED")          // non-LPM 220 standard
            $display("Error!  LPM_FFTYPE value must be \"DFF\" or \"TFF\".");
 
        tmp_q = (lpm_pvalue == "UNUSED") ? 0 : str_to_int(lpm_pvalue);
        prev_clock = clock;
    end
 
    always @(i_aclr or i_aset or i_aload or data or clock)
	begin :asyn_block // Asynchronous process
		if (i_aclr)
            tmp_q = (i_aset) ? 'bx : 0;
        else if (i_aset)
            tmp_q = (lpm_avalue == "UNUSED") ? {lpm_width{1'b1}}
                                             : str_to_int(lpm_avalue);
		else if (i_aload)
            tmp_q = data;
        else if (clock === 1 && prev_clock !== 1 && $time > 0)
		begin :syn_block // Synchronous process
			if (i_enable)
			begin
				if (i_sclr)
					tmp_q <= 0;
				else if (i_sset)
                    tmp_q <= (lpm_svalue == "UNUSED") ? {lpm_width{1'b1}}
                                                     : str_to_int(lpm_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] <= ~tmp_q[i];
					end
                    else    // DFF, load data
                        tmp_q <= data;
				end
			end
		end
        prev_clock = clock;
	end
 
	assign q = tmp_q;
endmodule // lpm_ff
 
//------------------------------------------------------------------------
 
module lpm_shiftreg ( q, shiftout, data, clock, enable, aclr, aset, 
					  sclr, sset, shiftin, load );
 
	parameter lpm_type = "lpm_shiftreg";
	parameter lpm_width  = 1;
	parameter lpm_avalue = "UNUSED";
	parameter lpm_svalue = "UNUSED";
	parameter lpm_pvalue = "UNUSED";
	parameter lpm_direction = "LEFT";
	parameter lpm_hint  = "UNUSED";
 
	input  [lpm_width-1:0] data;
	input  clock, enable;
	input  aclr, aset;
	input  sclr, sset;
	input  shiftin, load;
	output [lpm_width-1:0] q;
	output shiftout;
 
	reg  [lpm_width-1:0] tmp_q;
	reg  abit;
	integer i;
 
	wire tmp_shiftout;
 
	tri1 enable;
	tri1 shiftin;
	tri0 load;
	tri0 sclr;
	tri0 sset;
	tri0 aclr;
	tri0 aset;
 
	buf (i_enable, enable);
	buf (i_shiftin, shiftin);
	buf (i_load, load);
	buf (i_sclr, sclr);
	buf (i_sset, sset);
	buf (i_aclr, aclr);
	buf (i_aset, aset);
 
 
//---------------------------------------------------------------//
//  function integer str_to_int;
//---------------------------------------------------------------//
	function integer str_to_int;
        input [8*16:1] s; 
 
		reg [8*16:1] reg_s;
        reg [8:1] digit;
		reg [8:1] tmp;
        integer m, ivalue; 
 
		begin 
			ivalue = 0;
			reg_s = s;
			for (m=1; m<=16; m= m+1) 
			begin 
				tmp = reg_s[128:121];
				digit = tmp & 8'b00001111;
				reg_s = reg_s << 8; 
				ivalue = ivalue * 10 + digit; 
			end
			str_to_int = ivalue;
		end
	endfunction
//---------------------------------------------------------------//
 
	initial
    begin
        if (lpm_direction != "LEFT" &&
            lpm_direction != "RIGHT" &&
            lpm_direction != "UNUSED")          // non-LPM 220 standard
            $display("Error!  LPM_DIRECTION value must be \"LEFT\" or \"RIGHT\".");
 
        tmp_q = (lpm_pvalue == "UNUSED") ? 0 : str_to_int(lpm_pvalue);
    end
 
    always @(i_aclr or i_aset)
    begin
		if (i_aclr)
            tmp_q <= (i_aset) ? 'bx : 0;
		else if (i_aset)
            tmp_q <= (lpm_avalue == "UNUSED") ? {lpm_width{1'b1}}
                                             : str_to_int(lpm_avalue);
    end
 
    always @(posedge clock)
	begin :asyn_block // Asynchronous process
		if (i_aclr)
            tmp_q <= (i_aset) ? 'bx : 0;
		else if (i_aset)
            tmp_q <= (lpm_avalue == "UNUSED") ? {lpm_width{1'b1}}
                                             : str_to_int(lpm_avalue);
		else
		begin :syn_block // Synchronous process
			if (i_enable)
			begin
				if (i_sclr)
					tmp_q <= 0;
				else if (i_sset)
                    tmp_q <= (lpm_svalue == "UNUSED") ? {lpm_width{1'b1}}
                                                     : str_to_int(lpm_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
 
 
    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
 
//------------------------------------------------------------------------
 
module lpm_ram_dq ( q, data, inclock, outclock, we, address );
 
  parameter lpm_type = "lpm_ram_dq";
  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 = "OFF";
  parameter intended_device_family = "UNUSED";
 
  input  [lpm_width-1:0] data;
  input  [lpm_widthad-1:0] address;
  input  inclock, outclock, we;
  output [lpm_width-1:0] q;
 
 
  // internal reg 
  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;
  reg  [8*256:1] ram_initf;
  integer i;
 
  tri0 inclock;
  tri0 outclock;
 
  buf (i_inclock, inclock);
  buf (i_outclock, outclock);
 
//---------------------------------------------------------------//
	function ValidAddress;
		input [lpm_widthad-1:0] paddress;
 
		begin
			ValidAddress = 1'b0;
			if (^paddress ==='bx)
                            $display("%t:Error!  Invalid address.\n", $time);
			else if (paddress >= lpm_numwords)
                            $display("%t:Error!  Address out of bound on RAM.\n", $time);
			else
				ValidAddress = 1'b1;
		end
  endfunction
//---------------------------------------------------------------//
 
	initial
	begin
 
		// Initialize the internal data register.
		pdata = 0;
		paddress = 0;
		pwe = 0;
 
		if (lpm_width <= 0)
                    $display("Error!  LPM_WIDTH parameter must be greater than 0.");
 
		if (lpm_widthad <= 0)
                    $display("Error!  LPM_WIDTHAD parameter must be greater than 0.");
		// check for number of words out of bound
		if ((lpm_numwords > (1 << lpm_widthad))
			||(lpm_numwords <= (1 << (lpm_widthad-1))))
                    $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD.");
 
                if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED"))
                    $display("Error!  LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\".");
                if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED"))
                    $display("Error!  LPM_INDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
                if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
                    $display("Error!  LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
 
 
		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] = ZEROS;
 
		// load data to the RAM
		if (lpm_file != "UNUSED")
		begin
`ifdef NO_PLI
			$readmemh(lpm_file, mem_data);
`else
			$convert_hex2ver(lpm_file, lpm_width, ram_initf);
			$readmemh(ram_initf, mem_data);
`endif
		end 
 
                tmp_q = ZEROS;
	end
 
 
	always @(posedge i_inclock)
	begin
        if (lpm_address_control == "REGISTERED")
        begin
            if ((we) && ((use_eab == "OFF")  && ((lpm_hint == "USE_EAB=OFF") || (lpm_hint == "UNUSED")))) 
            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 <= UNKNOWN;
		end
	end
 
	always @(posedge i_outclock)
	begin
        if (lpm_outdata == "REGISTERED")
		begin
			if (ValidAddress(paddress))
                            tmp_q <= mem_data[paddress];
			else
                            tmp_q <= UNKNOWN;
		end
	end
 
        always @(negedge i_inclock or pdata)
	begin
        if ((lpm_address_control == "REGISTERED") && (pwe))
            if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON")) 
            begin
                if (i_inclock == 0) mem_data[paddress] = pdata;
            end
	end
 
    assign q = (lpm_outdata == "UNREGISTERED") ? mem_data[paddress] : tmp_q;
 
endmodule // lpm_ram_dq
 
//--------------------------------------------------------------------------
 
module lpm_ram_dp ( q, data, wraddress, rdaddress, rdclock, wrclock, rdclken, wrclken, rden, wren);
 
	parameter lpm_type = "lpm_ram_dp";
	parameter lpm_width = 1;
	parameter lpm_widthad = 1;
	parameter lpm_numwords = 1<< lpm_widthad;
	parameter lpm_indata = "REGISTERED";
	parameter lpm_outdata = "REGISTERED";
	parameter lpm_rdaddress_control  = "REGISTERED";
	parameter lpm_wraddress_control  = "REGISTERED";
	parameter lpm_file = "UNUSED";
	parameter lpm_hint = "UNUSED";
	parameter use_eab = "OFF";
	parameter intended_device_family = "UNUSED";
	parameter rden_used = "TRUE";
 
	input  [lpm_width-1:0] data;
	input  [lpm_widthad-1:0] rdaddress, wraddress;
	input  rdclock, wrclock, rdclken, wrclken, rden, wren;
	output [lpm_width-1:0] q;
 
    // internal reg
    reg [lpm_width-1:0] mem_data [(1<<lpm_widthad)-1:0];
    reg [lpm_width-1:0] i_data_reg, i_data_tmp, i_q_reg, i_q_tmp;
    reg [lpm_width-1:0] ZEROS, ONES, UNKNOWN;
    reg [lpm_widthad-1:0] i_wraddress_reg, i_wraddress_tmp;
    reg [lpm_widthad-1:0] i_rdaddress_reg, i_rdaddress_tmp;
    reg [lpm_widthad-1:0] ZEROS_AD;
    reg i_wren_reg, i_wren_tmp, i_rden_reg, i_rden_tmp;
    reg [8*256:1] ram_initf;
    reg mem_updated;
    integer i, i_numwords;
 
    tri0 wrclock;
    tri1 wrclken;
    tri0 rdclock;
    tri1 rdclken;
    tri0 wren;
    tri1 rden;
 
    buf (i_inclock, wrclock);
    buf (i_inclocken, wrclken);
    buf (i_outclock, rdclock);
    buf (i_outclocken, rdclken);
    buf (i_wren, wren);
    buf (i_rden, rden);
 
//---------------------------------------------------------------//
	function ValidAddress;
		input [lpm_widthad-1:0] paddress;
 
		begin
			ValidAddress = 1'b0;
            if (^paddress === 'bx)
                $display("%t:Error!  Invalid address.\n", $time);
			else if (paddress >= lpm_numwords)
                $display("%t:Error!  Address out of bound on RAM.\n", $time);
			else
				ValidAddress = 1'b1;
		end
	endfunction
//---------------------------------------------------------------//
 
	initial
	begin
        // Check for invalid parameters
        if (lpm_width < 1)
            $display("Error! lpm_width parameter must be greater than 0.");
        if (lpm_widthad < 1)
            $display("Error! lpm_widthad parameter must be greater than 0.");
 
        if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED"))
            $display("Error! lpm_indata must be \"REGISTERED\" or \"UNREGISTERED\".");
        if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
            $display("Error! lpm_outdata must be \"REGISTERED\" or \"UNREGISTERED\".");
        if ((lpm_wraddress_control != "REGISTERED") && (lpm_wraddress_control != "UNREGISTERED"))
            $display("Error! lpm_wraddress_control must be \"REGISTERED\" or \"UNREGISTERED\".");
        if ((lpm_rdaddress_control != "REGISTERED") && (lpm_rdaddress_control != "UNREGISTERED"))
            $display("Error! lpm_rdaddress_control must be \"REGISTERED\" or \"UNREGISTERED\".");
 
        // Initialize constants
        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_widthad; i=i+1)
            ZEROS_AD[i] = 1'b0;
 
        // Initialize mem_data
        i_numwords = (lpm_numwords) ? lpm_numwords : 1<<lpm_widthad;
        if (lpm_file == "UNUSED")
            for (i=0; i<i_numwords; i=i+1)
                mem_data[i] = ZEROS;
        else
		begin
`ifdef NO_PLI
			$readmemh(lpm_file, mem_data);
`else
            $convert_hex2ver(lpm_file, lpm_width, ram_initf);
		    $readmemh(ram_initf, mem_data);
`endif
		end
 
        mem_updated = 0;
 
        // Initialize registers
        i_data_reg <= ZEROS;
        i_wraddress_reg <= ZEROS_AD;
        i_rdaddress_reg <= ZEROS_AD;
        i_wren_reg <= 0;
        if (rden_used == "TRUE")
            i_rden_reg <= 0;
        else
            i_rden_reg <= 1;
 
        // Initialize output
        i_q_reg = ZEROS;
        if ((use_eab == "ON") || (lpm_hint == "USE_EAB=ON"))
        begin
            if (intended_device_family == "APEX20K")
                i_q_tmp = ZEROS;
            else
                i_q_tmp = ONES;
        end
        else i_q_tmp = ZEROS;
 
 
	end
 
 
    //=========
    // Clocks
    //=========
 
    always @(posedge i_inclock)
	begin
        if (lpm_indata == "REGISTERED")
            if (i_inclocken == 1 && $time > 0)
                i_data_reg <= data;
 
        if (lpm_wraddress_control == "REGISTERED")
            if (i_inclocken == 1 && $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 && $time > 0)
            begin
                i_q_reg <= i_q_tmp;
            end
 
        if (lpm_rdaddress_control == "REGISTERED")
            if (i_outclocken == 1 && $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)
            if (ValidAddress(i_wraddress_tmp))
            begin
                if (((use_eab == "ON") || (lpm_hint == "USE_EAB=ON")) && (lpm_wraddress_control == "REGISTERED"))
                begin
                    if (i_inclock == 0)
                    begin
                        mem_data[i_wraddress_tmp] = i_data_tmp;
                        mem_updated <= ~mem_updated;
                    end
                end
                else
                begin
                        mem_data[i_wraddress_tmp] = i_data_tmp;
                        mem_updated <= ~mem_updated;
                end
            end
	end
 
    always @(i_rden_tmp or i_rdaddress_tmp or mem_updated)
	begin
        if (i_rden_tmp == 1)
                    i_q_tmp = (ValidAddress(i_rdaddress_tmp))
                        ? mem_data[i_rdaddress_tmp]
                        : UNKNOWN;
        else if ((intended_device_family == "APEX20K") && ((use_eab == "ON")  || (lpm_hint == "USE_EAB=ON")))
            i_q_tmp = 0;
 
	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;
 
    assign q = (lpm_outdata == "REGISTERED") ? i_q_reg : i_q_tmp;
 
endmodule // lpm_ram_dp
 
//------------------------------------------------------------------------
 
module lpm_ram_io ( dio, inclock, outclock, we, memenab, outenab, address );
 
	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 = "OFF";
	parameter intended_device_family = "UNUSED";
 
	input  [lpm_widthad-1:0] address;
	input  inclock, outclock, we;
	input  memenab;
	input  outenab;
	inout  [lpm_width-1:0] dio;
 
 
	// inernal reg 
	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  pwe;
	reg  [lpm_width-1:0] ZEROS, ONES, UNKNOWN, HiZ;
	reg  [8*256:1] ram_initf;
	integer i;
 
	tri0 inclock;
	tri0 outclock;
        tri1 memenab;
        tri1 outenab;
 
 
	buf (i_inclock, inclock);
	buf (i_outclock, outclock);
	buf (i_memenab, memenab);
	buf (i_outenab, outenab);
 
 
//---------------------------------------------------------------//
	function ValidAddress;
		input [lpm_widthad-1:0] paddress;
 
		begin
			ValidAddress = 1'b0;
			if (^paddress ==='bx)
                             $display("%t:Error:  Invalid address.", $time);
                         else if (paddress >= lpm_numwords)
                             $display("%t:Error:  Address out of bound on RAM.", $time);
			else
				ValidAddress = 1'b1;
		end
	endfunction
//---------------------------------------------------------------//
 
	initial
	begin
 
		if (lpm_width <= 0)
                    $display("Error!  LPM_WIDTH parameter must be greater than 0.");
 
		if (lpm_widthad <= 0)
                    $display("Error!  LPM_WIDTHAD parameter must be greater than 0.");
 
		// 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.");
		end
 
                if ((lpm_indata != "REGISTERED") && (lpm_indata != "UNREGISTERED")) 
                    $display("Error!  LPM_INDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
 
                if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED")) 
                    $display("Error!  LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\".");
 
                if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED")) 
                    $display("Error!  LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
 
 
		for (i=0; i < lpm_width; i=i+1)
		begin
			ZEROS[i] = 1'b0;
			ONES[i] = 1'b1;
			UNKNOWN[i] = 1'bX;
			HiZ[i] = 1'bZ;
		end 
 
		for (i = 0; i < lpm_numwords; i=i+1)
			mem_data[i] = ZEROS;
 
		// Initialize input/output 
		pwe <= 0;
		pdio <= 0;
		paddress <= 0;
		tmp_io = 0;
		tmp_q <= ZEROS;
 
		// load data to the RAM
		if (lpm_file != "UNUSED")
		begin
`ifdef NO_PLI
			$readmemh(lpm_file, mem_data);
`else
			$convert_hex2ver(lpm_file, lpm_width, ram_initf);
			$readmemh(ram_initf, mem_data);
`endif
		end
	end
 
 
	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 :block_a
		if (ValidAddress(paddress))
		begin
                    if (lpm_address_control == "UNREGISTERED")
		        if (pwe && i_memenab)
                            mem_data[paddress] <= pdio;
 
                    if (lpm_outdata == "UNREGISTERED")
                        tmp_q <= mem_data[paddress];
		end
		else
		begin
                    if (lpm_outdata == "UNREGISTERED")
                        tmp_q <= UNKNOWN;
		end
	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 == 0))
                            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 = HiZ;
	end
 
	assign dio =  tmp_io;
 
endmodule // lpm_ram_io
 
//------------------------------------------------------------------------
 
module lpm_rom ( q, inclock, outclock, memenab, address );
 
	parameter lpm_type = "lpm_rom";
	parameter lpm_width = 1;
	parameter lpm_widthad = 1;
        parameter lpm_numwords = 1 << lpm_widthad;
	parameter lpm_address_control = "REGISTERED";
	parameter lpm_outdata = "REGISTERED";
        parameter lpm_file = "";
	parameter lpm_hint = "UNUSED";
	parameter intended_device_family = "UNUSED";
 
	input  [lpm_widthad-1:0] address;
	input  inclock, outclock;
	input  memenab;
	output [lpm_width-1:0] q;
 
	// inernal reg 
	reg  [lpm_width-1:0] mem_data [lpm_numwords-1:0];
	reg  [lpm_widthad-1:0] paddress;
	reg  [lpm_width-1:0] tmp_q;
	reg  [lpm_width-1:0] tmp_q_reg;
	reg  [lpm_width-1:0] ZEROS, UNKNOWN, HiZ;
	reg  [8*256:1] rom_initf;
	integer i;
 
	tri0 inclock;
	tri0 outclock;
	tri1 memenab;
 
	buf (i_inclock, inclock);
	buf (i_outclock, outclock);
	buf (i_memenab, memenab);
 
 
//---------------------------------------------------------------//
	function ValidAddress;
		input [lpm_widthad-1:0] address;
		begin
			ValidAddress = 1'b0;
			if (^address =='bx)
                            $display("%d:Error:  Invalid address.", $time);
			else if (address >= lpm_numwords)
                            $display("%d:Error:  Address out of bound on ROM.", $time);
			else
				ValidAddress = 1'b1;
		end
	endfunction
//---------------------------------------------------------------//
 
	initial     
	begin
		// Initialize output
		tmp_q <= 0;
		tmp_q_reg <= 0;
		paddress <= 0;
 
		if (lpm_width <= 0)
                    $display("Error!  LPM_WIDTH parameter must be greater than 0.");
 
		if (lpm_widthad <= 0)
                    $display("Error!  LPM_WIDTHAD parameter must be greater than 0.");        
 
		// check for number of words out of bound
		if ((lpm_numwords > (1 << lpm_widthad))
			||(lpm_numwords <= (1 << (lpm_widthad-1))))
                    $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHAD.");
 
                if ((lpm_address_control != "REGISTERED") && (lpm_address_control != "UNREGISTERED"))
                    $display("Error!  LPM_ADDRESS_CONTROL must be \"REGISTERED\" or \"UNREGISTERED\".");
 
                if ((lpm_outdata != "REGISTERED") && (lpm_outdata != "UNREGISTERED"))
                    $display("Error!  LPM_OUTDATA must be \"REGISTERED\" or \"UNREGISTERED\".");
 
 
		for (i=0; i < lpm_width; i=i+1)
		begin
			ZEROS[i] = 1'b0;
			UNKNOWN[i] = 1'bX;
			HiZ[i] = 1'bZ;
		end 
 
		for (i = 0; i < lpm_numwords; i=i+1)
			mem_data[i] = ZEROS;
 
		// load data to the ROM
                if (lpm_file == "" || lpm_file == "UNUSED")
                    $display("Warning:  LPM_ROM must have data file for initialization.\n");
                else
		begin
`ifdef NO_PLI
			$readmemh(lpm_file, mem_data);
`else
			$convert_hex2ver(lpm_file, lpm_width, rom_initf);
			$readmemh(rom_initf, mem_data);
`endif
		end
	end
 
	always @(posedge i_inclock)
	begin
        if (lpm_address_control == "REGISTERED")
            paddress <=  address;
	end
 
	always @(address)
	begin
        if (lpm_address_control == "UNREGISTERED")
            paddress <=  address;
	end
 
	always @(paddress)
	begin 
		if (ValidAddress(paddress))
		begin
                    if (lpm_outdata == "UNREGISTERED")
                        tmp_q_reg <=  mem_data[paddress];
		end
		else
		begin
                    if (lpm_outdata == "UNREGISTERED")
                        tmp_q_reg <= UNKNOWN;
		end
	end
 
	always @(posedge i_outclock)
	begin
        if (lpm_outdata == "REGISTERED")
		begin
			if (ValidAddress(paddress))
                            tmp_q_reg <=  mem_data[paddress];
			else
                            tmp_q_reg <= UNKNOWN;
		end
	end
 
 
	always @(i_memenab or tmp_q_reg)
        begin
            tmp_q <= (i_memenab) ? tmp_q_reg : HiZ;
        end
 
	assign q = tmp_q;
 
endmodule // lpm_rom
 
//------------------------------------------------------------------------
 
module lpm_fifo ( data, clock, wrreq, rdreq, aclr, sclr, q, usedw, full, empty );
 
	parameter lpm_type = "lpm_fifo";
	parameter lpm_width  = 1;
	parameter lpm_widthu  = 1;
    parameter lpm_numwords = 1;
	parameter lpm_showahead = "OFF";
	parameter lpm_hint = "UNUSED";
 
    input  [lpm_width-1:0] data;
    input  clock;
    input  wrreq;
    input  rdreq;
    input  aclr;
    input  sclr;
	output [lpm_width-1:0] q;
	output [lpm_widthu-1:0] usedw;
	output full;
	output empty;
 
 
	// internal reg
	reg [lpm_width-1:0] mem_data [lpm_numwords-1:0];
	reg [lpm_width-1:0] tmp_q;
	reg [lpm_width-1:0] ZEROS;
	reg [lpm_widthu+1:0] count_id;
	reg [lpm_widthu-1:0] write_id;
	reg [lpm_widthu-1:0] read_id;
	reg empty_flag;
	reg full_flag;
	integer i;
 
	// VCS fix
	reg [lpm_widthu+1:0] usedw_tmp;
 
	tri0 aclr;
	tri0 sclr;
 
	buf (i_aclr, aclr);
	buf (i_sclr, sclr);
 
 
	initial
	begin
        if (lpm_width <= 0)
            $display("Error!  LPM_WIDTH must be greater than 0.");
 
        if (lpm_numwords < 1)
            $display("Error!  LPM_NUMWORDS must be greater than 0.");
 
		// check for number of words out of bound
        if ((lpm_widthu != 1) && (lpm_numwords > (1 << lpm_widthu)))
            $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHU.");
        if (lpm_numwords <= (1 << (lpm_widthu-1)) && lpm_numwords > 1)
            $display("Error!  The ceiling of log2(LPM_NUMWORDS) must equal to LPM_WIDTHU.");
 
        if (lpm_showahead != "ON" && lpm_showahead != "OFF")
            $display("Error!  LPM_SHOWAHEAD must be \"ON\" or \"OFF\".");
 
 
		for (i=0; i < lpm_width; i=i+1)
			ZEROS[i] = 1'b0;
 
		for (i = 0; i < lpm_numwords; i=i+1)
			mem_data[i] = ZEROS;
 
		full_flag = 0;
		empty_flag = 1;
		read_id = 0;
		write_id = 0;
		count_id = 0;
		usedw_tmp = 0;
		tmp_q = ZEROS;
	end
 
    always @(posedge clock or posedge i_aclr)
	begin
		if (i_aclr)
		begin
			tmp_q = ZEROS;
			full_flag = 0;
			empty_flag = 1;
			read_id = 0;
			write_id = 0;
			count_id = 0;
			if (lpm_showahead == "ON")
				tmp_q = mem_data[0];
		end
		else if (clock)
		begin
			if (i_sclr)
			begin
				tmp_q <= mem_data[read_id];
				full_flag <= 0;
				empty_flag <= 1;
				read_id = 0;
				write_id = 0;
				count_id = 0;
				if (lpm_showahead == "ON")
					tmp_q <= mem_data[0];
			end
			else
			begin
				// both WRITE and READ
				if ((wrreq && !full_flag) && (rdreq && !empty_flag))
				begin
					mem_data[write_id] = data;
					if (write_id >= lpm_numwords-1)
						write_id = 0;
					else
						write_id = write_id + 1;
 
					tmp_q <= mem_data[read_id];
					if (read_id >= lpm_numwords-1)
						read_id = 0;
					else
						read_id = read_id + 1;
					if (lpm_showahead == "ON")
						tmp_q <= mem_data[read_id];
				end
 
				// WRITE
				else if (wrreq && !full_flag)
				begin
					mem_data[write_id] = data;
					if (lpm_showahead == "ON")
					begin
						// changed by M.Singal :
						// showahead should show current
						// write data
//						tmp_q <= mem_data[read_id];
						tmp_q <= data;
					end
					count_id = count_id + 1;
					empty_flag <= 0;
					if (count_id >= lpm_numwords)
					begin
						full_flag <= 1;
						count_id = lpm_numwords;
					end
					if (write_id >= lpm_numwords-1)
						write_id = 0;
					else
						write_id = write_id + 1;
				end
 
				// READ
				else if (rdreq && !empty_flag)
				begin
					tmp_q <= mem_data[read_id];
					count_id = count_id - 1;
					full_flag <= 0;
					if (count_id <= 0)
					begin
						empty_flag <= 1;
						count_id = 0;
					end
					if (read_id >= lpm_numwords-1)
						read_id = 0;
					else
						read_id = read_id + 1;
					if (lpm_showahead == "ON")
						tmp_q <= mem_data[read_id];
				end
			end
		end
		usedw_tmp <= count_id;
	end
 
	assign q = tmp_q;
	assign full = full_flag;
	assign empty = empty_flag;
//	assign usedw = count_id;
	assign usedw = usedw_tmp;
 
endmodule // lpm_fifo
 
//------------------------------------------------------------------------
 
module lpm_fifo_dc_dffpipe ( d, q, clock, aclr );
 
    parameter lpm_delay = 1;
    parameter lpm_width = 128;
 
    input [lpm_width-1:0] d;
    input clock;
    input aclr;
    output [lpm_width-1:0] q;    
 
	// internal reg
    reg [lpm_width-1:0] dffpipe [lpm_delay:0];
    reg [lpm_width-1:0] i_q;
    integer delay, i;
 
    initial
    begin
        delay = lpm_delay-1;
        for (i=0; i<lpm_delay; i=i+1)
            dffpipe[i] = 0;
        i_q = 0;
    end
 
    always @(d)
    begin
        if (lpm_delay == 0 && !aclr)
            i_q <= (aclr) ? 0 : d;
    end
 
    always @(aclr)
    begin
        if (aclr)
        begin
            for (i=0; i<lpm_delay; i=i+1)
                dffpipe[i] = 0;
            i_q <= 0;
        end
    end
 
    always @(posedge clock)
    begin
        if (!aclr && lpm_delay > 0 && $time > 0)
        begin
            if (delay > 0)
                for (i=delay; i>0; i=i-1)
                    dffpipe[i] = dffpipe[i-1];
            dffpipe[0] = d;
            i_q <= dffpipe[delay];
        end
    end
 
    assign q = i_q;
 
endmodule // lpm_fifo_dc_dffpipe
 
//------------------------------------------------------------------------
 
module lpm_fifo_dc_fefifo ( usedw_in, wreq, rreq, empty, full, clock, aclr );
 
    parameter lpm_widthad = 1;
    parameter lpm_numwords = 1;
    parameter lpm_mode = "READ";
    parameter underflow_checking = "ON"; 
    parameter overflow_checking = "ON"; 
 
    input [lpm_widthad-1:0] usedw_in;
    input wreq, rreq;
    output empty, full;
    input clock;
    input aclr;
 
	// internal reg
    reg [1:0] sm_empty;
    reg i_empty;
    reg lrreq;
    reg valid_rreq;
    reg i_full;
    integer almostfull;
 
    initial
    begin
        if (lpm_mode != "READ" && lpm_mode != "WRITE")
            $display("Error!  LPM_MODE must be \"READ\" or \"WRITE\".");
        if(underflow_checking != "ON" && underflow_checking != "OFF")
            $display("Error! underflow_checking must be ON or OFF.");
        if(overflow_checking != "ON" && overflow_checking != "OFF")
            $display("Error! overflow_checking must be ON or OFF.");
 
        sm_empty = 2'b00;
        i_empty = 1'b1;
        lrreq = 1'b0;
        i_full = 1'b0;
        almostfull = (lpm_numwords >= 3) ? lpm_numwords-3 : 0;
    end
 
    always @(rreq or i_empty)
        valid_rreq = (underflow_checking == "OFF") ? rreq
                                                   : rreq && !i_empty;
 
    always @(posedge clock or posedge aclr)
    begin
        if (aclr)
        begin
            sm_empty = 2'b00;
            lrreq <= 1'b0;
        end
        else // if ($time > 0)
        begin
            lrreq <= valid_rreq;
            if (lpm_mode == "READ")
            begin
               casex (sm_empty)
                    2'b00:                          // state_empty
                        if (usedw_in != 0)
                            sm_empty = 2'b01;
                    2'b01:                          // state_non_empty
                        if (rreq && ((usedw_in==1 && !lrreq) || (usedw_in==2 && lrreq)))
                            sm_empty = 2'b10;
                    2'b10:                          // state_emptywait
                        if (usedw_in > 1) sm_empty = 2'b01;
                        else sm_empty = 2'b00;
                endcase
            end
            else if (lpm_mode == "WRITE")
            begin
                casex (sm_empty)
                    2'b00:                          // state_empty
                        if (wreq)
                            sm_empty = 2'b01;
                    2'b01:                          // state_one
                        if (!wreq)
                            sm_empty = 2'b11;
                    2'b11:                          // state_non_empty
                        if (wreq)
                            sm_empty = 2'b01;
                        else if (usedw_in == 0)
                            sm_empty = 2'b00;
                endcase
            end
        end
 
        i_empty <= !sm_empty[0];
        i_full <= (!aclr && $time>0 && usedw_in>=almostfull) ? 1'b1 : 1'b0;
    end
 
    assign empty = i_empty;
    assign full = i_full;
 
endmodule // lpm_fifo_dc_fefifo
 
//------------------------------------------------------------------------
//------------------------------------------------------------------------
module lpm_fifo_dc ( data, rdclock, wrclock, aclr, rdreq, wrreq, rdfull,
                      wrfull, rdempty, wrempty, rdusedw, wrusedw, q );
 
	parameter lpm_type = "lpm_fifo_dc";
	parameter lpm_width = 1;
	parameter lpm_widthu = 1;
        parameter lpm_numwords = 1;
	parameter lpm_showahead = "OFF";
	parameter lpm_hint = "USE_EAB=ON"; 
	parameter underflow_checking = "ON"; 
	parameter overflow_checking = "ON"; 
        parameter delay_rdusedw = 1;
        parameter delay_wrusedw = 1;
        parameter rdsync_delaypipe = 3;
        parameter wrsync_delaypipe = 3;
 
	input [lpm_width-1:0] data;
        input rdclock;
        input wrclock;
	input wrreq;
	input rdreq;
	input aclr;
	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 reg
    reg [lpm_width-1:0] mem_data [(1<<lpm_widthu)-1:0];
    reg [lpm_widthu-1:0] i_rdptr, i_wrptr;
    wire [lpm_widthu-1:0] w_rdptrrg, w_wrdelaycycle;
    wire [lpm_widthu-1:0] w_ws_nbrp, w_rs_nbwp, w_ws_dbrp, w_rs_dbwp;
    wire [lpm_widthu-1:0] w_wr_dbuw, w_rd_dbuw, w_rdusedw, w_wrusedw;
    reg [lpm_widthu-1:0] i_wr_udwn, i_rd_udwn;
    wire w_rdempty, w_wrempty, wrdfull, w_wrfull;
    reg i_rdempty, i_wrempty;
    reg i_rdfull, i_wrfull;
    reg i_rden, i_wren, i_rdenclock;
    reg [lpm_width-1:0] i_q;
    integer i;
 
    reg [lpm_width-1:0] i_data_tmp, i_data_reg;
    reg [lpm_width-1:0] i_q_tmp, i_q_reg;
    reg [lpm_widthu-1:0] i_rdptr_tmp, i_wrptr_tmp, i_wrptr_reg;
    reg i_wren_tmp, i_wren_reg;
 
	tri0 aclr;
	buf (i_aclr, aclr);
 
 
    initial
    begin
        if(lpm_showahead != "ON" && lpm_showahead != "OFF")
            $display("Error! lpm_showahead must be ON or OFF.");
        if(underflow_checking != "ON" && underflow_checking != "OFF")
            $display("Error! underflow_checking must be ON or OFF.");
        if(overflow_checking != "ON" && overflow_checking != "OFF")
            $display("Error! overflow_checking must be ON or OFF.");
 
        i_rdptr = 0;
        i_wrptr = 0;
        i_rdempty = 1;
        i_wrempty = 1;
        i_rdfull = 0;
        i_wrfull = 0;
        i_rden = 0;
        i_rdenclock = 0;
        i_wren = 0;
        i_q = 0;
 
        i_data_tmp = 0;
        i_data_reg = 0;
        i_q_tmp = 0;
        i_q_reg = 0;
        i_rdptr_tmp = 0;
        i_wrptr_tmp = 0;
        i_wrptr_reg = 0;
        i_wren_tmp = 0;
        i_wren_reg = 0;
        i_wr_udwn = 0;
        i_rd_udwn = 0;
 
        for (i=0; i<(1<<lpm_widthu); i=i+1)
            mem_data[i] = 0;
    end
 
 
    //--------
    // FIFOram
    //--------
 
    always @(rdreq or i_rdempty)
        i_rden = (underflow_checking == "OFF") ? rdreq
                                               : rdreq && !i_rdempty;
    always @(wrreq or i_wrfull)
        i_wren = (overflow_checking == "OFF") ? wrreq
                                              : wrreq && !i_wrfull;
 
    // FIFOram_sync
    always @(i_data_reg or i_q_tmp or i_q_reg or i_aclr or
             i_rdptr or i_wren_reg or i_wrptr_reg)
    begin
        if (i_aclr)
        begin
            i_wrptr_tmp <= 0;
            i_rdptr_tmp <= 0;
            i_wren_tmp <= 0;
            i_data_tmp <= 0;
            i_q <= (lpm_showahead == "ON") ? i_q_tmp : 0;
        end
        else
        begin
            i_wrptr_tmp <= i_wrptr_reg;
            i_rdptr_tmp <= i_rdptr;
            i_wren_tmp <= i_wren_reg;
            i_data_tmp <= i_data_reg;
            i_q <= (lpm_showahead == "ON") ? i_q_tmp : i_q_reg;
        end
    end
 
    // FIFOram_aclr
    always @(i_aclr)
    begin
        if (i_aclr)
        begin
            i_data_reg <= 0;
            i_wrptr_reg <= 0;
            i_wren_reg <= 0;
            i_q_reg <= 0;
        end
    end
 
    // FIFOram_wrclock
    always @(posedge wrclock)
    begin
        if (!i_aclr && $time > 0)
        begin
            i_data_reg <= data;
            i_wrptr_reg <= i_wrptr;
            i_wren_reg <= i_wren;
        end
    end
 
    // FIFOram_rdclock
    always @(posedge rdclock)
    begin
        if (!i_aclr && i_rden && $time > 0)
            i_q_reg <= i_q_tmp;
    end
 
    // FIFOram_memory_read
    always @(i_rdptr_tmp)
        i_q_tmp <= mem_data[i_rdptr_tmp];
 
    // FIFOram_memory_write_eab
    always @(negedge wrclock)
    begin
        if (lpm_hint == "USE_EAB=ON")
        begin
            if (i_wren_tmp)
                mem_data[i_wrptr_tmp] = i_data_tmp;
            i_q_tmp = mem_data[i_rdptr_tmp];
        end
    end
 
    // FIFOram_memory_write_lcell
    always @(posedge wrclock)
    begin
        if (lpm_hint != "USE_EAB=ON")
        begin
            if (i_wren_tmp)
                mem_data[i_wrptr_tmp] = i_data_tmp;
            i_q_tmp = mem_data[i_rdptr_tmp];
        end
    end
 
 
    //---------
    // Counters
    //---------
 
    // rdptr
    always @(i_aclr)
        if (i_aclr)
            i_rdptr <= 0;
    always @(posedge rdclock)
        if (!i_aclr && i_rden && $time > 0)
            i_rdptr <= ((i_rdptr < (1<<lpm_widthu)-1) || (underflow_checking == "OFF"))
                        ? i_rdptr+1 : 0;
 
    // wrptr
    always @(i_aclr)
        if (i_aclr)
            i_wrptr <= 0;
    always @(posedge wrclock)
        if (!i_aclr && i_wren && $time > 0)
            i_wrptr <= ((i_wrptr < (1<<lpm_widthu)-1) || (overflow_checking == "OFF"))
                        ? i_wrptr+1 : 0;
 
    //-------------------
    // Delays & DFF Pipes
    //-------------------
 
    always @(negedge rdclock)  i_rdenclock <= 0;
    always @(posedge rdclock)  if (i_rden) i_rdenclock <= 1;
 
    lpm_fifo_dc_dffpipe RDPTR_D ( .d (i_rdptr), .q (w_rdptrrg),
                             .clock (i_rdenclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe WRPTR_D ( .d (i_wrptr), .q (w_wrdelaycycle),
                             .clock (wrclock), .aclr (i_aclr) );
    defparam
        RDPTR_D.lpm_delay = 0,
        RDPTR_D.lpm_width = lpm_widthu,
        WRPTR_D.lpm_delay = 1,
        WRPTR_D.lpm_width = lpm_widthu;
 
    lpm_fifo_dc_dffpipe WS_NBRP ( .d (w_rdptrrg), .q (w_ws_nbrp),
                             .clock (wrclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe RS_NBWP ( .d (w_wrdelaycycle), .q (w_rs_nbwp),
                             .clock (rdclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe WS_DBRP ( .d (w_ws_nbrp), .q (w_ws_dbrp),
                             .clock (wrclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe RS_DBWP ( .d (w_rs_nbwp), .q (w_rs_dbwp),
                             .clock (rdclock), .aclr (i_aclr) );   
    defparam
        WS_NBRP.lpm_delay = wrsync_delaypipe,
        WS_NBRP.lpm_width = lpm_widthu,
        RS_NBWP.lpm_delay = rdsync_delaypipe,
        RS_NBWP.lpm_width = lpm_widthu,
        WS_DBRP.lpm_delay = 1,              // gray_delaypipe
        WS_DBRP.lpm_width = lpm_widthu,
        RS_DBWP.lpm_delay = 1,              // gray_delaypipe
        RS_DBWP.lpm_width = lpm_widthu;
 
    always @(i_wrptr or w_ws_dbrp)
        i_wr_udwn = i_wrptr - w_ws_dbrp;
 
    always @(i_rdptr or w_rs_dbwp)
        i_rd_udwn = w_rs_dbwp - i_rdptr;
 
    lpm_fifo_dc_dffpipe WRUSEDW ( .d (i_wr_udwn), .q (w_wrusedw),
                             .clock (wrclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe RDUSEDW ( .d (i_rd_udwn), .q (w_rdusedw),
                             .clock (rdclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe WR_DBUW ( .d (i_wr_udwn), .q (w_wr_dbuw),
                             .clock (wrclock), .aclr (i_aclr) );
    lpm_fifo_dc_dffpipe RD_DBUW ( .d (i_rd_udwn), .q (w_rd_dbuw),
                             .clock (rdclock), .aclr (i_aclr) );
    defparam
        WRUSEDW.lpm_delay = delay_wrusedw,
        WRUSEDW.lpm_width = lpm_widthu,
        RDUSEDW.lpm_delay = delay_rdusedw,
        RDUSEDW.lpm_width = lpm_widthu,
        WR_DBUW.lpm_delay = 1,              // wrusedw_delaypipe
        WR_DBUW.lpm_width = lpm_widthu,
        RD_DBUW.lpm_delay = 1,              // rdusedw_delaypipe
        RD_DBUW.lpm_width = lpm_widthu;
 
 
    //-----------
    // Full/Empty
    //-----------
 
    lpm_fifo_dc_fefifo WR_FE ( .usedw_in (w_wr_dbuw), .wreq (wrreq), .rreq (rdreq),
                          .clock (wrclock), .aclr (i_aclr),
                          .empty (w_wrempty), .full (w_wrfull) );
    lpm_fifo_dc_fefifo RD_FE ( .usedw_in (w_rd_dbuw), .rreq (rdreq), .wreq(wrreq),
                          .clock (rdclock), .aclr (i_aclr),
                          .empty (w_rdempty), .full (w_rdfull) );
 
    defparam
        WR_FE.lpm_widthad = lpm_widthu,
        WR_FE.lpm_numwords = lpm_numwords,
        WR_FE.underflow_checking = underflow_checking,
        WR_FE.overflow_checking = overflow_checking,
        WR_FE.lpm_mode = "WRITE",
        RD_FE.lpm_widthad = lpm_widthu,
        RD_FE.lpm_numwords = lpm_numwords,
        RD_FE.underflow_checking = underflow_checking,
        RD_FE.overflow_checking = overflow_checking,
        RD_FE.lpm_mode = "READ";
 
    always @(w_wrfull)  i_wrfull = w_wrfull;
    always @(w_rdfull)  i_rdfull = w_rdfull;
    always @(w_wrempty)  i_wrempty = w_wrempty;
    always @(w_rdempty)  i_rdempty = w_rdempty;
 
 
    //--------
    // Outputs
    //--------
 
    assign q = i_q;
    assign wrfull = i_wrfull;
    assign rdfull = i_rdfull;
    assign wrempty = i_wrempty;
    assign rdempty = i_rdempty;
    assign wrusedw = w_wrusedw;
    assign rdusedw = w_rdusedw;
 
endmodule // lpm_fifo_dc
 
//------------------------------------------------------------------------
 
module lpm_inpad ( result, pad );
 
	parameter lpm_type = "lpm_inpad";
	parameter lpm_width = 1;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] pad;
	output [lpm_width-1:0] result;
 
	reg    [lpm_width-1:0] result;
 
	always @(pad)
	begin
		result = pad;
	end
 
endmodule // lpm_inpad
 
//------------------------------------------------------------------------
 
module lpm_outpad ( data, pad );
 
	parameter lpm_type = "lpm_outpad";
	parameter lpm_width = 1;
	parameter lpm_hint = "UNUSED";
 
    input  [lpm_width-1:0] data;
    output [lpm_width-1:0] pad;
 
    reg    [lpm_width-1:0] pad;
 
	always @(data)
	begin
		pad = data;
	end
 
endmodule // lpm_outpad
 
//------------------------------------------------------------------------
 
module lpm_bipad ( result, pad, data, enable );
 
	parameter lpm_type = "lpm_bipad";
	parameter lpm_width = 1;
	parameter lpm_hint = "UNUSED";
 
	input  [lpm_width-1:0] data;
	input  enable;
	inout  [lpm_width-1:0] pad;
	output [lpm_width-1:0] result;
 
	reg    [lpm_width-1:0] tmp_pad;
	reg    [lpm_width-1:0] result;
 
	always @(data or pad or enable)
	begin
		if (enable == 1)
		begin
			tmp_pad = data;
			result = 'bz;
		end
		else if (enable == 0)
		begin
			result = pad;
			tmp_pad = 'bz;
		end
	end
 
	assign pad = tmp_pad;
 
endmodule // lpm_bipad
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.