CRC 4 Bit to CRC 8 - Bit

Discussion in 'Embedded Systems and Microcontrollers' started by Bpick, Apr 25, 2018.

  1. Bpick

    Thread Starter New Member

    Apr 25, 2018
    1
    0
    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;
     
  2. WBahn

    Moderator

    Mar 31, 2012
    22,865
    6,829
    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?
     
    BobaMosfet likes this.
  3. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,191
    1,444
    Google is your friend.
     
  4. BobaMosfet

    Senior Member

    Jul 1, 2009
    333
    72
    flow chart; hand test; prove your algorithm on paper, first. create tables, it's far faster.
     
  5. mlv

    New Member

    Nov 6, 2017
    17
    4
    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"
     
Loading...