📄 usiedcd.v
字号:
/******************************************
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 + -