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 2

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

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

powered by: WebSVN 2.1.0

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