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

Subversion Repositories t48

[/] [t48/] [tags/] [rel_1_0/] [rtl/] [vhdl/] [alu.vhd] - Blame information for rev 4

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

Line No. Rev Author Line
1 4 arniml
-------------------------------------------------------------------------------
2
--
3
-- The Arithmetic Logic Unit (ALU).
4
-- It contains the ALU core plus the Accumulator and the Temp Reg.
5
--
6
-- $Id: alu.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $
7
--
8
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org)
9
--
10
-- All rights reserved
11
--
12
-- Redistribution and use in source and synthezised forms, with or without
13
-- modification, are permitted provided that the following conditions are met:
14
--
15
-- Redistributions of source code must retain the above copyright notice,
16
-- this list of conditions and the following disclaimer.
17
--
18
-- Redistributions in synthesized form must reproduce the above copyright
19
-- notice, this list of conditions and the following disclaimer in the
20
-- documentation and/or other materials provided with the distribution.
21
--
22
-- Neither the name of the author nor the names of other contributors may
23
-- be used to endorse or promote products derived from this software without
24
-- specific prior written permission.
25
--
26
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
30
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
-- POSSIBILITY OF SUCH DAMAGE.
37
--
38
-- Please report bugs to the author, but before you do so, please
39
-- make sure that this is not a derivative work and that
40
-- you have the latest version of this file.
41
--
42
-- The latest version of this file can be found at:
43
--      http://www.opencores.org/cvsweb.shtml/t48/
44
--
45
-------------------------------------------------------------------------------
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
 
50
use work.t48_pack.word_t;
51
use work.alu_pack.alu_op_t;
52
 
53
entity alu is
54
 
55
  port (
56
    -- Global Interface -------------------------------------------------------
57
    clk_i              : in  std_logic;
58
    res_i              : in  std_logic;
59
    en_clk_i           : in  boolean;
60
    -- T48 Bus Interface ------------------------------------------------------
61
    data_i             : in  word_t;
62
    data_o             : out word_t;
63
    write_accu_i       : in  boolean;
64
    write_shadow_i     : in  boolean;
65
    write_temp_reg_i   : in  boolean;
66
    read_alu_i         : in  boolean;
67
    -- Decoder Interface ------------------------------------------------------
68
    carry_i            : in  std_logic;
69
    carry_o            : out std_logic;
70
    aux_carry_i        : in  std_logic;
71
    aux_carry_o        : out std_logic;
72
    alu_op_i           : in  alu_op_t;
73
    use_carry_i        : in  boolean
74
  );
75
 
76
end alu;
77
 
78
 
79
library ieee;
80
use ieee.std_logic_arith.all;
81
 
82
use work.t48_pack.clk_active_c;
83
use work.t48_pack.res_active_c;
84
use work.t48_pack.bus_idle_level_c;
85
use work.alu_pack.all;
86
 
87
-- pragma translate_off
88
use work.t48_tb_pack.tb_accu_s;
89
-- pragma translate_on
90
 
91
architecture rtl of alu is
92
 
93
  -- the Accumulator and Temp Reg
94
  signal accumulator_q,
95
         accu_shadow_q,
96
         temp_req_q     : word_t;
97
  -- inputs to the ALU core
98
  signal in_a_s,
99
         in_b_s  : word_t;
100
  -- output of the ALU core
101
  signal data_s  : word_t;
102
 
103
begin
104
 
105
  -----------------------------------------------------------------------------
106
  -- Process working_regs
107
  --
108
  -- Purpose:
109
  --   Implements the working registers:
110
  --    + Accumulator
111
  --    + Temp Reg
112
  --
113
  working_regs: process (res_i, clk_i)
114
  begin
115
    if res_i = res_active_c then
116
      accumulator_q     <= (others => '0');
117
      accu_shadow_q     <= (others => '0');
118
      temp_req_q        <= (others => '0');
119
 
120
    elsif clk_i'event and clk_i = clk_active_c then
121
      if en_clk_i then
122
 
123
        if write_accu_i then
124
          accumulator_q   <= data_i;
125
        end if;
126
 
127
        if write_shadow_i then
128
          -- write shadow directly from t48 data bus
129
          accu_shadow_q <= data_i;
130
        else
131
          -- default: update shadow Accumulator from real Accumulator
132
          accu_shadow_q <= accumulator_q;
133
        end if;
134
 
135
        if write_temp_reg_i then
136
          temp_req_q      <= data_i;
137
        end if;
138
 
139
      end if;
140
 
141
    end if;
142
 
143
  end process working_regs;
144
  --
145
  -----------------------------------------------------------------------------
146
 
147
 
148
  -----------------------------------------------------------------------------
149
  -- Build the inputs to the ALU core.
150
  -- Input A:
151
  --   Unary operators use only Input A.
152
  --   Is always fed from the shadow Accumulator.
153
  --   Assumption: It never happens that the Accumulator is written and then
154
  --               read for an ALU operation in the next cycle.
155
  --               Its contents can thus be staged through the shadow Accu.
156
  -- Input B:
157
  --   Is always fed from the Temp Reg.
158
  -----------------------------------------------------------------------------
159
  in_a_s <= accu_shadow_q;
160
  in_b_s <= temp_req_q;
161
 
162
 
163
  -----------------------------------------------------------------------------
164
  -- Process alu_core
165
  --
166
  -- Purpose:
167
  --   Implements the ALU core.
168
  --   All operations defined in alu_op_t are handled here.
169
  --
170
  alu_core: process (in_a_s,
171
                     in_b_s,
172
                     alu_op_i,
173
                     use_carry_i,
174
                     carry_i,
175
                     aux_carry_i)
176
 
177
    variable add_v : alu_operand_t;
178
    variable c_v   : std_logic;
179
 
180
    function add_f(a, b : alu_operand_t;
181
                      c : std_logic      ) return alu_operand_t is
182
    begin
183
      return UNSIGNED(a) + UNSIGNED(b) + CONV_UNSIGNED(c, alu_operand_t'length);
184
    end;
185
 
186
  begin
187
    -- default assigments
188
    data_s      <= (others => '0');
189
    carry_o     <= '0';
190
    aux_carry_o <= '0';
191
 
192
    case alu_op_i is
193
      -- Operation: AND -------------------------------------------------------
194
      when ALU_AND =>
195
        data_s <= in_a_s and in_b_s;
196
 
197
      -- Operation: OR --------------------------------------------------------
198
      when ALU_OR =>
199
        data_s <= in_a_s or in_b_s;
200
 
201
      -- Operation: XOR -------------------------------------------------------
202
      when ALU_XOR =>
203
        data_s <= in_a_s xor in_b_s;
204
 
205
      -- Operation: Add -------------------------------------------------------
206
      when ALU_ADD =>
207
        if use_carry_i then
208
          c_v := carry_i;
209
        else
210
          c_v := '0';
211
        end if;
212
 
213
        add_v   := add_f("0" & in_a_s, "0" & in_b_s, c_v);
214
 
215
        data_s  <= add_v(data_s'range);
216
        carry_o <= add_v(add_v'high);
217
 
218
      -- Operation: CPL -------------------------------------------------------
219
      when ALU_CPL =>
220
        data_s <= not in_a_s;
221
 
222
      -- Operation: CLR -------------------------------------------------------
223
      when ALU_CLR =>
224
        data_s <= (others => '0');
225
 
226
      -- Operation: RL --------------------------------------------------------
227
      when ALU_RL =>
228
        data_s(7 downto 1) <= in_a_s(6 downto 0);
229
        carry_o            <= in_a_s(7);
230
 
231
        if use_carry_i then
232
          data_s(0)        <= carry_i;
233
        else
234
          data_s(0)        <= in_a_s(7);
235
        end if;
236
 
237
      -- Operation: RR --------------------------------------------------------
238
      when ALU_RR =>
239
        data_s(6 downto 0) <= in_a_s(7 downto 1);
240
        carry_o            <= in_a_s(0);
241
 
242
        if use_carry_i then
243
          data_s(7)        <= carry_i;
244
        else
245
          data_s(7)        <= in_a_s(0);
246
        end if;
247
 
248
      -- Operation: Swap ------------------------------------------------------
249
      when ALU_SWAP =>
250
        data_s(3 downto 0) <= in_a_s(7 downto 4);
251
        data_s(7 downto 4) <= in_a_s(3 downto 0);
252
 
253
      -- Operation: DEC -------------------------------------------------------
254
      when ALU_DEC =>
255
        add_v  := add_f(not ("0" & in_a_s), "000000001", '0');
256
        data_s <= not add_v(data_s'range);
257
 
258
      -- Operation: INC -------------------------------------------------------
259
      when ALU_INC =>
260
        add_v  := add_f("0" & in_a_s, "000000001", '0');
261
        data_s <= add_v(data_s'range);
262
 
263
      -- Operation: DA --------------------------------------------------------
264
      when ALU_DA =>
265
        -- pragma translate_off
266
        assert false
267
          report "ALU Operation DA not yet implemented."
268
          severity warning;
269
        -- pragma translate_on
270
 
271
      -- Operation: NOP -------------------------------------------------------
272
      when ALU_NOP =>
273
        data_s <= in_a_s;
274
 
275
      when others =>
276
        -- pragma translate_off
277
        assert false
278
          report "Unknown ALU operation selected!"
279
          severity error;
280
        -- pragma translate_on
281
 
282
    end case;
283
 
284
  end process alu_core;
285
  --
286
  -----------------------------------------------------------------------------
287
 
288
 
289
  -- pragma translate_off
290
  -----------------------------------------------------------------------------
291
  -- Testbench support.
292
  -----------------------------------------------------------------------------
293
  tb_accu_s <= accumulator_q;
294
  -- pragma translate_on
295
 
296
  -----------------------------------------------------------------------------
297
  -- Output Multiplexer.
298
  -----------------------------------------------------------------------------
299
  data_o <=   data_s
300
            when read_alu_i else
301
              (others => bus_idle_level_c);
302
 
303
end rtl;
304
 
305
 
306
-------------------------------------------------------------------------------
307
-- File History:
308
--
309
-- $Log: not supported by cvs2svn $
310
--
311
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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