Перейти к содержанию
    

Вычисление 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;

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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

свою функцию-монстра мне пришлось сделать для обмена данными с компом через RS-232

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

кхм, может быть я чего не догоняю

 

// Description   : 
//  generate HEC for payload headers. 
//  G(x) = x16 + x12 + x5 + 1, see ITU-T G.7041 Generic framing procedure (GFP)

module gfp_crc16 (
  clk     ,
  reset   , 
  sclr    , 
  ena     , 
  init    , 
  ibyte   , 
  crc     
  ); 

  //
  //
  //

  input wire clk   ;
  input wire reset ;
  input wire sclr  ;
   
  input wire ena   ; 
  input wire init  ;

  input wire   [7:0]  ibyte;
  output logic [15:0] crc  ;
  
  //
  //
  // 

  wire [15:0] crc_load_value = init ? 16'h0 : crc; 

  always_ff @(posedge clk or posedge reset) begin : crc_register 
    if (reset)
      crc <= 16'h0;
    else if (sclr)
      crc <= 16'h0;
    else if (ena)
      crc <= Crc16(crc_load_value, ibyte);
  end

  //
  //
  //

  function bit [15:0] Crc16x1 (input bit [15:0] crc, input bit d); 
    bit         msb;
    bit [15:0]  crc_next;
  begin     
    msb       = crc[15];
    crc_next  = crc << 1;
    
    crc_next[0]  = d ^ msb;
    crc_next[5]  = d ^ msb ^ crc[4];
    crc_next[12] = d ^ msb ^ crc[11];
    
    return crc_next;     
  end 
  endfunction   

  //
  //
  //

  function bit [15:0] Crc16(input bit [15:0] crc, input bit [7:0] data);
    bit [15:0] crc_next;  
    int i;
  begin
    crc_next = crc;  
    for (i = 8; i > 0; i--) begin
      crc_next = Crc16x1 (crc_next, data[i-1]);  
    end 
    
    return crc_next;    
  end 
  endfunction

  //
  //
  //
endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как-то нецелесообразно использовать табличное вычисление в программируемой логике.

 

А вот посмотрите как красива аппаратная реализация алгоритма:

CRC8-gen.gif

 

http://en.wikipedia.org/wiki/Computation_of_CRC

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

там я был, только не понятно как пользоваца сгенеренной функцией
Сильно :)

 

Функция nextCRC16_D8(Data,CRC)

 

Data - входной байт данных

 

CRC - Текущее состояние регистра-накопителя CRC

 

Возвращает новое состояние для регистра-накопителя CRC

 

 

signal CRC : STD_LOGIC_VECTOR (15 downto 0) := x"FFFF";


CRC_counter : process (clk,reset_CRC)
begin
if reset_CRC = '1' then
CRC <= x"FFFF";
elsif clk'event and clk='1' and SLD = '1' then
CRC <= nextCRC16_D8(data,CRC);

end if;

end process CRC_counter;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нетабличная реализация, к сожалению, на AHDL, но логику работы проследить можно.

 

-- CRC16.TDF

-- Fast CRC16 real-time algorithm for 16 bit data stream with (16,12,5,0) polinom and FFFFh initial value

-- AHDL

INCLUDE "lpm_ff.inc";

SUBDESIGN CRC16

( INIT : input; -- вход инициализации. Активный уровень - низкий

DATA[15..0] : input; -- входные данные

DCLK : input; -- сигнал тактирования входных данных

CLKEN : input; -- разрешение тактирования

Q[15..0] : output; -- выходные данные

)

VARIABLE

regD, regI : lpm_ff WITH ( -- входной регистр regD и результата обработки предыдущего числа regI

LPM_FFTYPE = "DFF",

LPM_TYPE = "LPM_FF",

LPM_WIDTH = 16);

regV[15..0][15..0] : node; -- виртуальные образы промежуточных состояний разрядов на каждом сдвиге входного числа [сдвиг][разряд]

regH : node; -- признак предистории обработки (есть/нет)

BEGIN

DEFAULTS

regV[][] = H"FFFF"; -- константа инициализации

END DEFAULTS;

-- вспомогательный регистр начальной инициализации, не позволяет внутреннему регистру обработки предыдущего числа совершить запись по спаду DCLK

regH = DFF(VCC, DCLK, INIT, VCC);

-- Описание входного регистра

regD.aclr = not(INIT); -- обнуляем регистры по низкому уровню INIT

regD.clock = DCLK; -- защёлкиваем данные по положительному фронту DCLK

regD.enable = CLKEN; -- вход разрешения

regD.data[] = DATA[]; -- входные данные

-- Перебираем промежуточные состояния (16 сдвигов на 1 разряд влево с новым числом)

-- 0-ое состояние

-- 0-ой бит

regV[0][0] = regD.q[15] XOR regI.q[15]; -- для 0-го используем обратную связь и старший бит новых данных

-- с 1-го по 4-ый

for j0_1_4 in 1 to 4 generate

regV[0][j0_1_4] = regI.q[j0_1_4-1]; -- сдвигаем на 1 позицию влево

