/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Top Level Test Bench ////
|
//// Top Level Test Bench ////
|
//// Task Library ////
|
//// Task Library ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// Author: Rudolf Usselmann ////
|
//// Author: Rudolf Usselmann ////
|
//// rudi@asics.ws ////
|
//// rudi@asics.ws ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
|
//// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
//// www.asics.ws ////
|
//// www.asics.ws ////
|
//// rudi@asics.ws ////
|
//// rudi@asics.ws ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer.////
|
//// the original copyright notice and the associated disclaimer.////
|
//// ////
|
//// ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
|
|
// CVS Log
|
// CVS Log
|
//
|
//
|
// $Id: test_lib.v,v 1.4 2002-01-21 13:10:37 rudi Exp $
|
// $Id: test_lib.v,v 1.4 2002-01-21 13:10:37 rudi Exp $
|
//
|
//
|
// $Date: 2002-01-21 13:10:37 $
|
// $Date: 2002-01-21 13:10:37 $
|
// $Revision: 1.4 $
|
// $Revision: 1.4 $
|
// $Author: rudi $
|
// $Author: rudi $
|
// $Locker: $
|
// $Locker: $
|
// $State: Exp $
|
// $State: Exp $
|
//
|
//
|
// Change History:
|
// Change History:
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
// Revision 1.3 2001/11/11 01:52:03 rudi
|
// Revision 1.3 2001/11/11 01:52:03 rudi
|
//
|
//
|
// Minor fixes to testbench ...
|
// Minor fixes to testbench ...
|
//
|
//
|
// Revision 1.2 2001/09/02 02:29:43 rudi
|
// Revision 1.2 2001/09/02 02:29:43 rudi
|
//
|
//
|
// Fixed the TMS register setup to be tight and correct.
|
// Fixed the TMS register setup to be tight and correct.
|
//
|
//
|
// Revision 1.1 2001/07/29 07:34:40 rudi
|
// Revision 1.1 2001/07/29 07:34:40 rudi
|
//
|
//
|
//
|
//
|
// 1) Changed Directory Structure
|
// 1) Changed Directory Structure
|
// 2) Fixed several minor bugs
|
// 2) Fixed several minor bugs
|
//
|
//
|
// Revision 1.1.1.1 2001/05/13 09:36:38 rudi
|
// Revision 1.1.1.1 2001/05/13 09:36:38 rudi
|
// Created Directory Structure
|
// Created Directory Structure
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Bandwidth Monitor
|
// Bandwidth Monitor
|
//
|
//
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if(wb_cyc_i) cyc_cnt = cyc_cnt + 1;
|
if(wb_cyc_i) cyc_cnt = cyc_cnt + 1;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if(wb_ack_o) ack_cnt = ack_cnt + 1;
|
if(wb_ack_o) ack_cnt = ack_cnt + 1;
|
|
|
task bw_report;
|
task bw_report;
|
|
|
integer bytes;
|
integer bytes;
|
|
|
begin
|
begin
|
|
|
bytes = ack_cnt * 4;
|
bytes = ack_cnt * 4;
|
$display("Last WB Bandwidth: %0d Mbytes/sec", bytes * 1000/(cyc_cnt * 10));
|
$display("Last WB Bandwidth: %0d Mbytes/sec", bytes * 1000/(cyc_cnt * 10));
|
end
|
end
|
endtask
|
endtask
|
|
|
task bw_clear;
|
task bw_clear;
|
|
|
begin
|
begin
|
cyc_cnt = 0;
|
cyc_cnt = 0;
|
ack_cnt = 0;
|
ack_cnt = 0;
|
end
|
end
|
endtask
|
endtask
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Suspend Resume Task
|
// Suspend Resume Task
|
//
|
//
|
|
|
task susp_res;
|
task susp_res;
|
begin
|
begin
|
|
|
#1;
|
#1;
|
susp_req = 1;
|
susp_req = 1;
|
while(!suspended) @(posedge clk);
|
while(!suspended) @(posedge clk);
|
#1;
|
#1;
|
susp_req = 0;
|
susp_req = 0;
|
repeat(20) @(posedge clk);
|
repeat(20) @(posedge clk);
|
#1;
|
#1;
|
resume_req = 1;
|
resume_req = 1;
|
while(suspended) @(posedge clk);
|
while(suspended) @(posedge clk);
|
#1;
|
#1;
|
resume_req = 0;
|
resume_req = 0;
|
repeat(1) @(posedge clk);
|
repeat(1) @(posedge clk);
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Bus Request/Grant Task
|
// Bus Request/Grant Task
|
//
|
//
|
task bus_req;
|
task bus_req;
|
begin
|
begin
|
mc_br = 1;
|
mc_br = 1;
|
while(!mc_bg) @(posedge clk);
|
while(!mc_bg) @(posedge clk);
|
repeat(40) @(posedge clk);
|
repeat(40) @(posedge clk);
|
mc_br = 0;
|
mc_br = 0;
|
repeat(2) @(posedge clk);
|
repeat(2) @(posedge clk);
|
end
|
end
|
endtask
|
endtask
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Monitor CKE
|
// Monitor CKE
|
//
|
//
|
time cke_low;
|
time cke_low;
|
|
|
always @(negedge mc_cke_)
|
always @(negedge mc_cke_)
|
cke_low = $time;
|
cke_low = $time;
|
|
|
always @(posedge mc_cke_)
|
always @(posedge mc_cke_)
|
if(($time-cke_low) < 10)
|
if(($time-cke_low) < 10)
|
$display("WARNING: Cke low period was %t. (%t, %t)",($time-cke_low), cke_low, $time);
|
$display("WARNING: Cke low period was %t. (%t, %t)",($time-cke_low), cke_low, $time);
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Monitor wb_err_o
|
// Monitor wb_err_o
|
//
|
//
|
always @(posedge clk)
|
always @(posedge clk)
|
if(wb_err_o & !wb_err_check_dis)
|
if(wb_err_o & !wb_err_check_dis)
|
$display("WARNING: WB_ERR_O was asserted at time %0t",$time);
|
$display("WARNING: WB_ERR_O was asserted at time %0t",$time);
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Watchdog Counter
|
// Watchdog Counter
|
//
|
//
|
|
|
always @(wb_ack_o or wb_stb_i)
|
always @(wb_ack_o or wb_stb_i)
|
wd_cnt = 0;
|
wd_cnt = 0;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
wd_cnt = wd_cnt + 1;
|
wd_cnt = wd_cnt + 1;
|
|
|
always @(wd_cnt)
|
always @(wd_cnt)
|
if(wd_cnt>6000)
|
if(wd_cnt>6000)
|
begin
|
begin
|
$display("\n\n*************************************\n");
|
$display("\n\n*************************************\n");
|
$display("ERROR: Watch Dog Counter Expired\n");
|
$display("ERROR: Watch Dog Counter Expired\n");
|
$display("*************************************\n\n\n");
|
$display("*************************************\n\n\n");
|
$finish;
|
$finish;
|
end
|
end
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Show Errors
|
// Show Errors
|
//
|
//
|
|
|
task show_errors;
|
task show_errors;
|
|
|
begin
|
begin
|
|
|
$display("\n");
|
$display("\n");
|
$display(" +--------------------+");
|
$display(" +--------------------+");
|
$display(" | Total ERRORS: %0d |", error_cnt);
|
$display(" | Total ERRORS: %0d |", error_cnt);
|
$display(" +--------------------+");
|
$display(" +--------------------+");
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Reset Memory Controller
|
// Reset Memory Controller
|
//
|
//
|
|
|
task mc_reset;
|
task mc_reset;
|
|
|
begin
|
begin
|
repeat(10) @(posedge clk);
|
repeat(10) @(posedge clk);
|
rst = 1;
|
rst = 1;
|
repeat(10) @(posedge clk);
|
repeat(10) @(posedge clk);
|
rst = 0;
|
rst = 0;
|
repeat(20) @(posedge clk);
|
repeat(20) @(posedge clk);
|
end
|
end
|
endtask
|
endtask
|
|
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Fill SDRAMs
|
// Fill SDRAMs
|
//
|
//
|
|
|
task fill_mem;
|
task fill_mem;
|
input size;
|
input size;
|
|
|
integer size, n;
|
integer size, n;
|
reg [31:0] data;
|
reg [31:0] data;
|
|
|
begin
|
begin
|
sdram0.mem_fill(size);
|
sdram0.mem_fill(size);
|
|
|
for(n=0;n<size;n=n+1)
|
for(n=0;n<size;n=n+1)
|
begin
|
begin
|
data = sdram0.Bank0[n];
|
data = sdram0.Bank0[n];
|
sdram0p.Bank0[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram0p.Bank0[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram0.Bank1[n];
|
data = sdram0.Bank1[n];
|
sdram0p.Bank1[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram0p.Bank1[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram0.Bank2[n];
|
data = sdram0.Bank2[n];
|
sdram0p.Bank2[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram0p.Bank2[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram0.Bank3[n];
|
data = sdram0.Bank3[n];
|
sdram0p.Bank3[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram0p.Bank3[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
end
|
end
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
task fill_mem1;
|
task fill_mem1;
|
input size;
|
input size;
|
|
|
integer size, n;
|
integer size, n;
|
reg [31:0] data;
|
reg [31:0] data;
|
|
|
begin
|
begin
|
sdram1.mem_fill(size);
|
sdram1.mem_fill(size);
|
|
|
for(n=0;n<size;n=n+1)
|
for(n=0;n<size;n=n+1)
|
begin
|
begin
|
data = sdram1.Bank0[n];
|
data = sdram1.Bank0[n];
|
sdram1p.Bank0[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram1p.Bank0[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram1.Bank1[n];
|
data = sdram1.Bank1[n];
|
sdram1p.Bank1[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram1p.Bank1[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram1.Bank2[n];
|
data = sdram1.Bank2[n];
|
sdram1p.Bank2[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram1p.Bank2[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram1.Bank3[n];
|
data = sdram1.Bank3[n];
|
sdram1p.Bank3[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram1p.Bank3[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
end
|
end
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
task fill_mem2;
|
task fill_mem2;
|
input size;
|
input size;
|
|
|
integer size, n;
|
integer size, n;
|
reg [31:0] data;
|
reg [31:0] data;
|
|
|
begin
|
begin
|
sdram2.mem_fill(size);
|
sdram2.mem_fill(size);
|
|
|
for(n=0;n<size;n=n+1)
|
for(n=0;n<size;n=n+1)
|
begin
|
begin
|
data = sdram2.Bank0[n];
|
data = sdram2.Bank0[n];
|
sdram2p.Bank0[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram2p.Bank0[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram2.Bank1[n];
|
data = sdram2.Bank1[n];
|
sdram2p.Bank1[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram2p.Bank1[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram2.Bank2[n];
|
data = sdram2.Bank2[n];
|
sdram2p.Bank2[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram2p.Bank2[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
data = sdram2.Bank3[n];
|
data = sdram2.Bank3[n];
|
sdram2p.Bank3[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
sdram2p.Bank3[n] = {28'h0, ^data[31:24], ^data[23:16], ^data[15:8], ^data[7:0] };
|
end
|
end
|
|
|
end
|
end
|
endtask
|
endtask
|
|
|
|
|
|
|