📄 210model.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.0 Date 07/09/97
//
//------------------------------------------------------------------------
// Excluded Functions:
//
// LPM_RAM_DQ, LPM_RAM_IO, LPM_ROM, and 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_abs ( result, overflow, data ) ;
parameter lpm_type = "lpm_abs" ;
parameter lpm_width = 1 ;
input [lpm_width-1:0] data ;
output [lpm_width-1:0] result ;
output overflow ;
reg [lpm_width-1:0] a_int ;
reg [lpm_width-1:0] result ;
reg overflow;
integer i;
always @(data)
begin
overflow = 0;
if ( data[lpm_width-1] == 1)
begin
a_int = 0;
for(i = 0; i < lpm_width - 1; i = i + 1)
a_int[i] = data[i] ^ 1;
result = (a_int + 1) ;
overflow = (result == ( 1<<(lpm_width -1))) ;
end
else result = data;
end
endmodule // lpm_abs
module lpm_add_sub ( result, cout, overflow,
add_sub, cin, dataa, datab, clock, aclr ) ;
parameter lpm_type = "lpm_add_sub" ;
parameter lpm_width = 1 ;
parameter lpm_pipeline = 0 ;
parameter lpm_representation = "UNSIGNED" ;
parameter lpm_direction = "UNUSED" ;
input [lpm_width-1:0] dataa, datab ;
input add_sub, cin ;
input clock ;
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 ;
reg tmp_cout ;
reg tmp_overflow ;
reg [lpm_width-2:0] tmp_a, tmp_b;
integer i, j, k, n;
integer dataa_int, datab_int, result_int, compare, borrow;
always @( cin or dataa or datab or add_sub )
begin
begin
borrow = cin?0:1 ;
// cout is the same for both signed and unsign representation.
if (lpm_direction == "ADD" || add_sub == 1)
begin
{tmp_cout,tmp_result} = dataa + datab + cin ;
tmp_overflow = tmp_cout ;
end
else
if (lpm_direction == "SUB" || add_sub == 0)
begin
// subtraction
{tmp_overflow, tmp_result} = dataa - datab - borrow ;
tmp_cout = (dataa >= (datab+borrow))?1:0 ;
end
if(lpm_representation == "SIGNED")
begin
// convert to negative integer
if(dataa[lpm_width-1] == 1)
begin
for(j = 0; j < lpm_width - 1; j = j + 1)
tmp_a[j] = dataa[j] ^ 1;
dataa_int = (tmp_a + 1) * (-1) ;
end
else dataa_int = dataa;
// convert to negative integer
if(datab[lpm_width-1] == 1)
begin
for(k = 0; k < lpm_width - 1; k = k + 1)
tmp_b[k] = datab[k] ^ 1;
datab_int = (tmp_b + 1) * (-1);
end
else datab_int = datab;
// perform the addtion or subtraction operation
if(lpm_direction == "ADD" || add_sub == 1)
result_int = dataa_int + datab_int + cin ;
else
if(lpm_direction == "SUB" || add_sub == 0)
result_int = dataa_int - datab_int - borrow ;
tmp_result = result_int ;
// set the overflow
compare = 1 << (lpm_width -1);
if((result_int > (compare - 1)) || (result_int < (-1)*(compare)))
tmp_overflow = 1;
else
tmp_overflow = 0;
end
end
end
always @(posedge clock or posedge aclr )
begin
if(aclr)
begin
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
else begin
tmp_result2[lpm_pipeline] = tmp_result ;
tmp_cout2[lpm_pipeline] = tmp_cout ;
tmp_overflow2[lpm_pipeline] = tmp_overflow ;
for(n = 0; n < lpm_pipeline; n = n +1)
begin
tmp_result2[n] = tmp_result2[n+1] ;
tmp_cout2[n] = tmp_cout2[n+1];
tmp_overflow2[n] = tmp_overflow2[n+1];
end
end
end
assign result = (lpm_pipeline >0) ? tmp_result2[0]:tmp_result ;
assign cout = (lpm_pipeline >0) ? tmp_cout2[0] : tmp_cout;
assign overflow = (lpm_pipeline >0) ? tmp_overflow2[0] : tmp_overflow ;
endmodule // lpm_add_sub
module lpm_and ( result, data ) ;
parameter lpm_type = "lpm_and" ;
parameter lpm_width = 1 ;
parameter lpm_size = 1 ;
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_bipad ( result, pad, data, enable ) ;
parameter lpm_type = "lpm_bipad" ;
parameter lpm_width = 1 ;
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
module lpm_bustri ( result, tridata, data, enabledt, enabletr ) ;
parameter lpm_type = "lpm_bustri" ;
parameter lpm_width = 1 ;
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_clshift ( result, overflow,
underflow, data,
direction, distance) ;
parameter lpm_type = "lpm_clshift" ;
parameter lpm_width = 1 ;
parameter lpm_widthdist = 1 ;
parameter lpm_shifttype = "LOGICAL" ;
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") )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -