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

Subversion Repositories t400

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

Go to most recent revision | 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 43 arniml
-- $Id: t400_alu.vhd,v 1.2 2006-05-21 21:47:40 arniml Exp $
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
    il_i       : in  dw_t;
75
    sio_i      : in  dw_t;
76
    a_o        : out dw_t;
77
    carry_o    : out std_logic;
78
    c_o        : out std_logic
79
  );
80
 
81
end t400_alu;
82
 
83
 
84
library ieee;
85
use ieee.numeric_std.all;
86
 
87
architecture rtl of t400_alu is
88
 
89
  subtype alu_dw_t     is unsigned(dw_t'high+1 downto 0);
90
  signal  alu_result_s : alu_dw_t;
91
 
92
  signal  a_q          : dw_t;
93
  signal  c_q          : std_logic;
94
 
95
begin
96
 
97
  -----------------------------------------------------------------------------
98
  -- Process regs
99
  --
100
  -- Purpose:
101
  --   Implements the sequential registers of the ALU:
102
  --     * A - accumulator
103
  --     * C - carry flag
104
  --
105
  regs: process (ck_i, por_i)
106
  begin
107
    if por_i then
108
      a_q <= (others => '0');
109
      c_q <= '0';
110
 
111
    elsif ck_i'event and ck_i = '1' then
112
      if res_i then
113
        -- synchronous reset upon external reset event
114
        a_q <= (others => '0');
115
        c_q <= '0';
116
 
117
      elsif ck_en_i then
118
        -- update accumulator
119
        case op_i is
120
          when ALU_CLRA    |
121
               ALU_ADD     |
122
               ALU_ADD_10  |
123
               ALU_ADD_C   |
124
               ALU_ADD_DEC |
125
               ALU_COMP    |
126
               ALU_XOR     =>
127
            a_q <= std_logic_vector(alu_result_s(dw_t'range));
128
          when ALU_LOAD_M =>
129
            a_q <= m_i;
130
          when ALU_LOAD_Q =>
131
            a_q <= q_low_i;
132
          when ALU_LOAD_G =>
133
            a_q <= g_i;
134
          when ALU_LOAD_IN =>
135
            a_q <= in_i;
136
          when ALU_LOAD_IL =>
137 43 arniml
            a_q(3) <= il_i(3);
138
            if opt_cko_g = t400_opt_cko_gpi_c then
139
              a_q(2) <= cko_i;
140
            else
141
              a_q(2) <= '1';
142
            end if;
143
            a_q(1) <= '0';
144
            a_q(0) <= il_i(0);
145 2 arniml
          when ALU_LOAD_BR =>
146
            a_q(3 downto 2) <= (others => '0');
147
            a_q(1 downto 0) <= b_i(br_range_t);
148
          when ALU_LOAD_BD =>
149
            a_q <= b_i(bd_range_t);
150
          when ALU_LOAD_SIO =>
151
            a_q <= sio_i;
152
          when others =>
153
            null;
154
        end case;
155
 
156
        -- update C flag upon the following instructions
157
        case op_i is
158
          -- carry result of addition -----------------------------------------
159
          when ALU_ADD_C =>
160
            c_q <= alu_result_s(alu_dw_t'high);
161
 
162
          -- reset C flag -----------------------------------------------------
163
          when ALU_RC =>
164
            c_q <= '0';
165
 
166
          -- set C flag -------------------------------------------------------
167
          when ALU_SC =>
168
            c_q <= '1';
169
 
170
          when others =>
171
            null;
172
        end case;
173
      end if;
174
    end if;
175
  end process regs;
176
  --
177
  -----------------------------------------------------------------------------
178
 
179
 
180
  -----------------------------------------------------------------------------
181
  -- Process dp
182
  --
183
  -- Purpose:
184
  --   Implements the ALU's data path.
185
  --
186
  dp: process (op_i,
187
               a_q,
188
               m_i,
189
               dec_data_i,
190
               c_q)
191
    variable in1_v,
192
             in2_v,
193
             in3_v,
194
             add_v, xor_v : alu_dw_t;
195
  begin
196
    -- prepare adder
197
    in1_v      := '0' & unsigned(a_q);
198
    if    op_i = ALU_ADD_10 then
199
      in2_v    := to_unsigned(10, alu_dw_t'length);
200
    elsif op_i = ALU_ADD_DEC then
201
      in2_v    := '0' & unsigned(dec_data_i(dw_t'range));
202
    else
203
      in2_v    := '0' & unsigned(m_i);
204
    end if;
205
    if op_i = ALU_ADD_C then
206
      in3_v    := (others => '0');
207
      in3_v(0) := c_q;
208
    else
209
      in3_v    := (others => '0');
210
    end if;
211
    add_v := in1_v + in2_v + in3_v;
212
 
213
    -- prepare exclusive or
214
    xor_v := in1_v xor in2_v;
215
 
216
    case op_i is
217
      -- ALU operation: Clear accumulator -------------------------------------
218
      when ALU_CLRA =>
219
        alu_result_s <= (others => '0');
220
 
221
      -- ALU operation: Add to accumulator ------------------------------------
222
      when ALU_ADD     |
223
           ALU_ADD_10  |
224
           ALU_ADD_C   |
225
           ALU_ADD_DEC =>
226
        alu_result_s <= add_v;
227
 
228
      -- ALU operation: Complement accumulator --------------------------------
229
      when ALU_COMP =>
230
        alu_result_s <= '0' & not unsigned(a_q);
231
 
232
      -- ALU operation: XOR to accumulator ------------------------------------
233
      when ALU_XOR =>
234
        alu_result_s <= xor_v;
235
 
236
      when others =>
237
        alu_result_s <= (others => '-');
238
    end case;
239
  end process dp;
240
  --
241
  -----------------------------------------------------------------------------
242
 
243
 
244
  -----------------------------------------------------------------------------
245
  -- Output mapping
246
  -----------------------------------------------------------------------------
247
  a_o     <= a_q;
248
  carry_o <= alu_result_s(alu_dw_t'high);
249
  c_o     <= c_q;
250
 
251
end rtl;
252
 
253
 
254
-------------------------------------------------------------------------------
255
-- File History:
256
--
257
-- $Log: not supported by cvs2svn $
258 43 arniml
-- Revision 1.1.1.1  2006/05/06 01:56:44  arniml
259
-- import from local CVS repository, LOC_CVS_0_1
260
--
261 2 arniml
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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