⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udevctl.v

📁 USBRTL电路的VHDL和Verilog代码
💻 V
📖 第 1 页 / 共 4 页
字号:
        sendnak <= 1'b0;
      
      if (usbreset)
        sendack <= 1'b0;
      else if (nextctlst == CTLSENDACK)
        sendack <= 1'b1;
      else if (acksent)
        sendack <= 1'b0;
      
      if (usbreset)
        senddata <= 1'b0;
      else if (nextctlst == CTLSENDDATA)
        senddata <= 1'b1;
      else if (datasent)
        senddata <= 1'b0;
      
      if (usbreset)
        begin
          firstbytevalid <= 1'b0;
          secondbytevalid <= 1'b0;
        end
      else if (grabdata)
      //else if (grabdata || grabsetup) //JAKE
        begin
          firstbytevalid <= 1'b1;
          secondbytevalid <= firstbytevalid;
        end
      else if (rcvpacketok || rcvpacketnotok)       // at end of packet, get rid of both
        begin
          firstbytevalid <= 1'b0;
          secondbytevalid <= 1'b0;
        end
      
      if (grabdata)
     // if (grabdata ||grabsetup) //JAKE
	   begin
          firstbyte <= rcvdatabyte;
          secondbyte <= firstbyte;
        end
      
      if (rcvendpointvalid) currentendp <= rcvendpoint;
      if (rcvaddressvalid) currentaddr <= rcvaddress;
    end

// state machine for doing the device control
//STATE MACHINE

