-
Notifications
You must be signed in to change notification settings - Fork 0
/
alu_tb.vhd.bak
215 lines (179 loc) · 7.05 KB
/
alu_tb.vhd.bak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
-- A testbed for ALU
-- Author: Stephen Carter
-- stephen.carter@mail.mcgill.ca
-- Date: 02/05/2016
--
-- Testbench for ALU implemented , checks a few operations
-- uncomment remaining tests to perform a test of every operation possible.
-- delay is two clock cycles as to ensure that the status register is accurately checked
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.status_type.all;
entity alu_tb is
end entity;
architecture testbed of alu_tb is
-- define the ALU compontent to be tested
Component alu_16 is
Generic(
DATA_WIDTH : integer := 16
);
Port(
OPCODE : in unsigned(3 downto 0);
DATA0 : in signed(DATA_WIDTH-1 downto 0);
DATA1 : in signed(DATA_WIDTH-1 downto 0);
CLOCK : in std_logic;
RESET : in std_logic;
DATA_OUT : out signed(DATA_WIDTH-1 downto 0);
STATUS : out unsigned(3 downto 0)
);
end component;
CONSTANT DATA_WIDTH : integer := 16;
--The input signals with their initial values
Signal clk : std_logic := '0';
Signal reset_t : std_logic := '0';
Signal input1_t : signed(DATA_WIDTH-1 downto 0) := (others => '0');
Signal input2_t : signed(DATA_WIDTH-1 downto 0) := (others => '0');
Signal output_t : signed(DATA_WIDTH-1 downto 0) := (others => '0');
Signal opcode_t : unsigned(3 downto 0);
Signal status_t : unsigned(3 downto 0);
-- clock input
CONSTANT clk_period : time := 1 ns;
-- constants for OPCODE values as to improve readability and testability
CONSTANT ADD : unsigned(3 downto 0) := "0000";
CONSTANT SUB : unsigned(3 downto 0) := "0001";
CONSTANT NOT_IN : unsigned(3 downto 0) := "0010";
CONSTANT AND_IN : unsigned(3 downto 0) := "0011";
CONSTANT NAND_IN : unsigned(3 downto 0) := "0100";
CONSTANT OR_IN : unsigned(3 downto 0) := "0101";
CONSTANT NOR_IN : unsigned(3 downto 0) := "0110";
CONSTANT XOR_IN : unsigned(3 downto 0) := "0111";
CONSTANT XNOR_IN : unsigned(3 downto 0) := "1000";
CONSTANT ASL : unsigned(3 downto 0) := "1001";
CONSTANT ASR : unsigned(3 downto 0) := "1010";
CONSTANT LSL : unsigned(3 downto 0) := "1011";
CONSTANT LSR : unsigned(3 downto 0) := "1100";
-- Constant test values to improve readability and ease of use.
-- Results are still hardcoded
CONSTANT TEST1_NUM : signed(DATA_WIDTH-1 downto 0) := "0101010101010101"; --
CONSTANT TEST2_NUM : signed(DATA_WIDTH-1 downto 0) := "1010101010101010"; --
CONSTANT TEST3_NUM : signed(DATA_WIDTH-1 downto 0) := "1111111100000000"; --
CONSTANT TEST4_NUM : signed(DATA_WIDTH-1 downto 0) := "0000000011111111"; --
CONSTANT TEST5_NUM : signed(DATA_WIDTH-1 downto 0) := "1100111100000110"; --
CONSTANT TEST6_NUM : signed(DATA_WIDTH-1 downto 0) := "0100110011110011"; --
Begin
-- device under test
dut: alu_16 PORT MAP(OPCODE => opcode_t, DATA0 => input1_t, DATA1 => input2_t, CLOCK => clk, RESET => reset_t, DATA_OUT => output_t, STATUS => status_t);
-- process for clock
clk_process : Process
Begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- process for testing the operation
stim_process: process
Begin
--"Zero | Negative | Overflow | Parity"
reset_t <= '1';
wait for 1 * clk_period;
reset_t <= '0';
wait for 1 * clk_period;
-- test add
REPORT "begin test case for add function";
REPORT "test case confims parity is high for even bits and negative number";
opcode_t <= ADD;
input1_t <= TEST1_NUM;
input2_t <= TEST2_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "1111111111111111") REPORT "addition failed" SEVERITY ERROR;
ASSERT(status_t = "0101") REPORT "status output incorrect" SEVERITY ERROR;
REPORT "test case shows a status of no set values";
input1_t <= TEST1_NUM;
input2_t <= TEST4_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "0101011001010100") REPORT "addition failed" SEVERITY ERROR;
ASSERT(status_t = "0000") REPORT "status output incorrect" SEVERITY ERROR;
REPORT "test case confims parity is high for even bits and negative number";
input1_t <= TEST2_NUM;
input2_t <= TEST3_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "1010100110101010") REPORT "addition failed" SEVERITY ERROR;
ASSERT(status_t = "0101") REPORT "status output incorrect" SEVERITY ERROR;
--SUB
REPORT "begin test case for SUB function";
REPORT "checking condition with overflow";
opcode_t <= SUB;
input1_t <= TEST1_NUM;
input2_t <= TEST2_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "1010101010101011") REPORT "subtraction failed" SEVERITY ERROR;
ASSERT(status_t = "0110") REPORT "status output incorrect" SEVERITY ERROR;
REPORT "test case confims negative number and no parity bit set";
input1_t <= TEST5_NUM;
input2_t <= TEST6_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "1000001000010011") REPORT "subtraction failed" SEVERITY ERROR;
ASSERT(status_t = "0100") REPORT "status output incorrect" SEVERITY ERROR;
input1_t <= TEST3_NUM;
input2_t <= TEST6_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "1011001000001101") REPORT "subtraction failed" SEVERITY ERROR;
ASSERT(status_t = "0100") REPORT "status output incorrect" SEVERITY ERROR;
REPORT "checking condition with overflow -- Status is wrong to demonstrate non exiting error";
opcode_t <= SUB;
input1_t <= TEST1_NUM;
input2_t <= TEST2_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "1010101010101011") REPORT "subtraction failed" SEVERITY ERROR;
ASSERT(status_t = "0100") REPORT "status output incorrect" SEVERITY ERROR;
--AND
REPORT "begin test case for AND function";
REPORT "test case confirms function of zero number and even parity";
opcode_t <= AND_IN;
input1_t <= TEST1_NUM;
input2_t <= TEST2_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "0000000000000000") REPORT "AND failed" SEVERITY ERROR;
ASSERT(status_t = "1001") REPORT "status output incorrect" SEVERITY ERROR;
input1_t <= TEST2_NUM;
input2_t <= TEST2_NUM;
wait for 2 * clk_period;
ASSERT(output_t = TEST2_NUM) REPORT "AND failed" SEVERITY ERROR;
ASSERT(status_t = "0101") REPORT "status output incorrect" SEVERITY ERROR;
REPORT "test case confirms even parity";
input1_t <= TEST5_NUM;
input2_t <= TEST4_NUM;
wait for 2 * clk_period;
ASSERT(output_t = "0000000000000110") REPORT "AND failed" SEVERITY ERROR;
ASSERT(status_t = "0001") REPORT "status output incorrect" SEVERITY ERROR;
--ASR
REPORT "begin test case for ASR function: no overflow due to barrel shift";
REPORT "Parity and negative";
opcode_t <= ASR;
input1_t <= TEST2_NUM;
input2_t <= "0000000000000011";
wait for 2 * clk_period;
ASSERT(output_t = "1111010101010101") REPORT "ASR failed" SEVERITY ERROR;
ASSERT(status_t = "0101") REPORT "status output incorrect" SEVERITY ERROR;
REPORT "checking negative value";
input1_t <= TEST5_NUM;
input2_t <= "0000000000000001";
wait for 2 * clk_period;
ASSERT(output_t = "1110011110000011") REPORT "ASR failed" SEVERITY ERROR;
ASSERT(status_t = "0100") REPORT "status output incorrect" SEVERITY ERROR;
input1_t <= TEST1_NUM;
input2_t <= "0000000000000110";
wait for 2 * clk_period;
ASSERT(output_t = "0000000101010101") REPORT "ASR failed" SEVERITY ERROR;
ASSERT(status_t = "0000") REPORT "status output incorrect" SEVERITY ERROR;
reset_t <= '1';
wait for 1 * clk_period;
reset_t <= '0';
wait for 1 * clk_period;
WAIT;
end process;
end testbed;