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

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [rtl/] [lxp32_execute.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 ring0_mipt
---------------------------------------------------------------------
2
-- Execution unit
3
--
4
-- Part of the LXP32 CPU
5
--
6
-- Copyright (c) 2016 by Alex I. Kuznetsov
7
--
8
-- The third stage of the LXP32 pipeline.
9
---------------------------------------------------------------------
10
 
11
library ieee;
12
use ieee.std_logic_1164.all;
13
 
14
entity lxp32_execute is
15
        generic(
16
                DBUS_RMW: boolean;
17
                DIVIDER_EN: boolean;
18
                MUL_ARCH: string
19
        );
20
        port(
21
                clk_i: in std_logic;
22
                rst_i: in std_logic;
23
 
24
                cmd_loadop3_i: in std_logic;
25
                cmd_signed_i: in std_logic;
26
                cmd_dbus_i: in std_logic;
27
                cmd_dbus_store_i: in std_logic;
28
                cmd_dbus_byte_i: in std_logic;
29
                cmd_addsub_i: in std_logic;
30
                cmd_mul_i: in std_logic;
31
                cmd_div_i: in std_logic;
32
                cmd_div_mod_i: in std_logic;
33
                cmd_cmp_i: in std_logic;
34
                cmd_jump_i: in std_logic;
35
                cmd_negate_op2_i: in std_logic;
36
                cmd_and_i: in std_logic;
37
                cmd_or_i: in std_logic;
38
                cmd_xor_i: in std_logic;
39
                cmd_shift_i: in std_logic;
40
                cmd_shift_right_i: in std_logic;
41
 
42
                jump_type_i: in std_logic_vector(3 downto 0);
43
 
44
                op1_i: in std_logic_vector(31 downto 0);
45
                op2_i: in std_logic_vector(31 downto 0);
46
                op3_i: in std_logic_vector(31 downto 0);
47
                dst_i: in std_logic_vector(7 downto 0);
48
 
49
                sp_waddr_o: out std_logic_vector(7 downto 0);
50
                sp_we_o: out std_logic;
51
                sp_wdata_o: out std_logic_vector(31 downto 0);
52
 
53
                valid_i: in std_logic;
54
                ready_o: out std_logic;
55
 
56
                dbus_cyc_o: out std_logic;
57
                dbus_stb_o: out std_logic;
58
                dbus_we_o: out std_logic;
59
                dbus_sel_o: out std_logic_vector(3 downto 0);
60
                dbus_ack_i: in std_logic;
61
                dbus_adr_o: out std_logic_vector(31 downto 2);
62
                dbus_dat_o: out std_logic_vector(31 downto 0);
63
                dbus_dat_i: in std_logic_vector(31 downto 0);
64
 
65
                jump_valid_o: out std_logic;
66
                jump_dst_o: out std_logic_vector(29 downto 0);
67
                jump_ready_i: in std_logic;
68
 
69
                interrupt_return_o: out std_logic;
70
                interrupts_enabled_o: out std_logic_vector(7 downto 0);
71
                interrupts_blocked_o: out std_logic_vector(7 downto 0)
72
        );
73
end entity;
74
 
75
architecture rtl of lxp32_execute is
76
 
77
-- Pipeline control signals
78
 
79
signal busy: std_logic;
80
signal can_execute: std_logic;
81
 
82
-- ALU signals
83
 
84
signal alu_result: std_logic_vector(31 downto 0);
85
signal alu_we: std_logic;
86
signal alu_busy: std_logic;
87
 
88
signal alu_cmp_eq: std_logic;
89
signal alu_cmp_ug: std_logic;
90
signal alu_cmp_sg: std_logic;
91
 
92
-- OP3 loader signals
93
 
94
signal loadop3_we: std_logic;
95
 
96
-- Jump machine signals
97
 
98
signal jump_condition: std_logic;
99
signal jump_valid: std_logic:='0';
100
signal jump_dst: std_logic_vector(jump_dst_o'range);
101
 
102
-- DBUS signals
103
 
104
signal dbus_result: std_logic_vector(31 downto 0);
105
signal dbus_busy: std_logic;
106
signal dbus_we: std_logic;
107
 
108
-- Result mux signals
109
 
110
signal result_mux: std_logic_vector(31 downto 0);
111
signal result_valid: std_logic;
112
signal result_regaddr: std_logic_vector(7 downto 0);
113
 
114
signal dst_reg: std_logic_vector(7 downto 0);
115
 
116
-- Signals related to interrupt handling
117
 
118
signal interrupt_return: std_logic:='0';
119
signal interrupts_enabled: std_logic_vector(7 downto 0):=(others=>'0');
120
signal interrupts_blocked: std_logic_vector(7 downto 0):=(others=>'0');
121
 
122
begin
123
 
124
-- Pipeline control
125
 
126
busy<=alu_busy or dbus_busy;
127
ready_o<=not busy;
128
can_execute<=valid_i and not busy;
129
 
130
-- ALU
131
 
132
alu_inst: entity work.lxp32_alu(rtl)
133
        generic map(
134
                DIVIDER_EN=>DIVIDER_EN,
135
                MUL_ARCH=>MUL_ARCH
136
        )
137
        port map(
138
                clk_i=>clk_i,
139
                rst_i=>rst_i,
140
 
141
                valid_i=>can_execute,
142
 
143
                cmd_signed_i=>cmd_signed_i,
144
                cmd_addsub_i=>cmd_addsub_i,
145
                cmd_mul_i=>cmd_mul_i,
146
                cmd_div_i=>cmd_div_i,
147
                cmd_div_mod_i=>cmd_div_mod_i,
148
                cmd_cmp_i=>cmd_cmp_i,
149
                cmd_negate_op2_i=>cmd_negate_op2_i,
150
                cmd_and_i=>cmd_and_i,
151
                cmd_or_i=>cmd_or_i,
152
                cmd_xor_i=>cmd_xor_i,
153
                cmd_shift_i=>cmd_shift_i,
154
                cmd_shift_right_i=>cmd_shift_right_i,
155
 
156
                op1_i=>op1_i,
157
                op2_i=>op2_i,
158
 
159
                result_o=>alu_result,
160
 
161
                cmp_eq_o=>alu_cmp_eq,
162
                cmp_ug_o=>alu_cmp_ug,
163
                cmp_sg_o=>alu_cmp_sg,
164
 
165
                we_o=>alu_we,
166
                busy_o=>alu_busy
167
        );
168
 
169
-- OP3 loader
170
 
171
loadop3_we<=can_execute and cmd_loadop3_i;
172
 
173
-- Jump logic
174
 
175
jump_condition<=(not cmd_cmp_i) or (jump_type_i(3) and alu_cmp_eq) or
176
        (jump_type_i(2) and not alu_cmp_eq) or (jump_type_i(1) and alu_cmp_ug) or
177
        (jump_type_i(0) and alu_cmp_sg);
178
 
179
process (clk_i) is
180
begin
181
        if rising_edge(clk_i) then
182
                if rst_i='1' then
183
                        jump_valid<='0';
184
                        interrupt_return<='0';
185
                else
186
                        if jump_valid='0' then
187
                                if can_execute='1' and cmd_jump_i='1' and jump_condition='1' then
188
                                        jump_valid<='1';
189
                                        jump_dst<=op1_i(31 downto 2);
190
                                        interrupt_return<=op1_i(0);
191
                                end if;
192
                        elsif jump_ready_i='1' then
193
                                jump_valid<='0';
194
                                interrupt_return<='0';
195
                        end if;
196
                end if;
197
        end if;
198
end process;
199
 
200
jump_valid_o<=jump_valid or (can_execute and cmd_jump_i and jump_condition);
201
jump_dst_o<=jump_dst when jump_valid='1' else op1_i(31 downto 2);
202
 
203
interrupt_return_o<=interrupt_return;
204
 
205
-- DBUS access
206
 
207
dbus_inst: entity work.lxp32_dbus(rtl)
208
        generic map(
209
                RMW=>DBUS_RMW
210
        )
211
        port map(
212
                clk_i=>clk_i,
213
                rst_i=>rst_i,
214
 
215
                valid_i=>can_execute,
216
 
217
                cmd_dbus_i=>cmd_dbus_i,
218
                cmd_dbus_store_i=>cmd_dbus_store_i,
219
                cmd_dbus_byte_i=>cmd_dbus_byte_i,
220
                cmd_signed_i=>cmd_signed_i,
221
                addr_i=>op1_i,
222
                wdata_i=>op2_i,
223
 
224
                rdata_o=>dbus_result,
225
                busy_o=>dbus_busy,
226
                we_o=>dbus_we,
227
 
228
                dbus_cyc_o=>dbus_cyc_o,
229
                dbus_stb_o=>dbus_stb_o,
230
                dbus_we_o=>dbus_we_o,
231
                dbus_sel_o=>dbus_sel_o,
232
                dbus_ack_i=>dbus_ack_i,
233
                dbus_adr_o=>dbus_adr_o,
234
                dbus_dat_o=>dbus_dat_o,
235
                dbus_dat_i=>dbus_dat_i
236
        );
237
 
238
-- Result multiplexer
239
 
240
result_mux_gen: for i in result_mux'range generate
241
        result_mux(i)<=(alu_result(i) and alu_we) or
242
                (op3_i(i) and loadop3_we) or
243
                (dbus_result(i) and dbus_we);
244
end generate;
245
 
246
result_valid<=alu_we or loadop3_we or dbus_we;
247
 
248
-- Write destination register
249
 
250
process (clk_i) is
251
begin
252
        if rising_edge(clk_i) then
253
                if can_execute='1' then
254
                        dst_reg<=dst_i;
255
                end if;
256
        end if;
257
end process;
258
 
259
result_regaddr<=dst_i when can_execute='1' else dst_reg;
260
 
261
sp_we_o<=result_valid;
262
sp_waddr_o<=result_regaddr;
263
sp_wdata_o<=result_mux;
264
 
265
process (clk_i) is
266
begin
267
        if rising_edge(clk_i) then
268
                if rst_i='1' then
269
                        interrupts_enabled<=(others=>'0');
270
                        interrupts_blocked<=(others=>'0');
271
                else
272
                        if result_valid='1' and result_regaddr=X"FC" then
273
                                interrupts_enabled<=result_mux(7 downto 0);
274
                                interrupts_blocked<=result_mux(15 downto 8);
275
                        end if;
276
                end if;
277
        end if;
278
end process;
279
 
280
interrupts_enabled_o<=interrupts_enabled;
281
interrupts_blocked_o<=interrupts_blocked;
282
 
283
end architecture;

powered by: WebSVN 2.1.0

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