1 |
2 |
DavidRAMBA |
--=============================================================================
|
2 |
|
|
-- TITRE : CRC16
|
3 |
|
|
-- DESCRIPTION :
|
4 |
|
|
-- Calcule le CRC16 à partir du polynome poly
|
5 |
|
|
-- La donnée entrante est traitée LSB first
|
6 |
|
|
-- Le CRC est initilisaé à 0xFFFF
|
7 |
|
|
-- Le CRC est complémenté à 1 et les 2 octets sont swappés
|
8 |
|
|
-- FICHIER : crc16.vhd
|
9 |
|
|
--=============================================================================
|
10 |
|
|
-- CREATION
|
11 |
|
|
-- DATE AUTEUR PROJET REVISION
|
12 |
|
|
-- 10/04/2014 DRA SATURN V1.0
|
13 |
|
|
--=============================================================================
|
14 |
|
|
-- HISTORIQUE DES MODIFICATIONS :
|
15 |
|
|
-- DATE AUTEUR PROJET REVISION
|
16 |
|
|
--=============================================================================
|
17 |
|
|
|
18 |
|
|
LIBRARY IEEE;
|
19 |
|
|
USE IEEE.STD_LOGIC_1164.ALL;
|
20 |
|
|
USE IEEE.STD_LOGIC_ARITH.ALL;
|
21 |
|
|
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
|
22 |
|
|
|
23 |
|
|
ENTITY crc16 IS
|
24 |
|
|
GENERIC (
|
25 |
|
|
poly : STD_LOGIC_VECTOR(15 downto 0) := x"1021" -- CCITT16 par défaut
|
26 |
|
|
);
|
27 |
|
|
PORT (
|
28 |
|
|
-- Ports système
|
29 |
|
|
clk_sys : IN STD_LOGIC; -- Clock système
|
30 |
|
|
rst_n : IN STD_LOGIC; -- Reset général système
|
31 |
|
|
|
32 |
|
|
-- Interfaces d'entrée
|
33 |
|
|
data : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Donnée transmise ou reçue (LSB first)
|
34 |
|
|
val : IN STD_LOGIC; -- validant du bus data
|
35 |
|
|
init : IN STD_LOGIC; -- Initialise le caclul du CRC
|
36 |
|
|
|
37 |
|
|
-- Résultat
|
38 |
|
|
crc : OUT STD_LOGIC_VECTOR(15 downto 0)-- Résultat du calcul
|
39 |
|
|
);
|
40 |
|
|
END crc16;
|
41 |
|
|
|
42 |
|
|
ARCHITECTURE rtl of crc16 is
|
43 |
|
|
SIGNAL shifter : STD_LOGIC_VECTOR(15 downto 0); -- DFF pour le calcul du CRC
|
44 |
|
|
|
45 |
|
|
BEGIN
|
46 |
|
|
--------------------------------------------
|
47 |
|
|
-- Détection des fronts montants et descendants sur rx1
|
48 |
|
|
--------------------------------------------
|
49 |
|
|
inst_crc : PROCESS(clk_sys, rst_n)
|
50 |
|
|
VARIABLE shift_temp : STD_LOGIC_VECTOR(15 downto 0); -- shifter temporaire pour traiter les 8 bits
|
51 |
|
|
VARIABLE mask : STD_LOGIC; -- Pour le XOR d'un bit de data avec CRC(15)
|
52 |
|
|
BEGIN
|
53 |
|
|
IF (rst_n = '0') THEN
|
54 |
|
|
shifter <= (others => '1');
|
55 |
|
|
ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
|
56 |
|
|
IF (init = '1') THEN
|
57 |
|
|
shifter <= (others => '1'); -- Le shifter est initialisé à FFFF (ISO 3309)
|
58 |
|
|
ELSIF (val = '1') THEN
|
59 |
|
|
-- Pour chaque octet reçu
|
60 |
|
|
shift_temp := shifter; -- Le shifter temp est initialisé avec le CRC courant
|
61 |
|
|
blc_bit : FOR i IN 0 to 7 LOOP -- On traite tous les bits un par un LSB first
|
62 |
|
|
mask := shift_temp(15) XOR data(i); -- Calcul de la valeur de feedback
|
63 |
|
|
-- Shift du CRC avec mise à jour en fonction du polynome
|
64 |
|
|
shift_temp := (shift_temp(14 downto 0) & '0') XOR
|
65 |
|
|
(poly AND SXT(mask & mask, 16));
|
66 |
|
|
END LOOP;
|
67 |
|
|
shifter <= shift_temp; -- Après traitement des 8 bits, maj du CRC
|
68 |
|
|
END IF;
|
69 |
|
|
END IF;
|
70 |
|
|
END PROCESS;
|
71 |
|
|
|
72 |
|
|
blc_form : FOR i IN 0 to 7 GENERATE
|
73 |
|
|
BEGIN
|
74 |
|
|
-- remise en forme du CRC pour assurer que x^15 est transmis en premier
|
75 |
|
|
crc(15-i) <= NOT(shifter(i + 8)); -- complément à 2 selon ISO 3309
|
76 |
|
|
crc(7-i) <= NOT(shifter(i));
|
77 |
|
|
END GENERATE;
|
78 |
|
|
|
79 |
|
|
END rtl;
|
80 |
|
|
|