📄 220model.v
字号:
always @(posedge inclock)
begin
if((lpm_indata === "REGISTERED") && (lpm_address_control === "REGISTERED"))
begin
paddress <= address;
pdata <= data;
pwe <= we;
end
else
begin
if((lpm_indata === "REGISTERED") && (lpm_address_control === "UNREGISTERED"))
pdata <= data;
if((lpm_indata === "UNREGISTERED") && (lpm_address_control === "REGISTERED"))
begin
paddress <= address;
pwe <= we;
end
end
end
always @(data)
begin
if(lpm_indata === "UNREGISTERED")
pdata <= data;
end
always @(address)
begin
if(lpm_address_control === "UNREGISTERED")
paddress <= address;
end
always @(we)
begin
if(lpm_address_control === "UNREGISTERED")
pwe <= we;
end
always @( pdata or paddress or pwe )
begin :unregistered_inclock
if(ValidAddress(paddress))
begin
if((lpm_indata === "UNREGISTERED" && lpm_address_control === "UNREGISTERED") || (lpm_address_control === "UNREGISTERED"))
begin
if (pwe)
mem_data[paddress] <= pdata ;
end
end
else
begin
if(lpm_outdata === "UNREGISTERED")
tmp_q <= UNKNOWN ;
end
end
always @(posedge outclock )
begin
if(lpm_outdata === "REGISTERED")
begin
if(ValidAddress(paddress))
tmp_q <= mem_data[paddress] ;
else
tmp_q <= UNKNOWN ;
end
end
always @(negedge inclock )
begin
if (lpm_address_control === "REGISTERED")
begin
if (pwe)
mem_data[paddress] <= pdata;
end
end
assign q = ( lpm_outdata === "UNREGISTERED" ) ? mem_data[paddress] : tmp_q ;
endmodule // lpm_ram_dq
//------------------------------------------------------------------------
module lpm_ram_dp ( q, data, wraddress, rdaddress, rdclock, wrclock, rdclken, wrclken, rden, wren) ;
parameter lpm_type = "lpm_ram_dp" ;
parameter lpm_width = 1 ;
parameter lpm_widthad = 1 ;
parameter lpm_numwords = 1<< lpm_widthad ;
parameter lpm_indata = "REGISTERED" ;
parameter lpm_outdata = "REGISTERED" ;
parameter lpm_rdaddress_control = "REGISTERED" ;
parameter lpm_wraddress_control = "REGISTERED" ;
parameter lpm_file = "UNUSED" ;
parameter lpm_hint = "UNUSED" ;
input [lpm_width-1:0] data ;
input [lpm_widthad-1:0] rdaddress, wraddress ;
input rdclock, wrclock, rdclken, wrclken, rden, wren ;
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] prev_q ;
reg [lpm_width-1:0] new_data ;
reg [lpm_widthad-1:0] new_raddress ;
reg [lpm_widthad-1:0] new_wraddress ;
reg wren_event, rden_event;
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.
new_data = 0;
new_raddress = 0;
new_wraddress = 0;
wren_event = 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_rdaddress_control !== "REGISTERED") && (lpm_rdaddress_control !== "UNREGISTERED"))
begin
$display("Error! lpm_rdaddress_control must be REGISTERED (the default) or UNREGISTERED.");
end
if((lpm_wraddress_control !== "REGISTERED") && (lpm_wraddress_control !== "UNREGISTERED"))
begin
$display("Error! lpm_wraddress_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_wraddress_control is set to registered
// wrclock and wrclken must be used.
if(((lpm_indata === "REGISTERED") || (lpm_wraddress_control === "REGISTERED")) && ((wrclock === 1'bz) || (wrclken == 1'bz)))
begin
$display("Error! wrclock = 1'bz. wrclock and wrclken pins must be used.\n");
end
// check if lpm_rdaddress_control is set to registered
// rdclock and rdclken must be used.
if((lpm_rdaddress_control === "REGISTERED") && ((rdclock === 1'bz) || (rdclken == 1'bz)))
begin
$display("Error! rdclock = 1'bz. rdclock and rdclken pins must be used.\n");
end
// check if lpm_outdata, rdclock must be used
if((lpm_outdata === "REGISTERED") && (rdclock === 1'bz))
begin
$display("Error! lpm_outdata = REGISTERED, rdclock = 1'bz . rdclock pnd rdclken pins 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
always @(posedge wrclock)
begin
if (wrclken)
begin
if((lpm_indata === "REGISTERED") && (lpm_wraddress_control === "REGISTERED"))
begin
new_wraddress <= wraddress;
new_data <= data;
wren_event <= wren;
end
else
begin
if((lpm_indata === "REGISTERED") && (lpm_wraddress_control === "UNREGISTERED"))
new_data <= data;
if((lpm_indata === "UNREGISTERED") && (lpm_wraddress_control === "REGISTERED"))
begin
new_wraddress <= wraddress;
wren_event <= wren;
end
end
end
end
always @(data)
begin
if(lpm_indata === "UNREGISTERED")
new_data <= data;
end
always @(wraddress)
begin
if(lpm_wraddress_control === "UNREGISTERED")
new_wraddress <= wraddress;
end
always @(rdaddress)
begin
if(lpm_rdaddress_control === "UNREGISTERED")
new_raddress <= rdaddress;
end
always @(wren)
begin
if(lpm_wraddress_control === "UNREGISTERED")
wren_event <= wren;
end
always @(rden)
begin
if(lpm_rdaddress_control === "UNREGISTERED")
rden_event <= rden;
end
always @( new_data or new_wraddress or wren_event )
begin
if(ValidAddress(new_wraddress))
begin
if ((wren_event) && (wrclken))
mem_data[new_wraddress] <= new_data ;
end
else
begin
if(lpm_outdata === "UNREGISTERED")
tmp_q <= UNKNOWN ;
end
end
always @(posedge rdclock)
begin
if(lpm_rdaddress_control == "REGISTERED")
if (rdclken)
begin
new_raddress <= rdaddress;
rden_event <= rden;
end
if(lpm_outdata === "REGISTERED")
begin
if ((rdclken) && (rden_event))
begin
if(ValidAddress(new_raddress))
begin
tmp_q <= mem_data[new_raddress] ;
end
else
tmp_q <= UNKNOWN ;
end
end
end
//assign q = ( lpm_outdata === "UNREGISTERED" ) ? mem_data[new_raddress] : tmp_q ;
always @( mem_data[new_raddress] or tmp_q or rden )
begin
if (rden || lpm_outdata === "REGISTERED")
prev_q <= ( lpm_outdata === "UNREGISTERED" ) ? mem_data[new_raddress] : tmp_q ;
end
assign q = prev_q;
endmodule // lpm_ram_dp
//------------------------------------------------------------------------
module lpm_ram_io ( dio, inclock, outclock, we, memenab, outenab, address ) ;
parameter lpm_type = "lpm_ram_io" ;
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_widthad-1:0] address ;
input inclock, outclock, we ;
input memenab ;
input outenab ;
inout [lpm_width-1:0] dio ;
// inernal reg
reg [lpm_width-1:0] mem_data [lpm_numwords-1:0];
reg [lpm_width-1:0] tmp_io ;
reg [lpm_width-1:0] tmp_q ;
reg [lpm_width-1:0] pdio ;
reg [lpm_widthad-1:0] paddress ;
reg pwe ;
reg [lpm_width-1:0] ZEROS, UNKNOWN, HiZ ;
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.", $time) ;
else if(paddress >= lpm_numwords)
$display("%d:Error: Address out of bound on RAM.", $time) ;
else
ValidAddress = 1'b1 ;
end
endfunction
initial
begin
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 is 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 ;
HiZ[i] = 1'bZ ;
end
for(i = 0; i < lpm_numwords; i=i+1)
mem_data[i] = ZEROS ;
// Initialize input/output
pdio = 0;
paddress = 0;
tmp_io = 0;
tmp_q = 0;
// 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
always @(dio)
begin
if(lpm_indata === "UNREGISTERED")
pdio <= dio;
end
always @(address)
begin
if(lpm_address_control === "UNREGISTERED")
paddress <= address;
end
always @(we)
begin
if(lpm_address_control === "UNREGISTERED")
pwe <= we;
end
always @(posedge inclock)
begin
if(lpm_indata === "REGISTERED")
pdio <= dio;
if(lpm_address_control === "REGISTERED")
begin
paddress <= address;
pwe <= we;
end
end
always @( pdio or paddress or pwe or memenab )
begin :block_a
if(ValidAddress(paddress))
begin
if((lpm_indata === "UNREGISTERED" && lpm_address_control === "UNREGISTERED") || (lpm_address_control === "UNREGISTERED"))
begin
if (pwe && memenab)
mem_data[paddress] <= pdio ;
end
if(lpm_outdata === "UNREGISTERED")
begin
tmp_q <= mem_data[paddress];
tmp_q <= mem_data[paddress];
end
end
else
begin
if(lpm_outdata === "UNREGISTERED")
tmp_q <= UNKNOWN ;
end
end
always @(negedge inclock )
begin
if (lpm_address_control === "REGISTERED")
begin
if (pwe && memenab)
mem_data[paddress] <= pdio ;
end
end
always @(posedge outclock )
begin
if(lpm_outdata === "REGISTERED")
begin
tmp_q <= mem_data[paddress];
end
end
always @( memenab or outenab or tmp_q)
begin
if(memenab && outenab)
tmp_io <= tmp_q ;
else if(!memenab || (memenab && !outenab))
tmp_io <= HiZ ;
end
assign dio = tmp_io ;
endmodule // lpm_ram_io
//------------------------------------------------------------------------
module lpm_rom ( q, inclock, outclock, memenab, address ) ;
parameter lpm_type = "lpm_rom" ;
parameter lpm_width = 1 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -