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

Subversion Repositories rise

[/] [rise/] [trunk/] [vhdl/] [ex_stage.vhd] - Blame information for rev 79

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

Line No. Rev Author Line
1 8 jlechner
-------------------------------------------------------------------------------
2 2 jlechner
-- File: ex_stage.vhd
3
-- Author: Jakob Lechner, Urban Stadler, Harald Trinkl, Christian Walter
4
-- Created: 2006-11-29
5
-- Last updated: 2006-11-29
6
 
7
-- Description:
8
-- Execute stage
9
-------------------------------------------------------------------------------
10
 
11 79 cwalter
library UNISIM;
12
use UNISIM.vcomponents.all;
13
 
14 2 jlechner
library IEEE;
15
use IEEE.STD_LOGIC_1164.all;
16 8 jlechner
use IEEE.std_logic_signed.all;
17 2 jlechner
use IEEE.STD_LOGIC_ARITH.all;
18
 
19
use WORK.RISE_PACK.all;
20 71 jlechner
use work.RISE_PACK_SPECIFIC.all;
21 2 jlechner
 
22
entity ex_stage is
23
 
24
  port (
25
    clk                 : in std_logic;
26
    reset               : in std_logic;
27
 
28
    id_ex_register      : in ID_EX_REGISTER_T;
29
    ex_mem_register     : out EX_MEM_REGISTER_T;
30
 
31
    branch              : out std_logic;
32
    stall_in            : in std_logic;
33
    clear_in            : in std_logic;
34
    clear_out           : out std_logic);
35
 
36
end ex_stage;
37
 
38 79 cwalter
 
39
 
40 2 jlechner
architecture ex_stage_rtl of ex_stage is
41 8 jlechner
 
42
--  signal id_ex_register : ID_EX_REGISTER_T;
43 2 jlechner
 
44
  signal ex_mem_register_int     : EX_MEM_REGISTER_T;
45
  signal ex_mem_register_next    : EX_MEM_REGISTER_T;
46 8 jlechner
  signal isLoadOp : std_logic;
47
  signal isJmpOp : std_logic;
48
 
49
  signal aluop1_int : ALUOP1_T;
50
  signal aluop2_int : ALUOP2_T;
51
 
52
  signal execute : std_logic;
53
  signal clear_out_int : std_logic;
54
  signal branch_int : std_logic;
55
 
56 79 cwalter
  signal bs_arithmetic : std_logic;
57
  signal bs_left : std_logic;
58
  signal bs_out : REGISTER_T;
59
 
60 8 jlechner
  function isOverflowAdd (
61
    op1 : std_logic_vector;
62
    op2 : std_logic_vector;
63
    result : std_logic_vector)
64
    return std_logic is
65
    variable x : std_logic;
66
  begin
67
    x := '0';
68
    if op1(REGISTER_WIDTH-1) = '0' and op2(REGISTER_WIDTH-1) = '0' then
69
      x := result(REGISTER_WIDTH-1);
70
    end if;
71
    if op1(REGISTER_WIDTH-1) = '1' and op2(REGISTER_WIDTH-1) = '1' then
72
      x := not result(REGISTER_WIDTH-1);
73
    end if;
74
    return x;
75
  end isOverflowAdd;
76
 
77
  function isOverflowSub (
78
    op1 : std_logic_vector;
79
    op2 : std_logic_vector;
80
    result : std_logic_vector)
81
    return std_logic is
82
    variable x : std_logic;
83
  begin
84
    x := '0';
85
    if op1(REGISTER_WIDTH-1) = '0' and op2(REGISTER_WIDTH-1) = '1' then
86
      x := result(REGISTER_WIDTH-1);
87
    end if;
88
    if op1(REGISTER_WIDTH-1) = '1' and op2(REGISTER_WIDTH-1) = '0' then
89
      x := not result(REGISTER_WIDTH-1);
90
    end if;
91
 
92
    return x;
93
  end isOverflowSub;
94
 
95 79 cwalter
  component barrel_shifter
96
    port(
97
      reg_a      : in  std_logic_vector(15 downto 0);
98
      reg_b      : in  std_logic_vector(15 downto 0);
99
      left       : in  std_logic;
100
      arithmetic : in  std_logic;
101
      reg_q      : out std_logic_vector(15 downto 0)
102
      );
103
  end component;
104 2 jlechner
begin  -- ex_stage_rtl
105
 
106 8 jlechner
  ex_mem_register        <= ex_mem_register_int;
107 2 jlechner
 
108 79 cwalter
  bs : barrel_shifter port map(
109
    reg_a      => id_ex_register.rX,
110
    reg_b      => id_ex_register.rY,
111
    left       => bs_left,
112
    arithmetic => bs_arithmetic,
113
    reg_q      => bs_out
114
    );
115
 
116 8 jlechner
  output: process (clk, reset)
117
  begin  -- process
118
    if reset = '0' then                 -- asynchronous reset (active low)
119
      ex_mem_register_int.aluop1        <= (others => '0');
120
      ex_mem_register_int.aluop2        <= (others => '0');
121
      ex_mem_register_int.reg           <= (others => '0');
122
      ex_mem_register_int.alu           <= (others => '0');
123
      ex_mem_register_int.dreg_addr     <= (others => '0');
124
      ex_mem_register_int.lr            <= (others => '0');
125
      ex_mem_register_int.sr            <= (others => '0');
126
    elsif clk'event and clk = '1' then  -- rising clock edge
127
      -- if PIPELINE isn't stalled: update registers
128
      if stall_in = '0' then
129
        ex_mem_register_int        <= ex_mem_register_next;
130
        --id_ex_register <= id_ex_register_in;
131
        clear_out <= clear_out_int;
132
        branch <= branch_int;
133
      end if;
134
    end if;
135
  end process output;
136 2 jlechner
 
137 8 jlechner
  cond_check: process (id_ex_register, aluop1_int, aluop2_int)
138
  begin  -- process cond_check
139
    execute <= '0';
140
 
141
    case id_ex_register.cond is
142
      when COND_UNCONDITIONAL =>
143
        execute <= '1';
144
      when COND_NOT_ZERO =>
145
        if id_ex_register.sr(SR_ZERO_BIT) = '0' then
146
          execute <= '1';
147
        end if;
148
      when COND_ZERO =>
149
        if id_ex_register.sr(SR_ZERO_BIT) = '1' then
150
          execute <= '1';
151
        end if;
152
      when COND_CARRY =>
153
        if id_ex_register.sr(SR_CARRY_BIT) = '1' then
154
          execute <= '1';
155
        end if;
156
      when COND_NEGATIVE =>
157
        if id_ex_register.sr(SR_NEGATIVE_BIT) = '1' then
158
          execute <= '1';
159
        end if;
160
      when COND_OVERFLOW =>
161
        if id_ex_register.sr(SR_OVERFLOW_BIT) = '1' then
162
          execute <= '1';
163
        end if;
164
      when COND_ZERO_NEGATIVE =>
165
        if id_ex_register.sr(SR_ZERO_BIT) = '1' or
166
          id_ex_register.sr(SR_ZERO_BIT) = '1' then
167
          execute <= '1';
168
        end if;
169
      when others => null;
170
    end case;
171
  end process cond_check;
172
 
173
  aluop: process (execute, aluop1_int, aluop2_int, clear_in)
174
  begin  -- process aluop
175
    -- insert nop in pipeline if instruction is conditional and
176
    -- condition is not met, or if pipeline is cleared
177
    if execute = '0' or clear_in = '1' then
178
      ex_mem_register_next.aluop1 <= (others => '0');
179
      ex_mem_register_next.aluop2 <= (others => '0');
180
    else
181
      ex_mem_register_next.aluop1 <= aluop1_int;
182
      ex_mem_register_next.aluop2 <= aluop2_int;
183
    end if;
184
  end process aluop;
185
 
186 79 cwalter
  alu: process (id_ex_register, ex_mem_register_next, bs_out)
187 8 jlechner
  begin
188
 
189
    ex_mem_register_next.alu <= (others => '0');
190
    ex_mem_register_next.dreg_addr <= id_ex_register.rX_addr;
191
    ex_mem_register_next.reg <= (others => '0');
192
    ex_mem_register_next.lr <= (others => '0');
193
    ex_mem_register_next.sr <= (others => '0');
194
 
195
    aluop1_int(ALUOP1_LD_MEM_BIT) <= '0';
196
    aluop1_int(ALUOP1_ST_MEM_BIT) <= '0';
197
    aluop1_int(ALUOP1_WB_REG_BIT) <= '1';
198
 
199
    aluop2_int <=  (ALUOP2_LR_BIT => '0', ALUOP2_SR_BIT => '1', others => '0');
200
 
201
    isLoadOp <= '0';
202
    isJmpOp <= '0';
203
 
204
    case id_ex_register.opcode is
205
      -- load opcodes
206
      when OPCODE_LD_IMM =>
207
        ex_mem_register_next.alu <= x"00" & id_ex_register.immediate(7 downto 0);
208
        isLoadOp <= '1';
209
      when OPCODE_LD_IMM_HB =>
210
        ex_mem_register_next.alu <= id_ex_register.rX or (id_ex_register.immediate(7 downto 0) & x"00");
211
        isLoadOp <= '1';
212
      when OPCODE_LD_DISP =>
213
        ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
214
        aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
215
        isLoadOp <= '1';
216
      when OPCODE_LD_DISP_MS =>
217
        ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
218
        aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
219
        isLoadOp <= '1';
220
      when OPCODE_LD_REG =>
221
        ex_mem_register_next.alu <= id_ex_register.rY;
