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

Subversion Repositories t400

[/] [t400/] [trunk/] [rtl/] [vhdl/] [t400_alu.vhd] - Blame information for rev 179

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 arniml
-------------------------------------------------------------------------------
2
--
3
-- The Arithmetic Logic Unit (ALU).
4
-- It contains the accumulator and the C flag.
5
--
6 179 arniml
-- $Id: t400_alu.vhd 179 2009-04-01 19:48:38Z arniml $
7 2 arniml
--
8
-- Copyright (c) 2006 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/t400/
44
--
45
-------------------------------------------------------------------------------
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
 
50
use work.t400_pack.all;
51 43 arniml
use work.t400_opt_pack.all;
52 2 arniml
 
53
entity t400_alu is
54
 
55 43 arniml
  generic (
56
    opt_cko_g : integer := t400_opt_cko_crystal_c
57
  );
58 2 arniml
  port (
59
    -- System Interface -------------------------------------------------------
60
    ck_i       : in  std_logic;
61
    ck_en_i    : in  boolean;
62
    por_i      : in  boolean;
63
    res_i      : in  boolean;
64 43 arniml
    cko_i      : in  std_logic;
65 2 arniml
    -- Control Interface ------------------------------------------------------
66
    op_i       : in  alu_op_t;
67
    -- Data Interface ---------------------------------------------------------
68
    m_i        : in  dw_t;
69
    dec_data_i : in  dec_data_t;
70
    q_low_i    : in  dw_t;
71
    b_i        : in  b_t;
72
    g_i        : in  dw_t;
73
    in_i       : in  dw_t;
74
    sio_i      : in  dw_t;
75
    a_o        : out dw_t;
76
    carry_o    : out std_logic;
77
    c_o        : out std_logic
78
  );
79
 
80
end t400_alu;
81
 
82
 
83
library ieee;
84
use ieee.numeric_std.all;
85
 
86
architecture rtl of t400_alu is
87
 
88
  subtype alu_dw_t     is unsigned(dw_t'high+1 downto 0);
89
  signal  alu_result_s : alu_dw_t;
90
 
91
  signal  a_q          : dw_t;
92
  signal  c_q          : std_logic;
93
 
94
begin
95
 
96
  -----------------------------------------------------------------------------
97
  -- Process regs
98
  --
99
  -- Purpose:
100
  --   Implements the sequential registers of the ALU:
101
  --     * A - accumulator
102
  --     * C - carry flag
103
  --
104
  regs: process (ck_i, por_i)
105
  begin
106
    if por_i then
107
      a_q <= (others => '0');
108
      c_q <= '0';
109
 
110
    elsif ck_i'event and ck_i = '1' then
111
      if res_i then
112
        -- synchronous reset upon external reset event
113
        a_q <= (others => '0');
114
        c_q <= '0';
115
 
116
      elsif ck_en_i then
117
        -- update accumulator
118
        case op_i is
119
          when ALU_CLRA    |
120
               ALU_ADD     |
121
               ALU_ADD_10  |
122
               ALU_ADD_C   |
123
               ALU_ADD_DEC |
124
               ALU_COMP    |
125
               ALU_XOR     =>
126
            a_q <= std_logic_vector(alu_result_s(dw_t'range));
127
          when ALU_LOAD_M =>
128
            a_q <= m_i;
129
          when ALU_LOAD_Q =>
130
            a_q <= q_low_i;
131
          when ALU_LOAD_G =>
132
            a_q <= g_i;
133
          when ALU_LOAD_IN =>
134
            a_q <= in_i;
135
          when ALU_LOAD_IL =>
136 47 arniml
            a_q(3) <= in_i(3);
137 43 arniml
            if opt_cko_g = t400_opt_cko_gpi_c then
138
              a_q(2) <= cko_i;
139
            else
140
              a_q(2) <= '1';
141
            end if;
142
            a_q(1) <= '0';
143 47 arniml
            a_q(0) <= in_i(0);
144 2 arniml
          when ALU_LOAD_BR =>
145
            a_q(3 downto 2) <= (others => '0');
146
            a_q(1 downto 0) <= b_i(br_range_t);
147
          when ALU_LOAD_BD =>
148
            a_q <= b_i(bd_range_t);
149
          when ALU_LOAD_SIO =>
150
            a_q <= sio_i;
151
          when others =>
152
            null;
153
        end case;
154
 
155
        -- update C flag upon the following instructions
156
        case op_i is
157
          -- carry result of addition -----------------------------------------
158
          when ALU_ADD_C =>
159
            c_q <= alu_result_s(alu_dw_t'high);
160
 
161
          -- reset C flag -----------------------------------------------------
162
          when ALU_RC =>
163
            c_q <= '0';
164
 
165
          -- set C flag -------------------------------------------------------
166
          when ALU_SC =>
167
            c_q <= '1';
168
 
169
          when others =>
170
            null;
171
        end case;
172
      end if;
173
    end if;
174
  end process regs;
175
  --
176
  -----------------------------------------------------------------------------
177
 
178
 
179
  -----------------------------------------------------------------------------
180
  -- Process dp
181
  --
182
  -- Purpose:
183
  --   Implements the ALU's data path.
184
  --
185
  dp: process (op_i,
186
               a_q,
187
               m_i,
188
               dec_data_i,
189
               c_q)
190
    variable in1_v,
191
             in2_v,
192
             in3_v,
193
             add_v, xor_v : alu_dw_t;
194
  begin
195
    -- prepare adder
196
    in1_v      := '0' & unsigned(a_q);
197
    if    op_i = ALU_ADD_10 then
198
      in2_v    := to_unsigned(10, alu_dw_t'length);
199
    elsif op_i = ALU_ADD_DEC then
200
      in2_v    := '0' & unsigned(dec_data_i(dw_t'range));
201
    else
202
      in2_v    := '0' & unsigned(m_i);
203
    end if;
204
    if op_i = ALU_ADD_C then
205
      in3_v    := (others => '0');
206
      in3_v(0) := c_q;
207
    else
208
      in3_v    := (others => '0');
209
    end if;
210
    add_v := in1_v + in2_v + in3_v;
211
 
212
    -- prepare exclusive or
213
    xor_v := in1_v xor in2_v;
214
 
215
    case op_i is
216
      -- ALU operation: Clear accumulator -------------------------------------
217
      when ALU_CLRA =>
218
        alu_result_s <= (others => '0');
219
 
220
      -- ALU operation: Add to accumulator ------------------------------------
221
      when ALU_ADD     |
222
           ALU_ADD_10  |
223
           ALU_ADD_C   |
224
           ALU_ADD_DEC =>
225
        alu_result_s <= add_v;
226
 
227
      -- ALU operation: Complement accumulator --------------------------------
228
      when ALU_COMP =>
229
        alu_result_s <= '0' & not unsigned(a_q);
230
 
231
      -- ALU operation: XOR to accumulator ------------------------------------
232
      when ALU_XOR =>
233
        alu_result_s <= xor_v;
234
 
235
      when others =>
236
        alu_result_s <= (others => '-');
237
    end case;
238
  end process dp;
239
  --
240
  -----------------------------------------------------------------------------
241
 
242
 
243
  -----------------------------------------------------------------------------
244
  -- Output mapping
245
  -----------------------------------------------------------------------------
246
  a_o     <= a_q;
247
  carry_o <= alu_result_s(alu_dw_t'high);
248
  c_o     <= c_q;
249
 
250
end rtl;

powered by: WebSVN 2.1.0

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