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

Subversion Repositories astron_statistics

[/] [astron_statistics/] [trunk/] [tb_st_acc.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2010
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22
LIBRARY IEEE, common_pkg_lib, common_components_lib;
23
USE IEEE.std_logic_1164.ALL;
24
USE IEEE.numeric_std.ALL;
25
USE common_pkg_lib.common_pkg.ALL;
26
 
27
 
28
ENTITY tb_st_acc IS
29
  GENERIC (
30
    g_dat_w            : NATURAL := 6;
31
    g_acc_w            : NATURAL := 9;
32
    g_hold_load        : BOOLEAN := TRUE;
33
    g_pipeline_input   : NATURAL := 0;
34
    g_pipeline_output  : NATURAL := 4
35
  );
36
END tb_st_acc;
37
 
38
 
39
ARCHITECTURE tb OF tb_st_acc IS
40
 
41
  CONSTANT clk_period    : TIME := 10 ns;
42
 
43
  CONSTANT c_pipeline    : NATURAL := g_pipeline_input + g_pipeline_output;
44
 
45
  FUNCTION func_acc(in_dat, in_acc  : STD_LOGIC_VECTOR;
46
                    in_val, in_load : STD_LOGIC) RETURN STD_LOGIC_VECTOR IS
47
    VARIABLE v_dat, v_acc, v_result : INTEGER;
48
  BEGIN
49
    -- Calculate expected result
50
    IF in_val='0' THEN              -- hold: out_acc = in_acc
51
      v_result := TO_SINT(in_acc);
52
    ELSIF in_load='1' THEN           -- force: out_acc = 0 + in_dat
53
      v_result := TO_SINT(in_dat);
54
    ELSE                            -- accumulate: out_acc = in_acc + in_dat
55
      v_result := TO_SINT(in_dat) + TO_SINT(in_acc);
56
    END IF;
57
    -- Wrap to avoid warning: NUMERIC_STD.TO_SIGNED: vector truncated
58
    IF v_result >  2**(g_acc_w-1)-1 THEN v_result := v_result - 2**g_acc_w; END IF;
59
    IF v_result < -2**(g_acc_w-1)   THEN v_result := v_result + 2**g_acc_w; END IF;
60
    RETURN TO_SVEC(v_result, g_acc_w);
61
  END;
62
 
63
  SIGNAL tb_end          : STD_LOGIC := '0';
64
  SIGNAL clk             : STD_LOGIC := '0';
65
 
66
  SIGNAL in_dat          : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
67
  SIGNAL in_acc          : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0) := (OTHERS=>'0');
68
  SIGNAL in_val          : STD_LOGIC;
69
  SIGNAL in_load         : STD_LOGIC;
70
  SIGNAL out_val         : STD_LOGIC;
71
  SIGNAL out_acc         : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
72
 
73
  SIGNAL expected_acc_p  : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
74
  SIGNAL expected_acc    : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
75
 
76
BEGIN
77
 
78
  clk  <= NOT clk OR tb_end AFTER clk_period/2;
79
 
80
  ------------------------------------------------------------------------------
81
  -- Input stimuli
82
  ------------------------------------------------------------------------------
83
 
84
  -- run -all
85
  p_stimuli : PROCESS
86
  BEGIN
87
    in_load <= '0';
88
    in_dat <= TO_SVEC(0, g_dat_w);
89
    in_val <= '0';
90
    WAIT UNTIL rising_edge(clk);
91
    FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
92
 
93
    in_load <= '1';
94
    in_val <= '1';
95
    FOR R IN 0 TO 2 LOOP  -- Repeat some intervals marked by in_load = '1'
96
      in_load <= '1';
97
      -- All combinations
98
      FOR I IN -2**(g_dat_w-1) TO 2**(g_dat_w-1)-1 LOOP
99
        in_dat <= TO_SVEC(I, g_dat_w);
100
        WAIT UNTIL rising_edge(clk);
101
        -- keep in_load low during rest of period
102
        in_load <= '0';
103
--         -- keep in_val low during rest of st_acc latency, to ease manual interpretation of out_acc as in_acc
104
--         in_val <= '0';
105
--         FOR J IN 1 TO c_pipeline-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
106
--         in_val <= '1';
107
      END LOOP;
108
    END LOOP;
109
    in_load <= '1';  -- keep '1' to avoid further toggling of out_acc (in a real design this would safe power)
110
    in_val <= '0';
111
    FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
112
    tb_end <= '1';
113
    WAIT;
114
  END PROCESS;
115
 
116
 
117
  ------------------------------------------------------------------------------
118
  -- DUT
119
  ------------------------------------------------------------------------------
120
 
121
  dut : ENTITY work.st_acc
122
  GENERIC MAP (
123
    g_dat_w            => g_dat_w,
124
    g_acc_w            => g_acc_w,
125
    g_hold_load        => g_hold_load,
126
    g_pipeline_input   => g_pipeline_input,
127
    g_pipeline_output  => g_pipeline_output
128
  )
129
  PORT MAP (
130
    clk        => clk,
131
    clken      => '1',
132
    in_load    => in_load,  -- start of accumulate period
133
    in_dat     => in_dat,
134
    in_acc     => in_acc,   -- use only one accumulator
135
    in_val     => in_val,
136
    out_acc    => out_acc,
137
    out_val    => out_val
138
  );
139
 
140
  in_acc <= out_acc WHEN c_pipeline>0 ELSE
141
            out_acc WHEN rising_edge(clk);  -- if DUT has no pipeline, then register feedback to avoid combinatorial loop
142
 
143
 
144
  ------------------------------------------------------------------------------
145
  -- Verify
146
  ------------------------------------------------------------------------------
147
 
148
  expected_acc <= func_acc(in_dat, in_acc, in_val, in_load);
149
 
150
  u_result : ENTITY common_components_lib.common_pipeline
151
  GENERIC MAP (
152
    g_representation => "SIGNED",
153
    g_pipeline       => c_pipeline,
154
    g_reset_value    => 0,
155
    g_in_dat_w       => g_acc_w,
156
    g_out_dat_w      => g_acc_w
157
  )
158
  PORT MAP (
159
    clk     => clk,
160
    clken   => '1',
161
    in_dat  => expected_acc,
162
    out_dat => expected_acc_p
163
  );
164
 
165
  p_verify : PROCESS(clk)
166
  BEGIN
167
    IF rising_edge(clk) THEN
168
      IF out_val='1' THEN
169
        ASSERT out_acc  = expected_acc_p REPORT "Error: wrong result" SEVERITY ERROR;
170
      END IF;
171
    END IF;
172
  END PROCESS;
173
 
174
END tb;

powered by: WebSVN 2.1.0

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