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

Subversion Repositories astron_statistics

[/] [astron_statistics/] [trunk/] [st_acc.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3 3 danv
-- Copyright 2020
4 2 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6 3 danv
-- 
7
-- Licensed under the Apache License, Version 2.0 (the "License");
8
-- you may not use this file except in compliance with the License.
9
-- You may obtain a copy of the License at
10
-- 
11
--     http://www.apache.org/licenses/LICENSE-2.0
12
-- 
13
-- Unless required by applicable law or agreed to in writing, software
14
-- distributed under the License is distributed on an "AS IS" BASIS,
15
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
-- See the License for the specific language governing permissions and
17
-- limitations under the License.
18 2 danv
--
19
-------------------------------------------------------------------------------
20
 
21 4 danv
LIBRARY IEEE, common_pkg_lib, common_components_lib, astron_adder_lib;
22 2 danv
USE IEEE.std_logic_1164.ALL;
23
USE IEEE.numeric_std.ALL;
24
USE common_pkg_lib.common_pkg.ALL;
25
 
26
 
27
-- Purpose:
28
--   Accumulate input data to an accumulator that is stored externally. In this
29
--   way blocks of input samples (e.g. subband products) can be accumulated to
30
--   a set of external accumulators. At the in_load the accumulator input value
31
--   is ignored so that the accumulation restarts with the in_dat.
32
--
33
-- Description:
34
--   if in_load = '1' then
35
--     out_acc = in_dat + 0         -- restart accumulation
36
--   else
37
--     out_acc = in_dat + in_acc    -- accumulate
38
--
39
-- Remarks:
40
-- . in_val propagates to out_val after the pipeline latency but does not 
41
--   affect the sum
42
 
43
ENTITY st_acc IS
44
  GENERIC (
45
    g_dat_w            : NATURAL;
46
    g_acc_w            : NATURAL;  -- g_acc_w >= g_dat_w
47
    g_hold_load        : BOOLEAN := TRUE;
48
    g_pipeline_input   : NATURAL;  -- 0 no input registers, else register input after in_load
49
    g_pipeline_output  : NATURAL   -- pipeline for the adder
50
  );
51
  PORT (
52
    clk         : IN  STD_LOGIC;
53
    clken       : IN  STD_LOGIC := '1';
54
    in_load     : IN  STD_LOGIC;
55
    in_dat      : IN  STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
56
    in_acc      : IN  STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
57
    in_val      : IN  STD_LOGIC := '1';
58
    out_acc     : OUT STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
59
    out_val     : OUT STD_LOGIC
60
  );
61
END st_acc;
62
 
63
 
64
ARCHITECTURE rtl OF st_acc IS
65
 
66
  CONSTANT c_pipeline  : NATURAL := g_pipeline_input + g_pipeline_output;
67
 
68
  -- Input signals
69
  SIGNAL hld_load        : STD_LOGIC := '0';
70
  SIGNAL nxt_hld_load    : STD_LOGIC;
71
  SIGNAL acc_clr        : STD_LOGIC;
72
 
73
  SIGNAL reg_dat        : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0) := (OTHERS=>'0');
74
  SIGNAL nxt_reg_dat    : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
75
  SIGNAL reg_acc        : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0) := (OTHERS=>'0');
76
  SIGNAL nxt_reg_acc    : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
77
 
78
  -- Pipeline control signals, map to slv to be able to use common_pipeline
79
  SIGNAL in_val_slv     : STD_LOGIC_VECTOR(0 DOWNTO 0);
80
  SIGNAL out_val_slv    : STD_LOGIC_VECTOR(0 DOWNTO 0);
81
 
82
BEGIN
83
 
84
  ASSERT NOT(g_acc_w < g_dat_w)
85
    REPORT "st_acc: output accumulator width must be >= input data width"
86
    SEVERITY FAILURE;
87
 
88
  ------------------------------------------------------------------------------
89
  -- Input load control
90
  ------------------------------------------------------------------------------
91
 
92
  p_clk : PROCESS(clk)
93
  BEGIN
94
    IF rising_edge(clk) THEN
95
      IF clken='1' THEN
96
        hld_load <= nxt_hld_load;
97
      END IF;
98
    END IF;
99
  END PROCESS;
100
 
101
  nxt_hld_load <= in_load WHEN in_val='1' ELSE hld_load;
102
 
103
  -- Hold in_load to save power by avoiding unneccessary out_acc toggling when in_val goes low  
104
  -- . For g_pipeline_input>0 this is fine
105
  -- . For g_pipeline_input=0 this may cause difficulty in achieving timing closure for synthesis
106
  use_in_load : IF g_hold_load = FALSE GENERATE
107
    acc_clr <= in_load;  -- the in_load may already be extended during in_val
108
  END GENERATE;
109
  use_hld_load : IF g_hold_load = TRUE GENERATE
110
    acc_clr <= in_load OR (hld_load AND NOT in_val);
111
  END GENERATE;
112
 
113
  -- Do not use g_pipeline_input of u_adder, to allow registered acc clear if g_pipeline_input=1
114
  nxt_reg_dat <= RESIZE_SVEC(in_dat, g_acc_w);
115
  nxt_reg_acc <= in_acc WHEN acc_clr='0' ELSE (OTHERS=>'0');
116
 
117
  no_input_reg : IF g_pipeline_input=0 GENERATE
118
    reg_dat <= nxt_reg_dat;
119
    reg_acc <= nxt_reg_acc;
120
  END GENERATE;
121
  gen_input_reg : IF g_pipeline_input>0 GENERATE
122
    p_reg : PROCESS(clk)
123
    BEGIN
124
      IF rising_edge(clk) THEN
125
        IF clken='1' THEN
126
          reg_dat <= nxt_reg_dat;
127
          reg_acc <= nxt_reg_acc;
128
        END IF;
129
      END IF;
130
    END PROCESS;
131
  END GENERATE;
132
 
133
 
134
  ------------------------------------------------------------------------------
135
  -- Adder for the external accumulator
136
  ------------------------------------------------------------------------------
137
 
138 4 danv
  u_adder : ENTITY astron_adder_lib.common_add_sub
139 2 danv
  GENERIC MAP (
140
    g_direction       => "ADD",
141
    g_representation  => "SIGNED",  -- not relevant because g_out_dat_w = g_in_dat_w
142
    g_pipeline_input  => 0,
143
    g_pipeline_output => g_pipeline_output,
144
    g_in_dat_w        => g_acc_w,
145
    g_out_dat_w       => g_acc_w
146
  )
147
  PORT MAP (
148
    clk     => clk,
149
    clken   => clken,
150
    in_a    => reg_dat,
151
    in_b    => reg_acc,
152
    result  => out_acc
153
  );
154
 
155
 
156
  ------------------------------------------------------------------------------
157
  -- Parallel output control pipeline
158
  ------------------------------------------------------------------------------
159
 
160
  in_val_slv(0) <= in_val;
161
  out_val       <= out_val_slv(0);
162
 
163
  u_out_val : ENTITY common_components_lib.common_pipeline
164
  GENERIC MAP (
165
    g_representation => "UNSIGNED",
166
    g_pipeline       => c_pipeline,
167
    g_reset_value    => 0,
168
    g_in_dat_w       => 1,
169
    g_out_dat_w      => 1
170
  )
171
  PORT MAP (
172
    clk     => clk,
173
    clken   => clken,
174
    in_dat  => slv(in_val),
175
    out_dat => out_val_slv
176
  );
177
 
178
END rtl;

powered by: WebSVN 2.1.0

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