/[projet1]/users/jede/electronique/vhdl/T6502_65816/T65_ALU.vhd
Defence Force logotype

Contents of /users/jede/electronique/vhdl/T6502_65816/T65_ALU.vhd

Parent Directory Parent Directory | Revision Log Revision Log


Revision 710 - (show annotations)
Tue Nov 1 12:36:41 2011 UTC (8 years, 7 months ago) by Jede
File size: 7783 byte(s)


1 -- ****
2 -- T65(b) core. In an effort to merge and maintain bug fixes ....
3 --
4 --
5 -- Ver 300 Bugfixes by ehenciak added
6 -- MikeJ March 2005
7 -- Latest version from www.fpgaarcade.com (original www.opencores.org)
8 --
9 -- ****
10 --
11 -- 6502 compatible microprocessor core
12 --
13 -- Version : 0245
14 --
15 -- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
16 --
17 -- All rights reserved
18 --
19 -- Redistribution and use in source and synthezised forms, with or without
20 -- modification, are permitted provided that the following conditions are met:
21 --
22 -- Redistributions of source code must retain the above copyright notice,
23 -- this list of conditions and the following disclaimer.
24 --
25 -- Redistributions in synthesized form must reproduce the above copyright
26 -- notice, this list of conditions and the following disclaimer in the
27 -- documentation and/or other materials provided with the distribution.
28 --
29 -- Neither the name of the author nor the names of other contributors may
30 -- be used to endorse or promote products derived from this software without
31 -- specific prior written permission.
32 --
33 -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
35 -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36 -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
37 -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 -- POSSIBILITY OF SUCH DAMAGE.
44 --
45 -- Please report bugs to the author, but before you do so, please
46 -- make sure that this is not a derivative work and that
47 -- you have the latest version of this file.
48 --
49 -- The latest version of this file can be found at:
50 -- http://www.opencores.org/cvsweb.shtml/t65/
51 --
52 -- Limitations :
53 --
54 -- File history :
55 --
56 -- 0245 : First version
57 --
58
59 library IEEE;
60 use IEEE.std_logic_1164.all;
61 use IEEE.numeric_std.all;
62 use work.T65_Pack.all;
63
64 entity T65_ALU is
65 port(
66 Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
67 Op : in std_logic_vector(3 downto 0);
68 BusA : in std_logic_vector(7 downto 0);
69 BusB : in std_logic_vector(7 downto 0);
70 P_In : in std_logic_vector(7 downto 0);
71 P_Out : out std_logic_vector(7 downto 0);
72 Q : out std_logic_vector(7 downto 0)
73 );
74 end T65_ALU;
75
76 architecture rtl of T65_ALU is
77
78 -- AddSub variables (temporary signals)
79 signal ADC_Z : std_logic;
80 signal ADC_C : std_logic;
81 signal ADC_V : std_logic;
82 signal ADC_N : std_logic;
83 signal ADC_Q : std_logic_vector(7 downto 0);
84 signal SBC_Z : std_logic;
85 signal SBC_C : std_logic;
86 signal SBC_V : std_logic;
87 signal SBC_N : std_logic;
88 signal SBC_Q : std_logic_vector(7 downto 0);
89
90 begin
91
92 process (P_In, BusA, BusB)
93 variable AL : unsigned(6 downto 0);
94 variable AH : unsigned(6 downto 0);
95 variable C : std_logic;
96 begin
97 AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7);
98 AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
99
100 -- pragma translate_off
101 if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
102 if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
103 -- pragma translate_on
104
105 if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
106 ADC_Z <= '1';
107 else
108 ADC_Z <= '0';
109 end if;
110
111 if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then
112 AL(6 downto 1) := AL(6 downto 1) + 6;
113 end if;
114
115 C := AL(6) or AL(5);
116 AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
117
118 ADC_N <= AH(4);
119 ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7));
120
121 -- pragma translate_off
122 if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
123 -- pragma translate_on
124
125 if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then
126 AH(6 downto 1) := AH(6 downto 1) + 6;
127 end if;
128
129 ADC_C <= AH(6) or AH(5);
130
131 ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
132 end process;
133
134 process (Op, P_In, BusA, BusB)
135 variable AL : unsigned(6 downto 0);
136 variable AH : unsigned(5 downto 0);
137 variable C : std_logic;
138 begin
139 C := P_In(Flag_C) or not Op(0);
140 AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6);
141 AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6);
142
143 -- pragma translate_off
144 if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
145 if is_x(std_logic_vector(AH)) then AH := "000000"; end if;
146 -- pragma translate_on
147
148 if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
149 SBC_Z <= '1';
150 else
151 SBC_Z <= '0';
152 end if;
153
154 SBC_C <= not AH(5);
155 SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7));
156 SBC_N <= AH(4);
157
158 if P_In(Flag_D) = '1' then
159 if AL(5) = '1' then
160 AL(5 downto 1) := AL(5 downto 1) - 6;
161 end if;
162 AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6);
163 if AH(5) = '1' then
164 AH(5 downto 1) := AH(5 downto 1) - 6;
165 end if;
166 end if;
167
168 SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
169 end process;
170
171 process (Op, P_In, BusA, BusB,
172 ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q,
173 SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q)
174 variable Q_t : std_logic_vector(7 downto 0);
175 begin
176 -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
177 -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
178 P_Out <= P_In;
179 Q_t := BusA;
180 case Op(3 downto 0) is
181 when "0000" =>
182 -- ORA
183 Q_t := BusA or BusB;
184 when "0001" =>
185 -- AND
186 Q_t := BusA and BusB;
187 when "0010" =>
188 -- EOR
189 Q_t := BusA xor BusB;
190 when "0011" =>
191 -- ADC
192 P_Out(Flag_V) <= ADC_V;
193 P_Out(Flag_C) <= ADC_C;
194 Q_t := ADC_Q;
195 when "0101" | "1101" =>
196 -- LDA
197 when "0110" =>
198 -- CMP
199 P_Out(Flag_C) <= SBC_C;
200 when "0111" =>
201 -- SBC
202 P_Out(Flag_V) <= SBC_V;
203 P_Out(Flag_C) <= SBC_C;
204 Q_t := SBC_Q;
205 when "1000" =>
206 -- ASL
207 Q_t := BusA(6 downto 0) & "0";
208 P_Out(Flag_C) <= BusA(7);
209 when "1001" =>
210 -- ROL
211 Q_t := BusA(6 downto 0) & P_In(Flag_C);
212 P_Out(Flag_C) <= BusA(7);
213 when "1010" =>
214 -- LSR
215 Q_t := "0" & BusA(7 downto 1);
216 P_Out(Flag_C) <= BusA(0);
217 when "1011" =>
218 -- ROR
219 Q_t := P_In(Flag_C) & BusA(7 downto 1);
220 P_Out(Flag_C) <= BusA(0);
221 when "1100" =>
222 -- BIT
223 P_Out(Flag_V) <= BusB(6);
224 when "1110" =>
225 -- DEC
226 Q_t := std_logic_vector(unsigned(BusA) - 1);
227 when "1111" =>
228 -- INC
229 Q_t := std_logic_vector(unsigned(BusA) + 1);
230 when others =>
231 end case;
232
233 case Op(3 downto 0) is
234 when "0011" =>
235 P_Out(Flag_N) <= ADC_N;
236 P_Out(Flag_Z) <= ADC_Z;
237 when "0110" | "0111" =>
238 P_Out(Flag_N) <= SBC_N;
239 P_Out(Flag_Z) <= SBC_Z;
240 when "0100" =>
241 when "1100" =>
242 P_Out(Flag_N) <= BusB(7);
243 if (BusA and BusB) = "00000000" then
244 P_Out(Flag_Z) <= '1';
245 else
246 P_Out(Flag_Z) <= '0';
247 end if;
248 when others =>
249 P_Out(Flag_N) <= Q_t(7);
250 if Q_t = "00000000" then
251 P_Out(Flag_Z) <= '1';
252 else
253 P_Out(Flag_Z) <= '0';
254 end if;
255 end case;
256
257 Q <= Q_t;
258 end process;
259
260 end;

  ViewVC Help
Powered by ViewVC 1.1.26