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

Subversion Repositories marca

[/] [marca/] [tags/] [INITIAL/] [vhdl/] [execute.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jeunes2
--  This file is part of the marca processor.
2
--  Copyright (C) 2007 Wolfgang Puffitsch
3
 
4
--  This program is free software; you can redistribute it and/or modify it
5
--  under the terms of the GNU Library General Public License as published
6
--  by the Free Software Foundation; either version 2, or (at your option)
7
--  any later version.
8
 
9
--  This program is distributed in the hope that it will be useful,
10
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
--  Library General Public License for more details.
13
 
14
--  You should have received a copy of the GNU Library General Public
15
--  License along with this program; if not, write to the Free Software
16
--  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
17
 
18
-------------------------------------------------------------------------------
19
-- MARCA execution stage
20
-------------------------------------------------------------------------------
21
-- architecture of the execution pipeline stage
22
-------------------------------------------------------------------------------
23
 
24
-------------------------------------------------------------------------------
25
-- Wolfgang Puffitsch
26
-- Computer Architecture Lab, Group 3
27
-------------------------------------------------------------------------------
28
 
29
library IEEE;
30
use IEEE.std_logic_1164.all;
31
use IEEE.numeric_std.all;
32
 
33
use work.marca_pkg.all;
34
 
35
architecture behaviour of execute is
36
 
37
component alu is
38
  port (
39
    clock   : in  std_logic;
40
    reset   : in  std_logic;
41
    busy    : out std_logic;
42
    op      : in  ALU_OP;
43
    a       : in  std_logic_vector(REG_WIDTH-1 downto 0);
44
    b       : in  std_logic_vector(REG_WIDTH-1 downto 0);
45
    i       : in  std_logic_vector(REG_WIDTH-1 downto 0);
46
    pc      : in  std_logic_vector(REG_WIDTH-1 downto 0);
47
    intr    : in  std_logic;
48
    exc     : out std_logic;
49
    iena    : out std_logic;
50
    pcchg   : out std_logic;
51
    result  : out std_logic_vector(REG_WIDTH-1 downto 0));
52
end component;
53
 
54
component mem is
55
  port (
56
    clock   : in  std_logic;
57
    reset   : in  std_logic;
58
    op      : in  MEM_OP;
59
    address : in  std_logic_vector(REG_WIDTH-1 downto 0);
60
    data    : in  std_logic_vector(REG_WIDTH-1 downto 0);
61
    exc     : out std_logic;
62
    busy    : out std_logic;
63
    result  : out std_logic_vector(REG_WIDTH-1 downto 0);
64
    intrs   : out std_logic_vector(VEC_COUNT-1 downto 3);
65
    ext_in  : in  std_logic_vector(IN_BITS-1 downto 0);
66
    ext_out : out std_logic_vector(OUT_BITS-1 downto 0));
67
end component;
68
 
69
component intr is
70
  port (
71
    clock   : in  std_logic;
72
    reset   : in  std_logic;
73
    enable  : in  std_logic;
74
    trigger : in  std_logic_vector(VEC_COUNT-1 downto 1);
75
    op      : in  INTR_OP;
76
    a       : in  std_logic_vector(REG_WIDTH-1 downto 0);
77
    i       : in  std_logic_vector(REG_WIDTH-1 downto 0);
78
    pc      : in  std_logic_vector(REG_WIDTH-1 downto 0);
79
    exc     : out std_logic;
80
    pcchg   : out std_logic;
81
    result  : out std_logic_vector(REG_WIDTH-1 downto 0));
82
end component;
83
 
84
signal any_busy : std_logic;
85
 
86
signal alu_iena   : std_logic;
87
signal alu_exc    : std_logic;
88
signal alu_busy   : std_logic;
89
signal alu_pcchg  : std_logic;
90
signal alu_result : std_logic_vector(REG_WIDTH-1 downto 0);
91
 
92
signal mem_exc    : std_logic;
93
signal mem_busy   : std_logic;
94
signal mem_result : std_logic_vector(REG_WIDTH-1 downto 0);
95
signal mem_intrs  : std_logic_vector(VEC_COUNT-1 downto 3);
96
 
97
signal intr_enable : std_logic;
98
signal intr_exc    : std_logic;
99
signal intr_pcchg  : std_logic;
100
signal intr_result : std_logic_vector(REG_WIDTH-1 downto 0);
101
 
102
signal pc_reg   : std_logic_vector(REG_WIDTH-1 downto 0);
103
 
104
signal src1_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
105
signal src2_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
106
signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
107
 
108
signal op1_reg  : std_logic_vector(REG_WIDTH-1 downto 0);
109
signal op2_reg  : std_logic_vector(REG_WIDTH-1 downto 0);
110
signal imm_reg  : std_logic_vector(REG_WIDTH-1 downto 0);
111
 
112
signal op1_fwed : std_logic_vector(REG_WIDTH-1 downto 0);
113
signal op2_fwed : std_logic_vector(REG_WIDTH-1 downto 0);
114
 
115
signal aop_reg  : ALU_OP;
116
signal mop_reg  : MEM_OP;
117
signal iop_reg  : INTR_OP;
118
 
119
signal unit_reg   : UNIT_SELECTOR;
120
signal target_reg : TARGET_SELECTOR;
121
 
122
signal stall_cnt      : std_logic_vector(1 downto 0);  -- prohibiting                                                        
123
signal next_stall_cnt : std_logic_vector(1 downto 0);  -- interrupts during reti
124
 
125
begin  -- behaviour
126
 
127
  -- interrupts do not work while jumping
128
  intr_enable <= alu_iena and zero(stall_cnt) and not any_busy;
129
 
130
  alu_unit : alu
131
    port map (
132
      clock => clock,
133
      reset => reset,
134
      op => aop_reg,
135
      a => op1_fwed,
136
      b => op2_fwed,
137
      i => imm_reg,
138
      pc => pc_reg,
139
      intr => intr_exc,
140
      exc => alu_exc,
141
      busy => alu_busy,
142
      iena => alu_iena,
143
      pcchg => alu_pcchg,
144
      result => alu_result);
145
 
146
  mem_unit : mem
147
    port map (
148
      clock   => clock,
149
      reset   => reset,
150
      op      => mop_reg,
151
      address => op2_fwed,
152
      data    => op1_fwed,
153
      exc     => mem_exc,
154
      busy    => mem_busy,
155
      result  => mem_result,
156
      intrs   => mem_intrs,
157
      ext_in  => ext_in,
158
      ext_out => ext_out);
159
 
160
  intr_unit : intr
161
    port map (
162
      clock            => clock,
163
      reset            => reset,
164
      enable           => intr_enable,
165
      trigger(EXC_ALU) => alu_exc,
166
      trigger(EXC_MEM) => mem_exc,
167
      trigger(VEC_COUNT-1 downto 3) => mem_intrs,
168
      op               => iop_reg,
169
      a                => op1_fwed,
170
      i                => imm_reg,
171
      pc               => pc_reg,
172
      exc              => intr_exc,
173
      pcchg            => intr_pcchg,
174
      result           => intr_result);
175
 
176
  syn_proc: process (clock, reset)
177
  begin  -- process syn_proc
178
    if reset = RESET_ACTIVE then                 -- asynchronous reset (active low)
179
      stall_cnt <= (others => '0');
180
      pc_reg <= (others => '0');
181
      src1_reg <= (others => '0');
182
      src2_reg <= (others => '0');
183
      dest_reg <= (others => '0');
184
      aop_reg <= ALU_NOP;
185
      mop_reg <= MEM_NOP;
186
      iop_reg <= INTR_NOP;
187
      op1_reg <= (others => '0');
188
      op2_reg <= (others => '0');
189
      imm_reg <= (others => '0');
190
      unit_reg <= UNIT_ALU;
191
      target_reg <= TARGET_NONE;
192
    elsif clock'event and clock = '1' then  -- rising clock edge
193
      if any_busy = '0' then
194
        stall_cnt <= next_stall_cnt;
195
        if stall = '1' then
196
          pc_reg <= (others => '0');
197
          src1_reg <= (others => '0');
198
          src2_reg <= (others => '0');
199
          dest_reg <= (others => '0');
200
          aop_reg <= ALU_NOP;
201
          mop_reg <= MEM_NOP;
202
          iop_reg <= INTR_NOP;
203
          op1_reg <= (others => '0');
204
          op2_reg <= (others => '0');
205
          imm_reg <= (others => '0');
206
          unit_reg <= UNIT_ALU;
207
          target_reg <= TARGET_NONE;
208
        else
209
          pc_reg <= pc_in;
210
          dest_reg <= dest_in;
211
          src1_reg <= src1;
212
          src2_reg <= src2;
213
          aop_reg <= aop;
214
          mop_reg <= mop;
215
          iop_reg <= iop;
216
          op1_reg <= op1;
217
          op2_reg <= op2;
218
          imm_reg <= imm;
219
          unit_reg <= unit;
220
          target_reg <= target_in;
221
        end if;
222
      end if;
223
    end if;
224
  end process syn_proc;
225
 
226
  stalling: process (stall, stall_cnt)
227
  begin  -- process hold_pc
228
 
229
    next_stall_cnt <= std_logic_vector(unsigned(stall_cnt) - 1);
230
    if zero(stall_cnt) = '1' then
231
      next_stall_cnt <= "00";
232
    end if;
233
    if stall = '1' then
234
      next_stall_cnt <= "11";
235
    end if;
236
 
237
  end process stalling;
238
 
239
  business: process (any_busy, alu_busy, mem_busy)
240
  begin  -- process business
241
    any_busy <= alu_busy or mem_busy;
242
    busy <= any_busy;
243
  end process business;
244
 
245
  feedthrough: process (pc_reg, dest_reg, unit_reg, target_reg, op2_fwed, intr_exc)
246
  begin  -- process feedthrough
247
    if unit_reg /= UNIT_CALL then
248
      pc_out <= pc_reg;
249
    else
250
      pc_out <= op2_fwed;
251
    end if;
252
    dest_out <= dest_reg;
253
    if intr_exc = '1' then
254
      target_out <= TARGET_PC;
255
    else
256
      target_out <= target_reg;
257
    end if;
258
  end process feedthrough;
259
 
260
  forward: process (src1_reg, src2_reg, op1_reg, op2_reg, fw_ena, fw_dest, fw_val)
261
  begin  -- process forward
262
    op1_fwed <= op1_reg;
263
    op2_fwed <= op2_reg;
264
    if fw_ena = '1' then
265
      if src1_reg = fw_dest then
266
        op1_fwed <= fw_val;
267
      end if;
268
      if src2_reg = fw_dest then
269
        op2_fwed <= fw_val;
270
      end if;
271
    end if;
272
  end process forward;
273
 
274
  select_result: process(unit_reg, alu_result, mem_result, intr_result, pc_reg,
275
                         alu_pcchg, intr_pcchg,
276
                         intr_exc)
277
  begin  -- process select_result
278
    case unit_reg is
279
      when UNIT_ALU => result <= alu_result;
280
      when UNIT_MEM => result <= mem_result;
281
      when UNIT_INTR => result <= intr_result;
282
      when UNIT_CALL => result <= std_logic_vector(unsigned(pc_reg) + 1);
283
      when others => null;
284
    end case;
285
    if intr_exc = '1' then
286
      result <= intr_result;
287
    end if;
288
    pcchg <= alu_pcchg or intr_pcchg;
289
  end process select_result;
290
 
291
end behaviour;

powered by: WebSVN 2.1.0

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