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

Subversion Repositories rise

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

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 90 jlechner
    clear_out           : out std_logic;
35
    clear_locks         : out std_logic);
36 2 jlechner
 
37
end ex_stage;
38
 
39 79 cwalter
 
40
 
41 2 jlechner
architecture ex_stage_rtl of ex_stage is
42 8 jlechner
 
43
--  signal id_ex_register : ID_EX_REGISTER_T;
44 2 jlechner
 
45
  signal ex_mem_register_int     : EX_MEM_REGISTER_T;
46
  signal ex_mem_register_next    : EX_MEM_REGISTER_T;
47 8 jlechner
  signal isLoadOp : std_logic;
48
  signal isJmpOp : std_logic;
49
 
50
  signal aluop1_int : ALUOP1_T;
51
  signal aluop2_int : ALUOP2_T;
52
 
53
  signal execute : std_logic;
54
  signal clear_out_int : std_logic;
55
  signal branch_int : std_logic;
56
 
57 79 cwalter
  signal bs_arithmetic : std_logic;
58
  signal bs_left : std_logic;
59
  signal bs_out : REGISTER_T;
60
 
61 8 jlechner
  function isOverflowAdd (
62
    op1 : std_logic_vector;
63
    op2 : std_logic_vector;
64
    result : std_logic_vector)
65
    return std_logic is
66
    variable x : std_logic;
67
  begin
68
    x := '0';
69
    if op1(REGISTER_WIDTH-1) = '0' and op2(REGISTER_WIDTH-1) = '0' then
70
      x := result(REGISTER_WIDTH-1);
71
    end if;
72
    if op1(REGISTER_WIDTH-1) = '1' and op2(REGISTER_WIDTH-1) = '1' then
73
      x := not result(REGISTER_WIDTH-1);
74
    end if;
75
    return x;
76
  end isOverflowAdd;
77
 
78
  function isOverflowSub (
79
    op1 : std_logic_vector;
80
    op2 : std_logic_vector;
81
    result : std_logic_vector)
82
    return std_logic is
83
    variable x : std_logic;
84
  begin
85
    x := '0';
86
    if op1(REGISTER_WIDTH-1) = '0' and op2(REGISTER_WIDTH-1) = '1' then
87
      x := result(REGISTER_WIDTH-1);
88
    end if;
89
    if op1(REGISTER_WIDTH-1) = '1' and op2(REGISTER_WIDTH-1) = '0' then
90
      x := not result(REGISTER_WIDTH-1);
91
    end if;
92
 
93
    return x;
94
  end isOverflowSub;
95
 
96 96 cwalter
  procedure getSRStatusBits ( value : in REGISTER_T; sr_reg : out SR_REGISTER_T ) is
97
  begin
98
    if value = CONV_STD_LOGIC_VECTOR(0, REGISTER_WIDTH) then
99
      sr_reg( SR_REGISTER_ZERO ) := '1';
100
    else
101
      sr_reg( SR_REGISTER_ZERO ) := '0';
102
    end if;
103
    if value( REGISTER_WIDTH - 1 ) = '1' then
104
      sr_reg( SR_REGISTER_NEGATIVE ) := '1';
105
    else
106
      sr_reg( SR_REGISTER_NEGATIVE ) := '0';
107
    end if;
108
  end getSRStatusBits;
109
 
110 79 cwalter
  component barrel_shifter
111
    port(
112
      reg_a      : in  std_logic_vector(15 downto 0);
113
      reg_b      : in  std_logic_vector(15 downto 0);
114
      left       : in  std_logic;
115
      arithmetic : in  std_logic;
116
      reg_q      : out std_logic_vector(15 downto 0)
117
      );
118
  end component;
119 2 jlechner
begin  -- ex_stage_rtl
120
 
121 8 jlechner
  ex_mem_register        <= ex_mem_register_int;
122 2 jlechner
 
123 79 cwalter
  bs : barrel_shifter port map(
124
    reg_a      => id_ex_register.rX,
125
    reg_b      => id_ex_register.rY,
126
    left       => bs_left,
127
    arithmetic => bs_arithmetic,
128
    reg_q      => bs_out
129
    );
