On 2009-01-29, Mark Brehob <> wrote:
> But it is _really_ helpful to understand why good people like to
> "break our rules". Otherwise I just know people do, but can't give
> examples to the students.
Another example for your consideration. Unrolling a CRC for Ethernet.
You could do this without variables by unrolling it manually, but why
do work yourself when the synthesis tool can do it for you?
/Andreas
-- (This could be done in a neater way using ranges)
process (clk)
variable crc_tmp : std_logic_vector(31 downto 0);
variable fb : std_logic;
begin -- process
if clk'event and clk = '1' then -- rising clock edge
if enable = '1' then
crc_tmp := crc;
-- Unrolled to process a nibble at a time.
for i in 0 to 3 loop
fb := crc_tmp(31);
crc_tmp(31) := crc_tmp(30);
crc_tmp(30) := crc_tmp(29);
crc_tmp(29) := crc_tmp(2

;
crc_tmp(2

:= crc_tmp(27);
crc_tmp(27) := crc_tmp(26);
crc_tmp(26) := d(i) xor fb xor crc_tmp(25); -- x^26
crc_tmp(25) := crc_tmp(24);
crc_tmp(24) := crc_tmp(23);
crc_tmp(23) := d(i) xor fb xor crc_tmp(22); -- x^23
crc_tmp(22) := d(i) xor fb xor crc_tmp(21); -- x^22
crc_tmp(21) := crc_tmp(20);
crc_tmp(20) := crc_tmp(19);
crc_tmp(19) := crc_tmp(1

;
crc_tmp(1

:= crc_tmp(17);
crc_tmp(17) := crc_tmp(16);
crc_tmp(16) := d(i) xor fb xor crc_tmp(15); -- x^16
crc_tmp(15) := crc_tmp(14);
crc_tmp(14) := crc_tmp(13);
crc_tmp(13) := crc_tmp(12);
crc_tmp(12) := d(i) xor fb xor crc_tmp(11); -- x^12
crc_tmp(11) := d(i) xor fb xor crc_tmp(10); -- x^11
crc_tmp(10) := d(i) xor fb xor crc_tmp(9); -- x^10
crc_tmp(9) := crc_tmp(

;
crc_tmp(

:= d(i) xor fb xor crc_tmp(7); -- x^8
crc_tmp(7) := d(i) xor fb xor crc_tmp(6); -- x^7
crc_tmp(6) := crc_tmp(5);
crc_tmp(5) := d(i) xor fb xor crc_tmp(4); -- x^5
crc_tmp(4) := d(i) xor fb xor crc_tmp(3); -- x^4
crc_tmp(3) := crc_tmp(2);
crc_tmp(2) := d(i) xor fb xor crc_tmp(1); -- x^2
crc_tmp(1) := d(i) xor fb xor crc_tmp(0); -- x^1
crc_tmp(0) := d(i) xor fb; -- 1
crc <= crc_tmp;
elsif clear = '1' then
crc <= (others => '1');
end if;
end if;
end process;