URL
https://opencores.org/ocsvn/usb1_funct/usb1_funct/trunk
Subversion Repositories usb1_funct
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/trunk/bench/verilog/test_bench_top.v
0,0 → 1,475
//////////////////////////////////////////////////////////////////// |
//// //// |
//// USB 1.1 Top Level Test Bench DEMO //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/usb1_funct///// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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. //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
`include "usb1_defines.v" |
|
module test; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Local IOs and Vars |
// |
|
reg clk; |
reg clk2; |
reg rst; |
|
integer error_cnt; |
reg [7:0] txmem[0:2048]; |
reg [7:0] buffer1[0:16384]; |
reg [7:0] buffer0[0:16384]; |
integer buffer1_last; |
reg [31:0] wd_cnt; |
reg setup_pid; |
integer pack_sz, pack_sz_max; |
wire tx_dp, tx_dn, tx_oe; |
wire rx_d, rx_dp, rx_dn; |
reg tb_tx_valid; |
wire tb_tx_ready; |
reg [7:0] tb_txdata; |
wire tb_rx_valid, tb_rx_active, tb_rx_error; |
wire [7:0] tb_rxdata; |
|
wire [7:0] ep1_us_din; |
wire ep1_us_re, ep1_us_empty; |
wire [7:0] ep3_us_din; |
wire ep3_us_re, ep3_us_empty; |
wire [7:0] ep5_us_din; |
wire ep5_us_re, ep4_us_empty; |
|
wire [7:0] ep2_us_dout; |
wire ep2_us_we, ep2_us_full; |
wire [7:0] ep4_us_dout; |
wire ep4_us_we, ep4_us_full; |
|
|
reg [7:0] ep1_f_din; |
reg ep1_f_we; |
wire ep1_f_full; |
wire [7:0] ep2_f_dout; |
reg ep2_f_re; |
wire ep2_f_empty; |
reg [7:0] ep3_f_din; |
reg ep3_f_we; |
wire ep3_f_full; |
wire [7:0] ep4_f_dout; |
reg ep4_f_re; |
wire ep4_f_empty; |
reg [7:0] ep5_f_din; |
reg ep5_f_we; |
wire ep5_f_full; |
|
reg [7:0] ep0_max_size; |
reg [7:0] ep1_max_size; |
reg [7:0] ep2_max_size; |
reg [7:0] ep3_max_size; |
reg [7:0] ep4_max_size; |
reg [7:0] ep5_max_size; |
reg [7:0] ep6_max_size; |
reg [7:0] ep7_max_size; |
|
wire rx_dp1; |
wire rx_dn1; |
wire tx_dp1; |
wire tx_dn1; |
wire rx_dp2; |
wire rx_dn2; |
wire tx_dp2; |
wire tx_dn2; |
|
reg usb_reset; |
integer n; |
reg [31:0] data; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Test Definitions |
// |
|
/////////////////////////////////////////////////////////////////// |
// |
// Initial Startup and Simulation Begin |
// |
|
|
initial |
begin |
usb_reset = 0; |
$timeformat (-9, 1, " ns", 12); |
|
`ifdef WAVES |
$shm_open("waves"); |
$shm_probe("AS",test,"AS"); |
$display("INFO: Signal dump enabled ...\n\n"); |
`endif |
tb_tx_valid = 0; |
error_cnt = 0; |
wd_cnt = 0; |
clk = 0; |
clk2 = 0; |
rst = 0; |
ep1_f_we=0; |
ep2_f_re=0; |
ep3_f_we=0; |
ep4_f_re=0; |
ep5_f_we=0; |
|
repeat(10) @(posedge clk); |
rst = 1; |
repeat(50) @(posedge clk); |
usb_reset = 1; |
repeat(300) @(posedge clk); |
usb_reset = 0; |
repeat(10) @(posedge clk); |
|
if(1) |
begin |
setup1; |
in0; |
out0; |
end |
else |
if(1) |
begin |
setup1; |
end |
|
repeat(500) @(posedge clk); |
$finish; |
end |
|
/////////////////////////////////////////////////////////////////// |
// |
// Watchdog Timer |
// |
always @(posedge clk) |
if(tx_dp1 | tx_dp2) 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 |
|
/////////////////////////////////////////////////////////////////// |
// |
// Clock generation |
// |
|
always #10.42 clk = ~clk; |
always #10.42 clk2 = ~clk2; |
|
/////////////////////////////////////////////////////////////////// |
// |
// Module Instantiations |
// |
|
usb_phy tb_phy(.clk( clk ), |
.rst( rst ), |
|
.phy_tx_mode( 1'b1 ), |
.usb_rst( ), |
|
.rxd( rx_dp1 ), |
.rxdp( rx_dp1 ), |
.rxdn( rx_dn1 ), |
|
.txdp( tx_dp1 ), |
.txdn( tx_dn1 ), |
.txoe( ), |
|
.DataIn_o( tb_rxdata ), |
.RxValid_o( tb_rx_valid ), |
.RxActive_o( tb_rx_active ), |
.RxError_o( tb_rx_error ), |
|
.DataOut_i( tb_txdata ), |
.TxValid_i( tb_tx_valid ), |
.TxReady_o( tb_tx_ready ), |
.LineState_o( ) |
); |
|
parameter LD = 40; |
|
assign #(LD) rx_dp1 = !usb_reset & tx_dp2; |
assign #(LD) rx_dn1 = !usb_reset & tx_dn2; |
|
assign #(LD) rx_dp2 = !usb_reset & tx_dp1; |
assign #(LD) rx_dn2 = !usb_reset & tx_dn1; |
|
usb1_core u0( .clk_i( clk2 ), |
.rst_i( rst ), |
|
// USB Misc |
.phy_tx_mode( 1'b1 ), |
.usb_rst( ), |
// USB Status |
.usb_busy( ), |
.ep_sel( ), |
|
// Interrupts |
.dropped_frame( ), |
.misaligned_frame( ), |
.crc16_err( ), |
|
// Vendor Features |
.v_set_int( ), |
.v_set_feature( ), |
.wValue( ), |
.wIndex( ), |
.vendor_data( ), |
|
// USB PHY Interface |
.tx_dp( tx_dp2 ), |
.tx_dn( tx_dn2 ), |
.tx_oe( ), |
|
.rx_d( rx_dp2 ), |
.rx_dp( rx_dp2 ), |
.rx_dn( rx_dn2 ), |
|
// End point 1 configuration |
.ep1_cfg( `ISO | `IN | 14'd0256 ), |
// End point 1 'OUT' FIFO i/f |
.ep1_dout( ), |
.ep1_we( ), |
.ep1_full( 1'b0 ), |
// End point 1 'IN' FIFO i/f |
.ep1_din( ep1_us_din ), |
.ep1_re( ep1_us_re ), |
.ep1_empty( ep1_us_empty ), |
.ep1_bf_en( 1'b0 ), |
.ep1_bf_size( 7'h0 ), |
|
// End point 2 configuration |
.ep2_cfg( `ISO | `OUT | 14'd0256 ), |
// End point 2 'OUT' FIFO i/f |
.ep2_dout( ep2_us_dout ), |
.ep2_we( ep2_us_we ), |
.ep2_full( ep2_us_full ), |
// End point 2 'IN' FIFO i/f |
.ep2_din( 8'h0 ), |
.ep2_re( ), |
.ep2_empty( 1'b0 ), |
.ep2_bf_en( 1'b0 ), |
.ep2_bf_size( 7'h0 ), |
|
// End point 3 configuration |
.ep3_cfg( `BULK | `IN | 14'd064 ), |
// End point 3 'OUT' FIFO i/f |
.ep3_dout( ), |
.ep3_we( ), |
.ep3_full( 1'b0 ), |
// End point 3 'IN' FIFO i/f |
.ep3_din( ep3_us_din ), |
.ep3_re( ep3_us_re ), |
.ep3_empty( ep3_us_empty ), |
.ep3_bf_en( 1'b0 ), |
.ep3_bf_size( 7'h0 ), |
|
// End point 4 configuration |
.ep4_cfg( `BULK | `OUT | 14'd064 ), |
// End point 4 'OUT' FIFO i/f |
.ep4_dout( ep4_us_dout ), |
.ep4_we( ep4_us_we ), |
.ep4_full( ep4_us_full ), |
// End point 4 'IN' FIFO i/f |
.ep4_din( 8'h0 ), |
.ep4_re( ), |
.ep4_empty( 1'b0 ), |
.ep4_bf_en( 1'b0 ), |
.ep4_bf_size( 7'h0 ), |
|
// End point 5 configuration |
.ep5_cfg( `INT | `IN | 14'd064 ), |
// End point 5 'OUT' FIFO i/f |
.ep5_dout( ), |
.ep5_we( ), |
.ep5_full( 1'b0 ), |
// End point 5 'IN' FIFO i/f |
.ep5_din( ep5_us_din ), |
.ep5_re( ep5_us_re ), |
.ep5_empty( ep5_us_empty ), |
.ep5_bf_en( 1'b0 ), |
.ep5_bf_size( 7'h0 ), |
|
// End point 6 configuration |
.ep6_cfg( 14'h00 ), |
// End point 6 'OUT' FIFO i/f |
.ep6_dout( ), |
.ep6_we( ), |
.ep6_full( 1'b0 ), |
// End point 6 'IN' FIFO i/f |
.ep6_din( 8'h0 ), |
.ep6_re( ), |
.ep6_empty( 1'b0 ), |
.ep6_bf_en( 1'b0 ), |
.ep6_bf_size( 7'h0 ), |
|
// End point 7 configuration |
.ep7_cfg( 14'h00 ), |
// End point 7 'OUT' FIFO i/f |
.ep7_dout( ), |
.ep7_we( ), |
.ep7_full( 1'b0 ), |
// End point 7 'IN' FIFO i/f |
.ep7_din( 8'h0 ), |
.ep7_re( ), |
.ep7_empty( 1'b0 ), |
.ep7_bf_en( 1'b0 ), |
.ep7_bf_size( 7'h0 ) |
); |
|
// EP 1 FIFO |
generic_fifo_sc_a #(8,9,0) |
f0( |
.clk( clk2 ), |
.rst( rst ), |
.clr( 1'b0 ), |
.din( ep1_f_din ), |
.we( ep1_f_we ), |
.dout( ep1_us_din ), |
.re( ep1_us_re ), |
.full( ), |
.empty( ), |
.full_r( ep1_f_full ), |
.empty_r( ep1_us_empty ), |
.full_n( ), |
.empty_n( ), |
.full_n_r( ), |
.empty_n_r( ), |
.level( ) |
); |
|
// EP 2 FIFO |
generic_fifo_sc_a #(8,9,0) |
f1( |
.clk( clk2 ), |
.rst( rst ), |
.clr( 1'b0 ), |
.din( ep2_us_dout ), |
.we( ep2_us_we ), |
.dout( ep2_f_dout ), |
.re( ep2_f_re ), |
.full( ), |
.empty( ), |
.full_r( ep2_us_full ), |
.empty_r( ep2_f_empty ), |
.full_n( ), |
.empty_n( ), |
.full_n_r( ), |
.empty_n_r( ), |
.level( ) |
); |
|
// EP 3 FIFO |
generic_fifo_sc_a #(8,9,0) |
f2( |
.clk( clk2 ), |
.rst( rst ), |
.clr( 1'b0 ), |
.din( ep3_f_din ), |
.we( ep3_f_we ), |
.dout( ep3_us_din ), |
.re( ep3_us_re ), |
.full( ), |
.empty( ), |
.full_r( ep3_f_full ), |
.empty_r( ep3_us_empty ), |
.full_n( ), |
.empty_n( ), |
.full_n_r( ), |
.empty_n_r( ), |
.level( ) |
); |
|
// EP 4 FIFO |
generic_fifo_sc_a #(8,9,0) |
f3( |
.clk( clk2 ), |
.rst( rst ), |
.clr( 1'b0 ), |
.din( ep4_us_dout ), |
.we( ep4_us_we ), |
.dout( ep4_f_dout ), |
.re( ep4_f_re ), |
.full( ), |
.empty( ), |
.full_r( ep4_us_full ), |
.empty_r( ep4_f_empty ), |
.full_n( ), |
.empty_n( ), |
.full_n_r( ), |
.empty_n_r( ), |
.level( ) |
); |
|
// EP 5 FIFO |
generic_fifo_sc_a #(8,6,0) |
f4( |
.clk( clk2 ), |
.rst( rst ), |
.clr( 1'b0 ), |
.din( ep5_f_din ), |
.we( ep5_f_we ), |
.dout( ep5_us_din ), |
.re( ep5_us_re ), |
.full( ), |
.empty( ), |
.full_r( ep5_f_full ), |
.empty_r( ep5_us_empty ), |
.full_n( ), |
.empty_n( ), |
.full_n_r( ), |
.empty_n_r( ), |
.level( ) |
); |
|
/////////////////////////////////////////////////////////////////// |
// |
// Test and test lib Includes |
// |
`include "tests_lib.v" |
`include "tests.v" |
|
endmodule |
|
/trunk/bench/verilog/tests.v
0,0 → 1,630
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Test Case Collection //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/usb1_funct///// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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: tests.v,v 1.1 2002-09-25 06:10:10 rudi Exp $ |
// |
// $Date: 2002-09-25 06:10:10 $ |
// $Revision: 1.1 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// |
// |
// |
// |
// |
// |
|
|
task send_setup; |
input [7:0] fa; |
input [7:0] req_type; |
input [7:0] request; |
input [15:0] wValue; |
input [15:0] wIndex; |
input [15:0] wLength; |
|
integer len; |
begin |
|
buffer1[0] = req_type; |
buffer1[1] = request; |
buffer1[3] = wValue[15:8]; |
buffer1[2] = wValue[7:0]; |
buffer1[5] = wIndex[15:8]; |
buffer1[4] = wIndex[7:0]; |
buffer1[7] = wLength[15:8]; |
buffer1[6] = wLength[7:0]; |
|
buffer1_last = 0; |
send_token( fa, // Function Address |
0, // Logical Endpoint Number |
`USBF_T_PID_SETUP // PID |
); |
|
repeat(1) @(posedge clk); |
|
send_data(`USBF_T_PID_DATA0, 8, 1); |
|
// Wait for ACK |
utmi_recv_pack(len); |
|
if(8'hd2 !== txmem[0]) |
begin |
$display("ERROR: SETUP: ACK mismatch. Expected: %h, Got: %h (%t)", |
8'hd2, txmem[0], $time); |
error_cnt = error_cnt + 1; |
end |
|
if(len !== 1) |
begin |
$display("ERROR: SETUP: Length mismatch. Expected: %h, Got: %h (%t)", |
8'h1, len, $time); |
error_cnt = error_cnt + 1; |
end |
|
repeat(1) @(posedge clk); |
setup_pid = 1; |
repeat(1) @(posedge clk); |
end |
|
endtask |
|
|
|
task data_in; |
input [7:0] fa; |
input [7:0] pl_size; |
|
integer rlen; |
reg [3:0] pid, expect_pid; |
begin |
|
buffer1_last = 0; |
repeat(5) @(posedge clk); |
send_token( fa, // Function Address |
0, // Logical Endpoint Number |
`USBF_T_PID_IN // PID |
); |
|
recv_packet(pid,rlen); |
if(setup_pid) expect_pid = 4'hb; // DATA 1 |
else expect_pid = 4'h3; // DATA 0 |
|
if(pid !== expect_pid) |
begin |
$display("ERROR: Data IN PID mismatch. Expected: %h, Got: %h (%t)", |
expect_pid, pid, $time); |
error_cnt = error_cnt + 1; |
end |
|
setup_pid = ~setup_pid; |
if(rlen != pl_size) |
begin |
$display("ERROR: Data IN Size mismatch. Expected: %d, Got: %d (%t)", |
pl_size, rlen, $time); |
error_cnt = error_cnt + 1; |
end |
|
for(n=0;n<rlen;n=n+1) |
$display("RCV Data[%0d]: %h",n,buffer1[n]); |
|
repeat(5) @(posedge clk); |
send_token( fa, // Function Address |
0, // Logical Endpoint Number |
`USBF_T_PID_ACK // PID |
); |
|
repeat(5) @(posedge clk); |
|
end |
endtask |
|
|
|
task data_out; |
input [7:0] fa; |
input [7:0] pl_size; |
|
integer len; |
|
begin |
send_token( fa, // Function Address |
0, // Logical Endpoint Number |
`USBF_T_PID_OUT // PID |
); |
|
repeat(1) @(posedge clk); |
|
if(setup_pid==0) send_data(`USBF_T_PID_DATA0, pl_size, 1); |
else send_data(`USBF_T_PID_DATA1, pl_size, 1); |
|
setup_pid = ~setup_pid; |
|
// Wait for ACK |
utmi_recv_pack(len); |
|
if(8'hd2 !== txmem[0]) |
begin |
$display("ERROR: ACK mismatch. Expected: %h, Got: %h (%t)", |
8'hd2, txmem[0], $time); |
error_cnt = error_cnt + 1; |
end |
|
if(len !== 1) |
begin |
$display("ERROR: SETUP: Length mismatch. Expected: %h, Got: %h (%t)", |
8'h1, len, $time); |
error_cnt = error_cnt + 1; |
end |
repeat(5) @(posedge clk); |
|
end |
endtask |
|
|
parameter GET_STATUS = 8'h0, |
CLEAR_FEATURE = 8'h1, |
SET_FEATURE = 8'h3, |
SET_ADDRESS = 8'h5, |
GET_DESCRIPTOR = 8'h6, |
SET_DESCRIPTOR = 8'h7, |
GET_CONFIG = 8'h8, |
SET_CONFIG = 8'h9, |
GET_INTERFACE = 8'ha, |
SET_INTERFACE = 8'hb, |
SYNCH_FRAME = 8'hc; |
|
|
task setup1; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** CTRL ep test 1 ***"); |
$display("*****************************************************\n"); |
|
|
$display("\n\nSetting Address ..."); |
|
send_setup( 8'h0, // Function Address |
8'h00, // Request Type |
SET_ADDRESS, // Request |
16'h012, // wValue |
16'h0, // wIndex |
16'h0 // wLength |
); |
|
// Status OK |
data_in( 8'h0, // Function Address |
8'h0 // Expected payload size |
); |
|
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0100, // wValue |
16'h0, // wIndex |
16'h8 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd08 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0200, // wValue |
16'h0, // wIndex |
16'h8 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd08 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0200, // wValue |
16'h0, // wIndex |
16'd053 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd053 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0300, // wValue |
16'h0, // wIndex |
16'd04 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd04 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0301, // wValue |
16'h0, // wIndex |
16'd010 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd010 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0302, // wValue |
16'h0, // wIndex |
16'd08 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd08 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0303, // wValue |
16'h0, // wIndex |
16'd016 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd010 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
$display("\n\nGetting descriptor ..."); |
send_setup( 8'h12, // Function Address |
8'h80, // Request Type |
GET_DESCRIPTOR, // Request |
16'h0203, // wValue |
16'h0, // wIndex |
16'd053 // wLength |
); |
|
data_in( 8'h12, // Function Address |
8'd053 // Expected payload size |
); |
|
// Status OK |
data_out( 8'h12, // Function Address |
8'h0 // Expected payload size |
); |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
|
end |
endtask |
|
|
task in0; |
|
reg [6:0] my_fa; |
integer quick, n, m, rlen,fc; |
reg [7:0] fd; |
integer pack_cnt, pack_cnt_max; |
reg [7:0] x; |
reg [3:0] pid; |
reg [3:0] expect_pid; |
reg [31:0] data; |
reg pid_cnt; |
|
begin |
|
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** IN ep test 0 ***"); |
$display("*****************************************************\n"); |
|
send_sof(11'h000 ); // Send SOF |
|
pack_sz_max = 64; |
pack_cnt_max = 4; |
|
pid_cnt = 0; |
my_fa = 7'h12; |
|
for(pack_sz=0;pack_sz<pack_sz_max;pack_sz=pack_sz+1) |
begin |
|
$display("PL size: %0d", pack_sz); |
|
for(pack_cnt=0;pack_cnt<pack_cnt_max;pack_cnt=pack_cnt+1) |
begin |
|
// Fill Buffer |
buffer1_last = 0; |
for(fc=0;fc<pack_sz;fc=fc+1) |
begin |
#2; |
while(ep1_f_full) @(posedge clk); |
|
#1; |
//x = fc[7:0]; |
x = $random; |
ep1_f_din = x; |
buffer0[fc] = x; |
ep1_f_we = 1; |
@(posedge clk); |
#1; |
ep1_f_we = 0; |
@(posedge clk); |
end |
#1; |
ep1_f_we = 0; |
@(posedge clk); |
|
// Send Data |
repeat(1) @(posedge clk); |
send_sof(11'h000 ); // Send SOF |
repeat(1) @(posedge clk); |
send_token( my_fa, // Function Address |
1, // Logical Endpoint Number |
`USBF_T_PID_IN // PID |
); |
|
repeat(1) @(posedge clk); |
|
recv_packet(pid,rlen); |
|
if(pid_cnt) expect_pid = 4'hb; |
else expect_pid = 4'h3; |
expect_pid = 4'h3; |
|
if(pid !== expect_pid) |
begin |
$display("ERROR: PID mismatch. Expected: %h, Got: %h (%t)", |
expect_pid, pid, $time); |
error_cnt = error_cnt + 1; |
end |
pid_cnt = ~pid_cnt; |
|
if(rlen != pack_sz) |
begin |
$display("ERROR: Size mismatch. Expected: %d, Got: %d (%t)", |
pack_sz, rlen, $time); |
error_cnt = error_cnt + 1; |
end |
|
repeat(4) @(posedge clk); |
send_token( my_fa, // Function Address |
1, // Logical Endpoint Number |
`USBF_T_PID_ACK // PID |
); |
repeat(5) @(posedge clk); |
|
// Verify Data |
for(fc=0;fc<pack_sz;fc=fc+1) |
begin |
x = buffer0[fc]; |
if( (buffer1[fc] !== x) | ( (^buffer1[fc] ^ ^x) === 1'hx) ) |
begin |
$display("ERROR: Data (%0d) mismatch. Expected: %h, Got: %h (%t)", |
fc, buffer1[fc], x, $time); |
error_cnt = error_cnt + 1; |
end |
end |
end |
|
repeat(50) @(posedge clk); |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
|
end |
|
endtask |
|
task out0; |
reg [6:0] my_fa; |
reg [31:0] data; |
integer len, n, no_pack, pl_sz; |
integer no_pack_max, pl_sz_max; |
reg pid; |
|
reg [7:0] x; |
|
begin |
$display("\n\n"); |
$display("*****************************************************"); |
$display("*** OUT ep test 0 ***"); |
$display("*****************************************************\n"); |
|
|
no_pack_max = 4; // Number Of packets to transfer |
pl_sz_max = 128; // Payload Size |
|
no_pack = 4; // Number Of packets to transfer |
pl_sz = 0; |
my_fa = 7'h12; |
|
|
for(pl_sz=0;pl_sz<pl_sz_max;pl_sz=pl_sz+4) |
begin |
pid = 0; |
|
$display("PL size: %0d", pl_sz); |
|
for(n=0;n<4096;n=n+1) |
//buffer1[n] = $random; |
buffer1[n] = n; |
|
buffer1_last = 0; |
|
fork |
for(no_pack=0;no_pack<no_pack_max;no_pack=no_pack+1) // Send no_pack Out packets |
begin |
repeat(1) @(posedge clk); |
send_sof(11'h000 ); // Send SOF |
repeat(1) @(posedge clk); |
|
send_token( my_fa, // Function Address |
4, // Logical Endpoint Number |
`USBF_T_PID_OUT // PID |
); |
|
repeat(1) @(posedge clk); |
|
if(pid==0) send_data(`USBF_T_PID_DATA0, pl_sz, 1); |
else send_data(`USBF_T_PID_DATA1, pl_sz, 1); |
|
pid = ~pid; |
|
// Wait for ACK |
utmi_recv_pack(len); |
|
if(8'hd2 !== txmem[0]) |
begin |
$display("ERROR: ACK mismatch. Expected: %h, Got: %h (%t)", |
8'hd2, txmem[0], $time); |
error_cnt = error_cnt + 1; |
end |
|
repeat(1) @(posedge clk); |
end |
|
begin |
repeat(10) @(posedge clk2); |
for(n=0;n<(no_pack_max*pl_sz);n=n+1) // Compare Buffers |
begin |
|
#4; |
ep4_f_re = 0; |
repeat(1) @(posedge clk2); |
|
while(ep4_f_empty) |
begin |
ep4_f_re = 0; |
repeat(2) @(posedge clk2); |
end |
|
#2; |
if(buffer1[n] !== ep4_f_dout) |
begin |
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)", |
buffer1[n], ep4_f_dout, $time); |
error_cnt = error_cnt + 1; |
end |
|
ep4_f_re = 1; |
@(posedge clk2); |
end |
#1; |
ep4_f_re = 0; |
@(posedge clk2); |
end |
|
join |
|
repeat(1) @(posedge clk); |
end |
|
show_errors; |
$display("*****************************************************"); |
$display("*** Test DONE ... ***"); |
$display("*****************************************************\n\n"); |
end |
endtask |
|
|
/trunk/bench/verilog/timescale.v
0,0 → 1,630
`timescale 1ns / 10ps |
/trunk/bench/verilog/tests_lib.v
0,0 → 1,373
///////////////////////////////////////////////////////////////////// |
//// //// |
//// Test Bench Library //// |
//// //// |
//// //// |
//// Author: Rudolf Usselmann //// |
//// rudi@asics.ws //// |
//// //// |
//// //// |
//// Downloaded from: http://www.opencores.org/cores/usb1_funct///// |
//// //// |
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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: tests_lib.v,v 1.1 2002-09-25 06:10:10 rudi Exp $ |
// |
// $Date: 2002-09-25 06:10:10 $ |
// $Revision: 1.1 $ |
// $Author: rudi $ |
// $Locker: $ |
// $State: Exp $ |
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// |
// |
// |
// |
// |
// |
|
|
task show_errors; |
|
begin |
|
$display("\n"); |
$display(" +--------------------+"); |
$display(" | Total ERRORS: %0d |", error_cnt); |
$display(" +--------------------+"); |
|
end |
endtask |
|
task recv_packet; |
output [3:0] pid; |
output size; |
|
integer del, size,n; |
reg [15:0] crc16r; |
reg [7:0] x,y; |
|
begin |
crc16r = 16'hffff; |
utmi_recv_pack(size); |
for(n=1;n<size-2;n=n+1) |
begin |
y = txmem[n]; |
x[7] = y[0]; |
x[6] = y[1]; |
x[5] = y[2]; |
x[4] = y[3]; |
x[3] = y[4]; |
x[2] = y[5]; |
x[1] = y[6]; |
x[0] = y[7]; |
crc16r = crc16(crc16r, x); |
end |
|
y = crc16r[15:8]; |
x[7] = y[0]; |
x[6] = y[1]; |
x[5] = y[2]; |
x[4] = y[3]; |
x[3] = y[4]; |
x[2] = y[5]; |
x[1] = y[6]; |
x[0] = y[7]; |
crc16r[15:8] = ~x; |
|
y = crc16r[7:0]; |
x[7] = y[0]; |
x[6] = y[1]; |
x[5] = y[2]; |
x[4] = y[3]; |
x[3] = y[4]; |
x[2] = y[5]; |
x[1] = y[6]; |
x[0] = y[7]; |
crc16r[7:0] = ~x; |
|
if(crc16r !== {txmem[n], txmem[n+1]}) |
$display("ERROR: CRC Mismatch: Expected: %h, Got: %h%h (%t)", |
crc16r, txmem[n], txmem[n+1], $time); |
|
for(n=0;n<size-3;n=n+1) |
buffer1[buffer1_last+n] = txmem[n+1]; |
buffer1_last = buffer1_last+n; |
|
// Check PID |
x = txmem[0]; |
|
if(x[7:4] !== ~x[3:0]) |
$display("ERROR: Pid Checksum mismatch: Top: %h Bottom: %h (%t)", |
x[7:4], x[3:0], $time); |
pid = x[3:0]; |
size=size-3; |
end |
endtask |
|
|
|
task send_token; |
input [6:0] fa; |
input [3:0] ep; |
input [3:0] pid; |
|
reg [15:0] tmp_data; |
reg [10:0] x,y; |
integer len; |
|
begin |
|
tmp_data = {fa, ep, 5'h0}; |
if(pid == `USBF_T_PID_ACK) len = 1; |
else len = 3; |
|
y = {fa, ep}; |
x[10] = y[4]; |
x[9] = y[5]; |
x[8] = y[6]; |
x[7] = y[7]; |
x[6] = y[8]; |
x[5] = y[9]; |
x[4] = y[10]; |
x[3] = y[0]; |
x[2] = y[1]; |
x[1] = y[2]; |
x[0] = y[3]; |
|
y[4:0] = crc5( 5'h1f, x ); |
tmp_data[4:0] = ~y[4:0]; |
tmp_data[15:5] = x; |
txmem[0] = {~pid, pid}; // PID |
txmem[1] = { tmp_data[8],tmp_data[9],tmp_data[10],tmp_data[11], |
tmp_data[12],tmp_data[13],tmp_data[14],tmp_data[15]}; |
txmem[2] = { tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3], |
tmp_data[4],tmp_data[5],tmp_data[6],tmp_data[7]}; |
utmi_send_pack(len); |
end |
endtask |
|
|
task send_sof; |
input [10:0] frmn; |
|
reg [15:0] tmp_data; |
reg [10:0] x,y; |
begin |
|
y = frmn; |
x[10] = y[0]; |
x[9] = y[1]; |
x[8] = y[2]; |
x[7] = y[3]; |
x[6] = y[4]; |
x[5] = y[5]; |
x[4] = y[6]; |
x[3] = y[7]; |
x[2] = y[8]; |
x[1] = y[9]; |
x[0] = y[10]; |
|
tmp_data[15:5] = x; |
y[4:0] = crc5( 5'h1f, x ); |
tmp_data[4:0] = ~y[4:0]; |
txmem[0] = {~`USBF_T_PID_SOF, `USBF_T_PID_SOF}; // PID |
txmem[1] = { tmp_data[8],tmp_data[9],tmp_data[10],tmp_data[11], |
tmp_data[12],tmp_data[13],tmp_data[14],tmp_data[15]}; |
txmem[2] = { tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3], |
tmp_data[4],tmp_data[5],tmp_data[6],tmp_data[7]}; |
txmem[1] = frmn[7:0]; |
txmem[2] = { tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3], |
tmp_data[4], frmn[10:8] }; |
utmi_send_pack(3); |
end |
endtask |
|
|
function [4:0] crc5; |
input [4:0] crc_in; |
input [10:0] din; |
reg [4:0] crc_out; |
|
begin |
|
crc5[0] = din[10] ^ din[9] ^ din[6] ^ din[5] ^ din[3] ^ |
din[0] ^ crc_in[0] ^ crc_in[3] ^ crc_in[4]; |
crc5[1] = din[10] ^ din[7] ^ din[6] ^ din[4] ^ din[1] ^ |
crc_in[0] ^ crc_in[1] ^ crc_in[4]; |
crc5[2] = din[10] ^ din[9] ^ din[8] ^ din[7] ^ din[6] ^ |
din[3] ^ din[2] ^ din[0] ^ crc_in[0] ^ crc_in[1] ^ |
crc_in[2] ^ crc_in[3] ^ crc_in[4]; |
crc5[3] = din[10] ^ din[9] ^ din[8] ^ din[7] ^ din[4] ^ din[3] ^ |
din[1] ^ crc_in[1] ^ crc_in[2] ^ crc_in[3] ^ crc_in[4]; |
crc5[4] = din[10] ^ din[9] ^ din[8] ^ din[5] ^ din[4] ^ din[2] ^ |
crc_in[2] ^ crc_in[3] ^ crc_in[4]; |
end |
endfunction |
|
|
task send_data; |
input [3:0] pid; |
input len; |
input mode; |
integer n, len, mode, delay; |
reg [15:0] crc16r; |
reg [7:0] x,y; |
|
begin |
txmem[0] = {~pid, pid}; // PID |
crc16r = 16'hffff; |
for(n=0;n<len;n=n+1) |
begin |
if(mode==1) y = buffer1[buffer1_last+n]; |
else y = n; |
x[7] = y[0]; |
x[6] = y[1]; |
x[5] = y[2]; |
x[4] = y[3]; |
x[3] = y[4]; |
x[2] = y[5]; |
x[1] = y[6]; |
x[0] = y[7]; |
txmem[n+1] = y; |
crc16r = crc16(crc16r, x); |
end |
|
buffer1_last = buffer1_last + n; |
y = crc16r[15:8]; |
x[7] = y[0]; |
x[6] = y[1]; |
x[5] = y[2]; |
x[4] = y[3]; |
x[3] = y[4]; |
x[2] = y[5]; |
x[1] = y[6]; |
x[0] = y[7]; |
txmem[n+1] = ~x; |
|
y = crc16r[7:0]; |
x[7] = y[0]; |
x[6] = y[1]; |
x[5] = y[2]; |
x[4] = y[3]; |
x[3] = y[4]; |
x[2] = y[5]; |
x[1] = y[6]; |
x[0] = y[7]; |
txmem[n+2] = ~x; |
utmi_send_pack(len+3); |
end |
endtask |
|
|
function [15:0] crc16; |
input [15:0] crc_in; |
input [7:0] din; |
reg [15:0] crc_out; |
|
begin |
crc_out[0] = din[7] ^ din[6] ^ din[5] ^ din[4] ^ din[3] ^ |
din[2] ^ din[1] ^ din[0] ^ crc_in[8] ^ crc_in[9] ^ |
crc_in[10] ^ crc_in[11] ^ crc_in[12] ^ crc_in[13] ^ |
crc_in[14] ^ crc_in[15]; |
crc_out[1] = din[7] ^ din[6] ^ din[5] ^ din[4] ^ din[3] ^ din[2] ^ |
din[1] ^ crc_in[9] ^ crc_in[10] ^ crc_in[11] ^ |
crc_in[12] ^ crc_in[13] ^ crc_in[14] ^ crc_in[15]; |
crc_out[2] = din[1] ^ din[0] ^ crc_in[8] ^ crc_in[9]; |
crc_out[3] = din[2] ^ din[1] ^ crc_in[9] ^ crc_in[10]; |
crc_out[4] = din[3] ^ din[2] ^ crc_in[10] ^ crc_in[11]; |
crc_out[5] = din[4] ^ din[3] ^ crc_in[11] ^ crc_in[12]; |
crc_out[6] = din[5] ^ din[4] ^ crc_in[12] ^ crc_in[13]; |
crc_out[7] = din[6] ^ din[5] ^ crc_in[13] ^ crc_in[14]; |
crc_out[8] = din[7] ^ din[6] ^ crc_in[0] ^ crc_in[14] ^ crc_in[15]; |
crc_out[9] = din[7] ^ crc_in[1] ^ crc_in[15]; |
crc_out[10] = crc_in[2]; |
crc_out[11] = crc_in[3]; |
crc_out[12] = crc_in[4]; |
crc_out[13] = crc_in[5]; |
crc_out[14] = crc_in[6]; |
crc_out[15] = din[7] ^ din[6] ^ din[5] ^ din[4] ^ din[3] ^ din[2] ^ |
din[1] ^ din[0] ^ crc_in[7] ^ crc_in[8] ^ crc_in[9] ^ |
crc_in[10] ^ crc_in[11] ^ crc_in[12] ^ crc_in[13] ^ |
crc_in[14] ^ crc_in[15]; |
crc16 = crc_out; |
end |
endfunction |
|
/////////////////////////////////////////////////////////////////// |
// |
// UTMI Low level Tasks |
// |
|
task utmi_send_pack; |
input size; |
integer n,size; |
|
begin |
@(posedge clk); |
#1; |
tb_tx_valid = 1'b1; |
for(n=0;n<size;n=n+1) |
begin |
tb_txdata = txmem[n]; |
@(posedge clk); |
#2; |
while(!tb_tx_ready) @(posedge clk); |
#1; |
end |
tb_tx_valid = 1'b0; |
@(posedge clk); |
end |
endtask |
|
task utmi_recv_pack; |
output size; |
integer size; |
|
begin |
size = 0; |
while(!tb_rx_active) @(posedge clk); |
while(tb_rx_active) |
begin |
#1; |
while(!tb_rx_valid & tb_rx_active) @(posedge clk); |
|
if(tb_rx_valid & tb_rx_active) |
begin |
txmem[size] = tb_rxdata; |
size = size + 1; |
end |
@(posedge clk); |
end |
end |
endtask |
|