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 3

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
LIBRARY IEEE, common_pkg_lib, common_components_lib;
22
USE IEEE.std_logic_1164.ALL;
23
USE IEEE.numeric_std.ALL;
24
USE common_pkg_lib.common_pkg.ALL;
25
 
26
 
27
ENTITY tb_st_acc IS
28
  GENERIC (
29
    g_dat_w            : NATURAL := 6;
30
    g_acc_w            : NATURAL := 9;
31
    g_hold_load        : BOOLEAN := TRUE;
32
    g_pipeline_input   : NATURAL := 0;
33
    g_pipeline_output  : NATURAL := 4
34
  );
35
END tb_st_acc;
36
 
37
 
38
ARCHITECTURE tb OF tb_st_acc IS
39
 
40
  CONSTANT clk_period    : TIME := 10 ns;
41
 
42
  CONSTANT c_pipeline    : NATURAL := g_pipeline_input + g_pipeline_output;
43
 
44
  FUNCTION func_acc(in_dat, in_acc  : STD_LOGIC_VECTOR;
45
                    in_val, in_load : STD_LOGIC) RETURN STD_LOGIC_VECTOR IS
46
    VARIABLE v_dat, v_acc, v_result : INTEGER;
47
  BEGIN
48
    -- Calculate expected result
49
    IF in_val='0' THEN              -- hold: out_acc = in_acc
50
      v_result := TO_SINT(in_acc);
51
    ELSIF in_load='1' THEN           -- force: out_acc = 0 + in_dat
52
      v_result := TO_SINT(in_dat);
53
    ELSE                            -- accumulate: out_acc = in_acc + in_dat
54
      v_result := TO_SINT(in_dat) + TO_SINT(in_acc);
55
    END IF;
56
    -- Wrap to avoid warning: NUMERIC_STD.TO_SIGNED: vector truncated
57
    IF v_result >  2**(g_acc_w-1)-1 THEN v_result := v_result - 2**g_acc_w; END IF;
58
    IF v_result < -2**(g_acc_w-1)   THEN v_result := v_result + 2**g_acc_w; END IF;
59
    RETURN TO_SVEC(v_result, g_acc_w);
60
  END;
61
 
62
  SIGNAL tb_end          : STD_LOGIC := '0';
63
  SIGNAL clk             : STD_LOGIC := '0';
64
 
65
  SIGNAL in_dat          : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
66
  SIGNAL in_acc          : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0) := (OTHERS=>'0');
67
  SIGNAL in_val          : STD_LOGIC;
68
  SIGNAL in_load         : STD_LOGIC;
69
  SIGNAL out_val         : STD_LOGIC;
70
  SIGNAL out_acc         : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
71
 
72
  SIGNAL expected_acc_p  : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
73
  SIGNAL expected_acc    : STD_LOGIC_VECTOR(g_acc_w-1 DOWNTO 0);
74
 
75
BEGIN
76
 
77
  clk  <= NOT clk OR tb_end AFTER clk_period/2;
78
 
79
  ------------------------------------------------------------------------------
80
  -- Input stimuli
81
  ------------------------------------------------------------------------------
82
 
83
  -- run -all
84
  p_stimuli : PROCESS
85
  BEGIN
86
    in_load <= '0';
87
    in_dat <= TO_SVEC(0, g_dat_w);
88
    in_val <= '0';
89
    WAIT UNTIL rising_edge(clk);
90
    FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
91
 
92
    in_load <= '1';
93
    in_val <= '1';
94
    FOR R IN 0 TO 2 LOOP  -- Repeat some intervals marked by in_load = '1'
95
      in_load <= '1';
96
      -- All combinations
97
      FOR I IN -2**(g_dat_w-1) TO 2**(g_dat_w-1)-1 LOOP
98
        in_dat <= TO_SVEC(I, g_dat_w);
99
        WAIT UNTIL rising_edge(clk);
100
        -- keep in_load low during rest of period
101
        in_load <= '0';
102
--         -- keep in_val low during rest of st_acc latency, to ease manual interpretation of out_acc as in_acc
103
--         in_val <= '0';
104
--         FOR J IN 1 TO c_pipeline-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
105
--         in_val <= '1';
106
      END LOOP;
107
    END LOOP;
108
    in_load <= '1';  -- keep '1' to avoid further toggling of out_acc (in a real design this would safe power)
109
    in_val <= '0';
110
    FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
111
    tb_end <= '1';
112
    WAIT;
113
  END PROCESS;
114
 
115
 
116
  ------------------------------------------------------------------------------
117
  -- DUT
118
  ------------------------------------------------------------------------------
119
 
120
  dut : ENTITY work.st_acc
121
  GENERIC MAP (
122
    g_dat_w            => g_dat_w,
123
    g_acc_w            => g_acc_w,
124
    g_hold_load        => g_hold_load,
125
    g_pipeline_input   => g_pipeline_input,
126
    g_pipeline_output  => g_pipeline_output
127
  )
128
  PORT MAP (
129
    clk        => clk,
130
    clken      => '1',
131
    in_load    => in_load,  -- start of accumulate period
132
    in_dat     => in_dat,
133
    in_acc     => in_acc,   -- use only one accumulator
134
    in_val     => in_val,
135
    out_acc    => out_acc,
136
    out_val    => out_val
137
  );
138
 
139
  in_acc <= out_acc WHEN c_pipeline>0 ELSE
140
            out_acc WHEN rising_edge(clk);  -- if DUT has no pipeline, then register feedback to avoid combinatorial loop
141
 
142
 
143
  ------------------------------------------------------------------------------
144
  -- Verify
145
  ------------------------------------------------------------------------------
146
 
147
  expected_acc <= func_acc(in_dat, in_acc, in_val, in_load);
148
 
149
  u_result : ENTITY common_components_lib.common_pipeline
150
  GENERIC MAP (
151
    g_representation => "SIGNED",
152
    g_pipeline       => c_pipeline,
153
    g_reset_value    => 0,
154
    g_in_dat_w       => g_acc_w,
155
    g_out_dat_w      => g_acc_w
156
  )
157
  PORT MAP (
158
    clk     => clk,
159
    clken   => '1',
160
    in_dat  => expected_acc,
161
    out_dat => expected_acc_p
162
  );
163
 
164
  p_verify : PROCESS(clk)
165
  BEGIN
166
    IF rising_edge(clk) THEN
167
      IF out_val='1' THEN
168
        ASSERT out_acc  = expected_acc_p REPORT "Error: wrong result" SEVERITY ERROR;
169
      END IF;
170
    END IF;
171
  END PROCESS;
172
 
173
END tb;

powered by: WebSVN 2.1.0

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