Example: Crc8s
Crc8s.VHD
------------------------------------------------------------------------- -- 8-bit Serial CRC Generator. -- -- This CRC generator implements the CRC-CCITT standard -- for serial data transmission. This VHDL description -- is based in an ABEL design appearing in "Digital Design -- Using ABEL" by David Pellerin and Michael Holley -- (Prentice Hall, 1994). -- -- This design description demonstrates the important -- distinction between signals and variables in VHDL. Note -- that the chain of registers and XOR operations has been -- written using signals within a process. It would be -- possible to describe the same circuit using variables, -- but great care would have to be taken to ensure that -- the desired circuit is produced. This is because variable -- assignments are immediate: writing variable assignments -- such as -- X(0) := Din xor X(15); -- X(1) := X(0); -- X(2) := X(1); -- X(3) := X(2); -- X(4) := X(3); -- ... -- -- would *not* result in a single XOR function and a simple -- chain of registers. Instead, the expression 'Din xor X(15)' -- would be assumed as the input to all registers, rather than -- just X(15). -- -- Copyright 1995, Accolade Design Automation, Inc. -- -- library ieee; use ieee.std_logic_1164.all; entity crc8s is port (Clk,Set, Din: in std_ulogic; CRC_Sum: out std_ulogic_vector(15 downto 0)); end crc8s; architecture behavior of crc8s is signal X: std_ulogic_vector(15 downto 0); begin process(Clk,Set) begin if Set = '1' then X <= (others=> '1'); elsif rising_edge(Clk) then X(0) <= Din xor X(15); X(1) <= X(0); X(2) <= X(1); X(3) <= X(2); X(4) <= X(3); X(5) <= X(4) xor Din xor X(15); X(6) <= X(5); X(7) <= X(6); X(8) <= X(7); X(9) <= X(8); X(10) <= X(9); X(11) <= X(10); X(12) <= X(11) xor Din xor X(15); X(13) <= X(12); X(14) <= X(13); X(15) <= X(14); end if; end process; CRC_Sum <= X; end behavior;
Testcrc.VHD
------------------------------------------------------- -- Test bench for CRC generator -- -- See comments in CRC8S.VHD. -- -- Copyright 1995, Accolade Design Automation, Inc. -- library ieee; use ieee.std_logic_1164.all; use work.all; -- Get the design out of library 'work' -- entity testcrc is end testcrc; -- architecture stimulus of testcrc is component crc8s port (Clk,Set,Din: in std_ulogic; CRC_Sum: out std_ulogic_vector(15 downto 0)); end component; signal CE, Clk, Set, Din: std_ulogic; signal CRC_Sum: std_ulogic_vector(15 downto 0); signal vector_cnt: integer := 1; signal error_flag: std_ulogic := '0'; type test_record is record CE : std_ulogic; -- Clock enable Set,Din : std_ulogic; CRC_Sum : std_ulogic_vector (15 downto 0); end record; type test_array is array(positive range <>) of test_record; signal svector: test_record; constant test_vectors : test_array := ( -- CE, Set, Din, CRC_Sum ('0', '1', '0', "----------------"), -- Reset -- ('1', '0', '0', "----------------"), -- 'H' ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '0', "0010100000111100"), -- 0x283C -- ('1', '0', '0', "----------------"), -- 'e' ('1', '0', '1', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '1', "1010010101101001"), -- 0xA569 -- ('1', '0', '0', "----------------"), -- 'l' ('1', '0', '1', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '0', "0010000101100101"), -- 0x2165 -- -- Commented out to fit in demo limitations... -- -- ('1', '0', '0', "----------------"), -- 'l' -- ('1', '0', '1', "----------------"), -- ('1', '0', '1', "----------------"), -- ('1', '0', '0', "----------------"), -- ('1', '0', '1', "----------------"), -- ('1', '0', '1', "----------------"), -- ('1', '0', '0', "----------------"), -- ('1', '0', '0', "1111110001101001"), -- 0xFC69 -- ('1', '0', '0', "----------------"), -- 'o' ('1', '0', '1', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '0', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '1', "----------------"), ('1', '0', '1', "1101101011011010"));-- 0xDADA -- begin -- instantiate the component DUT: crc8s port map(Clk,Set,Din,CRC_Sum); -- -- provide Stimulus and check the result -- testrun: process variable vector : test_record; begin for index in test_vectors'range loop vector_cnt <= index; vector := test_vectors(index); svector <= vector; -- so we can see it in simulation -- -- Apply the input stimulus... CE <= vector.CE; Set <= vector.Set; Din <= vector.Din; -- -- Clock (low-high-low) with a 100 ns cycle... Clk <= '0'; wait for 25 ns; if CE = '1' then Clk <= '1'; end if; wait for 50 ns; Clk <= '0'; wait for 25 ns; -- -- Check the results... if (vector.CRC_Sum /= "----------------" and CRC_Sum /= vector.CRC_Sum) then error_flag <= '1'; assert false report "Output did not match!" severity WARNING; else error_flag <= '0'; end if; end loop; end process; end stimulus;