精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

用Verilog實現CRC-8的串行計算

FPGA自習室 ? 來源:FPGA自習室 ? 作者:FPGA自習室 ? 2021-03-12 17:47 ? 次閱讀

(2021樂鑫科技數字IC提前批代碼編程

Verilog實現CRC-8的串行計算,G(D)=D8+D2+D+1,計算流程如下圖所示:

一、分析

CRC循環冗余校驗碼(Cyclic Redundancy Check),檢錯碼。

(1)該題目所述為CRC-8,即輸出8位CRC校驗值,給定一段長為N-bit的有效輸入序列,輸出(N+8)-bit的數據,其中前N-bit數據為輸入的原始數據,添加的8-bit數據為CRC校驗數據;

(2)該CRC-8的生成多項式為G(D)=D8+D2+D+1,對CRC進行簡化表示時可以忽略最高位的D8,結合圖示中三個異或運算的位置更容易理解生成多項式,8位CRC有8個寄存器C0~C7,根據多項式,C0、C1和C2的輸入是由異或運算而來;

二、Verilog編程

1. 并行計算,串行輸出

對于輸入位寬為1的輸入,這種方法的計算非常簡單,直接根據生成多項式運算。

(注意!如果輸入位寬不為1,則需要根據多項式進行化簡,可以使用http://outputlogic.com/?page_id=321生成運算邏輯和代碼)

1.1 自己一步一步寫

完整工程代碼在【FPGA探索者】公眾號回復【CRC】獲取。

(1)先定義8個寄存器reg [7:0]

reg [7:0] crc_reg_q;// 寄存器 Q 輸出端reg [7:0] crc_reg_d;// 寄存器 D 輸入端

(對crc_reg_d,使用always賦值就定義成reg,使用assign就定義成wire)

(2)異或計算

寄存器0的輸入crc_reg_d[0],來自寄存器7的輸出crc_reg_q[7]和數據輸入data_in異或運算,即:

crc_reg_d [0] = crc_reg_q[7] ^ data_in;

同理可得:

always @ (*)begin crc_reg_d[0] = crc_reg_q[7] ^ data_in;crc_reg_d[1] = crc_reg_q[7] ^ data_in ^ crc_reg_q[0];crc_reg_d[2] = crc_reg_q[7] ^ data_in ^ crc_reg_q[1];crc_reg_d[3] = crc_reg_q[2];crc_reg_d[4] = crc_reg_q[3];crc_reg_d[5] = crc_reg_q[4];crc_reg_d[6] = crc_reg_q[5];crc_reg_d[7] = crc_reg_q[6];end

上述使用組合邏輯實現異或運算和數據的傳遞,另外,對于每個寄存器的輸入到輸出(D端到Q端),使用時序邏輯,并且按照題目要求,設置初始值為全1,將數據有效標志作為控制邏輯:

always @ (posedge clk)beginif(rst) crc_reg_q <= 8’hff; elsebegin if(data_valid ) crc_reg_q<= crc_reg_d;// 輸入數據有效就更新值else crc_reg_q<= crc_reg_q;// 輸入數據無效就等待 endend

(3)串行輸出

上述已經實現了并行的 CRC,計算出的 CRC 結果就是直接的 8 位 CRC,按照題目要求,需要串行輸出 CRC 結果。

思路:寫一個計數器,當需要輸出 CRC 時,串行計數輸出,實現并串轉換。這里,由于題目給了一個信號 crc_start,我把這個信號作為 CRC 的標志,當 data_valid 有效時表示輸入的是數據,當 data_valid 無效且crc_start 有效表示數據輸入完畢,該輸出 CRC 了。

reg [2:0] count;always @ (posedge clk)begin if(rst)begin crc_out <= 0; count<= 0; end elsebegin if(data_valid) begin crc_out <= data_in; crc_valid <= 1'b0; end elseif(crc_start)begin count <= count + 1'b1; crc_out <= crc_reg_q [7-count]; crc_valid <= 1'b1; end elsebegin crc_valid <= 1'b0; end endend

完整工程代碼在【FPGA探索者】公眾號回復【CRC】獲取。

1.2 CRC Generator自動生成

在Step1中,根據要求,1處表示輸入數據位寬為1,2處CRC輸出8位,3處選擇自定義CRC的多項式,4處點擊運用設定,然后進入Step2。

根據生成多項式,勾選1、X1、X2即可(對應1+D1+D2,最高位的D8不用管)。

//-----------------------------------------------------------------------------// Copyright (C) 2009 OutputLogic.com // This source file may be used and distributedwithout restriction // provided that this copyright statement is notremoved from the file // and that any derivative work contains theoriginal copyright notice // and the associated disclaimer. // // THIS SOURCE FILE IS PROVIDED "ASIS" AND WITHOUT ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, WITHOUTLIMITATION, THE IMPLIED // WARRANTIES OF MERCHANTIBILITY AND FITNESS FORA PARTICULAR PURPOSE. //-----------------------------------------------------------------------------// CRC module for data[0:0] , crc[7:0]=1+x^1+x^2+x^8;//-----------------------------------------------------------------------------module crc( input [0:0] data_in, input crc_en, output [7:0] crc_out, input rst, input clk); reg [7:0] lfsr_q,lfsr_c; assign crc_out = lfsr_q; always @(*) begin lfsr_c[0] = lfsr_q[7] ^ data_in[0]; lfsr_c[1] = lfsr_q[0] ^ lfsr_q[7]^ data_in[0]; lfsr_c[2] = lfsr_q[1] ^ lfsr_q[7]^ data_in[0]; lfsr_c[3] = lfsr_q[2]; lfsr_c[4] = lfsr_q[3]; lfsr_c[5] = lfsr_q[4]; lfsr_c[6] = lfsr_q[5]; lfsr_c[7] = lfsr_q[6]; end // always always @(posedge clk, posedge rst) begin if(rst) begin lfsr_q <= {8{1'b1}}; end else begin lfsr_q <= crc_en ? lfsr_c: lfsr_q; end end // alwaysendmodule // crc

將上述代碼按照題目要求改變輸入輸出的名稱,并進行串并轉換(并->串)即可。

1.3 easics自動生成

https://www.easics.com/crctool

(1)1處選擇CRC的生成多項式,這里與1.2的不同在于,要把最高位的D8選上,easics能識別的CRC協議更多;

(2)2處自動識別出這個CRC多項式其實是CRC8 ATM HEC協議使用的 CRC;

(3)3處設置輸入數據位寬為1;

(4)選擇生成Verilog代碼;

(5)下載代碼。

仔細閱讀代碼注釋,注意!

convention: the first serial bit is D[0]

數據的最低位先輸出,此代碼將會把低位作為異或移出位,而上面已經提到的兩種方法均是將最高位作為移出位去異或,所以,代碼中需要稍作修改,將d[0]改成d[7],d[1]改成d[6],…,以此類推,c[0]- c[7]不要變。

有興趣的可以去看看【大小端問題】,在不同處理器、不同協議中非常常見。

///////////////////////////////////////////////////////////////////////////////// Copyright (C) 1999-2008 Easics NV.// This source file may be used and distributedwithout restriction// provided that this copyright statement is notremoved from the file// and that any derivative work contains theoriginal copyright notice// and the associated disclaimer.//// THIS SOURCE FILE IS PROVIDED "AS IS"AND WITHOUT ANY EXPRESS// OR IMPLIED WARRANTIES, INCLUDING, WITHOUTLIMITATION, THE IMPLIED// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR APARTICULAR PURPOSE.//// Purpose : synthesizable CRC function// *polynomial: x^8 + x^2 + x^1 + 1// * datawidth: 1//// Info : tools@easics.be// http://www.easics.com///////////////////////////////////////////////////////////////////////////////module CRC8_D1; //polynomial: x^8 + x^2 + x^1 + 1 // datawidth: 1 //convention: the first serial bit is D[0] function[7:0] nextCRC8_D1; inputData; input[7:0] crc; reg [0:0]d; reg [7:0]c; reg [7:0]newcrc; begin d[0] =Data; c = crc; newcrc[0]= d[0] ^ c[7]; newcrc[1]= d[0] ^ c[0] ^ c[7]; newcrc[2]= d[0] ^ c[1] ^ c[7]; newcrc[3]= c[2]; newcrc[4]= c[3]; newcrc[5]= c[4]; newcrc[6]= c[5]; newcrc[7]= c[6]; nextCRC8_D1 = newcrc; end endfunctionendmodule

2. 串行計算,串行輸出(函數function用法)

CRC計算的重要思想是不斷的消除最高位。

(1)新建函數function

Verilog函數名為next_crc,輸入信號為 data_in 和 current_crc,輸出信號為8位的新 crc。

函數功能為:根據輸入信號data_in,跳轉CRC的狀態;

函數的設計邏輯為:

(a)將CRC寄存器的數據左移1位,低位補零,得到

{current_crc[6:0],1'b0} (其中{ }為位拼接符);

(b)新輸入的數據data_in和移出的CRC最高位做異或得到

current_crc[7]^data_in;

(c)使用位拼接符對異或結果進行位擴展,CRC-8進行8位的擴展,得到

{8{current_crc[7]^data_in}};

(d)擴展后的數據和生成多項式進行與運算,得到

{8{current_crc[7]^data_in}}&(8'h07);

(e)將(a)的數據和(d)的數據進行異或運算,得到CRC結果;

next_crc = {current_crc[6:0],1'b0} ^({8{current_crc[7]^data_in}} & (8'h07));

上述,(a)是對CRC低位的處理,(b)-(d)是對CRC最高位的處理。

8’h07從何而來?

因為生成多項式G(D) = D8+D2+D1+D0,前面提到了最高位的D8不用管,那么使用8位去表示為0000_0111,即低3位為1,其余為0,即8’h07。

function [7:0] next_crc; inputdata_in; input[7:0] current_crc; begin next_crc = {current_crc[6:0],1'b0} ^ ({8{current_crc[7]^data_in}} &(8'h07)); end endfunction

(2)調用function函數

初始化時給寄存器賦值全為1,當數據有效時,進行CRC計算。

reg [7:0] crc_reg;always @ (posedge clk)begin if(rst)begin crc_reg <= 8'hff; end elsebegin if(data_valid) begin crc_reg <= next_crc(data_in, crc_reg); end endend

(3)串行輸出(串并轉換)

按照上面的老方法,串并轉換(并->串)。

完整工程代碼在【FPGA探索者】公眾號回復【CRC】獲取。

輸入32個1,先輸出輸入的32個1,緊跟著輸出32個1的CRC校驗值8’b00001111。

三、原理圖設計

使用Quartus原理圖設計,調用DFF觸發器和XOR異或門搭建題目所示的CRC邏輯。

這里沒有做data_valid的控制,輸入數據是連續的32個1,輸入完成后的CRC值是8’h0f,串行輸出8位二進制數據 8’b00001111。

四、擴展

1. 并行計算并行輸出

(1)對于單bit輸入的序列,只要將并行計算串行輸出的串并轉換去掉,直接輸出8-bit的CRC校驗值即可;

(2)對于多bit同時輸入的序列,通過介紹的兩個在線平臺去生成運算邏輯(筆試肯定不會喪心病狂到考多bit并行);

2. 查表法

實際工程中,為了減少運算量,還經常使用一種查表法,將CRC的校驗表直接存儲在ROM中,進行索引查找,常見的CRC表可以自行去查找,這里只是拋磚引玉。

責任編輯:lq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1626

    文章

    21671

    瀏覽量

    601902
  • crc
    crc
    +關注

    關注

    0

    文章

    199

    瀏覽量

    29438
  • Verilog
    +關注

    關注

    28

    文章

    1345

    瀏覽量

    109988

原文標題:FPGA手撕代碼——CRC校驗碼的多種Verilog實現方式

文章出處:【微信號:FPGA_Study,微信公眾號:FPGA自習室】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    使用MSP430 MCU實現CRC

    電子發燒友網站提供《使用MSP430 MCU實現CRC.pdf》資料免費下載
    發表于 10-23 10:19 ?0次下載
    使用MSP430 MCU<b class='flag-5'>實現</b><b class='flag-5'>CRC</b>

    TAS5805內部的硬件CRC8對應標準的哪種? CRC校驗的數據是offset和value值嗎?

    TAS5805 內部的硬件 CRC8 對應標準的哪種? CRC 校驗的數據是 offset 和 value 值嗎? PPC 加載文件計算出來的值和在線
    發表于 10-12 06:19

    CRC實施

    電子發燒友網站提供《CRC實施.pdf》資料免費下載
    發表于 09-26 09:44 ?0次下載
    <b class='flag-5'>CRC</b>實施

    如何計算BMHD中的逆CRC值?

    我想知道如何計算 BMHD 中的逆 CRC 值。 以Ifx_Ssw.h中的示例為例 Ifx_Ssw_Bmhd結構的頭文件和手冊。 /** BMHD 的結構定義 * 根據 BMI 和起始地址計算
    發表于 05-31 06:43

    matlab與FPGA數字信號處理系列 Verilog 實現并行 FIR 濾波器

    Verilog 共計有 8 次乘法,但是其中有 2 個乘法的乘數是常數 0,所以 Vivado 只綜合出 6 個乘法器; 與串行的對比,下圖為串行 FIR 濾波器的 RTL 圖:
    發表于 05-24 07:48

    使用C語言實現CRC計算單元的例子

    使用C語言實現CRC計算單元的例子
    的頭像 發表于 05-16 16:16 ?860次閱讀

    這個CRC計算單元是如何基于固定的生成多項式(0x4C11DB7)來獲取給定數據緩沖區的CRC碼的?

    這個CRC計算單元是如何基于固定的生成多項式(0x4C11DB7)來獲取給定數據緩沖區的CRC碼的?
    的頭像 發表于 05-16 16:06 ?737次閱讀

    STM32L05x的CRC模塊做modbus CRC16計算,結果不正確是為什么?

    根據參考文檔,CRC模塊可以配置CRC多項式,應該可以做(Modbus)CRC16計算,自己試了一下,發現結果不正確,總是一個固定值,不知道為什么?另外多項式應該是0x8005還是0x
    發表于 04-29 06:50

    8b10b編碼verilog實現

    8b/10b編碼是一種用于減少數據線上的低效能時鐘信號傳輸的技術,通過在數據流中插入特殊的控制字符,來同步數據和時鐘。在Verilog實現8b/10b編碼器可以通過以下步驟完成: 定
    發表于 03-26 07:55

    verilog語音實現浮點運算

    Verilog可以通過使用IEEE標準的浮點數表示來實現浮點運算。下面是一個基本的Verilog模塊示例,展示了如何進行加法、乘法和除法等常見的浮點運算操作: module
    發表于 03-25 21:49

    RA MCU中的CRC模塊和使用方法

    瑞薩RA單片機硬件CRC計算單元采用固定的多項式發生器來計算8位或者32位數據的CRC校驗值,對數據傳輸或數據存儲的一致性、完整性進行驗證。
    發表于 02-26 11:45 ?845次閱讀
    RA MCU中的<b class='flag-5'>CRC</b>模塊和使用方法

    verilog中for循環是串行執行還是并行執行

    的for循環也是并行執行的。 Verilog中的for循環可以用來實現重復的操作,例如在一個時鐘周期中對多個電路進行操作。在循環內部,多個語句可以同時執行,而不受循環次數的限制。這種并行執行的機制使得Verilog在硬件設計中非
    的頭像 發表于 02-22 16:06 ?2716次閱讀

    怎么emac實現Verilog自動連線呢?

    我們在編寫一些比較復雜的Verilog代碼時,通常需要進行大量的手動連線工作,這種工作十分容易出錯,并且在代碼模塊的嵌套層級較多時,更改里層的一個代碼
    的頭像 發表于 01-24 10:03 ?1230次閱讀

    fpga報告crc故障是什么意思

    方法,通過對發送的數據進行計算并附加到數據末尾,接收方能夠使用相同的校驗算法來檢測傳輸中的錯誤。CRC可以檢測多種不同類型的錯
    的頭像 發表于 01-04 11:06 ?1327次閱讀

    虹科技術|保障數據傳輸穩定性:BabyLIN產品的CRC算法實現

    文章將以CRC8校驗為例,介紹在BabyLIN產品中如何使用CRC校驗算法。 CRC校驗原理 在CAN報文中,增加Checksum校驗,能夠用來檢測和校驗數據傳輸或保存后可能出現的錯誤。它是利用除法及余數的原理來作錯誤偵測的。
    的頭像 發表于 01-02 10:45 ?465次閱讀
    虹科技術|保障數據傳輸穩定性:BabyLIN產品的<b class='flag-5'>CRC</b>算法<b class='flag-5'>實現</b>