end generate;

-- 5-ый бит

regV[0][5] = regI.q[4] XOR regI.q[15]; -- для 5-го ОС и 4-ый

-- с 6-го по 11-ый

for j0_6_11 in 6 to 11 generate

regV[0][j0_6_11] = regI.q[j0_6_11-1]; -- сдвигаем на 1 позицию влево

end generate;

-- 12-ый бит

regV[0][12] = regI.q[11] XOR regI.q[15]; -- для 12-го ОС и 11-ый

-- c 13-го по 15-ый

for j0_13_15 in 13 to 15 generate

regV[0][j0_13_15] = regI.q[j0_13_15-1]; -- сдвигаем на 1 позицию влево

end generate;

-- с 1-го по 15-ое промежуточные состояния

for j in 1 to 15 generate

-- 0-ой бит j-го состояния

regV[j][0] = regD.q[15-j] XOR regV[j-1][15]; -- для 0-го используем обратную связь и старший бит новых данных

-- с 1-го по 4-ый

for i1_4 in 1 to 4 generate

regV[j][i1_4] = regV[j-1][i1_4-1]; -- сдвигаем на 1 позицию влево

end generate;

-- 5-ый бит

regV[j][5] = regV[j-1][4] XOR regV[j-1][15]; -- для 5-го ОС и 4-ый

-- с 6-го по 11-ый

for i6_11 in 6 to 11 generate

regV[j][i6_11] = regV[j-1][i6_11-1]; -- сдвигаем на 1 позицию влево

end generate;

-- 12-ый

regV[j][12] = regV[j-1][11] XOR regV[j-1][15]; -- для 12-го ОС и 11-ый

-- с 13-го по 15-ый

for i13_15 in 13 to 15 generate

regV[j][i13_15] = regV[j-1][i13_15-1]; -- сдвигаем на 1 позицию влево

end generate;

end generate;

-- Описание внутреннего регистра захвата результата от предыдущего слова данных

regI.aset = not(INIT); -- устанавка начального значения низким уровнем INIT

regI.enable = regH & CLKEN; -- разрешение на захват предшествующего состояния

regI.clock = not(DCLK); -- защёлкивается по отрицательному фронту DCLK

regI.data[] = regV[15][]; -- заводим данные 15-го (последнего) состояния

-- Описание выхода модуля

Q[] = regV[15][];

END;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все это не катит.

Ознакомтесь с документом XAPP 209.

Главная фишка в том, что при расчете CRC базовый регистр одновременно устанавливается в начальное состояние, что позволяет налету обрабатывать фреймы. Одновременно это и генератор, и чеккер со сравнением по волшебному слову с регистровыми выходами.

Причем можно скачать уже говый проект.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все это не катит.

Ознакомтесь с документом 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помогите перевести на VHDL, моя попытка увенчалась не удачей. Код взят из XAPP 209. К сожалению я Verilg не владею.

 

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

 

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

Первые два блока переведете наверняка сами, что там такого - ресет да инит... :)

 

По поводу двух последних - фигурные скобки в Verilog - это операция "сборки" слова из "кусочков", то есть:

crc_reg <= {crc_reg[7:0], 8'h00}; - в словесном описании: "взять младшие восемь бит crc_reg, справа к ним добавить восемь нулевых бит и полученное записать в crc_reg". Фактически - сдвиг влево на восемь бит с заполнением нулями.

crc - это сборка 8-ми битного слова из отдельных бит crc_reg.

~ - логическое "НЕ".

 

Как записать это на VHDL - не знаю, но уверен, что справитесь теперь. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Первые два блока переведете наверняка сами, что там такого - ресет да инит... :)

 

По поводу двух последних - фигурные скобки в Verilog - это операция "сборки" слова из "кусочков", то есть:

crc_reg <= {crc_reg[7:0], 8'h00}; - в словесном описании: "взять младшие восемь бит crc_reg, справа к ним добавить восемь нулевых бит и полученное записать в crc_reg". Фактически - сдвиг влево на восемь бит с заполнением нулями.

crc - это сборка 8-ми битного слова из отдельных бит crc_reg.

~ - логическое "НЕ".

 

Как записать это на VHDL - не знаю, но уверен, что справитесь теперь. :)

 

Спасибо!

 

Этот блок не содержит описания FSM, а просто if else, я так понимаю? и как понимать например

 

if (reset) begin с чем сравнивается?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо!

 

Этот блок не содержит описания FSM, а просто if else, я так понимаю? и как понимать например

 

if (reset) begin с чем сравнивается?

 

Да. Циничная загрузка регистров с обнулением по ресету (синхронному) и иниту (асинхронному)

 

С лог."1" сигнала reset

 

if (~reset) - с лог."0"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо ReedCat! :a14:

 

 

выкладываю код на VHDL, который является переводом с Verilog в коде есть комментарий(стоят вопросительные знаки -- код который я не смог перевести) Это касается строки

 

crc_reg <= {crc_reg[7:0], 8'h00}

 

Прошу проверить и исправить. Выложенный код даже синтезируется :)

 

Но синтезатор пишет

 

Width mismatch. <crc> has a width of 8 bits but assigned expression is 9-bit wide.

 

Т.е. где-то не совпадение размеров шин

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity crc_modul is
    Port ( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
           crc_reg_out : out  STD_LOGIC_VECTOR (15 downto 0);
           crc_out : out  STD_LOGIC_VECTOR (7 downto 0);
           calc : in  STD_LOGIC;
           init : in  STD_LOGIC;
           d_valid : in  STD_LOGIC;
           d : in  STD_LOGIC_VECTOR (7 downto 0));
end crc_modul;

architecture Behavioral of crc_modul is

signal crc_reg : STD_LOGIC_VECTOR (15 downto 0);
signal crc : STD_LOGIC_VECTOR (7 downto 0);
signal next_crc : STD_LOGIC_VECTOR (15 downto 0);

begin

process ( clk,  rst)

begin
if rst = '1' then 
crc_reg <= (others => '0'); 
crc <= (others => '0'); 

elsif (clk'event and clk = '1') then
if init = '1'  then
crc_reg <= (others => '0'); 
crc <= (others => '0'); 
end if;

if (calc and d_valid) = '1'  then
crc_reg <= next_crc;
crc <= not (next_crc(15 downto 8));
end if;

if (not(calc) and d_valid) = '1'  then
--crc_reg <= ????;
crc <= not (next_crc(8 downto 0));

end if;
end if; 
crc_reg_out <= crc_reg;
crc_out <= crc;
end process;

next_crc(0) <= d(4) xor d(0) xor crc_reg(13) xor crc_reg(9) xor d(5) xor d(1) xor crc_reg(14) xor crc_reg(10) xor d(6) xor d(2) xor crc_reg(15) xor crc_reg(11) xor d(7) xor d(3) xor crc_reg(12) xor crc_reg(8);
next_crc(1) <= d(4) xor d(0) xor crc_reg(13) xor crc_reg(9) xor d(5) xor d(1) xor crc_reg(14) xor crc_reg(10) xor d(6) xor d(2) xor crc_reg(15) xor crc_reg(11) xor d(3) xor crc_reg(12);
next_crc(2) <= crc_reg(9) xor d(6) xor d(7) xor crc_reg(8);
next_crc(3) <= crc_reg(9) xor d(5) xor crc_reg(10) xor d(6);
next_crc(4) <= d(4) xor d(5) xor crc_reg(10) xor crc_reg(11);
next_crc(5) <= d(4) xor crc_reg(11) xor crc_reg(12) xor d(3);
next_crc(6) <= crc_reg(12) xor crc_reg(13) xor d(2) xor d(3);
next_crc(7) <= crc_reg(13) xor d(1) xor crc_reg(14) xor d(2);
next_crc(8) <= d(0) xor d(1) xor crc_reg(14) xor crc_reg(15) xor crc_reg(0);
next_crc(9) <= d(0) xor crc_reg(15) xor crc_reg(1);
next_crc(10) <= crc_reg(2);
next_crc(11) <= crc_reg(3);
next_crc(12) <= crc_reg(4);
next_crc(13) <= crc_reg(5);
next_crc(14) <= crc_reg(6);
next_crc(15) <= d(4) xor crc_reg(9) xor d(5) xor crc_reg(10) xor d(6) xor crc_reg(11) xor d(7) xor crc_reg(12) xor d(0) xor crc_reg(13) xor d(1) xor crc_reg(14) xor d(2) xor crc_reg(15) xor crc_reg(7) xor d(3) xor crc_reg(8);

end Behavioral;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наверно так:

process ( clk, rst)

begin

if rst = '1' then

crc_reg <= (others => '0');

crc <= (others => '0');

elsif (clk'event and clk = '1') then

if init = '1' then

crc_reg <= (others => '0');

crc <= (others => '0');

elsif (calc and d_valid) = '1' then

crc_reg <= next_crc;

crc <= not(next_crc(8 downto 8) & next_crc(9 downto 9) & next_crc(10 downto 10) & next_crc(11 downto 11)

& next_crc(12 downto 12) & next_crc(13 downto 13) & next_crc(14 downto 14) & next_crc(15 downto 15));

elsif (not(calc) and d_valid) = '1' then

crc_reg <= crc_reg(7 downto 0) & "00000000";

crc <= not(crc_reg(0 downto 0) & crc_reg(1 downto 1) & crc_reg(2 downto 2) & crc_reg(3 downto 3)

& crc_reg(4 downto 4) & crc_reg(5 downto 5) & crc_reg(6 downto 6) & crc_reg(7 downto 7));

end if;

end if;

 

end process;

 

crc_reg_out <= crc_reg;

crc_out <= crc;

 

next_crc(0) <=

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но синтезатор пишет

 

Width mismatch. <crc> has a width of 8 bits but assigned expression is 9-bit wide.

 

Т.е. где-то не совпадение размеров шин

 

if (not(calc) and d_valid) = '1'  then
--crc_reg <= ????;
crc <= not (next_crc(8 downto 0));

Ну вы уже совсем.

 

Без комментариев.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...