1 -----------------------------------------
2 ------------- ALU Core -----------------
3 -----------------------------------------
6 use ieee.std_logic_1164.all;
7 use ieee.std_logic_unsigned.all;
12 generic ( dsize : integer := 8
15 sel : in std_logic_vector (3 downto 0);
16 d1 : in std_logic_vector (dsize - 1 downto 0);
17 d2 : in std_logic_vector (dsize - 1 downto 0);
18 d_out : out std_logic_vector (dsize - 1 downto 0);
19 carry_in : in std_logic;
20 negative : out std_logic;
22 carry_out : out std_logic;
23 overflow : out std_logic
27 architecture rtl of alu_core is
29 procedure d_print(msg : string) is
31 use ieee.std_logic_textio.all;
32 variable out_l : line;
35 writeline(output, out_l);
38 constant ALU_AND : std_logic_vector (3 downto 0) := "0000";
39 constant ALU_EOR : std_logic_vector (3 downto 0) := "0001";
40 constant ALU_OR : std_logic_vector (3 downto 0) := "0010";
41 constant ALU_BIT : std_logic_vector (3 downto 0) := "0011";
42 constant ALU_ADC : std_logic_vector (3 downto 0) := "0100";
43 constant ALU_SBC : std_logic_vector (3 downto 0) := "0101";
44 constant ALU_CMP : std_logic_vector (3 downto 0) := "0110";
45 constant ALU_SL : std_logic_vector (3 downto 0) := "0111";
46 constant ALU_SR : std_logic_vector (3 downto 0) := "1000";
47 constant ALU_RL : std_logic_vector (3 downto 0) := "1001";
48 constant ALU_RR : std_logic_vector (3 downto 0) := "1010";
49 constant ALU_INC : std_logic_vector (3 downto 0) := "1011";
50 constant ALU_DEC : std_logic_vector (3 downto 0) := "1100";
54 alu_p : process (sel, d1, d2, carry_in)
55 variable res : std_logic_vector (dsize downto 0);
57 procedure set_n (data : in std_logic_vector (dsize - 1 downto 0)) is
59 if (data(7) = '1') then
66 procedure set_z (data : in std_logic_vector (dsize - 1 downto 0)) is
68 if (data(7) or data(6) or data(5) or data(4) or
69 data(3) or data(2) or data(1) or data(0)) = '0' then
79 elsif sel = ALU_EOR then
81 elsif sel = ALU_OR then
83 elsif sel = ALU_BIT then
85 elsif sel = ALU_ADC then
86 res := ('0' & d1) + ('0' & d2) + carry_in;
87 d_out <= res(dsize - 1 downto 0);
88 carry_out <= res(dsize);
89 if ((d1(dsize - 1) = d1(dsize - 1))
90 and (d1(dsize - 1) /= res(dsize - 1))) then
96 elsif sel = ALU_SBC then
98 elsif sel = ALU_CMP then
100 elsif sel = ALU_SL then
102 elsif sel = ALU_SR then
104 elsif sel = ALU_RL then
106 elsif sel = ALU_RR then
108 elsif sel = ALU_INC then
109 res := ('0' & d1) + "000000001";
110 d_out <= res(dsize - 1 downto 0);
111 carry_out <= res(dsize);
112 elsif sel = ALU_DEC then
113 res := ('0' & d1) - "000000001";
114 d_out <= res(dsize - 1 downto 0);
115 carry_out <= res(dsize);
117 set_n(res(dsize - 1 downto 0));
118 set_z(res(dsize - 1 downto 0));
125 ----------------------------
126 ---- 6502 ALU implementation
127 ----------------------------
129 use ieee.std_logic_1164.all;
130 use ieee.std_logic_unsigned.all;
133 generic ( dsize : integer := 8
135 port ( clk : in std_logic;
136 pcl_inc_n : in std_logic;
137 pch_inc_n : in std_logic;
138 sph_oe_n : in std_logic;
139 sp_push_n : in std_logic;
140 sp_pop_n : in std_logic;
141 abs_xy_n : in std_logic;
142 abs_pg_next_n : in std_logic;
144 zp_xy_n : in std_logic;
145 arith_en_n : in std_logic;
146 instruction : in std_logic_vector (dsize - 1 downto 0);
147 int_d_bus : inout std_logic_vector (dsize - 1 downto 0);
148 acc_out : in std_logic_vector (dsize - 1 downto 0);
149 index_bus : in std_logic_vector (dsize - 1 downto 0);
150 bal : in std_logic_vector (dsize - 1 downto 0);
151 bah : in std_logic_vector (dsize - 1 downto 0);
152 alu_res : out std_logic_vector (dsize - 1 downto 0);
153 abl : out std_logic_vector (dsize - 1 downto 0);
154 abh : out std_logic_vector (dsize - 1 downto 0);
155 pcl_inc_carry : out std_logic;
156 ea_carry : out std_logic;
157 carry_in : in std_logic;
158 negative : out std_logic;
159 zero : out std_logic;
160 carry_out : out std_logic;
161 overflow : out std_logic
165 architecture rtl of alu is
167 component d_flip_flop
173 res_n : in std_logic;
174 set_n : in std_logic;
176 d : in std_logic_vector (dsize - 1 downto 0);
177 q : out std_logic_vector (dsize - 1 downto 0)
182 generic ( dsize : integer := 8
185 sel : in std_logic_vector (3 downto 0);
186 d1 : in std_logic_vector (dsize - 1 downto 0);
187 d2 : in std_logic_vector (dsize - 1 downto 0);
188 d_out : out std_logic_vector (dsize - 1 downto 0);
189 carry_in : in std_logic;
190 negative : out std_logic;
191 zero : out std_logic;
192 carry_out : out std_logic;
193 overflow : out std_logic
197 constant ALU_AND : std_logic_vector (3 downto 0) := "0000";
198 constant ALU_EOR : std_logic_vector (3 downto 0) := "0001";
199 constant ALU_OR : std_logic_vector (3 downto 0) := "0010";
200 constant ALU_BIT : std_logic_vector (3 downto 0) := "0011";
201 constant ALU_ADC : std_logic_vector (3 downto 0) := "0100";
202 constant ALU_SBC : std_logic_vector (3 downto 0) := "0101";
203 constant ALU_CMP : std_logic_vector (3 downto 0) := "0110";
204 constant ALU_SL : std_logic_vector (3 downto 0) := "0111";
205 constant ALU_SR : std_logic_vector (3 downto 0) := "1000";
206 constant ALU_RL : std_logic_vector (3 downto 0) := "1001";
207 constant ALU_RR : std_logic_vector (3 downto 0) := "1010";
208 constant ALU_INC : std_logic_vector (3 downto 0) := "1011";
209 constant ALU_DEC : std_logic_vector (3 downto 0) := "1100";
211 procedure d_print(msg : string) is
213 use ieee.std_logic_textio.all;
214 variable out_l : line;
217 writeline(output, out_l);
220 signal sel : std_logic_vector (3 downto 0);
221 signal d1 : std_logic_vector (dsize - 1 downto 0);
222 signal d2 : std_logic_vector (dsize - 1 downto 0);
223 signal d_out : std_logic_vector (dsize - 1 downto 0);
225 signal al_reg_in : std_logic_vector (dsize - 1 downto 0);
226 signal ah_reg_in : std_logic_vector (dsize - 1 downto 0);
227 signal al_reg : std_logic_vector (dsize - 1 downto 0);
228 signal ah_reg : std_logic_vector (dsize - 1 downto 0);
230 signal n : std_logic;
231 signal z : std_logic;
232 signal c_in : std_logic;
233 signal c : std_logic;
234 signal v : std_logic;
236 signal al_buf_we : std_logic;
237 signal ah_buf_we : std_logic;
241 al_buf : d_flip_flop generic map (dsize)
242 port map(clk, '1', '1', al_buf_we, al_reg_in, al_reg);
243 ah_buf : d_flip_flop generic map (dsize)
244 port map(clk, '1', '1', ah_buf_we, ah_reg_in, ah_reg);
246 alu_inst : alu_core generic map (dsize)
247 port map (sel, d1, d2, d_out, c_in, n, z, c, v);
249 alu_p : process (clk, pcl_inc_n, pch_inc_n, sph_oe_n, sp_push_n, sp_pop_n,
250 abs_xy_n, abs_pg_next_n, zp_n, zp_xy_n, arith_en_n,
252 int_d_bus, acc_out, index_bus, bal, bal, carry_in, d_out,
255 if (pcl_inc_n = '0') then
261 --keep the value in the cycle
271 elsif (pch_inc_n = '0') then
275 pcl_inc_carry <= '0';
277 --inc pch cycle is not fetch cycle.
278 --it is special cycle.
282 elsif (sph_oe_n = '0') then
286 if (sp_push_n /= '0' and sp_pop_n /= '0') then
288 elsif (sp_pop_n = '0') then
312 elsif (abs_xy_n = '0') then
313 if (abs_pg_next_n = '0') then
320 ---al is in the al_reg.
329 ---keep al for page crossed case
336 elsif (arith_en_n = '0') then
337 --instruction is aaabbbcc format.
338 if instruction (1 downto 0) = "01" then
339 if instruction (7 downto 5) = "000" then
341 elsif instruction (7 downto 5) = "001" then
343 elsif instruction (7 downto 5) = "010" then
345 elsif instruction (7 downto 5) = "011" then
347 elsif instruction (7 downto 5) = "110" then
355 elsif instruction (7 downto 5) = "111" then
358 elsif instruction (1 downto 0) = "10" then
359 if instruction (7 downto 5) = "000" then
361 elsif instruction (7 downto 5) = "001" then
363 elsif instruction (7 downto 5) = "010" then
365 elsif instruction (7 downto 5) = "011" then
367 elsif instruction (7 downto 5) = "110" then
369 elsif instruction (7 downto 5) = "111" then
372 elsif instruction (1 downto 0) = "00" then
373 if instruction (7 downto 5) = "001" then
375 elsif instruction (7 downto 5) = "110" then
377 elsif instruction (7 downto 5) = "111" then
379 end if; --if instruction (7 downto 5) = "001" then
380 end if; --if instruction (1 downto 0) = "01"
382 int_d_bus <= (others => 'Z');
391 ----alu_res is always bal for jsr instruction....
392 -----TODO must check later if it's ok.
394 pcl_inc_carry <= '0';
395 end if; --if (pcl_inc_n = '0') then
401 ----------------------------------------
402 ---- 6502 effective address calucurator
403 ----------------------------------------
405 use ieee.std_logic_1164.all;
406 use ieee.std_logic_unsigned.all;
408 entity effective_adder is
409 generic ( dsize : integer := 8
412 ea_calc_n : in std_logic;
414 pg_next_n : in std_logic;
415 base_l : in std_logic_vector (dsize - 1 downto 0);
416 base_h : in std_logic_vector (dsize - 1 downto 0);
417 index : in std_logic_vector (dsize - 1 downto 0);
418 ah_bus : out std_logic_vector (dsize - 1 downto 0);
419 al_bus : out std_logic_vector (dsize - 1 downto 0);
420 carry : out std_logic
424 architecture rtl of effective_adder is
426 signal adc_work : std_logic_vector (dsize downto 0);
429 adc_work <= ('0' & base_l) + ('0' & index);
430 carry <= adc_work(dsize) when ea_calc_n = '0' else
432 --if not calc effective adder, pass through input.
433 al_bus <= adc_work(dsize - 1 downto 0) when ea_calc_n = '0' else
436 ah_bus <= "00000000" when zp_n = '0' else
437 base_h + '1' when ea_calc_n = '0' and pg_next_n = '0' else