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

Subversion Repositories ppx16

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 jesus
--
2
-- PIC16xx compatible microcontroller core
3
--
4 11 jesus
-- Version : 0222
5 3 jesus
--
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 11 jesus
                InstructionLength : integer;
55
                TriState        : boolean := false
56 3 jesus
        );
57
        port (
58
                Clk                     : in std_logic;
59
                ROM_Data        : in std_logic_vector(InstructionLength - 1 downto 0);
60
                A                       : in std_logic_vector(7 downto 0);
61
                B                       : in std_logic_vector(7 downto 0);
62 11 jesus
                Q                       : out std_logic_vector(7 downto 0);
63 3 jesus
                Skip            : in std_logic;
64
                Carry           : in std_logic;
65
                Z_Skip          : out std_logic;
66
                STATUS_d        : out std_logic_vector(2 downto 0);
67
                STATUS_Wr       : out std_logic_vector(2 downto 0)
68
        );
69
end PPX_ALU;
70
 
71
architecture rtl of PPX_ALU is
72
 
73
        procedure AddSub(A : std_logic_vector(3 downto 0);
74
                                        B : std_logic_vector(3 downto 0);
75
                                        Sub : std_logic;
76
                                        Carry_In : std_logic;
77
                                        signal Res : out std_logic_vector(3 downto 0);
78
                                        signal Carry : out std_logic) is
79
                variable B_i            : unsigned(4 downto 0);
80
                variable Full_Carry     : unsigned(4 downto 0);
81
                variable Res_i          : unsigned(4 downto 0);
82
        begin
83
                if Sub = '1' then
84
                        B_i := "0" & not unsigned(B);
85
                else
86
                        B_i := "0" & unsigned(B);
87
                end if;
88
                if (Sub = '1' and Carry_In = '1') or (Sub = '0' and Carry_In = '1') then
89
                        Full_Carry := "00001";
90
                else
91
                        Full_Carry := "00000";
92
                end if;
93
                Res_i := unsigned("0" & A) + B_i + Full_Carry;
94
                Carry <= Res_i(4);
95
                Res <= std_logic_vector(Res_i(3 downto 0));
96
        end;
97
 
98
        signal  Do_IDTEST               : std_logic;
99
        signal  Do_ADD                  : std_logic;
100
        signal  Do_SUB                  : std_logic;
101
        signal  Do_DEC                  : std_logic;
102
        signal  Do_INC                  : std_logic;
103
        signal  Do_AND                  : std_logic;
104
        signal  Do_OR                   : std_logic;
105
        signal  Do_XOR                  : std_logic;
106
        signal  Do_COM                  : std_logic;
107
        signal  Do_RRF                  : std_logic;
108
        signal  Do_RLF                  : std_logic;
109
        signal  Do_SWAP                 : std_logic;
110
        signal  Do_BITCLR               : std_logic;
111
        signal  Do_BITSET               : std_logic;
112
        signal  Do_BITTESTCLR   : std_logic;
113
        signal  Do_BITTESTSET   : std_logic;
114 11 jesus
        signal  Do_CLR                  : std_logic;
115 3 jesus
 
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 11 jesus
        signal  Q_ID                    : std_logic_vector(7 downto 0);
122
        signal  Q_L                             : std_logic_vector(7 downto 0);
123
        signal  Q_C                             : std_logic_vector(7 downto 0);
124
        signal  Q_RR                    : std_logic_vector(7 downto 0);
125
        signal  Q_RL                    : std_logic_vector(7 downto 0);
126
        signal  Q_S                             : std_logic_vector(7 downto 0);
127
        signal  Q_BC                    : std_logic_vector(7 downto 0);
128
        signal  Q_BS                    : std_logic_vector(7 downto 0);
129 3 jesus
 
130
        signal  DC_i                    : std_logic;
131
        signal  AddSubRes               : std_logic_vector(8 downto 0);
132
 
133 11 jesus
        signal  Q_i                             : std_logic_vector(7 downto 0);
134
 
135 3 jesus
begin
136
 
137 11 jesus
        Q <= Q_i;
138
 
139 3 jesus
        Inst_Top <= ROM_Data(InstructionLength - 1 downto InstructionLength - 12);
140
 
141 11 jesus
        gNoTri : if not TriState generate
142
                Q_i <= Q_ID when Do_INC = '1' or Do_DEC = '1' else
143
                        AddSubRes(7 downto 0) when Do_ADD = '1' OR Do_SUB = '1' else
144
                        Q_L when Do_AND = '1' or Do_OR = '1' or Do_XOR = '1' else
145
                        Q_C when Do_COM = '1' else
146
                        Q_RR when Do_RRF = '1' else
147
                        Q_RL when Do_RLF = '1' else
148
                        Q_S when Do_SWAP = '1' else
149
                        Q_BC when Do_BITCLR = '1' else
150
                        Q_BS when Do_BITSET = '1' else
151
                        "00000000";
152
        end generate;
153
 
154
        gTri : if TriState generate
155
                Q_i <= Q_ID when Do_INC = '1' or Do_DEC = '1' else "ZZZZZZZZ";
156
                Q_i <= AddSubRes(7 downto 0) when Do_ADD = '1' OR Do_SUB = '1' else "ZZZZZZZZ";
157
                Q_i <= Q_L when Do_AND = '1' or Do_OR = '1' or Do_XOR = '1' else "ZZZZZZZZ";
158
                Q_i <= Q_C when Do_COM = '1' else "ZZZZZZZZ";
159
                Q_i <= Q_RR when Do_RRF = '1' else "ZZZZZZZZ";
160
                Q_i <= Q_RL when Do_RLF = '1' else "ZZZZZZZZ";
161
                Q_i <= Q_S when Do_SWAP = '1' else "ZZZZZZZZ";
162
                Q_i <= Q_BC when Do_BITCLR = '1' else "ZZZZZZZZ";
163
                Q_i <= Q_BS when Do_BITSET = '1' else "ZZZZZZZZ";
164
                Q_i <= "00000000" when Do_CLR = '1' else "ZZZZZZZZ";
165
        end generate;
166
 
167 3 jesus
        process (Clk)
168
        begin
169
                if Clk'event and Clk = '1' then
170
                        Do_ADD <= '0';
171
                        Do_SUB <= '0';
172
                        Do_AND <= '0';
173
                        Do_OR <= '0';
174
                        Do_XOR <= '0';
175
                        Do_IDTEST <= '0';
176
                        Do_INC <= '0';
177
                        Do_DEC <= '0';
178
                        Do_COM <= '0';
179
                        Do_RRF <= '0';
180
                        Do_RLF <= '0';
181
                        Do_SWAP <= '0';
182
                        Do_BITCLR <= '0';
183
                        Do_BITSET <= '0';
184
                        Do_BITTESTCLR <= '0';
185
                        Do_BITTESTSET <= '0';
186
                        Do_CLR <= '0';
187
                        if Skip = '0' then
188
                                if InstructionLength = 12 then
189
                                        if Inst_Top(11 downto 6) = "000111" then
190
                                                -- ADDWF
191
                                                Do_ADD <= '1';
192
                                        end if;
193
                                        if Inst_Top(11 downto 6) = "000010" then
194
                                                -- SUBWF
195
                                                Do_SUB <= '1';
196
                                        end if;
197
                                        if Inst_Top(11 downto 6) = "000101" or Inst_Top(11 downto 8) = "1110" then
198
                                                -- ANDWF, ANDLW
199
                                                Do_AND <= '1';
200
                                        end if;
201
                                        if Inst_Top(11 downto 6) = "000100" or Inst_Top(11 downto 8) = "1101" then
202
                                                -- IORWF, IORLW
203
                                                Do_OR <= '1';
204
                                        end if;
205
                                        if Inst_Top(11 downto 6) = "000110" or Inst_Top(11 downto 8) = "1111" then
206
                                                -- XORWF, XORLW
207
                                                Do_XOR <= '1';
208
                                        end if;
209
                                else
210
                                        if Inst_Top(11 downto 6) = "000111" or Inst_Top(11 downto 7) = "11111" then
211
                                                -- ADDWF, ADDLW
212
                                                Do_ADD <= '1';
213
                                        end if;
214
                                        if Inst_Top(11 downto 6) = "000010" or Inst_Top(11 downto 7) = "11110" then
215
                                                -- SUBWF, SUBLW
216
                                                Do_SUB <= '1';
217
                                        end if;
218
                                        if Inst_Top(11 downto 6) = "000101" or Inst_Top(11 downto 6) = "111001" then
219
                                                -- ANDWF, ANDLW
220
                                                Do_AND <= '1';
221
                                        end if;
222
                                        if Inst_Top(11 downto 6) = "000100" or Inst_Top(11 downto 6) = "111000" then
223
                                                -- IORWF, IORLW
224
                                                Do_OR <= '1';
225
                                        end if;
226
                                        if Inst_Top(11 downto 6) = "000110" or Inst_Top(11 downto 6) = "111010" then
227
                                                -- XORWF, XORLW
228
                                                Do_XOR <= '1';
229
                                        end if;
230
                                end if;
231
 
232
                                if Inst_Top(11 downto 9) = "001" and Inst_Top(7 downto 6) = "11" then
233
                                        -- INC/DEC w conditional skip
234
                                        Do_IDTEST <= '1';
235
                                end if;
236
                                if Inst_Top(11 downto 6) = "001010" or Inst_Top(11 downto 6) = "001111" then
237
                                        -- INCF, INCFSZ
238
                                        Do_INC <= '1';
239
                                end if;
240
                                if Inst_Top(11 downto 6) = "000011" or Inst_Top(11 downto 6) = "001011" then
241
                                        -- DECF, DECFSZ, 
242
                                        Do_DEC <= '1';
243
                                end if;
244
                                if Inst_Top(11 downto 6) = "001001" then
