1 | -- datapath .vhd
|
2 |
|
3 | library ieee ;
|
4 | use ieee.std_logic_1164.all ;
|
5 | use work.pack.all;
|
6 |
|
7 | entity datapath is port( clk: in std_logic;
|
8 | input: in std_logic_vector(7 downto 0);
|
9 | ie: in std_logic;
|
10 | we: in std_logic;
|
11 | wa: in std_logic_vector(1 downto 0);
|
12 | rae: in std_logic;
|
13 | raa: in std_logic_vector(1 downto 0);
|
14 | rbe: in std_logic;
|
15 | rba: in std_logic_vector(1 downto 0);
|
16 | opcode: in std_logic_vector(2 downto 0);
|
17 | shsel: in std_logic_vector(1 downto 0);
|
18 | oe: in std_logic;
|
19 | output: out std_logic_vector(7 downto 0));
|
20 | end datapath ;
|
21 | architecture behavior of datapath is
|
22 |
|
23 | signal muxout, rfAout, rfBout: std_logic_vector(7 downto 0);
|
24 | signal aluout, shiftout, tristateout: std_logic_vector(7 downto 0);
|
25 |
|
26 | begin
|
27 | U0: mux2 port map( ie, input, shiftout, muxout );
|
28 | U1: regfile port map(clk,we,wa,muxout,rae,raa,rbe,rba,rfAout,rfBout );
|
29 | U2: alu port map( opcode, rfAout, rfBout, aluout );
|
30 | U3: shifter port map(shsel,aluout,shiftout);
|
31 | U4: tristatebuffer port map(oe, shiftout, tristateout);
|
32 | output <= tristateout;
|
33 | end behavior;
|
34 |
|
35 | -- mux2 .vhd
|
36 |
|
37 | library ieee ;
|
38 | use ieee.std_logic_1164.all ;
|
39 |
|
40 | entity mux2 is port( s: in std_logic; -- select line
|
41 | d1, d0: in std_logic_vector(7 downto 0); -- data bus input
|
42 | y: out std_logic_vector(7 downto 0)); -- data bus output
|
43 | end mux2;
|
44 | architecture behavior of mux2 is
|
45 | begin
|
46 | process(s, d1, d0)
|
47 | begin
|
48 | if(s = '0')then
|
49 | y <= d0;
|
50 | else
|
51 | y <= d1;
|
52 | end if;
|
53 | end process;
|
54 | end behavior;
|
55 |
|
56 | -- regfile .vhd
|
57 |
|
58 | library ieee ;
|
59 | use ieee.std_logic_1164.all ;
|
60 | use ieee.std_logic_unsigned.all;
|
61 | use ieee.numeric_std.all;
|
62 |
|
63 | entity regfile is port( clk: in std_logic; --clock
|
64 | we: in std_logic; --write enable WE
|
65 | wa: in std_logic_vector(1 downto 0); --write address WA
|
66 | input: in std_logic_vector(7 downto 0); --input
|
67 | rae: in std_logic; --read enable port A
|
68 | raa: in std_logic_vector(1 downto 0); --read address port A
|
69 | rbe: in std_logic; --read enable port B
|
70 | rba: in std_logic_vector(1 downto 0); --read address port B
|
71 | Aout, Bout: out std_logic_vector(7 downto 0)); --output port A & B
|
72 | end regfile;
|
73 | architecture behavior of regfile is
|
74 | subtype reg is std_logic_vector(7 downto 0);
|
75 | type regArray is array(0 to 3) of reg;
|
76 | signal rf: regArray; --register file contents
|
77 | begin
|
78 | WritePort: process(clk)
|
79 | begin
|
80 | if (clk'event and clk = '1')then
|
81 | if (we = '1')then
|
82 | rf(to_integer(unsigned(wa))) <= input;
|
83 | end if;
|
84 | end if;
|
85 | end process;
|
86 | ReadPortA: process(rae, raa)
|
87 | begin
|
88 | if (rae = '1') then
|
89 | Aout <= rf(to_integer(unsigned(raa))); -- convert bit VECTOR to integer
|
90 | else
|
91 | Aout <= (others => '0');
|
92 | end if;
|
93 | end process;
|
94 | ReadPortB: process(rbe, rba)
|
95 | begin
|
96 | if (rbe = '1') then
|
97 | Bout <= rf(to_integer(unsigned(rba))); -- convert bit VECTOR to integer
|
98 | else
|
99 | Bout <= (others => '0');
|
100 | end if;
|
101 | end process;
|
102 | end behavior;
|
103 |
|
104 | -- alu .vhd
|
105 |
|
106 | library ieee ;
|
107 | use ieee.std_logic_1164.all ;
|
108 | use ieee.std_logic_unsigned.all;
|
109 |
|
110 | entity alu is port( opcode: in std_logic_vector(2 downto 0); -- select for operations
|
111 | a, b: in std_logic_vector(7 downto 0); -- input operands
|
112 | f: out std_logic_vector(7 downto 0)); -- output
|
113 | end alu;
|
114 | architecture behavior of alu is
|
115 | begin
|
116 | PROCESS(opcode, a, b)
|
117 | begin
|
118 | case opcode is
|
119 | when "000" => f <= a; -- pass
|
120 | when "001" => f <= a and b; -- and
|
121 | when "010" => f <= a or b; -- or
|
122 | when "011" => f <= not b; -- not
|
123 | when "100" => f <= a + b; -- add
|
124 | when "101" => f <= a - b; -- substact
|
125 | when "110" => f <= a + 1; -- increment
|
126 | when "111" => f <= a - 1; -- decrement
|
127 | when others => f <= (others => '0');
|
128 | end case;
|
129 | end process;
|
130 | end behavior;
|
131 |
|
132 | -- shifter .vhd
|
133 |
|
134 | library ieee ;
|
135 | use ieee.std_logic_1164.all ;
|
136 |
|
137 | entity shifter is port( shsel: in std_logic_vector(1 downto 0); -- select for operations
|
138 | input: in std_logic_vector(7 downto 0); -- input operands
|
139 | output: out std_logic_vector(7 downto 0)); -- output
|
140 | end shifter;
|
141 | architecture behavior of shifter is
|
142 | begin
|
143 | process(shsel, input)
|
144 | begin
|
145 | case shsel is
|
146 | when "00" => output <= input; -- pass
|
147 | when "01" => output <= input(6 downto 0) & '0'; -- shift right
|
148 | when "10" => output <= '0' & input(7 downto 1); -- shift left
|
149 | when "11" => output <= input(0) & input(7 downto 1); -- rotate right
|
150 | when others => output <= (others => '0');
|
151 | end case;
|
152 | end process;
|
153 | end behavior;
|
154 |
|
155 | -- tristatebuffer .vhd
|
156 |
|
157 | library ieee ;
|
158 | use ieee.std_logic_1164.all ;
|
159 | use ieee.std_logic_arith.all;
|
160 | use ieee.std_logic_unsigned.all;
|
161 |
|
162 | entity tristatebuffer is port( e: in std_logic; -- single buffer input
|
163 | d: in std_logic_vector(7 downto 0); -- single buffer enable
|
164 | y: out std_logic_vector(7 downto 0)); -- single buffer output
|
165 | end tristatebuffer;
|
166 | architecture behavior of tristatebuffer is
|
167 | begin
|
168 | process (e, d) -- get error message if no d
|
169 | begin
|
170 | if (e = '1')then
|
171 | y <= d;
|
172 | else
|
173 | y <= (others => 'Z'); -- to get 8 Z values
|
174 | end if;
|
175 | end process;
|
176 | end behavior;
|
177 |
|
178 | -- datapath_tb .vhd
|
179 |
|
180 | library ieee;
|
181 | use ieee.std_logic_1164.all;
|
182 | use ieee.std_logic_arith.all;
|
183 | use ieee.std_logic_unsigned.all;
|
184 | use ieee.numeric_std.all;
|
185 |
|
186 | entity datapath_tb is
|
187 | end datapath_tb;
|
188 |
|
189 | architecture behavior of datapath_tb is
|
190 | -- Component Declaration for the Unit Under Test (UUT)
|
191 | component datapath port( clk: in std_logic;
|
192 | input: in std_logic_vector(7 downto 0);
|
193 | ie: in std_logic;
|
194 | we: in std_logic;
|
195 | wa: in std_logic_vector(1 downto 0);
|
196 | rae: in std_logic;
|
197 | raa: in std_logic_vector(1 downto 0);
|
198 | rbe: in std_logic;
|
199 | rba: in std_logic_vector(1 downto 0);
|
200 | opcode: in std_logic_vector(2 downto 0);
|
201 | shsel: in std_logic_vector(1 downto 0);
|
202 | oe: in std_logic;
|
203 | output: out std_logic_vector(7 downto 0));
|
204 | end component;
|
205 | --inputs
|
206 | signal clk : std_logic := '0';
|
207 | signal input : std_logic_vector(7 downto 0) := (others => '0');
|
208 | signal ie : std_logic := '0';
|
209 | signal we : std_logic := '0';
|
210 | signal wa : std_logic_vector(1 downto 0) := (others => '0');
|
211 | signal rae : std_logic := '0';
|
212 | signal raa : std_logic_vector(1 downto 0) := (others => '0');
|
213 | signal rbe : std_logic := '0';
|
214 | signal rba : std_logic_vector(1 downto 0) := (others => '0');
|
215 | signal opcode : std_logic_vector(2 downto 0) := (others => '0');
|
216 | signal shsel : std_logic_vector(1 downto 0) := (others => '0');
|
217 | signal oe : std_logic := '0';
|
218 | --Outputs
|
219 | signal output : std_logic_vector(7 downto 0);
|
220 | -- Clock period definitions
|
221 | constant clock_period : time := 50 ns;
|
222 |
|
223 | begin
|
224 |
|
225 | -- Instantiate the Unit Under Test (UUT)
|
226 | uut: datapath port map(clk, input, ie, we, wa, rae, raa, rbe, rba, opcode, shsel, oe, output);
|
227 |
|
228 | -- Clock process definitions
|
229 | clock_process :process
|
230 | begin
|
231 | clk <= '0';
|
232 | wait for clock_period/2;
|
233 | clk <= '1';
|
234 | wait for clock_period/2;
|
235 | end process;
|
236 |
|
237 | -- Stimulus process
|
238 | stim_proc: process
|
239 | begin
|
240 | -- hold reset state for 100 ns.
|
241 | --Initialize inputs
|
242 |
|
243 | input <= "00000000"; -- input binary 4
|
244 | ie <= '0'; --input enabled
|
245 | wa <= "00"; -- input stored in address binary 0
|
246 | we <= '0'; --write enabled
|
247 | raa <= "00";
|
248 | rae <= '0';
|
249 | rba <= "00";
|
250 | rbe <= '0';
|
251 | opcode <= "000";
|
252 | shsel <= "00";
|
253 | oe <= '0';
|
254 |
|
255 | wait for 50 ns;
|
256 | input <= "00000100"; -- input binary 4
|
257 | ie <= '1'; --input enabled
|
258 | wa <= "00"; -- input stored in address binary 0
|
259 | we <= '1'; --write enabled
|
260 | raa <= "00";
|
261 | rae <= '0';
|
262 | rba <= "00";
|
263 | rbe <= '0';
|
264 | opcode <= "000";
|
265 | shsel <= "00";
|
266 | oe <= '0';
|
267 |
|
268 | wait for 50 ns;
|
269 | input <= "00000000";
|
270 | ie <= '0';
|
271 | wa <= "01"; --store result of the operation done in the ALU in address binary 1 the result is 1000
|
272 | we <= '1'; --write in address enabled
|
273 | raa <= "00"; --read address 0 in A
|
274 | rae <= '1'; --read enabled
|
275 | rba <= "00"; --read address 0 in B
|
276 | rbe <= '1'; --read enabled
|
277 | opcode <= "100"; --add A + B = 100+100=1000
|
278 | shsel <= "00";
|
279 | oe <= '1';
|
280 |
|
281 | -- insert stimulus here
|
282 |
|
283 | wait;
|
284 | end process;
|
285 |
|
286 | end;
|
287 |
|
288 | --addresses 00 = 00000100 binary 4
|
289 | --addresses 01 = 00001000 result binary 8
|
290 | --addresses 10
|
291 | --addresses 11
|
292 |
|
293 | --pack. vhd
|
294 |
|
295 | library ieee ;
|
296 | use ieee.std_logic_1164.all ;
|
297 | package pack is
|
298 | component mux2 port( s: in std_logic; -- select lines
|
299 | d1, d0: in std_logic_vector(7 downto 0); -- data bus input
|
300 | y: out std_logic_vector(7 downto 0)); -- data bus output
|
301 | end component;
|
302 | component regfile port( clk: in std_logic; --clock
|
303 | we: in std_logic; --write enable WE
|
304 | wa: in std_logic_vector(1 downto 0); --write address WA
|
305 | input: in std_logic_vector(7 downto 0); --input
|
306 | rae: in std_logic; --read enable port A
|
307 | raa: in std_logic_vector(1 downto 0); --read address port A
|
308 | rbe: in std_logic; --read enable port B
|
309 | rba: in std_logic_vector(1 downto 0); --read address port B
|
310 | Aout, Bout: out std_logic_vector(7 downto 0)); --output port A & B
|
311 | end component;
|
312 | component alu port( opcode: in std_logic_vector(2 downto 0); -- select for operations
|
313 | a, b: in std_logic_vector(7 downto 0); -- input operands
|
314 | f: out std_logic_vector(7 downto 0)); -- output
|
315 | end component;
|
316 | component shifter port( shsel: in std_logic_vector(1 downto 0); -- select for operations
|
317 | input: in std_logic_vector(7 downto 0); -- input operands
|
318 | output: out std_logic_vector(7 downto 0)); -- output
|
319 | end component;
|
320 | component tristatebuffer port( e: in std_logic; -- single buffer input
|
321 | d: in std_logic_vector(7 downto 0); -- single buffer enable
|
322 | y: out std_logic_vector(7 downto 0)); -- single buffer output
|
323 | end component;
|
324 | end pack ;
|