Hallo Liebe Mikrocontroller.net-Leser Ich schreibe im Moment für einen CPLD eine SPI-GPIO-Erweiterung. Da die Daten die über den SPI-Bus übertragen werden sehr wichtig sind wird eine CRC Checksumme über die gesendeten Daten gebildet und ebenfalls über den SPI-Bus übertragen. Das Format der Übertragung sieht folgendermaßen aus: Telegramm 1 Checksumme über Telegramm 1 Telegramm 2 Checksumme über Telegramm 2 Da der Mikrocontroller (Master) lediglich ein 8 Bit breiten TX-Buffer für das SPI-Modul besitzt ist die Aufteilung in 4 Übertragungen a 8 Bit notwendig. Ich habe als Generatorpolynom folgendes ausgewählt: x^8+x^4+x^3+x^2+1 (==> somit ist die Checksumme ebenfalls 8 Bit breit) Ich habe mir das ganze mal manuell durchgerechnet. Als verwendetes Testdatenmuster habe ich 0xA3 (0b10100011) verwendet: 1010 0011 0000 0000 : 1 0001 1101 1000 1110 1 0010 1101 100 10 0011 101 00 1110 0010 0 1000 1110 1 0110 1100 10 100 0111 01 010 1011 110 10 0011 101 00 1000 0110 Somit habe ich als Rest 0x86. Auf der Seite http://zorc.breitbandkatze.de/crc.html habe ich das ganze verifizieren wollen. Da komme ich aber auf folgende Werte: Eingestellte Parameter: CRC-Order: 8 / CRC-Polynom: 1D / Initialwert FF / Final XOR value:00 Reverse Data Bytes 0 Final XOR value 0 Result: 8A Eingestellte Parameter: CRC-Order: 8 / CRC-Polynom: 1D / Initialwert FF / Final XOR value:00 Reverse Data Bytes 0 Final XOR value 1 Result: 51 Eingestellte Parameter: CRC-Order: 8 / CRC-Polynom: 1D / Initialwert FF / Final XOR value:00 Reverse Data Bytes 1 Final XOR value 0 Result: B9 Eingestellte Parameter: CRC-Order: 8 / CRC-Polynom: 1D / Initialwert FF / Final XOR value:00 Reverse Data Bytes 1 Final XOR value 1 Result: 9D Meine Testbench liefert mir als Ergebnis 0x42. Als Testbench habe ich folgenden Code:
1 | -- Testbench
|
2 | |
3 | library ieee; |
4 | use ieee.std_logic_1164.all; |
5 | use ieee.std_logic_arith.all; |
6 | use ieee.std_logic_unsigned.all; |
7 | use ieee.numeric_std.all; |
8 | |
9 | |
10 | -- Leere entity
|
11 | entity mein_DUT_tb is |
12 | generic ( |
13 | gDatenlaenge : integer :=8; |
14 | gCRCLaenge : integer :=8); |
15 | |
16 | end entity mein_DUT_tb ; |
17 | |
18 | architecture Verhalten of mein_DUT_tb is |
19 | |
20 | -- Moduldeklaration
|
21 | COMPONENT crc |
22 | port ( |
23 | data_in : in std_logic_vector (gDatenlaenge - 1 downto 0); |
24 | crc_en : in std_logic; |
25 | rst : in std_logic; |
26 | clk : in std_logic; |
27 | crc_out : out std_logic_vector (gCRCLaenge - 1 downto 0)); |
28 | end component; |
29 | |
30 | signal data_in : std_logic_vector (gDatenlaenge - 1 downto 0):= (others =>'0'); |
31 | signal crc_en : std_logic :='0'; |
32 | signal rst : std_logic :='0'; |
33 | signal clk : std_logic :='0'; |
34 | signal crc_out : std_logic_vector (gCRCLaenge - 1 downto 0):= (others =>'0'); |
35 | |
36 | procedure Testdaten_anlegen |
37 | (
|
38 | signal crc_en : out std_logic; |
39 | signal rst : out std_logic |
40 | ) is |
41 | |
42 | begin
|
43 | --wait until rising_edge(clk);
|
44 | crc_en<= '1'; |
45 | wait until rising_edge(clk); |
46 | wait until rising_edge(clk); |
47 | crc_en<= '0'; |
48 | rst<='1'; |
49 | wait until rising_edge(clk); |
50 | rst<='0'; |
51 | wait until rising_edge(clk); |
52 | |
53 | end Testdaten_anlegen ; |
54 | --0000010110001100
|
55 | |
56 | |
57 | begin
|
58 | clk <= not clk after 20 ns; -- 25 MHz Taktfrequenz |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | CRC_berechnen: process |
65 | begin
|
66 | rst <= '1'; |
67 | wait until rising_edge(clk); |
68 | rst <= '0'; |
69 | wait until rising_edge(clk); |
70 | |
71 | |
72 | data_in <= conv_std_logic_vector((163),gDatenlaenge); Testdaten_anlegen (crc_en => crc_en, rst => rst); |
73 | |
74 | |
75 | for I in 0 to 255 loop |
76 | data_in <= conv_std_logic_vector((I),gDatenlaenge); Testdaten_anlegen (crc_en => crc_en, rst => rst); |
77 | end loop; |
78 | |
79 | wait until rising_edge(clk); |
80 | crc_en<= '1'; |
81 | wait until rising_edge(clk); |
82 | crc_en<= '0'; |
83 | wait until rising_edge(clk); |
84 | |
85 | |
86 | |
87 | end process; |
88 | |
89 | |
90 | -- Modulinstatziierung
|
91 | mein_dut : crc |
92 | port map ( |
93 | data_in => data_in, |
94 | crc_en => crc_en, |
95 | rst => rst, |
96 | clk => clk, |
97 | crc_out => crc_out |
98 | );
|
99 | |
100 | end architecture; |
Als DUT habe ich folgenden generierten Code von http://outputlogic.com/?page_id=321 eingefügt
1 | -------------------------------------------------------------------------------
|
2 | -- Link zum Generieren des Files: http://outputlogic.com/?page_id=321
|
3 | -------------------------------------------------------------------------------
|
4 | -------------------------------------------------------------------------------
|
5 | -- Ports
|
6 | -- data_in : Paralleler Eingang der Daten
|
7 | -- crc_en : Startsignal
|
8 | -- rst : Reset
|
9 | -- clk : CLK-Signal
|
10 | -- crc_out : Paralleler Ausgang an dem die berechnete CRC bereitgestellt wird
|
11 | |
12 | |
13 | -------------------------------------------------------------------------------
|
14 | -- Copyright (C) 2009 OutputLogic.com
|
15 | -- This source file may be used and distributed without restriction
|
16 | -- provided that this copyright statement is not removed from the file
|
17 | -- and that any derivative work contains the original copyright notice
|
18 | -- and the associated disclaimer.
|
19 | --
|
20 | -- THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
|
21 | -- OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
22 | -- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
23 | -------------------------------------------------------------------------------
|
24 | -- CRC module for data(7:0)
|
25 | -- lfsr(7:0)=1+x^2+x^3+x^4+x^8;
|
26 | -------------------------------------------------------------------------------
|
27 | library ieee; |
28 | use ieee.std_logic_1164.all; |
29 | |
30 | entity crc is |
31 | port ( data_in : in std_logic_vector (7 downto 0); |
32 | crc_en , rst, clk : in std_logic; |
33 | crc_out : out std_logic_vector (7 downto 0)); |
34 | end crc; |
35 | |
36 | architecture imp_crc of crc is |
37 | signal lfsr_q: std_logic_vector (7 downto 0); |
38 | signal lfsr_c: std_logic_vector (7 downto 0); |
39 | begin
|
40 | crc_out <= lfsr_q; |
41 | |
42 | lfsr_c(0) <= lfsr_q(0) xor lfsr_q(4) xor lfsr_q(5) xor lfsr_q(6) xor data_in(0) xor data_in(4) xor data_in(5) xor data_in(6); |
43 | lfsr_c(1) <= lfsr_q(1) xor lfsr_q(5) xor lfsr_q(6) xor lfsr_q(7) xor data_in(1) xor data_in(5) xor data_in(6) xor data_in(7); |
44 | lfsr_c(2) <= lfsr_q(0) xor lfsr_q(2) xor lfsr_q(4) xor lfsr_q(5) xor lfsr_q(7) xor data_in(0) xor data_in(2) xor data_in(4) xor data_in(5) xor data_in(7); |
45 | lfsr_c(3) <= lfsr_q(0) xor lfsr_q(1) xor lfsr_q(3) xor lfsr_q(4) xor data_in(0) xor data_in(1) xor data_in(3) xor data_in(4); |
46 | lfsr_c(4) <= lfsr_q(0) xor lfsr_q(1) xor lfsr_q(2) xor lfsr_q(6) xor data_in(0) xor data_in(1) xor data_in(2) xor data_in(6); |
47 | lfsr_c(5) <= lfsr_q(1) xor lfsr_q(2) xor lfsr_q(3) xor lfsr_q(7) xor data_in(1) xor data_in(2) xor data_in(3) xor data_in(7); |
48 | lfsr_c(6) <= lfsr_q(2) xor lfsr_q(3) xor lfsr_q(4) xor data_in(2) xor data_in(3) xor data_in(4); |
49 | lfsr_c(7) <= lfsr_q(3) xor lfsr_q(4) xor lfsr_q(5) xor data_in(3) xor data_in(4) xor data_in(5); |
50 | |
51 | |
52 | process (clk,rst) begin |
53 | if (rst = '1') then |
54 | lfsr_q <= b"11111111"; |
55 | elsif (clk'EVENT and clk = '1') then |
56 | if (crc_en = '1') then |
57 | lfsr_q <= lfsr_c; |
58 | end if; |
59 | end if; |
60 | end process; |
61 | end architecture imp_crc; |
Wenn mir da vielleicht jemand einen Tipp geben kann wo der Fehler liegt wäre ich sehr dankbar. Viele Grüße Martin