245
                                        -- COMF
246
                                        Do_COM <= '1';
247
                                end if;
248
                                if Inst_Top(11 downto 6) = "001100" then
249
                                        -- RRF
250
                                        Do_RRF <= '1';
251
                                end if;
252
                                if Inst_Top(11 downto 6) = "001101" then
253
                                        -- RLF
254
                                        Do_RLF <= '1';
255
                                end if;
256
                                if Inst_Top(11 downto 6) = "001110" then
257
                                        -- SWAPF
258
                                        Do_SWAP <= '1';
259
                                end if;
260
                                if Inst_Top(11 downto 8) = "0100" then
261
                                        -- BCF
262
                                        Do_BITCLR <= '1';
263
                                end if;
264
                                if Inst_Top(11 downto 8) = "0101" then
265
                                        -- BSF
266
                                        Do_BITSET <= '1';
267
                                end if;
268
                                if Inst_Top(11 downto 8) = "0110" then
269
                                        -- BTFSC
270
                                        Do_BITTESTCLR <= '1';
271
                                end if;
272
                                if Inst_Top(11 downto 8) = "0111" then
273
                                        -- BTFSS
274
                                        Do_BITTESTSET <= '1';
275
                                end if;
276
                                if Inst_Top(11 downto 6) = "000001" then
277
                                        -- CLRF, CLRW
278
                                        Do_CLR <= '1';
279
                                end if;
280
                        end if;
281
 
282
                        case Inst_Top(7 downto 5) is
283
                        when "000" =>
284
                                Bit_Pattern <= "00000001";
285
                        when "001" =>
286
                                Bit_Pattern <= "00000010";
287
                        when "010" =>
288
                                Bit_Pattern <= "00000100";
289
                        when "011" =>
290
                                Bit_Pattern <= "00001000";
291
                        when "100" =>
292
                                Bit_Pattern <= "00010000";
293
                        when "101" =>
294
                                Bit_Pattern <= "00100000";
295
                        when "110" =>
296
                                Bit_Pattern <= "01000000";
297
                        when others =>
298
                                Bit_Pattern <= "10000000";
299
                        end case;
300
                end if;
301
        end process;
302
 
303 11 jesus
        Q_ID <= std_logic_vector(unsigned(A) + 1) when Do_INC = '1' else
304
                        std_logic_vector(unsigned(A) - 1);
305 3 jesus
 
306
        AddSub(A(3 downto 0), B(3 downto 0), Do_SUB, Do_SUB, AddSubRes(3 downto 0), DC_i);
307
        AddSub(A(7 downto 4), B(7 downto 4), Do_SUB, DC_i, AddSubRes(7 downto 4), AddSubRes(8));
308
 
309 11 jesus
        Q_L <= (A and B) when Do_AND = '1' else
310 3 jesus
                (A or B) when Do_OR = '1' else
311 11 jesus
                (A xor B);
312
        Q_C <= (not A);
313 3 jesus
 
314 11 jesus
        Q_RR <= Carry & A(7 downto 1);
315
        Q_RL <= A(6 downto 0) & Carry;
316 3 jesus
 
317 11 jesus
        Q_S <= A(3 downto 0) & A(7 downto 4);
318 3 jesus
 
319 11 jesus
        Q_BC <= ((not Bit_Pattern) and A);
320
        Q_BS <= (Bit_Pattern or A);
321 3 jesus
 
322
        Bit_Test <= Bit_Pattern and A;
323
 
324 11 jesus
        Z_Skip <= '1' when (Do_IDTEST = '1' and Q_ID = "00000000") or
325 3 jesus
                                        (Bit_Test /= "00000000" and Do_BITTESTSET = '1') or
326
                                        (Bit_Test = "00000000" and Do_BITTESTCLR = '1') else '0';
327
 
328 11 jesus
        STATUS_d(2) <= '1' when Q_i(7 downto 0) = "00000000" else '0';
329 3 jesus
        STATUS_d(1) <= DC_i;
330
        STATUS_d(0) <= A(0) when Do_RRF = '1' else
331
                                        A(7) when Do_RLF = '1' else
332
                                        AddSubRes(8);
333
 
334
        -- Z
335
        STATUS_Wr(2) <= '1' when Do_SUB = '1' or Do_ADD = '1' or
336
                ((Do_DEC = '1' or Do_INC = '1') and Do_IDTEST = '0') or
337
                Do_AND = '1' or Do_OR = '1' or Do_XOR = '1' or
338 11 jesus
                Do_CLR = '1' or Do_COM = '1' else '0';
339 3 jesus
        -- DC
340
        STATUS_Wr(1) <= '1' when Do_SUB = '1' or Do_ADD = '1' else '0';
341
        -- C
342
        STATUS_Wr(0) <= '1' when Do_SUB = '1' or Do_ADD = '1' or Do_RRF = '1' or Do_RLF = '1' else '0';
343
 
344
end;

powered by: WebSVN 2.1.0

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