在NFC通信中,所使用的CRC多项式为:
输入输出反转,寄存器初始值为0xFFFF,输出结果异或0xFFFF,相当CRC输出结果于取反。根据公式,我们进行编程。
CRC实现可以采用并行或串行结构,本次使用串行结构。首先实现1bit数据的CRC实现。其中的公式可以根据crc_16介绍中有所体现。
//one_biyt a clock
function [15:0]crc16_serial;
input [15:0]crc16;
input data;
begin
crc16_serial[0]=data^crc16[15];
crc16_serial[1]=crc16[0];
crc16_serial[2]=crc16[1];
crc16_serial[3]=crc16[2];
crc16_serial[4]=crc16[3];
crc16_serial[5]=crc16[4]^data^crc16[15];
crc16_serial[6]=crc16[5];
crc16_serial[7]=crc16[6];
crc16_serial[8]=crc16[7];
crc16_serial[9]=crc16[8];
crc16_serial[10]=crc16[9];
crc16_serial[11]=crc16[10];
crc16_serial[12]=data^crc16[15]^crc16[11];
crc16_serial[13]=crc16[12];
crc16_serial[14]=crc16[13];
crc16_serial[15]=crc16[14];
end
endfunction
利用该1bit crc_16方法实现8bit,也就是一个字节的crc_16计算。
//8bit 8 clock
function [15:0]crc_iteration;
input [15:0] crc;
input [7:0] data;
integer i;
begin
crc_iteration = crc;
for(i = 0; i < 8; i =i + 1)
crc_iteration = crc16_serial(crc_iteration,data[i]);
end
endfunction
由于发送和接收命令的长度是不确定的,为了使得所以命令都能够进行CRC编码,输出参数除了命令外还有命令字节长度,最大可编码20个字节的命令。整个实现过程利用三段状态机实现。共包括五个状态。
always @(posedge clk_system or negedge rstn) begin
if(!rstn)
state <= idle;
else
state <= next_state;
end
always @(*) begin
case (state)
idle : if(data_vaild) next_state = start; else next_state = idle;///č°ćśç¨posedge_data_vaild
start : next_state = shift;
shift :if(byte_count == cmd_cnt_temp) next_state = turn; else next_state = shift;
turn : next_state <= finish;
finish : next_state <= idle;
default: ;
endcase
end
integer i;
always @(posedge clk_system or negedge rstn) begin
if (!rstn)begin
temp_cmd <= 0;
byte_data <= 8'd0;
LSFR <= 16'hFFFF;
byte_count <= 0;
cmd_vaild <=1'd0;
cmd_crc <= 0;
LSFR_S <= 16'd0;
cmd_cnt <= 0;
cmd_crc_temp <= 0;
cmd_cnt_temp <= 0;
end
else begin
case (next_state)
idle : begin
LSFR <= 16'hFFFF;
cmd_vaild <= 1'd0;
cmd_cnt_temp <= 0;
end
start :begin
cmd_crc_temp <= data;
cmd_cnt_temp <= data_cnt;
case (data_cnt)
5'd1 : byte_data <= data;
5'd2 : begin byte_data <= data[2*8-1:1*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-1)*8] <= data[1*8-1:0];end
5'd3 : begin byte_data <= data[3*8-1:2*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-2)*8] <= data[2*8-1:0];end
5'd4 : begin byte_data <= data[4*8-1:3*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-3)*8] <= data[3*8-1:0];end
5'd5 : begin byte_data <= data[5*8-1:4*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-4)*8] <= data[4*8-1:0];end
5'd6 : begin byte_data <= data[6*8-1:5*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-5)*8] <= data[5*8-1:0];end
5'd7 : begin byte_data <= data[7*8-1:6*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-6)*8] <= data[6*8-1:0];end
5'd8 : begin byte_data <= data[8*8-1:7*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-7)*8] <= data[7*8-1:0];end
5'd9 : begin byte_data <= data[9*8-1:8*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-8)*8] <= data[8*8-1:0];end
5'd10: begin byte_data <= data[10*8-1:9*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-9)*8] <= data[9*8-1:0];end
5'd11: begin byte_data <= data[11*8-1:10*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-10)*8] <= data[10*8-1:0];end
5'd12: begin byte_data <= data[12*8-1:11*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-11)*8] <= data[11*8-1:0];end
5'd13: begin byte_data <= data[13*8-1:12*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-12)*8] <= data[12*8-1:0];end
5'd14: begin byte_data <= data[14*8-1:13*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-13)*8] <= data[13*8-1:0];end
5'd15: begin byte_data <= data[15*8-1:14*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-14)*8] <= data[14*8-1:0];end
5'd16: begin byte_data <= data[16*8-1:15*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-15)*8] <= data[15*8-1:0];end
5'd17: begin byte_data <= data[17*8-1:16*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-16)*8] <= data[16*8-1:0];end
5'd18: begin byte_data <= data[18*8-1:17*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-17)*8] <= data[17*8-1:0];end
5'd19: begin byte_data <= data[19*8-1:18*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-18)*8] <= data[18*8-1:0];end
5'd20: begin byte_data <= data[20*8-1:19*8]; temp_cmd[CMD_WITH * 8-1:(CMD_WITH-19)*8] <= data[19*8-1:0];end
default: ;
endcase
end
shift :begin
LSFR <= crc_iteration(LSFR,byte_data);
temp_cmd <= {temp_cmd[(CMD_WITH-1) * 8-1:0],8'd0};
byte_count <= byte_count + 1'd1;
byte_data <= temp_cmd[CMD_WITH * 8-1 : (CMD_WITH-1)*8];
end
turn : begin
for (i = 0; i<16; i=i+1)
LSFR_S[i] <= LSFR [15-i];
end
finish :begin
byte_count <= 0;
cmd_crc <= {cmd_crc_temp,~ LSFR_S};
cmd_vaild <= 1'd1;
cmd_cnt <= cmd_cnt_temp + 2;
end
default: ;
endcase
end
end
模块参数有 :
module crc_code
#(
parameter CMD_WITH = 20,
parameter BYTE_CNT = 4
)
(
input rstn,
input clk_system,
input [BYTE_CNT : 0] data_cnt, //ĺ¤ĺ°byte
input [CMD_WITH * 8 - 1:0] data, //ć?大ĺŞč˝ć6个byte
input data_vaild, //ć°ćŽćć
output reg [CMD_WITH * 8 + 15:0] cmd_crc, //希ćCRCčžĺş
output reg cmd_vaild, //ć°ćŽćć
output reg [BYTE_CNT:0] cmd_cnt
);
334

被折叠的 条评论
为什么被折叠?



