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

📄 usiedcd.v

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 V
📖 第 1 页 / 共 2 页
字号:
/******************************************
	Filename: 	siedcd.v 1.24
******************************************/

/*
The decoder module gets incoming data bits and decodes the packet
information.  It decides when to run the crc checker and when to
query the crc checker.  It checks for bad pids.  It sends single clock
outputs for each type of pid received.  It also grabs the address and
endpoint from tokens.  And the data byte from data.  For data it can't
know when data stops and crc starts (a 2-byte deep fifo in the next
module can through out the last two bytes received).
*/

module Usiedcd
	(
	// inputs
		usbclock,
		usbreset,
		datavalid,
		databit,
		dataidle,
		dataerror,
		datase0,
		crcerrordetected,

	// outputs to device
		address,
		addressvalid,
		endpoint,
		endpointvalid,
		databyte,
		databytevalid,
		startofframe,
		framenumber,
		rcvdatatogglebit,
		rcvack,
		rcvdata,
		rcvdataout,
		rcvdatain,
		rcvsetup,
		rcvpacketnotok,

	// outputs to sie internals
		rcvcrc5data,
		rcvcrc5check,
		rcvcrc16data,
		rcvcrc16check

	 );

`include "Usiedcddef.v"
`include "Uusbdef.v"

  input	       usbclock;
  input	       usbreset;	// synopsys sync_set_reset "usbreset"
  input	       datavalid;
  input	       databit;
  input	       dataidle;
  input	       dataerror;
  input	       datase0;
  input	       crcerrordetected;

  output [6:0] address;
  output       addressvalid;
  output [3:0] endpoint;
  output       endpointvalid;
  output [7:0] databyte;
  output       databytevalid;
  output       startofframe;
  output       [10:0]	framenumber;
  output       rcvpacketnotok;
  output       rcvdatatogglebit;
  output       rcvack;
  output       rcvdata;
  output       rcvdataout;
  output       rcvdatain;
  output       rcvsetup;
  output       rcvcrc5data;
  output       rcvcrc5check;
  output       rcvcrc16data;
  output       rcvcrc16check;

  reg [6:0]    address;
  reg	       addressvalid;
  reg [3:0]    endpoint;
  reg	       endpointvalid;
  reg [7:0]    databyte;
  reg	       databytevalid;
  reg	       startofframe;
  reg [10:0]   framenumber;
  reg	       rcvdatatogglebit;
  reg	       rcvack;
  reg	       rcvdata;
  reg	       rcvdataout;
  reg	       rcvdatain;
  reg	       rcvsetup;

  reg [3:0]    bitcount;
  reg	       resetbitcount;
  reg [9:0]    bytecount;
  reg	       resetbytecount;
  reg	       incrbytecount;
  reg	       rcvcrc5data;
  reg	       rcvcrc5check;
  reg	       rcvcrc16check;

  reg [3:0]    prevdcdst, dcdst, nextdcdst;

  reg [7:0]    currentpid;
  reg	       checkpid;
  reg	       rcvpacketnotok;
  reg [3:0]    last4bits;

	// tell the crc when the crc16 bits are arriving
  wire	       rcvcrc16data = ((dcdst == DCDDATA) && ~(datase0 || dataerror) && ~usbreset);

	// baddata is when I get dataerror after good pid but before crc fails
  wire	       baddata = (((dcdst == DCDDATA) || (dcdst == DCDADDR) || (dcdst == DCDENDP) ||
			(dcdst == DCDSOF) || (dcdst == DCDCRC5)) && dataerror);
	// badpid is wire, since checkpid is a reg
  wire	       badpid = (checkpid && (currentpid[3:0] != ~currentpid[7:4]));

  // call it a sync when we see 4 zeros and a 1 allows us to see a little garbage at the
  // beginning
  wire	       lookslikeasync = datavalid && databit == 1'b1 && 
                                   last4bits == 4'b0000 && bitcount >= 4'h7;
  
// always block for grabbing various bits based on the next, current, or previous state
always @(posedge usbclock)
begin
        last4bits[3:0] <= {last4bits[2:0],databit};
	if (resetbitcount)
		bitcount <= 4'b0;
	else if (datavalid)
		bitcount <= bitcount + 1'b1;

	if (badpid || crcerrordetected || baddata)
		rcvpacketnotok <= 1'b1;
	else
		rcvpacketnotok <= 1'b0;

	if (~datavalid)
		currentpid <= currentpid;
	else if (dcdst == DCDPID)
//		currentpid[bitcount] <= databit;
                case(bitcount[2:0])
                  3'b000 : 
                     begin
                       currentpid[0] <= databit;
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= currentpid[7];
                     end
                  3'b001 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= databit;
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= currentpid[7];
                     end
                  3'b010 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= databit;
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= currentpid[7];
                     end
                  3'b011 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= databit;
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= currentpid[7];
                     end
                  3'b100 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= databit;
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= currentpid[7];
                     end
                  3'b101 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= databit;
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= currentpid[7];
                     end
                  3'b110 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= databit;
                       currentpid[7] <= currentpid[7];
                     end
                  3'b111 : 
                     begin
                       currentpid[0] <= currentpid[0];
                       currentpid[1] <= currentpid[1];
                       currentpid[2] <= currentpid[2];
                       currentpid[3] <= currentpid[3];
                       currentpid[4] <= currentpid[4];
                       currentpid[5] <= currentpid[5];
                       currentpid[6] <= currentpid[6];
                       currentpid[7] <= databit;
                     end
                endcase

	if (~datavalid)
		address <= address;
	else if (dcdst == DCDADDR)
