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

Subversion Repositories ppx16

[/] [ppx16/] [trunk/] [rtl/] [vhdl/] [PPX_ALU.vhd] - Blame information for rev 3

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

Line No. Rev Author Line
1 3 jesus
--
2
-- PIC16xx compatible microcontroller core
3
--
4
-- Version : 0146
5
--
6
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
7
--
8
-- All rights reserved
9
--
10
-- Redistribution and use in source and synthezised forms, with or without
11
-- modification, are permitted provided that the following conditions are met:
12
--
13
-- Redistributions of source code must retain the above copyright notice,
14
-- this list of conditions and the following disclaimer.
15
--
16
-- Redistributions in synthesized form must reproduce the above copyright
17
-- notice, this list of conditions and the following disclaimer in the
18
-- documentation and/or other materials provided with the distribution.
19
--
20
-- Neither the name of the author nor the names of other contributors may
21
-- be used to endorse or promote products derived from this software without
22
-- specific prior written permission.
23
--
24
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
28
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
-- POSSIBILITY OF SUCH DAMAGE.
35
--
36
-- Please report bugs to the author, but before you do so, please
37
-- make sure that this is not a derivative work and that
38
-- you have the latest version of this file.
39
--
40
-- The latest version of this file can be found at:
41
--      http://www.opencores.org/cvsweb.shtml/t51/
42
--
43
-- Limitations :
44
--
45
-- File history :
46
--
47
 
48
library IEEE;
49
use IEEE.std_logic_1164.all;
50
use IEEE.numeric_std.all;
51
 
52
entity PPX_ALU is
53
        generic(
54
                InstructionLength : integer
55
        );
56
        port (
57
                Clk                     : in std_logic;
58
                ROM_Data        : in std_logic_vector(InstructionLength - 1 downto 0);
59
                A                       : in std_logic_vector(7 downto 0);
60
                B                       : in std_logic_vector(7 downto 0);
61
                Q                       : inout std_logic_vector(7 downto 0);
62
                Skip            : in std_logic;
63
                Carry           : in std_logic;
64
                Z_Skip          : out std_logic;
65
                STATUS_d        : out std_logic_vector(2 downto 0);
66
                STATUS_Wr       : out std_logic_vector(2 downto 0)
67
        );
68
end PPX_ALU;
69
 
70
architecture rtl of PPX_ALU is
71
 
72
        procedure AddSub(A : std_logic_vector(3 downto 0);
73
                                        B : std_logic_vector(3 downto 0);
74
                                        Sub : std_logic;
75
                                        Carry_In : std_logic;
76
                                        signal Res : out std_logic_vector(3 downto 0);
77
                                        signal Carry : out std_logic) is
78
                variable B_i            : unsigned(4 downto 0);
79
                variable Full_Carry     : unsigned(4 downto 0);
80
                variable Res_i          : unsigned(4 downto 0);
81
        begin
82
                if Sub = '1' then
83
                        B_i := "0" & not unsigned(B);
84
                else
85
                        B_i := "0" & unsigned(B);
86
                end if;
87
                if (Sub = '1' and Carry_In = '1') or (Sub = '0' and Carry_In = '1') then
88
                        Full_Carry := "00001";
89
                else
90
                        Full_Carry := "00000";
91
                end if;
92
                Res_i := unsigned("0" & A) + B_i + Full_Carry;
93
                Carry <= Res_i(4);
94
                Res <= std_logic_vector(Res_i(3 downto 0));
95
        end;
96
 
97
        signal  Do_IDTEST               : std_logic;
98
        signal  Do_ADD                  : std_logic;
99
        signal  Do_SUB                  : std_logic;
100
        signal  Do_DEC                  : std_logic;
101
        signal  Do_INC                  : std_logic;
102
        signal  Do_AND                  : std_logic;
103
        signal  Do_OR                   : std_logic;
104
        signal  Do_XOR                  : std_logic;
105
        signal  Do_COM                  : std_logic;
106
        signal  Do_RRF                  : std_logic;
107
        signal  Do_RLF                  : std_logic;
108
        signal  Do_SWAP                 : std_logic;
109
        signal  Do_BITCLR               : std_logic;
110
        signal  Do_BITSET               : std_logic;
111
        signal  Do_BITTESTCLR   : std_logic;
112
        signal  Do_BITTESTSET   : std_logic;
113
        signal  Do_CLR  : std_logic;
114
        signal  Do_PASSA                : std_logic;
115
 
116
        signal  Inst_Top                : std_logic_vector(11 downto 0);
117
 
118
        signal  Bit_Pattern             : std_logic_vector(7 downto 0);
119
        signal  Bit_Test                : std_logic_vector(7 downto 0);
120
 
121
        signal  IDD                             : std_logic_vector(7 downto 0);
122
 
123
        signal  DC_i                    : std_logic;
124
        signal  AddSubRes               : std_logic_vector(8 downto 0);
