📄 220model.v
字号:
reg tmp_updown ;
integer tmp_modulus ;
//---------------------------------------------------------------//
function [lpm_width-1:0] NextBin ;
input [lpm_width-1:0] count ;
//reg [lpm_width-1:0] re_start ;
//reg [lpm_width-1:0] tmp_nextbin ;
//integer up_limit ;
begin
if(tmp_updown == 1)
begin
if(cin == 1 && count == tmp_modulus-2)
NextBin = 0 ;
else
NextBin = (count >= tmp_modulus-1) ? cin : count+1+cin;
end
else
begin
if(cin == 1 && count == 1)
NextBin = tmp_modulus - 1 ;
else
NextBin = (count <= 0) ? tmp_modulus-1-cin : count-1-cin;
end
end
endfunction
//---------------------------------------------------------------//
// function [(1<<lpm_width)-1:0] CountDecode ;
//---------------------------------------------------------------//
// function [lpm_modulus:0] CountDecode ;
// input [lpm_width-1:0] count ;
// integer eq_index ;
// begin
// CountDecode = 0 ;
// eq_index = 0;
// if(count < lpm_modulus)
// begin
// eq_index = count ;
// CountDecode[eq_index] = 1'b1 ;
// end
// end
// endfunction
//---------------------------------------------------------------//
// 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("%t: Error! LPM_MODULUS must be greater than 0.\n", $time);
// check if lpm_modulus > 1<<lpm_width
if(lpm_modulus > 1<<lpm_width)
$display("%t: Error! LPM_MODULUS must be less than or equal to 1<<LPM_WIDTH.\n", $time);
if(lpm_direction == "UNUSED")
tmp_updown = (updown == 0) ? 0 : 1 ;
else
tmp_updown = (lpm_direction == "DOWN") ? 0 : 1 ;
tmp_modulus = (lpm_modulus == 0) ? (1 << lpm_width) : lpm_modulus ;
tmp_count = (lpm_pvalue == "UNUSED") ? 0 : str_to_int(lpm_pvalue) ;
end
always @( updown )
begin
if(lpm_direction == "UNUSED")
tmp_updown = (updown == 0) ? 0 : 1 ;
else
$display("%t: Error! LPM_DIRECTION and UPDOWN cannot be used at the same time.\n", $time);
end
always @( posedge clock or posedge aclr or posedge aset or
posedge aload )
begin :asyn_block
if (aclr)
tmp_count = 0 ;
else if (aset)
tmp_count = (lpm_avalue == "UNUSED") ? {lpm_width{1'b1}}
: str_to_int(lpm_avalue) ;
else if (aload)
tmp_count = data ;
else
begin :syn_block
if(clk_en)
begin
if (sclr)
tmp_count = 0 ;
else if (sset)
tmp_count = (lpm_svalue == "UNUSED") ? {lpm_width{1'b1}}
: str_to_int(lpm_svalue) ;
else if (sload)
tmp_count = data ;
else if (cnt_en)
tmp_count = NextBin(tmp_count) ;
end
end
end
assign q = tmp_count ;
//assign eq = CountDecode(tmp_count) ;
assign cout = (((tmp_count >= tmp_modulus-1-cin) && tmp_updown)
|| ((tmp_count <= cin) && !tmp_updown)) ? 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 ;
//---------------------------------------------------------------//
// 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
//---------------------------------------------------------------//
always @(data or gate or aclr or aset)
begin
if (aclr)
q = 'b0;
else if (aset)
begin
if (lpm_avalue == "UNUSED")
q = {lpm_width{1'b1}};
else
q = str_to_int(lpm_avalue);
end
else if (gate)
q = 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 ;
integer i ;
//---------------------------------------------------------------//
// 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
//---------------------------------------------------------------//
always @( posedge clock or posedge aclr or posedge aset or posedge aload )
begin :asyn_block // Asynchronous process
if (aclr)
begin
tmp_q = 0 ;
end
else if (aset)
begin
if (lpm_avalue == "UNUSED")
tmp_q = {lpm_width{1'b1}};
else
tmp_q = str_to_int(lpm_avalue) ;
end
else if (aload)
begin
tmp_q = data ;
end
else
begin :syn_block // Synchronous process
if (enable)
begin
if(sclr)
begin
tmp_q = 0;
end
else if (sset )
begin
if (lpm_svalue == "UNUSED")
tmp_q = {lpm_width{1'b1}};
else
tmp_q = str_to_int(lpm_svalue) ;
end
else if (sload) // Load data
begin
tmp_q = data ;
end
else
begin
if(lpm_fftype == "TFF") // toggle
begin
for (i = 0 ; i < lpm_width; i=i+1)
begin
if(data[i] == 1'b1)
tmp_q[i] = ~tmp_q[i];
end
end
else
if(lpm_fftype == "DFF") // load data
tmp_q = data ;
end
end
end
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;
//---------------------------------------------------------------//
// 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
//---------------------------------------------------------------//
always @( posedge clock or posedge aclr or posedge aset )
begin :asyn_block // Asynchronous process
if (aclr)
begin
tmp_q = 0 ;
end
else if (aset )
begin
if (lpm_avalue === "UNUSED")
tmp_q = {lpm_width{1'b1}};
else
tmp_q = str_to_int(lpm_avalue) ;
end
else
begin :syn_block // Synchronous process
if (enable)
begin
if(sclr)
begin
tmp_q = 0;
end
else if (sset)
begin
if (lpm_svalue === "UNUSED")
tmp_q = {lpm_width{1'b1}};
else
tmp_q = str_to_int(lpm_svalue) ;
end
else if (load)
begin
tmp_q = data ;
end
else if (!load)
begin
if(lpm_direction === "LEFT")
begin
{abit,tmp_q} = {tmp_q,shiftin};
end
else if(lpm_direction === "RIGHT")
begin
{tmp_q,abit} = {shiftin,tmp_q};
end
end
end
end
end
assign tmp_shiftout = (lpm_direction === "LEFT")?tmp_q[lpm_width-1]:tmp_q[0];
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" ;
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, UNKNOWN ;
reg [8*256:1] ram_initf ;
integer i ;
function ValidAddress ;
input [lpm_widthad-1:0] paddress ;
begin
ValidAddress = 1'b0 ;
if(^paddress ==='bx)
$display("%d:Error! Invalid address.\n", $time) ;
else if(paddress >= lpm_numwords)
$display("%d: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;
tmp_q = 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))))
begin
$display("Error! lpm_numwords must equal to the ceiling of log2(lpm_widthad).");
end
if((lpm_indata !== "REGISTERED") && (lpm_indata !== "UNREGISTERED"))
begin
$display("Error! lpm_indata must be REGISTERED (the default) or UNREGISTERED.");
end
if((lpm_address_control !== "REGISTERED") && (lpm_address_control !== "UNREGISTERED"))
begin
$display("Error! lpm_address_control must be REGISTERED (the default) or UNREGISTERED.");
end
if((lpm_outdata !== "REGISTERED") && (lpm_outdata !== "UNREGISTERED"))
begin
$display("Error! lpm_outdata must be REGISTERED (the default) or UNREGISTERED.");
end
// check if lpm_indata or lpm_address_control is set to registered
// inclock must be used.
if(((lpm_indata === "REGISTERED") || (lpm_address_control === "REGISTERED")) && (inclock === 1'bz))
begin
$display("Error! inclock = 1'bz. Inclock pin must be used.\n");
end
// check if lpm_outdata, outclock must be used
if((lpm_outdata === "REGISTERED") && (outclock === 1'bz))
begin
$display("Error! lpm_outdata = REGISTERED, outclock = 1'bz . Outclock pin must be used.\n");
end
for(i=0; i < lpm_width; i=i+1)
begin
ZEROS[i] = 1'b0 ;
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
$convert_hex2ver(lpm_file, lpm_width, ram_initf);
$readmemh(ram_initf, mem_data);
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -