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

Subversion Repositories astron_adder

[/] [astron_adder/] [trunk/] [tb_common_add_sub.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_common_add_sub IS
28
  GENERIC (
29
    g_direction    : STRING := "SUB";  -- "SUB", "ADD" or "BOTH"
30
    g_sel_add      : STD_LOGIC :='1';  -- '0' = sub, '1' = add, only valid for g_direction = "BOTH"
31
    g_pipeline_in  : NATURAL := 0;     -- input pipelining 0 or 1
32
    g_pipeline_out : NATURAL := 2;     -- output pipelining >= 0
33
    g_in_dat_w     : NATURAL := 5;
34
    g_out_dat_w    : NATURAL := 5      -- g_in_dat_w or g_in_dat_w+1
35
  );
36
END tb_common_add_sub;
37
 
38
 
39
ARCHITECTURE tb OF tb_common_add_sub IS
40
 
41
  CONSTANT clk_period    : TIME := 10 ns;
42
  CONSTANT c_pipeline    : NATURAL := g_pipeline_in + g_pipeline_out;
43
 
44
  FUNCTION func_result(in_a, in_b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
45
    VARIABLE v_a, v_b, v_result : INTEGER;
46
  BEGIN
47
    -- Calculate expected result
48
    v_a := TO_SINT(in_a);
49
    v_b := TO_SINT(in_b);
50
    IF g_direction="ADD"                    THEN v_result := v_a + v_b; END IF;
51
    IF g_direction="SUB"                    THEN v_result := v_a - v_b; END IF;
52
    IF g_direction="BOTH" AND g_sel_add='1' THEN v_result := v_a + v_b; END IF;
53
    IF g_direction="BOTH" AND g_sel_add='0' THEN v_result := v_a - v_b; END IF;
54
    -- Wrap to avoid warning: NUMERIC_STD.TO_SIGNED: vector truncated
55
    IF v_result >  2**(g_out_dat_w-1)-1 THEN v_result := v_result - 2**g_out_dat_w; END IF;
56
    IF v_result < -2**(g_out_dat_w-1)   THEN v_result := v_result + 2**g_out_dat_w; END IF;
57
    RETURN TO_SVEC(v_result, g_out_dat_w);
58
  END;
59
 
60
  SIGNAL tb_end          : STD_LOGIC := '0';
61
  SIGNAL rst             : STD_LOGIC;
62
  SIGNAL clk             : STD_LOGIC := '0';
63
  SIGNAL in_a            : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
64
  SIGNAL in_b            : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
65
  SIGNAL out_result      : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);  -- combinatorial result
66
  SIGNAL result_expected : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);  -- pipelined results
67
  SIGNAL result_rtl      : STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
68
 
69
BEGIN
70
 
71
  clk  <= NOT clk OR tb_end AFTER clk_period/2;
72
 
73
  -- run 1 us or -all
74
  p_in_stimuli : PROCESS
75
  BEGIN
76
    rst <= '1';
77
    in_a <= TO_SVEC(0, g_in_dat_w);
78
    in_b <= TO_SVEC(0, g_in_dat_w);
79
    WAIT UNTIL rising_edge(clk);
80
    FOR I IN 0 TO 9 LOOP
81
      WAIT UNTIL rising_edge(clk);
82
    END LOOP;
83
    rst <= '0';
84
    FOR I IN 0 TO 9 LOOP
85
      WAIT UNTIL rising_edge(clk);
86
    END LOOP;
87
 
88
    -- Some special combinations
89
    in_a <= TO_SVEC(2, g_in_dat_w);
90
    in_b <= TO_SVEC(5, g_in_dat_w);
91
    WAIT UNTIL rising_edge(clk);
92
    in_a <= TO_SVEC(2, g_in_dat_w);
93
    in_b <= TO_SVEC(-5, g_in_dat_w);
94
    WAIT UNTIL rising_edge(clk);
95
    in_a <= TO_SVEC(-3, g_in_dat_w);
96
    in_b <= TO_SVEC(-9, g_in_dat_w);
97
    WAIT UNTIL rising_edge(clk);
98
    in_a <= TO_SVEC(-3, g_in_dat_w);
99
    in_b <= TO_SVEC(9, g_in_dat_w);
100
    WAIT UNTIL rising_edge(clk);
101
    in_a <= TO_SVEC(11, g_in_dat_w);
102
    in_b <= TO_SVEC(15, g_in_dat_w);
103
    WAIT UNTIL rising_edge(clk);
104
    in_a <= TO_SVEC(11, g_in_dat_w);
105
    in_b <= TO_SVEC(-15, g_in_dat_w);
106
    WAIT UNTIL rising_edge(clk);
107
    in_a <= TO_SVEC(-11, g_in_dat_w);
108
    in_b <= TO_SVEC(15, g_in_dat_w);
109
    WAIT UNTIL rising_edge(clk);
110
    in_a <= TO_SVEC(-11, g_in_dat_w);
111
    in_b <= TO_SVEC(-15, g_in_dat_w);
112
    WAIT UNTIL rising_edge(clk);
113
 
114
    FOR I IN 0 TO 49 LOOP
115
      WAIT UNTIL rising_edge(clk);
116
    END LOOP;
117
 
118
    -- All combinations
119
    FOR I IN -2**(g_in_dat_w-1) TO 2**(g_in_dat_w-1)-1 LOOP
120
      FOR J IN -2**(g_in_dat_w-1) TO 2**(g_in_dat_w-1)-1 LOOP
121
        in_a <= TO_SVEC(I, g_in_dat_w);
122
        in_b <= TO_SVEC(J, g_in_dat_w);
123
        WAIT UNTIL rising_edge(clk);
124
      END LOOP;
125
    END LOOP;
126
    WAIT UNTIL rising_edge(clk);
127
    tb_end <= '1';
128
    WAIT;
129
  END PROCESS;
130
 
131
  out_result <= func_result(in_a, in_b);
132
 
133
  u_result : ENTITY common_components_lib.common_pipeline
134
  GENERIC MAP (
135
    g_representation => "SIGNED",
136
    g_pipeline       => c_pipeline,
137
    g_reset_value    => 0,
138
    g_in_dat_w       => g_out_dat_w,
139
    g_out_dat_w      => g_out_dat_w
140
  )
141
  PORT MAP (
142
    rst     => rst,
143
    clk     => clk,
144
    clken   => '1',
145
    in_dat  => out_result,
146
    out_dat => result_expected
147
  );
148
 
149
  u_dut_rtl : ENTITY work.common_add_sub
150
  GENERIC MAP (
151
    g_direction       => g_direction,
152
    g_representation  => "SIGNED",
153
    g_pipeline_input  => g_pipeline_in,
154
    g_pipeline_output => g_pipeline_out,
155
    g_in_dat_w        => g_in_dat_w,
156
    g_out_dat_w       => g_out_dat_w
157
  )
158
  PORT MAP (
159
    clk     => clk,
160
    clken   => '1',
161
    sel_add => g_sel_add,
162
    in_a    => in_a,
163
    in_b    => in_b,
164
    result  => result_rtl
165
  );
166
 
167
  p_verify : PROCESS(rst, clk)
168
  BEGIN
169
    IF rst='0' THEN
170
      IF rising_edge(clk) THEN
171
        ASSERT result_rtl      = result_expected REPORT "Error: wrong RTL result" SEVERITY ERROR;
172
      END IF;
173
    END IF;
174
  END PROCESS;
175
 
176
END tb;

powered by: WebSVN 2.1.0

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