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

Subversion Repositories common

[/] [common/] [trunk/] [LPM_gates.v] - Diff between revs 14 and 48

Show entire file | Details | Blame | View Log

Rev 14 Rev 48
Line 1... Line 1...
 
//------------------------------------------------------------------------
 
//   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.
 
//
 
//------------------------------------------------------------------------
 
// Imported to Opencores directory.   Date Sept 10, 2001
 
// Split related modules into separate files, as the manual splits them.
 
// Added example instantiations to the beginning of each file.
 
//
 
/* EXAMPLE INSTANTIATIONS:
 
 
 
lpm_constant
 
#( 1,                         // lpm_width
 
   0,                         // lpm_cvalue
 
   "UNUSED"                   // lpm_strength, optional, {UNUSED, WEAK}
 
 ) lpm_constant_example (
 
  .result                     (const_out[lpm_width-1:0])
 
);
 
 
 
lpm_inv
 
#( 1                          // lpm_width
 
 ) lpm_inv_example (
 
  .result                     (data_out[lpm_width-1:0]),
 
  .data                       (data_in[lpm_width-1:0])
 
);
 
 
 
// NOTE: Bits data[lpm_size-1:0] are ANDed together to make result[0]
 
lpm_and
 
#( 1,                         // lpm_width (output width)
 
   1                          // lpm_size (inputs to each gate)
 
 ) lpm_and_example (
 
  .result                     (data_out[lpm_width-1:0]),
 
  .data                       (data_in[(lpm_size*lpm_width)-1:0])
 
);
 
 
 
// NOTE: Bits data[lpm_size-1:0] are ORed together to make result[0]
 
lpm_or
 
#( 1,                         // lpm_width (output width)
 
   1                          // lpm_size (inputs to each gate)
 
 ) lpm_or_example (
 
  .result                     (data_out[lpm_width-1:0]),
 
  .data                       (data_in[(lpm_size*lpm_width)-1:0])
 
);
 
 
 
// NOTE: Bits data_[lpm_size-1:0] are XORed together to make result[0]
 
lpm_xor
 
#( 1,                         // lpm_width (output width)
 
   1                          // lpm_size (inputs to each gate)
 
 ) lpm_xor_example (
 
  .result                     (data_out[lpm_width-1:0]),
 
  .data                       (data_in[(lpm_size*lpm_width)-1:0])
 
);
 
 
 
lpm_bustri
 
#( 1                          // lpm_width
 
 ) lpm_bustri_example (
 
  .tridata                    (data_tristate[lpm_width-1:0]),
 
  .data                       (data_to_tristate[lpm_width-1:0]),    // CHOICE
 
  .enabledt                   (enable_data_to_tristate_bus_HIGH),   // OPTIONAL
 
  .result                     (data_from_tristate[lpm_width-1:0]),  // CHOICE
 
  .enabletr                   (enable_data_to_result_bus_HIGH),     // OPTIONAL
 
);
 
 
 
// NOTE: Bits data[lpm_size-1:0] are SELECTED to make result[0]
 
lpm_mux
 
#( 1,                         // lpm_width (output width)
 
   1,                         // lpm_size (inputs to each mux)
 
   1,                         // lpm_widths (number of bits in output select bus)
 
   0                          // lpm_pipeline, optional, {0, 1}
 
 ) lpm_mux_example (
 
  .result                     (data_out[lpm_width-1:0]),
 
  .data                       (data_in[(lpm_size*lpm_width)-1:0]),
 
  .sel                        (data_sel[lpm_widths-1:0]),
 
  .clock                      (clock_if_pipelined),              // OPTIONAL
 
  .clken                      (clock_enable_HIGH_if_pipelined),  // OPTIONAL
 
  .aclr                       (async_clear_if_pipelined)         // OPTIONAL
 
);
 
 
 
lpm_decode
 
#( 1,                         // lpm_width (number of bits in input to be decoded)
 
   1,                         // lpm_decodes (number of actual outputs decoded)
 
   0                          // lpm_pipeline, optional, {0, 1}
 
 ) lpm_decode_example (
 
  .eq                         (decodes_out[lpm_decodes-1:0]),
 
  .data                       (data_in[lpm_width:0]),
 
  .enable                     (force_all_outputs_LOW_when_LOW),  // OPTIONAL
 
  .clock                      (clock_if_pipelined),              // OPTIONAL
 
  .clken                      (clock_enable_HIGH_if_pipelined),  // OPTIONAL
 
  .aclr                       (async_clear_if_pipelined)         // OPTIONAL
 
);
 
 
 
lpm_clshift
 
#( 1,                         // lpm_width (width of input vector)
 
   1,                         // lpm_widthdist (width of shift distance port)
 
   "LOGICAL"                  // lpm_shifttype, optional, {LOGICAL, ROTATE, ARITHMETIC}
 
 ) lpm_clshift_example (
 
  .result                     (data_out[lpm_width-1:0]),
 
  .overflow                   (overflow_means_arith_bit_lost_or_result_became_0),  // OPTIONAL
 
  .underflow                  (underflow_means_result_became_0),  // OPTIONAL
 
  .data                       (data_in[lpm_width-1:0]),
 
  .direction                  (low_means_towards_LSB),  // OPTIONAL
 
  .distance                   (shift_distance[lpm_widthdist-1:0])
 
);
 
*/
 
 
 
