📄 usb_ocp_test.cpp
字号:
///////////////////////////////////////////////////////////////////////// //////// USB 1.1 Top Level Test Bench //////// //////// SystemC Version: usb_test.cpp //////// Author: Alfredo Luiz Foltran Fialho //////// alfoltran@ig.com.br //////// //////// ///////////////////////////////////////////////////////////////////////////// //////// Verilog Version: test_bench_top.v + tests.v + tests_lib.v //////// 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 <stdlib.h>#include <time.h>#include "systemc.h"#include "usb_defines.h"#include "usb_phy.h"#include "usb_ocp.h"#define VCD_OUTPUT_ENABLE//#define WIF_OUTPUT_ENABLESC_MODULE(test) { sc_in<bool> clk, clk2; sc_out<bool> rst; sc_in<bool> txdp; sc_in<bool> txdn; sc_out<bool> rxdp; sc_out<bool> rxdn; sc_out<sc_uint<8> > dout; sc_out<bool> tx_valid; sc_in<bool> tx_ready; sc_in<sc_uint<8> > din; sc_in<bool> rx_valid; sc_in<bool> rx_active; sc_in<bool> rx_error; sc_in<bool> txdp2; sc_in<bool> txdn2; sc_out<bool> rxdp2; sc_out<bool> rxdn2; sc_in<bool> s_int; sc_in<sc_uint<8> > s_flag; sc_in<bool> s_error; sc_out<sc_uint<32> >m_addr; sc_out<sc_uint<3> > m_cmd; sc_out<sc_uint<8> > m_data; sc_in<bool> s_cmd_accept; sc_in<sc_uint<8> > s_data; sc_in<sc_uint<2> > s_resp; // Signals sc_signal<bool> usb_reset; sc_signal<sc_uint<32> > wd_cnt; sc_signal<bool> setup_pid; // Local Vars sc_uint<8> txmem[2049]; sc_uint<8> buffer0[16385]; sc_uint<8> buffer1[16385]; sc_uint<8> buffer1_last; int error_cnt; int i;///////////////////////////////////////////////////////////////////////// //////// Test Bench Library //////// /////////////////////////////////////////////////////////////////////////void show_errors(void) { cout << "+----------------------+" << endl; cout << "| TOTAL ERRORS: " << error_cnt << endl; cout << "+----------------------+" << endl << endl;}sc_uint<5> crc5(sc_uint<5> crc_in, sc_uint<11> din) { sc_uint<5> crc_out; crc_out[0] = din[10] ^ din[9] ^ din[6] ^ din[5] ^ din[3] ^ din[0] ^ crc_in[0] ^ crc_in[3] ^ crc_in[4]; crc_out[1] = din[10] ^ din[7] ^ din[6] ^ din[4] ^ din[1] ^ crc_in[0] ^ crc_in[1] ^ crc_in[4]; crc_out[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]; crc_out[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]; crc_out[4] = din[10] ^ din[9] ^ din[8] ^ din[5] ^ din[4] ^ din[2] ^ crc_in[2] ^ crc_in[3] ^ crc_in[4]; return crc_out;}sc_uint<16> crc16(sc_uint<16> crc_in, sc_uint<8> din) { sc_uint<16> crc_out; 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]; return crc_out;}void utmi_send_pack(int size) { int n; wait(clk.posedge_event()); tx_valid.write(true); for (n = 0; n < size; n++) { dout.write(txmem[n]); wait(clk.posedge_event()); while (!tx_ready.read()) wait(clk.posedge_event()); } tx_valid.write(false); wait(clk.posedge_event());}void utmi_recv_pack(int *size) { *size = 0; while (!rx_active.read()) wait(clk.posedge_event()); while (rx_active.read()) { while (!rx_valid.read() && rx_active.read()) wait(clk.posedge_event()); if (rx_valid.read() && rx_active.read()) { txmem[*size] = din.read(); (*size)++; } wait(clk.posedge_event()); }}void recv_packet(sc_uint<4> *pid, int *size) { int n; sc_uint<16> crc16r; sc_uint<8> x, y; crc16r = 0xffff; utmi_recv_pack(size); if (*size != 1) { for (n = 1; n < *size - 2; n++) { y = txmem[n]; x = ( (sc_uint<1>)y[0], (sc_uint<1>)y[1], (sc_uint<1>)y[2], (sc_uint<1>)y[3], (sc_uint<1>)y[4], (sc_uint<1>)y[5], (sc_uint<1>)y[6], (sc_uint<1>)y[7]); crc16r = crc16(crc16r, x); } crc16r = ( (sc_uint<1>)!crc16r[8], (sc_uint<1>)!crc16r[9], (sc_uint<1>)!crc16r[10], (sc_uint<1>)!crc16r[11], (sc_uint<1>)!crc16r[12], (sc_uint<1>)!crc16r[13], (sc_uint<1>)!crc16r[14], (sc_uint<1>)!crc16r[15], (sc_uint<1>)!crc16r[0], (sc_uint<1>)!crc16r[1], (sc_uint<1>)!crc16r[2], (sc_uint<1>)!crc16r[3], (sc_uint<1>)!crc16r[4], (sc_uint<1>)!crc16r[5], (sc_uint<1>)!crc16r[6], (sc_uint<1>)!crc16r[7]); if (crc16r != (sc_uint<16>)(txmem[n], txmem[n + 1])) cout << "ERROR: CRC Mismatch: Expected: " << crc16r << ", Got: " << txmem[n] << txmem[n + 1] << " (" << sc_simulation_time() << ")" << endl << endl; for (n = 0; n < *size - 3; n++) buffer1[buffer1_last + n] = txmem[n + 1]; buffer1_last = buffer1_last + n; } else { *size = 3; } x = txmem[0]; if ((sc_uint<4>)x.range(7, 4) != (sc_uint<4>)~x.range(3, 0)) cout << "ERROR: Pid Checksum mismatch: Top: " << (sc_uint<4>)x.range(7, 4) << " Bottom: " << (sc_uint<4>)x.range(3, 0) << " (" << sc_simulation_time() << ")" << endl << endl; *pid = (sc_uint<4>)x.range(3, 0); *size = *size - 3;}void send_token(sc_uint<7> fa, sc_uint<4> ep, sc_uint<4> pid) { sc_uint<16> tmp_data; sc_uint<11> x, y; int len; tmp_data = ((sc_uint<7>)fa, (sc_uint<4>)ep, (sc_uint<5>)0); if (pid == USBF_T_PID_ACK) len = 1; else len = 3; y = ((sc_uint<7>)fa, (sc_uint<4>)ep); x = ( (sc_uint<1>)y[4], (sc_uint<1>)y[5], (sc_uint<1>)y[6], (sc_uint<1>)y[7], (sc_uint<1>)y[8], (sc_uint<1>)y[9], (sc_uint<1>)y[10], (sc_uint<1>)y[0], (sc_uint<1>)y[1], (sc_uint<1>)y[2], (sc_uint<1>)y[3]); y = ((sc_uint<6>)0, (sc_uint<5>)crc5(0x1f, x)); tmp_data = ((sc_uint<11>)x, (sc_uint<5>)~y.range(4, 0)); txmem[0] = ((sc_uint<4>)~pid, (sc_uint<4>)pid); txmem[1] = ( (sc_uint<1>)tmp_data[8], (sc_uint<1>)tmp_data[9], (sc_uint<1>)tmp_data[10], (sc_uint<1>)tmp_data[11], (sc_uint<1>)tmp_data[12], (sc_uint<1>)tmp_data[13], (sc_uint<1>)tmp_data[14], (sc_uint<1>)tmp_data[15]); txmem[2] = ( (sc_uint<1>)tmp_data[0], (sc_uint<1>)tmp_data[1], (sc_uint<1>)tmp_data[2], (sc_uint<1>)tmp_data[3], (sc_uint<1>)tmp_data[4], (sc_uint<1>)tmp_data[5], (sc_uint<1>)tmp_data[6], (sc_uint<1>)tmp_data[7]); utmi_send_pack(len);}void send_sof(sc_uint<11> frmn) { sc_uint<16> tmp_data; sc_uint<11> x; x = ( (sc_uint<1>)frmn[0], (sc_uint<1>)frmn[1], (sc_uint<1>)frmn[2], (sc_uint<1>)frmn[3], (sc_uint<1>)frmn[4], (sc_uint<1>)frmn[5], (sc_uint<1>)frmn[6], (sc_uint<1>)frmn[7], (sc_uint<1>)frmn[8], (sc_uint<1>)frmn[9], (sc_uint<1>)frmn[10]); tmp_data = ((sc_uint<11>)x, (sc_uint<5>)~crc5(0x1f, x)); txmem[0] = ((sc_uint<4>)~USBF_T_PID_SOF, (sc_uint<4>)USBF_T_PID_SOF);// txmem[1] = ( (sc_uint<1>)tmp_data[8],// (sc_uint<1>)tmp_data[9],// (sc_uint<1>)tmp_data[10],// (sc_uint<1>)tmp_data[11],// (sc_uint<1>)tmp_data[12],// (sc_uint<1>)tmp_data[13],// (sc_uint<1>)tmp_data[14],// (sc_uint<1>)tmp_data[15]);// txmem[2] = ( (sc_uint<1>)tmp_data[0],// (sc_uint<1>)tmp_data[1],// (sc_uint<1>)tmp_data[2],// (sc_uint<1>)tmp_data[3],// (sc_uint<1>)tmp_data[4],// (sc_uint<1>)tmp_data[5],// (sc_uint<1>)tmp_data[6],// (sc_uint<1>)tmp_data[7]); txmem[1] = (sc_uint<8>)frmn.range(7, 0); txmem[2] = ( (sc_uint<1>)tmp_data[0], (sc_uint<1>)tmp_data[1], (sc_uint<1>)tmp_data[2], (sc_uint<1>)tmp_data[3], (sc_uint<1>)tmp_data[4], (sc_uint<3>)frmn.range(10, 8)); utmi_send_pack(3);}void send_data(sc_uint<4> pid, int len, int mode) { int n; sc_uint<16> crc16r; sc_uint<8> x, y; txmem[0] = ((sc_uint<4>)~pid, (sc_uint<4>)pid); crc16r = 0xffff; for (n = 0; n < len; n++) { if (mode == 1) y = buffer1[buffer1_last + n]; else y = n; x = ( (sc_uint<1>)y[0], (sc_uint<1>)y[1], (sc_uint<1>)y[2], (sc_uint<1>)y[3], (sc_uint<1>)y[4], (sc_uint<1>)y[5], (sc_uint<1>)y[6], (sc_uint<1>)y[7]); txmem[n + 1] = y; crc16r = crc16(crc16r, x); } buffer1_last = buffer1_last + n; y = (sc_uint<8>)crc16r.range(15, 8); txmem[n + 1] = ( (sc_uint<1>)!y[0], (sc_uint<1>)!y[1], (sc_uint<1>)!y[2], (sc_uint<1>)!y[3], (sc_uint<1>)!y[4], (sc_uint<1>)!y[5], (sc_uint<1>)!y[6], (sc_uint<1>)!y[7]); y = (sc_uint<8>)crc16r.range(7, 0); txmem[n + 2] = ( (sc_uint<1>)!y[0], (sc_uint<1>)!y[1], (sc_uint<1>)!y[2], (sc_uint<1>)!y[3], (sc_uint<1>)!y[4], (sc_uint<1>)!y[5], (sc_uint<1>)!y[6], (sc_uint<1>)!y[7]); utmi_send_pack(len + 3);}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////// Test Case Collection //////// /////////////////////////////////////////////////////////////////////////void send_setup( sc_uint<7> fa, sc_uint<8> req_type, sc_uint<8> request, sc_uint<16> wValue, sc_uint<16> wIndex, sc_uint<16> wLength) { int len; buffer1[0] = req_type; buffer1[1] = request; buffer1[3] = (sc_uint<8>)wValue.range(15, 8); buffer1[2] = (sc_uint<8>)wValue.range(7, 0); buffer1[5] = (sc_uint<8>)wIndex.range(15, 8); buffer1[4] = (sc_uint<8>)wIndex.range(7, 0); buffer1[7] = (sc_uint<8>)wLength.range(15, 8); buffer1[6] = (sc_uint<8>)wLength.range(7, 0); buffer1_last = 0; send_token(fa, 0, USBF_T_PID_SETUP); wait(clk.posedge_event()); send_data(USBF_T_PID_DATA0, 8, 1); utmi_recv_pack(&len); if (txmem[0] != 0xd2) { cout << "ERROR: SETUP: ACK mismatch. Expected: 0xD2, Got: " << txmem[0] << " (" << sc_simulation_time() << ")" << endl << endl; error_cnt++; } if (len != 1) { cout << "ERROR: SETUP: ACK mismatch. Expected: 1, Got: " << len << " (" << sc_simulation_time() << ")" << endl << endl; error_cnt++; } wait(clk.posedge_event()); setup_pid.write(true); wait(clk.posedge_event());}void data_in(sc_uint<7> fa, int pl_size) { int rlen; sc_uint<4> pid, expect_pid; buffer1_last = 0; for (i = 0; i < 5; i++) wait(clk.posedge_event()); send_token(fa, 0, USBF_T_PID_IN); recv_packet(&pid, &rlen); if (setup_pid.read()) expect_pid = 0xb; // DATA 1 else expect_pid = 0x3; // DATA 0 if (pid != expect_pid) { cout << "ERROR: Data IN PID mismatch. Expected: " << expect_pid << ", Got: " << pid << " (" << sc_simulation_time() << ")" << endl << endl; error_cnt++; } setup_pid.write(!setup_pid.read()); if (rlen != pl_size) { cout << "ERROR: Data IN Size mismatch. Expected: " << pl_size << ", Got: " << rlen << " (" << sc_simulation_time() << ")" << endl << endl; error_cnt++; } for (i = 0; i < rlen; i++) { cout << "RCV Data[" << i << "]: 0x"; printf("%02x", (unsigned int)buffer1[i]); cout << endl; } cout << endl; for (i = 0; i < 5; i++) wait(clk.posedge_event()); send_token(fa, 0, USBF_T_PID_ACK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -