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

Subversion Repositories rise

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

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