130
 
131 8 jlechner
  output: process (clk, reset)
132
  begin  -- process
133
    if reset = '0' then                 -- asynchronous reset (active low)
134
      ex_mem_register_int.aluop1        <= (others => '0');
135
      ex_mem_register_int.aluop2        <= (others => '0');
136
      ex_mem_register_int.reg           <= (others => '0');
137
      ex_mem_register_int.alu           <= (others => '0');
138
      ex_mem_register_int.dreg_addr     <= (others => '0');
139
      ex_mem_register_int.lr            <= (others => '0');
140
      ex_mem_register_int.sr            <= (others => '0');
141
    elsif clk'event and clk = '1' then  -- rising clock edge
142
      -- if PIPELINE isn't stalled: update registers
143
      if stall_in = '0' then
144
        ex_mem_register_int        <= ex_mem_register_next;
145
        --id_ex_register <= id_ex_register_in;
146
        clear_out <= clear_out_int;
147
        branch <= branch_int;
148
      end if;
149
    end if;
150
  end process output;
151 2 jlechner
 
152 8 jlechner
  cond_check: process (id_ex_register, aluop1_int, aluop2_int)
153
  begin  -- process cond_check
154
    execute <= '0';
155
 
156
    case id_ex_register.cond is
157
      when COND_UNCONDITIONAL =>
158
        execute <= '1';
159
      when COND_NOT_ZERO =>
160
        if id_ex_register.sr(SR_ZERO_BIT) = '0' then
161
          execute <= '1';
162
        end if;
163
      when COND_ZERO =>
164
        if id_ex_register.sr(SR_ZERO_BIT) = '1' then
165
          execute <= '1';
166
        end if;
167
      when COND_CARRY =>
168
        if id_ex_register.sr(SR_CARRY_BIT) = '1' then
169
          execute <= '1';
170
        end if;
171
      when COND_NEGATIVE =>
172
        if id_ex_register.sr(SR_NEGATIVE_BIT) = '1' then
173
          execute <= '1';
174
        end if;
175
      when COND_OVERFLOW =>
176
        if id_ex_register.sr(SR_OVERFLOW_BIT) = '1' then
177
          execute <= '1';
178
        end if;
179
      when COND_ZERO_NEGATIVE =>
180
        if id_ex_register.sr(SR_ZERO_BIT) = '1' or
181
          id_ex_register.sr(SR_ZERO_BIT) = '1' then
182
          execute <= '1';
183
        end if;
184
      when others => null;
185
    end case;
186
  end process cond_check;
187
 
188
  aluop: process (execute, aluop1_int, aluop2_int, clear_in)
189
  begin  -- process aluop
190
    -- insert nop in pipeline if instruction is conditional and
191
    -- condition is not met, or if pipeline is cleared
192
    if execute = '0' or clear_in = '1' then
193
      ex_mem_register_next.aluop1 <= (others => '0');
194
      ex_mem_register_next.aluop2 <= (others => '0');
195
    else
196
      ex_mem_register_next.aluop1 <= aluop1_int;
197
      ex_mem_register_next.aluop2 <= aluop2_int;
198
    end if;
199
  end process aluop;
200
 
201 79 cwalter
  alu: process (id_ex_register, ex_mem_register_next, bs_out)
202 96 cwalter
    variable new_sr : SR_REGISTER_T;
203 8 jlechner
  begin
204
 
205 96 cwalter
    new_sr := id_ex_register.sr;
206 8 jlechner
    ex_mem_register_next.alu <= (others => '0');
207
    ex_mem_register_next.dreg_addr <= id_ex_register.rX_addr;
208
    ex_mem_register_next.reg <= (others => '0');
209
    ex_mem_register_next.lr <= (others => '0');
210 99 cwalter
 
211 8 jlechner
    aluop1_int(ALUOP1_LD_MEM_BIT) <= '0';
212
    aluop1_int(ALUOP1_ST_MEM_BIT) <= '0';
213
    aluop1_int(ALUOP1_WB_REG_BIT) <= '1';
214
 
215
    aluop2_int <=  (ALUOP2_LR_BIT => '0', ALUOP2_SR_BIT => '1', others => '0');
216
 
217
    isLoadOp <= '0';
218
    isJmpOp <= '0';
219 99 cwalter
    bs_left <= '0';
220
    bs_arithmetic <= '0';
221 8 jlechner
    case id_ex_register.opcode is
222
      -- load opcodes
223
      when OPCODE_LD_IMM =>
224
        ex_mem_register_next.alu <= x"00" & id_ex_register.immediate(7 downto 0);
225 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
226 8 jlechner
        isLoadOp <= '1';
227
      when OPCODE_LD_IMM_HB =>
228
        ex_mem_register_next.alu <= id_ex_register.rX or (id_ex_register.immediate(7 downto 0) & x"00");
229 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
230 8 jlechner
        isLoadOp <= '1';
231
      when OPCODE_LD_DISP =>
232
        ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
233
        aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
234
        isLoadOp <= '1';
235
      when OPCODE_LD_DISP_MS =>
236
        ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
237
        aluop1_int(ALUOP1_LD_MEM_BIT) <= '1';
238
        isLoadOp <= '1';
239
      when OPCODE_LD_REG =>
240
        ex_mem_register_next.alu <= id_ex_register.rY;
241
        isLoadOp <= '1';
242
 
243
        -- store opcodes
244
      when OPCODE_ST_DISP =>
245
        ex_mem_register_next.alu <= id_ex_register.rY + id_ex_register.rZ;
246
        ex_mem_register_next.reg <= id_ex_register.rX;
247 96 cwalter
        getSRStatusBits( ex_mem_register_next.reg, new_sr );
248 8 jlechner
        aluop1_int(ALUOP1_ST_MEM_BIT) <= '1';
249
        aluop2_int(ALUOP2_SR_BIT) <= '0';
250 105 cwalter
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
251 8 jlechner
 
252
        -- arithmetic opcodes
253
      when OPCODE_ADD =>
254
        ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.rY;
255 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
256
        new_sr(SR_OVERFLOW_BIT) := isOverflowAdd(id_ex_register.rX,
257
                                                 id_ex_register.rY,
258
                                                 ex_mem_register_next.alu);
259 8 jlechner
      when OPCODE_ADD_IMM =>
260
        ex_mem_register_next.alu <= id_ex_register.rX + id_ex_register.immediate;
261 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
262
        new_sr(SR_OVERFLOW_BIT) := isOverflowAdd(id_ex_register.rX,
263
                                                id_ex_register.immediate,
264
                                                ex_mem_register_next.alu);
265 8 jlechner
      when OPCODE_SUB =>
266
        ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.rY;
267 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
268
        new_sr(SR_OVERFLOW_BIT) := isOverflowSub(id_ex_register.rX,
269
                                                 id_ex_register.rY,
270
                                                 ex_mem_register_next.alu);
271 8 jlechner
      when OPCODE_SUB_IMM =>
272
        ex_mem_register_next.alu <= id_ex_register.rX - id_ex_register.immediate;
273 96 cwalter
        getSRStatusBits( ex_mem_register_next.reg, new_sr );
274
        new_sr(SR_OVERFLOW_BIT) := isOverflowSub(id_ex_register.rX,
275
                                                 id_ex_register.immediate,
276
                                                 ex_mem_register_next.alu);
277 8 jlechner
      when OPCODE_NEG =>
278
        ex_mem_register_next.alu <= not id_ex_register.rY + x"0001";
279 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
280 79 cwalter
--      when OPCODE_ALS =>
281
--        ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
282
--        ex_mem_register_next.sr(SR_OVERFLOW_BIT) <= id_ex_register.rY(REGISTER_WIDTH-1) xor
283
--                                                    id_ex_register.rY(REGISTER_WIDTH-2);
284
--      when OPCODE_ARS =>
285
--        ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-1) & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
286 8 jlechner
      when OPCODE_ALS =>
287 96 cwalter
        bs_left                  <= '1';
288
        bs_arithmetic            <= '1';
289
        ex_mem_register_next.alu <= bs_out;
290
        getSRStatusBits( bs_out, new_sr );
291
        new_sr(SR_OVERFLOW_BIT)  := id_ex_register.rY(REGISTER_WIDTH-1) xor
292
                                    id_ex_register.rY(REGISTER_WIDTH-2);
293 8 jlechner
      when OPCODE_ARS =>
294 96 cwalter
        bs_left                  <= '0';
295
        bs_arithmetic            <= '1';
296
        ex_mem_register_next.alu <= bs_out;
297
        getSRStatusBits( bs_out, new_sr );
298
        new_sr(SR_OVERFLOW_BIT)  := id_ex_register.rY(REGISTER_WIDTH-1) xor
299
                                    id_ex_register.rY(REGISTER_WIDTH-2);
300 8 jlechner
        -- logical opcodes
301
      when OPCODE_AND =>
302 96 cwalter
        ex_mem_register_next.alu <= id_ex_register.rX and id_ex_register.rY;
303
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
304 8 jlechner
      when OPCODE_NOT =>
305 96 cwalter
        ex_mem_register_next.alu <= not id_ex_register.rY;
306
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
307 8 jlechner
      when OPCODE_EOR =>
308
        ex_mem_register_next.alu <= id_ex_register.rX xor id_ex_register.rY;
309 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
310 79 cwalter
--      when OPCODE_LS =>
311
--        ex_mem_register_next.alu <= id_ex_register.rY(REGISTER_WIDTH-2 downto 0) & "0";
312
--      when OPCODE_RS =>
313
--        ex_mem_register_next.alu <= "0" & id_ex_register.rY(REGISTER_WIDTH-1 downto 1);
314 8 jlechner
      when OPCODE_LS =>
315 79 cwalter
        bs_left                  <= '1';
316
        bs_arithmetic            <= '0';
317
        ex_mem_register_next.alu <= bs_out;
318 96 cwalter
        getSRStatusBits( bs_out, new_sr );
319 8 jlechner
      when OPCODE_RS =>
320 79 cwalter
        bs_left                  <= '0';
321
        bs_arithmetic            <= '0';
322
        ex_mem_register_next.alu <= bs_out;
323 96 cwalter
        getSRStatusBits( bs_out, new_sr );
324 8 jlechner
        -- program control
325
      when OPCODE_JMP =>
326
        ex_mem_register_next.lr             <= id_ex_register.pc;
327
        ex_mem_register_next.dreg_addr      <= PC_ADDR;
328
        ex_mem_register_next.alu            <= id_ex_register.rX;
329 96 cwalter
        getSRStatusBits( ex_mem_register_next.alu, new_sr );
330 8 jlechner
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
331
        aluop2_int(ALUOP2_SR_BIT) <= '0';
332
        aluop2_int(ALUOP2_LR_BIT) <= '1';
333
        isJmpOp <= '1';
334
 
335
      when OPCODE_NOP =>
336
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
337
        aluop2_int(ALUOP2_SR_BIT) <= '0';
338
 
339
      when OPCODE_TST =>
340
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
341
        aluop2_int(ALUOP2_SR_BIT) <= '1';
342 96 cwalter
        getSRStatusBits( id_ex_register.rX, new_sr );
343 8 jlechner
 
344
      when others =>
345
        aluop1_int(ALUOP1_WB_REG_BIT) <= '0';
346
        aluop2_int(ALUOP2_SR_BIT) <= '0';
347
 
348
    end case;
349 96 cwalter
 
350
    -- update current SR register value.
351
    ex_mem_register_next.sr <= new_sr;
352 8 jlechner
  end process;
353
 
354 97 jlechner
  branch_logic: process (id_ex_register, isLoadOp, isJmpOp, execute)
355 8 jlechner
  begin  -- process branch_logic
356
    branch_int <= '0';
357
    clear_out_int <= '0';
358 90 jlechner
    clear_locks <= '0';
359 97 jlechner
    if execute = '1' then
360
      if (id_ex_register.rX_addr = PC_ADDR and isLoadOp = '1') or (isJmpOp = '1') then
361
        branch_int <= '1';
362
        clear_out_int <= '1';
363
        clear_locks <= '1';
364
      end if;
365
    end if;
366 8 jlechner
  end process branch_logic;
367
 
368 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.