基于FPAG的NFC Reader端(五)附——CRC完整代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/07/07 15:18:06
// Design Name: 
// Module Name: crc_code
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


//äźĺçšďź
//      ĺ˝äť¤ä˝ĺŽ˝ĺŻäťĽç¨ä¸ä¸ŞĺŽćĽćčż°ă??
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     
    );

    //çćĺ¤éĄšĺźX^16+X^12+X^5+1
    //čžĺĽčžĺşçżťč˝ŹďźçťćĺźćFFFF

    //ä¸?个ĺ­čä¸ä¸Şĺ­čç§ťĺ?
    parameter idle = 0;
    parameter start = 1;
    parameter shift = 2;
    parameter turn = 3;
    parameter finish = 4;

    reg [2:0]state;
    reg [2:0]next_state;

    reg [7:0] byte_data;
    reg [BYTE_CNT:0]byte_count;
    reg [CMD_WITH * 8 -1 :0] temp_cmd;

    reg [15:0] LSFR;
    reg [15:0] LSFR_S;



    reg [CMD_WITH * 8 -1 :0] cmd_crc_temp;
    reg reg_data_vaild0;
    reg reg_data_vaild1;
    wire posedge_data_vaild;

    reg [BYTE_CNT:0]cmd_cnt_temp;

    assign posedge_data_vaild = reg_data_vaild0 & ~ reg_data_vaild1;
    always @(posedge clk_system or negedge rstn) begin
        if(!rstn)begin
            reg_data_vaild0 <= 1'd0;
            reg_data_vaild1 <= 1'd0;
        end
        else begin
            reg_data_vaild0 <= data_vaild;
            reg_data_vaild1 <= reg_data_vaild0;
        end
    end

    //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


    //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

    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
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crystal(mercy)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值