//------------------------------------------------------------------------
 
// LPM Synthesizable Models
 
//------------------------------------------------------------------------
 
// 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. LPM_SVALUE, LPM_AVALUE, LPM_MODULUS, and LPM_NUMWORDS,
 
//    LPM_STRENGTH, LPM_DIRECTION, and LPM_PVALUE  default value 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.
 
//
 
//------------------------------------------------------------------------
 
// Synthesis Issues:
 
// 
 
// 1. LPM_COUNTER 
 
//
 
// Currently synthesis tools do not allow mixing of level and edge
 
// sensetive signals. To overcome that problem the "data" signal is
 
// removed from the clock always block of lpm_counter, however the
 
// synthesis result is accurate. For correct simulation add the "data"
 
// pin to the sensetivity list as follows:
 
//
 
//  always @(posedge clock or posedge aclr or posedge aset or 
 
//           posedge aload or data)
 
//------------------------------------------------------------------------
 
 
 
module lpm_constant ( result );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_cvalue = 0;
 
        parameter lpm_strength = "UNUSED";
 
        parameter lpm_type = "lpm_constant";
 
        parameter lpm_hint = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        output [lpm_width-1:0] result;
 
 
 
        assign result = lpm_cvalue;
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_constant") || (lpm_type !== "lpm_constant"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_constant
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_inv ( result, data );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_type = "lpm_inv";
 
        parameter lpm_hint = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        input  [lpm_width-1:0] data;
 
        output [lpm_width-1:0] result;
 
 
 
        reg    [lpm_width-1:0] result;
 
 
 
        always @(data)
 
        begin
 
                result = ~data;
 
        end
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_inv") || (lpm_type !== "lpm_inv"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_inv
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_and ( result, data );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_size = 1;
 
        parameter lpm_type = "lpm_and";
 
        parameter lpm_hint = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_and") || (lpm_type !== "lpm_and"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_and
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_or ( result, data );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_size = 1;
 
        parameter lpm_type = "lpm_or";
 
        parameter lpm_hint  = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_or") || (lpm_type !== "lpm_or"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_or
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_xor ( result, data );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_size = 1;
 
        parameter lpm_type = "lpm_xor";
 
        parameter lpm_hint  = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_xor") || (lpm_type !== "lpm_xor"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_xor
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_bustri ( result, tridata, data, enabledt, enabletr );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_type = "lpm_bustri";
 
        parameter lpm_hint = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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;
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_bustri") || (lpm_type !== "lpm_bustri"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_bustri
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_mux ( result, clock, clken, data, aclr, sel );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_size = 1;
 
        parameter lpm_widths = 1;
 
        parameter lpm_pipeline = 0;
 
        parameter lpm_type = "lpm_mux";
 
        parameter lpm_hint  = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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;
 
 
 
        integer i, j, m, n;
 
        reg [lpm_width-1:0] tmp_result;
 
        reg [lpm_width-1:0] tmp_result2 [lpm_pipeline:0];
 
 
 
        tri0 aclr;
 
        tri0 clock;
 
        tri1 clken;
 
 
 
        buf (i_aclr, aclr);
 
        buf (i_clock, clock);
 
        buf (i_clken, clken);
 
 
 
        always @(data or sel)
 
        begin
 
                tmp_result = 0;
 
                for (m=0; m<lpm_width; m=m+1)
 
                begin
 
                        n = sel * lpm_width + m;
 
                        tmp_result[m] = data[n];
 
                end
 
        end
 
 
 
        always @(posedge i_clock or posedge i_aclr)
 
        begin
 
                if (i_aclr)
 
                begin
 
                        for (i = 0; i <= lpm_pipeline; i = i + 1)
 
                                tmp_result2[i] = 'b0;
 
                end
 
                else if (i_clken == 1)
 
                begin
 
                        tmp_result2[lpm_pipeline] = tmp_result;
 
                        for (j = 0; j < lpm_pipeline; j = j +1)
 
                                tmp_result2[j] = tmp_result2[j+1];
 
                end
 
        end
 
 
 
        assign result = (lpm_pipeline > 0) ? tmp_result2[0] : tmp_result;
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_mux") || (lpm_type !== "lpm_mux"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_mux
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_decode ( eq, data, enable, clock, clken, aclr );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_decodes = 1 << lpm_width;
 
        parameter lpm_pipeline = 0;
 
        parameter lpm_type = "lpm_decode";
 
        parameter lpm_hint = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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, j;
 
 
 
        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)
 
        begin
 
                tmp_eq = 0;
 
                if (i_enable)
 
                begin
 
                        if ((data < lpm_decodes))
 
                        begin
 
                                tmp_eq[data] = 1'b1;
 
                        end
 
                else
 
                        tmp_eq = 0;
 
                end
 
        end
 
 
 
        always @(posedge i_clock or posedge i_aclr)
 
        begin
 
                if (i_aclr)
 
                begin
 
                        for (i = 0; i <= lpm_pipeline; i = i + 1)
 
                                tmp_eq2[i] = 'b0;
 
                end
 
                else if (clken == 1)
 
                begin
 
                        tmp_eq2[lpm_pipeline] = tmp_eq;
 
                        for (j = 0; j < lpm_pipeline; j = j +1)
 
                                tmp_eq2[j] = tmp_eq2[j+1];
 
                end
 
        end
 
 
 
        assign eq = (lpm_pipeline > 0) ? tmp_eq2[0] : tmp_eq;
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_decode") || (lpm_type !== "lpm_decode"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_decode
 
 
 
//------------------------------------------------------------------------
 
 
 
module lpm_clshift ( result, overflow, underflow, data, direction, distance );
 
 
 
// NOTE: Parameters must be declared in the same order as the Properties
 
//       are specified in the Cell Specification document.
 
        parameter lpm_width = 1;
 
        parameter lpm_widthdist = 1;
 
        parameter lpm_shifttype = "LOGICAL";
 
        parameter lpm_type = "lpm_clshift";
 
        parameter lpm_hint = "UNUSED";
 
        parameter lpm_source_version = "lpm 220 version 1.6";
 
 
 
        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
 
                        begin
 
                                tmp_buf = (data >> dist) | (data << (lpm_width - dist));
 
                        end
 
                        else if (dist > 0) // shift left
 
                        begin
 
                                tmp_buf = (data << dist) | (data >> (lpm_width - dist));
 
                        end
 
                        RotateShift = tmp_buf[lpm_width-1:0];
 
                end
 
        endfunction
 
//---------------------------------------------------------------//
 
 
 
        initial
 
        begin
 
                for (i=0; i < lpm_width; i=i+1)
 
                        ONES[i] = 1'b1;
 
        end
 
 
 
        always @(data or i_direction or distance)
 
        begin
 
                // lpm_shifttype is optional and default to LOGICAL
 
                if ((lpm_shifttype == "LOGICAL"))
 
                begin
 
                        {overflow,underflow,result} = LogicShift(data,distance,i_direction);
 
                end
 
                else if (lpm_shifttype == "ARITHMETIC")
 
                begin
 
                        {overflow,underflow,result} = ArithShift(data,distance,i_direction);
 
                end
 
                else if (lpm_shifttype == "ROTATE")
 
                begin
 
                        result = RotateShift(data, distance, i_direction);
 
                        overflow = 1'b0;
 
                        underflow = 1'b0;
 
                end
 
                else
 
                begin
 
                        result = 'bx;
 
                        overflow = 1'b0;
 
                        underflow = 1'b0;
 
                end
 
        end
 
 
 
// Check for previous Parameter declaration order
 
initial if ((lpm_width === "lpm_clshift") || (lpm_type !== "lpm_clshift"))
 
  begin
 
    $display ("LPM 220 Version 1.6 Parameter Order changed; update instantiation");
 
    $finish;
 
  end
 
endmodule // lpm_clshift
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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