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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [mavg_8ch_16b_64d.vhd] - Blame information for rev 315

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 315 jshamlet
-- Copyright (c)2023 Jeremy Seth Henry
2
-- All rights reserved.
3
--
4
-- Redistribution and use in source and binary forms, with or without
5
-- modification, are permitted provided that the following conditions are met:
6
--     * Redistributions of source code must retain the above copyright
7
--       notice, this list of conditions and the following disclaimer.
8
--     * Redistributions in binary form must reproduce the above copyright
9
--       notice, this list of conditions and the following disclaimer in the
10
--       documentation and/or other materials provided with the distribution,
11
--       where applicable (as part of a user interface, debugging port, etc.)
12
--
13
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
14
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
17
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
--
24
-- VHDL units : mavg_8ch_16b_64d
25
-- Description: 8-channel moving average calculation for 16-bit unsigned data
26
--              Accumulator depth is 64 elements, using 1 block RAM.
27
--
28
-- Revision History
29
-- Author          Date     Change
30
------------------ -------- ---------------------------------------------------
31
-- Seth Henry      05/18/23 Initial Upload
32
 
33
library ieee;
34
use ieee.std_logic_1164.all;
35
use ieee.std_logic_arith.all;
36
use ieee.std_logic_unsigned.all;
37
use ieee.std_logic_misc.all;
38
 
39
entity mavg_8ch_16b_64d is
40
generic(
41
  Reset_Level           : std_logic := '1'
42
);
43
port(
44
  Clock                 : in  std_logic;
45
  Reset                 : in  std_logic;
46
  --
47
  RAW_Channel           : in  std_logic_vector(2 downto 0);
48
  RAW_Data              : in  std_logic_vector(15 downto 0);
49
  RAW_Valid             : in  std_logic;
50
  --
51
  Busy_Out              : out std_logic;
52
  --
53
  AVG_Channel           : out std_logic_vector(2 downto 0);
54
  AVG_Out               : out std_logic_vector(15 downto 0);
55
  AVG_Valid             : out std_logic;
56
  --
57
  Busy_In               : in  std_logic
58
);
59
end entity;
60
 
61
architecture behave of mavg_8ch_16b_64d is
62
 
63
  type AVG_CTL_STATES is (INIT, CLR_BUFF, IDLE, BUSY_WAIT, RD_LAST,
64
                          ADV_PTR, CALC_NEXT, WR_NEW);
65
  signal AVG_Ctl        : AVG_CTL_STATES := INIT;
66
 
67
  signal CH_Select      : std_logic_vector(2 downto 0);
68
  signal Data_New       : std_logic_vector(15 downto 0) := (others => '0');
69
 
70
  signal RAM_Wr_Addr    : std_logic_vector(8 downto 0) := (others => '0');
71
  alias  RAM_Wr_Chan    is RAM_Wr_Addr(8 downto 6);
72
  alias  RAM_Wr_Ptr     is RAM_Wr_Addr(5 downto 0);
73
 
74
  signal RAM_Wr_Data    : std_logic_vector(15 downto 0) := (others => '0');
75
 
76
  signal RAM_Wr_En      : std_logic := '0';
77
 
78
  signal RAM_Rd_Addr    : std_logic_vector(8 downto 0) := (others => '0');
79
  alias  RAM_Rd_Chan    is RAM_Rd_Addr(8 downto 6);
80
  alias  RAM_Rd_Ptr     is RAM_Rd_Addr(5 downto 0);
81
 
82
  signal RAM_Rd_Data    : std_logic_vector(15 downto 0) := (others => '0');
83
  alias  Data_Old       is RAM_Rd_Data;
84
 
85
  type PTR_ARRAY is array (0 to 7) of std_logic_vector(5 downto 0);
86
  signal SP0_Pointers   : PTR_ARRAY;
87
  signal SPN_Pointers   : PTR_ARRAY;
88
 
89
  -- Accumulator width is bus_size (16) + log depth (6)
90
  type ACCUM_ARRAY is array (0 to 7) of unsigned(21 downto 0);
91
  signal Accumulators   : ACCUM_ARRAY;
92
 
93
begin
94
 