//		address[bitcount[2:0]] <= databit;
                case(bitcount[2:0])
                  3'b000 :
                    begin
                      address[0] <= databit;
                      address[1] <= address[1];
                      address[2] <= address[2];
                      address[3] <= address[3];
                      address[4] <= address[4];
                      address[5] <= address[5];
                      address[6] <= address[6];
                    end
                  3'b001 :
                    begin
                      address[0] <= address[0];
                      address[1] <= databit;
                      address[2] <= address[2];
                      address[3] <= address[3];
                      address[4] <= address[4];
                      address[5] <= address[5];
                      address[6] <= address[6];
                    end
                  3'b010 :
                    begin
                      address[0] <= address[0];
                      address[1] <= address[1];
                      address[2] <= databit;
                      address[3] <= address[3];
                      address[4] <= address[4];
                      address[5] <= address[5];
                      address[6] <= address[6];
                    end
                  3'b011 :
                    begin
                      address[0] <= address[0];
                      address[1] <= address[1];
                      address[2] <= address[2];
                      address[3] <= databit;
                      address[4] <= address[4];
                      address[5] <= address[5];
                      address[6] <= address[6];
                    end
                  3'b100 :
                    begin
                      address[0] <= address[0];
                      address[1] <= address[1];
                      address[2] <= address[2];
                      address[3] <= address[3];
                      address[4] <= databit;
                      address[5] <= address[5];
                      address[6] <= address[6];
                    end
                  3'b101 :
                    begin
                      address[0] <= address[0];
                      address[1] <= address[1];
                      address[2] <= address[2];
                      address[3] <= address[3];
                      address[4] <= address[4];
                      address[5] <= databit;
                      address[6] <= address[6];
                    end
                  3'b110 :
                    begin
                      address[0] <= address[0];
                      address[1] <= address[1];
                      address[2] <= address[2];
                      address[3] <= address[3];
                      address[4] <= address[4];
                      address[5] <= address[5];
                      address[6] <= databit;
                    end
                  3'b111 :
                    begin
                      address <= address;
                    end
                endcase

	if (usbreset || dcdst == DCDERROR)
		addressvalid <= 1'b0;
	else if (dcdst == DCDADDR)		// getting a new one, old one invalid
		addressvalid <= 1'b0;
	else if (dcdst == DCDENDP && prevdcdst == DCDADDR)
		addressvalid <= 1'b1;

	if (~datavalid)
		endpoint <= endpoint;
	else if (dcdst == DCDENDP)
//		endpoint[bitcount[2:0]] <= databit;
                case(bitcount[1:0])
                  2'b00 :
                     begin
                       endpoint[0] <= databit;
                       endpoint[1] <= endpoint[1];
                       endpoint[2] <= endpoint[2];
                       endpoint[3] <= endpoint[3];
                     end
                  2'b01 :
                     begin
                       endpoint[0] <= endpoint[0];
                       endpoint[1] <= databit;
                       endpoint[2] <= endpoint[2];
                       endpoint[3] <= endpoint[3];
                     end
                  2'b10 :
                     begin
                       endpoint[0] <= endpoint[0];
                       endpoint[1] <= endpoint[1];
                       endpoint[2] <= databit;
                       endpoint[3] <= endpoint[3];
                     end
                  2'b11 :
                     begin
                       endpoint[0] <= endpoint[0];
                       endpoint[1] <= endpoint[1];
                       endpoint[2] <= endpoint[2];
                       endpoint[3] <= databit;
                     end
                endcase

	if (usbreset || dcdst == DCDERROR)
		endpointvalid <= 1'b0;
	else if (dcdst == DCDADDR)		// getting a new one, old one invalid
		endpointvalid <= 1'b0;
	else if (dcdst == DCDENDP && datavalid && bitcount == 4'h3)	// last bit
		endpointvalid <= 1'b1;

	if (usbreset || dcdst == DCDERROR || dcdst == DCDIDLE)
		bytecount <= 1'b0;
	else if (dcdst == DCDDATA && bitcount == 8'b0 && datavalid)		// incr on first bit of a byte
										// so we can know when we are done
		bytecount <= bytecount + 1'b1;

	if (~datavalid)
		databyte <= databyte;
	else if (dcdst == DCDDATA)
//		databyte[bitcount[3:0]] <= databit;
                case(bitcount[2:0])
                  3'b000 :
                    begin
                      databyte[0] <= databit;
                      databyte[1] <= databyte[1];
                      databyte[2] <= databyte[2];
                      databyte[3] <= databyte[3];
                      databyte[4] <= databyte[4];
                      databyte[5] <= databyte[5];

⌨️ 快捷键说明

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