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

Subversion Repositories arm4u

[/] [arm4u/] [trunk/] [hdl/] [execute.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Bregalad
-- This file is part of ARM4U CPU
2
-- 
3
-- This is a creation of the Laboratory of Processor Architecture
4
-- of Ecole Polytechnique Fédérale de Lausanne ( http://lap.epfl.ch )
5
--
6
-- execute.vhd  --  Description of the execute pipeline stage
7
--
8
-- Written By -  Jonathan Masur and Xavier Jimenez (2013)
9
--
10
-- This program is free software; you can redistribute it and/or modify it
11
-- under the terms of the GNU General Public License as published by the
12
-- Free Software Foundation; either version 2, or (at your option) any
13
-- later version.
14
--
15
-- This program is distributed in the hope that it will be useful,
16
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
17
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
-- GNU General Public License for more details.
19
--
20
-- In other words, you are welcome to use, share and improve this program.
21
-- You are forbidden to forbid anyone else to use, share and improve
22
-- what you give them.   Help stamp out software-hoarding!
23
 
24
library ieee;
25
use ieee.std_logic_1164.all;
26
use ieee.numeric_std.all;
27
use work.arm_types.all;
28
 
29
entity execute is
30
        port(
31
                clk : in std_logic;
32
                n_reset : in std_logic;
33
 
34
                exe_A_adr, exe_B_adr, exe_C_adr : in std_logic_vector(5 downto 0);
35
                exe_stage_valid : in std_logic;
36
                exe_barrelshift_operand : in std_logic;
37
                exe_barrelshift_type : in std_logic_vector(1 downto 0);
38
                exe_literal_shift_amnt : in std_logic_vector(4 downto 0);
39
                exe_literal_data : in std_logic_vector(23 downto 0);
40
                exe_opb_is_literal : in std_logic;
41
                exe_opb_sel : in std_logic;
42
                exe_alu_operation : in ALU_OPERATION;
43
                exe_condition : in std_logic_vector(3 downto 0);
44
                exe_affect_sflags : in std_logic;
45
                exe_data_sel : in std_logic;
46
                exe_rdest_wren : in std_logic;
47
                exe_rdest_adr : in std_logic_vector(4 downto 0);
48
                exe_branch_en : in std_logic;
49
                exe_wb_sel : in std_logic;
50
                exe_mem_ctrl : in MEM_OPERATION;
51
                exe_mem_burstcount : in std_logic_vector(3 downto 0);
52
 
53
                exe_pc_plus_4 : in unsigned(31 downto 0);
54
                exe_pc_plus_8 : in unsigned(31 downto 0);
55
                --- fowrarding signals to come here
56
 
57
                rfile_A_data : in std_logic_vector(31 downto 0);
58
                rfile_B_data : in std_logic_vector(31 downto 0);
59
                rfile_C_data : in std_logic_vector(31 downto 0);
60
 
61
                fwd_wb2_enable : in std_logic;
62
                fwd_wb2_address : in std_logic_vector(4 downto 0);
63
                fwd_wb2_data : in std_logic_vector(31 downto 0);
64
                fwd_wb1_enable : in std_logic;
65
                fwd_wb1_address : in std_logic_vector(4 downto 0);
66
                fwd_wb1_data : in std_logic_vector(31 downto 0);
67
                fwd_wb1_is_invalid : in std_logic;
68
                fwd_mem_enable : in std_logic;
69
                fwd_mem_address : in std_logic_vector(4 downto 0);
70
                fwd_mem_data : in std_logic_vector(31 downto 0);
71
                fwd_mem_is_invalid : in std_logic;
72
 
73
                mem_stage_valid : out std_logic;
74
                mem_rdest_wren : out std_logic;
75
                mem_rdest_adr : out std_logic_vector(4 downto 0);
76
                mem_branch_en : out std_logic;
77
                mem_wb_sel : out std_logic;
78
                mem_exe_data : out std_logic_vector(31 downto 0);
79
                mem_wrdata : out std_logic_vector(31 downto 0);
80
                mem_mem_ctrl : out MEM_OPERATION;
81
                mem_mem_burstcount : out std_logic_vector(3 downto 0);
82
 
83
                low_flags : out std_logic_vector(5 downto 0);
84
                exe_PC_wrdata : out unsigned(31 downto 0);
85
                exe_blocked_n : out std_logic;
86
                exe_PC_wr : out std_logic;
87
                exe_latch_enable : in std_logic
88
        );
89
end entity;
90
 
91
architecture rtl of execute is
92
 
93
        signal exe_data : std_logic_vector(31 downto 0);
94
        signal stage_active, forward_ok, forward_a_ok, forward_b_ok, forward_c_ok, condition_is_true : std_logic;
95
        signal barrelshift_out, alu_out, mult_out, alu_opb, op_a_data, op_b_data, op_c_data : unsigned(31 downto 0);
96
 
97
        signal n, z, v, c : std_logic;
98
        signal next_n, next_z, next_v, next_c, barrelshift_c : std_logic;
99
        signal lowflags, next_lowflags : std_logic_vector(5 downto 0);
100
 
101
begin
102
 
103
        -- output latch
104
        process(clk, n_reset) is
105
        begin
106
                if n_reset = '0'
107
                then
108
                        mem_stage_valid <= '0';
109
                elsif rising_edge(clk)
110
                then
111
                        if exe_latch_enable = '1'
112
                        then
113
                                mem_stage_valid <= stage_active;
114
                        end if;
115
                end if;
116
        end process;
117
 
118
        process(clk) is
119
        begin
120
                if rising_edge(clk)
121
                then
122
                        if exe_latch_enable = '1'
123
                        then
124
                                mem_rdest_wren <= exe_rdest_wren;
125
                                mem_rdest_adr <= exe_rdest_adr;
126
                                mem_branch_en <= exe_branch_en;
127
                                mem_wb_sel <= exe_wb_sel;
128
                                mem_exe_data <= exe_data;
129
                                mem_wrdata <= std_logic_vector(op_c_data);
130
                                mem_mem_ctrl <= exe_mem_ctrl;
131
                                mem_mem_burstcount <= exe_mem_burstcount;
132
                        end if;
133
                end if;
134
        end process;
135
 
136
        low_flags <= lowflags;
137
 
138
        -- enable stage condition
139
        stage_active <= exe_stage_valid and forward_ok and condition_is_true;
140
 
141
        exe_data <= std_logic_vector(alu_out) when exe_data_sel = '1' else std_logic_vector(exe_pc_plus_4);
142
        exe_pc_wrdata <= alu_out;
143
        exe_pc_wr <= exe_branch_en and (not exe_wb_sel) and stage_active;
144
 
145
        exe_blocked_n <= forward_ok or not (exe_stage_valid and condition_is_true);
146
 
147
        -- fowrawrding for operand a
148
        fwa : entity work.forwarding(rtl) port map
149
        (
150
                reg => exe_A_adr,
151
 
152
                fwd_wb2_enable => fwd_wb2_enable,
153
                fwd_wb2_address => fwd_wb2_address,
154
                fwd_wb2_data => fwd_wb2_data,
155
                fwd_wb1_enable => fwd_wb1_enable,
156
                fwd_wb1_address => fwd_wb1_address,
157
                fwd_wb1_data => fwd_wb1_data,
158
                fwd_wb1_is_invalid => fwd_wb1_is_invalid,
159
                fwd_mem_enable => fwd_mem_enable,
160
                fwd_mem_address => fwd_mem_address,
161
                fwd_mem_data => fwd_mem_data,
162
                fwd_mem_is_invalid => fwd_mem_is_invalid,
163
 
164
                exe_pc_plus_8 => exe_pc_plus_8,
165
                rfile_data => rfile_a_data,
166
 
167
                forward_ok => forward_a_ok,
168
                op_data => op_a_data
169
        );
170
 
171
        -- fowrawrding for operand b
172
        fwb : entity work.forwarding(rtl) port map
173
        (
174
                reg => exe_B_adr,
175
 
176
                fwd_wb2_enable => fwd_wb2_enable,
177
                fwd_wb2_address => fwd_wb2_address,
178
                fwd_wb2_data => fwd_wb2_data,
179
                fwd_wb1_enable => fwd_wb1_enable,
180
                fwd_wb1_address => fwd_wb1_address,
181
                fwd_wb1_data => fwd_wb1_data,
182
                fwd_wb1_is_invalid => fwd_wb1_is_invalid,
183
                fwd_mem_enable => fwd_mem_enable,
184
                fwd_mem_address => fwd_mem_address,
185
                fwd_mem_data => fwd_mem_data,
186
                fwd_mem_is_invalid => fwd_mem_is_invalid,
187
 
188
                exe_pc_plus_8 => exe_pc_plus_8,
189
                rfile_data => rfile_b_data,
190
 
191
                forward_ok => forward_b_ok,
192
                op_data => op_b_data
193
        );
194
 
195
        -- fowrawrding for operands c
196
        fwc : entity work.forwarding(rtl) port map
197
        (
198
                reg => exe_C_adr,
199
 
200
                fwd_wb2_enable => fwd_wb2_enable,
201
                fwd_wb2_address => fwd_wb2_address,
202
                fwd_wb2_data => fwd_wb2_data,
203
                fwd_wb1_enable => fwd_wb1_enable,
204
                fwd_wb1_address => fwd_wb1_address,
205
                fwd_wb1_data => fwd_wb1_data,
206
                fwd_wb1_is_invalid => fwd_wb1_is_invalid,
207
                fwd_mem_enable => fwd_mem_enable,
208
                fwd_mem_address => fwd_mem_address,
209
                fwd_mem_data => fwd_mem_data,
210
                fwd_mem_is_invalid => fwd_mem_is_invalid,
211
 
212
                exe_pc_plus_8 => exe_pc_plus_8,
213
                rfile_data => rfile_c_data,
214
 
215
                forward_ok => forward_c_ok,
216
                op_data => op_c_data
217
        );
218
        -- in order for the forwarding to work, all 3 of the operands have to work
219
        forward_ok <= forward_a_ok and forward_b_ok and forward_c_ok;
220
 
221
        -- check if the condition is true
222
        with exe_condition select condition_is_true <=
223
                z when COND_EQ,
224
                not z when COND_NE,
225
                c when COND_CS,
226
                not c when COND_CC,
227
                n when COND_MI,
228
                not n when COND_PL,
229
                v when COND_VS,
230
                not v when COND_VC,
231
                c and not z when COND_HI,
232
                z or not c when COND_LS,
233
                n xnor v when COND_GE,
234
                n xor v when COND_LT,
235
                (not z) and (n xnor v) when COND_GT,
236
                z or (n xor v) when COND_LE,
237
                '1' when COND_AL,
238
                '-' when others;
239
 
240
        -- barrel shifter (exernal component)
241
        bs : entity work.barrelshift(optimized) port map
242
        (
243
                c => c,
244
                exe_barrelshift_operand => exe_barrelshift_operand,
245
                exe_barrelshift_type => exe_barrelshift_type,
246
                exe_literal_shift_amnt => exe_literal_shift_amnt,
247
                exe_literal_data => exe_literal_data,
248
                exe_opb_is_literal => exe_opb_is_literal,
249
                op_b_data => op_b_data,
250
                op_c_data => op_c_data,
251
                barrelshift_c => barrelshift_c,
252
                barrelshift_out => barrelshift_out
253
        );
254
 
255
        -- multiplier unit
256
        multiplier : process(op_b_data, op_c_data) is
257
                variable mult_dummy : unsigned(63 downto 0);
258
        begin
259
                mult_dummy := op_b_data * op_c_data;
260
                mult_out <= mult_dummy(31 downto 0);
261
        end process;
262
 
263
        -- end process;
264
 
265
        -- alu opb multiplexer
266
        alu_opb <= mult_out when exe_opb_sel = '1' else barrelshift_out;
267
 
268
        -- alu
269
        alu : entity work.alu(rtl) port map
270
        (
271
                exe_alu_operation => exe_alu_operation,
272
                alu_o => alu_out,
273
                alu_opb => alu_opb,
274
                alu_opa => op_a_data,
275
                n => n,
276
                z => z,
277
                c => c,
278
                v => v,
279
                lowflags => lowflags,
280
                barrelshift_c => barrelshift_c,
281
                next_n => next_n,
282
                next_z => next_z,
283
                next_c => next_c,
284
                next_v => next_v,
285
                next_lowflags => next_lowflags
286
        );
287
 
288
        -- flags flip flops
289
        process(clk, n_reset) is
290
        begin
291
                if rising_edge(clk)
292
                then
293
                        if exe_affect_sflags = '1' and stage_active = '1' and exe_latch_enable = '1'
294
                        then
295
                                n <= next_n;
296
                                z <= next_z;
297
                                v <= next_v;
298
                                c <= next_c;
299
                                lowflags <= next_lowflags;
300
                        end if;
301
                end if;
302
        end process;
303
 
304
end architecture;

powered by: WebSVN 2.1.0

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