URL
https://opencores.org/ocsvn/wb_dma/wb_dma/trunk
Subversion Repositories wb_dma
Compare Revisions
- This comparison shows the changes necessary to convert path
/wb_dma/trunk/bench/verilog
- from Rev 15 to Rev 17
- ↔ Reverse comparison
Rev 15 → Rev 17
/wb_mast_model.v
0,0 → 1,687
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE Master Model //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/wb_dma/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: wb_mast_model.v,v 1.3 2002-02-01 01:55:44 rudi Exp $ |
// |
// $Date: 2002-02-01 01:55:44 $ |
// $Revision: 1.3 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2001/09/07 15:34:36 rudi |
// |
// Changed reset to active high. |
// |
// Revision 1.1 2001/07/29 08:57:02 rudi |
// |
// |
// 1) Changed Directory Structure |
// 2) Added restart signal (REST) |
// |
// Revision 1.1.1.1 2001/03/19 13:11:34 rudi |
// Initial Release |
// |
// |
// |
|
`include "wb_model_defines.v" |
|
module wb_mast(clk, rst, adr, din, dout, cyc, stb, sel, we, ack, err, rty); |
|
input clk, rst; |
output [31:0] adr; |
input [31:0] din; |
output [31:0] dout; |
output cyc, stb; |
output [3:0] sel; |
output we; |
input ack, err, rty; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Local Wires |
// |
|
parameter mem_size = 4096; |
|
reg [31:0] adr; |
reg [31:0] dout; |
reg cyc, stb; |
reg [3:0] sel; |
reg we; |
|
reg [31:0] rd_mem[mem_size:0]; |
reg [31:0] wr_mem[mem_size:0]; |
integer rd_cnt; |
integer wr_cnt; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Memory Logic |
// |
|
initial |
begin |
//adr = 32'hxxxx_xxxx; |
//adr = 0; |
adr = 32'hffff_ffff; |
dout = 32'hxxxx_xxxx; |
cyc = 0; |
stb = 0; |
sel = 4'hx; |
we = 1'hx; |
rd_cnt = 0; |
wr_cnt = 0; |
#1; |
$display("\nINFO: WISHBONE MASTER MODEL INSTANTIATED (%m)\n"); |
end |
|
|
|
task mem_fill; |
|
integer n; |
begin |
rd_cnt = 0; |
wr_cnt = 0; |
for(n=0;n<mem_size;n=n+1) |
begin |
rd_mem[n] = $random; |
wr_mem[n] = $random; |
end |
end |
endtask |
|
//////////////////////////////////////////////////////////////////// |
// |
// Write 1 Word Task |
// |
|
task wb_wr1; |
input [31:0] a; |
input [3:0] s; |
input [31:0] d; |
|
begin |
|
@(posedge clk); |
#1; |
adr = a; |
dout = d; |
cyc = 1; |
stb = 1; |
we=1; |
sel = s; |
|
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#1; |
cyc=0; |
stb=0; |
adr = 32'hxxxx_xxxx; |
//adr = 32'hffff_ffff; |
//adr = 0; |
dout = 32'hxxxx_xxxx; |
we = 1'hx; |
sel = 4'hx; |
|
end |
endtask |
|
//////////////////////////////////////////////////////////////////// |
// |
// Write 4 Words Task |
// |
|
task wb_wr4; |
input [31:0] a; |
input [3:0] s; |
input delay; |
input [31:0] d1; |
input [31:0] d2; |
input [31:0] d3; |
input [31:0] d4; |
|
integer delay; |
|
begin |
|
@(posedge clk); |
#1; |
cyc = 1; |
sel = s; |
|
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
adr = a; |
dout = d1; |
stb = 1; |
we=1; |
while(~ack & ~err) @(posedge clk); |
#2; |
stb=0; |
we=1'bx; |
dout = 32'hxxxx_xxxx; |
|
|
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
stb=1; |
adr = a+4; |
dout = d2; |
we=1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#2; |
stb=0; |
we=1'bx; |
dout = 32'hxxxx_xxxx; |
|
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
stb=1; |
adr = a+8; |
dout = d3; |
we=1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#2; |
stb=0; |
we=1'bx; |
dout = 32'hxxxx_xxxx; |
|
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
stb=1; |
adr = a+12; |
dout = d4; |
we=1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#1; |
stb=0; |
cyc=0; |
|
adr = 32'hxxxx_xxxx; |
//adr = 0; |
//adr = 32'hffff_ffff; |
dout = 32'hxxxx_xxxx; |
we = 1'hx; |
sel = 4'hx; |
|
end |
endtask |
|
|
task wb_wr_mult; |
input [31:0] a; |
input [3:0] s; |
input delay; |
input count; |
|
integer delay; |
integer count; |
integer n; |
|
begin |
|
@(posedge clk); |
#1; |
cyc = 1; |
|
for(n=0;n<count;n=n+1) |
begin |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
adr = a + (n*4); |
dout = wr_mem[n + wr_cnt]; |
stb = 1; |
we=1; |
sel = s; |
if(n!=0) @(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#2; |
stb=0; |
we=1'bx; |
sel = 4'hx; |
dout = 32'hxxxx_xxxx; |
adr = 32'hxxxx_xxxx; |
end |
|
cyc=0; |
|
adr = 32'hxxxx_xxxx; |
//adr = 32'hffff_ffff; |
|
wr_cnt = wr_cnt + count; |
end |
endtask |
|
|
task wb_rmw; |
input [31:0] a; |
input [3:0] s; |
input delay; |
input rcount; |
input wcount; |
|
integer delay; |
integer rcount; |
integer wcount; |
integer n; |
|
begin |
|
@(posedge clk); |
#1; |
cyc = 1; |
we = 0; |
sel = s; |
repeat(delay) @(posedge clk); |
|
for(n=0;n<rcount-1;n=n+1) |
begin |
adr = a + (n*4); |
stb = 1; |
while(~ack & ~err) @(posedge clk); |
rd_mem[n + rd_cnt] = din; |
//$display("Rd Mem[%0d]: %h", (n + rd_cnt), rd_mem[n + rd_cnt] ); |
#2; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hxxxx_xxxx; |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
we = 0; |
sel = s; |
end |
|
adr = a+(n*4); |
stb = 1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
rd_mem[n + rd_cnt] = din; |
//$display("Rd Mem[%0d]: %h", (n + rd_cnt), rd_mem[n + rd_cnt] ); |
#1; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hxxxx_xxxx; |
|
rd_cnt = rd_cnt + rcount; |
|
//@(posedge clk); |
|
|
for(n=0;n<wcount;n=n+1) |
begin |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
adr = a + (n*4); |
dout = wr_mem[n + wr_cnt]; |
stb = 1; |
we=1; |
sel = s; |
// if(n!=0) |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#2; |
stb=0; |
we=1'bx; |
sel = 4'hx; |
dout = 32'hxxxx_xxxx; |
adr = 32'hxxxx_xxxx; |
end |
|
cyc=0; |
|
adr = 32'hxxxx_xxxx; |
//adr = 32'hffff_ffff; |
|
wr_cnt = wr_cnt + wcount; |
end |
endtask |
|
|
|
|
task wb_wmr; |
input [31:0] a; |
input [3:0] s; |
input delay; |
input rcount; |
input wcount; |
|
integer delay; |
integer rcount; |
integer wcount; |
integer n; |
|
begin |
|
@(posedge clk); |
#1; |
cyc = 1; |
we = 1'bx; |
sel = 4'hx; |
sel = s; |
|
for(n=0;n<wcount;n=n+1) |
begin |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
adr = a + (n*4); |
dout = wr_mem[n + wr_cnt]; |
stb = 1; |
we=1; |
sel = s; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
#2; |
stb=0; |
we=1'bx; |
sel = 4'hx; |
dout = 32'hxxxx_xxxx; |
adr = 32'hxxxx_xxxx; |
end |
|
wr_cnt = wr_cnt + wcount; |
stb=0; |
repeat(delay) @(posedge clk); |
#1; |
|
sel = s; |
we = 0; |
for(n=0;n<rcount-1;n=n+1) |
begin |
adr = a + (n*4); |
stb = 1; |
while(~ack & ~err) @(posedge clk); |
rd_mem[n + rd_cnt] = din; |
//$display("Rd Mem[%0d]: %h", (n + rd_cnt), rd_mem[n + rd_cnt] ); |
#2; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hxxxx_xxxx; |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
we = 0; |
sel = s; |
end |
|
adr = a+(n*4); |
stb = 1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
rd_mem[n + rd_cnt] = din; |
rd_cnt = rd_cnt + rcount; |
//$display("Rd Mem[%0d]: %h", (n + rd_cnt), rd_mem[n + rd_cnt] ); |
#1; |
|
cyc = 0; |
stb = 0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hxxxx_xxxx; |
|
end |
endtask |
|
|
|
|
//////////////////////////////////////////////////////////////////// |
// |
// Read 1 Word Task |
// |
|
task wb_rd1; |
input [31:0] a; |
input [3:0] s; |
output [31:0] d; |
|
begin |
|
@(posedge clk); |
#1; |
adr = a; |
cyc = 1; |
stb = 1; |
we = 0; |
sel = s; |
|
//@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
d = din; |
#1; |
cyc=0; |
stb=0; |
//adr = 32'hxxxx_xxxx; |
//adr = 0; |
adr = 32'hffff_ffff; |
dout = 32'hxxxx_xxxx; |
we = 1'hx; |
sel = 4'hx; |
|
end |
endtask |
|
|
//////////////////////////////////////////////////////////////////// |
// |
// Read 4 Words Task |
// |
|
|
task wb_rd4; |
input [31:0] a; |
input [3:0] s; |
input delay; |
output [31:0] d1; |
output [31:0] d2; |
output [31:0] d3; |
output [31:0] d4; |
|
integer delay; |
begin |
|
@(posedge clk); |
#1; |
cyc = 1; |
we = 0; |
sel = s; |
repeat(delay) @(posedge clk); |
|
adr = a; |
stb = 1; |
while(~ack & ~err) @(posedge clk); |
d1 = din; |
#2; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
we = 0; |
sel = s; |
|
adr = a+4; |
stb = 1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
d2 = din; |
#2; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
we = 0; |
sel = s; |
|
|
adr = a+8; |
stb = 1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
d3 = din; |
#2; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
we = 0; |
sel = s; |
|
adr = a+12; |
stb = 1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
d4 = din; |
#1; |
stb=0; |
cyc=0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hffff_ffff; |
end |
endtask |
|
|
|
task wb_rd_mult; |
input [31:0] a; |
input [3:0] s; |
input delay; |
input count; |
|
integer delay; |
integer count; |
integer n; |
|
begin |
|
@(posedge clk); |
#1; |
cyc = 1; |
we = 0; |
sel = s; |
repeat(delay) @(posedge clk); |
|
for(n=0;n<count-1;n=n+1) |
begin |
adr = a + (n*4); |
stb = 1; |
while(~ack & ~err) @(posedge clk); |
rd_mem[n + rd_cnt] = din; |
#2; |
stb=0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hxxxx_xxxx; |
repeat(delay) |
begin |
@(posedge clk); |
#1; |
end |
we = 0; |
sel = s; |
end |
|
adr = a+(n*4); |
stb = 1; |
@(posedge clk); |
while(~ack & ~err) @(posedge clk); |
rd_mem[n + rd_cnt] = din; |
#1; |
stb=0; |
cyc=0; |
we = 1'hx; |
sel = 4'hx; |
adr = 32'hffff_ffff; |
adr = 32'hxxxx_xxxx; |
|
rd_cnt = rd_cnt + count; |
end |
endtask |
|
endmodule |
/wb_slv_model.v
0,0 → 1,158
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE Slave Model //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/wb_dma/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: wb_slv_model.v,v 1.2 2002-02-01 01:55:44 rudi Exp $ |
// |
// $Date: 2002-02-01 01:55:44 $ |
// $Revision: 1.2 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2001/07/29 08:57:02 rudi |
// |
// |
// 1) Changed Directory Structure |
// 2) Added restart signal (REST) |
// |
// Revision 1.1.1.1 2001/03/19 13:11:29 rudi |
// Initial Release |
// |
// |
// |
|
`include "wb_model_defines.v" |
|
module wb_slv(clk, rst, adr, din, dout, cyc, stb, sel, we, ack, err, rty); |
|
input clk, rst; |
input [31:0] adr, din; |
output [31:0] dout; |
input cyc, stb; |
input [3:0] sel; |
input we; |
output ack, err, rty; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Local Wires |
// |
|
parameter mem_size = 13; |
parameter sz = (1<<mem_size)-1; |
|
reg [31:0] mem[sz:0]; |
wire mem_re, mem_we; |
wire [31:0] tmp; |
reg [31:0] dout, tmp2; |
|
reg err, rty; |
reg [31:0] del_ack; |
reg [5:0] delay; |
|
//////////////////////////////////////////////////////////////////// |
// |
// Memory Logic |
// |
|
initial |
begin |
delay = 0; |
err = 0; |
rty = 0; |
#2; |
$display("\nINFO: WISHBONE MEMORY MODEL INSTANTIATED (%m)"); |
$display(" Memory Size %0d address lines %0d words\n", |
mem_size, sz+1); |
end |
|
assign mem_re = cyc & stb & !we; |
assign mem_we = cyc & stb & we; |
|
assign tmp = mem[adr[mem_size+1:2]]; |
|
always @(sel or tmp or mem_re or ack) |
if(mem_re & ack) |
begin |
dout[31:24] <= #1 sel[3] ? tmp[31:24] : 8'hxx; |
dout[23:16] <= #1 sel[2] ? tmp[23:16] : 8'hxx; |
dout[15:08] <= #1 sel[1] ? tmp[15:08] : 8'hxx; |
dout[07:00] <= #1 sel[0] ? tmp[07:00] : 8'hxx; |
end |
else dout <= #1 32'hzzzz_zzzz; |
|
|
always @(sel or tmp or din) |
begin |
tmp2[31:24] = !sel[3] ? tmp[31:24] : din[31:24]; |
tmp2[23:16] = !sel[2] ? tmp[23:16] : din[23:16]; |
tmp2[15:08] = !sel[1] ? tmp[15:08] : din[15:08]; |
tmp2[07:00] = !sel[0] ? tmp[07:00] : din[07:00]; |
end |
|
always @(posedge clk) |
if(mem_we) mem[adr[mem_size+1:2]] <= #1 tmp2; |
|
always @(posedge clk) |
del_ack = ack ? 0 : {del_ack[30:0], (mem_re | mem_we)}; |
|
assign #3 ack = cyc & ((delay==0) ? (mem_re | mem_we) : del_ack[delay-1]); |
|
task fill_mem; |
input mode; |
|
integer n, mode; |
|
begin |
|
for(n=0;n<(sz+1);n=n+1) |
begin |
case(mode) |
0: mem[n] = { ~n[15:0], n[15:0] }; |
1: mem[n] = $random; |
endcase |
end |
|
end |
endtask |
|
endmodule |
/test_bench_top.v
0,0 → 1,451
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Top Level Test Bench //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/wb_dma/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: test_bench_top.v,v 1.5 2002-02-01 01:55:44 rudi Exp $ |
// |
// $Date: 2002-02-01 01:55:44 $ |
// $Revision: 1.5 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2001/10/19 04:47:31 rudi |
// |
// - Made the core parameterized |
// |
// Revision 1.3 2001/09/07 15:34:36 rudi |
// |
// Changed reset to active high. |
// |
// Revision 1.2 2001/08/15 05:40:29 rudi |
// |
// - Changed IO names to be more clear. |
// - Uniquifyed define names to be core specific. |
// - Added Section 3.10, describing DMA restart. |
// |
// Revision 1.1 2001/07/29 08:57:02 rudi |
// |
// |
// 1) Changed Directory Structure |
// 2) Added restart signal (REST) |
// |
// Revision 1.1.1.1 2001/03/19 13:11:22 rudi |
// Initial Release |
// |
// |
// |
|
`include "wb_dma_defines.v" |
|
`define CH_COUNT 4 |
|
module test; |
|
reg clk; |
reg rst; |
|
// IO Prototypes |
|
wire [31:0] wb0s_data_i; |
wire [31:0] wb0s_data_o; |
wire [31:0] wb0_addr_i; |
wire [3:0] wb0_sel_i; |
wire wb0_we_i; |
wire wb0_cyc_i; |
wire wb0_stb_i; |
wire wb0_ack_o; |
wire wb0_err_o; |
wire wb0_rty_o; |
wire [31:0] wb0m_data_i; |
wire [31:0] wb0m_data_o; |
wire [31:0] wb0_addr_o; |
wire [3:0] wb0_sel_o; |
wire wb0_we_o; |
wire wb0_cyc_o; |
wire wb0_stb_o; |
wire wb0_ack_i; |
wire wb0_err_i; |
wire wb0_rty_i; |
wire [31:0] wb1s_data_i; |
wire [31:0] wb1s_data_o; |
wire [31:0] wb1_addr_i; |
wire [3:0] wb1_sel_i; |
wire wb1_we_i; |
wire wb1_cyc_i; |
wire wb1_stb_i; |
wire wb1_ack_o; |
wire wb1_err_o; |
wire wb1_rty_o; |
wire [31:0] wb1m_data_i; |
wire [31:0] wb1m_data_o; |
wire [31:0] wb1_addr_o; |
wire [3:0] wb1_sel_o; |
wire wb1_we_o; |
wire wb1_cyc_o; |
wire wb1_stb_o; |
wire wb1_ack_i; |
wire wb1_err_i; |
wire wb1_rty_i; |
reg [`CH_COUNT-1:0] req_i; |
wire [`CH_COUNT-1:0] ack_o; |
reg [`CH_COUNT-1:0] nd_i; |
reg [`CH_COUNT-1:0] rest_i; |
wire inta_o; |
wire intb_o; |
|
wire [31:0] wb0_data_o_mast; |
wire [31:0] wb1_data_o_mast; |
wire [31:0] wb0_data_o_slv; |
wire [31:0] wb1_data_o_slv; |
|
// Test Bench Variables |
reg [31:0] wd_cnt; |
integer error_cnt; |
reg ack_cnt_clr; |
reg [31:0] ack_cnt; |
|
// Misc Variables |
|
///////////////////////////////////////////////////////////////////// |
// |
// Defines |
// |
|
|
`define MEM 32'h0002_0000 |
`define REG_BASE 32'hb000_0000 |
|
`define COR 8'h0 |
`define INT_MASKA 8'h4 |
`define INT_MASKB 8'h8 |
`define INT_SRCA 8'hc |
`define INT_SRCB 8'h10 |
|
`define CH0_CSR 8'h20 |
`define CH0_TXSZ 8'h24 |
`define CH0_ADR0 8'h28 |
`define CH0_AM0 8'h2c |
`define CH0_ADR1 8'h30 |
`define CH0_AM1 8'h34 |
`define PTR0 8'h38 |
|
`define CH1_CSR 8'h40 |
`define CH1_TXSZ 8'h44 |
`define CH1_ADR0 8'h48 |
`define CH1_AM0 8'h4c |
`define CH1_ADR1 8'h50 |
`define CH1_AM1 8'h54 |
`define PTR1 8'h58 |
|
`define CH2_CSR 8'h60 |
`define CH2_TXSZ 8'h64 |
`define CH2_ADR0 8'h68 |
`define CH2_AM0 8'h6c |
`define CH2_ADR1 8'h70 |
`define CH2_AM1 8'h74 |
`define PTR2 8'h78 |
|
`define CH3_CSR 8'h80 |
`define CH3_TXSZ 8'h84 |
`define CH3_ADR0 8'h88 |
`define CH3_AM0 8'h8c |
`define CH3_ADR1 8'h90 |
`define CH3_AM1 8'h94 |
`define PTR3 8'h98 |
|
///////////////////////////////////////////////////////////////////// |
// |
// Simulation Initialization and Start up Section |
// |
|
initial |
begin |
$display("\n\n"); |
$display("**********************************************"); |
$display("* WISHBONE DMA/BRIDGE Simulation started ... *"); |
$display("**********************************************"); |
$display("\n"); |
`ifdef WAVES |
$shm_open("waves"); |
$shm_probe("AS",test,"AS"); |
$display("INFO: Signal dump enabled ...\n\n"); |
`endif |
req_i = 0; |
nd_i = 0; |
wd_cnt = 0; |
ack_cnt = 0; |
ack_cnt_clr = 0; |
error_cnt = 0; |
clk = 0; |
rst = 1; |
rest_i = 0; |
|
repeat(10) @(posedge clk); |
rst = 0; |
repeat(10) @(posedge clk); |
|
// HERE IS WHERE THE TEST CASES GO ... |
|
if(1) // Full Regression Run |
begin |
$display(" ......................................................"); |
$display(" : :"); |
$display(" : Long Regression Run ... :"); |
$display(" :....................................................:"); |
pt10_rd; |
pt01_wr; |
pt01_rd; |
pt10_wr; |
sw_dma1(0); |
sw_dma2(0); |
hw_dma1(0); |
hw_dma2(0); |
arb_test1; |
sw_ext_desc1(0); |
hw_dma3(0); |
hw_dma4(0); |
end |
else |
if(1) // Quick Regression Run |
begin |
$display(" ......................................................"); |
$display(" : :"); |
$display(" : Short Regression Run ... :"); |
$display(" :....................................................:"); |
pt10_rd; |
pt01_wr; |
pt01_rd; |
pt10_wr; |
sw_dma1(2); |
sw_dma2(2); |
hw_dma1(1); |
hw_dma2(2); |
hw_dma3(2); |
hw_dma4(2); |
arb_test1; |
sw_ext_desc1(1); |
end |
else |
begin |
|
// |
// TEST DEVELOPMENT AREA |
// |
sw_dma1(3); |
|
//arb_test1; |
|
repeat(100) @(posedge clk); |
|
end |
|
repeat(100) @(posedge clk); |
$finish; |
end |
|
///////////////////////////////////////////////////////////////////// |
// |
// ack counter |
// |
|
always @(posedge clk) |
if(ack_cnt_clr) ack_cnt <= #1 0; |
else |
if(wb0_ack_i | wb1_ack_i) ack_cnt <= #1 ack_cnt + 1; |
|
///////////////////////////////////////////////////////////////////// |
// |
// Watchdog Counter |
// |
|
|
always @(posedge clk) |
if(wb0_cyc_i | wb1_cyc_i | wb0_ack_i | wb1_ack_i) wd_cnt <= #1 0; |
else wd_cnt <= #1 wd_cnt + 1; |
|
always @(wd_cnt) |
if(wd_cnt>5000) |
begin |
$display("\n\n*************************************\n"); |
$display("ERROR: Watch Dog Counter Expired\n"); |
$display("*************************************\n\n\n"); |
$finish; |
end |
|
always #5 clk = ~clk; |
|
///////////////////////////////////////////////////////////////////// |
// |
// WISHBONE DMA IP Core |
// |
|
|
// Module Prototype |
|
wb_dma_top |
#( 4'hb, // register file address |
2'd1, // Number of priorities (4) |
`CH_COUNT, // Number of channels |
4'hf, |
4'hf, |
4'hf, |
4'hf, |
4'hf, |
4'hf, |
4'hf, |
4'hf |
) |
u0( |
.clk_i( clk ), |
.rst_i( rst ), |
.wb0s_data_i( wb0s_data_i ), |
.wb0s_data_o( wb0s_data_o ), |
.wb0_addr_i( wb0_addr_i ), |
.wb0_sel_i( wb0_sel_i ), |
.wb0_we_i( wb0_we_i ), |
.wb0_cyc_i( wb0_cyc_i ), |
.wb0_stb_i( wb0_stb_i ), |
.wb0_ack_o( wb0_ack_o ), |
.wb0_err_o( wb0_err_o ), |
.wb0_rty_o( wb0_rty_o ), |
.wb0m_data_i( wb0m_data_i ), |
.wb0m_data_o( wb0m_data_o ), |
.wb0_addr_o( wb0_addr_o ), |
.wb0_sel_o( wb0_sel_o ), |
.wb0_we_o( wb0_we_o ), |
.wb0_cyc_o( wb0_cyc_o ), |
.wb0_stb_o( wb0_stb_o ), |
.wb0_ack_i( wb0_ack_i ), |
.wb0_err_i( wb0_err_i ), |
.wb0_rty_i( wb0_rty_i ), |
.wb1s_data_i( wb1s_data_i ), |
.wb1s_data_o( wb1s_data_o ), |
.wb1_addr_i( wb1_addr_i ), |
.wb1_sel_i( wb1_sel_i ), |
.wb1_we_i( wb1_we_i ), |
.wb1_cyc_i( wb1_cyc_i ), |
.wb1_stb_i( wb1_stb_i ), |
.wb1_ack_o( wb1_ack_o ), |
.wb1_err_o( wb1_err_o ), |
.wb1_rty_o( wb1_rty_o ), |
.wb1m_data_i( wb1m_data_i ), |
.wb1m_data_o( wb1m_data_o ), |
.wb1_addr_o( wb1_addr_o ), |
.wb1_sel_o( wb1_sel_o ), |
.wb1_we_o( wb1_we_o ), |
.wb1_cyc_o( wb1_cyc_o ), |
.wb1_stb_o( wb1_stb_o ), |
.wb1_ack_i( wb1_ack_i ), |
.wb1_err_i( wb1_err_i ), |
.wb1_rty_i( wb1_rty_i ), |
.dma_req_i( req_i ), |
.dma_ack_o( ack_o ), |
.dma_nd_i( nd_i ), |
.dma_rest_i( rest_i ), |
.inta_o( inta_o ), |
.intb_o( intb_o ) |
); |
|
wb_slv #(14) s0( |
.clk( clk ), |
.rst( ~rst ), |
.adr( wb0_addr_o ), |
.din( wb0s_data_o ), |
.dout( wb0s_data_i ), |
.cyc( wb0_cyc_o ), |
.stb( wb0_stb_o ), |
.sel( wb0_sel_o ), |
.we( wb0_we_o ), |
.ack( wb0_ack_i ), |
.err( wb0_err_i ), |
.rty( wb0_rty_i ) |
); |
|
wb_slv #(14) s1( |
.clk( clk ), |
.rst( ~rst ), |
.adr( wb1_addr_o ), |
.din( wb1s_data_o ), |
.dout( wb1s_data_i ), |
.cyc( wb1_cyc_o ), |
.stb( wb1_stb_o ), |
.sel( wb1_sel_o ), |
.we( wb1_we_o ), |
.ack( wb1_ack_i ), |
.err( wb1_err_i ), |
.rty( wb1_rty_i ) |
); |
|
wb_mast m0( |
.clk( clk ), |
.rst( ~rst ), |
.adr( wb0_addr_i ), |
.din( wb0m_data_o ), |
.dout( wb0m_data_i ), |
.cyc( wb0_cyc_i ), |
.stb( wb0_stb_i ), |
.sel( wb0_sel_i ), |
.we( wb0_we_i ), |
.ack( wb0_ack_o ), |
.err( wb0_err_o ), |
.rty( wb0_rty_o ) |
); |
|
wb_mast m1( |
.clk( clk ), |
.rst( ~rst ), |
.adr( wb1_addr_i ), |
.din( wb1m_data_o ), |
.dout( wb1m_data_i ), |
.cyc( wb1_cyc_i ), |
.stb( wb1_stb_i ), |
.sel( wb1_sel_i ), |
.we( wb1_we_i ), |
.ack( wb1_ack_o ), |
.err( wb1_err_o ), |
.rty( wb1_rty_o ) |
); |
|
`include "tests.v" |
|
endmodule |
|
/wb_model_defines.v
0,0 → 1,63
///////////////////////////////////////////////////////////////////// |
//// //// |
//// WISHBONE Model Definitions //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/wb_dma/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000-2002 Rudolf Usselmann //// |
//// www.asics.ws //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: wb_model_defines.v,v 1.2 2002-02-01 01:55:44 rudi Exp $ |
// |
// $Date: 2002-02-01 01:55:44 $ |
// $Revision: 1.2 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.1 2001/07/29 08:57:02 rudi |
// |
// |
// 1) Changed Directory Structure |
// 2) Added restart signal (REST) |
// |
// Revision 1.1.1.1 2001/03/19 13:12:48 rudi |
// Initial Release |
// |
// |
// |
|
`timescale 1ns / 10ps |
/tests.v
0,0 → 1,2502
///////////////////////////////////////////////////////////////////// |
//// //// |
//// DMA Test Cases //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/wb_dma/ //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer.//// |
//// //// |
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// |
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// |
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// |
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// |
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// |
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// |
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// |
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// |
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// |
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// |
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// |
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// |
//// POSSIBILITY OF SUCH DAMAGE. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
// CVS Log |
// |
// $Id: tests.v,v 1.3 2001-09-07 15:34:36 rudi Exp $ |
// |
// $Date: 2001-09-07 15:34:36 $ |
// $Revision: 1.3 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2001/08/15 05:40:29 rudi |
// |
// - Changed IO names to be more clear. |
// - Uniquifyed define names to be core specific. |
// - Added Section 3.10, describing DMA restart. |
// |
// Revision 1.1 2001/07/29 08:57:02 rudi |
// |
// |
// 1) Changed Directory Structure |
// 2) Added restart signal (REST) |
// |
// Revision 1.1.1.1 2001/03/19 13:12:39 rudi |
// Initial Release |
// |
// |
// |
|
task sw_ext_desc1; |
input quick; |
|
integer quick, tot_sz_max, chunk_sz_max, del_max; |
|
reg [7:0] mode; |
reg [15:0] tot_sz; |
reg [15:0] chunk_sz; |
integer ii, n,del; |
reg [31:0] int_src, d0, d1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** SW DMA No Buffer Ext. Descr LL ... ***"); |
$display("*****************************************************\n"); |
|
rst = 1; |
repeat(10) @(posedge clk); |
rst = 0; |
repeat(10) @(posedge clk); |
|
if(quick) |
begin |
tot_sz_max = 32; |
del_max = 2; |
chunk_sz_max = 4; |
end |
else |
begin |
tot_sz_max = 128; |
del_max = 6; |
chunk_sz_max = 8; |
end |
|
|
mode = 1; |
tot_sz = 64; |
chunk_sz=3; |
del = 0; |
|
for(del=0;del<del_max;del=del+1) |
for(mode=0;mode<4;mode=mode+1) |
for(tot_sz=1;tot_sz<tot_sz_max;tot_sz=tot_sz + 1) |
begin |
|
if(tot_sz>8) tot_sz = tot_sz + 2; |
if(tot_sz>16) tot_sz = tot_sz + 2; |
if(tot_sz>32) tot_sz = tot_sz + 12; |
|
|
for(chunk_sz=0;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
begin |
|
case(mode) |
0: $write("Mode: 0->0, "); |
1: $write("Mode: 0->1, "); |
2: $write("Mode: 1->0, "); |
3: $write("Mode: 1->1, "); |
endcase |
$display("Total Size: %0d, Chunk Size: %0d, Slave Delay: %0d", |
tot_sz, chunk_sz, del); |
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
s0.delay = del; |
s1.delay = del; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
s0.mem[0] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[1] = 32'h0000_0100; |
s0.mem[2] = 32'h0000_0400; |
s0.mem[3] = 32'h0000_0010; |
|
s0.mem[4] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[5] = 32'h0000_0100 + (tot_sz * 4); |
s0.mem[6] = 32'h0000_0400 + (tot_sz * 4); |
s0.mem[7] = 32'h0000_0000; |
|
|
s0.mem[8] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[9] = 32'h0000_0800; |
s0.mem[10] = 32'h0000_0c00; |
s0.mem[11] = 32'h0000_0030; |
|
s0.mem[12] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[13] = 32'h0000_0800 + (tot_sz * 4); |
s0.mem[14] = 32'h0000_0c00 + (tot_sz * 4); |
s0.mem[15] = 32'h0000_0000; |
|
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'hffff_ffff); |
|
m0.wb_wr1(`REG_BASE + `PTR0, 4'hf, 32'h0000_0020); |
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, 12'h0}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_0080); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_4000); |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{15'h0002, 3'b000, 1'b0, 6'h1, 4'b0011, 2'b00, 1'b1}); |
|
|
m0.wb_wr1(`REG_BASE + `PTR1, 4'hf, 32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH1_TXSZ,4'hf, {chunk_sz, 12'h0}); |
m0.wb_wr1(`REG_BASE + `CH1_ADR0,4'hf,32'h0000_0080); |
m0.wb_wr1(`REG_BASE + `CH1_ADR1,4'hf,32'h0000_4000); |
|
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, |
{15'h0002, 3'b000, 1'b0, 6'h1, 4'b0011, 2'b00, 1'b1}); |
|
|
for(ii=0;ii<2;ii=ii+1) |
begin |
repeat(5) @(posedge clk); |
while(!inta_o) @(posedge clk); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
if(int_src[0]) |
begin |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[9]>>2) + n ]; |
else d0=s0.mem[(s0.mem[9]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[10]>>2) + n ]; |
else d1=s0.mem[(s0.mem[10]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d1); |
d0 = {24'h0064_089, 1'b1, mode[1:0], 1'b0}; |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
|
if(int_src[1]) |
begin |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[1]>>2) + n ]; |
else d0=s0.mem[(s0.mem[1]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[2]>>2) + n ]; |
else d1=s0.mem[(s0.mem[2]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
m0.wb_rd1(`REG_BASE + `CH1_CSR, 4'hf, d1); |
d0 = {24'h0064_089, 1'b1, mode[1:0], 1'b0}; |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
end |
|
if(ack_cnt != ((tot_sz*4)+(4*2))*2 ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*4)+(4*2)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
repeat(5) @(posedge clk); |
|
end |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
|
|
endtask |
|
|
|
task arb_test1; |
|
reg [7:0] mode; |
reg [15:0] tot_sz; |
reg [15:0] chunk_sz0; |
reg [15:0] chunk_sz1; |
reg [15:0] chunk_sz2; |
reg [15:0] chunk_sz3; |
integer a,n,ptr; |
reg [31:0] d0,d1; |
reg [7:0] pri, order, finish; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** SW DMA No Buffer 4 ch pri ... ***"); |
$display("*****************************************************\n"); |
|
mode = 0; |
tot_sz = 32; |
chunk_sz0=4; |
chunk_sz1=4; |
chunk_sz2=4; |
chunk_sz3=4; |
a=0; |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, 32'h0); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, d0); |
|
for(mode=0;mode<4;mode=mode+1) |
for(a=0;a<17;a=a+1) |
begin |
|
chunk_sz0=4; |
chunk_sz1=4; |
chunk_sz2=4; |
chunk_sz3=4; |
|
s0.delay = 0; |
s1.delay = 0; |
|
case(a) // ch3 ch2 ch1 ch0 |
0: |
begin |
pri = 8'b10_10_10_10; // All equal 0,1,2,3 |
order = {2'd0, 2'd1, 2'd2, 2'd3}; |
end |
|
// One channel with High Priority |
// The other depend oon the ARB state |
1: |
begin |
pri = 8'b00_00_00_10; // 3,1,0,2 |
order = {2'b0, 2'd3, 2'd1, 2'd2}; |
end |
2: |
begin |
pri = 8'b00_00_10_00; // 2,3,0,1 |
order = {2'd1, 2'd0, 2'd2, 2'd3}; |
end |
3: |
begin |
pri = 8'b00_10_00_00; // 1,0,2,3 |
order = {2'd2, 2'd0, 2'd1, 2'd3}; |
end |
4: |
begin |
pri = 8'b10_00_00_00; // 0,3,1,2 |
order = {2'd3, 2'd0, 2'd1, 2'd2}; |
end |
|
// Specific order for all Channels |
5: |
begin |
pri = 8'b10_00_01_11; // 3,0,2,1 |
order = {2'd0, 2'd3, 2'd1, 2'd2}; |
end |
|
6: |
begin |
pri = 8'b00_10_11_01; // 2,1,3,0 |
order = {2'd1, 2'd2, 2'd0, 2'd3}; |
end |
|
7: |
begin |
pri = 8'b00_11_01_10; // 1,3,2,0 |
order = {2'd2, 2'd0, 2'd1, 2'd3}; |
end |
|
8: |
begin |
pri = 8'b00_01_10_11; // 3,2,1,0 |
order = {2'd0, 2'd1, 2'd2, 2'd3}; |
end |
|
// One channel with High Priority |
// The other depend oon the ARB state |
// Chunk Size varies |
// First channel small chunkc size |
9: |
begin |
pri = 8'b00_00_00_10; // 3,1,0,2 |
order = {2'd0, 2'd1, 2'd2, 2'd3}; |
chunk_sz3=1; |
end |
10: |
begin |
pri = 8'b00_00_10_00; // 2,0,1,3 |
order = {2'd1, 2'd0, 2'd3, 2'd2}; |
chunk_sz2=1; |
end |
11: |
begin |
pri = 8'b00_10_00_00; // 1,0,2,3 |
order = {2'd2, 2'd0, 2'd3, 2'd1}; |
chunk_sz1=1; |
end |
12: |
begin |
pri = 8'b10_00_00_00; // 0,2,3,1 |
order = {2'd3, 2'd1, 2'd2, 2'd0}; |
chunk_sz0=1; |
end |
|
// First channel large chunkc size |
13: |
begin |
pri = 8'b00_00_00_10; // 3,0,2,1 |
order = {2'd0, 2'd3, 2'd1, 2'd2}; |
chunk_sz3=8; |
end |
14: |
begin |
pri = 8'b00_00_10_00; // 2,0,3,1 |
order = {2'd1, 2'd2, 2'd0, 2'd3}; |
chunk_sz2=8; |
end |
15: |
begin |
pri = 8'b00_10_00_00; // 1,0,3,2 |
order = {2'd2, 2'd1, 2'd0, 2'd3}; |
chunk_sz1=8; |
end |
16: |
begin |
pri = 8'b10_00_00_00; // 0,2,3,1 |
order = {2'd3, 2'd0, 2'd1, 2'd2}; |
chunk_sz0=8; |
end |
|
endcase |
|
case(mode) |
0: $write("Mode: 0->0, "); |
1: $write("Mode: 0->1, "); |
2: $write("Mode: 1->0, "); |
3: $write("Mode: 1->1, "); |
endcase |
$display("a: %0d", a); |
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{17'h00000, pri[1:0], 6'h0, 4'b0011, mode[1:0], 1'b0}); |
|
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, |
{17'h00000, pri[3:2], 6'h0, 4'b0011, mode[1:0], 1'b0}); |
|
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, |
{17'h00000, pri[5:4], 6'h0, 4'b0011, mode[1:0], 1'b0}); |
|
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, |
{17'h00000, pri[7:6], 6'h0, 4'b0011, mode[1:0], 1'b0}); |
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'hffff_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz0, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_4000); |
|
m0.wb_wr1(`REG_BASE + `CH1_TXSZ,4'hf, {chunk_sz1, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH1_ADR0,4'hf,32'h0000_0080); |
m0.wb_wr1(`REG_BASE + `CH1_ADR1,4'hf,32'h0000_4080); |
|
m0.wb_wr1(`REG_BASE + `CH2_TXSZ,4'hf, {chunk_sz2, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH2_ADR0,4'hf,32'h0000_0100); |
m0.wb_wr1(`REG_BASE + `CH2_ADR1,4'hf,32'h0000_4100); |
|
m0.wb_wr1(`REG_BASE + `CH3_TXSZ,4'hf, {chunk_sz3, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH3_ADR0,4'hf,32'h0000_0180); |
m0.wb_wr1(`REG_BASE + `CH3_ADR1,4'hf,32'h0000_4180); |
|
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{12'h000, 3'b010, 1'b0, 1'b0, pri[1:0], 6'h0, 4'b0011, mode[1:0], 1'b1}); |
|
//{15'h0002, 3'b000, 1'b0, 6'h1, 4'b0011, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, |
{12'h000, 3'b010, 1'b0, 1'b0, pri[3:2], 6'h0, 4'b0011, mode[1:0], 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, |
{12'h000, 3'b010, 1'b0, 1'b0, pri[5:4], 6'h0, 4'b0011, mode[1:0], 1'b1}); |
|
|
|
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 1'b0, pri[7:6], 6'h0, 4'b0011, mode[1:0], 1'b1}); |
|
repeat(1) @(posedge clk); |
|
// Wait for interrupt, Check completion order |
|
ptr=0; |
finish = 8'hxx; |
|
while(ptr!=4) |
begin |
while(!inta_o) @(posedge clk); |
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, d0); |
|
if(d0[0]) d0[1:0] = 0; |
else |
if(d0[1]) d0[1:0] = 1; |
else |
if(d0[2]) d0[1:0] = 2; |
else |
if(d0[3]) d0[1:0] = 3; |
|
case(ptr) |
0: finish[7:6] = d0[1:0]; |
1: finish[5:4] = d0[1:0]; |
2: finish[3:2] = d0[1:0]; |
3: finish[1:0] = d0[1:0]; |
endcase |
|
case(d0[1:0]) |
0: m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d0); |
1: m0.wb_rd1(`REG_BASE + `CH1_CSR, 4'hf, d0); |
2: m0.wb_rd1(`REG_BASE + `CH2_CSR, 4'hf, d0); |
3: m0.wb_rd1(`REG_BASE + `CH3_CSR, 4'hf, d0); |
endcase |
|
ptr=ptr+1; |
repeat(4) @(posedge clk); |
end |
|
|
if(finish !== order) |
begin |
$display("ERROR: Completion Order[%0d] Mismatch: Expected: %b, Got: %b (%0t)", |
a, order, finish, $time); |
error_cnt = error_cnt + 1; |
end |
|
|
for(n=0;n<tot_sz*4;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[ n ]; |
else d0=s0.mem[ n ]; |
if(mode[0]) d1=s1.mem[32'h0000_1000 + n ]; |
else d1=s0.mem[32'h0000_1000 + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
if(ack_cnt != ((tot_sz*4*2)) ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*4)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
|
repeat(5) @(posedge clk); |
|
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
|
endtask |
|
|
|
|
|
|
task hw_dma1; |
input quick; |
|
integer quick, chunk_sz_max, del_max; |
|
reg [7:0] mode; |
reg [15:0] chunk_sz, tot_sz; |
integer n,m,k,rep,del; |
reg [31:0] d0,d1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** HW DMA No Buffer ... ***"); |
$display("*****************************************************\n"); |
|
if(quick) |
begin |
tot_sz = 32; |
chunk_sz_max= 4; |
del_max = 3; |
end |
else |
begin |
tot_sz = 64; |
chunk_sz_max= 8; |
del_max = 5; |
end |
|
mode = 1; |
chunk_sz=4; |
del = 8; |
for(mode=0;mode<4;mode=mode+1) |
for(chunk_sz=0;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
for(del=0;del<del_max;del=del+1) |
begin |
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_4000); |
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{25'h0000000, 4'b1111, mode[1:0], 1'b1}); |
|
$write("Delay: %0d ",del); |
case(mode) |
0: $display("Mode: 0->0, chunk_size: %0d", chunk_sz); |
1: $display("Mode: 0->1, chunk_size: %0d", chunk_sz); |
2: $display("Mode: 1->0, chunk_size: %0d", chunk_sz); |
3: $display("Mode: 1->1, chunk_size: %0d", chunk_sz); |
endcase |
|
for(rep=0;rep<4;rep=rep+1) |
begin |
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
if(del==4) del = 10; |
|
s0.delay = del; |
s1.delay = del; |
|
if(chunk_sz==0) k = 1; |
else |
begin |
k = tot_sz/chunk_sz; |
if((k*chunk_sz) != tot_sz) k = k + 1; |
end |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
fork |
begin |
|
for(m=0;m < k;m=m+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[0] = 1; |
while(!ack_o[0]) @(posedge clk); |
#1; |
req_i[0] = 0; |
end |
|
end |
|
begin |
repeat(1) @(posedge clk); |
while(!u0.dma_done_all) @(posedge clk); |
|
/* |
repeat(5) @(posedge clk); |
while(!inta_o) @(posedge clk); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, d1); |
d0 = 32'h0000_0002; |
if( d1 !== d0 ) |
begin |
$display("ERROR: INT_SRC Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
|
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d1); |
d0 = {24'h0000_081, 1'b1, mode[1:0], 1'b0}; |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
*/ |
|
|
for(n=0;n<tot_sz;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[ n ]; |
else d0=s0.mem[ n ]; |
if(mode[0]) d1=s1.mem[32'h0000_1000 + n ]; |
else d1=s0.mem[32'h0000_1000 + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
end |
|
join |
|
if(ack_cnt != ((tot_sz*2)) ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*2)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
end |
end |
|
s0.delay = 0; |
s1.delay = 0; |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
|
endtask |
|
|
|
|
task hw_dma2; |
input quick; |
|
integer quick, tot_sz_max, chunk_sz_max, del_max; |
|
reg [7:0] mode; |
reg [15:0] chunk_sz, tot_sz; |
integer i, n,m0, m1, m2, m3, k,rep,del; |
reg [31:0] int_src, d0,d1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** HW DMA No Buffer Ext Descr. 4 Channels ... ***"); |
$display("*****************************************************\n"); |
|
case(quick) |
default: |
begin |
del_max = 6; |
tot_sz_max = 200; |
chunk_sz_max = 8; |
end |
1: |
begin |
del_max = 4; |
tot_sz_max = 128; |
chunk_sz_max = 4; |
end |
2: |
begin |
del_max = 3; |
tot_sz_max = 32; |
chunk_sz_max = 4; |
end |
endcase |
|
mode = 0; |
tot_sz = 128; |
chunk_sz=2; |
del = 0; |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, 32'h0); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
for(tot_sz=1;tot_sz<tot_sz_max;tot_sz=tot_sz+1) |
begin |
|
if(tot_sz>4) tot_sz = tot_sz + 4; |
if(tot_sz>16) tot_sz = tot_sz + 12; |
if(tot_sz>64) tot_sz = tot_sz + 48; |
|
for(del=0;del<del_max;del=del+1) |
for(mode=0;mode<4;mode=mode+1) |
for(chunk_sz=0;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
begin |
s0.delay = del; |
s1.delay = del; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
s0.mem[0] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[1] = 32'h0000_0100; |
s0.mem[2] = 32'h0000_0900; |
s0.mem[3] = 32'h0000_0010; |
|
s0.mem[4] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[5] = 32'h0000_0100 + (tot_sz * 4); |
s0.mem[6] = 32'h0000_0900 + (tot_sz * 4); |
s0.mem[7] = 32'h0000_0000; |
|
s0.mem[8] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[9] = 32'h0000_1100; |
s0.mem[10] = 32'h0000_1900; |
s0.mem[11] = 32'h0000_0030; |
|
s0.mem[12] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[13] = 32'h0000_1100 + (tot_sz * 4); |
s0.mem[14] = 32'h0000_1900 + (tot_sz * 4); |
s0.mem[15] = 32'h0000_0000; |
|
s0.mem[16] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[17] = 32'h0000_2100; |
s0.mem[18] = 32'h0000_2900; |
s0.mem[19] = 32'h0000_0050; |
|
s0.mem[20] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[21] = 32'h0000_2100 + (tot_sz * 4); |
s0.mem[22] = 32'h0000_2900 + (tot_sz * 4); |
s0.mem[23] = 32'h0000_0000; |
|
s0.mem[24] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[25] = 32'h0000_3100; |
s0.mem[26] = 32'h0000_3900; |
s0.mem[27] = 32'h0000_0070; |
|
s0.mem[28] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[29] = 32'h0000_3100 + (tot_sz * 4); |
s0.mem[30] = 32'h0000_3900 + (tot_sz * 4); |
s0.mem[31] = 32'h0000_0000; |
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'hffff_ffff); |
|
m0.wb_wr1(`REG_BASE + `PTR0, 4'hf, 32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b0, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR1, 4'hf, 32'h0000_0020); |
m0.wb_wr1(`REG_BASE + `CH1_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH1_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH1_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b0, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR2, 4'hf, 32'h0000_0040); |
m0.wb_wr1(`REG_BASE + `CH2_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH2_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH2_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b0, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR3, 4'hf, 32'h0000_0060); |
m0.wb_wr1(`REG_BASE + `CH3_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH3_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH3_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b0, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
|
$write("Total Size: %0d, Delay: %0d ",tot_sz, del); |
case(mode) |
0: $display("Mode: 0->0, chunk_size: %0d", chunk_sz); |
1: $display("Mode: 0->1, chunk_size: %0d", chunk_sz); |
2: $display("Mode: 1->0, chunk_size: %0d", chunk_sz); |
3: $display("Mode: 1->1, chunk_size: %0d", chunk_sz); |
endcase |
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
if(chunk_sz==0) k = 1; |
else |
begin |
k = tot_sz/chunk_sz; |
if((k*chunk_sz) != tot_sz) k = k + 1; |
end |
|
k = k * 2; |
|
fork |
begin |
repeat(5) @(posedge clk); |
for(m0=0;m0 < k;m0=m0+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[0] = 1; |
while(!ack_o[0]) @(posedge clk); |
#1; |
req_i[0] = 0; |
end |
end |
|
begin |
repeat(5) @(posedge clk); |
for(m1=0;m1 < k;m1=m1+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[1] = 1; |
while(!ack_o[1]) @(posedge clk); |
#1; |
req_i[1] = 0; |
end |
end |
|
begin |
repeat(5) @(posedge clk); |
for(m2=0;m2 < k;m2=m2+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[2] = 1; |
while(!ack_o[2]) @(posedge clk); |
#1; |
req_i[2] = 0; |
end |
end |
|
begin |
repeat(5) @(posedge clk); |
for(m3=0;m3 < k;m3=m3+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[3] = 1; |
while(!ack_o[3]) @(posedge clk); |
#1; |
req_i[3] = 0; |
end |
end |
|
for(i=0;i<4;i=i) |
begin |
repeat(5) @(posedge clk); |
while(!inta_o) @(posedge clk); |
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
if(int_src[0]) |
begin |
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[1]>>2) + n ]; |
else d0=s0.mem[(s0.mem[1]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[2]>>2) + n ]; |
else d1=s0.mem[(s0.mem[2]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
if(int_src[1]) |
begin |
m0.wb_rd1(`REG_BASE + `CH1_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[9]>>2) + n ]; |
else d0=s0.mem[(s0.mem[9]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[10]>>2) + n ]; |
else d1=s0.mem[(s0.mem[10]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
if(int_src[2]) |
begin |
m0.wb_rd1(`REG_BASE + `CH2_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[17]>>2) + n ]; |
else d0=s0.mem[(s0.mem[17]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[18]>>2) + n ]; |
else d1=s0.mem[(s0.mem[18]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH2: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
if(int_src[3]) |
begin |
m0.wb_rd1(`REG_BASE + `CH3_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[25]>>2) + n ]; |
else d0=s0.mem[(s0.mem[25]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[26]>>2) + n ]; |
else d1=s0.mem[(s0.mem[26]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH3: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
end |
|
join |
|
|
if(ack_cnt != ((tot_sz*2*4*2)+(4*4*2)) ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*2*4*2)+(4*4*2)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
repeat(5) @(posedge clk); |
|
end |
end |
|
s0.delay = 0; |
s1.delay = 0; |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
|
endtask |
|
|
|
|
|
|
task hw_dma3; |
input quick; |
|
integer quick, tot_sz_max, chunk_sz_max, del_max; |
|
reg [7:0] mode; |
reg [15:0] chunk_sz, tot_sz; |
integer odd, i, iz, n,m0, m1, m2, m3, k, k1, rep,del; |
reg [31:0] int_src, d0,d1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** HW DMA Ext Descr. 4 Channels ND Test ... ***"); |
$display("*****************************************************\n"); |
|
case(quick) |
default: |
begin |
del_max = 6; |
chunk_sz_max = 8; |
end |
1: |
begin |
del_max = 4; |
chunk_sz_max = 4; |
end |
2: |
begin |
del_max = 3; |
chunk_sz_max = 4; |
end |
endcase |
|
mode = 0; |
tot_sz = 64; |
chunk_sz=4; |
del = 0; |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, 32'h0); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
|
for(del=0;del<del_max;del=del+1) |
for(mode=0;mode<4;mode=mode+1) |
for(chunk_sz=1;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
begin |
repeat(50) @(posedge clk); |
s0.delay = del; |
s1.delay = del; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
// Channel 0 Descriptors |
s0.mem[0] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[1] = 32'h0000_0400; |
s0.mem[2] = 32'h0000_0800; |
s0.mem[3] = 32'h0000_0010; |
|
s0.mem[4] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[5] = 32'h0000_0400 + (tot_sz * 4); |
s0.mem[6] = 32'h0000_0800 + (tot_sz * 4); |
s0.mem[7] = 32'h0000_0020; |
|
s0.mem[8] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[9] = 32'h0000_0400 + (tot_sz * 4); |
s0.mem[10] = 32'h0000_0800 + (tot_sz * 4); |
s0.mem[11] = 32'h0000_0030; |
|
s0.mem[12] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[13] = 32'h0000_0400 + (tot_sz * 4); |
s0.mem[14] = 32'h0000_0800 + (tot_sz * 4); |
s0.mem[15] = 32'h0000_0000; |
|
// Channel 1 Descriptors |
s0.mem[16] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[17] = 32'h0000_0c00; |
s0.mem[18] = 32'h0000_1000; |
s0.mem[19] = 32'h0000_0050; |
|
s0.mem[20] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[21] = 32'h0000_0c00 + (tot_sz * 4); |
s0.mem[22] = 32'h0000_1000 + (tot_sz * 4); |
s0.mem[23] = 32'h0000_0060; |
|
s0.mem[24] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[25] = 32'h0000_0c00 + (tot_sz * 4); |
s0.mem[26] = 32'h0000_1000 + (tot_sz * 4); |
s0.mem[27] = 32'h0000_0070; |
|
s0.mem[28] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[29] = 32'h0000_0c00 + (tot_sz * 4); |
s0.mem[30] = 32'h0000_1000 + (tot_sz * 4); |
s0.mem[31] = 32'h0000_0000; |
|
// Channel 2 Descriptors |
s0.mem[32] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[33] = 32'h0000_1400; |
s0.mem[34] = 32'h0000_1800; |
s0.mem[35] = 32'h0000_0090; |
|
s0.mem[36] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[37] = 32'h0000_1400 + (tot_sz * 4); |
s0.mem[38] = 32'h0000_1800 + (tot_sz * 4); |
s0.mem[39] = 32'h0000_00a0; |
|
s0.mem[40] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[41] = 32'h0000_1400 + (tot_sz * 4); |
s0.mem[42] = 32'h0000_1800 + (tot_sz * 4); |
s0.mem[43] = 32'h0000_00b0; |
|
s0.mem[44] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[45] = 32'h0000_1400 + (tot_sz * 4); |
s0.mem[46] = 32'h0000_1800 + (tot_sz * 4); |
s0.mem[47] = 32'h0000_0000; |
|
// Channel 3 Descriptors |
s0.mem[48] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[49] = 32'h0000_1c00; |
s0.mem[50] = 32'h0000_2000; |
s0.mem[51] = 32'h0000_00d0; |
|
s0.mem[52] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[53] = 32'h0000_1c00 + (tot_sz * 4); |
s0.mem[54] = 32'h0000_2000 + (tot_sz * 4); |
s0.mem[55] = 32'h0000_00e0; |
|
s0.mem[56] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[57] = 32'h0000_1c00 + (tot_sz * 4); |
s0.mem[58] = 32'h0000_2000 + (tot_sz * 4); |
s0.mem[59] = 32'h0000_00f0; |
|
s0.mem[60] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz*4; |
s0.mem[61] = 32'h0000_1c00 + (tot_sz * 4); |
s0.mem[62] = 32'h0000_2000 + (tot_sz * 4); |
s0.mem[63] = 32'h0000_0000; |
|
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'hffff_ffff); |
|
m0.wb_wr1(`REG_BASE + `PTR0, 4'hf, 32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 9'h003, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR1, 4'hf, 32'h0000_0040); |
m0.wb_wr1(`REG_BASE + `CH1_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH1_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH1_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 9'h003, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR2, 4'hf, 32'h0000_0080); |
m0.wb_wr1(`REG_BASE + `CH2_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH2_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH2_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 9'h003, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR3, 4'hf, 32'h0000_00c0); |
m0.wb_wr1(`REG_BASE + `CH3_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH3_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH3_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 9'h003, 4'b0111, 2'b00, 1'b1}); |
|
|
$write("Total Size: %0d, Delay: %0d ",tot_sz, del); |
case(mode) |
0: $display("Mode: 0->0, chunk_size: %0d", chunk_sz); |
1: $display("Mode: 0->1, chunk_size: %0d", chunk_sz); |
2: $display("Mode: 1->0, chunk_size: %0d", chunk_sz); |
3: $display("Mode: 1->1, chunk_size: %0d", chunk_sz); |
endcase |
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
if(chunk_sz==0) k = 1; |
else |
begin |
k = tot_sz/chunk_sz; |
if((k*chunk_sz) != tot_sz) k = k + 1; |
if((k*chunk_sz) != tot_sz) odd = 1; |
else odd = 0; |
end |
|
if(chunk_sz==0) k1 = 4; |
else |
begin |
k1 = tot_sz/chunk_sz; |
if((k1*chunk_sz) != tot_sz) k1 = k1 + 1; |
k1 = k1 * 4; |
end |
|
k1 = k * 4; |
iz = k; |
|
fork |
begin |
repeat(5) @(posedge clk); |
for(m0=0;m0 < k1+1;m0=m0+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
|
if(m0==iz) nd_i[0] = 1; |
else |
if(m0==(iz*2)) nd_i[0] = 1; |
else |
if(m0==(iz*3)) nd_i[0] = 1; |
else |
if(m0==(iz*4)) nd_i[0] = 1; |
else req_i[0] = 1; |
|
if(nd_i[0]==1) |
begin |
@(posedge clk); |
#1; |
nd_i[0] = 0; |
repeat(1) @(posedge clk); |
#1; |
req_i[0] = 1; |
end |
|
while(!ack_o[0] & (m0 < k1)) @(posedge clk); |
#1; |
req_i[0] = 0; |
nd_i[0] = 0; |
end |
end |
|
begin |
repeat(5) @(posedge clk); |
for(m1=0;m1 < k1;m1=m1+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
if(m1==k-1) nd_i[1] = 1; |
if(m1==(k*2)-1) nd_i[1] = 1; |
if(m1==(k*3)-1) nd_i[1] = 1; |
if(m1==(k*4)-1) nd_i[1] = 1; |
req_i[1] = 1; |
while(!ack_o[1]) @(posedge clk); |
#1; |
req_i[1] = 0; |
nd_i[1] = 0; |
end |
end |
|
begin |
repeat(5) @(posedge clk); |
for(m2=0;m2 < k1+1;m2=m2+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
|
if(m2==k) nd_i[2] = 1; |
else |
if(m2==(k*2)) nd_i[2] = 1; |
else |
if(m2==(k*3)) nd_i[2] = 1; |
else |
if(m2==(k*4)) nd_i[2] = 1; |
else req_i[2] = 1; |
|
if(nd_i[2]==1) |
begin |
@(posedge clk); |
#1; |
nd_i[2] = 0; |
repeat(1) @(posedge clk); |
#1; |
req_i[2] = 1; |
end |
|
while(!ack_o[2] & (m2 < k1)) @(posedge clk); |
#1; |
req_i[2] = 0; |
nd_i[2] = 0; |
end |
end |
|
|
begin |
repeat(5) @(posedge clk); |
for(m3=0;m3 < k1;m3=m3+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
if(m3==k-1) nd_i[3] = 1; |
if(m3==(k*2)-1) nd_i[3] = 1; |
if(m3==(k*3)-1) nd_i[3] = 1; |
if(m3==(k*4)-1) nd_i[3] = 1; |
req_i[3] = 1; |
while(!ack_o[3]) @(posedge clk); |
#1; |
req_i[3] = 0; |
nd_i[3] = 0; |
end |
end |
|
|
for(i=0;i<4;i=i) |
begin |
repeat(5) @(posedge clk); |
while(!inta_o) @(posedge clk); |
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
if(int_src[0]) |
begin |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[1]>>2) + n ]; |
else d0=s0.mem[(s0.mem[1]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[2]>>2) + n ]; |
else d1=s0.mem[(s0.mem[2]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
repeat(1) @(posedge clk); |
d1 = {28'h0064_09b, 1'b1, mode[1:0], 1'b0}; |
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d0); |
repeat(1) @(posedge clk); |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0: CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d1, d0, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
if(int_src[1]) |
begin |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[17]>>2) + n ]; |
else d0=s0.mem[(s0.mem[17]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[18]>>2) + n ]; |
else d1=s0.mem[(s0.mem[18]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
repeat(1) @(posedge clk); |
d1 = {28'h0064_09b, 1'b1, mode[1:0], 1'b0}; |
m0.wb_rd1(`REG_BASE + `CH1_CSR, 4'hf, d0); |
repeat(1) @(posedge clk); |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1: CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d1, d0, $time); |
error_cnt = error_cnt + 1; |
end |
repeat(1) @(posedge clk); |
case(chunk_sz) |
default: d1 = 32'h0000_00c0; |
3: d1 = 32'h0000_00be; |
5: d1 = 32'h0000_00bf; |
6: d1 = 32'h0000_00be; |
7: d1 = 32'h0000_00ba; |
endcase |
d0 = s0.mem[16]; |
repeat(1) @(posedge clk); |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1: DESC_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d1, d0, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
if(int_src[2]) |
begin |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[33]>>2) + n ]; |
else d0=s0.mem[(s0.mem[33]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[34]>>2) + n ]; |
else d1=s0.mem[(s0.mem[34]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH2: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
repeat(1) @(posedge clk); |
d1 = {28'h0064_09b, 1'b1, mode[1:0], 1'b0}; |
m0.wb_rd1(`REG_BASE + `CH2_CSR, 4'hf, d0); |
repeat(1) @(posedge clk); |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH2: CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d1, d0, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
if(int_src[3]) |
begin |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[49]>>2) + n ]; |
else d0=s0.mem[(s0.mem[49]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[50]>>2) + n ]; |
else d1=s0.mem[(s0.mem[50]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH3: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
repeat(1) @(posedge clk); |
d1 = {28'h0064_09b, 1'b1, mode[1:0], 1'b0}; |
m0.wb_rd1(`REG_BASE + `CH3_CSR, 4'hf, d0); |
repeat(1) @(posedge clk); |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH3: CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d1, d0, $time); |
error_cnt = error_cnt + 1; |
end |
repeat(1) @(posedge clk); |
case(chunk_sz) |
default: d1 = 32'h0000_00c0; |
3: d1 = 32'h0000_00be; |
5: d1 = 32'h0000_00bf; |
6: d1 = 32'h0000_00be; |
7: d1 = 32'h0000_00ba; |
endcase |
d0 = s0.mem[48]; |
repeat(1) @(posedge clk); |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH3: DESC_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d1, d0, $time); |
error_cnt = error_cnt + 1; |
end |
|
end |
|
end |
join |
|
// CH0: 528 Acks |
// CH1: 532 Acks |
// CH2: 528 Acks |
// CH3: 532 Acks |
|
case(chunk_sz) |
default: k = 2120; |
3: k = 2184; |
5: k = 2152; |
6: k = 2184; |
7: k = 2312; |
endcase |
|
if(ack_cnt != k ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
k, ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
repeat(5) @(posedge clk); |
|
end |
|
s0.delay = 0; |
s1.delay = 0; |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
|
endtask |
|
|
|
|
|
task sw_dma1; |
input quick; |
|
integer quick, tot_sz_max, chunk_sz_max; |
reg [7:0] mode; |
reg [15:0] chunk_sz, tot_sz; |
integer n; |
reg [31:0] d0,d1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** SW DMA No Buffer (tx & chunk size test) ... ***"); |
$display("*****************************************************\n"); |
|
case(quick) |
default: |
begin |
tot_sz_max = 1024; |
chunk_sz_max = 256; |
end |
1: |
begin |
tot_sz_max = 128; |
chunk_sz_max = 64; |
end |
2: |
begin |
tot_sz_max = 32; |
chunk_sz_max = 4; |
end |
endcase |
|
mode = 1; |
tot_sz = 2048; |
tot_sz = 16; |
chunk_sz=4; |
|
for(mode=0;mode<4;mode=mode+1) |
for(tot_sz=1;tot_sz<tot_sz_max;tot_sz=tot_sz+1) |
begin |
|
if(tot_sz>64) tot_sz=tot_sz+4; |
if(tot_sz>128) tot_sz=tot_sz+12; |
case(mode) |
0: $display("Mode: 0->0, tot_size: %0d", tot_sz); |
1: $display("Mode: 0->1, tot_size: %0d", tot_sz); |
2: $display("Mode: 1->0, tot_size: %0d", tot_sz); |
3: $display("Mode: 1->1, tot_size: %0d", tot_sz); |
endcase |
|
for(chunk_sz=0;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
begin |
|
if(chunk_sz==17) chunk_sz=128; |
if(chunk_sz==129) chunk_sz=255; |
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'hffff_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_4000); |
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 11'h000, 2'b11, mode[1:0], 1'b1}); |
|
repeat(5) @(posedge clk); |
while(!inta_o) @(posedge clk); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, d1); |
d0 = 32'h0000_0001; |
if( d1 !== d0 ) |
begin |
$display("ERROR: INT_SRCA Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
|
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d1); |
d0 = {24'h0064_081, 1'b1, mode[1:0], 1'b0}; |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
|
for(n=0;n<tot_sz;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[ n ]; |
else d0=s0.mem[ n ]; |
if(mode[0]) d1=s1.mem[32'h0000_1000 + n ]; |
else d1=s0.mem[32'h0000_1000 + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
if(ack_cnt != ((tot_sz*2)) ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*2)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
end |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
endtask |
|
|
|
task sw_dma2; |
input quick; |
|
integer quick, tot_sz_max, chunk_sz_max, max_del; |
|
reg [7:0] mode; |
reg [15:0] chunk_sz, tot_sz; |
integer n; |
reg [31:0] d0,d1; |
integer del0, del1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** SW DMA No Buffer (slave delay slide) ... ***"); |
$display("*****************************************************\n"); |
|
case(quick) |
default: |
begin |
max_del = 6; |
tot_sz_max = 256; |
chunk_sz_max = 16; |
end |
1: |
begin |
max_del = 4; |
tot_sz_max = 128; |
chunk_sz_max = 8; |
end |
2: |
begin |
max_del = 2; |
tot_sz_max = 32; |
chunk_sz_max = 4; |
end |
endcase |
|
mode = 0; |
tot_sz = 2048; |
tot_sz = 16; |
chunk_sz=4; |
|
for(del0=0;del0<max_del;del0=del0+1) |
for(del1=0;del1<max_del;del1=del1+1) |
for(mode=0;mode<4;mode=mode+1) |
for(tot_sz=1;tot_sz<tot_sz_max;tot_sz=tot_sz+4) |
begin |
|
if(del0==5) del0=8; |
if(del1==5) del1=8; |
|
if(tot_sz>128) tot_sz=tot_sz+4; |
|
$write("Slv 0 delay: %0d, Slv 1 Delay: %0d - ",del0, del1); |
case(mode) |
0: $display("Mode: 0->0, tot_size: %0d", tot_sz); |
1: $display("Mode: 0->1, tot_size: %0d", tot_sz); |
2: $display("Mode: 1->0, tot_size: %0d", tot_sz); |
3: $display("Mode: 1->1, tot_size: %0d", tot_sz); |
endcase |
|
for(chunk_sz=0;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
|
begin |
|
if(quick & (chunk_sz > 4)) chunk_sz = chunk_sz + 1; |
|
s0.delay = del0; |
s1.delay = del1; |
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
m0.wb_wr1(`REG_BASE + `INT_MASKB,4'hf,32'hffff_ffff); |
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, tot_sz}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_4000); |
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
{12'h0000, 3'b010, 1'b0, 11'h000, 2'b11, mode[1:0], 1'b1}); |
|
repeat(5) @(posedge clk); |
while(!intb_o) @(posedge clk); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCB, 4'hf, d1); |
d0 = 32'h0000_0001; |
if( d1 !== d0 ) |
begin |
$display("ERROR: INT_SRC Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
|
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d1); |
d0 = {24'h0064_081, 1'b1, mode[1:0], 1'b0}; |
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0_CSR Mismatch: Expected: %x, Got: %x (%0t)", |
d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
|
for(n=0;n<tot_sz;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[ n ]; |
else d0=s0.mem[ n ]; |
if(mode[0]) d1=s1.mem[32'h0000_1000 + n ]; |
else d1=s0.mem[32'h0000_1000 + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
|
|
if(ack_cnt != ((tot_sz*2)) ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*2)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
|
|
end |
end |
|
s0.delay = 0; |
s1.delay = 0; |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
endtask |
|
|
|
task pt10_rd; |
|
// Misc Variables |
reg [31:0] d0,d1,d2,d3; |
integer d,n; |
|
begin |
$display("\n"); |
$display("*****************************************************"); |
$display("*** Running Path Through 1->0 Read Test .... ***"); |
$display("*****************************************************\n"); |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
d=0; |
n=16; |
|
for(d=0;d<16;d=d+1) |
begin |
$display("INFO: PT10 RD4, delay %0d",d); |
for(n=0;n<512;n=n+4) |
begin |
m0.wb_rd4(n<<2,4'hf,d,d0,d1,d2,d3); |
|
if( (s1.mem[n+0] !== d0) | (s1.mem[n+1] !== d1) | |
(s1.mem[n+2] !== d2) | (s1.mem[n+3] !== d3) ) |
begin |
$display("ERROR: Memory Read Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s1.mem[n+0], d0); |
$display("D1: Expected: %x, Got %x", s1.mem[n+1], d1); |
$display("D2: Expected: %x, Got %x", s1.mem[n+2], d2); |
$display("D3: Expected: %x, Got %x", s1.mem[n+3], d3); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
|
$display("\nINFO: PT10 RD1"); |
for(n=0;n<512;n=n+1) |
begin |
m0.wb_rd1(n<<2,4'hf,d0); |
|
if( s1.mem[n] !== d0 ) |
begin |
$display("ERROR: Memory Read Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s1.mem[n], d0); |
error_cnt = error_cnt + 1; |
end |
end |
|
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n"); |
end |
endtask |
|
|
task pt01_rd; |
|
// Misc Variables |
reg [31:0] d0,d1,d2,d3; |
integer d,n; |
|
begin |
$display("\n"); |
$display("*****************************************************"); |
$display("*** Running Path Through 0->1 Read Test .... ***"); |
$display("*****************************************************\n"); |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
d=1; |
n=0; |
for(d=0;d<16;d=d+1) |
begin |
$display("INFO: PT01 RD4, delay %0d",d); |
for(n=0;n<512;n=n+4) |
begin |
m1.wb_rd4(n<<2,4'hf,d,d0,d1,d2,d3); |
@(posedge clk); |
|
if( (s0.mem[n+0] !== d0) | (s0.mem[n+1] !== d1) | |
(s0.mem[n+2] !== d2) | (s0.mem[n+3] !== d3) ) |
begin |
$display("ERROR: Memory Read Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s0.mem[n+0], d0); |
$display("D1: Expected: %x, Got %x", s0.mem[n+1], d1); |
$display("D2: Expected: %x, Got %x", s0.mem[n+2], d2); |
$display("D3: Expected: %x, Got %x", s0.mem[n+3], d3); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
$display("\nINFO: PT01 RD1"); |
for(n=0;n<512;n=n+1) |
begin |
m1.wb_rd1(n<<2,4'hf,d0); |
|
if( s0.mem[n+0] !== d0 ) |
begin |
$display("ERROR: Memory Read Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s0.mem[n+0], d0); |
error_cnt = error_cnt + 1; |
end |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n"); |
end |
endtask |
|
|
|
|
task pt10_wr; |
|
// Misc Variables |
reg [31:0] d0,d1,d2,d3; |
integer d,n; |
|
begin |
|
$display("\n"); |
$display("*****************************************************"); |
$display("*** Running Path Through 1->0 Write Test .... ***"); |
$display("*****************************************************\n"); |
|
|
s0.fill_mem(1); |
s1.fill_mem(1); |
d=1; |
n=0; |
for(d=0;d<16;d=d+1) |
begin |
$display("INFO: PT10 WR4, delay %0d",d); |
for(n=0;n<512;n=n+4) |
begin |
|
d0 = $random; |
d1 = $random; |
d2 = $random; |
d3 = $random; |
m0.wb_wr4(n<<2,4'hf,d,d0,d1,d2,d3); |
@(posedge clk); |
|
if( (s1.mem[n+0] !== d0) | (s1.mem[n+1] !== d1) | |
(s1.mem[n+2] !== d2) | (s1.mem[n+3] !== d3) ) |
begin |
$display("ERROR: Memory Write Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s1.mem[n+0], d0); |
$display("D1: Expected: %x, Got %x", s1.mem[n+1], d1); |
$display("D2: Expected: %x, Got %x", s1.mem[n+2], d2); |
$display("D3: Expected: %x, Got %x", s1.mem[n+3], d3); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
$display("\nINFO: PT10 WR1"); |
for(n=0;n<512;n=n+1) |
begin |
d0 = $random; |
m0.wb_wr1(n<<2,4'hf,d0); |
@(posedge clk); |
|
if( s1.mem[n+0] !== d0 ) |
begin |
$display("ERROR: Memory Write Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s1.mem[n+0], d0); |
error_cnt = error_cnt + 1; |
end |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n"); |
end |
endtask |
|
|
|
task pt01_wr; |
|
// Misc Variables |
reg [31:0] d0,d1,d2,d3; |
integer d,n; |
|
begin |
|
$display("\n"); |
$display("*****************************************************"); |
$display("*** Running Path Through 0->1 Write Test .... ***"); |
$display("*****************************************************\n"); |
|
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
d=1; |
n=0; |
for(d=0;d<16;d=d+1) |
begin |
$display("INFO: PT01 WR4, delay %0d",d); |
for(n=0;n<512;n=n+4) |
begin |
|
d0 = $random; |
d1 = $random; |
d2 = $random; |
d3 = $random; |
m1.wb_wr4(n<<2,4'hf,d,d0,d1,d2,d3); |
@(posedge clk); |
|
if( (s0.mem[n+0] !== d0) | (s0.mem[n+1] !== d1) | |
(s0.mem[n+2] !== d2) | (s0.mem[n+3] !== d3) ) |
begin |
$display("ERROR: Memory Write Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s0.mem[n+0], d0); |
$display("D1: Expected: %x, Got %x", s0.mem[n+1], d1); |
$display("D2: Expected: %x, Got %x", s0.mem[n+2], d2); |
$display("D3: Expected: %x, Got %x", s0.mem[n+3], d3); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
$display("\nINFO: PT01 WR1"); |
for(n=0;n<512;n=n+1) |
begin |
d0 = $random; |
m1.wb_wr1(n<<2,4'hf,d0); |
@(posedge clk); |
|
if( s0.mem[n+0] !== d0 ) |
begin |
$display("ERROR: Memory Write Data (%0d) Mismatch: (%0t)",n,$time); |
$display("D0: Expected: %x, Got %x", s0.mem[n+0], d0); |
error_cnt = error_cnt + 1; |
end |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n"); |
end |
endtask |
|
|
|
|
|
|
|
task show_errors; |
|
begin |
|
$display("\n"); |
$display(" +--------------------+"); |
$display(" | Total ERRORS: %0d |", error_cnt); |
$display(" +--------------------+"); |
|
end |
endtask |
|
|
|
task hw_dma4; |
input quick; |
|
integer quick, tot_sz_max, chunk_sz_max, del_max; |
|
reg [7:0] mode; |
reg [15:0] chunk_sz, tot_sz; |
integer i, n,m0, m1, m2, m3, k,rep,del; |
reg [31:0] int_src, d0,d1; |
reg do_rest; |
integer rest_del; |
integer rest_del_t; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** HW DMA No Buffer Ext Descr. REST Test ... ***"); |
$display("*****************************************************\n"); |
|
case(quick) |
default: |
begin |
del_max = 6; |
tot_sz_max = 200; |
chunk_sz_max = 8; |
end |
1: |
begin |
del_max = 4; |
tot_sz_max = 128; |
chunk_sz_max = 4; |
end |
2: |
begin |
del_max = 3; |
tot_sz_max = 32; |
chunk_sz_max = 4; |
end |
endcase |
|
mode = 1; |
tot_sz = 32; |
chunk_sz=7; |
del = 0; |
do_rest = 1; |
rest_del = 7; |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, 32'h0); |
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, 32'h0); |
|
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
for(tot_sz=1;tot_sz<tot_sz_max;tot_sz=tot_sz+1) |
begin |
|
if(tot_sz>4) tot_sz = tot_sz + 4; |
if(tot_sz>16) tot_sz = tot_sz + 12; |
if(tot_sz>64) tot_sz = tot_sz + 48; |
|
for(del=0;del<del_max;del=del+1) |
//for(mode=0;mode<4;mode=mode+1) |
//for(chunk_sz=0;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
|
for(rest_del=0;rest_del<16;rest_del=rest_del + 1) |
for(chunk_sz=1;chunk_sz<chunk_sz_max;chunk_sz=chunk_sz+1) |
begin |
do_rest = 1; |
s0.delay = del; |
s1.delay = del; |
|
s0.fill_mem(1); |
s1.fill_mem(1); |
|
s0.mem[0] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[1] = 32'h0000_0100; |
s0.mem[2] = 32'h0000_0900; |
s0.mem[3] = 32'h0000_0010; |
|
s0.mem[4] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[5] = 32'h0000_0100 + (tot_sz * 4); |
s0.mem[6] = 32'h0000_0900 + (tot_sz * 4); |
s0.mem[7] = 32'h0000_0000; |
|
s0.mem[8] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[9] = 32'h0000_1100; |
s0.mem[10] = 32'h0000_1900; |
s0.mem[11] = 32'h0000_0030; |
|
s0.mem[12] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[13] = 32'h0000_1100 + (tot_sz * 4); |
s0.mem[14] = 32'h0000_1900 + (tot_sz * 4); |
s0.mem[15] = 32'h0000_0000; |
|
s0.mem[16] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[17] = 32'h0000_2100; |
s0.mem[18] = 32'h0000_2900; |
s0.mem[19] = 32'h0000_0050; |
|
s0.mem[20] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[21] = 32'h0000_2100 + (tot_sz * 4); |
s0.mem[22] = 32'h0000_2900 + (tot_sz * 4); |
s0.mem[23] = 32'h0000_0000; |
|
s0.mem[24] = (32'h000c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[25] = 32'h0000_3100; |
s0.mem[26] = 32'h0000_3900; |
s0.mem[27] = 32'h0000_0070; |
|
s0.mem[28] = (32'h001c_0000 | (mode[1:0]<<16)) + tot_sz; |
s0.mem[29] = 32'h0000_3100 + (tot_sz * 4); |
s0.mem[30] = 32'h0000_3900 + (tot_sz * 4); |
s0.mem[31] = 32'h0000_0000; |
|
m0.wb_wr1(`REG_BASE + `INT_MASKA,4'hf,32'hffff_ffff); |
|
m0.wb_wr1(`REG_BASE + `PTR0, 4'hf, 32'h0000_0000); |
m0.wb_wr1(`REG_BASE + `CH0_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH0_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH0_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH0_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b1, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR1, 4'hf, 32'h0000_0020); |
m0.wb_wr1(`REG_BASE + `CH1_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH1_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH1_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH1_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b1, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR2, 4'hf, 32'h0000_0040); |
m0.wb_wr1(`REG_BASE + `CH2_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH2_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH2_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH2_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b1, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
m0.wb_wr1(`REG_BASE + `PTR3, 4'hf, 32'h0000_0060); |
m0.wb_wr1(`REG_BASE + `CH3_TXSZ,4'hf, {chunk_sz, 16'h0fff}); |
m0.wb_wr1(`REG_BASE + `CH3_ADR0,4'hf,32'h0000_ffff); |
m0.wb_wr1(`REG_BASE + `CH3_ADR1,4'hf,32'h0000_ffff); |
|
m0.wb_wr1(`REG_BASE + `CH3_CSR,4'hf, |
//{25'h0000001, 4'b0111, 2'b00, 1'b1}); |
{12'h0000, 3'b010, 1'b1, 9'h001, 4'b0111, 2'b00, 1'b1}); |
|
|
ack_cnt_clr = 1; |
@(posedge clk); |
ack_cnt_clr = 0; |
|
if(chunk_sz==0) k = 1; |
else |
begin |
k = tot_sz/chunk_sz; |
if((k*chunk_sz) != tot_sz) k = k + 1; |
end |
|
//$display("rest_del: %0d, k: %0d", rest_del, k); |
|
if(rest_del >= k) rest_del_t = k - 1; |
else rest_del_t = rest_del; |
|
k = k * 2; |
|
|
$write("Total Size: %0d, Delay: %0d REST_del: %0d ",tot_sz, del, rest_del_t); |
case(mode) |
0: $display("Mode: 0->0, chunk_size: %0d", chunk_sz); |
1: $display("Mode: 0->1, chunk_size: %0d", chunk_sz); |
2: $display("Mode: 1->0, chunk_size: %0d", chunk_sz); |
3: $display("Mode: 1->1, chunk_size: %0d", chunk_sz); |
endcase |
|
|
|
//$display("k=%0d",k); |
|
fork |
begin // Hardware Handshake Channel 0 |
repeat(5) @(posedge clk); |
for(m0=0;m0 < k;m0=m0+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[0] = 1; |
while(!ack_o[0]) @(posedge clk); |
#1; |
req_i[0] = 0; |
end |
end |
|
begin // Hardware Handshake Channel 1 |
repeat(5) @(posedge clk); |
for(m1=0;m1 < (k + rest_del_t + 1);m1=m1+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[1] = 1; |
while(!ack_o[1]) @(posedge clk); |
#1; |
req_i[1] = 0; |
//$display("m1=%0d",m1); |
if( (do_rest==1) & (m1==rest_del_t) ) |
//if( do_rest==1 ) |
begin |
//$display("Asserting Restart ..."); |
@(posedge clk); |
#1; |
rest_i[1] = 1; |
@(posedge clk); |
#1; |
rest_i[1] = 0; |
do_rest = 0; |
@(posedge clk); |
@(posedge clk); |
end |
|
end |
end |
|
begin // Hardware Handshake Channel 2 |
repeat(5) @(posedge clk); |
for(m2=0;m2 < k;m2=m2+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[2] = 1; |
while(!ack_o[2]) @(posedge clk); |
#1; |
req_i[2] = 0; |
end |
end |
|
begin // Hardware Handshake Channel 3 |
repeat(5) @(posedge clk); |
for(m3=0;m3 < k;m3=m3+1) |
begin |
repeat(del) @(posedge clk); |
#1; |
req_i[3] = 1; |
while(!ack_o[3]) @(posedge clk); |
#1; |
req_i[3] = 0; |
end |
end |
|
for(i=0;i<4;i=i) |
begin |
repeat(5) @(posedge clk); |
while(!inta_o) @(posedge clk); |
m0.wb_rd1(`REG_BASE + `INT_SRCA, 4'hf, int_src); |
|
if(int_src[0]) |
begin |
m0.wb_rd1(`REG_BASE + `CH0_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[1]>>2) + n ]; |
else d0=s0.mem[(s0.mem[1]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[2]>>2) + n ]; |
else d1=s0.mem[(s0.mem[2]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH0: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
if(int_src[1]) |
begin |
m0.wb_rd1(`REG_BASE + `CH1_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[9]>>2) + n ]; |
else d0=s0.mem[(s0.mem[9]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[10]>>2) + n ]; |
else d1=s0.mem[(s0.mem[10]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH1: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
if(int_src[2]) |
begin |
m0.wb_rd1(`REG_BASE + `CH2_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[17]>>2) + n ]; |
else d0=s0.mem[(s0.mem[17]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[18]>>2) + n ]; |
else d1=s0.mem[(s0.mem[18]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH2: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
if(int_src[3]) |
begin |
m0.wb_rd1(`REG_BASE + `CH3_CSR, 4'hf, d0); |
i=i+1; |
for(n=0;n<tot_sz*2;n=n+1) |
begin |
if(mode[1]) d0=s1.mem[(s0.mem[25]>>2) + n ]; |
else d0=s0.mem[(s0.mem[25]>>2) + n ]; |
if(mode[0]) d1=s1.mem[(s0.mem[26]>>2) + n ]; |
else d1=s0.mem[(s0.mem[26]>>2) + n ]; |
|
if( d1 !== d0 ) |
begin |
$display("ERROR: CH3: Data[%0d] Mismatch: Expected: %x, Got: %x (%0t)", |
n, d0, d1, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
end |
|
join |
|
|
/* |
if(ack_cnt != ((tot_sz*2*4*2)+(4*4*2)) ) |
begin |
$display("ERROR: ACK count Mismatch: Expected: %0d, Got: %0d (%0t)", |
((tot_sz*2*4*2)+(4*4*2)), ack_cnt, $time); |
error_cnt = error_cnt + 1; |
end |
*/ |
|
repeat(5) @(posedge clk); |
|
end |
end |
|
s0.delay = 0; |
s1.delay = 0; |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
|
endtask |
|
|
|
|