??? 09/20/04 18:24 Read: times |
#77737 - RE: About CRC-16 Responding to: ???'s previous message |
I found this odd peice of vhdl which implements a crc16 calculator
its odd because of the way that the author has used variables rather than signals for some of the registers.Normally you avoid variables in shift registers like the plague because they assume the values immediatly rather than after some delta delay and so the normal style of constructing them in vhdl doesn't work.However synthesis tools sometimes give faster results with variables as the feedback loops are more localised ------------------------------------------------------------------------------- -- University of Stockholm -- -- Department of Physics -- -- System & Instrumentation Group -- ------------------------------------------------------------------------------- -- -- Project : Tile-DMU chip -- Title : CRC-16 -- File name : crc_16.vhdl -- Author : Jonas Klereborn Email: klere@physto.se -- Date : Apr 20 1999 -- Version : 1.7 -- ------------------------------------------------------------------------------- -- -- This unit calculates the CRC-16 checksum for the output data. -- The algorithm used is the standard CRC-16: -- -- Name : CRC-16 -- Width : 16 bit -- Poly : 8005 This is the divisor polynome -- Init : 0000 This is the initial value of the register -- Refin : Yes Reflect the input e.g. bit 0 first -- Refout : Yes Reflect the checksum output -- Xorout : 0000 Do not xor the checksum with anything -- check : BB3D This is the checksum for the ascii string "123456789" -- Library IEEE; use IEEE.std_logic_1164.all; entity crc_16 is port( clk : in std_logic; -- clock data_in : in std_logic_vector(1 downto 0); -- data out v_in : in std_logic; -- link "valid"-signal in u_in : in std_logic; -- link "user-control" in crc : in std_logic; -- end of event, output CRC start : in std_logic; -- start readout en : in std_logic; -- enable wait_now : out std_logic; -- sends a wait signal data_out : out std_logic_vector(1 downto 0); -- data in, from serializer v_out : out std_logic; -- link "valid"-signal out u_out : out std_logic -- link "user-control" out ); end crc_16; architecture crc_16 of crc_16 is signal start_bfr : std_logic_vector(2 downto 0); -- Buffer to delay the start signal crc_bfr : std_logic_vector(1 downto 0); -- Buffer to delay the crc- -- readout signal start_alt : std_logic; begin CRC1: process(clk) variable data1 : std_logic_vector(15 downto 0); -- FIFO for data bit 1 variable reg1 : std_logic_vector(15 downto 0); -- crc-register for bit 1 variable outbit1 : std_logic; -- used for the xor fkn variable data0 : std_logic_vector(15 downto 0); -- FIFO for data bit 0 variable reg0 : std_logic_vector(15 downto 0); -- crc-register for bit 0 variable outbit0 : std_logic; -- used for the xor fkn variable poly : std_logic_vector(15 downto 0); -- the divisor polynome variable u_fifo : std_logic_vector(15 downto 0); -- FIFO for usr_ctrl variable v_fifo : std_logic_vector(15 downto 0); -- FIFO for valid variable crc_mode : std_logic; -- if 0 => data readout -- if 1 => crc readout begin -- Use divisor polynome 8005 poly := "1000000000000101"; if rising_edge(clk) then -- Enable (see enable unit) if en = '0' then -- Both u_ctrl_b and valid_b are high when enable is low, no readout u_out <= '1'; v_out <= '1'; wait_now <= '0'; if start = '1' then start_alt <= '1'; end if; else -- Delay the start and crc-readout start_bfr(2 downto 1) <= start_bfr(1 downto 0); start_bfr(0) <= (start or start_alt); start_alt <= '0'; crc_bfr(1) <= crc_bfr(0); crc_bfr(0) <= crc; -- At start empty the registers (initial value = 0000) and FIFO's. -- The data bits and u_fifo, v_fifo registers are initialized -- to send a link control start signal before readout. -- Set crc_mode to 0, regular data readout. if start_bfr(2) = '1' then reg1 := "0000000000000000"; data1 := "0000000000000001"; reg0 := "0000000000000000"; data0 := "0000000000000001"; u_fifo := "1111111111111110"; v_fifo := "1111111111111110"; outbit1 := '0'; outbit0 := '0'; data_out <= "00"; crc_mode := '0'; u_out <= '1'; v_out <= '1'; else -- Delay the link signals to syncronize with data. u_fifo(15 downto 1) := u_fifo(14 downto 0); u_fifo(0) := u_in; v_fifo(15 downto 1) := v_fifo(14 downto 0); v_fifo(0) := v_in; u_out <= u_fifo(15); v_out <= v_fifo(15); if crc_mode = '0' then -- Regular DATA readout and crc-16 calculation. -- Rotate the register left saving the leftmost bit in outbit. -- Delay data to syncronize with the crc-checksum. -- Xor the register with the divisor polynome if outbit is 1. outbit1 := reg1(15); outbit0 := reg0(15); reg1(15 downto 1) := reg1(14 downto 0); reg1(0) := data_in(1); data1(15 downto 1) := data1(14 downto 0); data1(0) := data_in(1); reg0(15 downto 1) := reg0(14 downto 0); reg0(0) := data_in(0); data0(15 downto 1) := data0(14 downto 0); data0(0) := data_in(0); data_out <= data1(15) & data0(15); if outbit1 = '1' then for i in 15 downto 0 loop reg1(i) := reg1(i) xor poly(i); end loop; end if; if outbit0 = '1' then for i in 15 downto 0 loop reg0(i) := reg0(i) xor poly(i); end loop; end if; if crc_bfr(0) = '1' then crc_mode := '1'; data_out <= reg1(0) & reg0(0); reg1(14 downto 0) := reg1(15 downto 1); reg1(15) := '0'; reg0(14 downto 0) := reg0(15 downto 1); reg0(15) := '0'; end if; else -- Readout CRC-16 checksum bit 0 first (checksum output reflected) data_out <= reg1(0) & reg0(0); reg1(14 downto 0) := reg1(15 downto 1); reg1(15) := '0'; reg0(14 downto 0) := reg0(15 downto 1); reg0(15) := '0'; end if; end if; -- Issues the waiting after link control word. if (u_fifo(15) = '0' and data0(15) = '1' and data1(15) = '1') then wait_now <= '1'; else wait_now <= '0'; end if; end if; end if; end process CRC1; end crc_16; |
Topic | Author | Date |
About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
What CRC-16? | 01/01/70 00:00 | |
RE: What CRC-16? | 01/01/70 00:00 | |
RE: What CRC-16? | 01/01/70 00:00 | |
RE: What CRC-16? | 01/01/70 00:00 | |
It works for me! | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: Initial values | 01/01/70 00:00 | |
RE: Initial values | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
Read the article | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: Karma | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16 | 01/01/70 00:00 | |
RE: About CRC-16![]() | 01/01/70 00:00 |