USB crc5计算

CRC 的发生和校检,发生器和检验器里的移位寄存器置成为全 1型。对于每个被发送或者被收到的数据位,当前余项的最高一位和数据位进行异或( XOR ),然后,余项是左移 1 位,并且,最低一位置零。如果异或的结果是 1 ,余项和生成多项式作异或。当检查的字段最后的一位被发送的时候,对发生器里的 CRC取反,再以最高位( MSb )在前发给检验器。

crc5的生成多项式为x5+x2+1;表示为5’b00101(x5不需表示出来)
这里写图片描述

对于每一位数据D有:
R0<=R4 ^ D
R1<=R0;
R2 <= (R4 ^ D) ^ R1;
R3 <= R2;
R4 <= R3;
数据流D是从LSB开始,对于token pid则依次处理ADR[0],ADR[1],……ADR[7],ENDP[0],……最后ENDP[3]。

(1)按bit串行计算,用testbench表现为:

bit[4:0] crc_reg,crc_reg_pre;
bits[7:0] token_bits;
bits[10:0] data_bits;
bits[4:0] crc_send;
bit[23:0] bitstream_send;
initial begin
	crc_reg = 5’h1f;
	token_bits = 8’b0110_1001; // IN token, {~pid[3:0],pid[3:0]}=0110_1001
	data_bits = 19’b0001_0001000  // (黄色为ENDP[3:0]=0001,绿色为ADDR[7:0]=0001000)
 	for(int i=0;i<11;i++) begin
		crc_reg_pre = crc_reg;
		crc_reg[0] = data_bits[i] ^ crc_reg_pre[4];
		crc_reg[1] = crc_reg_pre[0];
		crc_reg[2]= crc_reg_pre[1] ^ bitdata[i] ^ crc_reg_pre[4];
		crc_reg[3] = crc_reg_pre[2];
		crc_reg[4] = crc_reg_pre[3];
	end
	crc_send = ~ {crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3], crc_reg[4]}; //取反,MSB在前
end

运算结果crc_reg=10100
bitstream_send = {crc_send,data_bits,token_bits}
在DP/DM线上是先发bitstream_send[0],最后发bitstream_send[23]。
在接收端是对{crc_send,data_bits}进行同样的crc计算,计算结果为01100(接收正确的crc计算结果都应为01100)
(2)并行计算
初始值:R0=R1=R2=R3=R4=1;
对每一比特的串行计算为:R0<=R4 ^ D; R1<=R; R2 <= (R4 ^ D) ^ R1;R3 <= R2; R4 <= R3;
则有:
这里写图片描述
最终得并行计算的公式为:
R0=1D0D1D4D5^D10
R1=1D0D3D4D6^D9
R2=1D0D1D2D3D4D7D8D10
R3= D0D1D2D3D6D7D9
R4=1D0D1D2D5D6D8
(3)按byte计算

bit[7:0] crc_reg,crc_poly;
bits[7:0] token_bits;
bits[10:0] data_bits;
bits[4:0] crc_send;
bit[23:0] bitstream_send;
initial begin
	crc_reg = 8’b0001_1111; //这里的[0]对应方法(1)的[4],对应R4
	crc_poly = 8’b00010100; //(对多项式’h5进行msb~lsb反置后右移3,即[0]对应R4位置
	token_bits = 8’b0110_1001; // IN token, {~pid[3:0],pid[3:0]}=0110_1001
	data_bits = 19’b0001_0001000  // (黄色为ENDP[3:0]=0001,绿色为ADDR[7:0]=0001000)
 	for(int i=0;i<2;i++) begin
	crc_reg = data_bits[7:0] ^ crc_reg;
	for(int j=0;j<8;j++) begin
			if(crc_reg[0]==1) begin
				crc_reg = {1’b0,crc_reg[7:1]};
				crc_reg = crc_reg ^ crc_poly;
			end
			else begin
				crc_reg = {1’b0,crc_reg[7:1]};
			end
			if((i==1) && (j==2))
				break;
		end
	end
	crc_send[4:0] = crc_reg[4:0] ^ 5’h1f; //不用高低位反置,因为[0]表示的是R4了
end

参考:
https://wenku.baidu.com/view/1ae311b3aef8941ea66e0535.html###

https://wenku.baidu.com/view/1a80b6601ed9ad51f01df2b8.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值