这是时序逻辑,转换成组合逻辑就是当前寄存器的值等于之前寄存器的值和当前输入做运算,用变量init来表示寄存器初始值,然后做8次迭代,

crc[0] = init[3] ^ data ;
crc[1] = init[0] ^ init[3] ^ data;
crc[2] = init[1];
crc[3] = init[2];
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

为了方便,在crc后面用迭代次数-1表示,那么第1次迭代:输入数据的最高位data[7]和上一轮的LFSR寄存器值(因为才开始,所以是初始值)做异或运算。

data[7]:
	crc7[0] = init[3] ^ data[7] ;
	crc7[1] = init[0] ^ init[3] ^ data[7];
	crc7[2] = init[1];
	crc7[3] = init[2];
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

同理,有第2次迭代:输入数据的次高位data[6]和上一轮的LFSR寄存器值(即crc7变量)做异或运算。

data[6]:
	crc6[0] = crc7[3] ^ data[6] = init[2] ^ data[6];
	crc6[1] = crc7[0] ^ crc7[3] ^ data[6] = init[3] ^ data[7] ^ init[2] ^ data[6];
	crc6[2] = crc7[1] = init[0] ^ init[3] ^ data[7];
	crc6[3] = crc7[2] = init[1];
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

直到第8次迭代,输入最后一个数据:

data[5]:
	crc5[0] = crc6[3] ^ data[5] = init[1] ^ data[5];
	crc5[1] = crc6[0] ^ crc6[3] ^ data[5] = init[2] ^ data[6] ^ init[1] ^ data[5];
	crc5[2] = crc6[1] = init[3] ^ data[7] ^ init[2] ^ data[6];
	crc5[3] = crc6[2] = init[0] ^ init[3] ^ data[7];	
data[4]:
	crc4[0] = crc5[3] ^ data[4] = init[0] ^ init[3] ^ data[7] ^ data[4]
	crc4[1] = crc5[0] ^ crc5[3] ^ data[4] = init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4];
	crc4[2] = crc5[1] = init[2] ^ data[6] ^ init[1] ^ data[5];
	crc4[3] = crc5[2] = init[3] ^ data[7] ^ init[2] ^ data[6];
data[3]:
	crc3[0] = crc4[3] ^ data[3] = init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3]
	crc3[1] = crc4[0] ^ crc4[3] ^ data[3] = init[0] ^ init[3] ^ data[7] ^ data[4] ^ init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3]
	crc3[2] = crc4[1] = init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4];
	crc3[3] = crc4[2] = init[2] ^ data[6] ^ init[1] ^ data[5];
data[2]:
	crc2[0] = crc3[3] ^ data[2] = init[2] ^ data[6] ^ init[1] ^ data[5] ^ data[2]
	crc2[1] = crc3[0] ^ crc3[3] ^ data[2] = init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3] ^ init[2] ^ data[6] ^ init[1] ^ data[5] ^ data[2]
	crc2[2] = crc3[1] = init[0] ^ init[3] ^ data[7] ^ data[4] ^ init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3]
	crc2[3] = crc3[2] = init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4]
data[1]:
	crc1[0] = crc2[3] ^ data[1] = init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4] ^ data[1]
	crc1[1] = crc2[0] ^ crc2[3] ^ data[1] = init[2] ^ data[6] ^ init[1] ^ data[5] ^ data[2] ^ init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4] ^ data[1]
	crc1[2] = crc2[1] = init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3] ^ init[2] ^ data[6] ^ init[1] ^ data[5] ^ data[2]
	crc1[3] = crc2[2] = init[0] ^ init[3] ^ data[7] ^ data[4] ^ init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3]	
data[0]:
	crc0[0] = crc1[3] ^ data[0] = init[0] ^ init[3] ^ data[7] ^ data[4] ^ init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3] ^ data[0]	
			= init[0] ^ data[4] ^ init[2] ^ data[6] ^ data[3] ^ data[0]
	crc0[1] = crc1[0] ^ crc1[3] ^ data[0] = init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4] ^ data[1] ^ init[0] ^ init[3] ^ data[7] ^ data[4] ^ init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3] ^ data[0]
			= init[1] ^ data[5]^ init[3] ^ data[4] ^ data[1]^ data[7] ^ data[4] ^ init[2] ^ data[6] ^ data[3] ^ data[0]
	crc0[2] = crc1[1] = init[2] ^ data[6] ^ init[1] ^ data[5] ^ data[2] ^ init[1] ^ data[5] ^ init[0] ^ init[3] ^ data[7] ^ data[4] ^ data[1]
	crc0[3] = crc1[2] = init[3] ^ data[7] ^ init[2] ^ data[6] ^ data[3] ^ init[2] ^ data[6] ^ init[1] ^ data[5] ^ data[2]
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

把crc0的表达式整理一下:

crc0[0] = data[6] ^ data[4] ^ data[3] ^ data[0]	^ init[0] ^ init[2];   
crc0[1]	= data[7] ^ data[6] ^ data[5] ^ data[1] ^ data[3] ^ data[0] ^ init[1] ^ init[2] ^ init[3];
crc0[2] = data[7] ^ data[6] ^ data[4] ^ data[2] ^ data[1] ^ init[0] ^ init[2] ^ init[3];
crc0[3] = data[7] ^ data[5] ^ data[3] ^ data[2] ^ init[1] ^ init[3];
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

和这个网站http://crctool.easics.be/用工具生成的代码(核心部分)做对比,二者结果一致。

