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

Subversion Repositories ecpu_alu

[/] [ecpu_alu/] [trunk/] [alu/] [rtl/] [vhdl/] [alu_tb.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 leonous
--------------------------------------------------------------------------------
2
--------------------------------------------------------------------------------
3
-- Module   - Introduction to VLSI Design [03ELD005]
4
-- Lecturer - Dr V. M. Dwyer
5
-- Course   - MEng Electronic and Electrical Engineering
6
-- Year     - Part D
7
-- Student  - Sahrfili Leonous Matturi A028459 [elslm]
8
--------------------------------------------------------------------------------
9
--------------------------------------------------------------------------------
10
-- Final coursework 2004
11
-- 
12
-- Details:     Design and Layout of an ALU
13
--------------------------------------------------------------------------------
14
--------------------------------------------------------------------------------
15
 
16
--      Description     :       ALU testbench
17
--  Entity                      :       alu_tb
18
--      Architecture    :       behavioural
19
--  Created on          :       07/03/2004
20
 
21
library ieee;
22
 
23
use ieee.std_logic_1164.all;
24
use     ieee.std_logic_unsigned.all;
25
use ieee.std_logic_arith.all;           -- for unsigned()
26
 
27
use std.textio.all;                                     -- for file i/o
28
use work.txt_util.all;                          -- for string<->other types conversions
29
 
30
entity alu_tb is
31
end alu_tb;
32
 
33
architecture behavioural of alu_tb is
34
component alu
35
        port    (
36
                        A                       : in    std_logic_vector(7 downto 0);
37
                        B                       : in    std_logic_vector(7 downto 0);
38
                        S                       : in    std_logic_vector(3 downto 0);
39
                        Y                       : out   std_logic_vector(7 downto 0);
40
                        CLR             : in    std_logic                                       ;
41
                        CLK                     : in    std_logic                                       ;
42
                        C                       : out   std_logic                                       ;
43
                        V                       : out   std_logic                                       ;
44
                        Z                       : out   std_logic
45
                        );
46
end component;
47
 
48
-- ALU test vector record
49
type test_vector is record
50
        A                       : string(8 downto 1)    ; -- ALU input operand 1
51
        B                       : string(8 downto 1)    ; -- ALU input operand 2
52
        S                       : string(3 downto 1)    ; -- ALU input opcode
53
end record test_vector;
54
 
55
--      records to store stimulus for verification
56
signal  this_record, next_record        : test_vector;
57
-- ALU access signals
58
signal                  A                       : std_logic_vector(7 downto 0)   ;
59
signal                  B                       : std_logic_vector(7 downto 0)   ;
60
signal                  S                       : std_logic_vector(3 downto 0)   ;
61
signal                  Y                       : std_logic_vector(7 downto 0)   ;
62
signal                  CLR                     : std_logic                                             ;
63
signal                  CLK                     : std_logic                                             ;
64
signal                  C                       : std_logic                                             ;
65
signal                  V                       : std_logic                                             ;
66
signal                  Z                       : std_logic                                             ;
67
 
68
-- finished = '1' indicates end of test run
69
signal          finished                : std_logic;
70
 
71
-- used to synchronise verification with stimulus
72
signal          started                 :       boolean := false;
73
 
74
-- testbench clock half period                                  
75
constant        CLK_HALF_PERIOD : time  := 10 ns                                ;
76
constant        zero                    : std_logic_vector(7 downto 0)
77
                                                                        := (others => '0');
78
 
79
-- procedure to write a string to the screen
80
procedure writestr (s : string) is
81
        variable lout : line;
82
        begin
83
                write(lout, s);
84
                writeline(output, lout);
85
        end writestr;
86
 
87
-- procedure to write a character to the screen
88
procedure writechr (s : character) is
89
        variable lout : line;
90
        begin
91
                write(lout, s);
92
                writeline(output, lout);
93
        end writechr;
94
 
95
begin
96
 
97
        -- instantiate ALU
98
        alu_inst0       :       alu
99
                port map        (
100
                                        A                       ,
101
                                        B                       ,
102
                                        S                       ,
103
                                        Y                       ,
104
                                        CLR                     ,
105
                                        CLK                     ,
106
                                        C                       ,
107
                                        V                       ,
108
                                        Z
109
                                        );
110
 
111
        -- apply clock stimulus
112
        clock_stim      :       process
113
                                        begin
114
                                                CLK     <= '1', '0' after CLK_HALF_PERIOD;
115
 
116
                                                if (finished /= '1') then
117
                                                        wait for 2 * CLK_HALF_PERIOD;
118
                                                else
119
                                                        wait; -- end test
120
                                                end if;
121
                                        end process clock_stim;
122
 
123
        apply_test_vectors
124
                                :       process
125
                                        -- uncomment this line for VHDL '87 file i/o
126
                                        --file          infile  :       text is in "alu_test.txt";
127
                                        file            infile  :       text open read_mode is "alu_test.txt";
128
                                        variable        buff    :       line;
129
                                        variable        in_vec  :       test_vector;
130
                                        variable        aa, bb, yy
131
                                                                                : string(A'low  + 1 to A'high + 1);
132
                                        variable        ss, last_ss
133
                                                                                : string(1 to 3);
134
                                        variable        cc, vv, zz, clrc, space
135
                                                                                : character;
136
                                        variable        count   : integer;
137
 
138
                                        -- function to return the opcode as a std_logic_vector
139
                                        -- from the given string
140
                                        function        string2opcode(s: string) return std_logic_vector is
141
                                                variable        opcode : std_logic_vector(3 downto 0);
142
                                                begin
143
                                                        if              (s = "add") then
144
                                                                opcode := "0000";
145
                                                        elsif   (s = "inc") then
146
                                                                opcode := "0001";
147
                                                        elsif   (s = "sub") then
148
                                                                opcode := "0010";
149
                                                        elsif   (s = "cmp") then
150
                                                                opcode := "0011";
151
                                                        elsif   (s = "and") then
152
                                                                opcode := "1100";
153
                                                        elsif   (s = "or ") then
154
                                                                opcode := "1101";
155
                                                        elsif   (s = "xor") then
156
                                                                opcode := "1110";
157
                                                        elsif   (s = "cpl") then
158
                                                                opcode := "1111";
159
                                                        elsif   (s = "asl") then
160
                                                                opcode := "0100";
161
                                                        elsif   (s = "asr") then
162
                                                                opcode := "0101";
163
                                                        elsif   (s = "clr") then
164
                                                                opcode := "0110";
165
                                                        end if;
166
                                                        return opcode;
167
                                                end string2opcode;
168
                                        begin
169
                                                finished <= '0';
170
                                                count   := 0;
171
                                                CLR     <= '1';
172
                                                started <= false;
173
                                                while ( not endfile(infile) ) loop
174
                                                        count := count + 1;
175
                                                        -- verify outputs are as expected
176
                                                        readline        (infile, buff);
177
                                                        if (count = 1) then
178
                                                                readline        (infile, buff); -- first read was the header
179
                                                                writestr("**** Start of Test ****");
180
                                                        end if;
181
                                                        read            (buff, aa);
182
                                                        read            (buff, space);
183
 
184
                                                        read            (buff, bb);
185
                                                        read            (buff, space);
186
 
187
                                                        read            (buff, ss);
188
                                                        read            (buff, space);
189
 
190
                                                        read            (buff, clrc);
191
 
192
                                                        -- wait for falling edge of clk
193
                                                        wait until (CLK'event and CLK = '0');
194
                                                        -- wait for half of half a period
195
                                                        wait for (CLK_HALF_PERIOD / 2);
196
 
197
                                                        -- apply stimulus to inputs
198
                                                        A       <=      to_std_logic_vector(aa);
199
                                                        B       <=      to_std_logic_vector(bb);
200
                                                        S       <=      string2opcode(ss);
201
                                                        CLR     <=      to_std_logic(clrc);
202
 
203
                                                        -- store stimulus for use when verifying outputs
204
                                                        if (last_ss = "clr") then
205
                                                                next_record.A   <= str(zero);
206
                                                                next_record.B   <= str(zero);
207
                                                        else
208
                                                                next_record.A   <= aa;
209
                                                                next_record.B   <= bb;
210
                                                        end if;
211
                                                        next_record.S   <= ss;
212
                                                        last_ss                 := ss;
213
                                                        -- wait for rising edge of clock when data 
214
                                                        -- should be loaded from registers into ALU
215
                                                        wait until clk'event and clk = '1';
216
 
217
                                                        -- set local 'started' flag so verification can
218
                                                        -- start
219
                                                        -- grace period of 2 clock cycles for ALU to read
220
                                                        -- first set of data
221
                                                        if (clr = '0' and started = false) then
222
                                                                wait until clk'event and clk = '1';
223
                                                                wait until clk'event and clk = '1';
224
                                                                started <= true;
225
                                                        end if;
226
                                                end loop;
227
 
228
                                                -- end test
229
                                                finished <= '1';
230
                                                wait;
231
                                        end process apply_test_vectors;
232
 
233
        verify_test     :       process
234
                                        variable        result  : std_logic_vector(7 downto 0);
235
                                        variable        op1, op2: std_logic_vector(7 downto 0);
236
                                        begin
237
                                                -- await positive clock edge
238
                                                wait until clk'event and clk = '1';
239
                                                -- wait a little more after results appear
240
                                                wait for (CLK_HALF_PERIOD/2);
241
 
242
                                                -- get expected record
243
                                                this_record <= next_record;
244
 
245
                                                if (started = true and clr = '0') then
246
                                                        -- convert string operands from this_record
247
                                                        -- into std_logic_vectors
248
                                                        op1     := to_std_logic_vector(this_record.A);
249
                                                        op2     := to_std_logic_vector(this_record.B);
250
 
251
                                                        -- depending on opcode command string...perform
252
                                                        -- high level equivalent of ALU operation and store
253
                                                        -- in 'result'
254
                                                        if              (this_record.S = "add") then
255
                                                                result := op1 + op2;
256
                                                        elsif   (this_record.S = "inc") then
257
                                                                result := op1 + 1;
258
                                                        elsif   (this_record.S = "sub") then
259
                                                                result := op1 - op2;
260
                                                        elsif   (this_record.S = "cmp") then
261
                                                                result := y;
262
                                                        elsif   (this_record.S = "and") then
263
                                                                result := op1 and op2;
264
                                                        elsif   (this_record.S = "or ") then
265
                                                                result := op1 or op2;
266
                                                        elsif   (this_record.S = "xor") then
267
                                                                result := op1 xor op2;
268
                                                        elsif   (this_record.S = "cpl") then
269
                                                                result := not op2;
270
 
271
                                                        -- VHDL functions sla and sra require left operand = bit_vector
272
                                                        -- and right operand = integer
273
                                                        -- bv2slv [see above] converts bit_vector to std_logic_vector
274
                                                        elsif   (this_record.S = "asl") then
275
                                                                result := bv2slv(to_bitvector(op1) sla conv_integer(unsigned(op2 and x"07")));
276
                                                                -- Also, these functions fill shifted bit positions with 1s not 0s
277
                                                                -- so this has to be taken care of
278
                                                                if (conv_integer(unsigned(op2 and x"07")) > 0) then
279
                                                                        result(conv_integer(unsigned(op2 and x"07")) - 1 downto 0) := (others => '0');
280
                                                                end if;
281
                                                        elsif   (this_record.S = "asr") then
282
                                                                result := bv2slv(to_bitvector(op1) sra conv_integer(unsigned(op2 and x"07")));
283
                                                                if (conv_integer(unsigned(op2 and x"07")) > 1) then
284
                                                                        result(result'high - 1  downto result'high - conv_integer(unsigned(op2 and x"07")) + 1 ) := (others => '0');
285
                                                                end if;
286
                                                        elsif   (this_record.S = "clr") then
287
                                                                result := y;
288
                                                        end if;
289
 
290
                                                        writestr(hstr(to_std_logic_vector(this_record.A)) & " " & this_record.S & " " & hstr(to_std_logic_vector(this_record.B)) & " = " & hstr(Y) & " expected " & hstr(result));
291
                                                        assert Y = result
292
                                                                report "Output Y is wrong"
293
                                                                severity warning;
294
                                                        --assert C = to_std_logic(cc)
295
                                                        --      report "Output C is wrong"
296
                                                        --      severity warning;
297
                                                        --assert V = to_std_logic(vv)
298
                                                        --      report "Output V is wrong"
299
                                                        --      severity warning;
300
                                                        --assert Z = to_std_logic(zz)
301
                                                        --      report "Output Z is wrong"
302
                                                        --      severity warning;
303
                                                end if;
304
                                        end process verify_test;
305
 
306
    vector_stim_out : process ( A                       ,
307
                                B                       ,
308
                                S                       ,
309
                                Y                       ,
310
                                CLR                     ,
311
                                CLK                     ,
312
                                C                       ,
313
                                V                       ,
314
                                Z
315
                                )
316
--                 type out_vector is record
317
--                      A           : string(8 downto 0)   ;
318
--                      B           : string(8 downto 0)   ;
319
--                      S           : string(4 downto 0)   ;
320
--                      Y           : string(8 downto 0)   ;
321
--                      CLR         : string(1 downto 1)   ;
322
--                      CLK         : string(1 downto 1)   ;
323
--                      C           : string(1 downto 1)   ;
324
--                      V           : string(1 downto 1)   ;
325
--                      Z           : string(1 downto 1)   ;
326
--                 end record;
327
                                        file            infile  :       text open write_mode is "alu_test.out";
328
                    variable    buff    :   line    ;
329
                    constant    space   :   string := " ";
330
                begin
331
                    if (CLK'event) then
332
                        write (buff, str(A));
333
                        write (buff, space);
334
                        write (buff, str(B));
335
                        write (buff, space);
336
                        write (buff, str(S));
337
                        write (buff, space);
338
                        write (buff, str(Y));
339
                        write (buff, space);
340
                        write (buff, str(CLR));
341
                        write (buff, space);
342
                        write (buff, str(CLK));
343
                        write (buff, space);
344
                        write (buff, str(C));
345
                        write (buff, space);
346
                        write (buff, str(V));
347
                        write (buff, space);
348
                        write (buff, str(Z));
349
                        writeline (infile, buff);
350
                    end if;
351
 
352
                end process vector_stim_out;
353
end behavioural;
354
 

powered by: WebSVN 2.1.0

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