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;