125
 
126
begin
127
 
128
        Inst_Top <= ROM_Data(InstructionLength - 1 downto InstructionLength - 12);
129
 
130
        process (Clk)
131
        begin
132
                if Clk'event and Clk = '1' then
133
                        Do_ADD <= '0';
134
                        Do_SUB <= '0';
135
                        Do_AND <= '0';
136
                        Do_OR <= '0';
137
                        Do_XOR <= '0';
138
                        Do_IDTEST <= '0';
139
                        Do_INC <= '0';
140
                        Do_DEC <= '0';
141
                        Do_COM <= '0';
142
                        Do_RRF <= '0';
143
                        Do_RLF <= '0';
144
                        Do_SWAP <= '0';
145
                        Do_BITCLR <= '0';
146
                        Do_BITSET <= '0';
147
                        Do_BITTESTCLR <= '0';
148
                        Do_BITTESTSET <= '0';
149
                        Do_CLR <= '0';
150
                        Do_PASSA <= '0';
151
                        if Skip = '0' then
152
                                if InstructionLength = 12 then
153
                                        if Inst_Top(11 downto 6) = "000111" then
154
                                                -- ADDWF
155
                                                Do_ADD <= '1';
156
                                        end if;
157
                                        if Inst_Top(11 downto 6) = "000010" then
158
                                                -- SUBWF
159
                                                Do_SUB <= '1';
160
                                        end if;
161
                                        if Inst_Top(11 downto 6) = "000101" or Inst_Top(11 downto 8) = "1110" then
162
                                                -- ANDWF, ANDLW
163
                                                Do_AND <= '1';
164
                                        end if;
165
                                        if Inst_Top(11 downto 6) = "000100" or Inst_Top(11 downto 8) = "1101" then
166
                                                -- IORWF, IORLW
167
                                                Do_OR <= '1';
168
                                        end if;
169
                                        if Inst_Top(11 downto 6) = "000110" or Inst_Top(11 downto 8) = "1111" then
170
                                                -- XORWF, XORLW
171
                                                Do_XOR <= '1';
172
                                        end if;
173
                                else
174
                                        if Inst_Top(11 downto 6) = "000111" or Inst_Top(11 downto 7) = "11111" then
175
                                                -- ADDWF, ADDLW
176
                                                Do_ADD <= '1';
177
                                        end if;
178
                                        if Inst_Top(11 downto 6) = "000010" or Inst_Top(11 downto 7) = "11110" then
179
                                                -- SUBWF, SUBLW
180
                                                Do_SUB <= '1';
181
                                        end if;
182
                                        if Inst_Top(11 downto 6) = "000101" or Inst_Top(11 downto 6) = "111001" then
183
                                                -- ANDWF, ANDLW
184
                                                Do_AND <= '1';
185
                                        end if;
186
                                        if Inst_Top(11 downto 6) = "000100" or Inst_Top(11 downto 6) = "111000" then
187
                                                -- IORWF, IORLW
188
                                                Do_OR <= '1';
189
                                        end if;
190
                                        if Inst_Top(11 downto 6) = "000110" or Inst_Top(11 downto 6) = "111010" then
191
                                                -- XORWF, XORLW
192
                                                Do_XOR <= '1';
193
                                        end if;
194
                                end if;
195
 
196
                                if Inst_Top(11 downto 9) = "001" and Inst_Top(7 downto 6) = "11" then
197
                                        -- INC/DEC w conditional skip
198
                                        Do_IDTEST <= '1';
199
                                end if;
200
                                if Inst_Top(11 downto 6) = "001010" or Inst_Top(11 downto 6) = "001111" then
201
                                        -- INCF, INCFSZ
202
                                        Do_INC <= '1';
203
                                end if;
204
                                if Inst_Top(11 downto 6) = "000011" or Inst_Top(11 downto 6) = "001011" then
205
                                        -- DECF, DECFSZ, 
206
                                        Do_DEC <= '1';
207
                                end if;
208
                                if Inst_Top(11 downto 6) = "001001" then
209
                                        -- COMF
210
                                        Do_COM <= '1';
211
                                end if;
212
                                if Inst_Top(11 downto 6) = "001100" then
213
                                        -- RRF
214
                                        Do_RRF <= '1';
215
                                end if;
216
                                if Inst_Top(11 downto 6) = "001101" then
217
                                        -- RLF
218
                                        Do_RLF <= '1';
219
                                end if;
220
                                if Inst_Top(11 downto 6) = "001110" then
221
                                        -- SWAPF
222
                                        Do_SWAP <= '1';
223
                                end if;
224
                                if Inst_Top(11 downto 8) = "0100" then
225
                                        -- BCF
226
                                        Do_BITCLR <= '1';
227
                                end if;
228
                                if Inst_Top(11 downto 8) = "0101" then
229
                                        -- BSF
230
                                        Do_BITSET <= '1';
231
                                end if;
232
                                if Inst_Top(11 downto 8) = "0110" then
233
                                        -- BTFSC
234
                                        Do_BITTESTCLR <= '1';
235
                                end if;
236
                                if Inst_Top(11 downto 8) = "0111" then
237
                                        -- BTFSS
238
                                        Do_BITTESTSET <= '1';
239
                                end if;
240
                                if Inst_Top(11 downto 6) = "000001" then
241
                                        -- CLRF, CLRW
242
                                        Do_CLR <= '1';
243
                                end if;
244
                                if Inst_Top(11 downto 6) = "001000" then
245
                                        -- MOVF
246
                                        Do_PASSA <= '1';
247
                                end if;
248
                        end if;
249
 
250
                        case Inst_Top(7 downto 5) is
251
                        when "000" =>
252
                                Bit_Pattern <= "00000001";
253
                        when "001" =>
254
                                Bit_Pattern <= "00000010";
255
                        when "010" =>
256
                                Bit_Pattern <= "00000100";
257
                        when "011" =>
258
                                Bit_Pattern <= "00001000";
259
                        when "100" =>
260
                                Bit_Pattern <= "00010000";
261
                        when "101" =>
262
                                Bit_Pattern <= "00100000";
263
                        when "110" =>
264
                                Bit_Pattern <= "01000000";
265
                        when others =>
266
                                Bit_Pattern <= "10000000";
267
                        end case;
268
                end if;
269
        end process;
270
 
271
        IDD <= std_logic_vector(unsigned(A) + 1) when Do_INC = '1' else
272
                        std_logic_vector(unsigned(A) - 1) when Do_DEC = '1' else "ZZZZZZZZ";
273
        Q <= IDD when Do_INC = '1' or Do_DEC = '1' else "ZZZZZZZZ";
274
 
275
        Q <= AddSubRes(7 downto 0) when (Do_ADD = '1' OR Do_SUB = '1') else "ZZZZZZZZ";
276
        AddSub(A(3 downto 0), B(3 downto 0), Do_SUB, Do_SUB, AddSubRes(3 downto 0), DC_i);
277
        AddSub(A(7 downto 4), B(7 downto 4), Do_SUB, DC_i, AddSubRes(7 downto 4), AddSubRes(8));
278
 
279
        Q <= (A and B) when Do_AND = '1' else
280
                (A or B) when Do_OR = '1' else
281
                (A xor B) when Do_XOR = '1' else "ZZZZZZZZ";
282
        Q <= (not A) when Do_COM = '1' else "ZZZZZZZZ";
283
 
284
        Q <= Carry & A(7 downto 1) when Do_RRF = '1' else "ZZZZZZZZ";
285
        Q <= A(6 downto 0) & Carry when Do_RLF = '1' else "ZZZZZZZZ";
286
 
287
        Q <= A(3 downto 0) & A(7 downto 4) when Do_SWAP = '1' else "ZZZZZZZZ";
288
 
289
        Q <= ((not Bit_Pattern) and A) when Do_BITCLR = '1' else "ZZZZZZZZ";
290
        Q <= (Bit_Pattern or A) when Do_BITSET = '1' else "ZZZZZZZZ";
291
 
292
        Q <= "00000000" when Do_CLR = '1' else "ZZZZZZZZ";
293
 
294
        Q <= A when Do_PASSA = '1' else "ZZZZZZZZ";
295
 
296
        Bit_Test <= Bit_Pattern and A;
297
 
298
        Z_Skip <= '1' when (Do_IDTEST = '1' and IDD = "00000000") or
299
                                        (Bit_Test /= "00000000" and Do_BITTESTSET = '1') or
300
                                        (Bit_Test = "00000000" and Do_BITTESTCLR = '1') else '0';
301
 
302
        STATUS_d(2) <= '1' when Q(7 downto 0) = "00000000" else '0';
303
        STATUS_d(1) <= DC_i;
304
        STATUS_d(0) <= A(0) when Do_RRF = '1' else
305
                                        A(7) when Do_RLF = '1' else
306
                                        AddSubRes(8);
307
 
308
        -- Z
309
        STATUS_Wr(2) <= '1' when Do_SUB = '1' or Do_ADD = '1' or
310
                ((Do_DEC = '1' or Do_INC = '1') and Do_IDTEST = '0') or
311
                Do_AND = '1' or Do_OR = '1' or Do_XOR = '1' or
312
                Do_CLR = '1' or Do_COM = '1' or Do_PASSA = '1' else '0';
313
        -- DC
314
        STATUS_Wr(1) <= '1' when Do_SUB = '1' or Do_ADD = '1' else '0';
315
        -- C
316
        STATUS_Wr(0) <= '1' when Do_SUB = '1' or Do_ADD = '1' or Do_RRF = '1' or Do_RLF = '1' else '0';
317
 
318
end;

powered by: WebSVN 2.1.0

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