📄 usb_pe_sie.cpp
字号:
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 packetsvoid usb_pe_sie::data_pid_sel_up(void) { data_pid_sel.write(this_dpid.read());}// Verify PID for incoming data packetsvoid 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 endpointsvoid 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 operationvoid 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 operationvoid 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 Logicvoid usb_pe_sie::uc_dpd_set_up(void) { uc_dpd_set.write(uc_stat_set_d.read());}// Abort signalvoid 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 timervoid 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 timervoid 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());}// Interruptsvoid 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -