/*
|
/*
|
This file is part of the Galois Linear Feedback Shift Register
|
This file is part of the Galois Linear Feedback Shift Register
|
(galois_lfsr) project:
|
(galois_lfsr) project:
|
http://www.opencores.org/project,galois_lfsr
|
http://www.opencores.org/project,galois_lfsr
|
|
|
Description
|
Description
|
Synthesisable use case for Galois LFSR.
|
Synthesisable use case for Galois LFSR.
|
This example is a CRC generator that uses a Galois LFSR.
|
This example is a CRC generator that uses a Galois LFSR.
|
|
|
ToDo:
|
ToDo:
|
|
|
Author(s):
|
Author(s):
|
- Daniel C.K. Kho, daniel.kho@opencores.org | daniel.kho@tauhop.com
|
- Daniel C.K. Kho, daniel.kho@opencores.org | daniel.kho@tauhop.com
|
|
|
Copyright (C) 2012-2013 Authors and OPENCORES.ORG
|
Copyright (C) 2012-2013 Authors and OPENCORES.ORG
|
|
|
This source file may be used and distributed without
|
This source file may be used and distributed without
|
restriction provided that this copyright statement is not
|
restriction provided that this copyright statement is not
|
removed from the file and that any derivative work contains
|
removed from the file and that any derivative work contains
|
the original copyright notice and the associated disclaimer.
|
the original copyright notice and the associated disclaimer.
|
|
|
This source file is free software; you can redistribute it
|
This source file is free software; you can redistribute it
|
and/or modify it under the terms of the GNU Lesser General
|
and/or modify it under the terms of the GNU Lesser General
|
Public License as published by the Free Software Foundation;
|
Public License as published by the Free Software Foundation;
|
either version 2.1 of the License, or (at your option) any
|
either version 2.1 of the License, or (at your option) any
|
later version.
|
later version.
|
|
|
This source is distributed in the hope that it will be
|
This source is distributed in the hope that it will be
|
useful, but WITHOUT ANY WARRANTY; without even the implied
|
useful, but WITHOUT ANY WARRANTY; without even the implied
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
PURPOSE. See the GNU Lesser General Public License for more
|
PURPOSE. See the GNU Lesser General Public License for more
|
details.
|
details.
|
|
|
You should have received a copy of the GNU Lesser General
|
You should have received a copy of the GNU Lesser General
|
Public License along with this source; if not, download it
|
Public License along with this source; if not, download it
|
from http://www.opencores.org/lgpl.shtml.
|
from http://www.opencores.org/lgpl.shtml.
|
*/
|
*/
|
library ieee; use ieee.std_logic_1164.all, ieee.numeric_std.all; use ieee.math_real.all;
|
library ieee; use ieee.std_logic_1164.all, ieee.numeric_std.all; use ieee.math_real.all;
|
--use work.types.all;
|
--use work.types.all;
|
|
|
entity user is
|
entity user is
|
generic(
|
generic(
|
parallelLoad:boolean:=false;
|
parallelLoad:boolean:=false;
|
tapVector:boolean_vector:=(
|
tapVector:boolean_vector:=(
|
/* Example polynomial from Wikipedia. */
|
/* Example polynomial from Wikipedia. */
|
0|1|2|8=>true, 7 downto 3=>false
|
0|1|2|8=>true, 7 downto 3=>false
|
)
|
)
|
);
|
);
|
port(
|
port(
|
/* Comment-out for simulation. */
|
/* Comment-out for simulation. */
|
--clk,reset:in std_ulogic;
|
--clk,reset:in std_ulogic;
|
msg:in unsigned(tapVector'length-1 downto 0):=9x"57"; -- Should be (tapVector'length downto 0). TODO report ModelSim bug.
|
msg:in unsigned(tapVector'length-1 downto 0):=9x"57"; -- Should be (tapVector'length downto 0). TODO report ModelSim bug.
|
crc32:out unsigned(31 downto 0):=(others=>'0')
|
crc32:out unsigned(31 downto 0):=(others=>'0')
|
);
|
);
|
end entity user;
|
end entity user;
|
|
|
architecture rtl of user is
|
architecture rtl of user is
|
signal n,c:natural;
|
signal n,c:natural;
|
|
|
/* Tester signals. */
|
/* Tester signals. */
|
signal d:std_ulogic;
|
signal d:std_ulogic;
|
/* synthesis translate_off */
|
/* synthesis translate_off */
|
signal clk,reset:std_ulogic:='0';
|
signal clk,reset:std_ulogic:='0';
|
/* synthesis translate_on */
|
/* synthesis translate_on */
|
|
|
signal loadEn,computeClk:std_ulogic; -- clock gating.
|
signal loadEn,computeClk:std_ulogic; -- clock gating.
|
signal loaded,i_loaded:boolean;
|
signal loaded,i_loaded:boolean;
|
signal computed,i_computed:boolean;
|
signal computed,i_computed:boolean;
|
|
|
begin
|
begin
|
/* Simulation Tester. */
|
/* Simulation Tester. */
|
/* synthesis translate_off */
|
/* synthesis translate_off */
|
clk<=not clk after 10 ps;
|
clk<=not clk after 10 ps;
|
|
|
process is begin
|
process is begin
|
reset<='0'; wait for 1 ps;
|
reset<='0'; wait for 1 ps;
|
reset<='1'; wait for 500 ps;
|
reset<='1'; wait for 500 ps;
|
reset<='0';
|
reset<='0';
|
wait;
|
wait;
|
end process;
|
end process;
|
/* synthesis translate_on */
|
/* synthesis translate_on */
|
|
|
loadEn<=clk when reset='0' and not i_computed else '0';
|
loadEn<=clk when reset='0' and not i_computed else '0';
|
computeClk<=clk when reset='0' and i_loaded and not i_computed else '0';
|
computeClk<=clk when reset='0' and i_loaded and not i_computed else '0';
|
|
|
/* CRC computer using LFSR.
|
/* Galois LFSR instance. */
|
E.g. Design a CRC-32 generator with the following polynomial (CRC-32 algorithm):
|
|
G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10
|
|
+ x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
|
|
|
|
Equivalent to the following hex code: 0x04C11DB7, with the MSbit discarded (assumed
|
|
present, but discarded in real implementation to save bits as it does not serve
|
|
any other purpose).
|
|
*/
|
|
i_lfsr: entity work.lfsr(rtl)
|
i_lfsr: entity work.lfsr(rtl)
|
generic map(taps=>tapVector)
|
generic map(taps=>tapVector)
|
/*generic map(taps => (
|
/*generic map(taps => (
|
0|1|2|8=>true,
|
0|1|2|8=>true,
|
7 downto 3=>false
|
7 downto 3=>false
|
))*/
|
))*/
|
port map(nReset=>not reset, clk=>loadEn,
|
port map(nReset=>not reset, clk=>loadEn,
|
load=>parallelLoad,
|
load=>parallelLoad,
|
seed=>msg,
|
seed=>msg,
|
d=>d,
|
d=>d,
|
q=>crc32(msg'range)
|
q=>crc32(msg'range)
|
);
|
);
|
|
|
/* Load message into LFSR. */
|
/* Load message into LFSR. */
|
process(reset,loadEn) is begin
|
process(reset,loadEn) is begin
|
if reset then loaded<=false; n<=msg'length-1; d<='0';
|
if reset then loaded<=false; n<=msg'length-1; d<='0';
|
elsif rising_edge(loadEn) then
|
elsif rising_edge(loadEn) then
|
d<='0';
|
d<='0';
|
|
|
/* for parallel mode, LFSR automatically loads the seed in parallel. */
|
/* for parallel mode, LFSR automatically loads the seed in parallel. */
|
if parallelLoad then d<='0'; loaded<=true;
|
if parallelLoad then d<='0'; loaded<=true;
|
else
|
else
|
if not loaded then d<=msg(n); end if;
|
if not loaded then d<=msg(n); end if;
|
|
|
if n>0 then n<=n-1;
|
if n>0 then n<=n-1;
|
else loaded<=true;
|
else loaded<=true;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
/* Shift zeroes into LFSR after message has been loaded completely. */
|
/* Shift zeroes into LFSR after message has been loaded completely. */
|
process(reset,loaded,computeClk) is begin
|
process(reset,loaded,computeClk) is begin
|
if reset='1' or not loaded then computed<=false; c<=msg'length-1;
|
if reset='1' or not loaded then computed<=false; c<=msg'length-1;
|
elsif rising_edge(computeClk) then
|
elsif rising_edge(computeClk) then
|
if c>0 then c<=c-1;
|
if c>0 then c<=c-1;
|
else computed<=true;
|
else computed<=true;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
/* Register pipelines. */
|
/* Register pipelines. */
|
process(clk) is begin
|
process(clk) is begin
|
if falling_edge(clk) then
|
if falling_edge(clk) then
|
i_loaded<=loaded;
|
i_loaded<=loaded;
|
i_computed<=computed;
|
i_computed<=computed;
|
end if;
|
end if;
|
end process;
|
end process;
|
end architecture rtl;
|
end architecture rtl;
|
|
|