always @(posedge usbclock)
    begin
      if (usbreset)
        ctlst <= CTLIDLE;
      else
        ctlst <= nextctlst;
    end
  
  always @(ctlst or usbreset or rcvsetup or rcvdata or rcvdatain or rcvdataout or rcvack or
                rcvendpointvalid or rcvaddressvalid or rcvaddress or rcvendpoint or
                rcvpacketok or rcvpacketnotok or naksent or isoendpoint or xmitlastbyte or
                acksent or addressmatch or stallsent or endpointzerotogglebit or endpoint0active or
                endpointrdready or endpointwrready or endpointrdstall or endpointwrstall or
                endpointouttogglebits or currentendp or setupcycle or rcvdatatogglebit or
                turnaround or endpointrdmatch or endpointwrmatch or setupdirection or grabdata or
		sendzerolengthpkt)

    begin
      if (usbreset)
        nextctlst = CTLIDLE;
      else
        case (ctlst)   // synopsys parallel_case full_case
          CTLIDLE:
            begin
              case (1'b1)       // synopsys parallel_case full_case
                rcvsetup:
                  nextctlst = CTLSETUP;
                rcvdata:                       // wasn't for us as identified during out packet
                  nextctlst = CTLIDLE;
                rcvdatain: 
                  nextctlst = CTLDIN;
                rcvdataout: 
                  nextctlst = CTLDOUT;
                rcvack:                        // isn't for us since we didn't just send data
                  nextctlst = CTLIDLE;
                default:
                  nextctlst = CTLIDLE;
              endcase
            end
          CTLSETUP: 
            begin 
              if (rcvpacketnotok)
                nextctlst = CTLIDLE;
              else if (rcvpacketok && addressmatch && endpoint0active)  // packet is ok and matches us
                nextctlst = CTLWAIT4SETUP;
              else if (rcvpacketok)
                nextctlst = CTLIDLE;
              else
                nextctlst = CTLSETUP; 
            end
          CTLDIN: 
            begin 
              if (rcvpacketnotok)
                nextctlst = CTLIDLE;
              // rcvpacketok means crc5 was good 
              // first condition is the null data on a control data in
              else if (rcvpacketok && addressmatch && endpoint0active && setupcycle && (setupdirection == HOSTTODEV))
                nextctlst = CTLSENDDATA;            // packet is ok and matches us
              else if (rcvpacketok && addressmatch && endpointrdmatch && endpointrdready && ~endpointrdstall)  
                nextctlst = CTLSENDDATA;            // packet is ok and matches us
              else if (rcvpacketok && addressmatch && endpointrdmatch && endpointrdstall && ~isoendpoint)
                nextctlst = CTLSENDSTALL;           // endpoint is stalled
              else if (rcvpacketok && addressmatch && endpointrdmatch && ~endpointrdready && ~isoendpoint)
                nextctlst = CTLSENDNAK;             // endpoint isn't ready, not stalled
              else if (rcvpacketok)   // not for us
                nextctlst = CTLIDLE;
              else
                nextctlst = CTLDIN; 
            end
          CTLDOUT: 
            begin 
              if (rcvpacketnotok)
                nextctlst = CTLIDLE;
              else if (rcvpacketok && addressmatch && endpointwrmatch)     // packet is ok and matches us
                nextctlst = CTLWAIT4DATA;
              else if (rcvpacketok)   // either bad or not us
                nextctlst = CTLIDLE;
              else
                nextctlst = CTLDOUT; 
            end
          CTLWAIT4SETUP:              // here during the intial setup token of a setup cycle
            // waiting for the data0 host transmit of the setup request packet
            begin
              if (rcvdata)
                nextctlst = CTLGRABSETUP; 
              else if (rcvpacketnotok || rcvpacketok || turnaround) // some other packet came ?!?
                nextctlst = CTLIDLE;                 // or nothing coming?  - give up and go to idle
              else 
                nextctlst = CTLWAIT4SETUP; 
            end
          CTLWAIT4DATA:               // once here, we know the address and endpoint match, just check endpoint is ok
            begin
                // first condition is the null data on a control data in
                if (rcvdata && sendzerolengthpkt && endpoint0active && (setupdirection == DEVTOHOST) && (endpointzerotogglebit == rcvdatatogglebit))     // null data, send ack
                  nextctlst = CTLSENDACK;
              else if (rcvdata && ~isoendpoint && (~endpointwrready || endpointwrstall))       // not ready or stalled
                nextctlst = CTLIGNOREDATA;
              else if (rcvdata)
                begin
              // don't check toggle bit if iso endpoint
                if (((endpointouttogglebits[currentendp] == rcvdatatogglebit) && ~endpoint0active) ||
                        ((endpointzerotogglebit == rcvdatatogglebit) && endpoint0active) ||
                        isoendpoint)
                  nextctlst = CTLGRABDATA;
                else            // toggle mismatch, must have seen this data already
                  // we can go straight to sendack, since we want to send
                  // ack no matter what and the xmit will wait for incoming
                  // data to complete first
                  nextctlst = CTLSENDACK;
                end     //if (rcvdata)
              else if (rcvpacketnotok || rcvpacketok || turnaround) // some other packet came ?!?
                nextctlst = CTLIDLE;                 // or nothing coming?  - give up and go to idle
              else
                nextctlst = CTLWAIT4DATA;
	    end
          CTLIGNOREDATA:      // got here because we are stalled or not ready, but must check for good packet
            // before sending NAK or STALL
            if (rcvpacketnotok)
              nextctlst = CTLIDLE;
            else if (rcvpacketok && endpointwrstall)        // endpoint is stalled
              nextctlst = CTLSENDSTALL;
            else if (rcvpacketok)                     // don't recheck ready here,
              nextctlst = CTLSENDNAK;       // if we got here, we missed data already
            else 
              nextctlst = CTLIGNOREDATA;
          CTLGRABDATA: 
            begin 
              if (rcvpacketnotok || (rcvpacketok && isoendpoint)) // no acks for iso endpoints
                nextctlst = CTLIDLE;
              else if (rcvpacketok)
                nextctlst = CTLSENDACK;
              else if (~endpointwrready && ~isoendpoint && grabdata)// overflowed! (iso's can't overflow)
                nextctlst = CTLOVERFLOW;
              else
                nextctlst = CTLGRABDATA; 
            end
          CTLGRABSETUP: 
            begin 
              if (rcvpacketnotok)
                nextctlst = CTLIDLE;
              else if (rcvpacketok)
                nextctlst = CTLSENDACK;
              else
                nextctlst = CTLGRABSETUP; 
            end
          CTLOVERFLOW:
            begin 
              if (rcvpacketnotok)
                nextctlst = CTLIDLE;
              else if (rcvpacketok)
                nextctlst = CTLSENDNAK;
              else
                nextctlst = CTLOVERFLOW; 
            end
          CTLSENDDATA: 
            begin 
              if (xmitlastbyte && ~isoendpoint)      // no acks for isochronous endpoints
                nextctlst = CTLWAIT4ACK;
              else if (xmitlastbyte)
                nextctlst = CTLIDLE;
              else
                nextctlst = CTLSENDDATA; 
            end
          CTLWAIT4ACK:
            begin
              // TEMP - this might technically be incorrect, I should wait for packetok, in case of badpidbar
              if (rcvack)
                nextctlst = CTLIDLE;
              else if (rcvpacketnotok || rcvpacketok || turnaround) // some other packet came ?!?
                nextctlst = CTLIDLE;                 // or nothing coming?  - give up and go to idle
              else 
                nextctlst = CTLWAIT4ACK; 
            end
          CTLSENDACK: 
            begin 
              if (acksent)
                nextctlst = CTLIDLE;
              else
                nextctlst = CTLSENDACK; 
            end
          CTLSENDNAK: 
            begin 
              if (naksent)
                nextctlst = CTLIDLE;
              else if (rcvpacketnotok || rcvpacketok)       // some other packet came ?!?
                nextctlst = CTLIDLE;                 // give up and go to idle
              else
                nextctlst = CTLSENDNAK; 
            end
          CTLSENDSTALL: 
            begin 
              if (stallsent)
                nextctlst = CTLIDLE;
              else if (rcvpacketnotok || rcvpacketok)       // some other packet came ?!?
                nextctlst = CTLIDLE;                 // give up and go to idle
              else
                nextctlst = CTLSENDSTALL; 
            end
        endcase
    end
  
  // for waves
  // setup direction is high for Device -> Host,
  wire [63:0] setupreqpkt = {setuplength, // bytes 7 and 6
                                setupwindex[15:0], // bytes 5 and 4
                                setupvalue1,  // byte 3 wValueH on get descriptor - type dev,cfg, or string
                                setupvalue0,    //  byte 2 wValueL - address on setaddress
                                setuprequest, // byte 1 request field
                                setupdirection,setuptype,3'b000,setuprecipient}; // byte lane 0

always @(setupreqpkt or setupbyteaddr)
begin
	case (setupbyteaddr)   // synopsys parallel_case full_case
	3'h0:	setupdata = setupreqpkt[7:0];
	3'h1:	setupdata = setupreqpkt[15:8];
	3'h2:	setupdata = setupreqpkt[23:16];
	3'h3:	setupdata = setupreqpkt[31:24];
	3'h4:	setupdata = setupreqpkt[39:32];
	3'h5:	setupdata = setupreqpkt[47:40];
	3'h6:	setupdata = setupreqpkt[55:48];
	3'h7:	setupdata = setupreqpkt[63:56];
	endcase
end
  
// make the ascii version of the ctl state
// synopsys translate_off
  reg [8*11:1] ctlstate;
  always @(ctlst)
    case (ctlst)
      CTLIDLE : ctlstate = "CTLIDLE";
      CTLSETUP : ctlstate = "CTLSETUP";
      CTLDIN : ctlstate = "CTLDIN";
      CTLDOUT : ctlstate = "CTLDOUT";
      CTLWAIT4SETUP : ctlstate = "CTLWAIT4SETUP";
      CTLWAIT4DATA : ctlstate = "CTLWAIT4DATA";
      CTLIGNOREDATA : ctlstate = "CTLIGNOREDATA";
      CTLOVERFLOW : ctlstate = "CTLOVERFLOW";
      CTLWAIT4ACK : ctlstate = "CTLWAIT4ACK";
      CTLGRABDATA : ctlstate = "CTLGRABDATA";
      CTLSENDDATA : ctlstate = "CTLSENDDATA";
      CTLSENDACK : ctlstate = "CTLSENDACK";
      CTLSENDNAK : ctlstate = "CTLSENDNAK";
      CTLSENDSTALL : ctlstate = "CTLSENDSTALL";
      CTLGRABSETUP : ctlstate = "CTLGRABSETUP";
      default:  ctlstate = "ILLEGAL STATE";
    endcase
  // synopsys translate_on

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -