📄 220model.v
字号:
//------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------
// 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)
//------------------------------------------------------------------------
// Modification History:
//
//------------------------------------------------------------------------
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)
begin
result = ~data ;
end
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_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_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 enabletr ;
input enabledt ;
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 ;
always @(data or tridata or enabletr or enabledt)
begin
if (enabledt == 0 && enabletr == 1)
begin
result = tridata;
tmp_tridata = 'bz;
end
else
if (enabledt == 1 && enabletr == 0)
begin
result = 'bz;
tmp_tridata = data;
end
else
if (enabledt == 1 && 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 ;
integer i, j, m, n;
reg [lpm_width-1:0] tmp_result;
reg [lpm_width-1:0] tmp_result2 [lpm_pipeline:0];
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 clock or posedge aclr)
begin
if (aclr)
begin
for(i = 0; i <= lpm_pipeline; i = i + 1)
tmp_result2[i] = 'b0 ;
end
else if (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;
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, j;
always @( data or enable)
begin
tmp_eq = 0;
if (enable)
begin
if( (data < lpm_decodes))
begin
tmp_eq[data] = 1'b1 ;
end else
tmp_eq = 0;
end
end
always @(posedge clock or posedge aclr)
begin
if (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;
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;
//---------------------------------------------------------------//
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 direction or distance)
begin
// lpm_shifttype is optional and default to LOGICAL
if ((lpm_shifttype == "LOGICAL") )
begin
{overflow,underflow,result} = LogicShift(data,distance,direction);
end
else if (lpm_shifttype == "ARITHMETIC")
begin
{overflow,underflow,result} = ArithShift(data,distance,direction);
end
else if (lpm_shifttype == "ROTATE")
begin
result = RotateShift(data, distance, direction) ;
overflow = 1'b0;
underflow = 1'b0;
end
else
begin
result = 'bx ;
overflow = 1'b0;
underflow = 1'b0;
end
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_result ;
reg [lpm_width-1:0] tmp_result2 [lpm_pipeline:0] ;
reg [lpm_pipeline:0] tmp_cout2 ;
reg [lpm_pipeline:0] tmp_overflow2 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -