реклама на сайте
подробности

 
 
> CRC16 VHDL, реализация CRC16 для Spartan3
cornflyer
сообщение May 6 2008, 06:17
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 166
Регистрация: 11-07-06
Из: Dubna
Пользователь №: 18 729



Вычисление CRC16 для 8-битного массива:
на порт data последовательно выставляюца 8-битные данные массива
и даеца строб SLD
после обработки всего массива считываеца порт crc16_out - там лежит CRC16
после этого подаеца строб сброса reset_CRC
теперь можно снова повторить процедуру вычисления CRC16

// С код:
const unsigned int crc16_Table [256]=
{
0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040
} ;
unsigned short calc_CRC(char *buf, unsigned short len)
{
unsigned short i;
unsigned short crc_data;
unsigned short CRC=0xFFFF;

for(i=0;i<len;i++)
{
crc_data = CRC^buf[i];
CRC=(CRC>>8)^crc16_Table[crc_data&0x00FF];
}
CRC=(CRC>>8)|(CRC<<8);
return CRC ;
}





-- VHDL код:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;


-- ================================================================================
=======
-- ================================================================================
=======
-- ================================================================================
=======


entity crc is port(
data : in STD_LOGIC_VECTOR (7 downto 0) ;
crc16_out : out STD_LOGIC_VECTOR (15 downto 0) ;
reset_CRC : in STD_LOGIC ;
SLD : in STD_LOGIC ;
----------------------------------------------
clk : in std_logic
);
end crc;


-- ================================================================================
=======
-- ================================================================================
=======
-- ================================================================================
=======


architecture crc of crc is
signal crc_data : STD_LOGIC_VECTOR (15 downto 0) := (others=>'0') ;
signal CRC : STD_LOGIC_VECTOR (15 downto 0) := x"FFFF" ;
--------------------------------------------------------
signal DO : STD_LOGIC_VECTOR (15 downto 0) := (others=>'0') ;
signal ADDR : STD_LOGIC_VECTOR (9 downto 0) := (others=>'0') ;
--------------------------------------------------------
type FSM is (
s0,s1,s2,s3,s4
);
signal state : FSM := s0 ;
--------------------------
signal crc16_out_buf : STD_LOGIC_VECTOR (15 downto 0) := (others=>'0') ;
begin


crc16_out <= crc16_out_buf ;

-- ================================================================================
=======
-- ================================================================================
=======
-- ================================================================================
=======

CRC_counter : process (clk,reset_CRC)
begin
if reset_CRC = '1' then
CRC <= x"FFFF" ;
state <= s0 ;
elsif clk'event and clk='0' then
case state is
when s0 =>
if SLD = '1' then
state <= s1 ;
end if ;
when s1 =>
crc_data <= CRC XOR ("00000000" & data) ;
state <= s2 ;
when s2 =>
ADDR <= crc_data AND (x"00FF") ;
state <= s3 ;
when s3 =>
CRC <= ("00000000" & CRC(15 downto 8)) XOR DO ;
state <= s4 ;
when s4 =>
crc16_out_buf <= ( "00000000" & CRC(15 downto 8)) OR (CRC(7 downto 0) & "00000000") ;
state <= s0 ;
when others => state <= s0 ;
end case ;
end if ;
end process CRC_counter ;


-- ================================================================================
=======
-- ================================================================================
=======
-- ================================================================================
=======


crc_Table : RAMB16_S18
generic map (
--INIT => X"00000", -- Value of output RAM registers at startup
--SRVAL => X"00000", -- Ouput value upon SSR assertion
WRITE_MODE => "READ_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE
-- The following INIT_xx declarations specify the intial contents of the RAM
-- Address 0 to 255
INIT_00 => X"0440C481C5C10500C741078006C0C601C241028003C0C3010140C181C0C10000",
INIT_01 => X"C841088009C0C9010B40CB81CAC10A000E40CE81CFC10F00CD410D800CC0CC01",
INIT_02 => X"DC411C801DC0DD011F40DF81DEC11E001A40DA81DBC11B00D941198018C0D801",
INIT_03 => X"1040D081D1C11100D341138012C0D201D641168017C0D7011540D581D4C11400",
INIT_04 => X"F441348035C0F5013740F781F6C136003240F281F3C13300F141318030C0F001",
INIT_05 => X"3840F881F9C13900FB413B803AC0FA01FE413E803FC0FF013D40FD81FCC13C00",
INIT_06 => X"2C40EC81EDC12D00EF412F802EC0EE01EA412A802BC0EB012940E981E8C12800",
INIT_07 => X"E041208021C0E1012340E381E2C122002640E681E7C12700E541258024C0E401",
INIT_08 => X"A441648065C0A5016740A781A6C166006240A281A3C16300A141618060C0A001",
INIT_09 => X"6840A881A9C16900AB416B806AC0AA01AE416E806FC0AF016D40AD81ACC16C00",
INIT_0A => X"7C40BC81BDC17D00BF417F807EC0BE01BA417A807BC0BB017940B981B8C17800",
INIT_0B => X"B041708071C0B1017340B381B2C172007640B681B7C17700B541758074C0B401",
INIT_0C => X"5440948195C155009741578056C096019241528053C093015140918190C15000",
INIT_0D => X"9841588059C099015B409B819AC15A005E409E819FC15F009D415D805CC09C01",
INIT_0E => X"8C414C804DC08D014F408F818EC14E004A408A818BC14B008941498048C08801",
INIT_0F => X"4040808181C141008341438042C082018641468047C087014540858184C14400")
port map (
DO => DO, -- 16-bit Data Output
ADDR => ADDR, -- 10-bit Address Input
CLK => clk, -- Clock
DI => (others=>'0'), -- 16-bit Data Input
DIP => (others=>'0'), -- 2-bit parity Input
EN => '1', -- RAM Enable Input
SSR => '0', -- Synchronous Set/Reset Input
WE => '0' -- Write Enable Input
);


-- ================================================================================
=======
-- ================================================================================
=======
-- ================================================================================
=======


end crc;
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sazh
сообщение May 7 2008, 07:01
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 435
Регистрация: 6-10-04
Из: Петербург
Пользователь №: 804



Все это не катит.
Ознакомтесь с документом XAPP 209.
Главная фишка в том, что при расчете CRC базовый регистр одновременно устанавливается в начальное состояние, что позволяет налету обрабатывать фреймы. Одновременно это и генератор, и чеккер со сравнением по волшебному слову с регистровыми выходами.
Причем можно скачать уже говый проект.
Go to the top of the page
 
+Quote Post
Maverick
сообщение May 8 2008, 07:37
Сообщение #3


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(sazh @ May 7 2008, 10:01) *
Все это не катит.
Ознакомтесь с документом XAPP 209.
Главная фишка в том, что при расчете CRC базовый регистр одновременно устанавливается в начальное состояние, что позволяет налету обрабатывать фреймы. Одновременно это и генератор, и чеккер со сравнением по волшебному слову с регистровыми выходами.
Причем можно скачать уже говый проект.


Помогите перевести на VHDL, моя попытка увенчалась не удачей. Код взят из XAPP 209. К сожалению я Verilg не владею.
Код
//////////////////////////////////////////////////////////////////////////////
//
// crc calculation
// This VERILOG code was generated using CRCGEN.PL version 1.7
// Last Modified: 01/02/2002
// Options Used:
//    Module Name = crc32
//      CRC Width = 16
//     Data Width = 8
//     CRC Init   = 0
//     Polynomial = [0 -> 16]
//        1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
//
// Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
//             WHATSOEVER AND XILINX SPECIFICALLY DISCLAIMS ANY
//             IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
//             A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
//
// Copyright (c) 2001,2002 Xilinx, Inc.  All rights reserved.
//
//
//////////////////////////////////////////////////////////////////////////////

module crc32 (
   crc_reg,
   crc,
   d,
   calc,
   init,
   d_valid,
   clk,
   reset
   );

output [15:0] crc_reg;
output [7:0]  crc;

input  [7:0]  d;
input         calc;
input         init;
input         d_valid;
input         clk;
input         reset;

reg    [15:0] crc_reg;
reg    [7:0]  crc;

//////////////////////////////////////////////////////////////////////////////
// Internal Signals
//////////////////////////////////////////////////////////////////////////////
wire   [15:0] next_crc;

//////////////////////////////////////////////////////////////////////////////
// Infer CRC-16 registers
//
// The crc_reg register stores the CRC-16 value.
// The crc register is the most significant 8 bits of the
// CRC-16 value.
//
// Truth Table:
// -----+---------+----------+----------------------------------------------
// calc | d_valid | crc_reg  | crc
// -----+---------+----------+----------------------------------------------
//  0   |     0   | crc_reg  | crc
//  0   |     1   |  shift   | bit-swapped, complimented msbyte of crc_reg
//  1   |     0   | crc_reg  | crc
//  1   |     1   | next_crc | bit-swapped, complimented msbyte of next_crc
// -----+---------+----------+----------------------------------------------
//
//////////////////////////////////////////////////////////////////////////////

always @ (posedge clk or posedge reset)
begin
   if (reset) begin
      crc_reg <= 16'h0000;
      crc     <= 8'h00;
   end
  
   else if (init) begin
      crc_reg <= 16'h0000;
      crc     <=  8'h00;
   end

   else if (calc & d_valid) begin
      crc_reg <= next_crc;
      crc     <= ~{next_crc[8], next_crc[9], next_crc[10], next_crc[11],
                   next_crc[12], next_crc[13], next_crc[14], next_crc[15]};
   end
  
   else if (~calc & d_valid) begin
      crc_reg <=  {crc_reg[7:0], 8'h00};
      crc     <= ~{crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3],
                   crc_reg[4], crc_reg[5], crc_reg[6], crc_reg[7]};
   end
end

//////////////////////////////////////////////////////////////////////////////
// CRC XOR equations
//////////////////////////////////////////////////////////////////////////////

assign next_crc[0] = d[4] ^ d[0] ^ crc_reg[13] ^ crc_reg[9] ^ d[5] ^ d[1] ^ crc_reg[14] ^ crc_reg[10] ^ d[6] ^ d[2] ^ crc_reg[15] ^ crc_reg[11] ^ d[7] ^ d[3] ^ crc_reg[12] ^ crc_reg[8];
assign next_crc[1] = d[4] ^ d[0] ^ crc_reg[13] ^ crc_reg[9] ^ d[5] ^ d[1] ^ crc_reg[14] ^ crc_reg[10] ^ d[6] ^ d[2] ^ crc_reg[15] ^ crc_reg[11] ^ d[3] ^ crc_reg[12];
assign next_crc[2] = crc_reg[9] ^ d[6] ^ d[7] ^ crc_reg[8];
assign next_crc[3] = crc_reg[9] ^ d[5] ^ crc_reg[10] ^ d[6];
assign next_crc[4] = d[4] ^ d[5] ^ crc_reg[10] ^ crc_reg[11];
assign next_crc[5] = d[4] ^ crc_reg[11] ^ crc_reg[12] ^ d[3];
assign next_crc[6] = crc_reg[12] ^ crc_reg[13] ^ d[2] ^ d[3];
assign next_crc[7] = crc_reg[13] ^ d[1] ^ crc_reg[14] ^ d[2];
assign next_crc[8] = d[0] ^ d[1] ^ crc_reg[14] ^ crc_reg[15] ^ crc_reg[0];
assign next_crc[9] = d[0] ^ crc_reg[15] ^ crc_reg[1];
assign next_crc[10] = crc_reg[2];
assign next_crc[11] = crc_reg[3];
assign next_crc[12] = crc_reg[4];
assign next_crc[13] = crc_reg[5];
assign next_crc[14] = crc_reg[6];
assign next_crc[15] = d[4] ^ crc_reg[9] ^ d[5] ^ crc_reg[10] ^ d[6] ^ crc_reg[11] ^ d[7] ^ crc_reg[12] ^ d[0] ^ crc_reg[13] ^ d[1] ^ crc_reg[14] ^ d[2] ^ crc_reg[15] ^ crc_reg[7] ^ d[3] ^ crc_reg[8];
endmodule


В приложении сам XAPP 209

в основном интересует коректный перевод только куска программы, остальное понятно

Код
always @ (posedge clk or posedge reset)
begin
   if (reset) begin
      crc_reg <= 16'h0000;
      crc     <= 8'h00;
   end
  
   else if (init) begin
      crc_reg <= 16'h0000;
      crc     <=  8'h00;
   end

   else if (calc & d_valid) begin
      crc_reg <= next_crc;
      crc     <= ~{next_crc[8], next_crc[9], next_crc[10], next_crc[11],
                   next_crc[12], next_crc[13], next_crc[14], next_crc[15]};
   end
  
   else if (~calc & d_valid) begin
      crc_reg <=  {crc_reg[7:0], 8'h00};
      crc     <= ~{crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3],
                   crc_reg[4], crc_reg[5], crc_reg[6], crc_reg[7]};
   end
end


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- cornflyer   CRC16 VHDL   May 6 2008, 06:17
- - vmp   А здесь вы были?   May 6 2008, 06:32
- - cornflyer   там я был, только не понятно как пользоваца сгенер...   May 6 2008, 06:40
|- - XVR   Цитата(cornflyer @ May 6 2008, 10:40) там...   May 6 2008, 08:05
- - des00   кхм, может быть я чего не догоняю Код// Descript...   May 6 2008, 07:54
- - rimpocha   Как-то нецелесообразно использовать табличное вычи...   May 6 2008, 07:57
- - Евгений Николаев   Нетабличная реализация, к сожалению, на AHDL, но л...   May 7 2008, 06:21
|- - ReedCat   Цитата(Maverick @ May 8 2008, 11:37) Помо...   May 8 2008, 09:05
|- - Maverick   Цитата(ReedCat @ May 8 2008, 12:05) Первы...   May 8 2008, 09:12
|- - ReedCat   Цитата(Maverick @ May 8 2008, 13:12) Спас...   May 8 2008, 09:31
|- - Maverick   спасибо ReedCat! выкладываю код на VHDL, ...   May 8 2008, 10:17
- - sazh   Наверно так: process ( clk, rst) begin if rst = ...   May 8 2008, 17:03
- - dvladim   Цитата(Maverick @ May 8 2008, 14:17) Но с...   May 9 2008, 17:28
- - Maverick   Цитата(dvladim @ May 9 2008, 20:28) Ну вы...   May 10 2008, 05:59


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 09:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016