OpenCores
URL https://opencores.org/ocsvn/usb11/usb11/trunk

Subversion Repositories usb11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/bench/systemc/usb_8051_test.cpp
0,0 → 1,167
/////////////////////////////////////////////////////////////////////
//// ////
//// 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 ////
//// 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 "systemc.h"
#include "usb_phy.h"
#include "usb_top.h"
 
#define VCD_OUTPUT_ENABLE
//#define WIF_OUTPUT_ENABLE
 
SC_MODULE(test) {
sc_in<bool> clk, clk2;
sc_out<bool> rst;
 
int i;
 
void update(void) {
rst.write(false);
for (i = 0; i < 10; i++) wait(clk.posedge_event());
rst.write(true);
for (i = 0; i < 500; i++) wait(clk.posedge_event());
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive_pos(clk);
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.84, SC_NS);
sc_clock clk2("clock2", 20.84, SC_NS);
 
sc_signal<bool> rst, vcc;
 
sc_signal<bool> rx_dp1, rx_dn1, tx_dp1, tx_dn1;
sc_signal<bool> tb_rx_valid, tb_rx_active, tb_rx_error;
sc_signal<bool> tb_tx_valid, tb_tx_ready;
sc_signal<sc_uint<8> > tb_rx_data, tb_tx_data;
 
sc_signal<bool> rx_dp2, rx_dn2, tx_dp2, tx_dn2;
sc_signal<sc_uint<8> > ep_f_din;
sc_signal_rv<8> ep_f_dout;
sc_signal<sc_uint<8> > ep_f_adr;
sc_signal<bool> cs, ep_f_re, ep_f_we, ep_f_empty, ep_f_full;
 
sc_signal<bool> usb_rst_nc, txoe_nc;
sc_signal<sc_uint<2> > line_nc;
 
sc_signal<bool> rst_nc, tx_oe_nc, crc16_nc, int_nc, feature_nc, busy_nc;
sc_signal<sc_uint<4> > sel_nc;
 
usb_phy i_phy("HOST_PHY");
usb_top i_top("USB_TOP");
test i_test("TEST");
 
i_phy.clk(clk);
i_phy.rst(rst);
i_phy.phy_tx_mode(vcc);
i_phy.usb_rst(usb_rst_nc);
i_phy.txdp(tx_dp1);
i_phy.txdn(tx_dn1);
i_phy.txoe(txoe_nc);
i_phy.rxd(rx_dp1);
i_phy.rxdp(rx_dp1);
i_phy.rxdn(rx_dn1);
i_phy.DataOut_i(tb_tx_data);
i_phy.TxValid_i(tb_tx_valid);
i_phy.TxReady_o(tb_tx_ready);
i_phy.DataIn_o(tb_rx_data);
i_phy.RxValid_o(tb_rx_valid);
i_phy.RxActive_o(tb_rx_active);
i_phy.RxError_o(tb_rx_error);
i_phy.LineState_o(line_nc);
 
i_top.clk_i(clk);
i_top.rst_i(rst);
i_top.tx_dp(tx_dp2);
i_top.tx_dn(tx_dn2);
i_top.tx_oe(tx_oe_nc);
i_top.rx_dp(rx_dp2);
i_top.rx_dn(rx_dn2);
i_top.rx_d(rx_dp2);
i_top.usb_rst(rst_nc);
i_top.crc16_err(crc16_nc);
i_top.v_set_int(int_nc);
i_top.v_set_feature(feature_nc);
i_top.usb_busy(busy_nc);
i_top.ep_sel(sel_nc);
i_top.adr(ep_f_adr);
i_top.din(ep_f_din);
i_top.dout(ep_f_dout);
i_top.cs(cs);
i_top.re(ep_f_re);
i_top.we(ep_f_we);
i_top.empty(ep_f_empty);
i_top.full(ep_f_full);
 
i_test.clk(clk);
i_test.clk2(clk2);
i_test.rst(rst);
 
vcc.write(true);
 
#ifdef VCD_OUTPUT_ENABLE
sc_trace_file *vcd_log = sc_create_vcd_trace_file("USB_TEST");
sc_trace(vcd_log, clk, "Clock");
sc_trace(vcd_log, rst, "Reset");
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_trace_file *wif_log = sc_create_wif_trace_file("USB_TEST");
sc_trace(wif_log, clk, "Clock");
sc_trace(wif_log, rst, "Reset");
#endif
 
sc_start();
 
#ifdef VCD_OUTPUT_ENABLE
sc_close_vcd_trace_file(vcd_log);
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_close_wif_trace_file(wif_log);
#endif
 
return 0;
}
 
/trunk/bench/systemc/usb_ocp_test.cpp
0,0 → 1,1411
/////////////////////////////////////////////////////////////////////
//// ////
//// 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_ENABLE
 
SC_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);
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
}
 
void data_out(sc_uint<7> fa, int pl_size) {
int len;
 
send_token(fa, 0, USBF_T_PID_OUT);
 
wait(clk.posedge_event());
 
if (!setup_pid.read())
send_data(USBF_T_PID_DATA0, pl_size, 1);
else
send_data(USBF_T_PID_DATA1, pl_size, 1);
 
setup_pid.write(!setup_pid.read());
 
utmi_recv_pack(&len);
 
if (txmem[0] != 0xd2) {
cout << "ERROR: Ack mismatch. Expected: 0xd2, Got: " << txmem[0] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
if (len != 1) {
cout << "ERROR: SETUP: Length mismatch. Expected: 1, Got: " << len <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
}
 
// Enumeration Test -> Endpoint 0
void setup0(void) {
cout << endl;
 
cout << "The Default Time Unit is: " << sc_get_default_time_unit().to_string() << endl << endl;
 
cout << "**************************************************" << endl;
cout << "*** CONTROL EP TEST 0 ***" << endl;
cout << "**************************************************" << endl << endl;
 
cout << "Setting Address ..." << endl << endl;
 
send_setup(0x00, 0x00, SET_ADDRESS, 0x0012, 0x0000, 0x0000);
data_in(0x00,0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0100, 0x0000, 0x0012);
data_in(0x12, 18);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0200, 0x0000, 0x0009);
data_in(0x12, 9);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0200, 0x0000, 0x003c);
data_in(0x12, 60);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0300, 0x0000, 0x0008);
data_in(0x12, 8);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0301, 0x0416, 0x001a);
data_in(0x12, 26);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0302, 0x0416, 0x001c);
data_in(0x12, 28);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0303, 0x0416, 0x0036);
data_in(0x12, 54);
data_out(0x12, 0);
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// ISO IN Test -> Endpoint 1
void in1(void) {
sc_uint<7> my_fa;
int rlen, fc;
sc_uint<8> fd;
int pack_cnt, pack_cnt_max, pack_sz, pack_sz_max;
sc_uint<8> x;
sc_uint<4> pid, expect_pid;
sc_uint<32> data;
// bool pid_cnt;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** ISOCHRONOUS IN EP TEST 1 ***" << endl;
cout << "**************************************************" << endl << endl;
 
send_sof(0x000);
 
pack_sz_max = 256;
pack_cnt_max = 4;
 
// pid_cnt = false;
my_fa = 0x12;
 
m_addr.write(0x00000001);
m_cmd.write(0x0);
 
for (pack_sz = 0; pack_sz <= pack_sz_max; pack_sz += 32) {
cout << "PL Size: " << pack_sz << endl;
 
for (pack_cnt = 0; pack_cnt < pack_cnt_max; pack_cnt++) {
buffer1_last = 0;
for (fc = 0; fc < pack_sz; fc++) {
while (s_flag.read()[1])
wait(clk.posedge_event());
 
x = (sc_uint<8>)(255.0 * rand() / (RAND_MAX + 1.0));
m_data.write(x);
buffer0[fc] = x;
m_cmd.write(0x1);
wait(clk.posedge_event());
m_cmd.write(0x0);
wait(clk.posedge_event());
}
m_cmd.write(0x0);
wait(clk.posedge_event());
 
// Send Data
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
send_token(my_fa, 1, USBF_T_PID_IN);
wait(clk.posedge_event());
 
recv_packet(&pid, &rlen);
 
// if (pid_cnt)
// expect_pid = 0xb;
// else
// expect_pid = 0x3;
expect_pid = 0x3;
 
if (pid != expect_pid) {
cout << "ERROR: PID mismatch. Expected: " << expect_pid << ", Got: " << pid <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
// pid_cnt = !pid_cnt;
 
if (rlen != pack_sz) {
cout << "ERROR: Size mismatch. Expected: " << pack_sz << ", Got: " << rlen <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 4; i++)
wait(clk.posedge_event());
 
// Verify Data
for (fc = 0; fc < pack_sz; fc++) {
x = buffer0[fc];
if (buffer1[fc] != x) {
cout << "ERROR: Data (" << fc << ") mismatch. Expected: " << x << ", Got: " << buffer1[fc] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
}
}
for (i = 0; i < 50; i++)
wait(clk.posedge_event());
}
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// ISO OUT Test -> Endpoint 2
void out2(void) {
sc_uint<7> my_fa;
sc_uint<32> data;
int n, no_pack, no_pack_max, pl_sz, pl_sz_max;
bool pid;
sc_uint<8> x;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** ISOCHRONOUS OUT EP TEST 2 ***" << endl;
cout << "**************************************************" << endl << endl;
 
no_pack_max = 4;
pl_sz_max = 256;
 
my_fa = 0x12;
 
m_addr.write(0x00000002);
m_cmd.write(0x0);
 
for (pl_sz = 0; pl_sz <= pl_sz_max; pl_sz += 32) {
pid = false;
 
cout << "PL Size: " << pl_sz << endl;
 
for (n = 0; n < 4096; n++)
buffer1[n] = n;
 
buffer1_last = 0;
 
no_pack = 0;
while (true) {
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
 
send_token(my_fa, 2, USBF_T_PID_OUT);
wait(clk.posedge_event());
 
if (!pid)
send_data(USBF_T_PID_DATA0, pl_sz, 1);
else
send_data(USBF_T_PID_DATA1, pl_sz, 1);
for (i = 0; i < 10; i++)
wait(clk2.posedge_event());
for (n = 0; n < pl_sz; n++) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
 
while (s_flag.read()[0]) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
}
 
if (buffer1[n + (pl_sz * no_pack)] != s_data.read()) {
cout << "ERROR: DATA mismatch. Expected: " << s_data.read() << ", Got: " << buffer1[n + (pl_sz * no_pack)] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
m_cmd.write(0x2);
wait(clk2.posedge_event());
wait(clk2.negedge_event());
}
m_cmd.write(0x0);
wait(clk2.posedge_event());
 
no_pack++;
if (no_pack == no_pack_max)
break;
}
wait(clk.posedge_event());
}
 
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// BULK IN Test -> Endpoint 3
void in3(void) {
sc_uint<7> my_fa;
int rlen, fc;
sc_uint<8> fd;
int pack_cnt, pack_cnt_max, pack_sz, pack_sz_max;
sc_uint<8> x;
sc_uint<4> pid, expect_pid;
sc_uint<32> data;
bool pid_cnt;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** BULK IN EP TEST 3 ***" << endl;
cout << "**************************************************" << endl << endl;
 
send_sof(0x000);
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = false;
my_fa = 0x12;
 
m_addr.write(0x00000003);
m_cmd.write(0x0);
 
for (pack_sz = 0; pack_sz <= pack_sz_max; pack_sz += 8) {
cout << "PL Size: " << pack_sz << endl;
 
for (pack_cnt = 0; pack_cnt < pack_cnt_max; pack_cnt++) {
buffer1_last = 0;
for (fc = 0; fc < pack_sz; fc++) {
while (s_flag.read()[1])
wait(clk.posedge_event());
 
x = (sc_uint<8>)(255.0 * rand() / (RAND_MAX + 1.0));
m_data.write(x);
buffer0[fc] = x;
m_cmd.write(0x1);
wait(clk.posedge_event());
m_cmd.write(0x0);
wait(clk.posedge_event());
}
m_cmd.write(0x0);
wait(clk.posedge_event());
 
// Send Data
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
send_token(my_fa, 3, USBF_T_PID_IN);
wait(clk.posedge_event());
 
recv_packet(&pid, &rlen);
 
if (pid_cnt)
expect_pid = 0xb;
else
expect_pid = 0x3;
// expect_pid = 0x3;
 
if (pid != expect_pid) {
cout << "ERROR: PID mismatch. Expected: " << expect_pid << ", Got: " << pid <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
pid_cnt = !pid_cnt;
 
if (rlen != pack_sz) {
cout << "ERROR: Size mismatch. Expected: " << pack_sz << ", Got: " << rlen <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 4; i++)
wait(clk.posedge_event());
 
send_token(my_fa, 3, USBF_T_PID_ACK);
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
 
// Verify Data
for (fc = 0; fc < pack_sz; fc++) {
x = buffer0[fc];
if (buffer1[fc] != x) {
cout << "ERROR: Data (" << fc << ") mismatch. Expected: " << x << ", Got: " << buffer1[fc] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
}
}
for (i = 0; i < 50; i++)
wait(clk.posedge_event());
}
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// BULK OUT Test -> Endpoint 4
void out4(void) {
sc_uint<7> my_fa;
sc_uint<32> data;
int n, len, no_pack, no_pack_max, pl_sz, pl_sz_max;
bool pid;
sc_uint<8> x;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** BULK OUT EP TEST 4 ***" << endl;
cout << "**************************************************" << endl << endl;
 
no_pack_max = 4;
pl_sz_max = 64;
 
my_fa = 0x12;
 
m_addr.write(0x00000004);
m_cmd.write(0x0);
 
for (pl_sz = 0; pl_sz <= pl_sz_max; pl_sz += 8) {
pid = false;
 
cout << "PL Size: " << pl_sz << endl;
 
for (n = 0; n < 4096; n++)
buffer1[n] = n;
 
buffer1_last = 0;
 
no_pack = 0;
while (true) {
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
 
send_token(my_fa, 4, USBF_T_PID_OUT);
wait(clk.posedge_event());
 
if (!pid)
send_data(USBF_T_PID_DATA0, pl_sz, 1);
else
send_data(USBF_T_PID_DATA1, pl_sz, 1);
pid = !pid;
 
utmi_recv_pack(&len);
 
if (txmem[0] != 0xd2) {
cout << "ERROR: ACK mismatch. Expected: 0xd2, Got: " << txmem[0] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
if (len != 1) {
cout << "ERROR: Size mismatch. Expected: 1, Got: " << len <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
wait(clk.posedge_event());
 
for (i = 0; i < 10; i++)
wait(clk2.posedge_event());
for (n = 0; n < pl_sz; n++) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
 
while (s_flag.read()[0]) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
}
 
if (buffer1[n + (pl_sz * no_pack)] != s_data.read()) {
cout << "ERROR: DATA mismatch. Expected: " << s_data.read() << ", Got: " << buffer1[n + (pl_sz * no_pack)] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
m_cmd.write(0x2);
wait(clk2.posedge_event());
wait(clk2.negedge_event());
}
m_cmd.write(0x0);
wait(clk2.posedge_event());
 
no_pack++;
if (no_pack == no_pack_max)
break;
}
wait(clk.posedge_event());
}
 
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// INT IN Test -> Endpoint 5
void in5(void) {
sc_uint<7> my_fa;
int rlen, fc;
sc_uint<8> fd;
int pack_cnt, pack_cnt_max, pack_sz, pack_sz_max;
sc_uint<8> x;
sc_uint<4> pid, expect_pid;
sc_uint<32> data;
bool pid_cnt;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** INTERRUPT IN EP TEST 5 ***" << endl;
cout << "**************************************************" << endl << endl;
 
send_sof(0x000);
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = false;
my_fa = 0x12;
 
m_addr.write(0x00000005);
m_cmd.write(0x0);
 
for (pack_sz = 0; pack_sz <= pack_sz_max; pack_sz += 8) {
cout << "PL Size: " << pack_sz << endl;
 
for (pack_cnt = 0; pack_cnt < pack_cnt_max; pack_cnt++) {
buffer1_last = 0;
for (fc = 0; fc < pack_sz; fc++) {
while (s_flag.read()[1])
wait(clk.posedge_event());
 
x = (sc_uint<8>)(255.0 * rand() / (RAND_MAX + 1.0));
m_data.write(x);
buffer0[fc] = x;
m_cmd.write(0x1);
wait(clk.posedge_event());
m_cmd.write(0x0);
wait(clk.posedge_event());
}
m_cmd.write(0x0);
wait(clk.posedge_event());
 
// Send Data
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
send_token(my_fa, 5, USBF_T_PID_IN);
wait(clk.posedge_event());
 
recv_packet(&pid, &rlen);
 
if (pack_sz == 0)
expect_pid = 0xa;
else if (pid_cnt)
expect_pid = 0xb;
else
expect_pid = 0x3;
// expect_pid = 0x3;
 
if (pid != expect_pid) {
cout << "ERROR: PID mismatch. Expected: " << expect_pid << ", Got: " << pid <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
pid_cnt = !pid_cnt;
 
if (rlen != pack_sz) {
cout << "ERROR: Size mismatch. Expected: " << pack_sz << ", Got: " << rlen <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 4; i++)
wait(clk.posedge_event());
 
send_token(my_fa, 5, USBF_T_PID_ACK);
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
 
// Verify Data
for (fc = 0; fc < pack_sz; fc++) {
x = buffer0[fc];
if (buffer1[fc] != x) {
cout << "ERROR: Data (" << fc << ") mismatch. Expected: " << x << ", Got: " << buffer1[fc] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
}
}
for (i = 0; i < 50; i++)
wait(clk.posedge_event());
}
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// INT OUT Test -> Endpoint 6
void out6(void) {
sc_uint<7> my_fa;
sc_uint<32> data;
int n, len, no_pack, no_pack_max, pl_sz, pl_sz_max;
bool pid;
sc_uint<8> x;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** INTERRUPT OUT EP TEST 6 ***" << endl;
cout << "**************************************************" << endl << endl;
 
no_pack_max = 4;
pl_sz_max = 64;
 
my_fa = 0x12;
 
m_addr.write(0x00000006);
m_cmd.write(0x0);
 
for (pl_sz = 0; pl_sz <= pl_sz_max; pl_sz += 8) {
pid = false;
 
cout << "PL Size: " << pl_sz << endl;
 
for (n = 0; n < 4096; n++)
buffer1[n] = n;
 
buffer1_last = 0;
 
no_pack = 0;
while (true) {
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
 
send_token(my_fa, 6, USBF_T_PID_OUT);
wait(clk.posedge_event());
 
if (!pid)
send_data(USBF_T_PID_DATA0, pl_sz, 1);
else
send_data(USBF_T_PID_DATA1, pl_sz, 1);
pid = !pid;
 
utmi_recv_pack(&len);
 
if (txmem[0] != 0xd2) {
cout << "ERROR: ACK mismatch. Expected: 0xd2, Got: " << txmem[0] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
if (len != 1) {
cout << "ERROR: Size mismatch. Expected: 1, Got: " << len <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
wait(clk.posedge_event());
 
for (i = 0; i < 10; i++)
wait(clk2.posedge_event());
for (n = 0; n < pl_sz; n++) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
 
while (s_flag.read()[0]) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
}
 
if (buffer1[n + (pl_sz * no_pack)] != s_data.read()) {
cout << "ERROR: DATA mismatch. Expected: " << s_data.read() << ", Got: " << buffer1[n + (pl_sz * no_pack)] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
m_cmd.write(0x2);
wait(clk2.posedge_event());
wait(clk2.negedge_event());
}
m_cmd.write(0x0);
wait(clk2.posedge_event());
 
no_pack++;
if (no_pack == no_pack_max)
break;
}
wait(clk.posedge_event());
}
 
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
/////////////////////////////////////////////////////////////////////
 
void rx1_update(void) {
rxdp.write(!usb_reset.read() && txdp2.read());
rxdn.write(!usb_reset.read() && txdn2.read());
}
 
void rx2_update(void) {
rxdp2.write(!usb_reset.read() && txdp.read());
rxdn2.write(!usb_reset.read() && txdn.read());
}
 
void watchdog(void) {
if (txdp.read() || txdp2.read())
wd_cnt.write(0);
else
wd_cnt.write(wd_cnt.read() + 1);
}
 
void wd_cnt_mon(void) {
if (wd_cnt.read() > 5000) {
cout << "**********************************" << endl;
cout << "ERROR: Watch Dog Counter Expired" << endl;
cout << "**********************************" << endl << endl;
sc_stop();
}
}
 
void init(void) {
usb_reset.write(false);
tx_valid.write(false);
error_cnt = 0;
wd_cnt.write(0);
rst.write(false);
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
for (i = 0; i < 10; i++) wait(clk.posedge_event());
rst.write(true);
 
for (i = 0; i < 50; i++) wait(clk.posedge_event());
usb_reset.write(true);
 
for (i = 0; i < 300; i++) wait(clk.posedge_event());
usb_reset.write(false);
 
for (i = 0; i < 10; i++) wait(clk.posedge_event());
 
setup0();
in1();
out2();
in3();
out4();
in5();
out6();
 
for (i = 0; i < 500; i++) wait(clk.posedge_event());
sc_stop();
}
 
SC_CTOR(test) {
SC_METHOD(rx1_update);
sensitive << usb_reset << txdp2 << txdn2;
SC_METHOD(rx2_update);
sensitive << usb_reset << txdp << txdn;
SC_METHOD(watchdog);
sensitive << clk.pos();
SC_METHOD(wd_cnt_mon);
sensitive << wd_cnt;
SC_THREAD(init);
sensitive << clk.pos();
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.84, SC_NS);
sc_clock clk2("clock2", 20.84, SC_NS);
 
sc_signal<bool> rst, vcc;
 
sc_signal<bool> rx_dp1, rx_dn1, tx_dp1, tx_dn1;
sc_signal<bool> tb_rx_valid, tb_rx_active, tb_rx_error;
sc_signal<bool> tb_tx_valid, tb_tx_ready;
sc_signal<sc_uint<8> > tb_rx_data, tb_tx_data;
 
sc_signal<bool> rx_dp2, rx_dn2, tx_dp2, tx_dn2;
sc_signal<sc_uint<8> > SData, MData, SFlag;
sc_signal<sc_uint<32> > MAddr;
sc_signal<sc_uint<3> > MCmd;
sc_signal<sc_uint<2> > SResp;
sc_signal<bool> SInterrupt, SError, SCmdAccept;
 
sc_signal<bool> usb_rst_nc, txoe_nc, tx_oe_nc;
sc_signal<sc_uint<2> > line_nc;
 
usb_phy i_phy("HOST_PHY");
usb_ocp i_ocp("USB_OCP");
test i_test("TEST");
 
i_phy.clk(clk);
i_phy.rst(rst);
i_phy.phy_tx_mode(vcc);
i_phy.usb_rst(usb_rst_nc);
i_phy.txdp(tx_dp1);
i_phy.txdn(tx_dn1);
i_phy.txoe(txoe_nc);
i_phy.rxd(rx_dp1);
i_phy.rxdp(rx_dp1);
i_phy.rxdn(rx_dn1);
i_phy.DataOut_i(tb_tx_data);
i_phy.TxValid_i(tb_tx_valid);
i_phy.TxReady_o(tb_tx_ready);
i_phy.DataIn_o(tb_rx_data);
i_phy.RxValid_o(tb_rx_valid);
i_phy.RxActive_o(tb_rx_active);
i_phy.RxError_o(tb_rx_error);
i_phy.LineState_o(line_nc);
 
i_ocp.Clk(clk2);
i_ocp.Reset_n(rst);
i_ocp.tx_dp(tx_dp2);
i_ocp.tx_dn(tx_dn2);
i_ocp.tx_oe(tx_oe_nc);
i_ocp.rx_dp(rx_dp2);
i_ocp.rx_dn(rx_dn2);
i_ocp.rx_d(rx_dp2);
i_ocp.SInterrupt(SInterrupt);
i_ocp.SFlag(SFlag);
i_ocp.SError(SError);
i_ocp.MAddr(MAddr);
i_ocp.MCmd(MCmd);
i_ocp.MData(MData);
i_ocp.SCmdAccept(SCmdAccept);
i_ocp.SData(SData);
i_ocp.SResp(SResp);
 
i_test.clk(clk);
i_test.rst(rst);
i_test.txdp(tx_dp1);
i_test.txdn(tx_dn1);
i_test.rxdp(rx_dp1);
i_test.rxdn(rx_dn1);
i_test.dout(tb_tx_data);
i_test.tx_valid(tb_tx_valid);
i_test.tx_ready(tb_tx_ready);
i_test.din(tb_rx_data);
i_test.rx_valid(tb_rx_valid);
i_test.rx_active(tb_rx_active);
i_test.rx_error(tb_rx_error);
 
i_test.clk2(clk2);
i_test.txdp2(tx_dp2);
i_test.txdn2(tx_dn2);
i_test.rxdp2(rx_dp2);
i_test.rxdn2(rx_dn2);
i_test.s_int(SInterrupt);
i_test.s_flag(SFlag);
i_test.s_error(SError);
i_test.m_addr(MAddr);
i_test.m_cmd(MCmd);
i_test.m_data(MData);
i_test.s_cmd_accept(SCmdAccept);
i_test.s_data(SData);
i_test.s_resp(SResp);
 
vcc.write(true);
 
#ifdef VCD_OUTPUT_ENABLE
sc_trace_file *vcd_log = sc_create_vcd_trace_file("USB_TEST");
sc_trace(vcd_log, clk2, "Clk");
sc_trace(vcd_log, rst, "Reset_n");
sc_trace(vcd_log, MAddr, "MAddr");
sc_trace(vcd_log, MCmd, "MCmd");
sc_trace(vcd_log, MData, "MData");
sc_trace(vcd_log, SData, "SData");
sc_trace(vcd_log, SCmdAccept, "SCmdAccept");
sc_trace(vcd_log, SResp, "SResp");
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_trace_file *wif_log = sc_create_wif_trace_file("USB_TEST");
sc_trace(wif_log, clk2, "Clk");
sc_trace(wif_log, rst, "Reset_n");
sc_trace(wif_log, MAddr, "MAddr");
sc_trace(wif_log, MCmd, "MCmd");
sc_trace(wif_log, MData, "MData");
sc_trace(wif_log, SData, "SData");
sc_trace(wif_log, SCmdAccept, "SCmdAccept");
sc_trace(wif_log, SResp, "SResp");
#endif
 
srand((unsigned int)(time(NULL) & 0xffffffff));
sc_start();
 
#ifdef VCD_OUTPUT_ENABLE
sc_close_vcd_trace_file(vcd_log);
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_close_wif_trace_file(wif_log);
#endif
 
return 0;
}
 
/trunk/bench/systemc/README
0,0 → 1,8
These files already are in 'rtl/systemc'.
The 'usb_ocp_test.cpp' file is the USB1.1 with OCP Interface test.
The 'usb_8051_test.cpp' file is the USB1.1 with 8051 Interface test (incomplete).
 
See http://www.ocpip.org
 
----------------------------
alfoltran@opencores.org
/trunk/bench/verilog/test_bench_8051_top.v
0,0 → 1,273
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 Top Level Test Bench - 8051 Interface ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// Modifications: Alfredo Luiz Foltran Fialho ////
//// alfoltran@opencores.org ////
//// ////
//// 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 "timescale.v"
`include "usb_defines.v"
`include "usb_top.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;
 
reg [7:0] ep_f_din;
wire [7:0] ep_f_dout;
reg ep_f_re;
reg ep_f_we;
wire ep_f_empty;
wire ep_f_full;
 
reg [7:0] ep_f_addr;
reg cs;
 
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;
ep_f_we=0;
ep_f_re=0;
cs=1;
ep_f_addr=8'h00;
 
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
setup0;
in1;
out2;
in3;
out4;
in5;
out6;
end
else
if(1)
begin
setup0;
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;
 
usb_top u0( .clk_i( clk2 ),
.rst_i( rst ),
 
// USB Misc
.usb_rst( ),
 
// USB Status
.usb_busy( ),
.ep_sel( ),
 
// Interrupts
.crc16_err( ),
 
// Vendor Features
.v_set_int( ),
.v_set_feature( ),
 
// 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 ),
 
// ENDPOINTS Interface
.din( ep_f_din ),
.dout( ep_f_dout ),
.re( ep_f_re ),
.we( ep_f_we ),
.empty( ep_f_empty ),
.full( ep_f_full ),
 
// 8051 Interface
.adr( ep_f_addr ),
.cs( cs )
);
 
///////////////////////////////////////////////////////////////////
//
// Test and test lib Includes
//
`include "tests_lib.v"
`include "tests.v"
 
endmodule
 
/trunk/bench/verilog/test_bench_ocp_top.v
0,0 → 1,256
////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 Top Level Test Bench - OCP Interface ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// Modifications: Alfredo Luiz Foltran Fialho ////
//// alfoltran@opencores.org ////
//// ////
//// 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 "timescale.v"
`include "usb_defines.v"
`include "usb_ocp.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;
 
reg [7:0] ep_f_din;
wire [7:0] ep_f_dout;
reg [2:0] cmd;
 
reg [31:0] ep_f_addr;
 
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 [7:0] flags;
 
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;
cmd=3'b100;
ep_f_addr=32'h00;
 
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
setup0;
in1;
out2;
in3;
out4;
in5;
out6;
end
else
if(1)
begin
setup0;
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;
 
usb_ocp u0( .Clk( clk2 ),
.Reset_n( rst ),
 
// USB Status
.SFlag( flags),
.SError( ),
 
// Interrupts
.SInterrupt( ),
 
// 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 ),
 
// OCP Interface
.MData( ep_f_din ),
.SData( ep_f_dout ),
.MCmd( cmd ),
.MAddr( ep_f_addr )
);
 
///////////////////////////////////////////////////////////////////
//
// Test and test lib Includes
//
`include "tests_lib.v"
`include "tests_ocp.v"
 
endmodule
 
/trunk/bench/verilog/tests.v
0,0 → 1,1104
/////////////////////////////////////////////////////////////////////
//// ////
//// Test Case Collection ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// Modifications: Alfredo Luiz Foltran Fialho ////
//// alfoltran@opencores.org ////
//// ////
//// 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 2004-05-10 19:23:26 alfoltran Exp $
//
// $Date: 2004-05-10 19:23:26 $
// $Revision: 1.1 $
// $Author: alfoltran $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.1 2002/09/25 06:10:10 rudi
// Added Test Bench
//
//
//
//
//
//
//
 
 
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 setup0;
 
begin
$display("\n\n");
$display("*****************************************************");
$display("*** CTRL ep test 0 ***");
$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'h12 // wLength
);
 
data_in( 8'h12, // Function Address
8'd18 // 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'h9 // wLength
);
 
data_in( 8'h12, // Function Address
8'd9 // 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'd060 // wLength
);
 
data_in( 8'h12, // Function Address
8'd060 // 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'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'h0301, // wValue
16'h0416, // wIndex
16'd026 // wLength
);
 
data_in( 8'h12, // Function Address
8'd026 // 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'h0416, // wIndex
16'd028 // wLength
);
 
data_in( 8'h12, // Function Address
8'd028 // 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'h0416, // wIndex
16'd054 // wLength
);
 
data_in( 8'h12, // Function Address
8'd054 // 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 in1;
 
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 1 ***");
$display("*****************************************************\n");
 
send_sof(11'h000 ); // Send SOF
 
pack_sz_max = 256;
pack_cnt_max = 4;
 
pid_cnt = 0;
my_fa = 7'h12;
 
ep_f_addr=8'h01;
cs=0;
 
for(pack_sz=0;pack_sz<=pack_sz_max;pack_sz=pack_sz+32)
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(ep_f_full) @(posedge clk);
#1;
//x = fc[7:0];
x = $random;
ep_f_din = x;
buffer0[fc] = x;
ep_f_we = 1;
@(posedge clk);
#1;
ep_f_we = 0;
@(posedge clk);
end
#1;
ep_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);
 
// 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, x, buffer1[fc], $time);
error_cnt = error_cnt + 1;
end
end
end
 
repeat(50) @(posedge clk);
end
 
cs=1;
ep_f_addr=8'h00;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
 
end
 
endtask
 
task out2;
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 2 ***");
$display("*****************************************************\n");
 
 
no_pack_max = 4; // Number Of packets to transfer
pl_sz_max = 256; // Payload Size
 
no_pack = 4; // Number Of packets to transfer
pl_sz = 0;
my_fa = 7'h12;
 
ep_f_addr=8'h02;
cs=0;
 
for(pl_sz=0;pl_sz<=pl_sz_max;pl_sz=pl_sz+32)
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
2, // 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);
end
 
begin
repeat(10) @(posedge clk2);
for(n=0;n<(no_pack_max*pl_sz);n=n+1) // Compare Buffers
begin
#4;
ep_f_re = 0;
repeat(1) @(posedge clk2);
 
while(ep_f_empty)
begin
ep_f_re = 0;
repeat(2) @(posedge clk2);
end
 
#2;
if(buffer1[n] !== ep_f_dout)
begin
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)",
ep_f_dout, buffer1[n], $time);
error_cnt = error_cnt + 1;
end
ep_f_re = 1;
@(posedge clk2);
end
#1;
ep_f_re = 0;
@(posedge clk2);
end
 
join
 
repeat(1) @(posedge clk);
end
 
cs=1;
ep_f_addr=8'h00;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
end
endtask
 
task in3;
 
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 3 ***");
$display("*****************************************************\n");
 
send_sof(11'h000 ); // Send SOF
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = 0;
my_fa = 7'h12;
 
ep_f_addr=8'h03;
cs=0;
 
for(pack_sz=0;pack_sz<=pack_sz_max;pack_sz=pack_sz+8)
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(ep_f_full) @(posedge clk);
#1;
//x = fc[7:0];
x = $random;
ep_f_din = x;
buffer0[fc] = x;
ep_f_we = 1;
@(posedge clk);
#1;
ep_f_we = 0;
@(posedge clk);
end
#1;
ep_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
3, // 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;
 
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
3, // 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, x, buffer1[fc], $time);
error_cnt = error_cnt + 1;
end
end
end
 
repeat(50) @(posedge clk);
end
 
cs=1;
ep_f_addr=8'h00;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
 
end
 
endtask
 
task out4;
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 4 ***");
$display("*****************************************************\n");
 
 
no_pack_max = 4; // Number Of packets to transfer
pl_sz_max = 64; // Payload Size
 
no_pack = 4; // Number Of packets to transfer
pl_sz = 0;
my_fa = 7'h12;
 
ep_f_addr=8'h04;
cs=0;
 
for(pl_sz=0;pl_sz<=pl_sz_max;pl_sz=pl_sz+8)
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
 
if(len != 1)
begin
$display("ERROR: Size mismatch. Expected: %d, Got: %d (%t)",
pl_sz, len, $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;
ep_f_re = 0;
repeat(1) @(posedge clk2);
 
while(ep_f_empty)
begin
ep_f_re = 0;
repeat(2) @(posedge clk2);
end
 
#2;
if(buffer1[n] !== ep_f_dout)
begin
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)",
ep_f_dout, buffer1[n], $time);
error_cnt = error_cnt + 1;
end
ep_f_re = 1;
@(posedge clk2);
end
#1;
ep_f_re = 0;
@(posedge clk2);
end
 
join
 
repeat(1) @(posedge clk);
end
 
cs=1;
ep_f_addr=8'h00;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
end
endtask
 
task in5;
 
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 5 ***");
$display("*****************************************************\n");
 
send_sof(11'h000 ); // Send SOF
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = 0;
my_fa = 7'h12;
 
ep_f_addr=8'h05;
cs=0;
 
for(pack_sz=0;pack_sz<=pack_sz_max;pack_sz=pack_sz+8)
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(ep_f_full) @(posedge clk);
#1;
//x = fc[7:0];
x = $random;
ep_f_din = x;
buffer0[fc] = x;
ep_f_we = 1;
@(posedge clk);
#1;
ep_f_we = 0;
@(posedge clk);
end
#1;
ep_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
5, // Logical Endpoint Number
`USBF_T_PID_IN // PID
);
 
repeat(1) @(posedge clk);
 
recv_packet(pid,rlen);
 
if (pack_sz == 0) expect_pid = 4'ha;
else if(pid_cnt) expect_pid = 4'hb;
else 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
5, // 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, x, buffer1[fc], $time);
error_cnt = error_cnt + 1;
end
end
end
 
repeat(50) @(posedge clk);
end
 
cs=1;
ep_f_addr=8'h00;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
 
end
 
endtask
 
task out6;
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 6 ***");
$display("*****************************************************\n");
 
 
no_pack_max = 4; // Number Of packets to transfer
pl_sz_max = 64; // Payload Size
 
no_pack = 4; // Number Of packets to transfer
pl_sz = 0;
my_fa = 7'h12;
 
ep_f_addr=8'h06;
cs=0;
 
for(pl_sz=0;pl_sz<=pl_sz_max;pl_sz=pl_sz+8)
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
6, // 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
 
if(len != 1)
begin
$display("ERROR: Size mismatch. Expected: %d, Got: %d (%t)",
pl_sz, len, $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;
ep_f_re = 0;
repeat(1) @(posedge clk2);
 
while(ep_f_empty)
begin
ep_f_re = 0;
repeat(2) @(posedge clk2);
end
 
#2;
if(buffer1[n] !== ep_f_dout)
begin
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)",
ep_f_dout, buffer1[n], $time);
error_cnt = error_cnt + 1;
end
ep_f_re = 1;
@(posedge clk2);
end
#1;
ep_f_re = 0;
@(posedge clk2);
end
 
join
 
repeat(1) @(posedge clk);
end
 
cs=1;
ep_f_addr=8'h00;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
end
endtask
 
/trunk/bench/verilog/tests_ocp.v
0,0 → 1,1104
/////////////////////////////////////////////////////////////////////
//// ////
//// Test Case Collection ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// Modifications: Alfredo Luiz Foltran Fialho ////
//// alfoltran@opencores.org ////
//// ////
//// 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_ocp.v,v 1.1 2004-05-10 19:23:26 alfoltran Exp $
//
// $Date: 2004-05-10 19:23:26 $
// $Revision: 1.1 $
// $Author: alfoltran $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.1 2002/09/25 06:10:10 rudi
// Added Test Bench
//
//
//
//
//
//
//
 
 
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 setup0;
 
begin
$display("\n\n");
$display("*****************************************************");
$display("*** CTRL ep test 0 ***");
$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'h12 // wLength
);
 
data_in( 8'h12, // Function Address
8'd18 // 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'h9 // wLength
);
 
data_in( 8'h12, // Function Address
8'd9 // 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'd060 // wLength
);
 
data_in( 8'h12, // Function Address
8'd060 // 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'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'h0301, // wValue
16'h0416, // wIndex
16'd026 // wLength
);
 
data_in( 8'h12, // Function Address
8'd026 // 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'h0416, // wIndex
16'd028 // wLength
);
 
data_in( 8'h12, // Function Address
8'd028 // 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'h0416, // wIndex
16'd054 // wLength
);
 
data_in( 8'h12, // Function Address
8'd054 // 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 in1;
 
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 1 ***");
$display("*****************************************************\n");
 
send_sof(11'h000 ); // Send SOF
 
pack_sz_max = 256;
pack_cnt_max = 4;
 
pid_cnt = 0;
my_fa = 7'h12;
 
ep_f_addr=32'h01;
cmd=3'b000;
 
for(pack_sz=0;pack_sz<=pack_sz_max;pack_sz=pack_sz+32)
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(flags[1]) @(posedge clk);
#1;
//x = fc[7:0];
x = $random;
ep_f_din = x;
buffer0[fc] = x;
cmd = 3'b001;
@(posedge clk);
#1;
cmd = 3'b000;
@(posedge clk);
end
#1;
cmd = 3'b000;
@(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);
 
// 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, x, buffer1[fc], $time);
error_cnt = error_cnt + 1;
end
end
end
 
repeat(50) @(posedge clk);
end
 
cmd = 100;
ep_f_addr=32'h0;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
 
end
 
endtask
 
task out2;
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 2 ***");
$display("*****************************************************\n");
 
 
no_pack_max = 4; // Number Of packets to transfer
pl_sz_max = 256; // Payload Size
 
no_pack = 4; // Number Of packets to transfer
pl_sz = 0;
my_fa = 7'h12;
 
ep_f_addr=32'h02;
cmd=3'b000;
 
for(pl_sz=0;pl_sz<=pl_sz_max;pl_sz=pl_sz+32)
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
2, // 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);
end
 
begin
repeat(10) @(posedge clk2);
for(n=0;n<(no_pack_max*pl_sz);n=n+1) // Compare Buffers
begin
#4;
cmd = 3'b000;
repeat(1) @(posedge clk2);
 
while(flags[0])
begin
cmd = 3'b000;
repeat(2) @(posedge clk2);
end
 
#2;
if(buffer1[n] !== ep_f_dout)
begin
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)",
ep_f_dout, buffer1[n], $time);
error_cnt = error_cnt + 1;
end
cmd = 3'b010;
@(posedge clk2);
end
#1;
cmd = 3'b000;
@(posedge clk2);
end
 
join
 
repeat(1) @(posedge clk);
end
 
cmd = 3'b100;
ep_f_addr=32'h0;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
end
endtask
 
task in3;
 
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 3 ***");
$display("*****************************************************\n");
 
send_sof(11'h000 ); // Send SOF
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = 0;
my_fa = 7'h12;
 
ep_f_addr=32'h03;
cmd=3'b000;
 
for(pack_sz=0;pack_sz<=pack_sz_max;pack_sz=pack_sz+8)
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(flags[1]) @(posedge clk);
#1;
//x = fc[7:0];
x = $random;
ep_f_din = x;
buffer0[fc] = x;
cmd = 3'b001;
@(posedge clk);
#1;
cmd = 3'b000;
@(posedge clk);
end
#1;
cmd = 3'b000;
@(posedge clk);
 
// Send Data
repeat(1) @(posedge clk);
send_sof(11'h000 ); // Send SOF
repeat(1) @(posedge clk);
send_token( my_fa, // Function Address
3, // 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;
 
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
3, // 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, x, buffer1[fc], $time);
error_cnt = error_cnt + 1;
end
end
end
 
repeat(50) @(posedge clk);
end
 
cmd = 3'b100;
ep_f_addr=32'h0;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
 
end
 
endtask
 
task out4;
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 4 ***");
$display("*****************************************************\n");
 
 
no_pack_max = 4; // Number Of packets to transfer
pl_sz_max = 64; // Payload Size
 
no_pack = 4; // Number Of packets to transfer
pl_sz = 0;
my_fa = 7'h12;
 
ep_f_addr=32'h04;
cmd=3'b000;
 
for(pl_sz=0;pl_sz<=pl_sz_max;pl_sz=pl_sz+8)
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
 
if(len != 1)
begin
$display("ERROR: Size mismatch. Expected: %d, Got: %d (%t)",
pl_sz, len, $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;
cmd = 3'b000;
repeat(1) @(posedge clk2);
 
while(flags[0])
begin
cmd = 3'b000;
repeat(2) @(posedge clk2);
end
 
#2;
if(buffer1[n] !== ep_f_dout)
begin
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)",
ep_f_dout, buffer1[n], $time);
error_cnt = error_cnt + 1;
end
cmd = 3'b010;
@(posedge clk2);
end
#1;
cmd = 3'b000;
@(posedge clk2);
end
 
join
 
repeat(1) @(posedge clk);
end
 
cmd=3'b100;
ep_f_addr=32'h0;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
end
endtask
 
task in5;
 
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 5 ***");
$display("*****************************************************\n");
 
send_sof(11'h000 ); // Send SOF
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = 0;
my_fa = 7'h12;
 
ep_f_addr=32'h05;
cmd=3'b000;
 
for(pack_sz=0;pack_sz<=pack_sz_max;pack_sz=pack_sz+8)
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(flags[1]) @(posedge clk);
#1;
//x = fc[7:0];
x = $random;
ep_f_din = x;
buffer0[fc] = x;
cmd = 3'b001;
@(posedge clk);
#1;
cmd = 3'b000;
@(posedge clk);
end
#1;
cmd = 3'b000;
@(posedge clk);
 
// Send Data
repeat(1) @(posedge clk);
send_sof(11'h000 ); // Send SOF
repeat(1) @(posedge clk);
send_token( my_fa, // Function Address
5, // Logical Endpoint Number
`USBF_T_PID_IN // PID
);
 
repeat(1) @(posedge clk);
 
recv_packet(pid,rlen);
 
if (pack_sz == 0) expect_pid = 4'ha;
else if(pid_cnt) expect_pid = 4'hb;
else 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
5, // 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, x, buffer1[fc], $time);
error_cnt = error_cnt + 1;
end
end
end
 
repeat(50) @(posedge clk);
end
 
cmd=3'b100;
ep_f_addr=32'h0;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
 
end
 
endtask
 
task out6;
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 6 ***");
$display("*****************************************************\n");
 
 
no_pack_max = 4; // Number Of packets to transfer
pl_sz_max = 64; // Payload Size
 
no_pack = 4; // Number Of packets to transfer
pl_sz = 0;
my_fa = 7'h12;
 
ep_f_addr=32'h06;
cmd=3'b000;
 
for(pl_sz=0;pl_sz<=pl_sz_max;pl_sz=pl_sz+8)
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
6, // 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
 
if(len != 1)
begin
$display("ERROR: Size mismatch. Expected: %d, Got: %d (%t)",
pl_sz, len, $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;
cmd = 3'b000;
repeat(1) @(posedge clk2);
 
while(flags[0])
begin
cmd = 3'b000;
repeat(2) @(posedge clk2);
end
 
#2;
if(buffer1[n] !== ep_f_dout)
begin
$display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)",
ep_f_dout, buffer1[n], $time);
error_cnt = error_cnt + 1;
end
cmd = 3'b010;
@(posedge clk2);
end
#1;
cmd = 3'b000;
@(posedge clk2);
end
 
join
 
repeat(1) @(posedge clk);
end
 
cmd=3'b100;
ep_f_addr=8'h0;
 
show_errors;
$display("*****************************************************");
$display("*** Test DONE ... ***");
$display("*****************************************************\n\n");
end
endtask
 
/trunk/bench/verilog/tests_lib.v
0,0 → 1,384
/////////////////////////////////////////////////////////////////////
//// ////
//// Test Bench Library ////
//// ////
//// ////
//// Author: Rudolf Usselmann ////
//// rudi@asics.ws ////
//// ////
//// Modifications: Alfredo Luiz Foltran Fialho ////
//// alfoltran@opencores.org ////
//// ////
//// 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 2004-05-10 19:23:26 alfoltran Exp $
//
// $Date: 2004-05-10 19:23:26 $
// $Revision: 1.1 $
// $Author: alfoltran $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.1 2002/09/25 06:10:10 rudi
// Added Test Bench
//
//
//
//
//
//
//
 
 
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);
 
if (size != 1)
begin
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;
 
end
else size = 3;
 
// 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
 
/trunk/bench/verilog/README
0,0 → 1,4
These files may be used to test the Verilog files generated by Synopsys CoCentric SystemC Compiler.
 
----------------------------
alfoltran@opencores.org
/trunk/rtl/systemc/usb.h
0,0 → 1,347
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 ////
//// Endpoints Config and FIFOs Instantiation ////
//// ////
//// SystemC Version: usb.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_H
#define USB_H
 
#include "systemc.h"
#include "usb_defines.h"
#include "usb_core.h"
#include "usb_fifo512x8.h"
#include "usb_fifo128x8.h"
 
SC_MODULE(usb) {
 
private:
 
sc_signal<bool> vcc, gnd;
sc_signal<sc_uint<8> > gnd8;
sc_signal<sc_uint<14> > cfg1, cfg2, cfg3, cfg4, cfg5, cfg6, cfg7;
sc_signal<bool> ep1_we_nc, ep2_re_nc, ep3_we_nc, ep4_re_nc, ep5_we_nc, ep6_re_nc, ep7_we_nc, ep7_re_nc;
sc_signal<sc_uint<8> > ep1_dout_nc, ep3_dout_nc, ep5_dout_nc, ep7_dout_nc;
 
public:
 
sc_in<bool> clk_i;
sc_in<bool> rst_i;
 
// PHY Interface
sc_out<bool> tx_dp, tx_dn, tx_oe;
sc_in<bool> rx_dp, rx_dn, rx_d;
sc_in<bool> phy_tx_mode;
 
// Misc
sc_out<bool> usb_rst;
 
// Interrupts
sc_out<bool> crc16_err;
 
// Vendor Features
sc_out<bool> v_set_int;
sc_out<bool> v_set_feature;
sc_out<sc_uint<16> > wValue;
sc_out<sc_uint<16> > wIndex;
sc_in<sc_uint<16> > vendor_data;
 
// USB Status
sc_out<bool> usb_busy;
sc_out<sc_uint<4> > ep_sel;
 
// Endpoint Interface
// EP1
sc_in<sc_uint<8> > ep1_f_din;
sc_in<bool> ep1_f_we;
sc_out<bool> ep1_f_full;
 
// EP2
sc_out<sc_uint<8> > ep2_f_dout;
sc_in<bool> ep2_f_re;
sc_out<bool> ep2_f_empty;
 
// EP3
sc_in<sc_uint<8> > ep3_f_din;
sc_in<bool> ep3_f_we;
sc_out<bool> ep3_f_full;
 
// EP4
sc_out<sc_uint<8> > ep4_f_dout;
sc_in<bool> ep4_f_re;
sc_out<bool> ep4_f_empty;
 
// EP5
sc_in<sc_uint<8> > ep5_f_din;
sc_in<bool> ep5_f_we;
sc_out<bool> ep5_f_full;
 
// EP6
sc_out<sc_uint<8> > ep6_f_dout;
sc_in<bool> ep6_f_re;
sc_out<bool> ep6_f_empty;
 
// Local Signals
// EP1
sc_signal<sc_uint<8> > ep1_us_din;
sc_signal<bool> ep1_us_re;
sc_signal<bool> ep1_us_empty;
 
// EP2
sc_signal<sc_uint<8> > ep2_us_dout;
sc_signal<bool> ep2_us_we;
sc_signal<bool> ep2_us_full;
 
// EP3
sc_signal<sc_uint<8> > ep3_us_din;
sc_signal<bool> ep3_us_re;
sc_signal<bool> ep3_us_empty;
 
// EP4
sc_signal<sc_uint<8> > ep4_us_dout;
sc_signal<bool> ep4_us_we;
sc_signal<bool> ep4_us_full;
 
// EP5
sc_signal<sc_uint<8> > ep5_us_din;
sc_signal<bool> ep5_us_re;
sc_signal<bool> ep5_us_empty;
 
// EP6
sc_signal<sc_uint<8> > ep6_us_dout;
sc_signal<bool> ep6_us_we;
sc_signal<bool> ep6_us_full;
 
usb_core *i_core; // CORE
usb_fifo512x8 *i_ff_ep1; // FIFO1
usb_fifo512x8 *i_ff_ep2; // FIFO2
usb_fifo128x8 *i_ff_ep3; // FIFO3
usb_fifo128x8 *i_ff_ep4; // FIFO4
usb_fifo128x8 *i_ff_ep5; // FIFO5
usb_fifo128x8 *i_ff_ep6; // FIFO6
/*
// Destructor
~usb(void) {
if (i_core)
delete i_core;
if (i_ff_ep1)
delete i_ff_ep1;
if (i_ff_ep2)
delete i_ff_ep2;
if (i_ff_ep3)
delete i_ff_ep3;
if (i_ff_ep4)
delete i_ff_ep4;
if (i_ff_ep5)
delete i_ff_ep5;
if (i_ff_ep6)
delete i_ff_ep6;
}
*/
SC_CTOR(usb) {
vcc.write(true);
gnd.write(false);
gnd8.write(0);
 
cfg1.write(ISO | IN | 256);
cfg2.write(ISO | OUT | 256);
cfg3.write(BULK | IN | 64);
cfg4.write(BULK | OUT | 64);
cfg5.write(INT | IN | 64);
cfg6.write(INT | OUT | 64);
cfg7.write(0);
 
// CORE Instantiation and Binding
i_core = new usb_core("CORE");
i_core->clk_i(clk_i);
i_core->rst_i(rst_i);
i_core->tx_dp(tx_dp);
i_core->tx_dn(tx_dn);
i_core->tx_oe(tx_oe);
i_core->rx_dp(rx_dp);
i_core->rx_dn(rx_dn);
i_core->rx_d(rx_d);
i_core->phy_tx_mode(vcc);
i_core->usb_rst(usb_rst);
i_core->crc16_err(crc16_err);
i_core->v_set_int(v_set_int);
i_core->v_set_feature(v_set_feature);
i_core->wValue(wValue);
i_core->wIndex(wIndex);
i_core->vendor_data(vendor_data);
i_core->usb_busy(usb_busy);
i_core->ep_sel(ep_sel);
 
// EP1 -> ISO IN 256
i_core->ep1_cfg(cfg1);
i_core->ep1_din(ep1_us_din);
i_core->ep1_dout(ep1_dout_nc);
i_core->ep1_we(ep1_we_nc);
i_core->ep1_re(ep1_us_re);
i_core->ep1_empty(ep1_us_empty);
i_core->ep1_full(gnd);
 
// EP2 -> ISO OUT 256
i_core->ep2_cfg(cfg2);
i_core->ep2_din(gnd8);
i_core->ep2_dout(ep2_us_dout);
i_core->ep2_we(ep2_us_we);
i_core->ep2_re(ep2_re_nc);
i_core->ep2_empty(gnd);
i_core->ep2_full(ep2_us_full);
 
// EP3 -> BULK IN 64
i_core->ep3_cfg(cfg3);
i_core->ep3_din(ep3_us_din);
i_core->ep3_dout(ep3_dout_nc);
i_core->ep3_we(ep3_we_nc);
i_core->ep3_re(ep3_us_re);
i_core->ep3_empty(ep3_us_empty);
i_core->ep3_full(gnd);
 
// EP4 -> BULK OUT 64
i_core->ep4_cfg(cfg4);
i_core->ep4_din(gnd8);
i_core->ep4_dout(ep4_us_dout);
i_core->ep4_we(ep4_us_we);
i_core->ep4_re(ep4_re_nc);
i_core->ep4_empty(gnd);
i_core->ep4_full(ep4_us_full);
 
// EP5 -> INT IN 64
i_core->ep5_cfg(cfg5);
i_core->ep5_din(ep5_us_din);
i_core->ep5_dout(ep5_dout_nc);
i_core->ep5_we(ep5_we_nc);
i_core->ep5_re(ep5_us_re);
i_core->ep5_empty(ep5_us_empty);
i_core->ep5_full(gnd);
 
// EP6 -> INT OUT 64
i_core->ep6_cfg(cfg6);
i_core->ep6_din(gnd8);
i_core->ep6_dout(ep6_us_dout);
i_core->ep6_we(ep6_us_we);
i_core->ep6_re(ep6_re_nc);
i_core->ep6_empty(gnd);
i_core->ep6_full(ep6_us_full);
 
// EP7 -> DEAD
i_core->ep7_cfg(cfg7);
i_core->ep7_din(gnd8);
i_core->ep7_dout(ep7_dout_nc);
i_core->ep7_we(ep7_we_nc);
i_core->ep7_re(ep7_re_nc);
i_core->ep7_empty(gnd);
i_core->ep7_full(gnd);
 
// FIFO1 Instantiation and Binding
i_ff_ep1 = new usb_fifo512x8("FIFO1");
i_ff_ep1->clk(clk_i);
i_ff_ep1->rst(rst_i);
i_ff_ep1->clr(gnd);
i_ff_ep1->we(ep1_f_we);
i_ff_ep1->din(ep1_f_din);
i_ff_ep1->re(ep1_us_re);
i_ff_ep1->dout(ep1_us_din);
i_ff_ep1->empty(ep1_us_empty);
i_ff_ep1->full(ep1_f_full);
 
// FIFO2 Instantiation and Binding
i_ff_ep2 = new usb_fifo512x8("FIFO2");
i_ff_ep2->clk(clk_i);
i_ff_ep2->rst(rst_i);
i_ff_ep2->clr(gnd);
i_ff_ep2->we(ep2_us_we);
i_ff_ep2->din(ep2_us_dout);
i_ff_ep2->re(ep2_f_re);
i_ff_ep2->dout(ep2_f_dout);
i_ff_ep2->empty(ep2_f_empty);
i_ff_ep2->full(ep2_us_full);
 
// FIFO3 Instantiation and Binding
i_ff_ep3 = new usb_fifo128x8("FIFO3");
i_ff_ep3->clk(clk_i);
i_ff_ep3->rst(rst_i);
i_ff_ep3->clr(gnd);
i_ff_ep3->we(ep3_f_we);
i_ff_ep3->din(ep3_f_din);
i_ff_ep3->re(ep3_us_re);
i_ff_ep3->dout(ep3_us_din);
i_ff_ep3->empty(ep3_us_empty);
i_ff_ep3->full(ep3_f_full);
 
// FIFO4 Instantiation and Binding
i_ff_ep4 = new usb_fifo128x8("FIFO4");
i_ff_ep4->clk(clk_i);
i_ff_ep4->rst(rst_i);
i_ff_ep4->clr(gnd);
i_ff_ep4->we(ep4_us_we);
i_ff_ep4->din(ep4_us_dout);
i_ff_ep4->re(ep4_f_re);
i_ff_ep4->dout(ep4_f_dout);
i_ff_ep4->empty(ep4_f_empty);
i_ff_ep4->full(ep4_us_full);
 
// FIFO5 Instantiation and Binding
i_ff_ep5 = new usb_fifo128x8("FIFO5");
i_ff_ep5->clk(clk_i);
i_ff_ep5->rst(rst_i);
i_ff_ep5->clr(gnd);
i_ff_ep5->we(ep5_f_we);
i_ff_ep5->din(ep5_f_din);
i_ff_ep5->re(ep5_us_re);
i_ff_ep5->dout(ep5_us_din);
i_ff_ep5->empty(ep5_us_empty);
i_ff_ep5->full(ep5_f_full);
 
// FIFO6 Instantiation and Binding
i_ff_ep6 = new usb_fifo128x8("FIFO6");
i_ff_ep6->clk(clk_i);
i_ff_ep6->rst(rst_i);
i_ff_ep6->clr(gnd);
i_ff_ep6->we(ep6_us_we);
i_ff_ep6->din(ep6_us_dout);
i_ff_ep6->re(ep6_f_re);
i_ff_ep6->dout(ep6_f_dout);
i_ff_ep6->empty(ep6_f_empty);
i_ff_ep6->full(ep6_us_full);
 
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_ram512x8.cpp
0,0 → 1,53
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RAM ////
//// ////
//// SystemC Version: usb_ram512x8.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_dpram.v ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// www.opencores.org ////
//// ////
//// 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 "systemc.h"
#include "usb_ram512x8.h"
 
void usb_ram512x8::dout_update(void) {
dout.write((oe.read() && rce.read()) ? dout_reg.read() : (sc_uint<8>)0);
}
 
void usb_ram512x8::read(void) {
if (rce.read())
dout_reg.write(mem[raddr.read()]);
}
 
void usb_ram512x8::write(void) {
if (wce.read() && we.read())
mem[waddr.read()] = din.read();
}
 
/trunk/rtl/systemc/Makefile.usb_8051
0,0 → 1,15
TARGET_ARCH = linux
 
CC = g++
OPT = -O3 -mcpu=pentiumpro
DEBUG = -g
OTHER = -Wall -Wno-deprecated
EXTRA_CFLAGS = $(OPT) $(OTHER)
# EXTRA_CFLAGS = $(DEBUG) $(OTHER)
 
MODULE = usb
SRCS = usb_test.cpp usb_top.cpp usb_core.cpp usb_fifo512x8.cpp usb_fifo128x8.cpp usb_fifo64x8.cpp usb_ram512x8.cpp usb_ram128x8.cpp usb_ram64x8.cpp usb_phy.cpp usb_tx_phy.cpp usb_rx_phy.cpp usb_sie.cpp usb_pa_sie.cpp usb_pd_sie.cpp usb_pe_sie.cpp usb_dma.cpp usb_fifo2.cpp usb_ep0.cpp usb_crc5.cpp usb_crc16.cpp
OBJS = $(SRCS:.cpp=.o)
 
include Makefile.defs
 
/trunk/rtl/systemc/usb_core.cpp
0,0 → 1,152
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 ////
//// Function IP Core ////
//// ////
//// SystemC Version: usb_core.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_core.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 "systemc.h"
#include "usb_core.h"
 
void usb_core::rst_local_up(void) {
rst_local.write(rst_i.read() && !usb_rst.read());
}
 
void usb_core::stat_up(void) {
ep0_ctrl_stat.write(((sc_uint<1>)0, (sc_uint<1>)stat2.read(), (sc_uint<1>)stat1.read(), (sc_uint<1>)0));
}
 
void usb_core::frame_no_up(void) {
frame_no.write(frm_nat.read().range(26, 16));
}
 
void usb_core::cfg_mux(void) {
switch (ep_sel.read()) {// synopsys full_case parallel_case
case 0: cfg.write(ep0_size.read() | CTRL); break;
case 1: cfg.write(ep1_cfg.read()); break;
case 2: cfg.write(ep2_cfg.read()); break;
case 3: cfg.write(ep3_cfg.read()); break;
case 4: cfg.write(ep4_cfg.read()); break;
case 5: cfg.write(ep5_cfg.read()); break;
case 6: cfg.write(ep6_cfg.read()); break;
case 7: cfg.write(ep7_cfg.read()); break;
}
}
 
void usb_core::tx_data_mux(void) {
switch (ep_sel.read()) {// synopsys full_case parallel_case
case 0: tx_data_st.write(ep0_dout.read()); break;
case 1: tx_data_st.write(ep1_din.read()); break;
case 2: tx_data_st.write(ep2_din.read()); break;
case 3: tx_data_st.write(ep3_din.read()); break;
case 4: tx_data_st.write(ep4_din.read()); break;
case 5: tx_data_st.write(ep5_din.read()); break;
case 6: tx_data_st.write(ep6_din.read()); break;
case 7: tx_data_st.write(ep7_din.read()); break;
}
}
 
void usb_core::ep_empty_mux(void) {
switch (ep_sel.read()) {// synopsys full_case parallel_case
case 0: ep_empty.write(ep0_empty.read()); break;
case 1: ep_empty.write(ep1_empty.read()); break;
case 2: ep_empty.write(ep2_empty.read()); break;
case 3: ep_empty.write(ep3_empty.read()); break;
case 4: ep_empty.write(ep4_empty.read()); break;
case 5: ep_empty.write(ep5_empty.read()); break;
case 6: ep_empty.write(ep6_empty.read()); break;
case 7: ep_empty.write(ep7_empty.read()); break;
}
}
 
void usb_core::ep_full_mux(void) {
switch (ep_sel.read()) {// synopsys full_case parallel_case
case 0: ep_full.write(ep0_full.read()); break;
case 1: ep_full.write(ep1_full.read()); break;
case 2: ep_full.write(ep2_full.read()); break;
case 3: ep_full.write(ep3_full.read()); break;
case 4: ep_full.write(ep4_full.read()); break;
case 5: ep_full.write(ep5_full.read()); break;
case 6: ep_full.write(ep6_full.read()); break;
case 7: ep_full.write(ep7_full.read()); break;
}
}
 
void usb_core::ep_dout_deco(void) {
ep1_dout.write(rx_data_st.read());
ep2_dout.write(rx_data_st.read());
ep3_dout.write(rx_data_st.read());
ep4_dout.write(rx_data_st.read());
ep5_dout.write(rx_data_st.read());
ep6_dout.write(rx_data_st.read());
ep7_dout.write(rx_data_st.read());
}
 
void usb_core::ep_re_deco(void) {
ep0_re.write(idma_re.read() && (ep_sel.read() == 0));
ep1_re.write(idma_re.read() && (ep_sel.read() == 1) && !ep1_empty.read());
ep2_re.write(idma_re.read() && (ep_sel.read() == 2) && !ep2_empty.read());
ep3_re.write(idma_re.read() && (ep_sel.read() == 3) && !ep3_empty.read());
ep4_re.write(idma_re.read() && (ep_sel.read() == 4) && !ep4_empty.read());
ep5_re.write(idma_re.read() && (ep_sel.read() == 5) && !ep5_empty.read());
ep6_re.write(idma_re.read() && (ep_sel.read() == 6) && !ep6_empty.read());
ep7_re.write(idma_re.read() && (ep_sel.read() == 7) && !ep7_empty.read());
}
 
void usb_core::ep_we_deco(void) {
ep0_we.write(idma_we.read() && (ep_sel.read() == 0));
ep1_we.write(idma_we.read() && (ep_sel.read() == 1) && !ep1_full.read());
ep2_we.write(idma_we.read() && (ep_sel.read() == 2) && !ep2_full.read());
ep3_we.write(idma_we.read() && (ep_sel.read() == 3) && !ep3_full.read());
ep4_we.write(idma_we.read() && (ep_sel.read() == 4) && !ep4_full.read());
ep5_we.write(idma_we.read() && (ep_sel.read() == 5) && !ep5_full.read());
ep6_we.write(idma_we.read() && (ep_sel.read() == 6) && !ep6_full.read());
ep7_we.write(idma_we.read() && (ep_sel.read() == 7) && !ep7_full.read());
}
/*
usb_core::~usb_core(void) {
if (i_phy)
delete i_phy;
if (i_sie)
delete i_sie;
if (i_ep0)
delete i_ep0;
if (i_rom)
delete i_rom;
if (i_ff_in)
delete i_ff_in;
if (i_ff_out)
delete i_ff_out;
}
*/
/trunk/rtl/systemc/usb_ep0.h
0,0 → 1,395
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Control Endpoint (Endpoint Zero) ////
//// Internal Setup Engine ////
//// ////
//// SystemC Version: usb_ep0.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_ctrl.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_EP0_H
#define USB_EP0_H
 
#include "usb_defines.h"
 
// State Decoding
enum EP0_STATE { EP0_IDLE = 1,
EP0_GET_HDR = 2,
EP0_GET_STATUS = 4,
EP0_CLEAR_FEATURE = 8,
EP0_SET_FEATURE = 16,
EP0_SET_ADDRESS = 32,
EP0_GET_DESCRIPTOR = 64,
EP0_SET_DESCRIPTOR = 128,
EP0_GET_CONFIG = 256,
EP0_SET_CONFIG = 512,
EP0_GET_INTERFACE = 1024,
EP0_SET_INTERFACE = 2048,
EP0_SYNCH_FRAME = 4096,
EP0_WAIT_IN_DATA = 8192,
EP0_STATUS_IN = 16384,
EP0_STATUS_OUT = 32768,
EP0_V_SET_INT = 65536,
EP0_V_GET_STATUS = 131072};
 
// Data Source (To Send to Host)
enum EP0_DATA_SOURCE { ZERO_DATA = 1,
ZERO_ONE_DATA = 2,
CONFIG_DATA = 4,
SYNC_FRAME_DATA = 8,
VEND_DATA = 16};
 
// Standard Request Codes
enum EP0_STD_REQUEST { GET_STATUS = 0,
CLEAR_FEATURE = 1,
// Reserved for future use
SET_FEATURE = 3,
// Reserved for future use
SET_ADDRESS = 5,
GET_DESCRIPTOR = 6,
SET_DESCRIPTOR = 7,
GET_CONFIG = 8,
SET_CONFIG = 9,
GET_INTERFACE = 10,
SET_INTERFACE = 11,
SYNCH_FRAME = 12,
V_SET_INT = 15};
 
SC_MODULE(usb_ep0) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
 
// ROM Interface
sc_out<sc_uint<8> > rom_adr;
sc_in<sc_uint<8> > rom_data;
 
// From PL
sc_in<bool> ctrl_setup;
sc_in<bool> ctrl_in;
sc_in<bool> ctrl_out;
sc_in<sc_uint<11> > frame_no;
 
// To PL
sc_out<bool> send_stall;
sc_out<sc_uint<7> > funct_adr;
sc_out<bool> addressed;
sc_out<bool> configured;
sc_out<bool> halt;
 
// FIFOs Interface
sc_in<sc_uint<8> > ep0_din;
sc_out<sc_uint<8> > ep0_dout;
sc_out<bool> ep0_re, ep0_we;
sc_in<sc_uint<4> > ep0_stat;
sc_out<sc_uint<8> > ep0_size;
 
// Function Interface
sc_out<bool> v_set_int;
sc_out<bool> v_set_feature;
sc_out<sc_uint<16> >wValue;
sc_out<sc_uint<16> >wIndex;
sc_in<sc_uint<16> > vendor_data;
 
// Local Signals
 
// Setup Data Fields
sc_signal<sc_uint<8> > bmReqType, bRequest;
sc_signal<sc_uint<16> > wLength;
sc_signal<bool> bm_req_dir;
sc_signal<sc_uint<2> > bm_req_type;
sc_signal<sc_uint<5> > bm_req_recp;
 
// Standard Device Requests - Status Registers
sc_signal<bool> get_status, clear_feature, set_feature, set_address;
sc_signal<bool> get_descriptor, set_descriptor, get_config, set_config;
sc_signal<bool> get_interface, set_interface, synch_frame;
sc_signal<bool> hdr_done_r, config_err;
sc_signal<bool> v_get_status;
 
// FIFOs Signals
sc_signal<bool> fifo_re1, fifo_full, fifo_empty;
sc_signal<bool> fifo_we_d;
sc_signal<sc_uint<5> > data_sel;
 
// EP0 FSM Signals
sc_signal<sc_uint<20> > state, next_state;
sc_signal<bool> get_hdr;
sc_signal<sc_uint<8> > le;
sc_signal<bool> hdr_done;
sc_signal<bool> adv;
sc_signal<sc_uint<8> > hdr0, hdr1, hdr2, hdr3, hdr4, hdr5, hdr6, hdr7;
sc_signal<bool> set_adr_pending;
sc_signal<sc_uint<7> > funct_adr_tmp;
sc_signal<bool> in_size_0, in_size_1, in_size_2;
sc_signal<bool> high_sel;
sc_signal<bool> write_done, write_done_r;
 
// Halt Signals
sc_signal<bool> clr_halt;
sc_signal<bool> set_halt;
 
// ROM Signals
sc_signal<bool> rom_sel, rom_sel_r;
sc_signal<bool> rom_done;
sc_signal<sc_uint<7> > rom_size, rom_size_d, rom_size_dd;
sc_signal<bool> fifo_we_rom, fifo_we_rom_r, fifo_we_rom_r2;
sc_signal<sc_uint<8> > rom_start_d;
 
// FIFOs Functions
void ep0_re_up(void);
void fifo_empty_up(void);
void fifo_full_up(void);
 
// Current State Functions
void clr_halt_up(void);
void addressed_up(void);
void configured_up(void);
void halt_up(void);
 
// ROM Functions
void rom_adr_up1(void);
void rom_adr_up2(void);
void rom_size_up1(void);
void rom_size_up2(void);
void rom_size_up3(void);
void rom_sel_up(void);
void fifo_we_rom_up1(void);
void fifo_we_rom_up2(void);
void fifo_we_rom_up3(void);
void rom_done_up(void);
 
// Get Header Functions
void fifo_re_up(void);
void adv_up(void);
void le_up(void);
void hdr_deco0(void);
void hdr_deco1(void);
void hdr_deco2(void);
void hdr_deco3(void);
void hdr_deco4(void);
void hdr_deco5(void);
void hdr_deco6(void);
void hdr_deco7(void);
void hdr_done_up(void);
 
// Send Data to Host Functions
void high_sel_up(void);
void ep0_dout_up(void);
void ep0_we_up(void);
void ep0_size_up(void);
void write_done_up1(void);
void write_done_up2(void);
 
// Header Decoder Functions
void bmReqType_up(void);
void bmReqType_Decoder(void);
void bRequest_up(void);
void wValue_up(void);
void wIndex_up(void);
void wLength_up(void);
void hdr_done_r_up(void);
void get_status_up(void);
void clear_feature_up(void);
void set_feature_up(void);
void set_address_up(void);
void get_descriptor_up(void);
void set_descriptor_up(void);
void get_config_up(void);
void set_config_up(void);
void get_interface_up(void);
void set_interface_up(void);
void synch_frame_up(void);
void v_set_int_up(void);
void v_set_feature_up(void);
void v_get_status_up(void);
void config_err_up(void);
void send_stall_up(void);
 
// Set Address Functions
void set_adr_pending_up(void);
void funct_adr_tmp_up(void);
void funct_adr_up(void);
 
// Control Pipe FSM Functions
void state_up(void);
void ep0_statemachine(void);
 
SC_CTOR(usb_ep0) {
set_halt.write(false);
 
SC_METHOD(ep0_re_up);
sensitive << fifo_re1;
SC_METHOD(fifo_empty_up);
sensitive << ep0_stat;
SC_METHOD(fifo_full_up);
sensitive << ep0_stat;
 
SC_METHOD(clr_halt_up);
sensitive << ctrl_setup;
SC_METHOD(addressed_up);
sensitive << clk.pos();
SC_METHOD(configured_up);
sensitive << clk.pos();
SC_METHOD(halt_up);
sensitive << clk.pos();
 
SC_METHOD(rom_adr_up1);
sensitive << wValue;
SC_METHOD(rom_adr_up2);
sensitive << clk.pos();
SC_METHOD(rom_size_up1);
sensitive << wValue;
SC_METHOD(rom_size_up2);
sensitive << rom_size_dd << wLength;
SC_METHOD(rom_size_up3);
sensitive << clk.pos();
SC_METHOD(rom_sel_up);
sensitive << clk.pos();
SC_METHOD(fifo_we_rom_up1);
sensitive << clk.pos();
SC_METHOD(fifo_we_rom_up2);
sensitive << clk.pos();
SC_METHOD(fifo_we_rom_up3);
sensitive << rom_sel << fifo_we_rom_r2;
SC_METHOD(rom_done_up);
sensitive << rom_size << rom_sel << rom_sel_r;
 
SC_METHOD(fifo_re_up);
sensitive << get_hdr << fifo_empty;
SC_METHOD(adv_up);
sensitive << clk.pos();
SC_METHOD(le_up);
sensitive << clk.pos();
SC_METHOD(hdr_deco0);
sensitive << clk.pos();
SC_METHOD(hdr_deco1);
sensitive << clk.pos();
SC_METHOD(hdr_deco2);
sensitive << clk.pos();
SC_METHOD(hdr_deco3);
sensitive << clk.pos();
SC_METHOD(hdr_deco4);
sensitive << clk.pos();
SC_METHOD(hdr_deco5);
sensitive << clk.pos();
SC_METHOD(hdr_deco6);
sensitive << clk.pos();
SC_METHOD(hdr_deco7);
sensitive << clk.pos();
SC_METHOD(hdr_done_up);
sensitive << le << adv;
 
SC_METHOD(high_sel_up);
sensitive << write_done_r;
SC_METHOD(ep0_dout_up);
sensitive << clk.pos();
SC_METHOD(ep0_we_up);
sensitive << clk.pos();
SC_METHOD(ep0_size_up);
sensitive << clk.pos();
SC_METHOD(write_done_up1);
sensitive << clk.pos();
SC_METHOD(write_done_up2);
sensitive << clk.pos();
 
SC_METHOD(bmReqType_up);
sensitive << hdr0;
SC_METHOD(bmReqType_Decoder);
sensitive << bmReqType;
SC_METHOD(bRequest_up);
sensitive << hdr1;
SC_METHOD(wValue_up);
sensitive << hdr2 << hdr3;
SC_METHOD(wIndex_up);
sensitive << hdr4 << hdr5;
SC_METHOD(wLength_up);
sensitive << hdr6 << hdr7;
SC_METHOD(hdr_done_r_up);
sensitive << clk.pos();
SC_METHOD(get_status_up);
sensitive << clk.pos();
SC_METHOD(clear_feature_up);
sensitive << clk.pos();
SC_METHOD(set_feature_up);
sensitive << clk.pos();
SC_METHOD(set_address_up);
sensitive << clk.pos();
SC_METHOD(get_descriptor_up);
sensitive << clk.pos();
SC_METHOD(set_descriptor_up);
sensitive << clk.pos();
SC_METHOD(get_config_up);
sensitive << clk.pos();
SC_METHOD(set_config_up);
sensitive << clk.pos();
SC_METHOD(set_interface_up);
sensitive << clk.pos();
SC_METHOD(get_interface_up);
sensitive << clk.pos();
SC_METHOD(synch_frame_up);
sensitive << clk.pos();
SC_METHOD(v_set_int_up);
sensitive << clk.pos();
SC_METHOD(v_set_feature_up);
sensitive << clk.pos();
SC_METHOD(v_get_status_up);
sensitive << clk.pos();
SC_METHOD(config_err_up);
sensitive << clk.pos();
SC_METHOD(send_stall_up);
sensitive << clk.pos();
 
SC_METHOD(set_adr_pending_up);
sensitive << clk.pos();
SC_METHOD(funct_adr_tmp_up);
sensitive << clk.pos();
SC_METHOD(funct_adr_up);
sensitive << clk.pos();
 
SC_METHOD(state_up);
sensitive << clk.pos();
SC_METHOD(ep0_statemachine);
sensitive << state << ctrl_setup << ctrl_in << ctrl_out;
sensitive << hdr_done << fifo_full << rom_done << write_done_r;
sensitive << wValue << bm_req_recp << get_status << clear_feature;
sensitive << set_feature << set_address << get_descriptor << set_descriptor;
sensitive << get_config << set_config << get_interface << set_interface;
sensitive << synch_frame << v_set_int << v_set_feature << v_get_status;
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_8051_test.cpp
0,0 → 1,167
/////////////////////////////////////////////////////////////////////
//// ////
//// 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 ////
//// 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 "systemc.h"
#include "usb_phy.h"
#include "usb_top.h"
 
#define VCD_OUTPUT_ENABLE
//#define WIF_OUTPUT_ENABLE
 
SC_MODULE(test) {
sc_in<bool> clk, clk2;
sc_out<bool> rst;
 
int i;
 
void update(void) {
rst.write(false);
for (i = 0; i < 10; i++) wait(clk.posedge_event());
rst.write(true);
for (i = 0; i < 500; i++) wait(clk.posedge_event());
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive_pos(clk);
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.84, SC_NS);
sc_clock clk2("clock2", 20.84, SC_NS);
 
sc_signal<bool> rst, vcc;
 
sc_signal<bool> rx_dp1, rx_dn1, tx_dp1, tx_dn1;
sc_signal<bool> tb_rx_valid, tb_rx_active, tb_rx_error;
sc_signal<bool> tb_tx_valid, tb_tx_ready;
sc_signal<sc_uint<8> > tb_rx_data, tb_tx_data;
 
sc_signal<bool> rx_dp2, rx_dn2, tx_dp2, tx_dn2;
sc_signal<sc_uint<8> > ep_f_din;
sc_signal_rv<8> ep_f_dout;
sc_signal<sc_uint<8> > ep_f_adr;
sc_signal<bool> cs, ep_f_re, ep_f_we, ep_f_empty, ep_f_full;
 
sc_signal<bool> usb_rst_nc, txoe_nc;
sc_signal<sc_uint<2> > line_nc;
 
sc_signal<bool> rst_nc, tx_oe_nc, crc16_nc, int_nc, feature_nc, busy_nc;
sc_signal<sc_uint<4> > sel_nc;
 
usb_phy i_phy("HOST_PHY");
usb_top i_top("USB_TOP");
test i_test("TEST");
 
i_phy.clk(clk);
i_phy.rst(rst);
i_phy.phy_tx_mode(vcc);
i_phy.usb_rst(usb_rst_nc);
i_phy.txdp(tx_dp1);
i_phy.txdn(tx_dn1);
i_phy.txoe(txoe_nc);
i_phy.rxd(rx_dp1);
i_phy.rxdp(rx_dp1);
i_phy.rxdn(rx_dn1);
i_phy.DataOut_i(tb_tx_data);
i_phy.TxValid_i(tb_tx_valid);
i_phy.TxReady_o(tb_tx_ready);
i_phy.DataIn_o(tb_rx_data);
i_phy.RxValid_o(tb_rx_valid);
i_phy.RxActive_o(tb_rx_active);
i_phy.RxError_o(tb_rx_error);
i_phy.LineState_o(line_nc);
 
i_top.clk_i(clk);
i_top.rst_i(rst);
i_top.tx_dp(tx_dp2);
i_top.tx_dn(tx_dn2);
i_top.tx_oe(tx_oe_nc);
i_top.rx_dp(rx_dp2);
i_top.rx_dn(rx_dn2);
i_top.rx_d(rx_dp2);
i_top.usb_rst(rst_nc);
i_top.crc16_err(crc16_nc);
i_top.v_set_int(int_nc);
i_top.v_set_feature(feature_nc);
i_top.usb_busy(busy_nc);
i_top.ep_sel(sel_nc);
i_top.adr(ep_f_adr);
i_top.din(ep_f_din);
i_top.dout(ep_f_dout);
i_top.cs(cs);
i_top.re(ep_f_re);
i_top.we(ep_f_we);
i_top.empty(ep_f_empty);
i_top.full(ep_f_full);
 
i_test.clk(clk);
i_test.clk2(clk2);
i_test.rst(rst);
 
vcc.write(true);
 
#ifdef VCD_OUTPUT_ENABLE
sc_trace_file *vcd_log = sc_create_vcd_trace_file("USB_TEST");
sc_trace(vcd_log, clk, "Clock");
sc_trace(vcd_log, rst, "Reset");
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_trace_file *wif_log = sc_create_wif_trace_file("USB_TEST");
sc_trace(wif_log, clk, "Clock");
sc_trace(wif_log, rst, "Reset");
#endif
 
sc_start();
 
#ifdef VCD_OUTPUT_ENABLE
sc_close_vcd_trace_file(vcd_log);
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_close_wif_trace_file(wif_log);
#endif
 
return 0;
}
 
/trunk/rtl/systemc/usb_fifo128x8.cpp
0,0 → 1,110
/////////////////////////////////////////////////////////////////////
//// ////
//// USB FIFO ////
//// ////
//// SystemC Version: usb_fifo128x8.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_fifo_sc_a.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 "systemc.h"
#include "usb_fifo128x8.h"
 
void usb_fifo128x8::write_pointer_update(void) {
if (!rst.read()) {
wp.write(0);
} else if (clr.read()) {
wp.write(0);
} else if (we.read()) {
wp.write(wp_pl1.read());
}
}
 
void usb_fifo128x8::read_pointer_update(void) {
if (!rst.read()) {
rp.write(0);
} else if (clr.read()) {
rp.write(0);
} else if (re.read()) {
rp.write(rp_pl1.read());
}
}
 
void usb_fifo128x8::future_pointers_update(void) {
wp_pl1.write(wp.read() + 1);
wp_pl2.write(wp.read() + 2);
rp_pl1.write(rp.read() + 1);
}
 
// Full & Empty Logic
// Guard Bit ...
void usb_fifo128x8::fe_gb_update(void) {
if (!rst.read())
gb.write(false);
else if (clr.read())
gb.write(false);
else if ((wp_pl2.read() == rp.read()) && we.read())
gb.write(true);
else if ((wp.read() != rp.read()) && re.read())
gb.write(false);
}
 
void usb_fifo128x8::fe_full_update(void) {
if (!rst.read())
full.write(false);
else if (clr.read())
full.write(false);
else if (we.read() && ((wp_pl1.read() == rp.read()) && gb.read()) && !re.read())
full.write(true);
else if (re.read() && ((wp_pl1.read() != rp.read()) || !gb.read()) && !we.read())
full.write(false);
}
 
void usb_fifo128x8::fe_empty_update(void) {
if (!rst.read())
empty.write(true);
else if (clr.read())
empty.write(true);
else if (we.read() && ((wp.read() != rp_pl1.read()) || gb.read()) && !re.read())
empty.write(false);
else if (re.read() && ((wp.read() == rp_pl1.read()) && !gb.read()) && !we.read())
empty.write(true);
}
 
void usb_fifo128x8::reset_update(void) {
n_rst.write(!rst.read());
}
/*
usb_fifo128x8::~usb_fifo128x8(void) {
if (i_ram)
delete i_ram;
}
*/
/trunk/rtl/systemc/usb_ram128x8.h
0,0 → 1,74
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RAM ////
//// ////
//// SystemC Version: usb_ram128x8.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_dpram.v ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// www.opencores.org ////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_RAM128X8_H
#define USB_RAM128X8_H
 
SC_MODULE(usb_ram128x8) {
 
public:
 
sc_in<bool> rclk, rrst, rce;
sc_in<bool> oe;
sc_in<sc_uint<7> > raddr;
sc_out<sc_uint<8> > dout;
 
sc_in<bool> wclk, wrst, wce;
sc_in<bool> we;
sc_in<sc_uint<7> > waddr;
sc_in<sc_uint<8> > din;
 
sc_signal<sc_uint<8> > dout_reg;
 
sc_uint<8> mem[128];
 
void dout_update(void);
void read(void);
void write(void);
 
SC_CTOR(usb_ram128x8) {
SC_METHOD(dout_update);
sensitive << oe << rce << dout_reg;
SC_METHOD(read);
sensitive << rclk.pos();
SC_METHOD(write);
sensitive << wclk.pos();
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_fifo512x8.h
0,0 → 1,115
/////////////////////////////////////////////////////////////////////
//// ////
//// USB FIFO ////
//// ////
//// SystemC Version: usb_fifo512x8.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_fifo_sc_a.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_FIFO512X8_H
#define USB_FIFO512X8_H
 
#include "usb_ram512x8.h"
 
#define FIFO_ASYNC_RESET
//#define FIFO_ASYNC_RESET << rst.neg()
 
SC_MODULE(usb_fifo512x8) {
 
private:
 
sc_signal<bool> vcc;
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_in<bool> clr;
sc_in<bool> we;
sc_in<sc_uint<8> > din;
sc_in<bool> re;
sc_out<sc_uint<8> > dout;
sc_out<bool> empty;
sc_out<bool> full;
 
sc_signal<sc_uint<9> > wp, wp_pl1, wp_pl2;
sc_signal<sc_uint<9> > rp, rp_pl1;
sc_signal<bool> gb, n_rst;
 
usb_ram512x8 *i_ram;
 
void write_pointer_update(void);
void read_pointer_update(void);
void future_pointers_update(void);
void fe_gb_update(void);
void fe_full_update(void);
void fe_empty_update(void);
void reset_update(void);
// ~usb_fifo512x8(void);
 
SC_CTOR(usb_fifo512x8) {
vcc.write(true);
 
SC_METHOD(write_pointer_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(read_pointer_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(future_pointers_update);
sensitive << wp << rp;
SC_METHOD(fe_gb_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(fe_full_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(fe_empty_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(reset_update);
sensitive << rst;
 
i_ram = new usb_ram512x8("RAM512X8");
i_ram->rclk(clk);
i_ram->rrst(n_rst);
i_ram->rce(vcc);
i_ram->oe(vcc);
i_ram->raddr(rp);
i_ram->dout(dout);
i_ram->wclk(clk);
i_ram->wrst(n_rst);
i_ram->wce(vcc);
i_ram->we(we);
i_ram->waddr(wp);
i_ram->din(din);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_crc5.h
0,0 → 1,59
/////////////////////////////////////////////////////////////////////
//// ////
//// USB CRC5 ////
//// ////
//// SystemC Version: usb_crc5.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_crc5.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_CRC5_H
#define USB_CRC5_H
 
SC_MODULE(usb_crc5) {
 
public:
 
sc_in<sc_uint<5> > crc_in;
sc_in<sc_uint<11> > din;
sc_out<sc_uint<5> > crc_out;
 
void update(void);
 
SC_CTOR(usb_crc5) {
SC_METHOD(update);
sensitive << crc_in << din;
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_top.cpp
0,0 → 1,108
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 Top Module ////
//// Function Interface ////
//// ////
//// SystemC Version: usb_top.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_8051_if.v ////
//// Copyright (C) 2003 Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// 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 "systemc.h"
#include "usb_top.h"
 
void usb_top::mux(void) {
sc_uint<9> sel;
 
dout.write("ZZZZZZZZ");
empty.write(false);
full.write(false);
ep1_f_we.write(false);
ep2_f_re.write(false);
ep3_f_we.write(false);
ep4_f_re.write(false);
ep5_f_we.write(false);
ep6_f_re.write(false);
 
sel = ((sc_uint<1>)cs.read(), (sc_uint<8>)adr.read());
 
switch (sel) {// synopsys full_case parallel_case
case 0: dout.write("00000000");
full.write(false);
empty.write(false);
break;
case 1: ep1_f_din.write(din.read());
ep1_f_we.write(we.read());
full.write(ep1_f_full.read());
break;
case 2: dout.write((sc_lv<8>)ep2_f_dout.read());
ep2_f_re.write(re.read());
empty.write(ep2_f_empty.read());
break;
case 3: ep3_f_din.write(din.read());
ep3_f_we.write(we.read());
full.write(ep3_f_full.read());
break;
case 4: dout.write((sc_lv<8>)ep4_f_dout.read());
ep4_f_re.write(re.read());
empty.write(ep4_f_empty.read());
break;
case 5: ep5_f_din.write(din.read());
ep5_f_we.write(we.read());
full.write(ep5_f_full.read());
break;
case 6: dout.write((sc_lv<8>)ep6_f_dout.read());
ep6_f_re.write(re.read());
empty.write(ep6_f_empty.read());
break;
case 8: dout.write("00000000");
full.write(false);
empty.write(false);
break;
case 16:dout.write((sc_lv<8>)wValue.read().range(7, 0));
break;
case 17:dout.write((sc_lv<8>)wValue.read().range(15, 8));
break;
case 18:dout.write((sc_lv<8>)wIndex.read().range(7, 0));
break;
case 19:dout.write((sc_lv<8>)wIndex.read().range(15, 8));
break;
case 20:vendor_data.write((vendor_data.read().range(15, 8), din.read()));
break;
case 21:vendor_data.write((din.read(), vendor_data.read().range(7, 0)));
break;
}
}
/*
usb_top::~usb_top(void) {
if (i_usb)
delete i_usb;
}
*/
/trunk/rtl/systemc/usb.out
0,0 → 1,382
WARNING: Default time step is used for VCD tracing.
 
The Default Time Unit is: 1 ns
 
**************************************************
*** CONTROL EP TEST 0 ***
**************************************************
 
Setting Address ...
 
 
Getting Descriptor ...
 
RCV Data[0]: 0x12
RCV Data[1]: 0x01
RCV Data[2]: 0x10
RCV Data[3]: 0x01
RCV Data[4]: 0xff
RCV Data[5]: 0x00
RCV Data[6]: 0xff
RCV Data[7]: 0x40
RCV Data[8]: 0x34
RCV Data[9]: 0x12
RCV Data[10]: 0x78
RCV Data[11]: 0x56
RCV Data[12]: 0x10
RCV Data[13]: 0x00
RCV Data[14]: 0x01
RCV Data[15]: 0x02
RCV Data[16]: 0x03
RCV Data[17]: 0x01
 
Getting Descriptor ...
 
RCV Data[0]: 0x09
RCV Data[1]: 0x02
RCV Data[2]: 0x3c
RCV Data[3]: 0x00
RCV Data[4]: 0x01
RCV Data[5]: 0x01
RCV Data[6]: 0x00
RCV Data[7]: 0x40
RCV Data[8]: 0x00
 
Getting Descriptor ...
 
RCV Data[0]: 0x09
RCV Data[1]: 0x02
RCV Data[2]: 0x3c
RCV Data[3]: 0x00
RCV Data[4]: 0x01
RCV Data[5]: 0x01
RCV Data[6]: 0x00
RCV Data[7]: 0x40
RCV Data[8]: 0x00
RCV Data[9]: 0x09
RCV Data[10]: 0x04
RCV Data[11]: 0x00
RCV Data[12]: 0x00
RCV Data[13]: 0x06
RCV Data[14]: 0xff
RCV Data[15]: 0x01
RCV Data[16]: 0xff
RCV Data[17]: 0x00
RCV Data[18]: 0x07
RCV Data[19]: 0x05
RCV Data[20]: 0x81
RCV Data[21]: 0x01
RCV Data[22]: 0x00
RCV Data[23]: 0x01
RCV Data[24]: 0x01
RCV Data[25]: 0x07
RCV Data[26]: 0x05
RCV Data[27]: 0x02
RCV Data[28]: 0x01
RCV Data[29]: 0x00
RCV Data[30]: 0x01
RCV Data[31]: 0x01
RCV Data[32]: 0x07
RCV Data[33]: 0x05
RCV Data[34]: 0x83
RCV Data[35]: 0x02
RCV Data[36]: 0x40
RCV Data[37]: 0x00
RCV Data[38]: 0x01
RCV Data[39]: 0x07
RCV Data[40]: 0x05
RCV Data[41]: 0x04
RCV Data[42]: 0x02
RCV Data[43]: 0x40
RCV Data[44]: 0x00
RCV Data[45]: 0x01
RCV Data[46]: 0x07
RCV Data[47]: 0x05
RCV Data[48]: 0x85
RCV Data[49]: 0x03
RCV Data[50]: 0x40
RCV Data[51]: 0x00
RCV Data[52]: 0x01
RCV Data[53]: 0x07
RCV Data[54]: 0x05
RCV Data[55]: 0x06
RCV Data[56]: 0x03
RCV Data[57]: 0x40
RCV Data[58]: 0x00
RCV Data[59]: 0x01
 
Getting Descriptor ...
 
RCV Data[0]: 0x06
RCV Data[1]: 0x03
RCV Data[2]: 0x16
RCV Data[3]: 0x04
RCV Data[4]: 0x16
RCV Data[5]: 0x04
RCV Data[6]: 0x16
RCV Data[7]: 0x04
 
Getting Descriptor ...
 
RCV Data[0]: 0x1a
RCV Data[1]: 0x03
RCV Data[2]: 0x00
RCV Data[3]: 0x67
RCV Data[4]: 0x00
RCV Data[5]: 0x72
RCV Data[6]: 0x00
RCV Data[7]: 0x6f
RCV Data[8]: 0x00
RCV Data[9]: 0x2e
RCV Data[10]: 0x00
RCV Data[11]: 0x50
RCV Data[12]: 0x00
RCV Data[13]: 0x49
RCV Data[14]: 0x00
RCV Data[15]: 0x6c
RCV Data[16]: 0x00
RCV Data[17]: 0x69
RCV Data[18]: 0x00
RCV Data[19]: 0x7a
RCV Data[20]: 0x00
RCV Data[21]: 0x61
RCV Data[22]: 0x00
RCV Data[23]: 0x72
RCV Data[24]: 0x00
RCV Data[25]: 0x42
 
Getting Descriptor ...
 
RCV Data[0]: 0x1c
RCV Data[1]: 0x03
RCV Data[2]: 0x00
RCV Data[3]: 0x78
RCV Data[4]: 0x00
RCV Data[5]: 0x69
RCV Data[6]: 0x00
RCV Data[7]: 0x6e
RCV Data[8]: 0x00
RCV Data[9]: 0xea
RCV Data[10]: 0x00
RCV Data[11]: 0x46
RCV Data[12]: 0x00
RCV Data[13]: 0x20
RCV Data[14]: 0x00
RCV Data[15]: 0x6f
RCV Data[16]: 0x00
RCV Data[17]: 0x74
RCV Data[18]: 0x00
RCV Data[19]: 0x65
RCV Data[20]: 0x00
RCV Data[21]: 0x6a
RCV Data[22]: 0x00
RCV Data[23]: 0x6f
RCV Data[24]: 0x00
RCV Data[25]: 0x72
RCV Data[26]: 0x00
RCV Data[27]: 0x50
 
Getting Descriptor ...
 
RCV Data[0]: 0x36
RCV Data[1]: 0x03
RCV Data[2]: 0x00
RCV Data[3]: 0x29
RCV Data[4]: 0x00
RCV Data[5]: 0x33
RCV Data[6]: 0x00
RCV Data[7]: 0x30
RCV Data[8]: 0x00
RCV Data[9]: 0x30
RCV Data[10]: 0x00
RCV Data[11]: 0x32
RCV Data[12]: 0x00
RCV Data[13]: 0x28
RCV Data[14]: 0x00
RCV Data[15]: 0x20
RCV Data[16]: 0x00
RCV Data[17]: 0x6c
RCV Data[18]: 0x00
RCV Data[19]: 0x61
RCV Data[20]: 0x00
RCV Data[21]: 0x74
RCV Data[22]: 0x00
RCV Data[23]: 0x6e
RCV Data[24]: 0x00
RCV Data[25]: 0x65
RCV Data[26]: 0x00
RCV Data[27]: 0x6d
RCV Data[28]: 0x00
RCV Data[29]: 0x69
RCV Data[30]: 0x00
RCV Data[31]: 0x72
RCV Data[32]: 0x00
RCV Data[33]: 0x65
RCV Data[34]: 0x00
RCV Data[35]: 0x70
RCV Data[36]: 0x00
RCV Data[37]: 0x78
RCV Data[38]: 0x00
RCV Data[39]: 0x45
RCV Data[40]: 0x00
RCV Data[41]: 0x20
RCV Data[42]: 0x00
RCV Data[43]: 0x6f
RCV Data[44]: 0x00
RCV Data[45]: 0xe3
RCV Data[46]: 0x00
RCV Data[47]: 0x73
RCV Data[48]: 0x00
RCV Data[49]: 0x72
RCV Data[50]: 0x00
RCV Data[51]: 0x65
RCV Data[52]: 0x00
RCV Data[53]: 0x56
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
 
**************************************************
*** ISOCHRONOUS IN EP TEST 1 ***
**************************************************
 
PL Size: 0
PL Size: 32
PL Size: 64
PL Size: 96
PL Size: 128
PL Size: 160
PL Size: 192
PL Size: 224
PL Size: 256
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
 
**************************************************
*** ISOCHRONOUS OUT EP TEST 2 ***
**************************************************
 
PL Size: 0
PL Size: 32
PL Size: 64
PL Size: 96
PL Size: 128
PL Size: 160
PL Size: 192
PL Size: 224
PL Size: 256
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
 
**************************************************
*** BULK IN EP TEST 3 ***
**************************************************
 
PL Size: 0
PL Size: 8
PL Size: 16
PL Size: 24
PL Size: 32
PL Size: 40
PL Size: 48
PL Size: 56
PL Size: 64
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
 
**************************************************
*** BULK OUT EP TEST 4 ***
**************************************************
 
PL Size: 0
PL Size: 8
PL Size: 16
PL Size: 24
PL Size: 32
PL Size: 40
PL Size: 48
PL Size: 56
PL Size: 64
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
 
**************************************************
*** INTERRUPT IN EP TEST 5 ***
**************************************************
 
PL Size: 0
PL Size: 8
PL Size: 16
PL Size: 24
PL Size: 32
PL Size: 40
PL Size: 48
PL Size: 56
PL Size: 64
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
 
**************************************************
*** INTERRUPT OUT EP TEST 6 ***
**************************************************
 
PL Size: 0
PL Size: 8
PL Size: 16
PL Size: 24
PL Size: 32
PL Size: 40
PL Size: 48
PL Size: 56
PL Size: 64
 
+----------------------+
| TOTAL ERRORS: 0
+----------------------+
 
**************************************************
*** TEST DONE ... ***
**************************************************
 
SystemC: simulation stopped by user.
/trunk/rtl/systemc/usb_pa_sie.h
0,0 → 1,207
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Packet Assembler ////
//// ////
//// SystemC Version: usb_pa_sie.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_pa.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_PA_SIE_H
#define USB_PA_SIE_H
 
#include "usb_defines.h"
#include "usb_crc16.h"
 
enum PA_STATE { PA_IDLE = 1,
PA_DATA = 2,
PA_CRC1 = 4,
PA_CRC2 = 8};
 
SC_MODULE(usb_pa_sie) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
 
// TX Interface
sc_out<sc_uint<8> > tx_data;
sc_out<bool> tx_valid, tx_valid_last;
sc_in<bool> tx_ready;
sc_out<bool> tx_first;
 
// Protocol Engine Interface
sc_in<bool> send_token;
sc_in<sc_uint<2> > token_pid_sel;
sc_in<bool> send_data;
sc_in<sc_uint<2> > data_pid_sel;
 
// IDMA Interface
sc_in<sc_uint<8> > tx_data_st;
sc_out<bool> rd_next;
 
sc_in<bool> ep_empty;
 
// Local Signals
sc_signal<sc_uint<4> > state, next_state;// synopsys state_vector state
sc_signal<bool> last;
sc_signal<sc_uint<8> > token_pid, data_pid; // PIDs from selectors
sc_signal<sc_uint<8> > tx_data_d, tx_data_data;
sc_signal<bool> dsel;
sc_signal<bool> tx_valid_d;
sc_signal<bool> send_token_r;
sc_signal<sc_uint<8> > tx_spec_data;
sc_signal<bool> crc_sel1, crc_sel2;
sc_signal<bool> tx_first_r;
sc_signal<bool> send_data_r;
sc_signal<bool> crc16_clr;
sc_signal<sc_uint<8> > crc16_din;
sc_signal<sc_uint<16> > crc16;
sc_signal<sc_uint<16> > crc16_next;
sc_signal<sc_uint<16> > crc16_rev;
sc_signal<bool> crc16_add;
sc_signal<bool> send_data_r2;
sc_signal<bool> tx_valid_r;
sc_signal<bool> tx_valid_r1;
sc_signal<bool> zero_length;
sc_signal<bool> zero_length_r;
 
usb_crc16 *i_crc16; // CRC16 Calculator
 
// Zero Length Functions
void zl_up(void);
void zl_r_up(void);
 
// Misc Functions
void tx_valid_r_up1(void);
void tx_valid_r_up2(void);
void send_token_up(void);
 
// PID Select Functions
void token_pid_up(void);
void data_pid_up(void);
 
// Data Path Muxes Functions
void tx_data_up1(void);
void tx_data_up2(void);
void tx_data_up3(void);
void tx_spec_up(void);
 
// TX Valid Assignment Functions
void tx_valid_up1(void);
void tx_valid_up2(void);
void tx_first_up1(void);
void tx_first_up2(void);
 
// CRC Logic Functions
void send_data_up1(void);
void send_data_up2(void);
void crc16_clr_up(void);
void crc16_din_up(void);
void crc16_add_up(void);
void crc16_up(void);
void crc16_rev_up(void);
 
// Transmit/Encode State Machine Functions
void state_up(void);
void pa_statemachine(void);
 
// Destructor
// ~usb_pa_sie(void);
 
SC_CTOR(usb_pa_sie) {
SC_METHOD(zl_up);
sensitive << ep_empty;
SC_METHOD(zl_r_up);
sensitive << clk.pos() << rst.neg();
 
SC_METHOD(tx_valid_r_up1);
sensitive << clk.pos();
SC_METHOD(tx_valid_r_up2);
sensitive << clk.pos();
SC_METHOD(send_token_up);
sensitive << clk.pos() << rst.neg();
 
SC_METHOD(token_pid_up);
sensitive << token_pid_sel;
SC_METHOD(data_pid_up);
sensitive << data_pid_sel;
 
SC_METHOD(tx_data_up1);
sensitive << dsel << tx_data_st << tx_spec_data;
SC_METHOD(tx_data_up2);
sensitive << send_token << send_token_r << token_pid << tx_data_data;
SC_METHOD(tx_data_up3);
sensitive << tx_data_d;
SC_METHOD(tx_spec_up);
sensitive << crc_sel1 << crc_sel2 << data_pid << crc16_rev;
 
SC_METHOD(tx_valid_up1);
sensitive << send_token << last;
SC_METHOD(tx_valid_up2);
sensitive << tx_valid_d;
SC_METHOD(tx_first_up1);
sensitive << clk.pos();
SC_METHOD(tx_first_up2);
sensitive << send_token << send_data << tx_first_r;
 
SC_METHOD(send_data_up1);
sensitive << clk.pos();
SC_METHOD(send_data_up2);
sensitive << clk.pos();
SC_METHOD(crc16_clr_up);
sensitive << send_data << send_data_r;
SC_METHOD(crc16_din_up);
sensitive << tx_data_st;
SC_METHOD(crc16_add_up);
sensitive << clk.pos();
SC_METHOD(crc16_up);
sensitive << clk.pos();
SC_METHOD(crc16_rev_up);
sensitive << crc16;
 
SC_METHOD(state_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(pa_statemachine);
sensitive << state << send_data << tx_ready << tx_valid_r << zero_length;
 
// CRC16 Calculator Instantiation and Binding
i_crc16 = new usb_crc16("CRC16");
i_crc16->crc_in(crc16);
i_crc16->din(crc16_din);
i_crc16->crc_out(crc16_next);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_phy.h
0,0 → 1,114
/////////////////////////////////////////////////////////////////////
//// ////
//// USB PHY ////
//// ////
//// SystemC Version: usb_phy.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_phy.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_PHY_H
#define USB_PHY_H
 
#include "usb_tx_phy.h"
#include "usb_rx_phy.h"
 
//#define USB_ASYNC_RESET
 
SC_MODULE(usb_phy) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_in<bool> phy_tx_mode;
sc_out<bool> usb_rst;
sc_out<bool> txdp, txdn, txoe;
sc_in<bool> rxd, rxdp, rxdn;
sc_in<sc_uint<8> > DataOut_i;
sc_in<bool> TxValid_i;
sc_out<bool> TxReady_o;
sc_out<sc_uint<8> > DataIn_o;
sc_out<bool> RxValid_o;
sc_out<bool> RxActive_o;
sc_out<bool> RxError_o;
sc_out<sc_uint<2> > LineState_o;
 
sc_signal<sc_uint<6> > rst_cnt;
sc_signal<bool> reset, fs_ce;
 
usb_tx_phy *i_tx_phy;
usb_rx_phy *i_rx_phy;
 
void reset_up(void);
void rst_cnt_up(void);
void usb_rst_up(void);
// ~usb_phy(void);
 
SC_CTOR(usb_phy) {
SC_METHOD(reset_up);
sensitive << rst << usb_rst;
SC_METHOD(rst_cnt_up);
sensitive << clk.pos();
SC_METHOD(usb_rst_up);
sensitive << clk.pos();
 
i_tx_phy = new usb_tx_phy("TX_PHY");
i_tx_phy->clk(clk);
i_tx_phy->rst(reset);
i_tx_phy->fs_ce(fs_ce);
i_tx_phy->phy_mode(phy_tx_mode);
i_tx_phy->txdp(txdp);
i_tx_phy->txdn(txdn);
i_tx_phy->txoe(txoe);
i_tx_phy->DataOut_i(DataOut_i);
i_tx_phy->TxValid_i(TxValid_i);
i_tx_phy->TxReady_o(TxReady_o);
 
i_rx_phy = new usb_rx_phy("RX_PHY");
i_rx_phy->clk(clk);
i_rx_phy->rst(reset);
i_rx_phy->fs_ce(fs_ce);
i_rx_phy->rxd(rxd);
i_rx_phy->rxdp(rxdp);
i_rx_phy->rxdn(rxdn);
i_rx_phy->DataIn_o(DataIn_o);
i_rx_phy->RxValid_o(RxValid_o);
i_rx_phy->RxActive_o(RxActive_o);
i_rx_phy->RxError_o(RxError_o);
i_rx_phy->RxEn_i(txoe);
i_rx_phy->LineState(LineState_o);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_dma.h
0,0 → 1,231
/////////////////////////////////////////////////////////////////////
//// ////
//// USB IDMA Engine ////
//// ////
//// SystemC Version: usb_dma.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_idma.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_DMA_H
#define USB_DMA_H
 
#include "usb_defines.h"
#include "usb_fifo2.h"
 
SC_MODULE(usb_dma) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
 
// PA/PD Interface
sc_in<bool> rx_data_valid;
sc_in<bool> rx_data_done;
sc_out<bool> send_data;
sc_in<bool> rd_next;
sc_in<bool> tx_valid;
sc_in<sc_uint<8> > tx_data_st_i;
sc_out<sc_uint<8> > tx_data_st_o;
 
// PE Interface
sc_in<bool> tx_dma_en;
sc_in<bool> rx_dma_en;
sc_out<bool> idma_done; // DMA is done
sc_in<sc_uint<4> > ep_sel;
 
// Register File Manager Interface
sc_in<sc_uint<9> > size; // Max PL size in bytes
sc_out<sc_uint<8> > rx_cnt;
sc_out<bool> rx_done;
sc_out<bool> tx_busy;
 
// Memory Arbiter Interface
sc_out<bool> mwe; // Memory Write Enable
sc_out<bool> mre; // Memory Read Enable
sc_in<bool> ep_empty;
sc_out<bool> ep_empty_int;
sc_in<bool> ep_full;
 
// Local Signals
sc_signal<bool> tx_dma_en_r;
sc_signal<sc_uint<9> > sizd_c; // Internal Size Counter
sc_signal<bool> adr_incw;
sc_signal<bool> adr_incb;
sc_signal<bool> siz_dec;
sc_signal<bool> mwe_r;
sc_signal<bool> sizd_is_zero; // Indicates when all bytes have been transferred
sc_signal<bool> sizd_is_zero_d;
sc_signal<bool> rx_data_done_r;
sc_signal<bool> rx_data_valid_r;
sc_signal<bool> ff_re, ff_full, ff_empty;
sc_signal<bool> ff_we, ff_we1;
sc_signal<bool> tx_dma_en_r1;
sc_signal<bool> tx_dma_en_r2;
sc_signal<bool> tx_dma_en_r3;
sc_signal<bool> send_data_r;
sc_signal<bool> ff_clr;
sc_signal<sc_uint<8> > rx_cnt_r;
sc_signal<bool> ep_empty_r;
sc_signal<bool> ep_full_int;
sc_signal<bool> tx_valid_r;
sc_signal<bool> tx_valid_e;
 
usb_fifo2 *i_ff2; // IDMA fast prefetch FIFO
 
// Empty/Full Logic Functions
void empty_int_up(void);
void full_int_up(void);
 
// FIFO Interface Functions
void mwe_up1(void);
void mwe_up2(void);
 
// Misc Logic Functions
void data_valid_up(void);
void data_done_up(void);
 
// TX DMA Enable Functions
void tx_dma_en_up1(void);
void tx_dma_en_up2(void);
void tx_dma_en_up3(void);
 
// DMA Done Indicator Function
void idma_done_up(void);
 
// RX DMA Done Indicator Functions
void rx_cnt_up1(void);
void rx_cnt_up2(void);
void rx_done_up(void);
 
// TX DMA Done Indicator Functions
void sizd_cnt_up(void);
void is_zero_up1(void);
void is_zero_up2(void);
void siz_dec_up(void);
 
// TX DMA Logic Functions
void tx_busy_up(void);
void tx_valid_up1(void);
void tx_valid_up2(void);
void empty_up(void);
void send_data_up1(void);
void send_data_up2(void);
void mre_up(void);
void ff_we_up1(void);
void ff_we_up2(void);
void ff_re_up(void);
void ff_clr_up(void);
 
// Destructor
// ~usb_dma(void);
 
SC_CTOR(usb_dma) {
SC_METHOD(empty_int_up);
sensitive << ep_empty;
SC_METHOD(full_int_up);
sensitive << ep_full;
 
SC_METHOD(mwe_up1);
sensitive << clk.pos();
SC_METHOD(mwe_up2);
sensitive << mwe_r << ep_full_int;
 
SC_METHOD(data_valid_up);
sensitive << clk.pos();
SC_METHOD(data_done_up);
sensitive << clk.pos();
 
SC_METHOD(tx_dma_en_up1);
sensitive << clk.pos();
SC_METHOD(tx_dma_en_up2);
sensitive << clk.pos();
SC_METHOD(tx_dma_en_up3);
sensitive << clk.pos();
 
SC_METHOD(idma_done_up);
sensitive << clk.pos();
 
SC_METHOD(rx_cnt_up1);
sensitive << clk.pos() << rst.neg();
SC_METHOD(rx_cnt_up2);
sensitive << clk.pos() << rst.neg();
SC_METHOD(rx_done_up);
sensitive << rx_data_done_r;
 
SC_METHOD(sizd_cnt_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(is_zero_up1);
sensitive << sizd_c;
SC_METHOD(is_zero_up2);
sensitive << clk.pos();
SC_METHOD(siz_dec_up);
sensitive << tx_dma_en_r << tx_dma_en_r1 << rd_next << sizd_is_zero_d;
 
SC_METHOD(tx_busy_up);
sensitive << send_data << tx_dma_en_r << tx_dma_en;
SC_METHOD(tx_valid_up1);
sensitive << clk.pos();
SC_METHOD(tx_valid_up2);
sensitive << tx_valid_r << tx_valid;
SC_METHOD(empty_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(send_data_up1);
sensitive << clk.pos() << rst.neg();
SC_METHOD(send_data_up2);
sensitive << send_data_r << ep_empty_r << sizd_is_zero << size << tx_dma_en_r1;
SC_METHOD(mre_up);
sensitive << tx_dma_en_r1 << tx_dma_en_r << rd_next << sizd_is_zero_d << ep_empty_int << send_data;
SC_METHOD(ff_we_up1);
sensitive << clk.pos();
SC_METHOD(ff_we_up2);
sensitive << clk.pos();
SC_METHOD(ff_re_up);
sensitive << rd_next;
SC_METHOD(ff_clr_up);
sensitive << tx_valid;
 
// IDMA FIFO Instantiation and Binding
i_ff2 = new usb_fifo2("FIFO2");
i_ff2->clk(clk);
i_ff2->rst(rst);
i_ff2->clr(ff_clr);
i_ff2->din(tx_data_st_i);
i_ff2->we(ff_we);
i_ff2->dout(tx_data_st_o);
i_ff2->re(ff_re);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_pd_sie.h
0,0 → 1,250
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Packet Disassembler ////
//// ////
//// SystemC Version: usb_pd_sie.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_pd.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_PD_SIE_H
#define USB_PD_SIE_H
 
#include "usb_defines.h"
#include "usb_crc5.h"
#include "usb_crc16.h"
 
enum PD_STATE { PD_IDLE = 1,
PD_ACTIVE = 2,
PD_TOKEN = 4,
PD_DATA = 8};
 
SC_MODULE(usb_pd_sie) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
 
// RX Interface
sc_in<sc_uint<8> > rx_data;
sc_in<bool> rx_valid, rx_active, rx_err;
 
// PID Information
// Decoded PIDs (used when token_valid is asserted)
sc_out<bool> pid_OUT, pid_IN, pid_SOF, pid_SETUP;
sc_out<bool> pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
sc_out<bool> pid_ACK, pid_NACK, pid_STALL, pid_NYET;
sc_out<bool> pid_PRE, pid_ERR, pid_SPLIT, pid_PING;
sc_out<bool> pid_cks_err; // Indicates a PID checksum error
 
// Token Information
sc_out<sc_uint<7> > token_fadr; // Function address from token
sc_out<sc_uint<4> > token_endp; // Endpoint number from token
sc_out<bool> token_valid; // Token is valid
sc_out<bool> crc5_err; // Token CRC5 error
sc_out<sc_uint<11> >frame_no; // Frame number for SOF tokens
 
// Receive Data Output
sc_out<sc_uint<8> > rx_data_st; // Data to memory store unit
sc_out<bool> rx_data_valid; // Data on rx_data_st is valid
sc_out<bool> rx_data_done; // Indicates end of a transfer
sc_out<bool> crc16_err; // Data packet CRC16 error
 
// Misc
sc_out<bool> seq_err; // State Machine Sequence Error
sc_out<bool> rx_busy; // Receiving Data Packet
 
// Local Signals
sc_signal<sc_uint<4> > state, next_state;// synopsys state_vector state
sc_signal<sc_uint<8> > pid; // Packet PID
sc_signal<bool> pid_le_sm; // PID load enable from State Machine
sc_signal<bool> pid_ld_en; // Enable loading of PID (all conditions)
sc_signal<bool> pid_RES;
sc_signal<bool> pid_TOKEN; // All TOKEN packet that we recognize
sc_signal<bool> pid_DATA; // All DATA packet that we recognize
sc_signal<sc_uint<8> > token0, token1; // Token registers
sc_signal<bool> token_le_1, token_le_2; // Latch enables for token storage registers
sc_signal<sc_uint<5> > token_crc5;
sc_signal<sc_uint<8> > d0, d1, d2; // Data path delay line (used to filter out crcs)
sc_signal<bool> data_valid_d; // Data valid output from State Machine
sc_signal<bool> data_done; // Data cycle complete output from State Machine
sc_signal<bool> data_valid0; // Data valid delay line
sc_signal<bool> rxv1, rxv2;
sc_signal<bool> pid_ack;
sc_signal<bool> token_valid_r1;
sc_signal<bool> token_valid_str1;
sc_signal<bool> rx_active_r;
sc_signal<bool> rx_busy_d;
sc_signal<sc_uint<5> > crc5_out, crc5_out2;
sc_signal<sc_uint<5> > crc5_pol;
sc_signal<sc_uint<11> > crc5_din;
sc_signal<bool> crc16_clr;
sc_signal<sc_uint<16> > crc16_sum, crc16_out;
sc_signal<sc_uint<8> > crc16_din;
 
usb_crc5 *i_crc5; // CRC5 Calculator
usb_crc16 *i_crc16; // CRC16 Calculator
 
// Busy Logic Functions
void rx_busy_up1(void);
void rx_busy_up2(void);
 
// PID Decoding Logic Functions
void pid_ld_up(void);
void pid_up(void);
void pid_cks_err_up(void);
void pid_decoder(void);
void pid_token_up(void);
void pid_data_up(void);
 
// Token Decoding Logic Functions
void token_decoder(void);
void token_valid_up1(void);
void token_valid_up2(void);
void token_valid_up3(void);
void token_up(void);
 
// CRC5 Logic Functions
void crc5_din_up(void);
void crc5_err_up(void);
void crc5_out2_up(void);
 
// Data Receiving Logic Functions
void rxv1_up(void);
void rxv2_up(void);
void data_valid0_up(void);
void d_up(void);
void rx_data_st_up(void);
void rx_data_valid_up(void);
void rx_data_done_up(void);
 
// CRC16 Logic Functions
void rx_active_r_up(void);
void crc16_din_up(void);
void crc16_clr_up(void);
void crc16_sum_up(void);
void crc16_err_up(void);
 
// Receive/Decode State Machine Functions
void state_up(void);
void pd_statemachine(void);
 
// Destructor
// ~usb_pd_sie(void);
 
SC_CTOR(usb_pd_sie) {
crc5_pol.write(31);
 
SC_METHOD(rx_busy_up1);
sensitive << clk.pos() << rst.neg();
SC_METHOD(rx_busy_up2);
sensitive << clk.pos();
 
SC_METHOD(pid_ld_up);
sensitive << pid_le_sm << rx_active << rx_valid;
SC_METHOD(pid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(pid_cks_err_up);
sensitive << pid;
SC_METHOD(pid_decoder);
sensitive << pid;
SC_METHOD(pid_token_up);
sensitive << pid_OUT << pid_IN << pid_SOF << pid_SETUP << pid_PING;
SC_METHOD(pid_data_up);
sensitive << pid_DATA0 << pid_DATA1 << pid_DATA2 << pid_MDATA;
 
SC_METHOD(token_decoder);
sensitive << clk.pos();
SC_METHOD(token_valid_up1);
sensitive << clk.pos();
SC_METHOD(token_valid_up2);
sensitive << clk.pos();
SC_METHOD(token_valid_up3);
sensitive << token_valid_str1;
SC_METHOD(token_up);
sensitive << token0 << token1;
 
SC_METHOD(crc5_din_up);
sensitive << token_fadr << token_endp;
SC_METHOD(crc5_err_up);
sensitive << token_valid << crc5_out2 << token_crc5;
SC_METHOD(crc5_out2_up);
sensitive << crc5_out;
 
SC_METHOD(rxv1_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(rxv2_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(data_valid0_up);
sensitive << clk.pos();
SC_METHOD(d_up);
sensitive << clk.pos();
SC_METHOD(rx_data_st_up);
sensitive << d2;
SC_METHOD(rx_data_valid_up);
sensitive << data_valid0;
SC_METHOD(rx_data_done_up);
sensitive << data_done;
 
SC_METHOD(rx_active_r_up);
sensitive << clk.pos();
SC_METHOD(crc16_din_up);
sensitive << rx_data;
SC_METHOD(crc16_clr_up);
sensitive << rx_active << rx_active_r;
SC_METHOD(crc16_sum_up);
sensitive << clk.pos();
SC_METHOD(crc16_err_up);
sensitive << data_done << crc16_sum;
 
SC_METHOD(state_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(pd_statemachine);
sensitive << state << rx_valid << rx_active << rx_err << pid_ACK << pid_TOKEN << pid_DATA;
 
// CRC5 Calculator Instantiation and Binding
i_crc5 = new usb_crc5("CRC5");
i_crc5->crc_in(crc5_pol);
i_crc5->din(crc5_din);
i_crc5->crc_out(crc5_out);
 
// CRC16 Calculator Instantiation and Binding
i_crc16 = new usb_crc16("CRC16");
i_crc16->crc_in(crc16_sum);
i_crc16->din(crc16_din);
i_crc16->crc_out(crc16_out);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_ram64x8.cpp
0,0 → 1,53
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RAM ////
//// ////
//// SystemC Version: usb_ram64x8.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_dpram.v ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// www.opencores.org ////
//// ////
//// 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 "systemc.h"
#include "usb_ram64x8.h"
 
void usb_ram64x8::dout_update(void) {
dout.write((oe.read() && rce.read()) ? dout_reg.read() : (sc_uint<8>)0);
}
 
void usb_ram64x8::read(void) {
if (rce.read())
dout_reg.write(mem[raddr.read()]);
}
 
void usb_ram64x8::write(void) {
if (wce.read() && we.read())
mem[waddr.read()] = din.read();
}
 
/trunk/rtl/systemc/usb_pe_sie.h
0,0 → 1,334
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Protocol Engine ////
//// Performs automatic protocol functions ////
//// ////
//// SystemC Version: usb_pe_sie.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_pe.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_PE_SIE_H
#define USB_PE_SIE_H
 
#include "usb_defines.h"
 
// TX Token Decoding
enum PE_TX_TOKEN {PE_ACK, PE_NACK, PE_STALL, PE_NYET};
 
// State Decoding
enum PE_STATE { PE_IDLE = 1,
PE_TOKEN = 2,
PE_IN = 4,
PE_IN2 = 8,
PE_OUT = 16,
PE_OUT2A = 32,
PE_OUT2B = 64,
PE_UPDATEW = 128,
PE_UPDATE = 256,
PE_UPDATE2 = 512};
 
SC_MODULE(usb_pe_sie) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
 
// PL Interface
sc_in<bool> tx_valid;
sc_in<bool> rx_active;
 
// PD Interface
// Decoded PIDs (used when token_valid is asserted)
sc_in<bool> pid_OUT, pid_IN, pid_SOF, pid_SETUP;
sc_in<bool> pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
sc_in<bool> pid_ACK, pid_PING;
sc_in<bool> token_valid; // Token is valid
sc_in<bool> rx_data_done; // Indicates end of a transfer
sc_in<bool> crc16_err; // Data packet CRC16 error
 
// PA Interface
sc_out<bool> send_token;
sc_out<sc_uint<2> > token_pid_sel;
sc_out<sc_uint<2> > data_pid_sel;
 
// IDMA Interface
sc_out<bool> rx_dma_en; // Allows the data to be stored
sc_out<bool> tx_dma_en; // Allows for data to be retrieved
sc_out<bool> abort; // Abort transfer (time out, CRC error or RX error)
sc_in<bool> idma_done; // DMA is done indicator
sc_in<bool> ep_full; // Indicates the endpoints FIFOs is full
sc_in<bool> ep_empty; // Indicates the endpoints FIFOs is empty
 
// Register File Interface
sc_in<bool> fsel; // This function is selected
sc_in<sc_uint<4> > ep_sel; // Endpoint Number Input
sc_in<bool> match; // Endpoint Matched
sc_out<bool> nse_err; // No such endpoint error
sc_out<bool> int_upid_set; // Set unsupported PID interrupt
sc_out<bool> int_crc16_set; // Set CRC16 error interrupt
sc_out<bool> int_to_set; // Set time out interrupt
sc_out<bool> int_seqerr_set; // Set PID sequence error interrupt
sc_in<sc_uint<14> > csr; // Internal CSR Output
sc_in<bool> send_stall; // Force sending a STALL during setup
 
// Local Signals
sc_signal<sc_uint<2> > token_pid_sel_d;
sc_signal<bool> send_token_d;
sc_signal<bool> int_seqerr_set_d;
sc_signal<bool> match_r;
 
// Endpoint Decoding
sc_signal<bool> IN_ep, OUT_ep, CTRL_ep; // Endpoint Types
sc_signal<bool> txfr_iso, txfr_bulk, txfr_int; // Transfer Types
 
sc_signal<sc_uint<2> > uc_dpd;
 
// Buffer checks
sc_signal<sc_uint<10> > state, next_state;// synopsys state_vector state
 
// PID next and current decoders
sc_signal<sc_uint<2> > next_dpid;
sc_signal<sc_uint<2> > this_dpid;
sc_signal<bool> pid_seq_err;
sc_signal<sc_uint<2> > tr_fr_d;
 
sc_signal<sc_uint<14> > size_next;
sc_signal<bool> buf_smaller;
 
// After sending data in response to an IN token from host, the
// host must reply with an ack. The host has XXXnS to reply.
// "rx_ack_to" indicates when this time has expired.
// rx_ack_to_clr, clears the timer
sc_signal<bool> rx_ack_to_clr;
sc_signal<bool> rx_ack_to_clr_d;
sc_signal<bool> rx_ack_to;
sc_signal<sc_uint<8> > rx_ack_to_cnt;
 
// After sending a OUT token the host must send a data packet,
// the host has XXXnS to send the packet. "tx_data_to" indicates
// when this time has expired.
// tx_data_to_clr, clears the timer
sc_signal<bool> tx_data_to_clr;
sc_signal<bool> tx_data_to;
sc_signal<sc_uint<8> > tx_data_to_cnt;
 
sc_signal<sc_uint<8> > rx_ack_to_val, tx_data_to_val;
sc_signal<sc_uint<2> > next_bsel;
sc_signal<bool> uc_stat_set_d;
sc_signal<bool> uc_dpd_set;
sc_signal<bool> in_token;
sc_signal<bool> out_token;
sc_signal<bool> setup_token;
sc_signal<bool> in_op, out_op; // Indicate a IN or OUT operation
sc_signal<sc_uint<2> > allow_pid;
sc_signal<sc_uint<2> > ep_type, txfr_type;
 
sc_signal<sc_uint<2> > ep0_dpid, ep1_dpid, ep2_dpid, ep3_dpid;
sc_signal<sc_uint<2> > ep4_dpid, ep5_dpid, ep6_dpid, ep7_dpid;
sc_signal<bool> pid_OUT_r, pid_IN_r, pid_PING_r, pid_SETUP_r;
sc_signal<bool> send_stall_r;
 
// Misc Functions
void csr_decoder(void);
void match_up(void);
void nse_err_up(void);
void send_token_up(void);
void token_pid_sel_up(void);
 
// Data PID Storage Functions
void ep0_dpid_up(void);
void ep1_dpid_up(void);
void ep2_dpid_up(void);
void ep3_dpid_up(void);
void ep4_dpid_up(void);
void ep5_dpid_up(void);
void ep6_dpid_up(void);
void ep7_dpid_up(void);
void uc_dpd_up(void);
 
// Data PID Sequencer Function
void sq_statemachine(void);
 
// Current PID Decoder Functions
void allow_pid_up(void);
void this_dpid_up(void);
void data_pid_sel_up(void);
void pid_seq_err_up(void);
 
// IDMA Setup and Buffer Select Functions
void in_token_up(void);
void out_token_up(void);
void setup_token_up(void);
void in_op_up(void);
void out_op_up(void);
 
// Register File Update Logic Functions
void uc_dpd_set_up(void);
void abort_up(void);
 
// Time Out Functions
void rx_ack_up1(void);
void rx_ack_up2(void);
void rx_ack_up3(void);
 
void tx_data_up1(void);
void tx_data_up2(void);
void tx_data_up3(void);
 
// Interrupts Functions
void pid_OUT_up(void);
void pid_IN_up(void);
void pid_PING_up(void);
void pid_SETUP_up(void);
void int_upid_up(void);
void int_to_up(void);
void int_crc16_up(void);
void int_seqerr_up(void);
 
void send_stall_up(void);
 
// Main Protocol State Machine Functions
void state_up(void);
void pe_statemachine(void);
 
SC_CTOR(usb_pe_sie) {
tr_fr_d.write(0);
rx_ack_to_val.write(USBF_RX_ACK_TO_VAL_FS);
tx_data_to_val.write(USBF_TX_DATA_TO_VAL_FS);
 
SC_METHOD(csr_decoder);
sensitive << csr;
SC_METHOD(match_up);
sensitive << clk.pos();
SC_METHOD(nse_err_up);
sensitive << clk.pos();
SC_METHOD(send_token_up);
sensitive << clk.pos();
SC_METHOD(token_pid_sel_up);
sensitive << clk.pos();
 
SC_METHOD(ep0_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep1_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep2_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep3_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep4_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep5_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep6_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(ep7_dpid_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(uc_dpd_up);
sensitive << clk.pos();
 
SC_METHOD(sq_statemachine);
sensitive << clk.pos();
 
SC_METHOD(allow_pid_up);
sensitive << pid_DATA0 << pid_DATA1 << pid_DATA2 << pid_MDATA;
SC_METHOD(this_dpid_up);
sensitive << clk.pos();
SC_METHOD(data_pid_sel_up);
sensitive << this_dpid;
SC_METHOD(pid_seq_err_up);
sensitive << clk.pos();
 
SC_METHOD(in_token_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(out_token_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(setup_token_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(in_op_up);
sensitive << IN_ep << CTRL_ep << in_token;
SC_METHOD(out_op_up);
sensitive << OUT_ep << CTRL_ep << out_token;
 
SC_METHOD(uc_dpd_set_up);
sensitive << clk.pos();
SC_METHOD(abort_up);
sensitive << clk.pos();
 
SC_METHOD(rx_ack_up1);
sensitive << clk.pos();
SC_METHOD(rx_ack_up2);
sensitive << clk.pos();
SC_METHOD(rx_ack_up3);
sensitive << clk.pos();
 
SC_METHOD(tx_data_up1);
sensitive << rx_active;
SC_METHOD(tx_data_up2);
sensitive << clk.pos();
SC_METHOD(tx_data_up3);
sensitive << clk.pos();
 
SC_METHOD(pid_OUT_up);
sensitive << clk.pos();
SC_METHOD(pid_IN_up);
sensitive << clk.pos();
SC_METHOD(pid_PING_up);
sensitive << clk.pos();
SC_METHOD(pid_SETUP_up);
sensitive << clk.pos();
SC_METHOD(int_upid_up);
sensitive << clk.pos();
SC_METHOD(int_to_up);
sensitive << state << rx_ack_to << tx_data_to;
SC_METHOD(int_crc16_up);
sensitive << rx_data_done << crc16_err;
SC_METHOD(int_seqerr_up);
sensitive << clk.pos();
 
SC_METHOD(send_stall_up);
sensitive << clk.pos() << rst.neg();
 
SC_METHOD(state_up);
sensitive << clk.pos() << rst.neg();
SC_METHOD(pe_statemachine);
sensitive << state << pid_seq_err << idma_done << ep_full << ep_empty;
sensitive << token_valid << pid_ACK << rx_data_done << tx_data_to << crc16_err;
sensitive << rx_ack_to << pid_PING << txfr_iso << txfr_int << CTRL_ep;
sensitive << pid_IN << pid_OUT << IN_ep << OUT_ep << pid_SETUP << pid_SOF;
sensitive << match_r << abort << send_stall_r << send_stall;
}
 
};
 
#endif
 
/trunk/rtl/systemc/fifo_test.cpp
0,0 → 1,95
#include "systemc.h"
#include "usb_fifo64x8.h"
 
SC_MODULE(test) {
sc_in<bool> clk;
sc_out<bool> rst, clr;
sc_out<sc_uint<8> > din;
sc_in<sc_uint<8> > dout;
sc_out<bool> we, re;
sc_in<bool> empty, full;
 
int i;
 
void update(void) {
i = 0;
rst.write(false);
clr.write(false);
we.write(false);
re.write(false);
wait();
rst.write(true);
wait(clk.posedge_event());
we.write(true);
while (!full.read()) {
din.write(i++);
wait(clk.posedge_event());
wait(clk.negedge_event());
cout << "WR: " << din.read() << endl;
}
we.write(false);
wait(clk.posedge_event());
re.write(true);
while (!empty.read()) {
wait(clk.posedge_event());
wait(clk.negedge_event());
cout << "RD: " << dout.read() << endl;
}
re.write(false);
wait();
wait();
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive_pos(clk);
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 10.0, SC_NS);
sc_signal<sc_uint<8> > din, dout;
sc_signal<bool> rst, clr, we, re, empty, full;
 
usb_fifo64x8 i_fifo("FIFO");
test i_test("TEST");
 
i_fifo.clk(clk);
i_fifo.rst(rst);
i_fifo.clr(clr);
i_fifo.we(we);
i_fifo.din(din);
i_fifo.re(re);
i_fifo.dout(dout);
i_fifo.empty(empty);
i_fifo.full(full);
 
i_test.clk(clk);
i_test.rst(rst);
i_test.clr(clr);
i_test.din(din);
i_test.dout(dout);
i_test.we(we);
i_test.re(re);
i_test.empty(empty);
i_test.full(full);
 
sc_trace_file *log = sc_create_vcd_trace_file("FIFO_TEST");
sc_trace(log, clk, "Clock");
sc_trace(log, din, "DataIn");
sc_trace(log, dout, "DataOut");
sc_trace(log, empty, "Empty");
sc_trace(log, full, "Full");
 
//sc_start(1000, SC_NS);
sc_start();
 
sc_close_vcd_trace_file(log);
 
return 0;
}
 
/trunk/rtl/systemc/usb_fifo2.h
0,0 → 1,80
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Fast FIFO - 2 Entries Deep ////
//// ////
//// SystemC Version: usb_fifo2.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_fifo2.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_FIFO2_H
#define USB_FIFO2_H
 
SC_MODULE(usb_fifo2) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_in<bool> clr;
sc_in<sc_uint<8> > din;
sc_in<bool> we;
sc_out<sc_uint<8> > dout;
sc_in<bool> re;
 
// Local Signals
sc_uint<8> mem[2];
sc_signal<bool> wp;
sc_signal<bool> rp;
 
// Write and Read Pointers Update Functions
void wp_update(void);
void rp_update(void);
 
// Write and Read FIFO Functions
void write(void);
void read(void);
 
SC_CTOR(usb_fifo2) {
SC_METHOD(wp_update);
sensitive << clk.pos() << rst.neg();
SC_METHOD(rp_update);
sensitive << clk.pos() << rst.neg();
SC_METHOD(write);
sensitive << clk.pos();
SC_METHOD(read);
sensitive << rp << wp;
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_rx_phy.h
0,0 → 1,204
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RX PHY ////
//// ////
//// SystemC Version: usb_rx_phy.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_rx_phy.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_RX_PHY_H
#define USB_RX_PHY_H
 
enum RX_STATE {FS_IDLE, K1, J1, K2, J2, K3, J3, K4};
 
SC_MODULE(usb_rx_phy) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_out<bool> fs_ce;
sc_in<bool> rxd, rxdp, rxdn;
sc_out<sc_uint<8> > DataIn_o;
sc_out<bool> RxValid_o;
sc_out<bool> RxActive_o;
sc_out<bool> RxError_o;
sc_in<bool> RxEn_i;
sc_out<sc_uint<2> > LineState;
 
sc_signal<bool> rxd_t1, rxd_s1, rxd_s;
sc_signal<bool> rxdp_t1, rxdp_s1, rxdp_s;
sc_signal<bool> rxdn_t1, rxdn_s1, rxdn_s;
sc_signal<bool> synced_d;
sc_signal<bool> k, j, se0;
sc_signal<bool> rx_en, rx_active;
sc_signal<sc_uint<3> > bit_cnt;
sc_signal<bool> rx_valid, rx_valid1, rx_valid_r;
sc_signal<bool> shift_en;
sc_signal<bool> sd_r, sd_nrzi;
sc_signal<sc_uint<8> > hold_reg;
sc_signal<bool> drop_bit;
sc_signal<sc_uint<3> > one_cnt;
sc_signal<sc_uint<2> > dpll_state, dpll_next_state;
sc_signal<bool> fs_ce_d, change;
sc_signal<bool> rxdp_s1r, rxdn_s1r;
sc_signal<bool> lock_en;
sc_signal<bool> fs_ce_r1, fs_ce_r2, fs_ce_r3;
sc_signal<sc_uint<3> > fs_state, fs_next_state;
 
void rx_error_init(void);
void misc_logic_up(void);
void misc_logic_RxActive_up(void);
void misc_logic_RxValid_up(void);
void misc_logic_DataIn_up(void);
void misc_logic_LineState_up(void);
void si_up1(void); // Synchronize Inputs
void si_up2(void);
void si_up3(void);
void si_up4(void);
void dpll_up1(void);
void dpll_up2(void);
void dpll_up3(void);
void dpll_up4(void);
void dpll_up5(void);
void dpll_up6(void);
void dpll_up7(void);
void dpll_up8(void);
void dpll_statemachine(void);
void fsp_up(void); // Find Sync Pattern
void fsp_statemachine(void);
void gra_up1(void); // Generate RxActive
void gra_up2(void);
void nrzi_up1(void); // NRZI Decoder
void nrzi_up2(void);
void bsd_up1(void); // Bit Stuff Detect
void bsd_up2(void);
void spc_up1(void); // Serial/Parallel Converter
void spc_up2(void);
void grv_up1(void); // Generate RxValid
void grv_up2(void);
void grv_up3(void);
 
SC_CTOR(usb_rx_phy) {
#ifdef USB_SIMULATION
SC_METHOD(rx_error_init);
#else
RxError_o.write(false);
#endif
SC_METHOD(misc_logic_up);
sensitive << clk.pos();
SC_METHOD(misc_logic_RxActive_up);
sensitive << rx_active;
SC_METHOD(misc_logic_RxValid_up);
sensitive << rx_valid;
SC_METHOD(misc_logic_DataIn_up);
sensitive << hold_reg;
SC_METHOD(misc_logic_LineState_up);
sensitive << rxdp_s1 << rxdn_s1;
SC_METHOD(si_up1);
sensitive << clk.pos();
SC_METHOD(si_up2);
sensitive << clk.pos();
SC_METHOD(si_up3);
sensitive << clk.pos();
SC_METHOD(si_up4);
sensitive << rxdp_s << rxdn_s;
SC_METHOD(dpll_up1);
sensitive << rx_en;
SC_METHOD(dpll_up2);
sensitive << clk.pos();
SC_METHOD(dpll_up3);
sensitive << rxdp_s1 << rxdp_s1r << rxdn_s1 << rxdn_s1r;
SC_METHOD(dpll_up4);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(dpll_up5);
sensitive << clk.pos();
SC_METHOD(dpll_up6);
sensitive << clk.pos();
SC_METHOD(dpll_up7);
sensitive << clk.pos();
SC_METHOD(dpll_up8);
sensitive << clk.pos();
SC_METHOD(dpll_statemachine);
sensitive << dpll_state << lock_en << change;
SC_METHOD(fsp_up);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(fsp_statemachine);
sensitive << fs_state << fs_ce << k << j << rx_en;
SC_METHOD(gra_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(gra_up2);
sensitive << clk.pos();
SC_METHOD(nrzi_up1);
sensitive << clk.pos();
SC_METHOD(nrzi_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(bsd_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(bsd_up2);
sensitive << one_cnt;
SC_METHOD(spc_up1);
sensitive << clk.pos();
SC_METHOD(spc_up2);
sensitive << clk.pos();
SC_METHOD(grv_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(grv_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(grv_up3);
sensitive << clk.pos();
}
 
};
 
#endif
/trunk/rtl/systemc/usb_crc16.cpp
0,0 → 1,71
/////////////////////////////////////////////////////////////////////
//// ////
//// USB CRC16 ////
//// ////
//// SystemC Version: usb_crc16.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_crc16.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 "systemc.h"
#include "usb_crc16.h"
 
void usb_crc16::update(void) {
sc_uint<16> temp;
 
temp[0] = din.read()[7] ^ din.read()[6] ^ din.read()[5] ^ din.read()[4] ^ din.read()[3] ^ din.read()[2] ^
din.read()[1] ^ din.read()[0] ^ crc_in.read()[8] ^ crc_in.read()[9] ^ crc_in.read()[10] ^
crc_in.read()[11] ^ crc_in.read()[12] ^ crc_in.read()[13] ^ crc_in.read()[14] ^
crc_in.read()[15];
temp[1] = din.read()[7] ^ din.read()[6] ^ din.read()[5] ^ din.read()[4] ^ din.read()[3] ^ din.read()[2] ^
din.read()[1] ^ crc_in.read()[9] ^ crc_in.read()[10] ^ crc_in.read()[11] ^ crc_in.read()[12] ^
crc_in.read()[13] ^ crc_in.read()[14] ^ crc_in.read()[15];
temp[2] = din.read()[1] ^ din.read()[0] ^ crc_in.read()[8] ^ crc_in.read()[9];
temp[3] = din.read()[2] ^ din.read()[1] ^ crc_in.read()[9] ^ crc_in.read()[10];
temp[4] = din.read()[3] ^ din.read()[2] ^ crc_in.read()[10] ^ crc_in.read()[11];
temp[5] = din.read()[4] ^ din.read()[3] ^ crc_in.read()[11] ^ crc_in.read()[12];
temp[6] = din.read()[5] ^ din.read()[4] ^ crc_in.read()[12] ^ crc_in.read()[13];
temp[7] = din.read()[6] ^ din.read()[5] ^ crc_in.read()[13] ^ crc_in.read()[14];
temp[8] = din.read()[7] ^ din.read()[6] ^ crc_in.read()[0] ^ crc_in.read()[14] ^ crc_in.read()[15];
temp[9] = din.read()[7] ^ crc_in.read()[1] ^ crc_in.read()[15];
temp[10] = crc_in.read()[2];
temp[11] = crc_in.read()[3];
temp[12] = crc_in.read()[4];
temp[13] = crc_in.read()[5];
temp[14] = crc_in.read()[6];
temp[15] = din.read()[7] ^ din.read()[6] ^ din.read()[5] ^ din.read()[4] ^ din.read()[3] ^
din.read()[2] ^ din.read()[1] ^ din.read()[0] ^ crc_in.read()[7] ^ crc_in.read()[8] ^
crc_in.read()[9] ^ crc_in.read()[10] ^ crc_in.read()[11] ^ crc_in.read()[12] ^
crc_in.read()[13] ^ crc_in.read()[14] ^ crc_in.read()[15];
 
crc_out.write(temp);
}
 
/trunk/rtl/systemc/rx_test.cpp
0,0 → 1,84
#include "systemc.h"
#include "usb_rx_phy.h"
 
SC_MODULE(test) {
sc_in<bool> clk;
sc_out<bool> rst;
sc_in<bool> fs_ce;
sc_out<bool> rxd, rxdp, rxdn, RxEn_i;
sc_in<sc_uint<8> > DataIn_o;
sc_in<bool> RxValid_o, RxActive_o, RxError_o;
sc_in<sc_uint<2> > LineState_o;
 
int i;
 
void update(void) {
i = 0;
rst.write(false);
wait();
wait();
rst.write(true);
wait();
wait();
wait();
wait();
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive << clk.pos();
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.83, SC_NS);
sc_signal<bool> rst, fs_ce, rxd, rxdp, rxdn, RxValid_o, RxActive_o, RxError_o, RxEn_i;
sc_signal<sc_uint<8> > DataIn_o;
sc_signal<sc_uint<2> > LineState_o;
 
usb_rx_phy i_rx_phy("RX_PHY");
test i_test("TEST");
 
i_rx_phy.clk(clk);
i_rx_phy.rst(rst);
i_rx_phy.fs_ce(fs_ce);
i_rx_phy.rxd(rxd);
i_rx_phy.rxdn(rxdn);
i_rx_phy.rxdp(rxdp);
i_rx_phy.DataIn_o(DataIn_o);
i_rx_phy.LineState(LineState_o);
i_rx_phy.RxValid_o(RxValid_o);
i_rx_phy.RxActive_o(RxActive_o);
i_rx_phy.RxError_o(RxError_o);
i_rx_phy.RxEn_i(RxEn_i);
 
i_test.clk(clk);
i_test.rst(rst);
i_test.fs_ce(fs_ce);
i_test.rxd(rxd);
i_test.rxdn(rxdn);
i_test.rxdp(rxdp);
i_test.DataIn_o(DataIn_o);
i_test.LineState_o(LineState_o);
i_test.RxValid_o(RxValid_o);
i_test.RxActive_o(RxActive_o);
i_test.RxError_o(RxError_o);
i_test.RxEn_i(RxEn_i);
 
sc_trace_file *log = sc_create_vcd_trace_file("RX_TEST");
sc_trace(log, clk, "Clock");
sc_trace(log, rst, "Reset");
sc_trace(log, RxError_o, "RX_Error");
 
//sc_start(1000, SC_NS);
sc_start();
 
sc_close_vcd_trace_file(log);
 
return 0;
}
 
/trunk/rtl/systemc/usb_tx_phy.h
0,0 → 1,209
/////////////////////////////////////////////////////////////////////
//// ////
//// USB TX PHY ////
//// ////
//// SystemC Version: usb_tx_phy.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_tx_phy.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_TX_PHY_H
#define USB_TX_PHY_H
 
enum TX_STATE {TX_IDLE, TX_SOP, TX_DATA, TX_EOP1, TX_EOP2, TX_WAIT};
 
SC_MODULE(usb_tx_phy) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_in<bool> fs_ce;
sc_in<bool> phy_mode;
sc_out<bool> txdp, txdn, txoe;
sc_in<sc_uint<8> > DataOut_i;
sc_in<bool> TxValid_i;
sc_out<bool> TxReady_o;
 
sc_signal<sc_uint<3> > state, next_state;
sc_signal<bool> tx_ready, tx_ready_d;
sc_signal<bool> ld_sop_d, ld_data, ld_data_d, ld_eop_d;
sc_signal<bool> tx_ip, tx_ip_sync;
sc_signal<sc_uint<3> > bit_cnt;
sc_signal<sc_uint<8> > hold_reg;
sc_signal<bool> sd_raw_o;
sc_signal<bool> hold;
sc_signal<bool> data_done, sft_done, sft_done_r, sft_done_e, eop_done;
sc_signal<sc_uint<3> > one_cnt;
sc_signal<bool> stuff;
sc_signal<bool> sd_bs_o, sd_nrzi_o;
sc_signal<bool> append_eop, append_eop_sync1, append_eop_sync2, append_eop_sync3;
sc_signal<bool> txoe_r1, txoe_r2;
 
void misc_logic_up1(void);
void misc_logic_up2(void);
void tpi_up1(void); // Transmit in Progress Indicator
void tpi_up2(void);
void tpi_up3(void);
void sr_up1(void); // Shift Register
void sr_up2(void);
void sr_up3(void);
void sr_up4(void);
void sr_up5(void);
void sr_hold_up(void);
void sr_sft_done_e_up(void);
void bs_up1(void); // Bit Stuffer
void bs_up2(void);
void bs_stuff_up(void);
void nrzi_up(void); // NRZI Encoder
void eop_up1(void); // EOP Append Logic
void eop_up2(void);
void eop_up3(void);
void eop_up4(void);
void eop_done_up(void);
void oel_up1(void); // Output Enable Logic
void oel_up2(void);
void oel_up3(void);
void or_up(void); // Output Registers
void tx_statemachine(void);
void tx_state_up(void);
 
SC_CTOR(usb_tx_phy) {
SC_METHOD(misc_logic_up1);
sensitive << clk.pos();
SC_METHOD(misc_logic_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(tpi_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(tpi_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(tpi_up3);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(sr_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(sr_up2);
sensitive << clk.pos();
SC_METHOD(sr_up3);
sensitive << clk.pos();
SC_METHOD(sr_up4);
sensitive << clk.pos();
SC_METHOD(sr_up5);
sensitive << clk.pos();
SC_METHOD(sr_hold_up);
sensitive << stuff;
SC_METHOD(sr_sft_done_e_up);
sensitive << sft_done << sft_done_r;
SC_METHOD(bs_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(bs_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(bs_stuff_up);
sensitive << one_cnt;
SC_METHOD(nrzi_up);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(eop_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(eop_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(eop_up3);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(eop_up4);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(eop_done_up);
sensitive << append_eop_sync3;
SC_METHOD(oel_up1);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(oel_up2);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(oel_up3);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(or_up);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
SC_METHOD(tx_statemachine);
sensitive << state << TxValid_i << data_done << sft_done_e << eop_done << fs_ce;
SC_METHOD(tx_state_up);
sensitive << clk.pos();
#ifdef USB_ASYNC_RESET
sensitive << rst.neg();
#endif
}
 
};
 
#endif
/trunk/rtl/systemc/usb_ocp_test.cpp
0,0 → 1,1411
/////////////////////////////////////////////////////////////////////
//// ////
//// 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_ENABLE
 
SC_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);
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
}
 
void data_out(sc_uint<7> fa, int pl_size) {
int len;
 
send_token(fa, 0, USBF_T_PID_OUT);
 
wait(clk.posedge_event());
 
if (!setup_pid.read())
send_data(USBF_T_PID_DATA0, pl_size, 1);
else
send_data(USBF_T_PID_DATA1, pl_size, 1);
 
setup_pid.write(!setup_pid.read());
 
utmi_recv_pack(&len);
 
if (txmem[0] != 0xd2) {
cout << "ERROR: Ack mismatch. Expected: 0xd2, Got: " << txmem[0] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
if (len != 1) {
cout << "ERROR: SETUP: Length mismatch. Expected: 1, Got: " << len <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
}
 
// Enumeration Test -> Endpoint 0
void setup0(void) {
cout << endl;
 
cout << "The Default Time Unit is: " << sc_get_default_time_unit().to_string() << endl << endl;
 
cout << "**************************************************" << endl;
cout << "*** CONTROL EP TEST 0 ***" << endl;
cout << "**************************************************" << endl << endl;
 
cout << "Setting Address ..." << endl << endl;
 
send_setup(0x00, 0x00, SET_ADDRESS, 0x0012, 0x0000, 0x0000);
data_in(0x00,0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0100, 0x0000, 0x0012);
data_in(0x12, 18);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0200, 0x0000, 0x0009);
data_in(0x12, 9);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0200, 0x0000, 0x003c);
data_in(0x12, 60);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0300, 0x0000, 0x0008);
data_in(0x12, 8);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0301, 0x0416, 0x001a);
data_in(0x12, 26);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0302, 0x0416, 0x001c);
data_in(0x12, 28);
data_out(0x12, 0);
 
cout << "Getting Descriptor ..." << endl << endl;
 
send_setup(0x12, 0x80, GET_DESCRIPTOR, 0x0303, 0x0416, 0x0036);
data_in(0x12, 54);
data_out(0x12, 0);
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// ISO IN Test -> Endpoint 1
void in1(void) {
sc_uint<7> my_fa;
int rlen, fc;
sc_uint<8> fd;
int pack_cnt, pack_cnt_max, pack_sz, pack_sz_max;
sc_uint<8> x;
sc_uint<4> pid, expect_pid;
sc_uint<32> data;
// bool pid_cnt;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** ISOCHRONOUS IN EP TEST 1 ***" << endl;
cout << "**************************************************" << endl << endl;
 
send_sof(0x000);
 
pack_sz_max = 256;
pack_cnt_max = 4;
 
// pid_cnt = false;
my_fa = 0x12;
 
m_addr.write(0x00000001);
m_cmd.write(0x0);
 
for (pack_sz = 0; pack_sz <= pack_sz_max; pack_sz += 32) {
cout << "PL Size: " << pack_sz << endl;
 
for (pack_cnt = 0; pack_cnt < pack_cnt_max; pack_cnt++) {
buffer1_last = 0;
for (fc = 0; fc < pack_sz; fc++) {
while (s_flag.read()[1])
wait(clk.posedge_event());
 
x = (sc_uint<8>)(255.0 * rand() / (RAND_MAX + 1.0));
m_data.write(x);
buffer0[fc] = x;
m_cmd.write(0x1);
wait(clk.posedge_event());
m_cmd.write(0x0);
wait(clk.posedge_event());
}
m_cmd.write(0x0);
wait(clk.posedge_event());
 
// Send Data
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
send_token(my_fa, 1, USBF_T_PID_IN);
wait(clk.posedge_event());
 
recv_packet(&pid, &rlen);
 
// if (pid_cnt)
// expect_pid = 0xb;
// else
// expect_pid = 0x3;
expect_pid = 0x3;
 
if (pid != expect_pid) {
cout << "ERROR: PID mismatch. Expected: " << expect_pid << ", Got: " << pid <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
// pid_cnt = !pid_cnt;
 
if (rlen != pack_sz) {
cout << "ERROR: Size mismatch. Expected: " << pack_sz << ", Got: " << rlen <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 4; i++)
wait(clk.posedge_event());
 
// Verify Data
for (fc = 0; fc < pack_sz; fc++) {
x = buffer0[fc];
if (buffer1[fc] != x) {
cout << "ERROR: Data (" << fc << ") mismatch. Expected: " << x << ", Got: " << buffer1[fc] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
}
}
for (i = 0; i < 50; i++)
wait(clk.posedge_event());
}
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// ISO OUT Test -> Endpoint 2
void out2(void) {
sc_uint<7> my_fa;
sc_uint<32> data;
int n, no_pack, no_pack_max, pl_sz, pl_sz_max;
bool pid;
sc_uint<8> x;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** ISOCHRONOUS OUT EP TEST 2 ***" << endl;
cout << "**************************************************" << endl << endl;
 
no_pack_max = 4;
pl_sz_max = 256;
 
my_fa = 0x12;
 
m_addr.write(0x00000002);
m_cmd.write(0x0);
 
for (pl_sz = 0; pl_sz <= pl_sz_max; pl_sz += 32) {
pid = false;
 
cout << "PL Size: " << pl_sz << endl;
 
for (n = 0; n < 4096; n++)
buffer1[n] = n;
 
buffer1_last = 0;
 
no_pack = 0;
while (true) {
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
 
send_token(my_fa, 2, USBF_T_PID_OUT);
wait(clk.posedge_event());
 
if (!pid)
send_data(USBF_T_PID_DATA0, pl_sz, 1);
else
send_data(USBF_T_PID_DATA1, pl_sz, 1);
for (i = 0; i < 10; i++)
wait(clk2.posedge_event());
for (n = 0; n < pl_sz; n++) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
 
while (s_flag.read()[0]) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
}
 
if (buffer1[n + (pl_sz * no_pack)] != s_data.read()) {
cout << "ERROR: DATA mismatch. Expected: " << s_data.read() << ", Got: " << buffer1[n + (pl_sz * no_pack)] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
m_cmd.write(0x2);
wait(clk2.posedge_event());
wait(clk2.negedge_event());
}
m_cmd.write(0x0);
wait(clk2.posedge_event());
 
no_pack++;
if (no_pack == no_pack_max)
break;
}
wait(clk.posedge_event());
}
 
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// BULK IN Test -> Endpoint 3
void in3(void) {
sc_uint<7> my_fa;
int rlen, fc;
sc_uint<8> fd;
int pack_cnt, pack_cnt_max, pack_sz, pack_sz_max;
sc_uint<8> x;
sc_uint<4> pid, expect_pid;
sc_uint<32> data;
bool pid_cnt;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** BULK IN EP TEST 3 ***" << endl;
cout << "**************************************************" << endl << endl;
 
send_sof(0x000);
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = false;
my_fa = 0x12;
 
m_addr.write(0x00000003);
m_cmd.write(0x0);
 
for (pack_sz = 0; pack_sz <= pack_sz_max; pack_sz += 8) {
cout << "PL Size: " << pack_sz << endl;
 
for (pack_cnt = 0; pack_cnt < pack_cnt_max; pack_cnt++) {
buffer1_last = 0;
for (fc = 0; fc < pack_sz; fc++) {
while (s_flag.read()[1])
wait(clk.posedge_event());
 
x = (sc_uint<8>)(255.0 * rand() / (RAND_MAX + 1.0));
m_data.write(x);
buffer0[fc] = x;
m_cmd.write(0x1);
wait(clk.posedge_event());
m_cmd.write(0x0);
wait(clk.posedge_event());
}
m_cmd.write(0x0);
wait(clk.posedge_event());
 
// Send Data
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
send_token(my_fa, 3, USBF_T_PID_IN);
wait(clk.posedge_event());
 
recv_packet(&pid, &rlen);
 
if (pid_cnt)
expect_pid = 0xb;
else
expect_pid = 0x3;
// expect_pid = 0x3;
 
if (pid != expect_pid) {
cout << "ERROR: PID mismatch. Expected: " << expect_pid << ", Got: " << pid <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
pid_cnt = !pid_cnt;
 
if (rlen != pack_sz) {
cout << "ERROR: Size mismatch. Expected: " << pack_sz << ", Got: " << rlen <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 4; i++)
wait(clk.posedge_event());
 
send_token(my_fa, 3, USBF_T_PID_ACK);
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
 
// Verify Data
for (fc = 0; fc < pack_sz; fc++) {
x = buffer0[fc];
if (buffer1[fc] != x) {
cout << "ERROR: Data (" << fc << ") mismatch. Expected: " << x << ", Got: " << buffer1[fc] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
}
}
for (i = 0; i < 50; i++)
wait(clk.posedge_event());
}
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// BULK OUT Test -> Endpoint 4
void out4(void) {
sc_uint<7> my_fa;
sc_uint<32> data;
int n, len, no_pack, no_pack_max, pl_sz, pl_sz_max;
bool pid;
sc_uint<8> x;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** BULK OUT EP TEST 4 ***" << endl;
cout << "**************************************************" << endl << endl;
 
no_pack_max = 4;
pl_sz_max = 64;
 
my_fa = 0x12;
 
m_addr.write(0x00000004);
m_cmd.write(0x0);
 
for (pl_sz = 0; pl_sz <= pl_sz_max; pl_sz += 8) {
pid = false;
 
cout << "PL Size: " << pl_sz << endl;
 
for (n = 0; n < 4096; n++)
buffer1[n] = n;
 
buffer1_last = 0;
 
no_pack = 0;
while (true) {
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
 
send_token(my_fa, 4, USBF_T_PID_OUT);
wait(clk.posedge_event());
 
if (!pid)
send_data(USBF_T_PID_DATA0, pl_sz, 1);
else
send_data(USBF_T_PID_DATA1, pl_sz, 1);
pid = !pid;
 
utmi_recv_pack(&len);
 
if (txmem[0] != 0xd2) {
cout << "ERROR: ACK mismatch. Expected: 0xd2, Got: " << txmem[0] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
if (len != 1) {
cout << "ERROR: Size mismatch. Expected: 1, Got: " << len <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
wait(clk.posedge_event());
 
for (i = 0; i < 10; i++)
wait(clk2.posedge_event());
for (n = 0; n < pl_sz; n++) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
 
while (s_flag.read()[0]) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
}
 
if (buffer1[n + (pl_sz * no_pack)] != s_data.read()) {
cout << "ERROR: DATA mismatch. Expected: " << s_data.read() << ", Got: " << buffer1[n + (pl_sz * no_pack)] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
m_cmd.write(0x2);
wait(clk2.posedge_event());
wait(clk2.negedge_event());
}
m_cmd.write(0x0);
wait(clk2.posedge_event());
 
no_pack++;
if (no_pack == no_pack_max)
break;
}
wait(clk.posedge_event());
}
 
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// INT IN Test -> Endpoint 5
void in5(void) {
sc_uint<7> my_fa;
int rlen, fc;
sc_uint<8> fd;
int pack_cnt, pack_cnt_max, pack_sz, pack_sz_max;
sc_uint<8> x;
sc_uint<4> pid, expect_pid;
sc_uint<32> data;
bool pid_cnt;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** INTERRUPT IN EP TEST 5 ***" << endl;
cout << "**************************************************" << endl << endl;
 
send_sof(0x000);
 
pack_sz_max = 64;
pack_cnt_max = 4;
 
pid_cnt = false;
my_fa = 0x12;
 
m_addr.write(0x00000005);
m_cmd.write(0x0);
 
for (pack_sz = 0; pack_sz <= pack_sz_max; pack_sz += 8) {
cout << "PL Size: " << pack_sz << endl;
 
for (pack_cnt = 0; pack_cnt < pack_cnt_max; pack_cnt++) {
buffer1_last = 0;
for (fc = 0; fc < pack_sz; fc++) {
while (s_flag.read()[1])
wait(clk.posedge_event());
 
x = (sc_uint<8>)(255.0 * rand() / (RAND_MAX + 1.0));
m_data.write(x);
buffer0[fc] = x;
m_cmd.write(0x1);
wait(clk.posedge_event());
m_cmd.write(0x0);
wait(clk.posedge_event());
}
m_cmd.write(0x0);
wait(clk.posedge_event());
 
// Send Data
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
send_token(my_fa, 5, USBF_T_PID_IN);
wait(clk.posedge_event());
 
recv_packet(&pid, &rlen);
 
if (pack_sz == 0)
expect_pid = 0xa;
else if (pid_cnt)
expect_pid = 0xb;
else
expect_pid = 0x3;
// expect_pid = 0x3;
 
if (pid != expect_pid) {
cout << "ERROR: PID mismatch. Expected: " << expect_pid << ", Got: " << pid <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
pid_cnt = !pid_cnt;
 
if (rlen != pack_sz) {
cout << "ERROR: Size mismatch. Expected: " << pack_sz << ", Got: " << rlen <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
for (i = 0; i < 4; i++)
wait(clk.posedge_event());
 
send_token(my_fa, 5, USBF_T_PID_ACK);
 
for (i = 0; i < 5; i++)
wait(clk.posedge_event());
 
// Verify Data
for (fc = 0; fc < pack_sz; fc++) {
x = buffer0[fc];
if (buffer1[fc] != x) {
cout << "ERROR: Data (" << fc << ") mismatch. Expected: " << x << ", Got: " << buffer1[fc] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
}
}
for (i = 0; i < 50; i++)
wait(clk.posedge_event());
}
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
// INT OUT Test -> Endpoint 6
void out6(void) {
sc_uint<7> my_fa;
sc_uint<32> data;
int n, len, no_pack, no_pack_max, pl_sz, pl_sz_max;
bool pid;
sc_uint<8> x;
 
cout << endl;
 
cout << "**************************************************" << endl;
cout << "*** INTERRUPT OUT EP TEST 6 ***" << endl;
cout << "**************************************************" << endl << endl;
 
no_pack_max = 4;
pl_sz_max = 64;
 
my_fa = 0x12;
 
m_addr.write(0x00000006);
m_cmd.write(0x0);
 
for (pl_sz = 0; pl_sz <= pl_sz_max; pl_sz += 8) {
pid = false;
 
cout << "PL Size: " << pl_sz << endl;
 
for (n = 0; n < 4096; n++)
buffer1[n] = n;
 
buffer1_last = 0;
 
no_pack = 0;
while (true) {
wait(clk.posedge_event());
send_sof(0x000);
wait(clk.posedge_event());
 
send_token(my_fa, 6, USBF_T_PID_OUT);
wait(clk.posedge_event());
 
if (!pid)
send_data(USBF_T_PID_DATA0, pl_sz, 1);
else
send_data(USBF_T_PID_DATA1, pl_sz, 1);
pid = !pid;
 
utmi_recv_pack(&len);
 
if (txmem[0] != 0xd2) {
cout << "ERROR: ACK mismatch. Expected: 0xd2, Got: " << txmem[0] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
if (len != 1) {
cout << "ERROR: Size mismatch. Expected: 1, Got: " << len <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
wait(clk.posedge_event());
 
for (i = 0; i < 10; i++)
wait(clk2.posedge_event());
for (n = 0; n < pl_sz; n++) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
 
while (s_flag.read()[0]) {
m_cmd.write(0x0);
wait(clk2.posedge_event());
wait(clk2.posedge_event());
}
 
if (buffer1[n + (pl_sz * no_pack)] != s_data.read()) {
cout << "ERROR: DATA mismatch. Expected: " << s_data.read() << ", Got: " << buffer1[n + (pl_sz * no_pack)] <<
" (" << sc_simulation_time() << ")" << endl << endl;
error_cnt++;
}
 
m_cmd.write(0x2);
wait(clk2.posedge_event());
wait(clk2.negedge_event());
}
m_cmd.write(0x0);
wait(clk2.posedge_event());
 
no_pack++;
if (no_pack == no_pack_max)
break;
}
wait(clk.posedge_event());
}
 
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
cout << endl;
 
show_errors();
 
cout << "**************************************************" << endl;
cout << "*** TEST DONE ... ***" << endl;
cout << "**************************************************" << endl << endl;
}
 
/////////////////////////////////////////////////////////////////////
 
void rx1_update(void) {
rxdp.write(!usb_reset.read() && txdp2.read());
rxdn.write(!usb_reset.read() && txdn2.read());
}
 
void rx2_update(void) {
rxdp2.write(!usb_reset.read() && txdp.read());
rxdn2.write(!usb_reset.read() && txdn.read());
}
 
void watchdog(void) {
if (txdp.read() || txdp2.read())
wd_cnt.write(0);
else
wd_cnt.write(wd_cnt.read() + 1);
}
 
void wd_cnt_mon(void) {
if (wd_cnt.read() > 5000) {
cout << "**********************************" << endl;
cout << "ERROR: Watch Dog Counter Expired" << endl;
cout << "**********************************" << endl << endl;
sc_stop();
}
}
 
void init(void) {
usb_reset.write(false);
tx_valid.write(false);
error_cnt = 0;
wd_cnt.write(0);
rst.write(false);
m_cmd.write(0x4);
m_addr.write(0x00000000);
 
for (i = 0; i < 10; i++) wait(clk.posedge_event());
rst.write(true);
 
for (i = 0; i < 50; i++) wait(clk.posedge_event());
usb_reset.write(true);
 
for (i = 0; i < 300; i++) wait(clk.posedge_event());
usb_reset.write(false);
 
for (i = 0; i < 10; i++) wait(clk.posedge_event());
 
setup0();
in1();
out2();
in3();
out4();
in5();
out6();
 
for (i = 0; i < 500; i++) wait(clk.posedge_event());
sc_stop();
}
 
SC_CTOR(test) {
SC_METHOD(rx1_update);
sensitive << usb_reset << txdp2 << txdn2;
SC_METHOD(rx2_update);
sensitive << usb_reset << txdp << txdn;
SC_METHOD(watchdog);
sensitive << clk.pos();
SC_METHOD(wd_cnt_mon);
sensitive << wd_cnt;
SC_THREAD(init);
sensitive << clk.pos();
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.84, SC_NS);
sc_clock clk2("clock2", 20.84, SC_NS);
 
sc_signal<bool> rst, vcc;
 
sc_signal<bool> rx_dp1, rx_dn1, tx_dp1, tx_dn1;
sc_signal<bool> tb_rx_valid, tb_rx_active, tb_rx_error;
sc_signal<bool> tb_tx_valid, tb_tx_ready;
sc_signal<sc_uint<8> > tb_rx_data, tb_tx_data;
 
sc_signal<bool> rx_dp2, rx_dn2, tx_dp2, tx_dn2;
sc_signal<sc_uint<8> > SData, MData, SFlag;
sc_signal<sc_uint<32> > MAddr;
sc_signal<sc_uint<3> > MCmd;
sc_signal<sc_uint<2> > SResp;
sc_signal<bool> SInterrupt, SError, SCmdAccept;
 
sc_signal<bool> usb_rst_nc, txoe_nc, tx_oe_nc;
sc_signal<sc_uint<2> > line_nc;
 
usb_phy i_phy("HOST_PHY");
usb_ocp i_ocp("USB_OCP");
test i_test("TEST");
 
i_phy.clk(clk);
i_phy.rst(rst);
i_phy.phy_tx_mode(vcc);
i_phy.usb_rst(usb_rst_nc);
i_phy.txdp(tx_dp1);
i_phy.txdn(tx_dn1);
i_phy.txoe(txoe_nc);
i_phy.rxd(rx_dp1);
i_phy.rxdp(rx_dp1);
i_phy.rxdn(rx_dn1);
i_phy.DataOut_i(tb_tx_data);
i_phy.TxValid_i(tb_tx_valid);
i_phy.TxReady_o(tb_tx_ready);
i_phy.DataIn_o(tb_rx_data);
i_phy.RxValid_o(tb_rx_valid);
i_phy.RxActive_o(tb_rx_active);
i_phy.RxError_o(tb_rx_error);
i_phy.LineState_o(line_nc);
 
i_ocp.Clk(clk2);
i_ocp.Reset_n(rst);
i_ocp.tx_dp(tx_dp2);
i_ocp.tx_dn(tx_dn2);
i_ocp.tx_oe(tx_oe_nc);
i_ocp.rx_dp(rx_dp2);
i_ocp.rx_dn(rx_dn2);
i_ocp.rx_d(rx_dp2);
i_ocp.SInterrupt(SInterrupt);
i_ocp.SFlag(SFlag);
i_ocp.SError(SError);
i_ocp.MAddr(MAddr);
i_ocp.MCmd(MCmd);
i_ocp.MData(MData);
i_ocp.SCmdAccept(SCmdAccept);
i_ocp.SData(SData);
i_ocp.SResp(SResp);
 
i_test.clk(clk);
i_test.rst(rst);
i_test.txdp(tx_dp1);
i_test.txdn(tx_dn1);
i_test.rxdp(rx_dp1);
i_test.rxdn(rx_dn1);
i_test.dout(tb_tx_data);
i_test.tx_valid(tb_tx_valid);
i_test.tx_ready(tb_tx_ready);
i_test.din(tb_rx_data);
i_test.rx_valid(tb_rx_valid);
i_test.rx_active(tb_rx_active);
i_test.rx_error(tb_rx_error);
 
i_test.clk2(clk2);
i_test.txdp2(tx_dp2);
i_test.txdn2(tx_dn2);
i_test.rxdp2(rx_dp2);
i_test.rxdn2(rx_dn2);
i_test.s_int(SInterrupt);
i_test.s_flag(SFlag);
i_test.s_error(SError);
i_test.m_addr(MAddr);
i_test.m_cmd(MCmd);
i_test.m_data(MData);
i_test.s_cmd_accept(SCmdAccept);
i_test.s_data(SData);
i_test.s_resp(SResp);
 
vcc.write(true);
 
#ifdef VCD_OUTPUT_ENABLE
sc_trace_file *vcd_log = sc_create_vcd_trace_file("USB_TEST");
sc_trace(vcd_log, clk2, "Clk");
sc_trace(vcd_log, rst, "Reset_n");
sc_trace(vcd_log, MAddr, "MAddr");
sc_trace(vcd_log, MCmd, "MCmd");
sc_trace(vcd_log, MData, "MData");
sc_trace(vcd_log, SData, "SData");
sc_trace(vcd_log, SCmdAccept, "SCmdAccept");
sc_trace(vcd_log, SResp, "SResp");
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_trace_file *wif_log = sc_create_wif_trace_file("USB_TEST");
sc_trace(wif_log, clk2, "Clk");
sc_trace(wif_log, rst, "Reset_n");
sc_trace(wif_log, MAddr, "MAddr");
sc_trace(wif_log, MCmd, "MCmd");
sc_trace(wif_log, MData, "MData");
sc_trace(wif_log, SData, "SData");
sc_trace(wif_log, SCmdAccept, "SCmdAccept");
sc_trace(wif_log, SResp, "SResp");
#endif
 
srand((unsigned int)(time(NULL) & 0xffffffff));
sc_start();
 
#ifdef VCD_OUTPUT_ENABLE
sc_close_vcd_trace_file(vcd_log);
#endif
 
#ifdef WIF_OUTPUT_ENABLE
sc_close_wif_trace_file(wif_log);
#endif
 
return 0;
}
 
/trunk/rtl/systemc/tx_test.cpp
0,0 → 1,77
#include "systemc.h"
#include "usb_tx_phy.h"
 
SC_MODULE(test) {
sc_in<bool> clk;
sc_out<bool> rst, fs_ce, phy_tx_mode;
sc_in<bool> txdp, txdn, txoe;
sc_out<sc_uint<8> > DataOut_i;
sc_out<bool> TxValid_i;
sc_in<bool> TxReady_o;
 
int i;
 
void update(void) {
i = 0;
rst.write(false);
wait();
wait();
rst.write(true);
wait();
wait();
wait();
wait();
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive << clk.pos();
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.83, SC_NS);
sc_signal<bool> rst, fs_ce, phy_tx_mode, txdp, txdn, txoe, TxValid_i, TxReady_o;
sc_signal<sc_uint<8> > DataOut_i;
 
usb_tx_phy i_tx_phy("TX_PHY");
test i_test("TEST");
 
i_tx_phy.clk(clk);
i_tx_phy.rst(rst);
i_tx_phy.fs_ce(fs_ce);
i_tx_phy.phy_mode(phy_tx_mode);
i_tx_phy.txdp(txdp);
i_tx_phy.txdn(txdn);
i_tx_phy.txoe(txoe);
i_tx_phy.DataOut_i(DataOut_i);
i_tx_phy.TxValid_i(TxValid_i);
i_tx_phy.TxReady_o(TxReady_o);
 
i_test.clk(clk);
i_test.rst(rst);
i_test.fs_ce(fs_ce);
i_test.phy_tx_mode(phy_tx_mode);
i_test.txdp(txdp);
i_test.txdn(txdn);
i_test.txoe(txoe);
i_test.DataOut_i(DataOut_i);
i_test.TxValid_i(TxValid_i);
i_test.TxReady_o(TxReady_o);
 
sc_trace_file *log = sc_create_vcd_trace_file("TX_TEST");
sc_trace(log, clk, "Clock");
sc_trace(log, rst, "Reset");
 
//sc_start(1000, SC_NS);
sc_start();
 
sc_close_vcd_trace_file(log);
 
return 0;
}
 
/trunk/rtl/systemc/usb_fifo64x8.h
0,0 → 1,115
/////////////////////////////////////////////////////////////////////
//// ////
//// USB FIFO ////
//// ////
//// SystemC Version: usb_fifo64x8.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_fifo_sc_a.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_FIFO64X8_H
#define USB_FIFO64X8_H
 
#include "usb_ram64x8.h"
 
#define FIFO_ASYNC_RESET
//#define FIFO_ASYNC_RESET << rst.neg()
 
SC_MODULE(usb_fifo64x8) {
 
private:
 
sc_signal<bool> vcc;
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_in<bool> clr;
sc_in<bool> we;
sc_in<sc_uint<8> > din;
sc_in<bool> re;
sc_out<sc_uint<8> > dout;
sc_out<bool> empty;
sc_out<bool> full;
 
sc_signal<sc_uint<6> > wp, wp_pl1, wp_pl2;
sc_signal<sc_uint<6> > rp, rp_pl1;
sc_signal<bool> gb, n_rst;
 
usb_ram64x8 *i_ram;
 
void write_pointer_update(void);
void read_pointer_update(void);
void future_pointers_update(void);
void fe_gb_update(void);
void fe_full_update(void);
void fe_empty_update(void);
void reset_update(void);
// ~usb_fifo64x8(void);
 
SC_CTOR(usb_fifo64x8) {
vcc.write(true);
 
SC_METHOD(write_pointer_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(read_pointer_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(future_pointers_update);
sensitive << wp << rp;
SC_METHOD(fe_gb_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(fe_full_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(fe_empty_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(reset_update);
sensitive << rst;
 
i_ram = new usb_ram64x8("RAM64X8");
i_ram->rclk(clk);
i_ram->rrst(n_rst);
i_ram->rce(vcc);
i_ram->oe(vcc);
i_ram->raddr(rp);
i_ram->dout(dout);
i_ram->wclk(clk);
i_ram->wrst(n_rst);
i_ram->wce(vcc);
i_ram->we(we);
i_ram->waddr(wp);
i_ram->din(din);
}
 
};
 
#endif
 
/trunk/rtl/systemc/rom_test.cpp
0,0 → 1,62
#include <stdio.h>
 
#include "systemc.h"
#include "usb_rom.h"
 
SC_MODULE(test) {
sc_in<bool> clk;
sc_out<sc_uint<8> > adr;
sc_in<sc_uint<8> > dout;
 
int i;
 
void update(void) {
i = 0;
for (i = 0; i < 256; i++) {
adr.write(i);
wait(clk.posedge_event());
wait(clk.negedge_event());
fprintf(stdout, "ROM[%x]: %x\n", i, dout.read().to_uint());
}
wait();
wait();
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive_pos(clk);
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 10.0, SC_NS);
sc_signal<sc_uint<8> > adr, dout;
 
usb_rom i_rom("ROM");
test i_test("TEST");
 
i_rom.clk(clk);
i_rom.adr(adr);
i_rom.dout(dout);
 
i_test.clk(clk);
i_test.adr(adr);
i_test.dout(dout);
 
sc_trace_file *log = sc_create_vcd_trace_file("ROM_TEST");
sc_trace(log, clk, "Clock");
sc_trace(log, adr, "Address");
sc_trace(log, dout, "ROM_Data");
 
//sc_start(1000, SC_NS);
sc_start();
 
sc_close_vcd_trace_file(log);
 
return 0;
}
 
/trunk/rtl/systemc/Makefile
0,0 → 1,15
TARGET_ARCH = linux
 
CC = g++
OPT = -O3 -mcpu=pentiumpro
DEBUG = -g
OTHER = -Wall -Wno-deprecated
EXTRA_CFLAGS = $(OPT) $(OTHER)
# EXTRA_CFLAGS = $(DEBUG) $(OTHER)
 
MODULE = usb
SRCS = usb_ocp_test.cpp usb_ocp.cpp usb_core.cpp usb_fifo512x8.cpp usb_fifo128x8.cpp usb_fifo64x8.cpp usb_ram512x8.cpp usb_ram128x8.cpp usb_ram64x8.cpp usb_phy.cpp usb_tx_phy.cpp usb_rx_phy.cpp usb_sie.cpp usb_pa_sie.cpp usb_pd_sie.cpp usb_pe_sie.cpp usb_dma.cpp usb_fifo2.cpp usb_ep0.cpp usb_crc5.cpp usb_crc16.cpp
OBJS = $(SRCS:.cpp=.o)
 
include Makefile.defs
 
/trunk/rtl/systemc/usb_ep0.cpp
0,0 → 1,824
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Control Endpoint (Endpoint Zero) ////
//// Internal Setup Engine ////
//// ////
//// SystemC Version: usb_ep0.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_ctrl.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 "systemc.h"
#include "usb_ep0.h"
 
void usb_ep0::ep0_re_up(void) {
ep0_re.write(fifo_re1.read());
}
 
void usb_ep0::fifo_empty_up(void) {
fifo_empty.write(ep0_stat.read()[1]);
}
 
void usb_ep0::fifo_full_up(void) {
fifo_full.write(ep0_stat.read()[2]);
}
 
// For this implementation we do not implement HALT for the
// device nor for any of the endpoints. This is useless for
// this device, but can be added here later ...
// FYI, we report device/endpoint errors via interrupts,
// instead of halting the entire or part of the device, much
// nicer for non-critical errors
void usb_ep0::clr_halt_up(void) {
clr_halt.write(ctrl_setup.read());
}
 
void usb_ep0::addressed_up(void) {
if (!rst.read())
addressed.write(false);
else if (set_address.read())
addressed.write(true);
}
 
void usb_ep0::configured_up(void) {
if (!rst.read())
configured.write(false);
else if (set_config.read())
configured.write(true);
}
 
void usb_ep0::halt_up(void) {
if (!rst.read())
halt.write(false);
else if (clr_halt.read())
halt.write(false);
else if (set_halt.read())
halt.write(true);
}
 
void usb_ep0::rom_adr_up1(void) {
sc_uint<4> sel1, sel2;
 
sel1 = wValue.read().range(11, 8);
sel2 = wValue.read().range(3, 0);
 
switch (sel1) {// synopsys full_case parallel_case
case 1: rom_start_d.write(ROM_START0); break;
case 2: rom_start_d.write(ROM_START1); break;
case 3: switch (sel2) {// synopsys full_case parallel_case
case 0: rom_start_d.write(ROM_START2A); break;
case 1: rom_start_d.write(ROM_START2B); break;
case 2: rom_start_d.write(ROM_START2C); break;
case 3: rom_start_d.write(ROM_START2D); break;
default:rom_start_d.write(ROM_START2A); break;
}
break;
default:rom_start_d.write(0); break;
}
}
 
void usb_ep0::rom_adr_up2(void) {
if (!rst.read())
rom_adr.write(0);
else if (rom_sel.read() && !rom_sel_r.read())
rom_adr.write(rom_start_d.read());
else if (rom_sel.read() && !fifo_full.read())
rom_adr.write(rom_adr.read() + 1);
}
 
void usb_ep0::rom_size_up1(void) {
sc_uint<4> sel1, sel2;
 
sel1 = wValue.read().range(11, 8);
sel2 = wValue.read().range(3, 0);
 
switch (sel1) {// synopsys full_case parallel_case
case 1: rom_size_dd.write(ROM_SIZE0); break;
case 2: rom_size_dd.write(ROM_SIZE1); break;
case 3: switch (sel2) {// synopsys full_case parallel_case
case 0: rom_size_dd.write(ROM_SIZE2A); break;
case 1: rom_size_dd.write(ROM_SIZE2B); break;
case 2: rom_size_dd.write(ROM_SIZE2C); break;
case 3: rom_size_dd.write(ROM_SIZE2D); break;
default:rom_size_dd.write(ROM_SIZE2A); break;
}
break;
default:rom_size_dd.write(1); break;
}
}
 
void usb_ep0::rom_size_up2(void) {
rom_size_d.write(((rom_size_dd.read() > wLength.read().range(6, 0)) ?
wLength.read().range(6, 0) : rom_size_dd.read()));
}
 
void usb_ep0::rom_size_up3(void) {
if (!rst.read())
rom_size.write(0);
else if (rom_sel.read() && !rom_sel_r.read())
rom_size.write(rom_size_d.read());
else if (rom_sel.read() && !fifo_full.read())
rom_size.write(rom_size.read() - 1);
}
 
void usb_ep0::rom_sel_up(void) {
rom_sel_r.write(rom_sel.read());
}
 
void usb_ep0::fifo_we_rom_up1(void) {
fifo_we_rom_r.write(rom_sel.read());
}
 
void usb_ep0::fifo_we_rom_up2(void) {
fifo_we_rom_r2.write(fifo_we_rom_r.read());
}
 
void usb_ep0::fifo_we_rom_up3(void) {
fifo_we_rom.write(rom_sel.read() && fifo_we_rom_r2.read());
}
 
void usb_ep0::rom_done_up(void) {
rom_done.write((rom_size.read() == 0) && !(rom_sel.read() && !rom_sel_r.read()));
}
 
void usb_ep0::fifo_re_up(void) {
fifo_re1.write(get_hdr.read() && !fifo_empty.read());
}
 
void usb_ep0::adv_up(void) {
adv.write(get_hdr.read() && !fifo_empty.read() && !adv.read());
}
 
void usb_ep0::le_up(void) {
if (!rst.read())
le.write(0);
else if (!get_hdr.read())
le.write(0);
#ifdef USB_SIMULATION
else if (!le.read().or_reduce())
#else
else if (!(le.read()[7] || le.read()[6] || le.read()[5] || le.read()[4] ||
le.read()[3] || le.read()[2] || le.read()[1] || le.read()[0]))
#endif
le.write(1);
else if (adv.read())
le.write(((sc_uint<7>)le.read().range(6, 0), (sc_uint<1>)0));
}
 
void usb_ep0::hdr_deco0(void) {
if (le.read()[0])
hdr0.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco1(void) {
if (le.read()[1])
hdr1.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco2(void) {
if (le.read()[2])
hdr2.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco3(void) {
if (le.read()[3])
hdr3.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco4(void) {
if (le.read()[4])
hdr4.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco5(void) {
if (le.read()[5])
hdr5.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco6(void) {
if (le.read()[6])
hdr6.write(ep0_din.read());
}
 
void usb_ep0::hdr_deco7(void) {
if (le.read()[7])
hdr7.write(ep0_din.read());
}
 
void usb_ep0::hdr_done_up(void) {
hdr_done.write(le.read()[7] && adv.read());
}
 
void usb_ep0::high_sel_up(void) {
high_sel.write(write_done_r.read());
}
 
void usb_ep0::ep0_dout_up(void) {
switch (data_sel.read()) {// synopsys full_case parallel_case
case ZERO_DATA: ep0_dout.write(((rom_sel.read()) ? rom_data.read() : (sc_uint<8>)0)); break;
case ZERO_ONE_DATA: ep0_dout.write(((high_sel.read()) ? (sc_uint<8>)1 : (sc_uint<8>)0)); break;
case CONFIG_DATA: ep0_dout.write(((sc_uint<7>)0, (sc_uint<1>)configured.read())); break; // Is configured?
case SYNC_FRAME_DATA: ep0_dout.write((high_sel.read()) ?
((sc_uint<5>)0, (sc_uint<3>)frame_no.read().range(10, 8)) :
frame_no.read().range(7, 0)); break;
case VEND_DATA: ep0_dout.write(((high_sel.read()) ?
vendor_data.read().range(15, 8) :
vendor_data.read().range(7, 0))); break;
}
}
 
void usb_ep0::ep0_we_up(void) {
ep0_we.write(fifo_we_d.read() || fifo_we_rom.read());
}
 
void usb_ep0::ep0_size_up(void) {
if (in_size_0.read())
ep0_size.write(0);
else if (in_size_1.read())
ep0_size.write(1);
else if (in_size_2.read())
ep0_size.write(2);
else if (rom_sel.read())
ep0_size.write(((sc_uint<1>)0, (sc_uint<7>)rom_size_d.read()));
}
 
void usb_ep0::write_done_up1(void) {
write_done_r.write(in_size_2.read() && !fifo_full.read() && fifo_we_d.read() &&
!write_done_r.read() && !write_done.read());
}
 
void usb_ep0::write_done_up2(void) {
write_done.write(in_size_2.read() && !fifo_full.read() && fifo_we_d.read() &&
write_done_r.read() && !write_done.read());
}
 
void usb_ep0::bmReqType_up(void) {
bmReqType.write(hdr0.read());
}
 
void usb_ep0::bmReqType_Decoder(void) {
bm_req_dir.write(bmReqType.read()[7]); // 0: Host to device; 1: Device to host
bm_req_type.write(bmReqType.read().range(6, 5)); // 0: Standard; 1: Class; 2: Vendor; 3: RESERVED
bm_req_recp.write(bmReqType.read().range(4, 0)); // 0: Device; 1: Interface; 2: Endpoint; 3: Other
// 4..31: RESERVED
}
 
void usb_ep0::bRequest_up(void) {
bRequest.write(hdr1.read());
}
 
void usb_ep0::wValue_up(void) {
wValue.write(((sc_uint<8>)hdr3.read(), (sc_uint<8>)hdr2.read()));
}
 
void usb_ep0::wIndex_up(void) {
wIndex.write(((sc_uint<8>)hdr5.read(), (sc_uint<8>)hdr4.read()));
}
 
void usb_ep0::wLength_up(void) {
wLength.write(((sc_uint<8>)hdr7.read(), (sc_uint<8>)hdr6.read()));
}
 
void usb_ep0::hdr_done_r_up(void) {
hdr_done_r.write(hdr_done.read());
}
 
// Standard commands that MUST support
void usb_ep0::get_status_up(void) {
get_status.write(hdr_done.read() && (bRequest.read() == GET_STATUS) && (bm_req_type.read() == 0));
}
 
void usb_ep0::clear_feature_up(void) {
clear_feature.write(hdr_done.read() && (bRequest.read() == CLEAR_FEATURE) && (bm_req_type.read() == 0));
}
 
void usb_ep0::set_feature_up(void) {
set_feature.write(hdr_done.read() && (bRequest.read() == SET_FEATURE) && (bm_req_type.read() == 0));
}
 
void usb_ep0::set_address_up(void) {
set_address.write(hdr_done.read() && (bRequest.read() == SET_ADDRESS) && (bm_req_type.read() == 0));
}
 
void usb_ep0::get_descriptor_up(void) {
get_descriptor.write(hdr_done.read() && (bRequest.read() == GET_DESCRIPTOR) && (bm_req_type.read() == 0));
}
 
void usb_ep0::set_descriptor_up(void) {
set_descriptor.write(hdr_done.read() && (bRequest.read() == SET_DESCRIPTOR) && (bm_req_type.read() == 0));
}
 
void usb_ep0::get_config_up(void) {
get_config.write(hdr_done.read() && (bRequest.read() == GET_CONFIG) && (bm_req_type.read() == 0));
}
 
void usb_ep0::set_config_up(void) {
set_config.write(hdr_done.read() && (bRequest.read() == SET_CONFIG) && (bm_req_type.read() == 0));
}
 
void usb_ep0::get_interface_up(void) {
get_interface.write(hdr_done.read() && (bRequest.read() == GET_INTERFACE) && (bm_req_type.read() == 0));
}
 
void usb_ep0::set_interface_up(void) {
set_interface.write(hdr_done.read() && (bRequest.read() == SET_INTERFACE) && (bm_req_type.read() == 0));
}
 
void usb_ep0::synch_frame_up(void) {
synch_frame.write(hdr_done.read() && (bRequest.read() == SYNCH_FRAME) && (bm_req_type.read() == 0));
}
 
void usb_ep0::v_set_int_up(void) {
v_set_int.write(hdr_done.read() && (bRequest.read() == V_SET_INT) && (bm_req_type.read() == 2));
}
 
void usb_ep0::v_set_feature_up(void) {
v_set_feature.write(hdr_done.read() && (bRequest.read() == SET_FEATURE) && (bm_req_type.read() == 2));
}
 
void usb_ep0::v_get_status_up(void) {
v_get_status.write(hdr_done.read() && (bRequest.read() == GET_STATUS) && (bm_req_type.read() == 2));
}
 
// A config err must cause the device to send a STALL for an ACK
void usb_ep0::config_err_up(void) {
config_err.write(hdr_done_r.read() && !(get_status.read() || clear_feature.read() ||
set_feature.read() || set_address.read() || get_descriptor.read() ||
set_descriptor.read() || get_config.read() || set_config.read() ||
get_interface.read() || set_interface.read() || synch_frame.read() ||
v_set_int.read() || v_set_feature.read() || v_get_status.read()));
}
 
void usb_ep0::send_stall_up(void) {
send_stall.write(config_err.read());
}
 
// Set address
void usb_ep0::set_adr_pending_up(void) {
if (!rst.read())
set_adr_pending.write(false);
else if (ctrl_in.read() || ctrl_out.read() || ctrl_setup.read())
set_adr_pending.write(false);
else if (set_address.read())
set_adr_pending.write(true);
 
}
 
void usb_ep0::funct_adr_tmp_up(void) {
if (!rst.read())
funct_adr_tmp.write(0);
else if (set_address.read())
funct_adr_tmp.write(wValue.read().range(6, 0));
}
 
void usb_ep0::funct_adr_up(void) {
if (!rst.read())
funct_adr.write(0);
else if (set_adr_pending.read() && ctrl_in.read())
funct_adr.write(funct_adr_tmp.read());
}
 
// Main FSM
void usb_ep0::state_up(void) {
if (!rst.read())
state.write(EP0_IDLE);
else
state.write(next_state.read());
}
 
void usb_ep0::ep0_statemachine(void) {
next_state.write(state.read());
get_hdr.write(false);
data_sel.write(ZERO_DATA);
fifo_we_d.write(false);
in_size_0.write(false);
in_size_1.write(false);
in_size_2.write(false);
rom_sel.write(false);
 
switch (state.read()) {// synopsys full_case parallel_case
case EP0_IDLE: // Wait for setup token
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state IDLE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (ctrl_setup.read())
next_state.write(EP0_GET_HDR);
if (get_status.read())
next_state.write(EP0_GET_STATUS);
if (clear_feature.read())
next_state.write(EP0_CLEAR_FEATURE);
if (set_feature.read())
next_state.write(EP0_SET_FEATURE);
if (set_address.read())
next_state.write(EP0_SET_ADDRESS);
if (get_descriptor.read())
next_state.write(EP0_GET_DESCRIPTOR);
if (set_descriptor.read())
next_state.write(EP0_SET_DESCRIPTOR);
if (get_config.read())
next_state.write(EP0_GET_CONFIG);
if (set_config.read())
next_state.write(EP0_SET_CONFIG);
if (get_interface.read())
next_state.write(EP0_GET_INTERFACE);
if (set_interface.read())
next_state.write(EP0_SET_INTERFACE);
if (synch_frame.read())
next_state.write(EP0_SYNCH_FRAME);
if (v_set_int.read())
next_state.write(EP0_V_SET_INT);
if (v_set_feature.read())
next_state.write(EP0_V_SET_INT);
if (v_get_status.read())
next_state.write(EP0_V_GET_STATUS);
break;
 
case EP0_GET_HDR: // Retrieve setup header
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state GET_HDR (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
get_hdr.write(true);
if (hdr_done.read())
next_state.write(EP0_IDLE);
break;
 
case EP0_GET_STATUS: // Actions for supported commands
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state GET_STATUS (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Return to host
// 1 for device
// 0 for interface
// 0 for endpoint
if (bm_req_recp.read() == 0)
data_sel.write(ZERO_ONE_DATA);
else
data_sel.write(ZERO_DATA);
 
in_size_2.write(true);
if (!fifo_full.read()) {
fifo_we_d.write(true);
if (write_done_r.read())
next_state.write(EP0_WAIT_IN_DATA);
}
break;
 
case EP0_V_GET_STATUS:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state V_GET_STATUS (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
data_sel.write(VEND_DATA);
in_size_2.write(true);
if (!fifo_full.read()) {
fifo_we_d.write(true);
if (write_done_r.read())
next_state.write(EP0_WAIT_IN_DATA);
}
break;
 
case EP0_CLEAR_FEATURE:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state CLEAR_FEATURE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Just ignore this for now
next_state.write(EP0_STATUS_IN);
break;
 
case EP0_SET_FEATURE:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state SET_FEATURE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Just ignore this for now
next_state.write(EP0_STATUS_IN);
break;
 
case EP0_SET_ADDRESS:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state SET_ADDRESS (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Done elsewhere
next_state.write(EP0_STATUS_IN);
break;
 
case EP0_GET_DESCRIPTOR:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state GET_DESCRIPTOR (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if ((wValue.read().range(15, 8) == 1) ||
(wValue.read().range(15, 8) == 2) ||
(wValue.read().range(15, 8) == 3))
rom_sel.write(true);
else
next_state.write(EP0_IDLE);
 
if (rom_done.read())
next_state.write(EP0_IDLE);
break;
 
case EP0_SET_DESCRIPTOR:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state SET_DESCRIPTOR (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// This doesn't do anything since we do not support
// setting the descriptor
next_state.write(EP0_IDLE);
break;
 
case EP0_GET_CONFIG:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state GET_CONFIG (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Send one byte back that indicates current status
in_size_1.write(true);
data_sel.write(CONFIG_DATA);
if (!fifo_full.read()) {
fifo_we_d.write(true);
next_state.write(EP0_WAIT_IN_DATA);
}
break;
 
case EP0_SET_CONFIG:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state SET_CONFIG (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Done elsewhere
next_state.write(EP0_STATUS_IN);
break;
 
case EP0_GET_INTERFACE:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state GET_INTERFACE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Return interface 0
in_size_1.write(true);
if (!fifo_full.read()) {
fifo_we_d.write(true);
next_state.write(EP0_WAIT_IN_DATA);
}
break;
 
case EP0_SET_INTERFACE:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state SET_INTERFACE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Just ignore this for now
next_state.write(EP0_STATUS_IN);
break;
 
case EP0_SYNCH_FRAME:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state SYNCH_FRAME (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Return Frame current frame number
data_sel.write(SYNC_FRAME_DATA);
in_size_2.write(true);
if (!fifo_full.read()) {
fifo_we_d.write(true);
if (write_done_r.read())
next_state.write(EP0_WAIT_IN_DATA);
}
break;
 
case EP0_V_SET_INT:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state V_SET_INT (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
// Done elsewhere
next_state.write(EP0_STATUS_IN);
break;
 
case EP0_WAIT_IN_DATA:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state WAIT_IN_DATA (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (ctrl_in.read())
next_state.write(EP0_STATUS_OUT);
break;
 
case EP0_STATUS_IN:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state STATUS_IN (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
in_size_0.write(true);
if (ctrl_in.read())
next_state.write(EP0_IDLE);
break;
 
case EP0_STATUS_OUT:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "EP0: Entered state STATUS_OUT (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (ctrl_out.read())
next_state.write(EP0_IDLE);
break;
}
}
 
/trunk/rtl/systemc/usb_sie.h
0,0 → 1,359
/////////////////////////////////////////////////////////////////////
//// ////
//// USB SIE ////
//// ////
//// SystemC Version: usb_sie.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_utmi_if.v + usb1_pl.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_SIE_H
#define USB_SIE_H
 
#include "usb_defines.h"
 
#include "usb_pa_sie.h"
#include "usb_pd_sie.h"
#include "usb_pe_sie.h"
#include "usb_dma.h"
 
SC_MODULE(usb_sie) {
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
 
// PHY Interface
sc_out<sc_uint<8> > DataOut;
sc_out<bool> TxValid;
sc_in<bool> TxReady;
sc_in<sc_uint<8> > DataIn;
sc_in<bool> RxValid;
sc_in<bool> RxActive;
sc_in<bool> RxError;
 
sc_out<bool> token_valid;
 
// Register File Interface
sc_in<sc_uint<7> > fa; // Function Address (as set by the controller)
sc_out<sc_uint<4> > ep_sel; // Endpoint Number Input
sc_out<bool> x_busy; // Indicates USB is busy
 
sc_out<bool> int_crc16_set; // Set CRC16 Error Interrupt
sc_out<bool> int_to_set; // Set Time Out Interrupt
sc_out<bool> int_seqerr_set; // Set PID Sequence Error Interrupt
 
// Misc and Control Interface
sc_out<bool> pid_cs_err; // PID Checksum error
sc_out<bool> crc5_err; // CRC5 Error
sc_out<sc_uint<32> >frm_nat;
sc_out<bool> nse_err; // No such endpoint error
sc_out<sc_uint<8> > rx_size;
sc_out<bool> rx_done;
sc_out<bool> ctrl_setup;
sc_out<bool> ctrl_in;
sc_out<bool> ctrl_out;
 
// Endpoint Interface
sc_in<sc_uint<14> > csr;
sc_in<sc_uint<8> > tx_data_st;
sc_out<sc_uint<8> > rx_data_st;
sc_out<bool> idma_re, idma_we;
sc_in<bool> ep_empty, ep_full;
sc_in<bool> send_stall;
 
// Signals
 
// PHY Interface
sc_signal<sc_uint<8> > tx_data;
sc_signal<bool> TxValid_s, tx_valid, tx_valid_last, tx_ready, tx_first;
sc_signal<sc_uint<8> > rx_data;
sc_signal<bool> rx_valid, rx_active, rx_err;
 
// Packet Disassembler Interface
sc_signal<bool> pid_OUT, pid_IN, pid_SOF, pid_SETUP;
sc_signal<bool> pid_DATA0, pid_DATA1, pid_DATA2, pid_MDATA;
sc_signal<bool> pid_ACK, pid_NACK, pid_STALL, pid_NYET;
sc_signal<bool> pid_PRE, pid_ERR, pid_SPLIT, pid_PING;
sc_signal<sc_uint<7> > token_fadr;
sc_signal<sc_uint<11> > frame_no;
sc_signal<sc_uint<8> > rx_data_st_d;
sc_signal<bool> rx_data_valid, rx_data_done;
sc_signal<bool> crc16_err, rx_seq_err;
 
// Packet Assembler Interface
sc_signal<bool> send_token;
sc_signal<sc_uint<2> > token_pid_sel;
sc_signal<bool> send_data;
sc_signal<sc_uint<2> > data_pid_sel;
sc_signal<sc_uint<8> > tx_data_st_o;
sc_signal<bool> rd_next;
 
// IDMA Interface
sc_signal<bool> rx_dma_en, tx_dma_en;
sc_signal<bool> abort, idma_done;
 
// Local Signals
sc_signal<sc_uint<9> > csr9;
sc_signal<bool> pid_bad;
sc_signal<bool> hms_clk; // 0.5 Micro Seconds Clock
sc_signal<sc_uint<5> > hms_cnt;
sc_signal<sc_uint<11> > frame_no_r; // Current Frame Number Register
sc_signal<bool> frame_no_we;
sc_signal<sc_uint<12> > sof_time; // Time since last SOF
sc_signal<bool> clr_sof_time;
sc_signal<bool> fsel; // This function is selected
sc_signal<bool> match_o;
 
sc_signal<bool> frame_no_we_r;
sc_signal<bool> idma_we_d;
sc_signal<bool> ep_empty_int;
sc_signal<bool> tx_busy, rx_busy;
sc_signal<bool> int_upid_set;
 
usb_pa_sie *i_pa_sie; // Packet Assembler
usb_pd_sie *i_pd_sie; // Packet Disassembler
usb_pe_sie *i_pe_sie; // Protocol Engine
usb_dma *i_dma; // Internal DMA
 
// PHY Functions
void tx_interface1(void);
void tx_interface2(void);
void tx_interface3(void);
void rx_interface1(void);
void rx_interface2(void);
 
// Misc Functions
void csr9_up(void);
void x_busy_up(void);
void pid_bad_up(void);
void match_o_up(void);
void rx_data_st_up(void);
 
// Receive Packet Decoder Function
void decoder_pk(void);
 
// Frame Number Update Functions
void frame_no_up1(void);
void frame_no_up2(void);
void frame_no_up3(void);
 
// SOF Delay Counter Functions
void frm_nat_up1(void);
void frm_nat_up2(void);
void frm_nat_up3(void);
 
// 0.5 Micro Seconds Clock Generator Functions
void hms_clk_up1(void);
void hms_clk_up2(void);
 
// "Is function addressed?" Functions
void fsel_up(void);
void idma_we_up(void);
 
// Destructor
// ~usb_sie(void);
 
SC_CTOR(usb_sie) {
SC_METHOD(tx_interface1);
sensitive << clk.pos() << rst.neg();
SC_METHOD(tx_interface2);
sensitive << clk.pos();
SC_METHOD(tx_interface3);
sensitive << TxValid_s;
SC_METHOD(rx_interface1);
sensitive << clk.pos() << rst.neg();
SC_METHOD(rx_interface2);
sensitive << clk.pos();
 
SC_METHOD(csr9_up);
sensitive << csr;
SC_METHOD(x_busy_up);
sensitive << tx_busy << rx_busy;
SC_METHOD(pid_bad_up);
sensitive << pid_ACK << pid_NACK << pid_STALL << pid_NYET;
sensitive << pid_PRE << pid_ERR << pid_SPLIT << pid_PING;
SC_METHOD(match_o_up);
sensitive << pid_bad << token_valid << crc5_err;
SC_METHOD(rx_data_st_up);
sensitive << clk.pos();
 
SC_METHOD(decoder_pk);
sensitive << clk.pos();
 
SC_METHOD(frame_no_up1);
sensitive << token_valid << crc5_err << pid_SOF;
SC_METHOD(frame_no_up2);
sensitive << clk.pos();
SC_METHOD(frame_no_up3);
sensitive << clk.pos() << rst.neg();
 
SC_METHOD(frm_nat_up1);
sensitive << clk.pos();
SC_METHOD(frm_nat_up2);
sensitive << clk.pos();
SC_METHOD(frm_nat_up3);
sensitive << frame_no_r << sof_time;
 
SC_METHOD(hms_clk_up1);
sensitive << clk.pos() << rst.neg();
SC_METHOD(hms_clk_up2);
sensitive << clk.pos();
 
SC_METHOD(fsel_up);
sensitive << token_fadr << fa;
SC_METHOD(idma_we_up);
sensitive << idma_we_d << fsel;
 
// Packet Assembler Instantiation and Binding
i_pa_sie = new usb_pa_sie("PA_SIE");
i_pa_sie->clk(clk);
i_pa_sie->rst(rst);
i_pa_sie->tx_data(tx_data);
i_pa_sie->tx_valid(tx_valid);
i_pa_sie->tx_valid_last(tx_valid_last);
i_pa_sie->tx_ready(tx_ready);
i_pa_sie->tx_first(tx_first);
i_pa_sie->send_token(send_token);
i_pa_sie->token_pid_sel(token_pid_sel);
i_pa_sie->send_data(send_data);
i_pa_sie->data_pid_sel(data_pid_sel);
i_pa_sie->tx_data_st(tx_data_st_o);
i_pa_sie->rd_next(rd_next);
i_pa_sie->ep_empty(ep_empty_int);
 
// Packet Disassembler Instantiation and Binding
i_pd_sie = new usb_pd_sie("PD_SIE");
i_pd_sie->clk(clk);
i_pd_sie->rst(rst);
i_pd_sie->rx_data(rx_data);
i_pd_sie->rx_valid(rx_valid);
i_pd_sie->rx_active(rx_active);
i_pd_sie->rx_err(rx_err);
i_pd_sie->pid_OUT(pid_OUT);
i_pd_sie->pid_IN(pid_IN);
i_pd_sie->pid_SOF(pid_SOF);
i_pd_sie->pid_SETUP(pid_SETUP);
i_pd_sie->pid_DATA0(pid_DATA0);
i_pd_sie->pid_DATA1(pid_DATA1);
i_pd_sie->pid_DATA2(pid_DATA2);
i_pd_sie->pid_MDATA(pid_MDATA);
i_pd_sie->pid_ACK(pid_ACK);
i_pd_sie->pid_NACK(pid_NACK);
i_pd_sie->pid_STALL(pid_STALL);
i_pd_sie->pid_NYET(pid_NYET);
i_pd_sie->pid_PRE(pid_PRE);
i_pd_sie->pid_ERR(pid_ERR);
i_pd_sie->pid_SPLIT(pid_SPLIT);
i_pd_sie->pid_PING(pid_PING);
i_pd_sie->pid_cks_err(pid_cs_err);
i_pd_sie->token_fadr(token_fadr);
i_pd_sie->token_endp(ep_sel);
i_pd_sie->token_valid(token_valid);
i_pd_sie->crc5_err(crc5_err);
i_pd_sie->frame_no(frame_no);
i_pd_sie->rx_data_st(rx_data_st_d);
i_pd_sie->rx_data_valid(rx_data_valid);
i_pd_sie->rx_data_done(rx_data_done);
i_pd_sie->crc16_err(crc16_err);
i_pd_sie->seq_err(rx_seq_err);
i_pd_sie->rx_busy(rx_busy);
 
// Protocol Engine Instantiation and Binding
i_pe_sie = new usb_pe_sie("PE_SIE");
i_pe_sie->clk(clk);
i_pe_sie->rst(rst);
i_pe_sie->tx_valid(TxValid_s);
i_pe_sie->rx_active(rx_active);
i_pe_sie->pid_OUT(pid_OUT);
i_pe_sie->pid_IN(pid_IN);
i_pe_sie->pid_SOF(pid_SOF);
i_pe_sie->pid_SETUP(pid_SETUP);
i_pe_sie->pid_DATA0(pid_DATA0);
i_pe_sie->pid_DATA1(pid_DATA1);
i_pe_sie->pid_DATA2(pid_DATA2);
i_pe_sie->pid_MDATA(pid_MDATA);
i_pe_sie->pid_ACK(pid_ACK);
i_pe_sie->pid_PING(pid_PING);
i_pe_sie->token_valid(token_valid);
i_pe_sie->rx_data_done(rx_data_done);
i_pe_sie->crc16_err(crc16_err);
i_pe_sie->send_token(send_token);
i_pe_sie->token_pid_sel(token_pid_sel);
i_pe_sie->data_pid_sel(data_pid_sel);
i_pe_sie->rx_dma_en(rx_dma_en);
i_pe_sie->tx_dma_en(tx_dma_en);
i_pe_sie->abort(abort);
i_pe_sie->idma_done(idma_done);
i_pe_sie->fsel(fsel);
i_pe_sie->ep_sel(ep_sel);
i_pe_sie->ep_full(ep_full);
i_pe_sie->ep_empty(ep_empty);
i_pe_sie->match(match_o);
i_pe_sie->nse_err(nse_err);
i_pe_sie->int_upid_set(int_upid_set);
i_pe_sie->int_crc16_set(int_crc16_set);
i_pe_sie->int_to_set(int_to_set);
i_pe_sie->int_seqerr_set(int_seqerr_set);
i_pe_sie->csr(csr);
i_pe_sie->send_stall(send_stall);
 
// Internal DMA / Memory Arbiter Interface Instantiation and Binding
i_dma = new usb_dma("DMA");
i_dma->clk(clk);
i_dma->rst(rst);
i_dma->tx_valid(tx_valid);
i_dma->rx_data_valid(rx_data_valid);
i_dma->rx_data_done(rx_data_done);
i_dma->send_data(send_data);
i_dma->rd_next(rd_next);
i_dma->tx_data_st_i(tx_data_st);
i_dma->tx_data_st_o(tx_data_st_o);
i_dma->ep_sel(ep_sel);
i_dma->tx_busy(tx_busy);
i_dma->tx_dma_en(tx_dma_en);
i_dma->rx_dma_en(rx_dma_en);
i_dma->idma_done(idma_done);
i_dma->size(csr9);
i_dma->rx_cnt(rx_size);
i_dma->rx_done(rx_done);
i_dma->mwe(idma_we_d);
i_dma->mre(idma_re);
i_dma->ep_empty(ep_empty);
i_dma->ep_empty_int(ep_empty_int);
i_dma->ep_full(ep_full);
}
 
};
 
#endif
 
/trunk/rtl/systemc/phy_test.cpp
0,0 → 1,98
#include "systemc.h"
#include "usb_phy.h"
 
SC_MODULE(test) {
sc_in<bool> clk, usb_rst;
sc_out<bool> rst, phy_tx_mode;
sc_in<bool> txdp, txdn, txoe;
sc_out<bool> rxd, rxdp, rxdn;
sc_out<sc_uint<8> > DataOut_i;
sc_in<sc_uint<8> > DataIn_o;
sc_out<bool> TxValid_i;
sc_in<bool> TxReady_o, RxValid_o, RxActive_o, RxError_o;
sc_in<sc_uint<2> > LineState_o;
 
int i;
 
void update(void) {
i = 0;
rst.write(false);
wait();
wait();
rst.write(true);
wait();
wait();
wait();
wait();
sc_stop();
}
 
SC_CTOR(test) {
SC_THREAD(update);
sensitive << clk.pos();
}
};
 
int sc_main(int argc, char *argv[]) {
 
sc_set_time_resolution(1.0, SC_NS);
 
sc_clock clk("clock", 20.83, SC_NS);
sc_signal<bool> rst, phy_tx_mode, usb_rst, txdp, txdn, txoe, rxd, rxdp, rxdn,
TxValid_i, TxReady_o, RxValid_o, RxActive_o, RxError_o;
sc_signal<sc_uint<8> > DataOut_i, DataIn_o;
sc_signal<sc_uint<2> > LineState_o;
 
usb_phy i_phy("PHY");
test i_test("TEST");
 
i_phy.clk(clk);
i_phy.rst(rst);
i_phy.phy_tx_mode(phy_tx_mode);
i_phy.usb_rst(usb_rst);
i_phy.txdp(txdp);
i_phy.txdn(txdn);
i_phy.txoe(txoe);
i_phy.rxd(rxd);
i_phy.rxdn(rxdn);
i_phy.rxdp(rxdp);
i_phy.DataOut_i(DataOut_i);
i_phy.DataIn_o(DataIn_o);
i_phy.LineState_o(LineState_o);
i_phy.TxValid_i(TxValid_i);
i_phy.TxReady_o(TxReady_o);
i_phy.RxValid_o(RxValid_o);
i_phy.RxActive_o(RxActive_o);
i_phy.RxError_o(RxError_o);
 
i_test.clk(clk);
i_test.rst(rst);
i_test.phy_tx_mode(phy_tx_mode);
i_test.usb_rst(usb_rst);
i_test.txdp(txdp);
i_test.txdn(txdn);
i_test.txoe(txoe);
i_test.rxd(rxd);
i_test.rxdn(rxdn);
i_test.rxdp(rxdp);
i_test.DataOut_i(DataOut_i);
i_test.DataIn_o(DataIn_o);
i_test.LineState_o(LineState_o);
i_test.TxValid_i(TxValid_i);
i_test.TxReady_o(TxReady_o);
i_test.RxValid_o(RxValid_o);
i_test.RxActive_o(RxActive_o);
i_test.RxError_o(RxError_o);
 
sc_trace_file *log = sc_create_vcd_trace_file("PHY_TEST");
sc_trace(log, clk, "Clock");
sc_trace(log, rst, "Reset");
 
//sc_start(1000, SC_NS);
sc_start();
 
sc_close_vcd_trace_file(log);
 
return 0;
}
 
/trunk/rtl/systemc/usb_ocp.h
0,0 → 1,200
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 Top Module ////
//// Function Interface ////
//// OCP Interface ////
//// ////
//// SystemC Version: usb_ocp.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_ocp_if.v ////
//// Copyright (C) 2004 Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_OCP_H
#define USB_OCP_H
 
#include "usb.h"
 
// Command Encoding -> MCmd[2:0]
enum COMMAND { OCP_IDLE = 0,
OCP_WR = 1,
OCP_RD = 2,
OCP_RDEX = 3,
// 100..110 -> Reserved,
OCP_BCST = 7};
 
// Response Encoding -> SResp[1:0]
enum RESPONSE { OCP_NULL = 0,
OCP_DVA = 1,
// 10 -> Reserved
OCP_ERR = 3};
 
SC_MODULE(usb_ocp) {
 
private:
 
sc_signal<bool> vcc;
sc_signal<bool> usb_rst_nc;
 
public:
 
sc_in<bool> Clk; // Basic Signal -> Clock signal
sc_in<bool> Reset_n; // Sideband Signal -> Reset signal
 
// PHY Interface
sc_out<bool> tx_dp, tx_dn, tx_oe;
sc_in<bool> rx_dp, rx_dn, rx_d;
 
// Sideband Interface
sc_out<bool> SInterrupt; // Interrupt
sc_out<sc_uint<8> > SFlag; // Flags
sc_out<bool> SError; // Error Indicator
 
// Basic Interface
sc_in<sc_uint<32> > MAddr;
sc_in<sc_uint<3> > MCmd;
sc_in<sc_uint<8> > MData;
sc_out<bool> SCmdAccept;
sc_out<sc_uint<8> > SData;
sc_out<sc_uint<2> > SResp;
 
// Local Signals
 
sc_signal<bool> empty;
sc_signal<bool> full;
 
// Vendor Signals
sc_signal<sc_uint<16> > wValue;
sc_signal<sc_uint<16> > wIndex;
sc_signal<sc_uint<16> > vendor_data;
 
// SFlag Signals
sc_signal<bool> SF_busy;
sc_signal<sc_uint<4> > SF_sel;
sc_signal<bool> SF_feature;
 
// Endpoint Interface
// EP1
sc_signal<sc_uint<8> > ep1_f_din;
sc_signal<bool> ep1_f_we;
sc_signal<bool> ep1_f_full;
 
// EP2
sc_signal<sc_uint<8> > ep2_f_dout;
sc_signal<bool> ep2_f_re;
sc_signal<bool> ep2_f_empty;
 
// EP3
sc_signal<sc_uint<8> > ep3_f_din;
sc_signal<bool> ep3_f_we;
sc_signal<bool> ep3_f_full;
 
// EP4
sc_signal<sc_uint<8> > ep4_f_dout;
sc_signal<bool> ep4_f_re;
sc_signal<bool> ep4_f_empty;
 
// EP5
sc_signal<sc_uint<8> > ep5_f_din;
sc_signal<bool> ep5_f_we;
sc_signal<bool> ep5_f_full;
 
// EP6
sc_signal<sc_uint<8> > ep6_f_dout;
sc_signal<bool> ep6_f_re;
sc_signal<bool> ep6_f_empty;
 
usb *i_usb; // USB
 
// Mux Function
void mux(void);
void sflag_up(void);
void sresp_up(void);
 
// Destructor
// ~usb_ocp(void);
 
SC_CTOR(usb_ocp) {
vcc.write(true);
 
SC_METHOD(mux);
sensitive << MAddr << MCmd << MData;
sensitive << ep1_f_full << ep2_f_dout << ep2_f_empty;
sensitive << ep3_f_full << ep4_f_dout << ep4_f_empty;
sensitive << ep5_f_full << ep6_f_dout << ep6_f_empty;
sensitive << wValue << wIndex;
SC_METHOD(sflag_up);
sensitive << empty << full << SF_busy << SF_sel << SF_feature;
SC_METHOD(sresp_up);
sensitive << Clk.pos();
 
// USB Instantiation and Binding
i_usb = new usb("USB");
i_usb->clk_i(Clk);
i_usb->rst_i(Reset_n);
i_usb->tx_dp(tx_dp);
i_usb->tx_dn(tx_dn);
i_usb->tx_oe(tx_oe);
i_usb->rx_dp(rx_dp);
i_usb->rx_dn(rx_dn);
i_usb->rx_d(rx_d);
i_usb->phy_tx_mode(vcc);
i_usb->usb_rst(usb_rst_nc);
i_usb->crc16_err(SError);
i_usb->v_set_int(SInterrupt);
i_usb->v_set_feature(SF_feature);
i_usb->wValue(wValue);
i_usb->wIndex(wIndex);
i_usb->vendor_data(vendor_data);
i_usb->usb_busy(SF_busy);
i_usb->ep_sel(SF_sel);
i_usb->ep1_f_din(ep1_f_din);
i_usb->ep1_f_we(ep1_f_we);
i_usb->ep1_f_full(ep1_f_full);
i_usb->ep2_f_dout(ep2_f_dout);
i_usb->ep2_f_re(ep2_f_re);
i_usb->ep2_f_empty(ep2_f_empty);
i_usb->ep3_f_din(ep3_f_din);
i_usb->ep3_f_we(ep3_f_we);
i_usb->ep3_f_full(ep3_f_full);
i_usb->ep4_f_dout(ep4_f_dout);
i_usb->ep4_f_re(ep4_f_re);
i_usb->ep4_f_empty(ep4_f_empty);
i_usb->ep5_f_din(ep5_f_din);
i_usb->ep5_f_we(ep5_f_we);
i_usb->ep5_f_full(ep5_f_full);
i_usb->ep6_f_dout(ep6_f_dout);
i_usb->ep6_f_re(ep6_f_re);
i_usb->ep6_f_empty(ep6_f_empty);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_ram128x8.cpp
0,0 → 1,53
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RAM ////
//// ////
//// SystemC Version: usb_ram128x8.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_dpram.v ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// www.opencores.org ////
//// ////
//// 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 "systemc.h"
#include "usb_ram128x8.h"
 
void usb_ram128x8::dout_update(void) {
dout.write((oe.read() && rce.read()) ? dout_reg.read() : (sc_uint<8>)0);
}
 
void usb_ram128x8::read(void) {
if (rce.read())
dout_reg.write(mem[raddr.read()]);
}
 
void usb_ram128x8::write(void) {
if (wce.read() && we.read())
mem[waddr.read()] = din.read();
}
 
/trunk/rtl/systemc/usb_fifo512x8.cpp
0,0 → 1,110
/////////////////////////////////////////////////////////////////////
//// ////
//// USB FIFO ////
//// ////
//// SystemC Version: usb_fifo512x8.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_fifo_sc_a.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 "systemc.h"
#include "usb_fifo512x8.h"
 
void usb_fifo512x8::write_pointer_update(void) {
if (!rst.read()) {
wp.write(0);
} else if (clr.read()) {
wp.write(0);
} else if (we.read()) {
wp.write(wp_pl1.read());
}
}
 
void usb_fifo512x8::read_pointer_update(void) {
if (!rst.read()) {
rp.write(0);
} else if (clr.read()) {
rp.write(0);
} else if (re.read()) {
rp.write(rp_pl1.read());
}
}
 
void usb_fifo512x8::future_pointers_update(void) {
wp_pl1.write(wp.read() + 1);
wp_pl2.write(wp.read() + 2);
rp_pl1.write(rp.read() + 1);
}
 
// Full & Empty Logic
// Guard Bit ...
void usb_fifo512x8::fe_gb_update(void) {
if (!rst.read())
gb.write(false);
else if (clr.read())
gb.write(false);
else if ((wp_pl2.read() == rp.read()) && we.read())
gb.write(true);
else if ((wp.read() != rp.read()) && re.read())
gb.write(false);
}
 
void usb_fifo512x8::fe_full_update(void) {
if (!rst.read())
full.write(false);
else if (clr.read())
full.write(false);
else if (we.read() && ((wp_pl1.read() == rp.read()) && gb.read()) && !re.read())
full.write(true);
else if (re.read() && ((wp_pl1.read() != rp.read()) || !gb.read()) && !we.read())
full.write(false);
}
 
void usb_fifo512x8::fe_empty_update(void) {
if (!rst.read())
empty.write(true);
else if (clr.read())
empty.write(true);
else if (we.read() && ((wp.read() != rp_pl1.read()) || gb.read()) && !re.read())
empty.write(false);
else if (re.read() && ((wp.read() == rp_pl1.read()) && !gb.read()) && !we.read())
empty.write(true);
}
 
void usb_fifo512x8::reset_update(void) {
n_rst.write(!rst.read());
}
/*
usb_fifo512x8::~usb_fifo512x8(void) {
if (i_ram)
delete i_ram;
}
*/
/trunk/rtl/systemc/usb_crc5.cpp
0,0 → 1,59
/////////////////////////////////////////////////////////////////////
//// ////
//// USB CRC5 ////
//// ////
//// SystemC Version: usb_crc5.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_crc5.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 "systemc.h"
#include "usb_crc5.h"
 
void usb_crc5::update(void) {
sc_uint<5> temp;
 
temp[0] = din.read()[10] ^ din.read()[9] ^ din.read()[6] ^ din.read()[5] ^ din.read()[3] ^
din.read()[0] ^ crc_in.read()[0] ^ crc_in.read()[3] ^ crc_in.read()[4];
temp[1] = din.read()[10] ^ din.read()[7] ^ din.read()[6] ^ din.read()[4] ^ din.read()[1] ^
crc_in.read()[0] ^ crc_in.read()[1] ^ crc_in.read()[4];
temp[2] = din.read()[10] ^ din.read()[9] ^ din.read()[8] ^ din.read()[7] ^ din.read()[6] ^
din.read()[3] ^ din.read()[2] ^ din.read()[0] ^ crc_in.read()[0] ^
crc_in.read()[1] ^ crc_in.read()[2] ^ crc_in.read()[3] ^ crc_in.read()[4];
temp[3] = din.read()[10] ^ din.read()[9] ^ din.read()[8] ^ din.read()[7] ^ din.read()[4] ^
din.read()[3] ^ din.read()[1] ^ crc_in.read()[1] ^ crc_in.read()[2] ^
crc_in.read()[3] ^ crc_in.read()[4];
temp[4] = din.read()[10] ^ din.read()[9] ^ din.read()[8] ^ din.read()[5] ^ din.read()[4] ^
din.read()[2] ^ crc_in.read()[2] ^ crc_in.read()[3] ^ crc_in.read()[4];
 
crc_out.write(temp);
}
 
/trunk/rtl/systemc/usb_ram512x8.h
0,0 → 1,74
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RAM ////
//// ////
//// SystemC Version: usb_ram512x8.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_dpram.v ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// www.opencores.org ////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_RAM512X8_H
#define USB_RAM512X8_H
 
SC_MODULE(usb_ram512x8) {
 
public:
 
sc_in<bool> rclk, rrst, rce;
sc_in<bool> oe;
sc_in<sc_uint<9> > raddr;
sc_out<sc_uint<8> > dout;
 
sc_in<bool> wclk, wrst, wce;
sc_in<bool> we;
sc_in<sc_uint<9> > waddr;
sc_in<sc_uint<8> > din;
 
sc_signal<sc_uint<8> > dout_reg;
 
sc_uint<8> mem[512];
 
void dout_update(void);
void read(void);
void write(void);
 
SC_CTOR(usb_ram512x8) {
SC_METHOD(dout_update);
sensitive << oe << rce << dout_reg;
SC_METHOD(read);
sensitive << rclk.pos();
SC_METHOD(write);
sensitive << wclk.pos();
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_core.h
0,0 → 1,426
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 ////
//// Function IP Core ////
//// ////
//// SystemC Version: usb_core.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_core.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_CORE_H
#define USB_CORE_H
 
#include "usb_defines.h"
 
#include "usb_phy.h"
#include "usb_sie.h"
#include "usb_ep0.h"
#include "usb_rom.h"
#include "usb_fifo64x8.h"
 
/*
USB PHY Interface
tx_dp, tx_dn, tx_oe,
rx_d, rx_dp, rx_dn,
These pins are a semi-standard interface to USB 1.1 transceivers.
Just match up the signal names with the IOs of the transceiver.
 
USB Misc
phy_tx_mode, usb_rst,
The PHY supports single ended and differential output to the
transceiver. Depending on which device you are using, you have
to tie the phy_tx_mode high or low.
usb_rst is asserted whenever the host signals reset on the USB
bus. The USB core will internally reset itself automatically.
This output is provided for external logic that needs to be
reset when the USB bus is reset.
 
Interrupts
crc16_err,
crc16_err, indicates when a crc 16 error was detected on the
payload of a USB packet.
 
Vendor Features
v_set_int, v_set_feature, wValue,
wIndex, vendor_data,
This signals allow to control vendor specific registers and logic
that can be manipulated and monitored via the control endpoint
through vendor defined commands.
 
USB Status
usb_busy, ep_sel,
usb_busy is asserted when the USB core is busy transferring
data ep_sel indicated the endpoint that is currently busy.
This information might be useful if one desires to reset/clear
the attached FIFOs and want to do this when the endpoint is idle.
 
Endpoint Interface
This implementation supports 8 endpoints. Endpoint 0 is the
control endpoint and used internally. Endpoints 1-7 are available
to the user. replace 'N' with the endpoint number.
 
epN_cfg,
This is a constant input used to configure the endpoint by ORing
these defines together and adding the max packet size for this
endpoint:
`IN and `OUT select the transfer direction for this endpoint
`ISO, `BULK and `INT determine the endpoint type
 
Example: "`BULK | `IN | 14'd064" defines a BULK IN endpoint with
max packet size of 64 bytes
 
epN_din, epN_we, epN_full,
This is the OUT FIFO interface. If this is a IN endpoint, ground
all unused inputs and leave outputs unconnected.
 
epN_dout, epN_re, epN_empty,
this is the IN FIFO interface. If this is a OUT endpoint ground
all unused inputs and leave outputs unconnected.
 
*/
 
SC_MODULE(usb_core) {
 
public:
 
sc_in<bool> clk_i;
sc_in<bool> rst_i;
 
// PHY Interface
sc_out<bool> tx_dp, tx_dn, tx_oe;
sc_in<bool> rx_dp, rx_dn, rx_d;
sc_in<bool> phy_tx_mode;
 
// Misc
sc_out<bool> usb_rst;
 
// Interrupts
sc_out<bool> crc16_err;
 
// Vendor Features
sc_out<bool> v_set_int;
sc_out<bool> v_set_feature;
sc_out<sc_uint<16> >wValue;
sc_out<sc_uint<16> >wIndex;
sc_in<sc_uint<16> > vendor_data;
 
// USB Status
sc_out<bool> usb_busy;
sc_out<sc_uint<4> > ep_sel;
 
// Endpoint Interface
// EP1
sc_in<sc_uint<14> > ep1_cfg;
sc_in<sc_uint<8> > ep1_din;
sc_out<sc_uint<8> > ep1_dout;
sc_out<bool> ep1_we, ep1_re;
sc_in<bool> ep1_empty, ep1_full;
 
// EP2
sc_in<sc_uint<14> > ep2_cfg;
sc_in<sc_uint<8> > ep2_din;
sc_out<sc_uint<8> > ep2_dout;
sc_out<bool> ep2_we, ep2_re;
sc_in<bool> ep2_empty, ep2_full;
 
// EP3
sc_in<sc_uint<14> > ep3_cfg;
sc_in<sc_uint<8> > ep3_din;
sc_out<sc_uint<8> > ep3_dout;
sc_out<bool> ep3_we, ep3_re;
sc_in<bool> ep3_empty, ep3_full;
 
// EP4
sc_in<sc_uint<14> > ep4_cfg;
sc_in<sc_uint<8> > ep4_din;
sc_out<sc_uint<8> > ep4_dout;
sc_out<bool> ep4_we, ep4_re;
sc_in<bool> ep4_empty, ep4_full;
 
// EP5
sc_in<sc_uint<14> > ep5_cfg;
sc_in<sc_uint<8> > ep5_din;
sc_out<sc_uint<8> > ep5_dout;
sc_out<bool> ep5_we, ep5_re;
sc_in<bool> ep5_empty, ep5_full;
 
// EP6
sc_in<sc_uint<14> > ep6_cfg;
sc_in<sc_uint<8> > ep6_din;
sc_out<sc_uint<8> > ep6_dout;
sc_out<bool> ep6_we, ep6_re;
sc_in<bool> ep6_empty, ep6_full;
 
// EP7
sc_in<sc_uint<14> > ep7_cfg;
sc_in<sc_uint<8> > ep7_din;
sc_out<sc_uint<8> > ep7_dout;
sc_out<bool> ep7_we, ep7_re;
sc_in<bool> ep7_empty, ep7_full;
 
// Local Signals
 
// SIE Interface
sc_signal<sc_uint<8> > DataOut;
sc_signal<bool> TxValid;
sc_signal<bool> TxReady;
sc_signal<sc_uint<8> > DataIn;
sc_signal<bool> RxValid;
sc_signal<bool> RxActive;
sc_signal<bool> RxError;
sc_signal<sc_uint<2> > LineState;
 
// Internal Register File Interface
sc_signal<sc_uint<7> > funct_adr; // This function address (set by Controller)
sc_signal<bool> int_to_set; // Set time out interrupt
sc_signal<bool> int_seqerr_set; // Set PID sequence error interrupt
sc_signal<sc_uint<32> > frm_nat; // Frame number and time register
sc_signal<bool> nse_err; // No such endpoint error
sc_signal<bool> pid_cs_err; // PID CS error
sc_signal<bool> crc5_err; // CRC5 error
 
// Status Signals
sc_signal<sc_uint<11> > frame_no;
sc_signal<bool> addressed;
sc_signal<bool> configured;
sc_signal<bool> halt;
 
// Data and Control Signals
sc_signal<sc_uint<8> > tx_data_st;
sc_signal<sc_uint<8> > rx_data_st;
sc_signal<sc_uint<14> > cfg;
sc_signal<bool> ep_empty;
sc_signal<bool> ep_full;
sc_signal<sc_uint<8> > rx_size;
sc_signal<bool> rx_done;
 
// EP0 Signals
sc_signal<sc_uint<8> > ep0_din;
sc_signal<sc_uint<8> > ep0_dout;
sc_signal<bool> ep0_re, ep0_we;
sc_signal<sc_uint<8> > ep0_size;
sc_signal<sc_uint<8> > ep0_ctrl_dout, ep0_ctrl_din;
sc_signal<bool> ep0_ctrl_re, ep0_ctrl_we;
sc_signal<sc_uint<4> > ep0_ctrl_stat;
 
// Control Pipe Interface
sc_signal<bool> ctrl_setup, ctrl_in, ctrl_out;
sc_signal<bool> send_stall;
sc_signal<bool> token_valid;
sc_signal<bool> rst_local; // Internal reset
 
// ROM Signals
sc_signal<sc_uint<8> > rom_adr;
sc_signal<sc_uint<8> > rom_data;
 
// FIFO Signals
sc_signal<bool> idma_re, idma_we;
sc_signal<bool> ep0_empty, ep0_full;
 
sc_signal<bool> stat1, stat2;
 
usb_phy *i_phy; // PHY
usb_sie *i_sie; // SIE
usb_ep0 *i_ep0; // EP0
usb_rom *i_rom; // ROM
usb_fifo64x8 *i_ff_in; // FIFO_IN
usb_fifo64x8 *i_ff_out; // FIFO_OUT
 
// Internal Reset Function
void rst_local_up(void);
 
// Misc Functions
void stat_up(void);
void frame_no_up(void);
 
// Muxes Functions
void cfg_mux(void);
void tx_data_mux(void);
void ep_empty_mux(void);
void ep_full_mux(void);
 
// Decos Functions
void ep_dout_deco(void);
void ep_re_deco(void);
void ep_we_deco(void);
 
// Destructor
// ~usb_core(void);
 
SC_CTOR(usb_core) {
SC_METHOD(rst_local_up);
sensitive << clk_i.pos();
 
SC_METHOD(stat_up);
sensitive << stat1 << stat2;
SC_METHOD(frame_no_up);
sensitive << frm_nat;
 
SC_METHOD(cfg_mux);
sensitive << ep_sel << ep0_size << ep1_cfg << ep2_cfg << ep3_cfg;
sensitive << ep4_cfg << ep5_cfg << ep6_cfg << ep7_cfg;
SC_METHOD(tx_data_mux);
sensitive << clk_i.pos();
SC_METHOD(ep_empty_mux);
sensitive << clk_i.pos();
SC_METHOD(ep_full_mux);
sensitive << ep_sel << ep0_full << ep1_full << ep2_full << ep3_full;
sensitive << ep4_full << ep5_full << ep6_full << ep7_full;
 
SC_METHOD(ep_dout_deco);
sensitive << rx_data_st;
SC_METHOD(ep_re_deco);
sensitive << idma_re << ep_sel << ep1_empty << ep2_empty << ep3_empty;
sensitive << ep4_empty << ep5_empty << ep6_empty << ep7_empty;
SC_METHOD(ep_we_deco);
sensitive << idma_we << ep_sel << ep1_full << ep2_full << ep3_full;
sensitive << ep4_full << ep5_full << ep6_full << ep7_full;
 
// PHY Instantiation and Binding
i_phy = new usb_phy("PHY");
i_phy->clk(clk_i);
i_phy->rst(rst_i); // ONLY external reset
i_phy->phy_tx_mode(phy_tx_mode);
i_phy->usb_rst(usb_rst);
i_phy->txdp(tx_dp);
i_phy->txdn(tx_dn);
i_phy->txoe(tx_oe);
i_phy->rxd(rx_d);
i_phy->rxdp(rx_dp);
i_phy->rxdn(rx_dn);
i_phy->DataOut_i(DataOut);
i_phy->TxValid_i(TxValid);
i_phy->TxReady_o(TxReady);
i_phy->DataIn_o(DataIn);
i_phy->RxValid_o(RxValid);
i_phy->RxActive_o(RxActive);
i_phy->RxError_o(RxError);
i_phy->LineState_o(LineState);
 
// SIE Instantiation and Binding
i_sie = new usb_sie("SIE");
i_sie->clk(clk_i);
i_sie->rst(rst_local);
i_sie->DataOut(DataOut);
i_sie->TxValid(TxValid);
i_sie->TxReady(TxReady);
i_sie->DataIn(DataIn);
i_sie->RxValid(RxValid);
i_sie->RxActive(RxActive);
i_sie->RxError(RxError);
i_sie->token_valid(token_valid);
i_sie->fa(funct_adr);
i_sie->ep_sel(ep_sel);
i_sie->x_busy(usb_busy);
i_sie->int_crc16_set(crc16_err);
i_sie->int_to_set(int_to_set);
i_sie->int_seqerr_set(int_seqerr_set);
i_sie->pid_cs_err(pid_cs_err);
i_sie->crc5_err(crc5_err);
i_sie->frm_nat(frm_nat);
i_sie->nse_err(nse_err);
i_sie->rx_size(rx_size);
i_sie->rx_done(rx_done);
i_sie->ctrl_setup(ctrl_setup);
i_sie->ctrl_in(ctrl_in);
i_sie->ctrl_out(ctrl_out);
i_sie->csr(cfg);
i_sie->tx_data_st(tx_data_st);
i_sie->rx_data_st(rx_data_st);
i_sie->idma_re(idma_re);
i_sie->idma_we(idma_we);
i_sie->ep_empty(ep_empty);
i_sie->ep_full(ep_full);
i_sie->send_stall(send_stall);
 
// EP0 Instantiation and Binding
i_ep0 = new usb_ep0("EP0");
i_ep0->clk(clk_i);
i_ep0->rst(rst_local);
i_ep0->rom_adr(rom_adr);
i_ep0->rom_data(rom_data);
i_ep0->ctrl_setup(ctrl_setup);
i_ep0->ctrl_in(ctrl_in);
i_ep0->ctrl_out(ctrl_out);
i_ep0->frame_no(frame_no);
i_ep0->send_stall(send_stall);
i_ep0->funct_adr(funct_adr);
i_ep0->addressed(addressed);
i_ep0->configured(configured);
i_ep0->halt(halt);
i_ep0->ep0_din(ep0_ctrl_dout);
i_ep0->ep0_dout(ep0_ctrl_din);
i_ep0->ep0_re(ep0_ctrl_re);
i_ep0->ep0_we(ep0_ctrl_we);
i_ep0->ep0_stat(ep0_ctrl_stat);
i_ep0->ep0_size(ep0_size);
i_ep0->v_set_int(v_set_int);
i_ep0->v_set_feature(v_set_feature);
i_ep0->wValue(wValue);
i_ep0->wIndex(wIndex);
i_ep0->vendor_data(vendor_data);
 
// ROM Instantiation and Binding
i_rom = new usb_rom("ROM");
i_rom->clk(clk_i);
i_rom->adr(rom_adr);
i_rom->dout(rom_data);
 
// FIFO_IN Instantiation and Binding
i_ff_in = new usb_fifo64x8("FIFO_IN");
i_ff_in->clk(clk_i);
i_ff_in->rst(rst_i);
i_ff_in->clr(usb_rst);
i_ff_in->we(ep0_ctrl_we);
i_ff_in->din(ep0_ctrl_din);
i_ff_in->re(ep0_re);
i_ff_in->dout(ep0_dout);
i_ff_in->empty(ep0_empty);
i_ff_in->full(stat2);
 
// FIFO_OUT Instantiation and Binding
i_ff_out = new usb_fifo64x8("FIFO_OUT");
i_ff_out->clk(clk_i);
i_ff_out->rst(rst_i);
i_ff_out->clr(usb_rst);
i_ff_out->we(ep0_we);
i_ff_out->din(rx_data_st);
i_ff_out->re(ep0_ctrl_re);
i_ff_out->dout(ep0_ctrl_dout);
i_ff_out->empty(stat1);
i_ff_out->full(ep0_full);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_pa_sie.cpp
0,0 → 1,272
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Packet Assembler ////
//// ////
//// SystemC Version: usb_pa_sie.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_pa.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 "systemc.h"
#include "usb_pa_sie.h"
 
void usb_pa_sie::zl_up(void) {
zero_length.write(ep_empty.read());
}
 
void usb_pa_sie::zl_r_up(void) {
if (!rst.read())
zero_length_r.write(false);
else if (last.read())
zero_length_r.write(false);
else if (crc16_clr.read())
zero_length_r.write(zero_length.read());
}
 
void usb_pa_sie::tx_valid_r_up1(void) {
tx_valid_r1.write(tx_valid.read());
}
 
void usb_pa_sie::tx_valid_r_up2(void) {
tx_valid_r.write(tx_valid_r1.read());
}
 
void usb_pa_sie::send_token_up(void) {
if (!rst.read())
send_token_r.write(false);
else if (send_token.read())
send_token_r.write(true);
else if (tx_ready.read())
send_token_r.write(false);
}
 
// TOKEN PID Select
void usb_pa_sie::token_pid_up(void) {
switch (token_pid_sel.read()) {// synopsys full_case parallel_case
case 0: token_pid.write(((sc_uint<4>)(~USBF_T_PID_ACK), (sc_uint<4>)USBF_T_PID_ACK));
break;
case 1: token_pid.write(((sc_uint<4>)(~USBF_T_PID_NACK), (sc_uint<4>)USBF_T_PID_NACK));
break;
case 2: token_pid.write(((sc_uint<4>)(~USBF_T_PID_STALL), (sc_uint<4>)USBF_T_PID_STALL));
break;
case 3: token_pid.write(((sc_uint<4>)(~USBF_T_PID_NYET), (sc_uint<4>)USBF_T_PID_NYET));
break;
}
}
 
// DATA PID Select
void usb_pa_sie::data_pid_up(void) {
switch (data_pid_sel.read()) {// synopsys full_case parallel_case
case 0: data_pid.write(((sc_uint<4>)(~USBF_T_PID_DATA0), (sc_uint<4>)USBF_T_PID_DATA0));
break;
case 1: data_pid.write(((sc_uint<4>)(~USBF_T_PID_DATA1), (sc_uint<4>)USBF_T_PID_DATA1));
break;
case 2: data_pid.write(((sc_uint<4>)(~USBF_T_PID_DATA2), (sc_uint<4>)USBF_T_PID_DATA2));
break;
case 3: data_pid.write(((sc_uint<4>)(~USBF_T_PID_MDATA), (sc_uint<4>)USBF_T_PID_MDATA));
break;
}
}
 
// Data Path Muxes
void usb_pa_sie::tx_data_up1(void) {
if (dsel.read())
tx_data_data.write(tx_spec_data.read());
else
tx_data_data.write(tx_data_st.read());
}
 
void usb_pa_sie::tx_data_up2(void) {
if (send_token.read() || send_token_r.read())
tx_data_d.write(token_pid.read());
else
tx_data_d.write(tx_data_data.read());
}
 
void usb_pa_sie::tx_data_up3(void) {
tx_data.write(tx_data_d.read());
}
 
void usb_pa_sie::tx_spec_up(void) {
if (!crc_sel1.read() && !crc_sel2.read())
tx_spec_data.write(data_pid.read());
else if (crc_sel1.read())
tx_spec_data.write(crc16_rev.read().range(15, 8)); // CRC 1
else
tx_spec_data.write(crc16_rev.read().range(7, 0)); // CRC 2
}
 
// TX Valid Assignment
void usb_pa_sie::tx_valid_up1(void) {
tx_valid_last.write(send_token.read() || last.read());
}
 
void usb_pa_sie::tx_valid_up2(void) {
tx_valid.write(tx_valid_d.read());
}
 
void usb_pa_sie::tx_first_up1(void) {
tx_first_r.write(send_token.read() || send_data.read());
}
 
void usb_pa_sie::tx_first_up2(void) {
tx_first.write((send_token.read() || send_data.read()) && !tx_first_r.read());
}
 
// CRC Logic
void usb_pa_sie::send_data_up1(void) {
send_data_r.write(send_data.read());
}
 
void usb_pa_sie::send_data_up2(void) {
send_data_r2.write(send_data_r.read());
}
 
void usb_pa_sie::crc16_clr_up(void) {
crc16_clr.write(send_data.read() && !send_data_r.read());
}
 
void usb_pa_sie::crc16_din_up(void) {
#ifdef USB_SIMULATION
crc16_din.write(( (sc_uint<1>)tx_data_st.read()[0],
(sc_uint<1>)tx_data_st.read()[1],
(sc_uint<1>)tx_data_st.read()[2],
(sc_uint<1>)tx_data_st.read()[3],
(sc_uint<1>)tx_data_st.read()[4],
(sc_uint<1>)tx_data_st.read()[5],
(sc_uint<1>)tx_data_st.read()[6],
(sc_uint<1>)tx_data_st.read()[7]));
#else
crc16_din.write(tx_data_st.read().range(0, 7));
#endif
}
 
void usb_pa_sie::crc16_add_up(void) {
crc16_add.write(!zero_length_r.read() &&
((send_data_r.read() && !send_data_r2.read()) || (rd_next.read() && !crc_sel1.read())));
}
 
void usb_pa_sie::crc16_up(void) {
if (crc16_clr.read())
crc16.write(65535);
else if (crc16_add.read())
crc16.write(crc16_next.read());
}
 
void usb_pa_sie::crc16_rev_up(void) {
#ifdef USB_SIMULATION
crc16_rev.write(( (sc_uint<1>)!crc16.read()[8],
(sc_uint<1>)!crc16.read()[9],
(sc_uint<1>)!crc16.read()[10],
(sc_uint<1>)!crc16.read()[11],
(sc_uint<1>)!crc16.read()[12],
(sc_uint<1>)!crc16.read()[13],
(sc_uint<1>)!crc16.read()[14],
(sc_uint<1>)!crc16.read()[15],
(sc_uint<1>)!crc16.read()[0],
(sc_uint<1>)!crc16.read()[1],
(sc_uint<1>)!crc16.read()[2],
(sc_uint<1>)!crc16.read()[3],
(sc_uint<1>)!crc16.read()[4],
(sc_uint<1>)!crc16.read()[5],
(sc_uint<1>)!crc16.read()[6],
(sc_uint<1>)!crc16.read()[7]));
#else
crc16_rev.write(((sc_uint<8>)(~crc16.read().range(8, 15)), (sc_uint<8>)(~crc16.read().range(0, 7))));
#endif
}
 
// Transmit and Encode FSM
void usb_pa_sie::state_up(void) {
if (!rst.read())
state.write(PA_IDLE);
else
state.write(next_state.read());
}
 
void usb_pa_sie::pa_statemachine(void) {
next_state.write(state.read()); // Default don't change current state
tx_valid_d.write(false);
dsel.write(false);
rd_next.write(false);
last.write(false);
crc_sel1.write(false);
crc_sel2.write(false);
 
switch (state.read()) {// synopsys full_case parallel_case
case PA_IDLE: if (zero_length.read() && send_data.read()) {
tx_valid_d.write(true);
dsel.write(true);
next_state.write(PA_CRC1);
 
// Send DATA packet
} else if (send_data.read()) {
tx_valid_d.write(true);
dsel.write(true);
next_state.write(PA_DATA);
}
break;
case PA_DATA: if (tx_ready.read() && tx_valid_r.read())
rd_next.write(true);
 
tx_valid_d.write(true);
if (!send_data.read() && tx_ready.read() && tx_valid_r.read()) {
dsel.write(true);
crc_sel1.write(true);
next_state.write(PA_CRC1);
}
break;
case PA_CRC1: dsel.write(true);
tx_valid_d.write(true);
if (tx_ready.read()) {
last.write(true);
crc_sel2.write(true);
next_state.write(PA_CRC2);
} else {
tx_valid_d.write(true);
crc_sel1.write(true);
}
break;
case PA_CRC2: dsel.write(true);
crc_sel2.write(true);
if (tx_ready.read())
next_state.write(PA_IDLE);
else
last.write(true);
break;
}
}
/*
usb_pa_sie::~usb_pa_sie(void) {
if (i_crc16)
delete i_crc16;
}
*/
/trunk/rtl/systemc/usb_phy.cpp
0,0 → 1,64
/////////////////////////////////////////////////////////////////////
//// ////
//// USB PHY ////
//// ////
//// SystemC Version: usb_phy.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_phy.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 "systemc.h"
#include "usb_phy.h"
 
void usb_phy::reset_up(void) {
reset.write(rst.read() && !usb_rst.read());
}
 
void usb_phy::rst_cnt_up(void) {
if (!rst.read())
rst_cnt.write(0);
else if (LineState_o.read() != 0)
rst_cnt.write(0);
else if (!usb_rst.read() && fs_ce.read())
rst_cnt.write(rst_cnt.read() + 1);
}
 
void usb_phy::usb_rst_up(void) {
usb_rst.write(rst_cnt.read() == 31);
}
/*
usb_phy::~usb_phy(void) {
if (i_tx_phy)
delete i_tx_phy;
if (i_rx_phy)
delete i_rx_phy;
}
*/
/trunk/rtl/systemc/usb_dma.cpp
0,0 → 1,188
/////////////////////////////////////////////////////////////////////
//// ////
//// USB IDMA Engine ////
//// ////
//// SystemC Version: usb_dma.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_idma.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 "systemc.h"
#include "usb_dma.h"
 
void usb_dma::empty_int_up(void) {
ep_empty_int.write(ep_empty.read());
}
 
void usb_dma::full_int_up(void) {
ep_full_int.write(ep_full.read());
}
 
void usb_dma::mwe_up1(void) {
mwe_r.write(rx_data_valid.read());
}
 
void usb_dma::mwe_up2(void) {
mwe.write(mwe_r.read() && !ep_full_int.read());
}
 
void usb_dma::data_valid_up(void) {
rx_data_valid_r.write(rx_data_valid.read());
}
 
void usb_dma::data_done_up(void) {
rx_data_done_r.write(rx_data_done.read());
}
 
void usb_dma::tx_dma_en_up1(void) {
tx_dma_en_r.write(tx_dma_en.read());
}
 
void usb_dma::tx_dma_en_up2(void) {
tx_dma_en_r1.write(tx_dma_en_r.read());
}
 
void usb_dma::tx_dma_en_up3(void) {
tx_dma_en_r2.write(tx_dma_en_r1.read());
}
 
void usb_dma::idma_done_up(void) {
idma_done.write(rx_data_done_r.read() || sizd_is_zero_d.read() || ep_empty_int.read());
}
 
void usb_dma::rx_cnt_up1(void) {
if (!rst.read())
rx_cnt_r.write(0);
else if (rx_data_done_r.read())
rx_cnt_r.write(0);
else if (rx_data_valid.read())
rx_cnt_r.write(rx_cnt_r.read() + 1);
}
 
void usb_dma::rx_cnt_up2(void) {
if (!rst.read())
rx_cnt.write(0);
else if (rx_data_done_r.read())
rx_cnt.write(rx_cnt_r.read());
}
 
void usb_dma::rx_done_up(void) {
rx_done.write(rx_data_done_r.read());
}
 
// Transmit Size Counter (counting backward from input size)
// For MAX packet size
void usb_dma::sizd_cnt_up(void) {
if (!rst.read())
sizd_c.write(511);
else if (tx_dma_en.read())
sizd_c.write(size.read());
else if (siz_dec.read())
sizd_c.write(sizd_c.read() - 1);
}
 
void usb_dma::is_zero_up1(void) {
sizd_is_zero_d.write(sizd_c.read() == 0);
}
 
void usb_dma::is_zero_up2(void) {
sizd_is_zero.write(sizd_is_zero_d.read());
}
 
void usb_dma::siz_dec_up(void) {
siz_dec.write((tx_dma_en_r.read() || tx_dma_en_r1.read() || rd_next.read()) && !sizd_is_zero_d.read());
}
 
void usb_dma::tx_busy_up(void) {
tx_busy.write(send_data.read() || tx_dma_en_r.read() || tx_dma_en.read());
}
 
void usb_dma::tx_valid_up1(void) {
tx_valid_r.write(tx_valid.read());
}
 
void usb_dma::tx_valid_up2(void) {
tx_valid_e.write(tx_valid_r.read() && !tx_valid.read());
}
 
// Since we are prefetching two entries in to our fast fifo, we
// need to know when exactly ep_empty was asserted, as we might
// only need 1 or 2 bytes. This is for ep_empty_r
void usb_dma::empty_up(void) {
if (!rst.read())
ep_empty_r.write(false);
else if (!tx_valid.read())
ep_empty_r.write(false);
else if (tx_dma_en_r2.read())
ep_empty_r.write(ep_empty_int.read());
}
 
void usb_dma::send_data_up1(void) {
if (!rst.read())
send_data_r.write(false);
else if (tx_dma_en_r.read() && !ep_empty_int.read())
send_data_r.write(true);
else if (rd_next.read() && (sizd_is_zero_d.read() || (ep_empty_int.read() && !sizd_is_zero_d.read())))
send_data_r.write(false);
}
 
void usb_dma::send_data_up2(void) {
send_data.write((send_data_r.read() && !ep_empty_r.read() && !(sizd_is_zero.read() &&
(size.read() == 1))) || tx_dma_en_r1.read());
}
 
void usb_dma::mre_up(void) {
mre.write((tx_dma_en_r1.read() || tx_dma_en_r.read() || rd_next.read()) &&
!sizd_is_zero_d.read() && !ep_empty_int.read() &&
(send_data.read() || tx_dma_en_r1.read() || tx_dma_en_r.read()));
}
 
void usb_dma::ff_we_up1(void) {
ff_we1.write(mre.read());
}
 
void usb_dma::ff_we_up2(void) {
ff_we.write(ff_we1.read());
}
 
void usb_dma::ff_re_up(void) {
ff_re.write(rd_next.read());
}
 
void usb_dma::ff_clr_up(void) {
ff_clr.write(!tx_valid.read());
}
/*
usb_dma::~usb_dma(void) {
if (i_ff2)
delete i_ff2;
}
*/
/trunk/rtl/systemc/usb_rom.h
0,0 → 1,323
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Descriptor ROM ////
//// ////
//// SystemC Version: usb_rom.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_rom1.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_ROM_H
#define USB_ROM_H
 
#include "systemc.h"
 
SC_MODULE(usb_rom) {
 
public:
 
sc_in<bool> clk;
sc_in<sc_uint<8> > adr;
sc_out<sc_uint<8> > dout;
 
void dout_update(void) {
switch (adr.read()) {// synopsys full_case parallel_case
// ====================================
// ===== DEVICE Descriptor =====
// ====================================
case 0x00: dout.write( 18); break; // this descriptor length
case 0x01: dout.write(0x01); break; // descriptor type
case 0x02: dout.write(0x10); break; // USB version low byte
case 0x03: dout.write(0x01); break; // USB version high byte
case 0x04: dout.write(0xff); break; // device class
case 0x05: dout.write(0x00); break; // device sub class
case 0x06: dout.write(0xff); break; // device protocol
case 0x07: dout.write( 64); break; // max packet size
case 0x08: dout.write(0x34); break; // vendor ID low byte
case 0x09: dout.write(0x12); break; // vendor ID high byte
case 0x0a: dout.write(0x78); break; // product ID low byte
case 0x0b: dout.write(0x56); break; // product ID high byte
case 0x0c: dout.write(0x10); break; // device rel. number low byte
case 0x0d: dout.write(0x00); break; // device rel. number high byte
case 0x0e: dout.write(0x01); break; // Manufacturer String Index
case 0x0f: dout.write(0x02); break; // Product Descr. String Index
case 0x10: dout.write(0x03); break; // S/N String Index
case 0x11: dout.write(0x01); break; // Number of possible config.
 
// ====================================
// ===== Configuration Descriptor =====
// ====================================
case 0x12: dout.write(0x09); break; // this descriptor length
case 0x13: dout.write(0x02); break; // descriptor type
case 0x14: dout.write( 60); break; // total data length low byte
case 0x15: dout.write( 0); break; // total data length high byte
case 0x16: dout.write(0x01); break; // number of interfaces
case 0x17: dout.write(0x01); break; // number of configurations
case 0x18: dout.write(0x00); break; // Conf. String Index
case 0x19: dout.write(0x40); break; // Config. Characteristics
case 0x1a: dout.write(0x00); break; // Max. Power Consumption
 
// ====================================
// ===== Interface Descriptor =====
// ====================================
case 0x1b: dout.write(0x09); break; // this descriptor length
case 0x1c: dout.write(0x04); break; // descriptor type
case 0x1d: dout.write(0x00); break; // interface number
case 0x1e: dout.write(0x00); break; // alternate setting
case 0x1f: dout.write(0x06); break; // number of endpoints
case 0x20: dout.write(0xff); break; // interface class
case 0x21: dout.write(0x01); break; // interface sub class
case 0x22: dout.write(0xff); break; // interface protocol
case 0x23: dout.write(0x00); break; // interface string index
 
// ====================================
// ===== Endpoint 1 Descriptor =====
// ====================================
case 0x24: dout.write(0x07); break; // this descriptor length
case 0x25: dout.write(0x05); break; // descriptor type
case 0x26: dout.write(0x81); break; // endpoint address
case 0x27: dout.write(0x01); break; // endpoint attributes
case 0x28: dout.write(0x00); break; // max packet size low byte
case 0x29: dout.write(0x01); break; // max packet size high byte
case 0x2a: dout.write(0x01); break; // polling interval
 
// ====================================
// ===== Endpoint 2 Descriptor =====
// ====================================
case 0x2b: dout.write(0x07); break; // this descriptor length
case 0x2c: dout.write(0x05); break; // descriptor type
case 0x2d: dout.write(0x02); break; // endpoint address
case 0x2e: dout.write(0x01); break; // endpoint attributes
case 0x2f: dout.write(0x00); break; // max packet size low byte
case 0x30: dout.write(0x01); break; // max packet size high byte
case 0x31: dout.write(0x01); break; // polling interval
 
// ====================================
// ===== Endpoint 3 Descriptor =====
// ====================================
case 0x32: dout.write(0x07); break; // this descriptor length
case 0x33: dout.write(0x05); break; // descriptor type
case 0x34: dout.write(0x83); break; // endpoint address
case 0x35: dout.write(0x02); break; // endpoint attributes
case 0x36: dout.write( 64); break; // max packet size low byte
case 0x37: dout.write( 0); break; // max packet size high byte
case 0x38: dout.write(0x01); break; // polling interval
 
// ====================================
// ===== Endpoint 4 Descriptor =====
// ====================================
case 0x39: dout.write(0x07); break; // this descriptor length
case 0x3a: dout.write(0x05); break; // descriptor type
case 0x3b: dout.write(0x04); break; // endpoint address
case 0x3c: dout.write(0x02); break; // endpoint attributes
case 0x3d: dout.write( 64); break; // max packet size low byte
case 0x3e: dout.write( 0); break; // max packet size high byte
case 0x3f: dout.write(0x01); break; // polling interval
 
// ====================================
// ===== Endpoint 5 Descriptor =====
// ====================================
case 0x40: dout.write(0x07); break; // this descriptor length
case 0x41: dout.write(0x05); break; // descriptor type
case 0x42: dout.write(0x85); break; // endpoint address
case 0x43: dout.write(0x03); break; // endpoint attributes
case 0x44: dout.write( 64); break; // max packet size low byte
case 0x45: dout.write( 0); break; // max packet size high byte
case 0x46: dout.write(0x01); break; // polling interval
 
// ====================================
// ===== Endpoint 6 Descriptor =====
// ====================================
case 0x47: dout.write(0x07); break; // this descriptor length
case 0x48: dout.write(0x05); break; // descriptor type
case 0x49: dout.write(0x06); break; // endpoint address
case 0x4a: dout.write(0x03); break; // endpoint attributes
case 0x4b: dout.write( 64); break; // max packet size low byte
case 0x4c: dout.write( 0); break; // max packet size high byte
case 0x4d: dout.write(0x01); break; // polling interval
 
// ====================================
// ===== String Descriptor Lang ID=====
// ====================================
case 0x4e: dout.write(0x06); break; // this descriptor length
case 0x4f: dout.write(0x03); break; // descriptor type
 
// Brazilian Portuguese
case 0x50: dout.write(0x16); break; // Language ID 0 low byte
case 0x51: dout.write(0x04); break; // Language ID 0 high byte
 
// Brazilian Portuguese
case 0x52: dout.write(0x16); break; // Language ID 1 low byte
case 0x53: dout.write(0x04); break; // Language ID 1 high byte
 
// Brazilian Portuguese
case 0x54: dout.write(0x16); break; // Language ID 2 low byte
case 0x55: dout.write(0x04); break; // Language ID 2 high byte
 
// ====================================
// ===== String Descriptor 1 =====
// ====================================
case 0x56: dout.write( 26); break; // this descriptor length
case 0x57: dout.write(0x03); break; // descriptor type
 
// "BrazilIP.org"
case 0x58: dout.write( 0); break;
case 0x59: dout.write( 'g'); break;
case 0x5a: dout.write( 0); break;
case 0x5b: dout.write( 'r'); break;
case 0x5c: dout.write( 0); break;
case 0x5d: dout.write( 'o'); break;
case 0x5e: dout.write( 0); break;
case 0x5f: dout.write( '.'); break;
case 0x60: dout.write( 0); break;
case 0x61: dout.write( 'P'); break;
case 0x62: dout.write( 0); break;
case 0x63: dout.write( 'I'); break;
case 0x64: dout.write( 0); break;
case 0x65: dout.write( 'l'); break;
case 0x66: dout.write( 0); break;
case 0x67: dout.write( 'i'); break;
case 0x68: dout.write( 0); break;
case 0x69: dout.write( 'z'); break;
case 0x6a: dout.write( 0); break;
case 0x6b: dout.write( 'a'); break;
case 0x6c: dout.write( 0); break;
case 0x6d: dout.write( 'r'); break;
case 0x6e: dout.write( 0); break;
case 0x6f: dout.write( 'B'); break;
 
// ====================================
// ===== String Descriptor 2 =====
// ====================================
case 0x70: dout.write( 28); break; // this descriptor length
case 0x71: dout.write(0x03); break; // descriptor type
 
 
case 0x72: dout.write( 0); break;
case 0x73: dout.write( 'x'); break;
case 0x74: dout.write( 0); break;
case 0x75: dout.write( 'i'); break;
case 0x76: dout.write( 0); break;
case 0x77: dout.write( 'n'); break;
case 0x78: dout.write( 0); break;
case 0x79: dout.write(0xea); break; //e-circumflex
case 0x7a: dout.write( 0); break;
case 0x7b: dout.write( 'F'); break;
case 0x7c: dout.write( 0); break;
case 0x7d: dout.write( ' '); break;
case 0x7e: dout.write( 0); break;
case 0x7f: dout.write( 'o'); break;
case 0x80: dout.write( 0); break;
case 0x81: dout.write( 't'); break;
case 0x82: dout.write( 0); break;
case 0x83: dout.write( 'e'); break;
case 0x84: dout.write( 0); break;
case 0x85: dout.write( 'j'); break;
case 0x86: dout.write( 0); break;
case 0x87: dout.write( 'o'); break;
case 0x88: dout.write( 0); break;
case 0x89: dout.write( 'r'); break;
case 0x8a: dout.write( 0); break;
case 0x8b: dout.write( 'P'); break;
 
// ====================================
// ===== String Descriptor 3 =====
// ====================================
case 0x8c: dout.write( 54); break; // this descriptor length
case 0x8d: dout.write(0x03); break; // descriptor type
 
 
case 0x8e: dout.write( 0); break;
case 0x8f: dout.write( ')'); break;
case 0x90: dout.write( 0); break;
case 0x91: dout.write( '3'); break;
case 0x92: dout.write( 0); break;
case 0x93: dout.write( '0'); break;
case 0x94: dout.write( 0); break;
case 0x95: dout.write( '0'); break;
case 0x96: dout.write( 0); break;
case 0x97: dout.write( '2'); break;
case 0x98: dout.write( 0); break;
case 0x99: dout.write( '('); break;
case 0x9a: dout.write( 0); break;
case 0x9b: dout.write( ' '); break;
case 0x9c: dout.write( 0); break;
case 0x9d: dout.write( 'l'); break;
case 0x9e: dout.write( 0); break;
case 0x9f: dout.write( 'a'); break;
case 0xa0: dout.write( 0); break;
case 0xa1: dout.write( 't'); break;
case 0xa2: dout.write( 0); break;
case 0xa3: dout.write( 'n'); break;
case 0xa4: dout.write( 0); break;
case 0xa5: dout.write( 'e'); break;
case 0xa6: dout.write( 0); break;
case 0xa7: dout.write( 'm'); break;
case 0xa8: dout.write( 0); break;
case 0xa9: dout.write( 'i'); break;
case 0xaa: dout.write( 0); break;
case 0xab: dout.write( 'r'); break;
case 0xac: dout.write( 0); break;
case 0xad: dout.write( 'e'); break;
case 0xae: dout.write( 0); break;
case 0xaf: dout.write( 'p'); break;
case 0xb0: dout.write( 0); break;
case 0xb1: dout.write( 'x'); break;
case 0xb2: dout.write( 0); break;
case 0xb3: dout.write( 'E'); break;
case 0xb4: dout.write( 0); break;
case 0xb5: dout.write( ' '); break;
case 0xb6: dout.write( 0); break;
case 0xb7: dout.write( 'o'); break;
case 0xb8: dout.write( 0); break;
case 0xb9: dout.write(0xe3); break; //a-tilde
case 0xba: dout.write( 0); break;
case 0xbb: dout.write( 's'); break;
case 0xbc: dout.write( 0); break;
case 0xbd: dout.write( 'r'); break;
case 0xbe: dout.write( 0); break;
case 0xbf: dout.write( 'e'); break;
case 0xc0: dout.write( 0); break;
case 0xc1: dout.write( 'V'); break;
 
default: dout.write(0x00); break;
}
}
 
SC_CTOR(usb_rom) {
SC_METHOD(dout_update);
sensitive << clk.pos();
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_fifo128x8.h
0,0 → 1,115
/////////////////////////////////////////////////////////////////////
//// ////
//// USB FIFO ////
//// ////
//// SystemC Version: usb_fifo128x8.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_fifo_sc_a.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_FIFO128X8_H
#define USB_FIFO128X8_H
 
#include "usb_ram128x8.h"
 
#define FIFO_ASYNC_RESET
//#define FIFO_ASYNC_RESET << rst.neg()
 
SC_MODULE(usb_fifo128x8) {
 
private:
 
sc_signal<bool> vcc;
 
public:
 
sc_in<bool> clk;
sc_in<bool> rst;
sc_in<bool> clr;
sc_in<bool> we;
sc_in<sc_uint<8> > din;
sc_in<bool> re;
sc_out<sc_uint<8> > dout;
sc_out<bool> empty;
sc_out<bool> full;
 
sc_signal<sc_uint<7> > wp, wp_pl1, wp_pl2;
sc_signal<sc_uint<7> > rp, rp_pl1;
sc_signal<bool> gb, n_rst;
 
usb_ram128x8 *i_ram;
 
void write_pointer_update(void);
void read_pointer_update(void);
void future_pointers_update(void);
void fe_gb_update(void);
void fe_full_update(void);
void fe_empty_update(void);
void reset_update(void);
// ~usb_fifo128x8(void);
 
SC_CTOR(usb_fifo128x8) {
vcc.write(true);
 
SC_METHOD(write_pointer_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(read_pointer_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(future_pointers_update);
sensitive << wp << rp;
SC_METHOD(fe_gb_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(fe_full_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(fe_empty_update);
sensitive << clk.pos() FIFO_ASYNC_RESET;
SC_METHOD(reset_update);
sensitive << rst;
 
i_ram = new usb_ram128x8("RAM128X8");
i_ram->rclk(clk);
i_ram->rrst(n_rst);
i_ram->rce(vcc);
i_ram->oe(vcc);
i_ram->raddr(rp);
i_ram->dout(dout);
i_ram->wclk(clk);
i_ram->wrst(n_rst);
i_ram->wce(vcc);
i_ram->we(we);
i_ram->waddr(wp);
i_ram->din(din);
}
 
};
 
#endif
 
/trunk/rtl/systemc/Makefile.defs
0,0 → 1,39
## Variable that points to SystemC installation path
SYSTEMC = $(SYSTEMC_HOME)
INCDIR = -I. -I.. -I$(SYSTEMC)/include
LIBDIR = -L. -L.. -L$(SYSTEMC)/lib-$(TARGET_ARCH)
 
# Build with maximum gcc warning level
CFLAGS = $(PLATFORM_SPECIFIC_FLAGS) $(EXTRA_CFLAGS)
 
# For gcc, but not for CoCentri SystemC Compiler
USB_FLAGS = -DUSB_SIMULATION
 
LIBS = -lsystemc -lm $(EXTRA_LIBS)
 
 
EXE = $(MODULE).x
 
.SUFFIXES: .cpp .cc .o .x
 
$(EXE): $(OBJS) $(SYSTEMC)/lib-$(TARGET_ARCH)/libsystemc.a
$(CC) $(CFLAGS) $(INCDIR) $(LIBDIR) -o $@ $(OBJS) $(LIBS) 2>&1 | c++filt
 
.cpp.o:
$(CC) $(CFLAGS) $(INCDIR) -c $< $(USB_FLAGS)
 
.cc.o:
$(CC) $(CFLAGS) $(INCDIR) -c $< $(USB_FLAGS)
 
clean::
rm -f $(OBJS) *~ $(EXE)
 
ultraclean: clean
rm -f Makefile.deps
 
Makefile.deps:
$(CC) $(CFLAGS) $(INCDIR) -M $(SRCS) >> Makefile.deps
 
#include Makefile.deps
 
/trunk/rtl/systemc/README
0,0 → 1,19
############## Requirement ##############
- GNU Make 3.79.1
- GCC 3.2.2
- Linux 2.4.x
- SystemC 2.0.1
 
############## Compilation ##############
1) Edit Makefile.defs file
 
2) Run 'make'
 
############## Test Execution ###########
3) Run 'usb.x'
 
4) The output result must be equals to 'usb.out' file
 
-----------------------------------
alfoltran@opencores.org
http://www.brazilip.org/fenix
/trunk/rtl/systemc/usb_pd_sie.cpp
0,0 → 1,322
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Packet Disassembler ////
//// ////
//// SystemC Version: usb_pd_sie.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_pd.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 "systemc.h"
#include "usb_pd_sie.h"
 
void usb_pd_sie::rx_busy_up1(void) {
if (!rst.read())
rx_busy_d.write(false);
else if (rx_valid.read() && (state.read() == PD_DATA))
rx_busy_d.write(true);
else if (state.read() != PD_DATA)
rx_busy_d.write(false);
}
 
void usb_pd_sie::rx_busy_up2(void) {
rx_busy.write(rx_busy_d.read());
}
 
void usb_pd_sie::pid_ld_up(void) {
pid_ld_en.write(pid_le_sm.read() && rx_active.read() && rx_valid.read());
}
 
void usb_pd_sie::pid_up(void) {
if (!rst.read())
pid.write(0xf0);
else if (pid_ld_en.read())
pid.write(rx_data.read());
}
 
void usb_pd_sie::pid_cks_err_up(void) {
pid_cks_err.write(pid.read().range(3, 0) != ~pid.read().range(7, 4));
}
 
void usb_pd_sie::pid_decoder(void) {
pid_OUT.write(pid.read().range(3, 0) == USBF_T_PID_OUT);
pid_IN.write(pid.read().range(3, 0) == USBF_T_PID_IN);
pid_SOF.write(pid.read().range(3, 0) == USBF_T_PID_SOF);
pid_SETUP.write(pid.read().range(3, 0) == USBF_T_PID_SETUP);
pid_DATA0.write(pid.read().range(3, 0) == USBF_T_PID_DATA0);
pid_DATA1.write(pid.read().range(3, 0) == USBF_T_PID_DATA1);
pid_DATA2.write(pid.read().range(3, 0) == USBF_T_PID_DATA2);
pid_MDATA.write(pid.read().range(3, 0) == USBF_T_PID_MDATA);
pid_ACK.write(pid.read().range(3, 0) == USBF_T_PID_ACK);
pid_NACK.write(pid.read().range(3, 0) == USBF_T_PID_NACK);
pid_STALL.write(pid.read().range(3, 0) == USBF_T_PID_STALL);
pid_NYET.write(pid.read().range(3, 0) == USBF_T_PID_NYET);
pid_PRE.write(pid.read().range(3, 0) == USBF_T_PID_PRE);
pid_ERR.write(pid.read().range(3, 0) == USBF_T_PID_ERR);
pid_SPLIT.write(pid.read().range(3, 0) == USBF_T_PID_SPLIT);
pid_PING.write(pid.read().range(3, 0) == USBF_T_PID_PING);
pid_RES.write(pid.read().range(3, 0) == USBF_T_PID_RES);
}
 
void usb_pd_sie::pid_token_up(void) {
pid_TOKEN.write(pid_OUT.read() || pid_IN.read() || pid_SOF.read() || pid_SETUP.read() || pid_PING.read());
}
 
void usb_pd_sie::pid_data_up(void) {
pid_DATA.write(pid_DATA0.read() || pid_DATA1.read() || pid_DATA2.read() || pid_MDATA.read());
}
 
void usb_pd_sie::token_decoder(void) {
if (token_le_1.read())
token0.write(rx_data.read());
 
if (token_le_2.read())
token1.write(rx_data.read());
}
 
void usb_pd_sie::token_valid_up1(void) {
token_valid_r1.write(token_le_2.read());
}
 
void usb_pd_sie::token_valid_up2(void) {
token_valid_str1.write(token_valid_r1.read() || pid_ack.read());
}
 
void usb_pd_sie::token_valid_up3(void) {
token_valid.write(token_valid_str1.read());
}
 
void usb_pd_sie::token_up(void) {
frame_no.write(((sc_uint<3>)token1.read().range(2, 0), token0.read()));
token_fadr.write((sc_uint<7>)token0.read().range(6, 0));
token_endp.write(((sc_uint<3>)token1.read().range(2, 0), (sc_uint<1>)token0.read()[7]));
token_crc5.write((sc_uint<5>)token1.read().range(7, 3));
}
 
// CRC5 should perform the check in one cycle (flow through logic)
// 11 bits and crc5 input, 1 bit output
void usb_pd_sie::crc5_din_up(void) {
#ifdef USB_SIMULATION
crc5_din.write(( (sc_uint<1>)token_fadr.read()[0],
(sc_uint<1>)token_fadr.read()[1],
(sc_uint<1>)token_fadr.read()[2],
(sc_uint<1>)token_fadr.read()[3],
(sc_uint<1>)token_fadr.read()[4],
(sc_uint<1>)token_fadr.read()[5],
(sc_uint<1>)token_fadr.read()[6],
(sc_uint<1>)token_endp.read()[0],
(sc_uint<1>)token_endp.read()[1],
(sc_uint<1>)token_endp.read()[2],
(sc_uint<1>)token_endp.read()[3]));
#else
crc5_din.write(((sc_uint<7>)token_fadr.read().range(0, 6), (sc_uint<4>)token_endp.read().range(0, 3)));
#endif
}
 
void usb_pd_sie::crc5_err_up(void) {
crc5_err.write(token_valid.read() && (crc5_out2.read() != token_crc5.read()));
}
 
// Invert and reverse result bits
void usb_pd_sie::crc5_out2_up(void) {
#ifdef USB_SIMULATION
crc5_out2.write(( (sc_uint<1>)!crc5_out.read()[0],
(sc_uint<1>)!crc5_out.read()[1],
(sc_uint<1>)!crc5_out.read()[2],
(sc_uint<1>)!crc5_out.read()[3],
(sc_uint<1>)!crc5_out.read()[4]));
#else
crc5_out2.write((sc_uint<5>)~crc5_out.read().range(0, 4));
#endif
}
 
// Data receiving logic
// Build a delay line and stop when we are about to get crc
void usb_pd_sie::rxv1_up(void) {
if (!rst.read())
rxv1.write(false);
else if (data_valid_d.read())
rxv1.write(true);
else if (data_done.read())
rxv1.write(false);
}
 
void usb_pd_sie::rxv2_up(void) {
if (!rst.read())
rxv2.write(false);
else if (rxv1.read() && data_valid_d.read())
rxv2.write(true);
else if (data_done.read())
rxv2.write(false);
}
 
void usb_pd_sie::data_valid0_up(void) {
data_valid0.write(rxv2.read() && data_valid_d.read());
}
 
void usb_pd_sie::d_up(void) {
if (data_valid_d.read())
d0.write(rx_data.read());
 
if (data_valid_d.read())
d1.write(d0.read());
 
if (data_valid_d.read())
d2.write(d1.read());
}
 
void usb_pd_sie::rx_data_st_up(void) {
rx_data_st.write(d2.read());
}
 
void usb_pd_sie::rx_data_valid_up(void) {
rx_data_valid.write(data_valid0.read());
}
 
void usb_pd_sie::rx_data_done_up(void) {
rx_data_done.write(data_done.read());
}
 
// CRC16 accumulates rx_data as long as data_valid_d is asserted.
// When data_done is asserted, CRC16 reports status, and resets itself
// next cycle
void usb_pd_sie::rx_active_r_up(void) {
rx_active_r.write(rx_active.read());
}
 
void usb_pd_sie::crc16_din_up(void) {
#ifdef USB_SIMULATION
crc16_din.write(( (sc_uint<1>)rx_data.read()[0],
(sc_uint<1>)rx_data.read()[1],
(sc_uint<1>)rx_data.read()[2],
(sc_uint<1>)rx_data.read()[3],
(sc_uint<1>)rx_data.read()[4],
(sc_uint<1>)rx_data.read()[5],
(sc_uint<1>)rx_data.read()[6],
(sc_uint<1>)rx_data.read()[7]));
#else
crc16_din.write((sc_uint<8>)rx_data.read().range(0, 7));
#endif
}
 
void usb_pd_sie::crc16_clr_up(void) {
crc16_clr.write(rx_active.read() && !rx_active_r.read());
}
 
void usb_pd_sie::crc16_sum_up(void) {
if (crc16_clr.read())
crc16_sum.write(0xffff);
else if (data_valid_d.read())
crc16_sum.write(crc16_out.read());
}
 
void usb_pd_sie::crc16_err_up(void) {
crc16_err.write(data_done.read() && (crc16_sum.read() != 0x800d));
}
 
// Receive and Decode FSM
void usb_pd_sie::state_up(void) {
if (!rst.read())
state.write(PD_IDLE);
else
state.write(next_state.read());
}
 
void usb_pd_sie::pd_statemachine(void) {
next_state.write(state.read()); // Default don't change current state
pid_le_sm.write(false);
token_le_1.write(false);
token_le_2.write(false);
data_valid_d.write(false);
data_done.write(false);
seq_err.write(false);
pid_ack.write(false);
 
switch (state.read()) {// synopsys full_case parallel_case
case PD_IDLE: pid_le_sm.write(true);
if (rx_valid.read() && rx_active.read())
next_state.write(PD_ACTIVE);
break;
case PD_ACTIVE: // Received a ACK from host
if (pid_ACK.read() && !rx_err.read()) {
pid_ack.write(true);
if (!rx_active.read())
next_state.write(PD_IDLE);
 
// Receiving a TOKEN
} else if (pid_TOKEN.read() && rx_valid.read() && rx_active.read() &&
!rx_err.read()) {
token_le_1.write(true);
next_state.write(PD_TOKEN);
 
// Receiving DATA
} else if (pid_DATA.read() && rx_valid.read() && rx_active.read() &&
!rx_err.read()) {
data_valid_d.write(true);
next_state.write(PD_DATA);
 
// ERROR
} else if (!rx_active.read() || rx_err.read() ||
(rx_valid.read() && !(pid_TOKEN.read() || pid_DATA.read()))) {
seq_err.write(!rx_err.read());
if (!rx_active.read())
next_state.write(PD_IDLE);
}
break;
case PD_TOKEN: if (rx_valid.read() && rx_active.read() && !rx_err.read()) {
token_le_2.write(true);
next_state.write(PD_IDLE);
 
// ERROR
} else if (!rx_active.read() || rx_err.read()) {
seq_err.write(!rx_err.read());
if (!rx_active.read())
next_state.write(PD_IDLE);
}
break;
case PD_DATA: if (rx_valid.read() && rx_active.read() && !rx_err.read())
data_valid_d.write(true);
if (!rx_active.read() || rx_err.read()) {
data_done.write(true);
if (!rx_active.read())
next_state.write(PD_IDLE);
}
break;
}
}
/*
usb_pd_sie::~usb_pd_sie(void) {
if (i_crc5)
delete i_crc5;
if (i_crc16)
delete i_crc16;
}
*/
/trunk/rtl/systemc/usb_pe_sie.cpp
0,0 → 1,991
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Protocol Engine ////
//// Performs automatic protocol functions ////
//// ////
//// SystemC Version: usb_pe_sie.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_pe.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 "systemc.h"
#include "usb_pe_sie.h"
 
// Endpoint/CSR Decoding
void usb_pe_sie::csr_decoder(void) {
IN_ep.write(csr.read()[9]);
OUT_ep.write(csr.read()[10]);
CTRL_ep.write(csr.read()[11]);
txfr_iso.write(csr.read()[12]);
txfr_bulk.write(csr.read()[13]);
txfr_int.write(!csr.read()[12] && !csr.read()[13]);
ep_type.write(csr.read().range(10, 9));
txfr_type.write(csr.read().range(13, 12));
}
 
void usb_pe_sie::match_up(void) {
match_r.write(match.read() && fsel.read());
}
 
// No such endpoint indicator
void usb_pe_sie::nse_err_up(void) {
nse_err.write(token_valid.read() && (pid_OUT.read() || pid_IN.read() || pid_SETUP.read()) && !match.read());
}
 
void usb_pe_sie::send_token_up(void) {
send_token.write(send_token_d.read());
}
 
void usb_pe_sie::token_pid_sel_up(void) {
token_pid_sel.write(token_pid_sel_d.read());
}
 
// Data PID storage
void usb_pe_sie::ep0_dpid_up(void) {
if (!rst.read())
ep0_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 0))
ep0_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep1_dpid_up(void) {
if (!rst.read())
ep1_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 1))
ep1_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep2_dpid_up(void) {
if (!rst.read())
ep2_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 2))
ep2_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep3_dpid_up(void) {
if (!rst.read())
ep3_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 3))
ep3_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep4_dpid_up(void) {
if (!rst.read())
ep4_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 4))
ep4_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep5_dpid_up(void) {
if (!rst.read())
ep5_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 5))
ep5_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep6_dpid_up(void) {
if (!rst.read())
ep6_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 6))
ep6_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::ep7_dpid_up(void) {
if (!rst.read())
ep7_dpid.write(0);
else if (uc_dpd_set.read() && (ep_sel.read() == 7))
ep7_dpid.write(next_dpid.read());
}
 
void usb_pe_sie::uc_dpd_up(void) {
switch (ep_sel.read()) {
case 0: uc_dpd.write(ep0_dpid.read()); break;
case 1: uc_dpd.write(ep1_dpid.read()); break;
case 2: uc_dpd.write(ep2_dpid.read()); break;
case 3: uc_dpd.write(ep3_dpid.read()); break;
case 4: uc_dpd.write(ep4_dpid.read()); break;
case 5: uc_dpd.write(ep5_dpid.read()); break;
case 6: uc_dpd.write(ep6_dpid.read()); break;
case 7: uc_dpd.write(ep7_dpid.read()); break;
}
}
 
// Data PID sequencer
void usb_pe_sie::sq_statemachine(void) {
sc_uint<8> sel1;
sc_uint<5> sel2;
sc_uint<2> sel_d1, sel_d2;
 
// tr/mf:ep/type:tr/type:last dpd
sel1 = ((sc_uint<2>)tr_fr_d.read(), (sc_uint<2>)ep_type.read(), (sc_uint<2>)txfr_type.read(), (sc_uint<2>)uc_dpd.read());
 
// CTRL Endpoint Selector
sel2 = ((sc_uint<1>)setup_token.read(), (sc_uint<1>)in_op.read(), (sc_uint<1>)out_op.read(), (sc_uint<2>)uc_dpd.read());
 
// Sync1 Selector
sel_d1 = ((sc_uint<1>)pid_MDATA.read(), (sc_uint<1>)pid_DATA1.read());
 
// Sync2 Selector
sel_d2 = ((sc_uint<1>)pid_MDATA.read(), (sc_uint<1>)pid_DATA2.read());
 
switch (sel1) {// synopsys full_case parallel_case
 
// 0X_01_01_XX -> ISO txfr. IN, 1 tr/mf
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x54:
case 0x55:
case 0x56:
case 0x57: next_dpid.write(0);
break;
 
// 10_01_01_X0 -> ISO txfr. IN, 2 tr/mf
case 0x94:
case 0x96: next_dpid.write(1);
break;
 
// 10_01_01_X1 -> ISO txfr. IN, 2 tr/mf
case 0x95:
case 0x97: next_dpid.write(0);
break;
 
// 11_01_01_00 -> ISO txfr. IN, 3 tr/mf
case 0xd4: next_dpid.write(1);
break;
 
// 11_01_01_01 -> ISO txfr. IN, 3 tr/mf
case 0xd5: next_dpid.write(2);
break;
 
// 11_01_01_10 -> ISO txfr. IN, 3 tr/mf
case 0xd6: next_dpid.write(0);
break;
 
// 0X_10_01_XX -> ISO txfr. OUT, 1 tr/mf
case 0x24:
case 0x25:
case 0x26:
case 0x27:
case 0x64:
case 0x65:
case 0x66:
case 0x67: next_dpid.write(0);
break;
 
// 10_10_01_XX -> ISO txfr. OUT, 2 tr/mf
case 0xa4:
case 0xa5:
case 0xa6: // Resynchronize in case of PID error
case 0xa7: switch (sel_d1) {// synopsys full_case parallel_case
case 2: next_dpid.write(1); break;
case 1: next_dpid.write(0); break;
}
break;
 
// 11_10_01_00 -> ISO txfr. OUT, 3 tr/mf
case 0xe4: // Resynchronize in case of PID error
switch (sel_d2) {// synopsys full_case parallel_case
case 2: next_dpid.write(1); break;
case 1: next_dpid.write(0); break;
}
break;
 
// 11_10_01_01 -> ISO txfr. OUT, 3 tr/mf
case 0xe5: // Resynchronize in case of PID error
switch (sel_d2) {// synopsys full_case parallel_case
case 2: next_dpid.write(2); break;
case 1: next_dpid.write(0); break;
}
break;
 
// 11_10_01_10 -> ISO txfr. OUT, 3 tr/mf
case 0xe6: // Resynchronize in case of PID error
switch (sel_d2) {// synopsys full_case parallel_case
case 2: next_dpid.write(1); break;
case 1: next_dpid.write(0); break;
}
break;
 
// XX_01_00_X0 or XX_10_00_X0 -> IN/OUT endpoint only
case 0x10:
case 0x12:
case 0x50:
case 0x52:
case 0x90:
case 0x92:
case 0xd0:
case 0xd2:
case 0x20:
case 0x22:
case 0x60:
case 0x62:
case 0xa0:
case 0xa2:
case 0xe0:
case 0xe2: next_dpid.write(1); // INT transfers
break;
 
// XX_01_00_X1 or XX_10_00_X1 -> IN/OUT endpoint only
case 0x11:
case 0x13:
case 0x51:
case 0x53:
case 0x91:
case 0x93:
case 0xd1:
case 0xd3:
case 0x21:
case 0x23:
case 0x61:
case 0x63:
case 0xa1:
case 0xa3:
case 0xe1:
case 0xe3: next_dpid.write(0); // INT transfers
break;
 
// XX_01_10_X0 or XX_10_10_X0 -> IN/OUT endpoint only
case 0x18:
case 0x1a:
case 0x58:
case 0x5a:
case 0x98:
case 0x9a:
case 0xd8:
case 0xda:
case 0x28:
case 0x2a:
case 0x68:
case 0x6a:
case 0xa8:
case 0xaa:
case 0xe8:
case 0xea: next_dpid.write(1); // BULK transfers
break;
 
// XX_01_10_X1 or XX_10_10_X1 -> IN/OUT endpoint only
case 0x19:
case 0x1b:
case 0x59:
case 0x5b:
case 0x99:
case 0x9b:
case 0xd9:
case 0xdb:
case 0x29:
case 0x2b:
case 0x69:
case 0x6b:
case 0xa9:
case 0xab:
case 0xe9:
case 0xeb: next_dpid.write(0); // BULK transfers
break;
 
// XX_00_XX_XX -> CTRL Endpoint
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
switch (sel2) {// synopsys full_case parallel_case
 
// 1_XX_XX -> SETUP operation
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f: next_dpid.write(3);
break;
 
// 0_10_0X -> IN operation
case 0x08:
case 0x09: next_dpid.write(3);
break;
 
// 0_10_1X -> IN operation
case 0x0a:
case 0x0b: next_dpid.write(1);
break;
 
// 0_01_X0 -> OUT operation
case 0x04:
case 0x06: next_dpid.write(3);
break;
 
// 0_01_X1 -> OUT operation
case 0x05:
case 0x07: next_dpid.write(2);
break;
}
break;
}
}
 
// Current PID decoder
// Allow any PID for ISO transfers when mode full speed or tr_fr is zero
void usb_pe_sie::allow_pid_up(void) {
sc_uint<4> sel;
 
sel = ((sc_uint<1>)pid_DATA0.read(), (sc_uint<1>)pid_DATA1.read(), (sc_uint<1>)pid_DATA2.read(), (sc_uint<1>)pid_MDATA.read());
 
switch (sel) {// synopsys full_case parallel_case
// 1000
case 8: allow_pid.write(0); break;
// 0100
case 4: allow_pid.write(1); break;
// 0010
case 2: allow_pid.write(2); break;
// 0001
case 1: allow_pid.write(3); break;
}
}
 
void usb_pe_sie::this_dpid_up(void) {
sc_uint<8> sel1;
sc_uint<5> sel2;
 
// tr/mf:ep/type:tr/type:last dpd
sel1 = ((sc_uint<2>)tr_fr_d.read(), (sc_uint<2>)ep_type.read(), (sc_uint<2>)txfr_type.read(), (sc_uint<2>)uc_dpd.read());
 
// CTRL Endpoint Selector
sel2 = ((sc_uint<1>)setup_token.read(), (sc_uint<1>)in_op.read(), (sc_uint<1>)out_op.read(), (sc_uint<2>)uc_dpd.read());
 
switch (sel1) {// synopsys full_case parallel_case
 
// 0X_01_01_XX -> ISO txfr. IN, 1 tr/mf
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x54:
case 0x55:
case 0x56:
case 0x57: this_dpid.write(0);
break;
 
// 10_01_01_X0 -> ISO txfr. IN, 2 tr/mf
case 0x94:
case 0x96: this_dpid.write(1);
break;
 
// 10_01_01_X1 -> ISO txfr. IN, 2 tr/mf
case 0x95:
case 0x97: this_dpid.write(0);
break;
 
// 11_01_01_00 -> ISO txfr. IN, 3 tr/mf
case 0xd4: this_dpid.write(2);
break;
 
// 11_01_01_01 -> ISO txfr. IN, 3 tr/mf
case 0xd5: this_dpid.write(1);
break;
 
// 11_01_01_10 -> ISO txfr. IN, 3 tr/mf
case 0xd6: this_dpid.write(0);
break;
 
// 00_10_01_XX -> ISO txfr. OUT, 0 tr/mf
case 0x24:
case 0x25:
case 0x26:
case 0x27: this_dpid.write(allow_pid.read());
break;
 
// 01_10_01_XX -> ISO txfr. OUT, 1 tr/mf
case 0x64:
case 0x65:
case 0x66:
case 0x67: this_dpid.write(0);
break;
 
// 10_10_01_X0 -> ISO txfr. OUT, 2 tr/mf
case 0xa4:
case 0xa6: this_dpid.write(3);
break;
 
// 10_10_01_X1 -> ISO txfr. OUT, 2 tr/mf
case 0xa5:
case 0xa7: this_dpid.write(1);
break;
 
// 11_10_01_00 -> ISO txfr. OUT, 3 tr/mf
case 0xe4: this_dpid.write(3);
break;
 
// 11_10_01_01 -> ISO txfr. OUT, 3 tr/mf
case 0xe5: this_dpid.write(3);
break;
 
// 11_10_01_10 -> ISO txfr. OUT, 3 tr/mf
case 0xe6: this_dpid.write(2);
break;
 
// XX_01_00_X0 or XX_10_00_X0 -> IN/OUT endpoint only
case 0x10:
case 0x12:
case 0x50:
case 0x52:
case 0x90:
case 0x92:
case 0xd0:
case 0xd2:
case 0x20:
case 0x22:
case 0x60:
case 0x62:
case 0xa0:
case 0xa2:
case 0xe0:
case 0xe2: this_dpid.write(0); // INT transfers
break;
 
// XX_01_00_X1 or XX_10_00_X1 -> IN/OUT endpoint only
case 0x11:
case 0x13:
case 0x51:
case 0x53:
case 0x91:
case 0x93:
case 0xd1:
case 0xd3:
case 0x21:
case 0x23:
case 0x61:
case 0x63:
case 0xa1:
case 0xa3:
case 0xe1:
case 0xe3: this_dpid.write(1); // INT transfers
break;
 
// XX_01_10_X0 or XX_10_10_X0 -> IN/OUT endpoint only
case 0x18:
case 0x1a:
case 0x58:
case 0x5a:
case 0x98:
case 0x9a:
case 0xd8:
case 0xda:
case 0x28:
case 0x2a:
case 0x68:
case 0x6a:
case 0xa8:
case 0xaa:
case 0xe8:
case 0xea: this_dpid.write(0); // BULK transfers
break;
 
// XX_01_10_X1 or XX_10_10_X1 -> IN/OUT endpoint only
case 0x19:
case 0x1b:
case 0x59:
case 0x5b:
case 0x99:
case 0x9b:
case 0xd9:
case 0xdb:
case 0x29:
case 0x2b:
case 0x69:
case 0x6b:
case 0xa9:
case 0xab:
case 0xe9:
case 0xeb: this_dpid.write(1); // BULK transfers
break;
 
// XX_00_XX_XX -> CTRL Endpoint
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf:
switch (sel2) {// synopsys full_case parallel_case
 
// 1_XX_XX -> SETUP operation
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x18:
case 0x19:
case 0x1a:
case 0x1b:
case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f: this_dpid.write(0);
break;
 
// 0_10_0X -> IN operation
case 0x08:
case 0x09: this_dpid.write(0);
break;
 
// 0_10_1X -> IN operation
case 0x0a:
case 0x0b: this_dpid.write(1);
break;
 
// 0_01_X0 -> OUT operation
case 0x04:
case 0x06: this_dpid.write(0);
break;
 
// 0_01_X1 -> OUT operation
case 0x05:
case 0x07: this_dpid.write(1);
break;
}
break;
}
}
 
// Assign PID for outgoing packets
void usb_pe_sie::data_pid_sel_up(void) {
data_pid_sel.write(this_dpid.read());
}
 
// Verify PID for incoming data packets
void usb_pe_sie::pid_seq_err_up(void) {
pid_seq_err.write(!(((this_dpid.read() == 0) && pid_DATA0.read()) ||
((this_dpid.read() == 1) && pid_DATA1.read()) ||
((this_dpid.read() == 2) && pid_DATA2.read()) ||
((this_dpid.read() == 3) && pid_MDATA.read())));
}
 
// IDMA Setup and SRC/DEST Buffer Select
// For Control Endpoint things are different:
// buffer0 is used for OUT (incoming) data packets
// buffer1 is used for IN (outgoing) data packets
 
// Keep track of last token for control endpoints
void usb_pe_sie::in_token_up(void) {
if (!rst.read())
in_token.write(false);
else if (pid_IN.read())
in_token.write(true);
else if (pid_OUT.read() || pid_SETUP.read())
in_token.write(false);
}
 
void usb_pe_sie::out_token_up(void) {
if (!rst.read())
out_token.write(false);
else if (pid_OUT.read() || pid_SETUP.read())
out_token.write(true);
else if (pid_IN.read())
out_token.write(false);
}
 
void usb_pe_sie::setup_token_up(void) {
if (!rst.read())
setup_token.write(false);
else if (pid_SETUP.read())
setup_token.write(true);
else if (pid_OUT.read() || pid_IN.read())
setup_token.write(false);
}
 
// Indicates if we are performing an IN operation
void usb_pe_sie::in_op_up(void) {
in_op.write(IN_ep.read() || (CTRL_ep.read() && in_token.read()));
}
 
// Indicates if we are performing an OUT operation
void usb_pe_sie::out_op_up(void) {
out_op.write(OUT_ep.read() || (CTRL_ep.read() && out_token.read()));
}
 
// Determine if packet is to small or to large
// This is used to NACK and ignore packet for OUT endpoints
 
// Register File Update Logic
 
void usb_pe_sie::uc_dpd_set_up(void) {
uc_dpd_set.write(uc_stat_set_d.read());
}
 
// Abort signal
void usb_pe_sie::abort_up(void) {
abort.write(match.read() && fsel.read() && (state.read() != PE_IDLE));
}
 
// Time Out Timers
 
// After sending data in response to an IN token from host, the
// host must reply with an ack. The host has 622nS in Full Speed
// mode and 400nS in High Speed mode to reply.
// "rx_ack_to" indicates when this time has expired and
// rx_ack_to_clr clears the timer
void usb_pe_sie::rx_ack_up1(void) {
rx_ack_to_clr.write(tx_valid.read() || rx_ack_to_clr_d.read());
}
 
void usb_pe_sie::rx_ack_up2(void) {
if (rx_ack_to_clr.read())
rx_ack_to_cnt.write(0);
else
rx_ack_to_cnt.write(rx_ack_to_cnt.read() + 1);
}
 
void usb_pe_sie::rx_ack_up3(void) {
rx_ack_to.write(rx_ack_to_cnt.read() == rx_ack_to_val.read());
}
 
// After sending a OUT token the host must send a data packet.
// The host has 622nS in Full Speed mode and 400nS in High Speed
// mode to send the data packet.
// "tx_data_to" indicates when this time has expired and
// "tx_data_to_clr" clears the timer
void usb_pe_sie::tx_data_up1(void) {
tx_data_to_clr.write(rx_active.read());
}
 
void usb_pe_sie::tx_data_up2(void) {
if (tx_data_to_clr.read())
tx_data_to_cnt.write(0);
else
tx_data_to_cnt.write(tx_data_to_cnt.read() + 1);
}
 
void usb_pe_sie::tx_data_up3(void) {
tx_data_to.write(tx_data_to_cnt.read() == tx_data_to_val.read());
}
 
// Interrupts
void usb_pe_sie::pid_OUT_up(void) {
pid_OUT_r.write(pid_OUT.read());
}
 
void usb_pe_sie::pid_IN_up(void) {
pid_IN_r.write(pid_IN.read());
}
 
void usb_pe_sie::pid_PING_up(void) {
pid_PING_r.write(pid_PING.read());
}
 
void usb_pe_sie::pid_SETUP_up(void) {
pid_SETUP_r.write(pid_SETUP.read());
}
 
void usb_pe_sie::int_upid_up(void) {
int_upid_set.write(match_r.read() && !pid_SOF.read() &&
((OUT_ep.read() && !(pid_OUT_r.read() || pid_PING_r.read())) ||
(IN_ep.read() && !pid_IN_r.read()) ||
(CTRL_ep.read() && !(pid_IN_r.read() || pid_OUT_r.read() || pid_PING_r.read() || pid_SETUP_r.read()))));
}
 
void usb_pe_sie::int_to_up(void) {
int_to_set.write(((state.read() == PE_IN2) && rx_ack_to.read()) ||
((state.read() == PE_OUT) && tx_data_to.read()));
}
 
void usb_pe_sie::int_crc16_up(void) {
int_crc16_set.write(rx_data_done.read() && crc16_err.read());
}
 
void usb_pe_sie::int_seqerr_up(void) {
int_seqerr_set.write(int_seqerr_set_d.read());
}
 
void usb_pe_sie::send_stall_up(void) {
if (!rst.read())
send_stall_r.write(false);
else if (send_stall.read())
send_stall_r.write(true);
else if (send_token.read())
send_stall_r.write(false);
}
 
void usb_pe_sie::state_up(void) {
if (!rst.read())
state.write(PE_IDLE);
else if (match.read())
state.write(PE_IDLE);
else
state.write(next_state.read());
}
 
void usb_pe_sie::pe_statemachine(void) {
next_state.write(state.read());
token_pid_sel_d.write(PE_ACK);
send_token_d.write(false);
rx_dma_en.write(false);
tx_dma_en.write(false);
uc_stat_set_d.write(false);
rx_ack_to_clr_d.write(true);
int_seqerr_set_d.write(false);
 
switch (state.read()) {// synopsys full_case parallel_case
case PE_IDLE:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state IDLE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (match_r.read() && !pid_SOF.read()) {
if (send_stall.read()) { // Halt Forced send STALL
token_pid_sel_d.write(PE_STALL);
send_token_d.write(true);
next_state.write(PE_TOKEN);
} else if (IN_ep.read() || (CTRL_ep.read() && pid_IN.read())) {
if (txfr_int.read() && ep_empty.read()) {
token_pid_sel_d.write(PE_NACK);
send_token_d.write(true);
next_state.write(PE_TOKEN);
} else {
tx_dma_en.write(true);
next_state.write(PE_IN);
}
} else if (OUT_ep.read() || (CTRL_ep.read() && (pid_OUT.read() || pid_SETUP.read()))) {
rx_dma_en.write(true);
next_state.write(PE_OUT);
}
}
break;
 
case PE_TOKEN:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state TOKEN (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
next_state.write(PE_IDLE);
break;
 
case PE_IN:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state IN (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
rx_ack_to_clr_d.write(false);
if (idma_done.read())
if (txfr_iso.read())
next_state.write(PE_UPDATE);
else
next_state.write(PE_IN2);
break;
 
case PE_IN2:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state IN2 (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
rx_ack_to_clr_d.write(false);
// Wait for ACK from host or time out
if (rx_ack_to.read())
next_state.write(PE_IDLE);
else if (token_valid.read() && pid_ACK.read())
next_state.write(PE_UPDATE);
break;
 
case PE_OUT:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state OUT (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (tx_data_to.read() || crc16_err.read() || abort.read())
next_state.write(PE_IDLE);
else if (rx_data_done.read()) { // Send ACK
if (txfr_iso.read()) {
if (pid_seq_err.read())
int_seqerr_set_d.write(true);
next_state.write(PE_UPDATEW);
} else {
next_state.write(PE_OUT2A);
}
}
break;
 
case PE_OUT2B: // This is a delay state to NACK to small or
// to large packets. This state could be skipped
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state OUT2B (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (abort.read())
next_state.write(PE_IDLE);
else
next_state.write(PE_OUT2B);
break;
 
case PE_OUT2A: // Send ACK/NACK/NYET
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state OUT2A (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
if (abort.read())
next_state.write(PE_IDLE);
else if (send_stall_r.read()) {
token_pid_sel_d.write(PE_STALL);
send_token_d.write(true);
next_state.write(PE_IDLE);
} else if (ep_full.read()) {
token_pid_sel_d.write(PE_NACK);
send_token_d.write(true);
next_state.write(PE_IDLE);
} else {
token_pid_sel_d.write(PE_ACK);
send_token_d.write(true);
if (pid_seq_err.read())
next_state.write(PE_IDLE);
else
next_state.write(PE_UPDATE);
}
break;
 
case PE_UPDATEW:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state UPDATEW (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
next_state.write(PE_UPDATE);
break;
 
case PE_UPDATE:
 
///////////////////////////////////////////////////////////////////////
//
// DEBUG INFORMATIONS
//
///////////////////////////////////////////////////////////////////////
 
#ifdef USBF_VERBOSE_DEBUG
cout << "SIE -> PE: Entered state UPDATE (" << sc_simulation_time() << ")" << endl;
#endif
 
///////////////////////////////////////////////////////////////////////
 
uc_stat_set_d.write(true);
next_state.write(PE_IDLE);
break;
}
}
 
/trunk/rtl/systemc/usb_fifo2.cpp
0,0 → 1,67
/////////////////////////////////////////////////////////////////////
//// ////
//// USB Fast FIFO - 2 Entries Deep ////
//// ////
//// SystemC Version: usb_fifo2.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_fifo2.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 "systemc.h"
#include "usb_fifo2.h"
 
void usb_fifo2::wp_update(void) {
if (!rst.read())
wp.write(false);
else if (clr.read())
wp.write(false);
else if (we.read())
wp.write(!wp.read());
}
 
void usb_fifo2::rp_update(void) {
if (!rst.read())
rp.write(false);
else if (clr.read())
rp.write(false);
else if (re.read())
rp.write(!rp.read());
}
 
void usb_fifo2::write(void) {
if (we.read())
mem[wp.read()] = din.read();
}
 
void usb_fifo2::read(void) {
dout.write(mem[rp.read()]);
}
 
/trunk/rtl/systemc/usb_top.h
0,0 → 1,179
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 Top Module ////
//// Function Interface ////
//// ////
//// SystemC Version: usb_top.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_8051_if.v ////
//// Copyright (C) 2003 Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_TOP_H
#define USB_TOP_H
 
#include "usb.h"
 
SC_MODULE(usb_top) {
 
private:
 
sc_signal<bool> vcc;
 
public:
 
sc_in<bool> clk_i;
sc_in<bool> rst_i;
 
// PHY Interface
sc_out<bool> tx_dp, tx_dn, tx_oe;
sc_in<bool> rx_dp, rx_dn, rx_d;
 
// Misc
sc_out<bool> usb_rst;
 
// Interrupts
sc_out<bool> crc16_err;
 
// Vendor Features
sc_out<bool> v_set_int;
sc_out<bool> v_set_feature;
 
// USB Status
sc_out<bool> usb_busy;
sc_out<sc_uint<4> > ep_sel;
 
// Function Interface
sc_in<sc_uint<8> > adr;
sc_in<sc_uint<8> > din;
sc_out_rv<8> dout;
sc_in<bool> cs;
sc_in<bool> re, we;
sc_out<bool> empty, full;
 
// Local Signals
 
// Vendor Signals
sc_signal<sc_uint<16> > wValue;
sc_signal<sc_uint<16> > wIndex;
sc_signal<sc_uint<16> > vendor_data;
 
// Endpoint Interface
// EP1
sc_signal<sc_uint<8> > ep1_f_din;
sc_signal<bool> ep1_f_we;
sc_signal<bool> ep1_f_full;
 
// EP2
sc_signal<sc_uint<8> > ep2_f_dout;
sc_signal<bool> ep2_f_re;
sc_signal<bool> ep2_f_empty;
 
// EP3
sc_signal<sc_uint<8> > ep3_f_din;
sc_signal<bool> ep3_f_we;
sc_signal<bool> ep3_f_full;
 
// EP4
sc_signal<sc_uint<8> > ep4_f_dout;
sc_signal<bool> ep4_f_re;
sc_signal<bool> ep4_f_empty;
 
// EP5
sc_signal<sc_uint<8> > ep5_f_din;
sc_signal<bool> ep5_f_we;
sc_signal<bool> ep5_f_full;
 
// EP6
sc_signal<sc_uint<8> > ep6_f_dout;
sc_signal<bool> ep6_f_re;
sc_signal<bool> ep6_f_empty;
 
usb *i_usb; // USB
 
// Mux Function
void mux(void);
 
// Destructor
// ~usb_top(void);
 
SC_CTOR(usb_top) {
vcc.write(true);
 
SC_METHOD(mux);
sensitive << adr << cs << din << re << we;
sensitive << ep1_f_full << ep2_f_dout << ep2_f_empty;
sensitive << ep3_f_full << ep4_f_dout << ep4_f_empty;
sensitive << ep5_f_full << ep6_f_dout << ep6_f_empty;
sensitive << wValue << wIndex;
 
// USB Instantiation and Binding
i_usb = new usb("USB");
i_usb->clk_i(clk_i);
i_usb->rst_i(rst_i);
i_usb->tx_dp(tx_dp);
i_usb->tx_dn(tx_dn);
i_usb->tx_oe(tx_oe);
i_usb->rx_dp(rx_dp);
i_usb->rx_dn(rx_dn);
i_usb->rx_d(rx_d);
i_usb->phy_tx_mode(vcc);
i_usb->usb_rst(usb_rst);
i_usb->crc16_err(crc16_err);
i_usb->v_set_int(v_set_int);
i_usb->v_set_feature(v_set_feature);
i_usb->wValue(wValue);
i_usb->wIndex(wIndex);
i_usb->vendor_data(vendor_data);
i_usb->usb_busy(usb_busy);
i_usb->ep_sel(ep_sel);
i_usb->ep1_f_din(ep1_f_din);
i_usb->ep1_f_we(ep1_f_we);
i_usb->ep1_f_full(ep1_f_full);
i_usb->ep2_f_dout(ep2_f_dout);
i_usb->ep2_f_re(ep2_f_re);
i_usb->ep2_f_empty(ep2_f_empty);
i_usb->ep3_f_din(ep3_f_din);
i_usb->ep3_f_we(ep3_f_we);
i_usb->ep3_f_full(ep3_f_full);
i_usb->ep4_f_dout(ep4_f_dout);
i_usb->ep4_f_re(ep4_f_re);
i_usb->ep4_f_empty(ep4_f_empty);
i_usb->ep5_f_din(ep5_f_din);
i_usb->ep5_f_we(ep5_f_we);
i_usb->ep5_f_full(ep5_f_full);
i_usb->ep6_f_dout(ep6_f_dout);
i_usb->ep6_f_re(ep6_f_re);
i_usb->ep6_f_empty(ep6_f_empty);
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_rx_phy.cpp
0,0 → 1,301
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RX PHY ////
//// ////
//// SystemC Version: usb_rx_phy.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_rx_phy.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 "systemc.h"
#include "usb_rx_phy.h"
 
#ifdef USB_SIMULATION
void usb_rx_phy::rx_error_init(void) {
RxError_o.write(false);
}
#endif
 
void usb_rx_phy::misc_logic_up(void) {
rx_en.write(RxEn_i.read());
}
 
void usb_rx_phy::misc_logic_RxActive_up(void) {
RxActive_o.write(rx_active.read());
}
 
void usb_rx_phy::misc_logic_RxValid_up(void) {
RxValid_o.write(rx_valid.read());
}
 
void usb_rx_phy::misc_logic_DataIn_up(void) {
DataIn_o.write(hold_reg.read());
}
 
void usb_rx_phy::misc_logic_LineState_up(void) {
LineState.write(((sc_uint<1>)rxdp_s1.read(), (sc_uint<1>)rxdn_s1.read()));
}
 
// First synchronize to the local system clock to
// avoid metastability outside the sync block (*_s1)
// Second synchronise to the internal bit clock (*_s)
void usb_rx_phy::si_up1(void) {
rxd_t1.write(rxd.read());
rxdp_t1.write(rxdp.read());
rxdn_t1.write(rxdn.read());
}
 
void usb_rx_phy::si_up2(void) {
rxd_s1.write(rxd_t1.read());
rxdp_s1.write(rxdp_t1.read());
rxdn_s1.write(rxdn_t1.read());
}
 
void usb_rx_phy::si_up3(void) {
rxd_s.write(rxd_s1.read());
rxdp_s.write(rxdp_s1.read());
rxdn_s.write(rxdn_s1.read());
}
 
void usb_rx_phy::si_up4(void) {
k.write(!rxdp_s.read() && rxdn_s.read());
j.write(rxdp_s.read() && !rxdn_s.read());
se0.write(!rxdp_s.read() && !rxdn_s.read());
}
 
// This design uses a clock enable to do 12Mhz timing and not a
// real 12Mhz clock. Everything always runs at 48Mhz. We want to
// make sure however, that the clock enable is always exactly in
// the middle between two virtual 12Mhz rising edges.
// We monitor rxdp and rxdn for any changes and do the appropiate
// adjustments.
// In addition to the locking done in the dpll FSM, we adjust the
// final latch enable to compensate for various sync registers ...
 
// Allow lockinf only when we are receiving
void usb_rx_phy::dpll_up1(void) {
lock_en.write(rx_en.read());
}
 
// Edge detector
void usb_rx_phy::dpll_up2(void) {
rxdp_s1r.write(rxdp_s1.read());
rxdn_s1r.write(rxdn_s1.read());
}
 
void usb_rx_phy::dpll_up3(void) {
change.write((rxdp_s1r.read() != rxdp_s1.read()) || (rxdn_s1r.read() != rxdn_s1.read()));
}
 
// DPLL FSM
void usb_rx_phy::dpll_up4(void) {
if (!rst.read())
dpll_state.write(1);
else
dpll_state.write(dpll_next_state.read());
}
 
// Compensate for sync registers at the input - allign full speed
// clock enable to be in the middle between two bit changes ...
void usb_rx_phy::dpll_up5(void) {
fs_ce_r1.write(fs_ce_d.read());
}
 
void usb_rx_phy::dpll_up6(void) {
fs_ce_r2.write(fs_ce_r1.read());
}
 
void usb_rx_phy::dpll_up7(void) {
fs_ce_r3.write(fs_ce_r2.read());
}
 
void usb_rx_phy::dpll_up8(void) {
fs_ce.write(fs_ce_r3.read());
}
 
void usb_rx_phy::dpll_statemachine(void) {
fs_ce_d.write(false);
switch (dpll_state.read()) {// synopsys full_case parallel_case
case 0: if (lock_en.read() && change.read())
dpll_next_state.write(0);
else
dpll_next_state.write(1);
break;
case 1: fs_ce_d.write(true);
if (lock_en.read() && change.read())
//dpll_next_state.write(0);
dpll_next_state.write(3);
else
dpll_next_state.write(2);
break;
case 2: if (lock_en.read() && change.read())
dpll_next_state = 0;
else
dpll_next_state = 3;
break;
case 3: //if (lock_en.read() && change.read())
dpll_next_state.write(0);
//else
//dpll_next_state.write(0);
break;
}
}
 
void usb_rx_phy::fsp_up(void) {
if(!rst.read())
fs_state.write(FS_IDLE);
else
fs_state.write(fs_next_state.read());
}
 
void usb_rx_phy::fsp_statemachine(void) {
synced_d.write(false);
fs_next_state.write(fs_state.read());
if (fs_ce.read())
switch (fs_state.read()) {// synopsys full_case parallel_case
case FS_IDLE: if (k.read() && rx_en.read())
fs_next_state.write(K1);
break;
case K1: if (j.read() && rx_en.read())
fs_next_state.write(J1);
else
fs_next_state.write(FS_IDLE);
break;
case J1: if (k.read() && rx_en.read())
fs_next_state.write(K2);
else
fs_next_state.write(FS_IDLE);
break;
case K2: if (j.read() && rx_en.read())
fs_next_state.write(J2);
else
fs_next_state.write(FS_IDLE);
break;
case J2: if (k.read() && rx_en.read())
fs_next_state.write(K3);
else
fs_next_state.write(FS_IDLE);
break;
case K3: if (j.read() && rx_en.read())
fs_next_state.write(J3);
else if (k.read() && rx_en.read())
fs_next_state.write(K4); // Allow missing one J
else
fs_next_state.write(FS_IDLE);
break;
case J3: if (k.read() && rx_en.read())
fs_next_state.write(K4);
else
fs_next_state.write(FS_IDLE);
break;
case K4: if (k.read())
synced_d.write(true);
fs_next_state.write(FS_IDLE);
break;
}
}
 
void usb_rx_phy::gra_up1(void) {
if (!rst.read())
rx_active.write(false);
else if (synced_d.read() && rx_en.read())
rx_active.write(true);
else if (se0.read() && rx_valid_r.read())
rx_active.write(false);
}
 
void usb_rx_phy::gra_up2(void) {
if (rx_valid.read())
rx_valid_r.write(true);
else if (fs_ce.read())
rx_valid_r.write(false);
}
 
void usb_rx_phy::nrzi_up1(void) {
if (fs_ce.read())
sd_r.write(rxd_s.read());
}
 
void usb_rx_phy::nrzi_up2(void) {
if (!rst.read())
sd_nrzi.write(false);
else if (rx_active.read() && fs_ce.read())
sd_nrzi.write(!(rxd_s.read() ^ sd_r.read()));
}
 
void usb_rx_phy::bsd_up1(void) {
if (!rst.read())
one_cnt.write(0);
else if (!shift_en.read())
one_cnt.write(0);
else if (fs_ce.read())
if (!sd_nrzi.read() || drop_bit.read())
one_cnt.write(0);
else
one_cnt.write(one_cnt.read() + 1);
}
 
void usb_rx_phy::bsd_up2(void) {
drop_bit.write((one_cnt.read() == 6));
}
 
void usb_rx_phy::spc_up1(void) {
if (fs_ce.read())
shift_en.write(synced_d.read() || rx_active.read());
}
 
void usb_rx_phy::spc_up2(void) {
if (fs_ce.read() && shift_en.read() && !drop_bit.read())
hold_reg.write(((sc_uint<1>)sd_nrzi.read(), hold_reg.read().range(7, 1)));
}
 
void usb_rx_phy::grv_up1(void) {
if (!rst.read())
bit_cnt.write(0);
else if (!shift_en.read())
bit_cnt.write(0);
else if (fs_ce.read() && !drop_bit.read())
bit_cnt.write(bit_cnt.read() + 1);
}
 
void usb_rx_phy::grv_up2(void) {
if (!rst.read())
rx_valid1.write(false);
else if (fs_ce.read() && !drop_bit.read() && (bit_cnt.read() == 7))
rx_valid1.write(true);
else if (rx_valid1.read() && fs_ce.read() && !drop_bit.read())
rx_valid1.write(false);
}
 
void usb_rx_phy::grv_up3(void) {
rx_valid.write(!drop_bit.read() && rx_valid1.read() && fs_ce.read());
}
 
/trunk/rtl/systemc/usb_tx_phy.cpp
0,0 → 1,274
/////////////////////////////////////////////////////////////////////
//// ////
//// USB TX PHY ////
//// ////
//// SystemC Version: usb_tx_phy.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_tx_phy.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 "systemc.h"
#include "usb_tx_phy.h"
 
void usb_tx_phy::misc_logic_up1(void) {
tx_ready.write(tx_ready_d.read());
ld_data.write(ld_data_d.read());
}
 
void usb_tx_phy::misc_logic_up2(void) {
if (!rst.read())
TxReady_o.write(false);
else
TxReady_o.write(tx_ready_d.read() && TxValid_i.read());
}
 
void usb_tx_phy::tpi_up1(void) {
if (!rst.read())
tx_ip.write(false);
else if (ld_sop_d.read())
tx_ip.write(true);
else if (eop_done.read())
tx_ip.write(false);
}
 
void usb_tx_phy::tpi_up2(void) {
if (!rst.read())
tx_ip_sync.write(false);
else if (fs_ce.read())
tx_ip_sync.write(tx_ip.read());
}
 
// data_done helps us to catch cases where TxValid drops due to
// packet end and then gets re-asserted as a new packet starts.
// We might not see this because we are still transmitting.
// data_done should solve those cases ...
void usb_tx_phy::tpi_up3(void) {
if (!rst.read())
data_done.write(false);
else if (TxValid_i.read() && !tx_ip.read())
data_done.write(true);
else if (!TxValid_i.read())
data_done.write(false);
}
 
void usb_tx_phy::sr_up1(void) {
if (!rst.read())
bit_cnt.write(0);
else if (!tx_ip_sync.read())
bit_cnt.write(0);
else if (fs_ce.read() && !hold.read())
bit_cnt.write(bit_cnt.read() + 1);
}
 
void usb_tx_phy::sr_up2(void) {
if (!tx_ip_sync.read())
sd_raw_o.write(false);
else
switch (bit_cnt.read()) {// synopsys full_case parallel_case
case 0: sd_raw_o.write(hold_reg.read()[0]); break;
case 1: sd_raw_o.write(hold_reg.read()[1]); break;
case 2: sd_raw_o.write(hold_reg.read()[2]); break;
case 3: sd_raw_o.write(hold_reg.read()[3]); break;
case 4: sd_raw_o.write(hold_reg.read()[4]); break;
case 5: sd_raw_o.write(hold_reg.read()[5]); break;
case 6: sd_raw_o.write(hold_reg.read()[6]); break;
case 7: sd_raw_o.write(hold_reg.read()[7]); break;
}
}
 
void usb_tx_phy::sr_up3(void) {
sft_done.write(!hold.read() && (bit_cnt.read() == 7));
}
 
void usb_tx_phy::sr_up4(void) {
sft_done_r.write(sft_done.read());
}
 
// Out Data Hold Register
void usb_tx_phy::sr_up5(void) {
if (ld_sop_d.read())
hold_reg.write(0x80); // 0x80 -> Sync Pattern
else if (ld_data.read())
hold_reg.write(DataOut_i.read());
}
 
void usb_tx_phy::sr_hold_up(void) {
hold.write(stuff.read());
}
 
void usb_tx_phy::sr_sft_done_e_up(void) {
sft_done_e.write(sft_done.read() && !sft_done_r.read());
}
 
void usb_tx_phy::bs_up1(void) {
if (!rst.read())
one_cnt.write(0);
else if (!tx_ip_sync.read())
one_cnt.write(0);
else if (fs_ce.read())
if (!sd_raw_o.read() || stuff.read())
one_cnt.write(0);
else
one_cnt.write(one_cnt.read() + 1);
}
 
void usb_tx_phy::bs_up2(void) {
if (!rst.read())
sd_bs_o.write(false);
else if (fs_ce.read())
sd_bs_o.write((!tx_ip_sync.read()) ? false : ((stuff.read()) ? false : sd_raw_o.read()));
}
 
void usb_tx_phy::bs_stuff_up(void) {
stuff.write((one_cnt.read() == 6));
}
 
void usb_tx_phy::nrzi_up(void) {
if (!rst.read())
sd_nrzi_o.write(true);
else if (!tx_ip_sync.read() || !txoe_r1.read())
sd_nrzi_o.write(true);
else if (fs_ce.read())
sd_nrzi_o.write((sd_bs_o.read()) ? sd_nrzi_o.read() : !sd_nrzi_o.read());
}
 
void usb_tx_phy::eop_up1(void) {
if (!rst.read())
append_eop.write(false);
else if (ld_eop_d.read())
append_eop.write(true);
else if (append_eop_sync2.read())
append_eop.write(false);
}
 
void usb_tx_phy::eop_up2(void) {
if (!rst.read())
append_eop_sync1.write(false);
else if (fs_ce.read())
append_eop_sync1.write(append_eop.read());
}
 
void usb_tx_phy::eop_up3(void) {
if (!rst.read())
append_eop_sync2.write(false);
else if (fs_ce.read())
append_eop_sync2.write(append_eop_sync1.read());
}
 
void usb_tx_phy::eop_up4(void) {
if (!rst.read())
append_eop_sync3.write(false);
else if (fs_ce.read())
append_eop_sync3.write(append_eop_sync2.read());
}
 
void usb_tx_phy::eop_done_up(void) {
eop_done.write(append_eop_sync3.read());
}
 
void usb_tx_phy::oel_up1(void) {
if (!rst.read())
txoe_r1.write(false);
else if (fs_ce.read())
txoe_r1.write(tx_ip_sync.read());
}
 
void usb_tx_phy::oel_up2(void) {
if (!rst.read())
txoe_r2.write(false);
else if (fs_ce.read())
txoe_r2.write(txoe_r1.read());
}
 
void usb_tx_phy::oel_up3(void) {
if (!rst.read())
txoe.write(true);
else if (fs_ce.read())
txoe.write(!(txoe_r1.read() || txoe_r2.read()));
}
 
void usb_tx_phy::or_up(void) {
if (!rst.read()) {
txdp.write(true);
txdn.write(false);
} else if (fs_ce.read()) {
txdp.write((phy_mode.read()) ? (!append_eop_sync3.read() && sd_nrzi_o.read()) : sd_nrzi_o.read());
txdn.write((phy_mode.read()) ? (!append_eop_sync3.read() && !sd_nrzi_o.read()) : append_eop_sync3.read());
}
}
 
void usb_tx_phy::tx_statemachine(void) {
next_state.write(state.read());
tx_ready_d.write(false);
ld_sop_d.write(false);
ld_data_d.write(false);
ld_eop_d.write(false);
 
switch (state.read()) {// synopsys full_case parallel_case
case TX_IDLE: if (TxValid_i.read()) {
ld_sop_d.write(true);
next_state.write(TX_SOP);
}
break;
case TX_SOP: if (sft_done_e.read()) {
tx_ready_d.write(true);
ld_data_d.write(true);
next_state.write(TX_DATA);
}
break;
case TX_DATA: if (!data_done.read() && sft_done_e.read()) {
ld_eop_d.write(true);
next_state.write(TX_EOP1);
}
if (data_done.read() && sft_done_e.read()) {
tx_ready_d.write(true);
ld_data_d.write(true);
}
break;
case TX_EOP1: if (eop_done.read())
next_state.write(TX_EOP2);
break;
case TX_EOP2: if (!eop_done.read() && fs_ce.read())
next_state.write(TX_WAIT);
break;
case TX_WAIT: if (fs_ce.read())
next_state.write(TX_IDLE);
break;
}
}
 
void usb_tx_phy::tx_state_up(void) {
if (!rst.read())
state.write(TX_IDLE);
else
state.write(next_state.read());
}
 
/trunk/rtl/systemc/usb_fifo64x8.cpp
0,0 → 1,110
/////////////////////////////////////////////////////////////////////
//// ////
//// USB FIFO ////
//// ////
//// SystemC Version: usb_fifo64x8.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_fifo_sc_a.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 "systemc.h"
#include "usb_fifo64x8.h"
 
void usb_fifo64x8::write_pointer_update(void) {
if (!rst.read()) {
wp.write(0);
} else if (clr.read()) {
wp.write(0);
} else if (we.read()) {
wp.write(wp_pl1.read());
}
}
 
void usb_fifo64x8::read_pointer_update(void) {
if (!rst.read()) {
rp.write(0);
} else if (clr.read()) {
rp.write(0);
} else if (re.read()) {
rp.write(rp_pl1.read());
}
}
 
void usb_fifo64x8::future_pointers_update(void) {
wp_pl1.write(wp.read() + 1);
wp_pl2.write(wp.read() + 2);
rp_pl1.write(rp.read() + 1);
}
 
// Full & Empty Logic
// Guard Bit ...
void usb_fifo64x8::fe_gb_update(void) {
if (!rst.read())
gb.write(false);
else if (clr.read())
gb.write(false);
else if ((wp_pl2.read() == rp.read()) && we.read())
gb.write(true);
else if ((wp.read() != rp.read()) && re.read())
gb.write(false);
}
 
void usb_fifo64x8::fe_full_update(void) {
if (!rst.read())
full.write(false);
else if (clr.read())
full.write(false);
else if (we.read() && ((wp_pl1.read() == rp.read()) && gb.read()) && !re.read())
full.write(true);
else if (re.read() && ((wp_pl1.read() != rp.read()) || !gb.read()) && !we.read())
full.write(false);
}
 
void usb_fifo64x8::fe_empty_update(void) {
if (!rst.read())
empty.write(true);
else if (clr.read())
empty.write(true);
else if (we.read() && ((wp.read() != rp_pl1.read()) || gb.read()) && !re.read())
empty.write(false);
else if (re.read() && ((wp.read() == rp_pl1.read()) && !gb.read()) && !we.read())
empty.write(true);
}
 
void usb_fifo64x8::reset_update(void) {
n_rst.write(!rst.read());
}
/*
usb_fifo64x8::~usb_fifo64x8(void) {
if (i_ram)
delete i_ram;
}
*/
/trunk/rtl/systemc/usb_ram64x8.h
0,0 → 1,74
/////////////////////////////////////////////////////////////////////
//// ////
//// USB RAM ////
//// ////
//// SystemC Version: usb_ram64x8.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: generic_dpram.v ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// www.opencores.org ////
//// ////
//// 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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_RAM64X8_H
#define USB_RAM64X8_H
 
SC_MODULE(usb_ram64x8) {
 
public:
 
sc_in<bool> rclk, rrst, rce;
sc_in<bool> oe;
sc_in<sc_uint<6> > raddr;
sc_out<sc_uint<8> > dout;
 
sc_in<bool> wclk, wrst, wce;
sc_in<bool> we;
sc_in<sc_uint<6> > waddr;
sc_in<sc_uint<8> > din;
 
sc_signal<sc_uint<8> > dout_reg;
 
sc_uint<8> mem[64];
 
void dout_update(void);
void read(void);
void write(void);
 
SC_CTOR(usb_ram64x8) {
SC_METHOD(dout_update);
sensitive << oe << rce << dout_reg;
SC_METHOD(read);
sensitive << rclk.pos();
SC_METHOD(write);
sensitive << wclk.pos();
}
 
};
 
#endif
 
/trunk/rtl/systemc/usb_sie.cpp
0,0 → 1,170
/////////////////////////////////////////////////////////////////////
//// ////
//// USB SIE ////
//// ////
//// SystemC Version: usb_sie.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_utmi_if.v + usb1_pl.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 "systemc.h"
#include "usb_sie.h"
 
void usb_sie::tx_interface1(void) {
if (!rst.read())
TxValid_s.write(false);
else
TxValid_s.write(tx_valid.read() || tx_valid_last.read() ||
(TxValid_s.read() && !TxReady.read()));
}
 
void usb_sie::tx_interface2(void) {
tx_ready.write(TxReady.read());
 
if (TxReady.read() || tx_first.read())
DataOut.write(tx_data.read());
}
 
void usb_sie::tx_interface3(void) {
TxValid.write(TxValid_s.read());
}
 
void usb_sie::rx_interface1(void) {
if (!rst.read()) {
rx_valid.write(false);
rx_active.write(false);
rx_err.write(false);
} else {
rx_valid.write(RxValid.read());
rx_active.write(RxActive.read());
rx_err.write(RxError.read());
}
}
 
void usb_sie::rx_interface2(void) {
rx_data.write(DataIn.read());
}
 
void usb_sie::csr9_up(void) {
csr9.write(csr.read().range(8, 0));
}
 
void usb_sie::x_busy_up(void) {
x_busy.write(tx_busy.read() || rx_busy.read());
}
 
// PIDs we should never receive
void usb_sie::pid_bad_up(void) {
pid_bad.write(pid_ACK.read() || pid_NACK.read() ||
pid_STALL.read() || pid_NYET.read() ||
pid_PRE.read() || pid_ERR.read() ||
pid_SPLIT.read() || pid_PING.read());
}
 
void usb_sie::match_o_up(void) {
match_o.write(!pid_bad.read() && token_valid.read() && !crc5_err.read());
}
 
void usb_sie::rx_data_st_up(void) {
rx_data_st.write(rx_data_st_d.read());
}
 
void usb_sie::decoder_pk(void) {
ctrl_setup.write(token_valid.read() && pid_SETUP.read() && (ep_sel.read() == 0));
ctrl_in.write(token_valid.read() && pid_IN.read() && (ep_sel.read() == 0));
ctrl_out.write(token_valid.read() && pid_OUT.read() && (ep_sel.read() == 0));
}
 
// Frame Number (from SOF token)
void usb_sie::frame_no_up1(void) {
frame_no_we.write(token_valid.read() && !crc5_err.read() && pid_SOF.read());
}
 
void usb_sie::frame_no_up2(void) {
frame_no_we_r.write(frame_no_we.read());
}
 
void usb_sie::frame_no_up3(void) {
if (!rst.read())
frame_no_r.write(0);
else if (frame_no_we_r.read())
frame_no_r.write(frame_no.read());
}
 
void usb_sie::frm_nat_up1(void) {
clr_sof_time.write(frame_no_we.read());
}
 
void usb_sie::frm_nat_up2(void) {
if (clr_sof_time.read())
sof_time.write(0);
else if (hms_clk.read())
sof_time.write(sof_time.read() + 1);
}
 
void usb_sie::frm_nat_up3(void) {
frm_nat.write(((sc_uint<5>)0, (sc_uint<11>)frame_no_r.read(), (sc_uint<4>)0, (sc_uint<12>)sof_time.read()));
}
 
void usb_sie::hms_clk_up1(void) {
if (!rst.read())
hms_cnt.write(0);
else if (hms_clk.read() || frame_no_we_r.read())
hms_cnt.write(0);
else
hms_cnt.write(hms_cnt.read() + 1);
}
 
void usb_sie::hms_clk_up2(void) {
hms_clk.write((hms_cnt.read() == USBF_HMS_DEL));
}
 
// This function is addressed
void usb_sie::fsel_up(void) {
fsel.write((token_fadr.read() == fa.read()));
}
 
// Only write when we are addressed
void usb_sie::idma_we_up(void) {
idma_we.write(idma_we_d.read() && fsel.read()); // moved full check to idma... && !ep_full.read());
}
/*
usb_sie::~usb_sie(void) {
if (i_pa_sie)
delete i_pa_sie;
if (i_pd_sie)
delete i_pd_sie;
if (i_pe_sie)
delete i_pe_sie;
if (i_dma)
delete i_dma;
}
*/
/trunk/rtl/systemc/usb_ocp.cpp
0,0 → 1,147
/////////////////////////////////////////////////////////////////////
//// ////
//// USB 1.1 Top Module ////
//// Function Interface ////
//// OCP Interface ////
//// ////
//// SystemC Version: usb_ocp.cpp ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb_ocp_if.v ////
//// Copyright (C) 2004 Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// 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 "systemc.h"
#include "usb_ocp.h"
 
void usb_ocp::sflag_up(void) {
SFlag.write(( (sc_uint<1>)SF_feature.read(),
(sc_uint<4>)SF_sel.read(),
(sc_uint<1>)SF_busy.read(),
(sc_uint<1>)full.read(),
(sc_uint<1>)empty.read()));
}
 
void usb_ocp::sresp_up(void) {
if ((MCmd.read() == OCP_RD) && SCmdAccept.read())
SResp.write(OCP_DVA);
else if (MCmd.read() == OCP_RD)
SResp.write(OCP_ERR);
else
SResp.write(OCP_NULL);
}
 
void usb_ocp::mux(void) {
sc_uint<9> sel;
 
SData.write(0);
empty.write(false);
full.write(false);
ep1_f_we.write(false);
ep2_f_re.write(false);
ep3_f_we.write(false);
ep4_f_re.write(false);
ep5_f_we.write(false);
ep6_f_re.write(false);
SCmdAccept.write(false);
 
sel = ((sc_uint<1>)MCmd.read()[2], (sc_uint<8>)MAddr.read().range(7, 0));
 
switch (sel) {// synopsys full_case parallel_case
case 0: SData.write(0);
full.write(false);
empty.write(false);
SCmdAccept.write(false);
break;
case 1: ep1_f_din.write(MData.read());
ep1_f_we.write(MCmd.read() == OCP_WR);
full.write(ep1_f_full.read());
SCmdAccept.write(MCmd.read() == OCP_WR);
break;
case 2: SData.write(ep2_f_dout.read());
ep2_f_re.write(MCmd.read() == OCP_RD);
empty.write(ep2_f_empty.read());
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 3: ep3_f_din.write(MData.read());
ep3_f_we.write(MCmd.read() == OCP_WR);
full.write(ep3_f_full.read());
SCmdAccept.write(MCmd.read() == OCP_WR);
break;
case 4: SData.write(ep4_f_dout.read());
ep4_f_re.write(MCmd.read() == OCP_RD);
empty.write(ep4_f_empty.read());
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 5: ep5_f_din.write(MData.read());
ep5_f_we.write(MCmd.read() == OCP_WR);
full.write(ep5_f_full.read());
SCmdAccept.write(MCmd.read() == OCP_WR);
break;
case 6: SData.write(ep6_f_dout.read());
ep6_f_re.write(MCmd.read() == OCP_RD);
empty.write(ep6_f_empty.read());
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 8: SData.write(0);
full.write(false);
empty.write(false);
SCmdAccept.write(false);
break;
case 16:if (MCmd.read() == OCP_RD)
SData.write(wValue.read().range(7, 0));
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 17:if (MCmd.read() == OCP_RD)
SData.write(wValue.read().range(15, 8));
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 18:if (MCmd.read() == OCP_RD)
SData.write(wIndex.read().range(7, 0));
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 19:if (MCmd.read() == OCP_RD)
SData.write(wIndex.read().range(15, 8));
SCmdAccept.write(MCmd.read() == OCP_RD);
break;
case 20:if (MCmd.read() == OCP_WR)
vendor_data.write((vendor_data.read().range(15, 8), MData.read()));
SCmdAccept.write(MCmd.read() == OCP_WR);
break;
case 21:if (MCmd.read() == OCP_WR)
vendor_data.write((MData.read(), vendor_data.read().range(7, 0)));
SCmdAccept.write(MCmd.read() == OCP_WR);
break;
}
}
/*
usb_ocp::~usb_ocp(void) {
if (i_usb)
delete i_usb;
}
*/
/trunk/rtl/systemc/usb_defines.h
0,0 → 1,121
/////////////////////////////////////////////////////////////////////
//// ////
//// USB DEFINES ////
//// ////
//// SystemC Version: usb_defines.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_defines.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_DEFINES_H
#define USB_DEFINES_H
 
//#define USBF_VERBOSE_DEBUG
 
// Device Descriptor Length
#define ROM_SIZE0 18
// Configuration Descriptor Length
#define ROM_SIZE1 60
// Language ID Descriptor Start Length
#define ROM_SIZE2A 8
// String 1 Descriptor Length
#define ROM_SIZE2B 26
// String 2 Descriptor Length
#define ROM_SIZE2C 28
// String 3 Descriptor Length
#define ROM_SIZE2D 54
 
// Device Descriptor Start Address
#define ROM_START0 0x00
// Configuration Descriptor Start Address
#define ROM_START1 0x12
// Language ID Descriptor Start Address
#define ROM_START2A 0x4e
// String 1 Descriptor Start Address
#define ROM_START2B 0x56
// String 2 Descriptor Start Address
#define ROM_START2C 0x70
// String 3 Descriptor Start Address
#define ROM_START2D 0x8c
 
// Endpoint Configuration Constants
#define IN 0x0200
#define OUT 0x0400
#define CTRL 0x2800
#define ISO 0x1000
#define BULK 0x2000
#define INT 0x0000
 
// PID Encodings
#define USBF_T_PID_OUT 0x1
#define USBF_T_PID_IN 0x9
#define USBF_T_PID_SOF 0x5
#define USBF_T_PID_SETUP 0xd
#define USBF_T_PID_DATA0 0x3
#define USBF_T_PID_DATA1 0xb
#define USBF_T_PID_DATA2 0x7
#define USBF_T_PID_MDATA 0xf
#define USBF_T_PID_ACK 0x2
#define USBF_T_PID_NACK 0xa
#define USBF_T_PID_STALL 0xe
#define USBF_T_PID_NYET 0x6
#define USBF_T_PID_PRE 0xc
#define USBF_T_PID_ERR 0xc
#define USBF_T_PID_SPLIT 0x8
#define USBF_T_PID_PING 0x4
#define USBF_T_PID_RES 0x0
 
// The HMS_DEL is a constant for the "Half Micro Second"
// Clock pulse generator. This constant specifies how many
// Phy clocks there are between two hms_clock pulses. This
// constant plus 2 represents the actual delay.
// Example: For a 60 Mhz (16.667 nS period) Phy Clock, the
// delay must be 30 phy clock: 500ns / 16.667nS = 30 clocks
#define USBF_HMS_DEL 0x16
 
// After sending Data in response to an IN token from host, the
// host must reply with an ack. The host has 622nS in Full Speed
// mode and 400nS in High Speed mode to reply. RX_ACK_TO_VAL_FS
// and RX_ACK_TO_VAL_HS are the numbers of UTMI clock cycles
// minus 2 for Full and High Speed modes.
// #define USBF_RX_ACK_TO_VAL_FS 36
#define USBF_RX_ACK_TO_VAL_FS 200
 
// After sending a OUT token the host must send a data packet.
// The host has 622nS in Full Speed mode and 400nS in High Speed
// mode to send the data packet.
// TX_DATA_TO_VAL_FS and TX_DATA_TO_VAL_HS are is the numbers of
// UTMI clock cycles minus 2.
// #define USBF_TX_DATA_TO_VAL_FS 36
#define USBF_TX_DATA_TO_VAL_FS 200
 
#endif
 
/trunk/rtl/systemc/usb_crc16.h
0,0 → 1,59
/////////////////////////////////////////////////////////////////////
//// ////
//// USB CRC16 ////
//// ////
//// SystemC Version: usb_crc16.h ////
//// Author: Alfredo Luiz Foltran Fialho ////
//// alfoltran@ig.com.br ////
//// ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Verilog Version: usb1_crc16.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. ////
//// ////
/////////////////////////////////////////////////////////////////////
 
#ifndef USB_CRC16_H
#define USB_CRC16_H
 
SC_MODULE(usb_crc16) {
 
public:
 
sc_in<sc_uint<16> > crc_in;
sc_in<sc_uint<8> > din;
sc_out<sc_uint<16> > crc_out;
 
void update(void);
 
SC_CTOR(usb_crc16) {
SC_METHOD(update);
sensitive << crc_in << din;
}
 
};
 
#endif
 
/trunk/doc/usb_rtl.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/doc/usb_rtl.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/phy_rtl.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/phy_rtl.pdf =================================================================== --- trunk/doc/phy_rtl.pdf (nonexistent) +++ trunk/doc/phy_rtl.pdf (revision 2)
trunk/doc/phy_rtl.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/sie_rtl.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/sie_rtl.pdf =================================================================== --- trunk/doc/sie_rtl.pdf (nonexistent) +++ trunk/doc/sie_rtl.pdf (revision 2)
trunk/doc/sie_rtl.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/ep0_rtl.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/ep0_rtl.pdf =================================================================== --- trunk/doc/ep0_rtl.pdf (nonexistent) +++ trunk/doc/ep0_rtl.pdf (revision 2)
trunk/doc/ep0_rtl.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.