OpenCores
URL https://opencores.org/ocsvn/neo430/neo430/trunk

Subversion Repositories neo430

[/] [neo430/] [trunk/] [neo430/] [rtl/] [core/] [neo430_crc.vhd] - Blame information for rev 198

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 198 zero_gravi
-- #################################################################################################
2
-- # << NEO430 - CRC Module >>                                                                     #
3
-- # ********************************************************************************************* #
4
-- # This module generates CRC16 and CRC32 check sums with variable polynomial masks.              #
5
-- # ********************************************************************************************* #
6
-- # BSD 3-Clause License                                                                          #
7
-- #                                                                                               #
8
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
9
-- #                                                                                               #
10
-- # Redistribution and use in source and binary forms, with or without modification, are          #
11
-- # permitted provided that the following conditions are met:                                     #
12
-- #                                                                                               #
13
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
14
-- #    conditions and the following disclaimer.                                                   #
15
-- #                                                                                               #
16
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
17
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
18
-- #    provided with the distribution.                                                            #
19
-- #                                                                                               #
20
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
21
-- #    endorse or promote products derived from this software without specific prior written      #
22
-- #    permission.                                                                                #
23
-- #                                                                                               #
24
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
25
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
26
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
27
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
28
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
29
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
30
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
31
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
32
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
33
-- # ********************************************************************************************* #
34
-- # The NEO430 Processor - https://github.com/stnolting/neo430                                    #
35
-- #################################################################################################
36
 
37
library ieee;
38
use ieee.std_logic_1164.all;
39
use ieee.numeric_std.all;
40
 
41
library neo430;
42
use neo430.neo430_package.all;
43
 
44
entity neo430_crc is
45
  port (
46
    -- host access --
47
    clk_i  : in  std_ulogic; -- global clock line
48
    rden_i : in  std_ulogic; -- read enable
49
    wren_i : in  std_ulogic; -- write enable
50
    addr_i : in  std_ulogic_vector(15 downto 0); -- address
51
    data_i : in  std_ulogic_vector(15 downto 0); -- data in
52
    data_o : out std_ulogic_vector(15 downto 0)  -- data out
53
  );
54
end neo430_crc;
55
 
56
architecture neo430_crc_rtl of neo430_crc is
57
 
58
  -- IO space: module base address --
59
  constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
60
  constant lo_abb_c : natural := index_size_f(crc_size_c); -- low address boundary bit
61
 
62
  -- access control --
63
  signal acc_en : std_ulogic; -- module access enable
64
  signal addr   : std_ulogic_vector(15 downto 0); -- access address
65
  signal wren   : std_ulogic;
66
 
67
  -- accessible registers --
68
  signal idata : std_ulogic_vector(07 downto 0);
69
  signal poly  : std_ulogic_vector(31 downto 0);
70
  signal start : std_ulogic;
71
  signal mode  : std_ulogic;
72
 
73
  -- core --
74
  signal cnt     : std_ulogic_vector(02 downto 0);
75
  signal run     : std_ulogic;
76
  signal crc_bit : std_ulogic;
77
  signal crc_sr  : std_ulogic_vector(31 downto 0);
78
 
79
begin
80
 
81
  -- Access Control -----------------------------------------------------------
82
  -- -----------------------------------------------------------------------------
83
  acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = crc_base_c(hi_abb_c downto lo_abb_c)) else '0';
84
  addr   <= crc_base_c(15 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 1) & '0'; -- word aligned
85
  wren   <= acc_en and wren_i;
86
 
87
 
88
  -- Write Access -------------------------------------------------------------
89
  -- -----------------------------------------------------------------------------
90
  write_access: process(clk_i)
91
  begin
92
    if rising_edge(clk_i) then
93
      start <= '0';
94
      if (wren = '1') then
95
        -- operands --
96
        if (addr = crc_crc16_in_addr_c) or (addr = crc_crc32_in_addr_c) then -- write data & start operation
97
          idata <= data_i(7 downto 0);
98
          start <= '1'; -- start operation
99
        end if;
100
        if (addr = crc_poly_lo_addr_c) then -- low (part) polynomial
101
          poly(15 downto 00) <= data_i;
102
        end if;
103
        if (addr = crc_poly_hi_addr_c) then -- high (part) polynomial
104
          poly(31 downto 16) <= data_i;
105
        end if;
106
        -- operation selection --
107
        if (addr = crc_crc16_in_addr_c) then
108
          mode <= '0'; -- crc16 mode
109
        else
110
          mode <= '1'; -- crc32 mode
111
        end if;
112
      end if;
113
    end if;
114
  end process write_access;
115
 
116
 
117
  -- CRC Core -----------------------------------------------------------------
118
  -- -----------------------------------------------------------------------------
119
  crc_core: process(clk_i)
120
  begin
121
    if rising_edge(clk_i) then
122
      -- arbitration --
123
      if (start = '1') then
124
        run <= '1';
125
      elsif (cnt = "000") then -- all done?
126
        run <= '0';
127
      end if;
128
      if (start = '1') then
129
        cnt <= "111"; -- start with MSB
130
      elsif (run = '1') then
131
        cnt <= std_ulogic_vector(unsigned(cnt) - 1);
132
      end if;
133
 
134
      -- computation --
135
      if ((wren = '1') and (addr = crc_resx_addr_c)) then -- write low part of CRC shift reg
136
        crc_sr(15 downto 0) <= data_i;
137
      elsif ((wren = '1') and (addr = crc_resy_addr_c)) then -- write high part of CRC shift reg
138
        crc_sr(31 downto 16) <= data_i;
139
      elsif (run = '1') then -- compute new CRC
140
        if (crc_bit /= idata(to_integer(unsigned(cnt(2 downto 0))))) then
141
          crc_sr <= (crc_sr(30 downto 0) & '0') xor poly;
142
        else
143
          crc_sr <= (crc_sr(30 downto 0) & '0');
144
        end if;
145
      end if;
146
    end if;
147
  end process crc_core;
148
 
149
  -- select compare bit according to selected mode --
150
  crc_bit <= crc_sr(31) when (mode = '1') else crc_sr(15);
151
 
152
 
153
  -- Read Access --------------------------------------------------------------
154
  -- -----------------------------------------------------------------------------
155
  read_access: process(clk_i)
156
  begin
157
    if rising_edge(clk_i) then
158
      data_o <= (others => '0');
159
      if (acc_en = '1') and (rden_i = '1') then
160
        if (addr = crc_resx_addr_c) then
161
          data_o <= crc_sr(15 downto 00);
162
        else -- if addr = crc_resy_addr_c
163
          data_o <= crc_sr(31 downto 16);
164
        end if;
165
      end if;
166
    end if;
167
  end process read_access;
168
 
169
 
170
end neo430_crc_rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.