newcrc[0] = data[6] ^ data[4] ^ data[3] ^ data[0] ^ crc[0] ^ crc[2];
newcrc[1] = data[7] ^ data[6] ^ data[5] ^ data[3] ^ data[1] ^ data[0] ^ crc[1] ^ crc[2] ^ crc[3];
newcrc[2] = data[7] ^ data[6] ^ data[4] ^ data[2] ^ data[1] ^ crc[0] ^ crc[2] ^ crc[3];
newcrc[3] = data[7] ^ data[5] ^ data[3] ^ data[2] ^ crc[1] ^ crc[3];
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

接着编写并行CRC-8的代码:

//并行CRC-8:宽度8,多项式0x07(x^8+x^2+x+1),初始值00,XOROUT00,REFIN/REFOUT均为FALSE
module test(
	input			clk,			//时钟
	input			rst,			//异步复位
	input	[7:0]	pal_in,			//并行8位输入数据
	input			pal_in_val,		//并行输入数据有效
	output	[7:0] 	crc_data,		//CRC校验数据
	output 			crc_data_val	//CRC校验数据有效
);

//定义寄存器变量
reg [7:0] 	crc;					//CRC校验数据
reg			data_val;				//CRC校验数据输出有效信号

localparam	CRC_INIT = 8'd0;		//LFSR寄存器初始值

//连接端口
assign crc_data = crc;
assign crc_data_val = data_val;

//并行电路使用函数来构造
function [7:0] CRC8;
	input [7:0] data;				//被校验数据
	input [7:0] crc_init;			//寄存器初值
	begin
		CRC8[0] = data[7] ^ data[6] ^ data[0] ^ crc_init[0] ^ crc_init[6] ^ crc_init[7];
		CRC8[1] = data[6] ^ data[1] ^ data[0] ^ crc_init[0] ^ crc_init[1] ^ crc_init[6];
		CRC8[2] = data[6] ^ data[2] ^ data[1] ^ data[0] ^ crc_init[0] ^ crc_init[1] ^ crc_init[2] ^ crc_init[6];
		CRC8[3] = data[7] ^ data[3] ^ data[2] ^ data[1] ^ crc_init[1] ^ crc_init[2] ^ crc_init[3] ^ crc_init[7];
		CRC8[4] = data[4] ^ data[3] ^ data[2] ^ crc_init[2] ^ crc_init[3] ^ crc_init[4];
		CRC8[5] = data[5] ^ data[4] ^ data[3] ^ crc_init[3] ^ crc_init[4] ^ crc_init[5];
		CRC8[6] = data[6] ^ data[5] ^ data[4] ^ crc_init[4] ^ crc_init[5] ^ crc_init[6];
		CRC8[7] = data[7] ^ data[6] ^ data[5] ^ crc_init[5] ^ crc_init[6] ^ crc_init[7];
	end
endfunction

//当输入有效时进行CRC校验
always @(posedge clk or posedge rst)begin
	if(rst)
		crc <= 8'd0;			
	else if(pal_in_val) 				//输入有效时
		crc <= CRC8(pal_in,CRC_INIT);	//校验结果落后一拍
end

//在输入数据有效的下一个周期输出有效
always @(posedge clk or posedge rst)begin
	if(rst)
		data_val <= 0;		
	else if(pal_in_val)	
		data_val <= 1;			
	else
		data_val <= 0;					//其他时间均为低电平	
end

endmodule 
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

测试逻辑和上面的串行CRC一样:依次输入0~255这256个数据,观察CRC校验结果:

`timescale 1ns/1ns
module tb_test();

//信号声明
reg			clk;
reg			rst;
reg	[7:0]	pal_in;	
reg			pal_in_val;	

wire[7:0]	crc_data;
wire		crc_data_val;

//被测模块实例化
test	inst_test(
	.clk			(clk		),		//时钟信号
	.rst			(rst		),		//时钟信号
	.pal_in			(pal_in		),		//串行输入数据
	.pal_in_val		(pal_in_val	),		//串行输入数据有效信号
	.crc_data		(crc_data	),
	.crc_data_val	(crc_data_val)
);	

//生成时钟信号
initial begin
    clk	= 1'b0;
	forever #5 clk = ~clk;
end

//生成复位信号
initial begin
		rst = 1'b1;	//复位
    #40 rst = 1'b0; //取消复位
end 

//生成输入数据与时钟使能信号
always @(posedge clk or posedge rst)begin
	if(rst)begin
		pal_in <= 255;
		pal_in_val <= 0;
	end
	else begin 
		pal_in <= pal_in + 1;
		pal_in_val <= 1;
	end
end   

//仿真过程
initial begin
	#1000 $stop;	//关闭仿真	
end

endmodule 
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

仿真结果如下,CRC校验结果依次输出00-07-0e-09······,与正确结果对比后,发现仿真无误。

image-20240302161000934

initial begin
		rst = 1'b1;	//复位
    #40 rst = 1'b0; //取消复位
end 

//生成输入数据与时钟使能信号
always @(posedge clk or posedge rst)begin
	if(rst)begin
		pal_in <= 255;
		pal_in_val <= 0;
	end
	else begin 
		pal_in <= pal_in + 1;
		pal_in_val <= 1;
	end
end   

//仿真过程
initial begin
	#1000 $stop;	//关闭仿真	
end

endmodule 
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

仿真结果如下,CRC校验结果依次输出00-07-0e-09······,与正确结果对比后,发现仿真无误。

在这里插入图片描述



data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://wuzhikai.blog.csdn.net/article/details/136441181","extend1":"pc","ab":"new"}">>
注:本文转载自blog.csdn.net的孤独的单刀的文章"https://blog.csdn.net/wuzhikaidetb/article/details/136441181"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!