222
        isLoadOp <= '1';
223
 
224
        -- store opcodes
225
      when OPCODE_ST_DISP =>
226
        ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
227
        ex_mem_register_next.reg <= id_ex_register.rX;
228
        aluop1_int(ALUOP1_ST_MEM_BIT) <= '1';
229
        aluop2_int(ALUOP2_SR_BIT) <= '0';
230
 
231
        -- arithmetic opcodes
232
      when OPCODE_ADD =>
233
        ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.rY;
234
        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowAdd(id_ex_register.rX,
235
                                                                  id_ex_register.rY,
236
                                                                  ex_mem_register_next.alu);
237
      when OPCODE_ADD_IMM =>
238
        ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.immediate;
239
        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowAdd(id_ex_register.rX,
240
                                                                  id_ex_register.immediate,
241
                                                                  ex_mem_register_next.alu);
242
      when OPCODE_SUB =>
243
        ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.rY;
244
        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowSub(id_ex_register.rX,
245
                                                                  id_ex_register.rY,
246
                                                                  ex_mem_register_next.alu);
247
      when OPCODE_SUB_IMM =>
248
        ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.immediate;
249
        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= isOverflowSub(id_ex_register.rX,
250
                                                                  id_ex_register.immediate,
251
                                                                  ex_mem_register_next.alu);
252
      when OPCODE_NEG =>
253
        ex_mem_register_next.alu <= not id_ex_register.rY + x"0001";
254 79 cwalter
--      when OPCODE_ALS =>
255
--        ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
256
--        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
257
--                                                    id_ex_register.rY(REGISTER_WIDTH-2);
258
--      when OPCODE_ARS =>
259
--        ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-1) & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
260 8 jlechner
      when OPCODE_ALS =>
261 79 cwalter
        bs_left                                  <= '1';
262
        bs_arithmetic                            <= '1';
263
        ex_mem_register_next.alu                 <= bs_out;
264 8 jlechner
        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
265
                                                    id_ex_register.rY(REGISTER_WIDTH-2);
266
      when OPCODE_ARS =>
267 79 cwalter
        bs_left                                  <= '0';
268
        bs_arithmetic                            <= '1';
269
        ex_mem_register_next.alu                 <= bs_out;
270
        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
271
                                                    id_ex_register.rY(REGISTER_WIDTH-2);
272 8 jlechner
        -- logical opcodes
273
      when OPCODE_AND =>
274
        ex_mem_register_next.alu <= id_ex_register.rX and id_ex_register.rY;
275
      when OPCODE_NOT =>
276
        ex_mem_register_next.alu <= not id_ex_register.rY;
277
      when OPCODE_EOR =>
278
        ex_mem_register_next.alu <= id_ex_register.rX xor id_ex_register.rY;
279 79 cwalter
--      when OPCODE_LS =>
280
--        ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
281
--      when OPCODE_RS =>
282
--        ex_mem_register_next.alu <= "0" & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
283 8 jlechner
      when OPCODE_LS =>
284 79 cwalter
        bs_left                  <= '1';
285
        bs_arithmetic            <= '0';
286
        ex_mem_register_next.alu <= bs_out;
287 8 jlechner
      when OPCODE_RS =>
288 79 cwalter
        bs_left                  <= '0';
289
        bs_arithmetic            <= '0';
290
        ex_mem_register_next.alu <= bs_out;
291 8 jlechner
        -- program control
292
      when OPCODE_JMP =>
293
        ex_mem_register_next.lr             <= id_ex_register.pc;
294
        ex_mem_register_next.dreg_addr      <= PC_ADDR;
295
        ex_mem_register_next.alu            <= id_ex_register.rX;
296
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
297
        aluop2_int(ALUOP2_SR_BIT) <= '0';
298
        aluop2_int(ALUOP2_LR_BIT) <= '1';
299
        isJmpOp <= '1';
300
 
301
      when OPCODE_NOP =>
302
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
303
        aluop2_int(ALUOP2_SR_BIT) <= '0';
304
 
305
      when OPCODE_TST =>
306
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
307
        aluop2_int(ALUOP2_SR_BIT) <= '1';
308
 
309
      when others =>
310
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
311
        aluop2_int(ALUOP2_SR_BIT) <= '0';
312
 
313
    end case;
314
  end process;
315
 
316
  branch_logic: process (id_ex_register, isLoadOp, isJmpOp)
317
  begin  -- process branch_logic
318
    branch_int <= '0';
319
    clear_out_int <= '0';
320
    if (id_ex_register.rX_addr = PC_ADDR and isLoadOp = '1') or (isJmpOp = '1') then
321
      branch_int <= '1';
322
      clear_out_int <= '1';
323
    end if;
324
  end process branch_logic;
325
 
326 2 jlechner
end ex_stage_rtl;

powered by: WebSVN 2.1.0

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