Commit 99a2de7e authored by Ille, Ondrej, Ing.'s avatar Ille, Ondrej, Ing.

Separated CRC to generic CRC entity

parent ea331edc
......@@ -48,7 +48,7 @@
-- enable signal appears. The output CRC is valid then. CRC stays valid until
-- following 0 to 1 enable transition. This also erases CRC registers.
--
-- Refer to CAN 2.0 or CAN FD Specification for CRC calculation algorythm --
-- Refer to CAN 2.0 or CAN FD Specification for CRC calculation algorithm
--------------------------------------------------------------------------------
-- Revision History:
-- June 2015 Created file
......@@ -60,6 +60,7 @@
-- and crc21 polynomial.
-- 13.7.2018 Replaced "crc15_nxt", "crc17_nxt", "crc21_nxt" by
-- signals instead of variable inside process.
-- 15.11.2018 Replaced hard-coded CRC calculation with generic CRC entity.
--------------------------------------------------------------------------------
Library ieee;
......@@ -67,6 +68,7 @@ USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.ALL;
use work.CANconstants.all;
use work.CAN_FD_register_map.all;
use work.CANcomponents.all;
entity canCRC is
......@@ -109,179 +111,93 @@ entity canCRC is
signal crc15 :out std_logic_vector(14 downto 0);
signal crc17 :out std_logic_vector(16 downto 0);
signal crc21 :out std_logic_vector(20 downto 0)
);
----------------------------------------------------------------------------
-- Internal registers
----------------------------------------------------------------------------
signal crc15_reg : std_logic_vector(14 downto 0);
signal crc17_reg : std_logic_vector(16 downto 0);
signal crc21_reg : std_logic_vector(20 downto 0);
-- Holds previous value of enable input. Detects 0 to 1 transition
signal start_reg : std_logic;
-- ISO CAN FD or NON ISO CAN FD Value
signal drv_fd_type : std_logic;
-- Combinational signals for next value of CRC
signal crc15_nxt : std_logic;
signal crc17_nxt : std_logic;
signal crc21_nxt : std_logic;
);
end entity;
architecture rtl of canCRC is
begin
crc15 <= crc15_reg;
crc17 <= crc17_reg;
crc21 <= crc21_reg;
drv_fd_type <= drv_bus(DRV_FD_TYPE_INDEX);
----------------------------------------------------------------------------
-- Calculation of next CRC bit
----------------------------------------------------------------------------
crc15_nxt <= data_in xor crc15_reg(14);
crc17_nxt <= data_in xor crc17_reg(16);
crc21_nxt <= data_in xor crc21_reg(20);
----------------------------------------------------------------------------
-- Registering previous value of enable input to detec 0 to 1 transition
----------------------------------------------------------------------------
start_reg_proc : process(res_n, clk_sys)
begin
if (res_n = '0') then
start_reg <= '0';
elsif rising_edge(clk_sys) then
start_reg <= enable;
end if;
end process start_reg_proc;
----------------------------------------------------------------------------
-- Calculation of CRC15 value
----------------------------------------------------------------------------
crc15_cycle : process(res_n, clk_sys)
begin
if (res_n = ACT_RESET) then
crc15_reg <= (OTHERS => '0');
elsif rising_edge(clk_sys) then
-- Erase the CRC value at the begining of calculation
if (start_reg = '0' and enable = '1') then
crc15_reg <= (OTHERS => '0');
else
-- Calculate the next value when triggered
if (enable = '1' and trig = '1') then
------------------------------------------------------------
-- CRC calculation
------------------------------------------------------------
-- Shift and xor with polynomial
if (crc15_nxt = '1') then
crc15_reg <= (crc15_reg(13 downto 0) & '0') xor
crc15_pol(14 downto 0);
-- Only shift bits
else
crc15_reg <= crc15_reg(13 downto 0) & '0';
end if;
else
crc15_reg <= crc15_reg;
end if;
end if;
end if;
end process crc15_cycle;
-- ISO CAN FD or NON ISO CAN FD Value
signal drv_fd_type : std_logic;
-- Initialization vectors
signal init_vect_15 : std_logic_vector(14 downto 0);
signal init_vect_17 : std_logic_vector(16 downto 0);
signal init_vect_21 : std_logic_vector(20 downto 0);
----------------------------------------------------------------------------
-- Calculation of CRC17 value
----------------------------------------------------------------------------
crc17_cycle : process(res_n, clk_sys)
begin
if (res_n = '0') then
crc17_reg <= (OTHERS => '0');
crc17_reg(16) <= '1';
elsif rising_edge(clk_sys) then
begin
-- Erase the CRC value at the begining of calculation
if (start_reg = '0' and enable = '1') then
crc17_reg <= (OTHERS => '0');
-- ISO vs NON-ISO FD for selection of initialization vectors of 17 and 21.
drv_fd_type <= drv_bus(DRV_FD_TYPE_INDEX);
if (drv_fd_type = ISO_FD) then
crc17_reg(16) <= '1';
end if;
-- For CRC 15 Init vector is constant zeroes
init_vect_15 <= (OTHERS => '0');
else
-- Calculate the next value only when triggered
if (enable = '1'and trig = '1') then
-- For CRC 17 and 21, Init vector depends on ISO/NON-ISO type
init_vect_17(16) <= '1' when (drv_fd_type = ISO_FD)
else
'0';
init_vect_17(15 downto 0) <= (OTHERS => '0');
------------------------------------------------------------
-- CRC calculation
------------------------------------------------------------
-- Shift and xor
if (crc17_nxt = '1') then
crc17_reg <= (crc17_reg(15 downto 0) & '0') xor
crc17_pol(16 downto 0);
-- Only shift bits
else
crc17_reg <= crc17_reg(15 downto 0) & '0';
end if;
else
crc17_reg <= crc17_reg;
end if;
end if;
end if;
end process crc17_cycle;
init_vect_21(20) <= '1' when (drv_fd_type = ISO_FD)
else
'0';
init_vect_21(19 downto 0) <= (OTHERS => '0');
----------------------------------------------------------------------------
-- Calculation of CRC21 value
-- CRC instances
----------------------------------------------------------------------------
crc21_cycle : process(res_n, clk_sys)
begin
if (res_n = '0') then
crc21_reg <= (OTHERS => '0');
crc21_reg(20) <= '1';
elsif rising_edge(clk_sys) then
-- Erase the CRC value at the begining of calculation
if (start_reg = '0' and enable = '1') then
crc21_reg <= (OTHERS => '0');
if (drv_fd_type = ISO_FD) then
crc21_reg(20) <= '1';
end if;
else
-- Calculate the next value only when triggered
if (enable = '1'and trig = '1') then
crc_15_comp : CRC_calc
generic map(
crc_width => 15,
reset_polarity => ACT_RESET,
polynomial => crc15_pol
)
port map(
res_n => res_n,
clk_sys => clk_sys,
data_in => data_in,
trig => trig,
enable => enable,
init_vect => init_vect_15,
crc => crc15
);
------------------------------------------------------------
-- CRC calculation
------------------------------------------------------------
crc_17_comp : CRC_calc
generic map(
crc_width => 17,
reset_polarity => ACT_RESET,
polynomial => crc17_pol
)
port map(
res_n => res_n,
clk_sys => clk_sys,
data_in => data_in,
trig => trig,
enable => enable,
init_vect => init_vect_17,
crc => crc17
);
-- Shift and xor
if (crc21_nxt = '1') then
crc21_reg <= (crc21_reg(19 downto 0) & '0') xor
crc21_pol(20 downto 0);
-- Only shift bits
else
crc21_reg <= crc21_reg(19 downto 0) & '0';
end if;
else
crc21_reg <= crc21_reg;
end if;
end if;
end if;
end process crc21_cycle;
crc_21_comp : CRC_calc
generic map(
crc_width => 21,
reset_polarity => ACT_RESET,
polynomial => crc21_pol
)
port map(
res_n => res_n,
clk_sys => clk_sys,
data_in => data_in,
trig => trig,
enable => enable,
init_vect => init_vect_21,
crc => crc21
);
end architecture;
--------------------------------------------------------------------------------
--
-- CTU CAN FD IP Core
-- Copyright (C) 2015-2018
--
-- Authors:
-- Ondrej Ille <ondrej.ille@gmail.com>
-- Martin Jerabek <martin.jerabek01@gmail.com>
--
-- Project advisors:
-- Jiri Novak <jnovak@fel.cvut.cz>
-- Pavel Pisa <pisa@cmp.felk.cvut.cz>
--
-- Department of Measurement (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University (http://www.cvut.cz/)
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this VHDL component and associated documentation files (the "Component"),
-- to deal in the Component without restriction, including without limitation
-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Component, and to permit persons to whom the
-- Component is furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Component.
--
-- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
-- IN THE COMPONENT.
--
-- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
-- Anybody who wants to implement this IP core on silicon has to obtain a CAN
-- protocol license from Bosch.
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Purpose:
-- Generic CRC calculation circuit. Serial Data input. Operation starts with
-- enable transition from 0 to 1. Valid input data has to be present then.
-- Circuit processes the data on trig signal in logic 1. Circuit operation
-- finishes when 1 to 0 transition on enable signal appears. The output CRC is
-- valid then. CRC stays valid until following 0 to 1 enable transition. This
-- also erases CRC registers.
--
--------------------------------------------------------------------------------
-- Revision History:
-- 15.11.2018 Created file
--------------------------------------------------------------------------------
Library ieee;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.ALL;
use work.CANconstants.all;
use work.CAN_FD_register_map.all;
entity CRC_calc is
generic(
-- Width of CRC sequence
constant crc_width : natural;
-- Reset Polarity
constant reset_polarity : std_logic := '0';
-- CRC Polynomial
constant polynomial : std_logic_vector
);
port(
------------------------------------------------------------------------
-- Inputs
------------------------------------------------------------------------
-- Asynchronous reset
signal res_n :in std_logic;
-- System clock input
signal clk_sys :in std_logic;
-- Serial data input
signal data_in :in std_logic;
-- Trigger to sample the input value
signal trig :in std_logic;
-- By transition from 0 to 1 on enable sampled on clk_sys rising edge
-- (and with trig='1') operation is started. First bit of data already
-- has to be on data_in input.
-- Circuit works as long as enable=1.
signal enable :in std_logic;
-- Initialization vector for CRC calculation
signal init_vect :in std_logic_vector(crc_width - 1 downto 0);
------------------------------------------------------------------------
-- CRC value
------------------------------------------------------------------------
signal crc :out std_logic_vector(crc_width - 1 downto 0)
);
end entity;
architecture rtl of CRC_calc is
----------------------------------------------------------------------------
-- Internal registers
----------------------------------------------------------------------------
signal crc_reg : std_logic_vector(crc_width - 1 downto 0);
-- Holds previous value of enable input. Detects 0 to 1 transition
signal start_reg : std_logic;
-- Signal if next value of CRC should be shifted and XORed or only shifted!
signal crc_nxt : std_logic;
-- Shifted value of CRC register. Insert 0 from left
signal crc_shift : std_logic_vector(crc_width - 1 downto 0);
-- XORed value
signal crc_shift_n_xor : std_logic_vector(crc_width - 1 downto 0);
-- Combinational value of next CRC value
signal crc_nxt_val : std_logic_vector(crc_width - 1 downto 0);
begin
----------------------------------------------------------------------------
-- Calculation of next CRC value
----------------------------------------------------------------------------
crc_nxt <= data_in xor crc_reg(crc_width - 1);
crc_shift <= crc_reg(crc_width - 2 downto 0) & '0';
crc_shift_n_xor <= crc_shift xor polynomial(crc_width - 1 downto 0);
crc_nxt_val <= crc_shift_n_xor when (crc_nxt = '1')
else
crc_shift;
----------------------------------------------------------------------------
-- Registering previous value of enable input to detect 0 to 1 transition
----------------------------------------------------------------------------
start_reg_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
start_reg <= '0';
elsif rising_edge(clk_sys) then
start_reg <= enable;
end if;
end process start_reg_proc;
----------------------------------------------------------------------------
-- Calculation of CRC value
----------------------------------------------------------------------------
crc_calc_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
crc_reg <= (OTHERS => '0');
elsif rising_edge(clk_sys) then
-- Load CRC init vector to CRC register
if (start_reg = '0' and enable = '1') then
crc_reg <= init_vect;
else
-- Calculate the next value when triggered
if (enable = '1' and trig = '1') then
crc_reg <= crc_nxt_val;
end if;
end if;
end if;
end process crc_calc_proc;
-- Register to output propagation.
crc <= crc_reg;
end architecture;
......@@ -630,7 +630,7 @@ package CANcomponents is
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- CRC module
-- CAN CRC module
----------------------------------------------------------------------------
component canCRC is
generic(
......@@ -652,6 +652,27 @@ package CANcomponents is
end component;
----------------------------------------------------------------------------
-- Generic CRC calculation module
----------------------------------------------------------------------------
component CRC_calc is
generic(
constant crc_width : natural;
constant reset_polarity : std_logic := '0';
constant polynomial : std_logic_vector
);
port(
signal res_n :in std_logic;
signal clk_sys :in std_logic;
signal data_in :in std_logic;
signal trig :in std_logic;
signal enable :in std_logic;
signal init_vect :in std_logic_vector(crc_width - 1 downto 0);
signal crc :out std_logic_vector(crc_width - 1 downto 0)
);
end component;
----------------------------------------------------------------------------
-- Bit Stuffing
----------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment