📄 220model.v
字号:
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 if (clken == 1) 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_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 tmp_alb, tmp_aeb, tmp_agb ;
reg tmp_aleb, tmp_aneb, tmp_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] a_int;
integer i, j, k, l, m, n, o, p, u, dataa_int, datab_int;
always @( dataa or datab)
begin
if (lpm_representation == "UNSIGNED")
begin
dataa_int = dataa[lpm_width-1:0];
datab_int = datab[lpm_width-1:0];
end
else
if (lpm_representation == "SIGNED")
begin
if ( dataa[lpm_width-1] == 1)
begin
a_int = 0;
for(i = 0; i < lpm_width - 1; i = i + 1)
a_int[i] = dataa[i] ^ 1;
dataa_int = (a_int + 1) * (-1) ;
end
else dataa_int = dataa[lpm_width-1:0];
if ( datab[lpm_width-1] == 1)
begin
a_int = 0;
for(j = 0; j < lpm_width - 1; j = j + 1)
a_int[j] = datab[j] ^ 1;
datab_int = (a_int + 1) * (-1) ;
end
else datab_int = datab[lpm_width-1:0];
end
tmp_alb = (dataa_int < datab_int);
tmp_aeb = (dataa_int == datab_int);
tmp_agb = (dataa_int > datab_int);
tmp_aleb = (dataa_int <= datab_int);
tmp_aneb = (dataa_int != datab_int);
tmp_ageb = (dataa_int >= datab_int);
end
always @( posedge clock or posedge aclr)
begin
if (aclr)
begin
for(u = 0; u <= lpm_pipeline; u = u +1)
begin
tmp_aeb2[u] = 'b0 ;
tmp_agb2[u] = 'b0 ;
tmp_alb2[u] = 'b0 ;
tmp_aleb2[u] = 'b0 ;
tmp_aneb2[u] = 'b0 ;
tmp_ageb2[u] = 'b0 ;
end
end
else if (clken == 1)
begin
// Assign results to registers
tmp_alb2[lpm_pipeline] = tmp_alb ;
tmp_aeb2[lpm_pipeline] = tmp_aeb ;
tmp_agb2[lpm_pipeline] = tmp_agb ;
tmp_aleb2[lpm_pipeline] = tmp_aleb ;
tmp_aneb2[lpm_pipeline] = tmp_aneb ;
tmp_ageb2[lpm_pipeline] = tmp_ageb ;
for(k = 0; k < lpm_pipeline; k = k +1)
tmp_alb2[k] = tmp_alb2[k+1] ;
for(l = 0; l < lpm_pipeline; l = l +1)
tmp_aeb2[l] = tmp_aeb2[l+1] ;
for(m = 0; m < lpm_pipeline; m = m +1)
tmp_agb2[m] = tmp_agb2[m+1] ;
for(n = 0; n < lpm_pipeline; n = n +1)
tmp_aleb2[n] = tmp_aleb2[n+1] ;
for(o = 0; o < lpm_pipeline; o = o +1)
tmp_aneb2[o] = tmp_aneb2[o+1] ;
for(p = 0; p < lpm_pipeline; p = p +1)
tmp_ageb2[p] = tmp_ageb2[p+1] ;
end
end
assign alb = (lpm_pipeline > 0) ? tmp_alb2[0] : tmp_alb;
assign aeb = (lpm_pipeline > 0) ? tmp_aeb2[0] : tmp_aeb;
assign agb = (lpm_pipeline > 0) ? tmp_agb2[0] : tmp_agb;
assign aleb = (lpm_pipeline > 0) ? tmp_aleb2[0] : tmp_aleb;
assign aneb = (lpm_pipeline > 0) ? tmp_aneb2[0] : tmp_aneb;
assign ageb = (lpm_pipeline > 0) ? tmp_ageb2[0] : tmp_ageb;
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 = 2 ;
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] tmp_result ;
reg [lpm_widthp-1:0] tmp_result2 [lpm_pipeline:0];
reg [lpm_widtha-2:0] a_int ;
reg [lpm_widthb-2:0] b_int ;
reg [lpm_widths-2:0] s_int ;
reg [lpm_widthp-2:0] p_reg ;
integer p_int;
integer i, j, k, m, n, p, maxs_mn ;
integer int_dataa, int_datab, int_sum, int_result ;
always @( dataa or datab or sum)
begin
if (lpm_representation == "UNSIGNED")
begin
int_dataa = dataa ;
int_datab = datab ;
int_sum = sum ;
end
else
if (lpm_representation == "SIGNED")
begin
// convert signed dataa
if(dataa[lpm_widtha-1] == 1)
begin
int_dataa = 0 ;
for(i = 0; i < lpm_widtha - 1; i = i + 1)
a_int[i] = dataa[i] ^ 1;
int_dataa = (a_int + 1) * (-1) ;
end
else int_dataa = dataa ;
// convert signed datab
if(datab[lpm_widthb-1] == 1)
begin
int_datab = 0 ;
for(j = 0; j < lpm_widthb - 1; j = j + 1)
b_int[j] = datab[j] ^ 1;
int_datab = (b_int + 1) * (-1) ;
end
else int_datab = datab ;
// convert signed sum
if(sum[lpm_widths-1] == 1)
begin
int_sum = 0 ;
for(k = 0; k < lpm_widths - 1; k = k + 1)
s_int[k] = sum[k] ^ 1;
int_sum = (s_int + 1) * (-1) ;
end
else int_sum = sum ;
end
else
begin
int_dataa = {lpm_widtha{1'bx}} ;
int_datab = {lpm_widthb{1'bx}} ;
int_sum = {lpm_widths{1'bx}} ;
end
p_int = int_dataa * int_datab + int_sum ;
maxs_mn = ((lpm_widtha+lpm_widthb)>lpm_widths)?lpm_widtha+lpm_widthb:lpm_widths ;
if(lpm_widthp >= maxs_mn)
tmp_result = p_int ;
else
begin
p_reg = p_int;
for(m = 0; m < lpm_widthp; m = m +1)
tmp_result[lpm_widthp-1-m] = p_reg[maxs_mn-1-m] ;
end
end
always @(posedge clock or posedge aclr)
begin
if(aclr)
begin
for(p = 0; p <= lpm_pipeline; p = p + 1)
tmp_result2[p] = 'b0;
end
else if (clken == 1)
begin :syn_block
tmp_result2[lpm_pipeline] = tmp_result ;
for(n = 0; n < lpm_pipeline; n = n +1)
tmp_result2[n] = tmp_result2[n+1] ;
end
end
assign result = (lpm_pipeline > 0) ? tmp_result2[0] : tmp_result ;
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_widthq = 1 ;
//parameter lpm_widthr = 1 ;
parameter lpm_nrepresentation = "UNSIGNED" ;
parameter lpm_drepresentation = "UNSIGNED" ;
parameter lpm_pipeline = 0 ;
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 ;
integer i;
integer int_numer, int_denom, int_quotient, int_remain ;
initial
begin
// check if lpm_widthn > 0
if(lpm_widthn <= 0)
$display("%t: Error! LPM_WIDTHN must be greater than 0.\n", $time);
// check if lpm_widthd > 0
if(lpm_widthd <= 0)
$display("%t: Error! LPM_WIDTHD must be greater than 0.\n", $time);
// check if lpm_widthn > 0
//if(lpm_widthq <= 0)
// $display("%t: Error! LPM_WIDTHQ must be greater than 0.\n", $time);
// check if lpm_widthR > 0
//if(lpm_widthr <= 0)
// $display("%t: Error! LPM_WIDTHR must be greater than 0.\n", $time);
// check for valid lpm_nrep value
if((lpm_nrepresentation !== "SIGNED") && (lpm_nrepresentation !== "UNSIGNED"))
$display("%t: Error! LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".", $time);
// check for valid lpm_drep value
if((lpm_drepresentation !== "SIGNED") && (lpm_drepresentation !== "UNSIGNED"))
$display("%t: Error! LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".", $time);
// check if lpm_pipeline is > 1 and clock is not used
if((lpm_pipeline >=1 ) && (clock === 1'bz) )
$display("%t: Error! The clock pin is requied if lpm_pipeline is used\n", $time) ;
else if((lpm_pipeline == 0 ) && (clock !== 1'bz) )
$display("%t: Error! If the clock pin is used, lpm_pipeline must be greater than 0.\n", $time) ;
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)
begin
if (lpm_nrepresentation == "UNSIGNED")
int_numer = numer ;
else if (lpm_nrepresentation == "SIGNED")
begin
// convert signed numer
if(numer[lpm_widthn-1] == 1)
begin
int_numer = 0 ;
for(i = 0; i < lpm_widthn - 1; i = i + 1)
int_numer[i] = numer[i] ^ 1;
int_numer = -(int_numer + 1) ;
end
else int_numer = numer ;
end
else
int_numer = NUNKNOWN ;
if (lpm_drepresentation == "UNSIGNED")
int_denom = denom ;
else if (lpm_drepresentation == "SIGNED")
begin
// convert signed denom
if(denom[lpm_widthd-1] == 1)
begin
int_denom = 0 ;
for(i = 0; i < lpm_widthd - 1; i = i + 1)
int_denom[i] = denom[i] ^ 1;
int_denom = -(int_denom + 1) ;
end
else int_denom = denom ;
end
else
int_denom = DUNKNOWN ;
int_quotient = int_numer / int_denom ;
int_remain = int_numer % int_denom ;
tmp_quotient[lpm_pipeline] = int_quotient ;
tmp_remain[lpm_pipeline] = int_remain ;
end
always @(posedge clock or aclr)
begin :syn_block
if(aclr)
begin
disable syn_block ;
for(i = 0; i <= lpm_pipeline; i = i + 1)
tmp_quotient[i] = ZEROS;
tmp_remain[i] = RZEROS;
end
else
if (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] 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_counter ( q, //eq,
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 [lpm_modulus-1:0] eq ;
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 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -