CRC 4 Bit to CRC 8 - Bit

Thread Starter

Bpick

Joined Apr 25, 2018
1
Hey guys im trying to turn this CRC 4 bit to an 8 bit however despite the modifications ive made it keeps giving me an 8 bit number which is correct but its the wrong actual number i also need 2 numbers to be displayed when i check the file. any help would be appreciated thanks!

CRC - 4 Bit

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity crc4_16b is
port ( clk : in std_logic;
data_in1 : in std_logic_vector(15 downto 0);
data_in1_ready : in std_logic;
crcout1 : out std_logic_vector(3 downto 0);
crcout1_valid : out std_logic);
end crc4_16b;

architecture Behavioral of crc4_16b is

signal crc_temp : std_logic_vector(3 downto 0) := "0000";
signal counter : std_logic_vector(4 downto 0):="00000";
signal crc_ready : std_logic;

begin

process(clk)
begin
--CRC Generator Polynomial = X^4 + X + 1.
if(clk'event and clk='1' and data_in1_ready='1') then
if (counter="00000") then
crc_temp(0) <= data_in1(15);
crc_temp(3 downto 1) <= "000";
else if (counter < "10000") then
crc_temp(0) <= data_in1(to_integer(15-unsigned(counter))) xor crc_temp(3);
else
crc_temp(0) <= crc_temp(3);
end if;

crc_temp(1) <= crc_temp(3) xor crc_temp(0);
crc_temp(2) <= crc_temp(1);
crc_temp(3) <= crc_temp(2);
end if;

crcout1_valid <= '0';
counter <= counter + '1';
if(crc_ready ='1') then
crcout1 <= crc_temp;
crcout1_valid<= '1';
crc_ready <= '0';
else if (counter ="10011") then
counter <= "00000";
crc_ready <= '1';
end if;
end if;


end if;

end process;

end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity crc4_20b is
port ( clk : in std_logic;
data_in2 : in std_logic_vector(19 downto 0);
data_in2_ready : in std_logic;
crcout2 : out std_logic_vector(3 downto 0);
crcout2_valid : out std_logic);
end crc4_20b;

architecture Behavioral of crc4_20b is

signal crc_temp : std_logic_vector(3 downto 0) := "0000";
signal counter : std_logic_vector(4 downto 0):="00000";
signal crc_ready : std_logic;

begin

process(clk, data_in2)
begin
if(clk'event and clk='1' and data_in2_ready='1') then
if (counter="00000") then
crc_temp(0) <= data_in2(19);
crc_temp(3 downto 1) <= "000";
else
crc_temp(0) <= data_in2(to_integer(19-unsigned(counter))) xor crc_temp(3);
crc_temp(1) <= crc_temp(3) xor crc_temp(0);
crc_temp(2) <= crc_temp(1);
crc_temp(3) <= crc_temp(2);
end if;

crcout2_valid <= '0';
counter <= counter + '1';
if(crc_ready ='1') then
crcout2 <= crc_temp;
crcout2_valid<= '1';
crc_ready <= '0';
else if (counter ="10011") then
counter <= "00000";
crc_ready <= '1';
end if;
end if;

end if;

end process;

end Behavioral;


MODIFICATIONS IVE MADE


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity crc8_16b is
port ( clk : in std_logic;
data_in1 : in std_logic_vector(15 downto 0);
data_in1_ready : in std_logic;
crcout1 : out std_logic_vector(7 downto 0);
crcout1_valid : out std_logic);
end crc8_16b;

architecture Behavioral of crc8_16b is

signal crc_temp : std_logic_vector(7 downto 0) := "00000000";
signal counter : std_logic_vector(4 downto 0):="00000";
signal crc_ready : std_logic;

begin

process(clk)
begin

if(clk'event and clk='1' and data_in1_ready='1') then
if (counter="000000000") then
crc_temp(0) <= data_in1(15);
crc_temp(7 downto 1) <= "0000000";
else if (counter < "10000") then
crc_temp(0) <= data_in1(to_integer(15 -unsigned(counter))) xor crc_temp(7);
else
crc_temp(0) <= crc_temp(7);
end if;

crc_temp(0) <= crc_temp(7) xor crc_temp(0);
crc_temp(1) <= crc_temp(7) xor crc_temp(1);
crc_temp(3) <= crc_temp(2);
crc_temp(4) <= crc_temp(3);
crc_temp(5) <= crc_temp(4);
crc_temp(6) <= crc_temp(5);
crc_temp(7) <= crc_temp(6);
end if;

crcout1_valid <= '0';
counter <= counter + '1';
if(crc_ready ='1') then
crcout1 <= crc_temp;
crcout1_valid<= '1';
crc_ready <= '0';
else if (counter ="100000111") then
counter <= "00000";
crc_ready <= '1';
end if;
end if;


end if;

end process;

end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity crc8_24b is
port ( clk : in std_logic;
data_in2 : in std_logic_vector(23 downto 0);
data_in2_ready : in std_logic;
crcout2 : out std_logic_vector(7 downto 0);
crcout2_valid : out std_logic);
end crc8_24b;

architecture Behavioral of crc8_24b is

signal crc_temp : std_logic_vector(7 downto 0) := "00000000";
signal counter : std_logic_vector(8 downto 0):="000000000";
signal crc_ready : std_logic;

begin

process(clk, data_in2)
begin
if(clk'event and clk='1' and data_in2_ready='1') then
if (counter="00000") then
crc_temp(0) <= data_in2(23);
crc_temp(7 downto 1) <= "0000000";
else
crc_temp(0) <= data_in2(to_integer(23-unsigned(counter))) xor crc_temp(3);
crc_temp(1) <= crc_temp(7) xor crc_temp(0);
crc_temp(2) <= crc_temp(7) xor crc_temp(0);
crc_temp(3) <= crc_temp(2);
crc_temp(4) <= crc_temp(3);
crc_temp(5) <= crc_temp(4);
crc_temp(6) <= crc_temp(5);
crc_temp(7) <= crc_temp(6);
end if;

crcout2_valid <= '0';
counter <= counter + '1';
if(crc_ready ='1') then
crcout2 <= crc_temp;
crcout2_valid<= '1';
crc_ready <= '0';
else if (counter ="10111") then
counter <= "000000000";
crc_ready <= '1';
end if;
end if;

end if;

end process;

end Behavioral;


TEST BENCH PROVIDED



library ieee;
use ieee.std_logic_1164.all;
use STD.textio.all;
use ieee.std_logic_textio.all;

-------------------------------------
-- EE2441 Test Bench --
-------------------------------------

entity crc_tb is
end crc_tb;

architecture tb_arch of crc_tb is
-- Component declaration of the UUT
component crc8_16b -- for transmitter
port(clk : in std_logic;
data_in1 : in std_logic_vector(15 downto 0);
data_in1_ready : in std_logic;
crcout1 : out std_logic_vector(7 downto 0);
crcout1_valid : out std_logic);
end component;

component crc8_24b -- for receiver
port(clk : in std_logic;
data_in2 : in std_logic_vector(23 downto 0);
data_in2_ready : in std_logic;
crcout2 : out std_logic_vector(7 downto 0);
crcout2_valid : out std_logic);

end component;

-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal data_in1 : std_logic_vector(15 downto 0);
signal data_in2 : std_logic_vector(23 downto 0);

-- Observed signals - signals mapped to the output ports of tested entity
signal crcout1 : std_logic_vector(7 downto 0);
signal crcout2 : std_logic_vector(7 downto 0);

signal clk : std_logic := '1'; -- initialize
signal data_in1_ready : std_logic := '0';
signal data_in2_ready : std_logic := '0';
signal crcout1_valid : std_logic := '0';
signal crcout2_valid : std_logic := '0';

constant NUM_SIM_CYCLES : integer := 110;

file VEC_OUT1_FILE : TEXT open WRITE_MODE is "CRCOUT1.txt";
file VEC_OUT2_FILE : TEXT open WRITE_MODE is "CRCOUT2.txt";

begin

-- Unit Under Test port map
UUT1 : crc8_16b port map (clk, data_in1, data_in1_ready, crcout1, crcout1_valid);
UUT2 : crc8_24b port map (clk, data_in2, data_in2_ready, crcout2, crcout2_valid);

STIMULUS: process

variable VEC_OUT1_LINE : line;
variable VEC_OUT2_LINE : line;
variable counter : integer :=0 ;

begin

for i in 1 to NUM_SIM_CYCLES loop
clk <= not clk;
wait for 5 ns;
clk <= not clk;
wait for 5 ns; -- clock period = 10 ns

case i is
when 3 => data_in1_ready <= '1'; data_in2_ready <= '1';
-- data_in_valid signals arer persistent '1' (not toggle)
-- each input data remains unchanged for duration of 24 clock cycles and then changes to new data

-- test vectors
data_in1 <= "1000001100000001"; -- 0x8301 -> crcout1 = 0x8E = 10001110
data_in2 <= "100110000011000001101010"; -- 0x98306a -> crcout2 = 0xb3 = 10110011

when 27 => data_in1 <= "1111111111111111"; -- 0xffff -> crcout1 = 0x24 = 00100100
data_in2 <= "111000100110000110101011"; -- 0xe261ab -> crcout2 = 0xe2 = 11100010

when 51 => data_in1 <= "0111101000001001"; -- 0x7a09 -> crcout1 = 0x1f = 00011111
data_in2 <= "010011110011000100101010"; -- 0x4f312a -> crcout2 = 0x25 = 00100101

when 75 => data_in1 <= "1100110100101011"; -- 0xcd2b -> crcout1 = 0xd5 = 11010101
data_in2 <= "100010001001000111111111"; -- 0x8891ff -> crcout2 = 0x1f = 00011111

when others =>

end case;

if(crcout1_valid='1') then -- crcout1_valid should be toggle (0->1->0), not persistent '1'
write(VEC_OUT1_LINE, crcout1);
writeline(VEC_OUT1_FILE, VEC_OUT1_LINE);
end if;

if(crcout2_valid='1') then -- crcout2_valid should be toggle (0->1->0), not persistent '1'
write(VEC_OUT2_LINE, crcout2);
writeline(VEC_OUT2_FILE, VEC_OUT2_LINE);
end if;
end loop;
file_close(VEC_OUT1_FILE);
file_close(VEC_OUT2_FILE);

wait;
end process;

end tb_arch;
 

WBahn

Joined Mar 31, 2012
32,847
You REALLY expect someone to wade through that much essentially undocumented code to figure something out?

You can't narrow it down at all?

What does it mean for an 8-bit number to be correct but be the wrong actual number???

Have you worked any examples by hand to see that your intended algorithm actually produces the correct result?

Have you walked your hand example through the code to see where the code's results start differing from your hand calculations?
 

mlv

Joined Nov 6, 2017
17
I'm not an HDL designer, but I dig into HW code from time to time. I see a few things to double-check regarding syntax. I'm not sure whether these are issues or not (the first is simply a side note):

1. it would be good to be explicit about what 8th order generator polynomial you're using - give a comment like is done for the 4th order gen poly
2. in the crc8_16b block:
- counter is a 5-bit value but your check is against a nine bit literal ("000000000")
- when checking the end of the loop, I think you only need to add 4 additional cycles compared to the 4 bit version, but you're comparing to the literal "100000111" (versus "10011" for 4 bit) - shouldn't this be "10111" for the 8 bit case?
3. in the crc8_24b block:
- counter is a 9 bit value but compared to a 5 bit literal ("00000")
- this time, the end of the loop looks like it's done correctly - up to "10111"
 
Top