95
  MAVG_Control_proc: process( Clock, Reset )
96
    variable i : integer := 0;
97
  begin
98
    if( Reset = Reset_Level )then
99
      AVG_Ctl                <= INIT;
100
 
101
      CH_Select              <= (others => '0');
102
      Data_New               <= (others => '0');
103
 
104
      Busy_Out               <= '0';
105
 
106
      for i in 0 to 7 loop
107
        SP0_Pointers(i)      <= (others => '1');
108
        SPN_Pointers(i)      <= (others => '0');
109
        Accumulators(i)      <= (others => '0');
110
      end loop;
111
 
112
      RAM_Wr_Addr            <= (others => '0');
113
      RAM_Wr_Data            <= (others => '0');
114
      RAM_Wr_En              <= '0';
115
      RAM_Rd_Addr            <= (others => '0');
116
 
117
      AVG_Channel            <= (others => '0');
118
      AVG_Out                <= (others => '0');
119
      AVG_Valid              <= '0';
120
 
121
    elsif( rising_edge(Clock) )then
122
 
123
      RAM_Wr_En              <= '0';
124
 
125
      Busy_Out               <= '1';
126
      AVG_Valid              <= '0';
127
 
128
      i                      := conv_integer(unsigned(CH_Select));
129
 
130
      case( AVG_Ctl )is
131
        when INIT =>
132
          RAM_Wr_Addr        <= (others => '0');
133
          RAM_Wr_Data        <= (others => '0');
134
          AVG_Ctl            <= CLR_BUFF;
135
 
136
        when CLR_BUFF =>
137
          RAM_Wr_Addr        <= RAM_Wr_Addr + 1;
138
          RAM_Wr_En          <= '1';
139
          if( and_reduce(RAM_Wr_Addr) = '1' )then
140
            AVG_Ctl          <= IDLE;
141
          end if;
142
 
143
        when IDLE =>
144
          Busy_Out           <= '0';
145
          if( RAW_Valid = '1' )then
146
            Data_New         <= RAW_Data;
147
            CH_Select        <= RAW_Channel;
148
            AVG_Ctl          <= BUSY_WAIT;
149
          end if;
150
 
151
        when BUSY_WAIT =>
152
          if( Busy_In = '0' )then
153
            AVG_Ctl          <= RD_LAST;
154
          end if;
155
 
156
        when RD_LAST =>
157
          RAM_Rd_Chan        <= CH_Select;
158
          RAM_Rd_Ptr         <= SPN_Pointers(i);
159
          AVG_Ctl            <= ADV_PTR;
160
 
161
        when ADV_PTR =>
162
          SP0_Pointers(i)    <= SP0_Pointers(i) + 1;
163
          AVG_Ctl            <= CALC_NEXT;
164
 
165
        when CALC_NEXT =>
166
          Accumulators(i)    <= Accumulators(i) +
167
                                unsigned( Data_New ) -
168
                                unsigned( Data_Old );
169
          AVG_Ctl            <= WR_NEW;
170
 
171
        when WR_NEW =>
172
          RAM_Wr_Chan        <= CH_Select;
173
          RAM_Wr_Ptr         <= SP0_Pointers(i);
174
          RAM_Wr_Data        <= Data_New;
175
          RAM_Wr_En          <= '1';
176
          SPN_Pointers(i)    <= SP0_Pointers(i) + 1;
177
          AVG_Channel        <= CH_Select;
178
          AVG_Out            <= std_logic_vector(Accumulators(i)(21 downto 6));
179
          AVG_Valid          <= '1';
180
          AVG_Ctl            <= IDLE;
181
 
182
        when others =>
183
          null;
184
      end case;
185
 
186
    end if;
187
  end process;
188
 
189
  U_BUFF : entity work.mavg_buffer_16b
190
  port map(
191
    clock               => Clock,
192
    data                => RAM_Wr_Data,
193
    rdaddress           => RAM_Rd_Addr,
194
    wraddress           => RAM_Wr_Addr,
195
    wren                => RAM_Wr_En,
196
    q                   => RAM_Rd_Data
197
  );
198
 
199
end architecture;

powered by: WebSVN 2.1.0

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