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