OSDN Git Service

- DE1 board initial commit
[motonesfpga/motonesfpga.git] / de1_nes / cpu / cpu_registers.vhd
1
2 ----------------------------------------
3 --- d-flipflop with set/reset
4 ----------------------------------------
5
6 library ieee;
7 use ieee.std_logic_1164.all;
8
9 entity d_flip_flop is 
10     generic (
11             dsize : integer := 8
12             );
13     port (  
14             clk     : in std_logic;
15             res_n   : in std_logic;
16             set_n   : in std_logic;
17             we_n    : in std_logic;
18             d       : in std_logic_vector (dsize - 1 downto 0);
19             q       : out std_logic_vector (dsize - 1 downto 0)
20         );
21 end d_flip_flop;
22
23 architecture rtl of d_flip_flop is
24 begin
25
26     process (clk, res_n, set_n, d)
27     begin
28         if (res_n = '0') then
29             q <= (others => '0');
30         elsif (set_n = '0') then
31             q <= d;
32         elsif (clk'event and clk = '1') then
33             if (we_n = '0') then
34                 q <= d;
35             end if;
36         end if;
37     end process;
38 end rtl;
39
40
41 --------- 1 bit d-flipflop.
42 library ieee;
43 use ieee.std_logic_1164.all;
44
45 entity d_flip_flop_bit is 
46     port (  
47             clk     : in std_logic;
48             res_n   : in std_logic;
49             set_n   : in std_logic;
50             we_n    : in std_logic;
51             d       : in std_logic;
52             q       : out std_logic
53         );
54 end d_flip_flop_bit;
55
56 architecture rtl of d_flip_flop_bit is
57 begin
58
59     process (clk, res_n, set_n, d)
60     begin
61         if (res_n = '0') then
62             q <= '0';
63         elsif (set_n = '0') then
64             q <= d;
65         elsif (clk'event and clk = '1') then
66             if (we_n = '0') then
67                 q <= d;
68             end if;
69         end if;
70     end process;
71 end rtl;
72
73 ----------------------------------------
74 --- data latch declaration
75 ----------------------------------------
76
77 library ieee;
78 use ieee.std_logic_1164.all;
79
80 entity latch is 
81     generic (
82             dsize : integer := 8
83             );
84     port (  
85             clk     : in std_logic;
86             d       : in std_logic_vector (dsize - 1 downto 0);
87             q       : out std_logic_vector (dsize - 1 downto 0)
88         );
89 end latch;
90
91 architecture rtl of latch is
92 begin
93
94     process (clk, d)
95     begin
96         if ( clk = '1') then
97             --latch only when clock is high
98             q <= d;
99         end if;
100     end process;
101 end rtl;
102
103 ----------------------------------------
104 --- tri-state buffer
105 ----------------------------------------
106
107 library ieee;
108 use ieee.std_logic_1164.all;
109
110 entity tri_state_buffer is 
111     generic (
112             dsize : integer := 8
113             );
114     port (  
115             oe_n    : in std_logic;
116             d       : in std_logic_vector (dsize - 1 downto 0);
117             q       : out std_logic_vector (dsize - 1 downto 0)
118         );
119 end tri_state_buffer;
120
121 architecture rtl of tri_state_buffer is
122 begin
123     q <= d when oe_n = '0' else
124         (others => 'Z');
125 end rtl;
126
127
128 ----------------------------------------
129 --- dual port d flip flop w/ tri-state buffer
130 ----------------------------------------
131
132 library ieee;
133 use ieee.std_logic_1164.all;
134
135 entity dual_dff is 
136     generic (
137             dsize : integer := 8
138             );
139     port (  
140             clk             : in std_logic;
141             res_n           : in std_logic;
142             set_n           : in std_logic;
143             gate_cmd        : in std_logic_vector (3 downto 0);
144             front_port      : inout std_logic_vector (dsize - 1 downto 0);
145             back_in_port    : in std_logic_vector (dsize - 1 downto 0);
146             back_out_port   : out std_logic_vector (dsize - 1 downto 0)
147         );
148 end dual_dff;
149
150 architecture rtl of dual_dff is
151
152 component d_flip_flop
153     generic (
154             dsize : integer := 8
155             );
156     port (  
157             clk     : in std_logic;
158             res_n   : in std_logic;
159             set_n   : in std_logic;
160             we_n    : in std_logic;
161             d       : in std_logic_vector (dsize - 1 downto 0);
162             q       : out std_logic_vector (dsize - 1 downto 0)
163         );
164 end component;
165
166 component tri_state_buffer
167     generic (
168             dsize : integer := 8
169             );
170     port (  
171             oe_n    : in std_logic;
172             d       : in std_logic_vector (dsize - 1 downto 0);
173             q       : out std_logic_vector (dsize - 1 downto 0)
174         );
175 end component;
176
177 signal we_n : std_logic;
178 signal q : std_logic_vector (dsize - 1 downto 0);
179 signal d : std_logic_vector (dsize - 1 downto 0);
180
181 begin
182     ----------gate_cmd format 
183     ------3 : front port oe_n
184     ------2 : front port we_n
185     ------1 : back port oe_n
186     ------0 : back port we_n
187     we_n <= (gate_cmd(2) and gate_cmd(0));
188
189     d <= front_port when gate_cmd(2) = '0' else
190          back_in_port when gate_cmd(0) = '0' else
191          (others => 'Z');
192
193     dff_inst : d_flip_flop generic map (dsize) 
194                     port map(clk, res_n, set_n, we_n, d, q);
195
196     front_tsb : tri_state_buffer generic map (dsize) 
197                     port map(gate_cmd(3), q, front_port);
198
199     back_tsb : tri_state_buffer generic map (dsize) 
200                     port map(gate_cmd(1), q, back_out_port);
201 end rtl;
202
203
204 ----------------------------------------
205 --- data bus buffer
206 ----------------------------------------
207
208 library ieee;
209 use ieee.std_logic_1164.all;
210
211 entity data_bus_buffer is 
212     generic (
213             dsize : integer := 8
214             );
215     port (  
216             clk         : in std_logic;
217             r_nw        : in std_logic;
218             int_oe_n    : in std_logic;
219             int_dbus : inout std_logic_vector (dsize - 1 downto 0);
220             ext_dbus : inout std_logic_vector (dsize - 1 downto 0)
221         );
222 end data_bus_buffer;
223
224 architecture rtl of data_bus_buffer is
225 component latch
226     generic (
227             dsize : integer := 8
228             );
229     port (  
230             clk     : in std_logic;
231             d       : in std_logic_vector (dsize - 1 downto 0);
232             q       : out std_logic_vector (dsize - 1 downto 0)
233         );
234 end component;
235
236 component tri_state_buffer
237     generic (
238             dsize : integer := 8
239             );
240     port (  
241             oe_n    : in std_logic;
242             d       : in std_logic_vector (dsize - 1 downto 0);
243             q       : out std_logic_vector (dsize - 1 downto 0)
244         );
245 end component;
246
247 signal rd_clk : std_logic;
248 signal wr_clk : std_logic;
249 signal read_buf : std_logic_vector (dsize - 1 downto 0);
250 signal write_buf : std_logic_vector (dsize - 1 downto 0);
251 begin
252     rd_clk <= r_nw and clk;
253     wr_clk <= (not r_nw) and clk;
254
255     --read from i/o to cpu
256     latch_r : latch generic map (dsize) 
257                     port map(rd_clk, ext_dbus, read_buf);
258     read_tsb : tri_state_buffer generic map (dsize) 
259                     port map(int_oe_n, read_buf, int_dbus);
260     --write from cpu to io
261     latch_w : latch generic map (dsize) 
262                     port map(wr_clk, int_dbus, write_buf);
263     write_tsb : tri_state_buffer generic map (dsize) 
264                     port map(r_nw, write_buf, ext_dbus);
265 end rtl;
266
267 ------------------------------------------
268 ----- input data latch register
269 ------------------------------------------
270
271 library ieee;
272 use ieee.std_logic_1164.all;
273
274 entity input_data_latch is 
275     generic (
276             dsize : integer := 8
277             );
278     port (  
279             clk         : in std_logic;
280             oe_n        : in std_logic;
281             we_n        : in std_logic;
282             int_dbus    : in std_logic_vector (dsize - 1 downto 0);
283             alu_bus     : out std_logic_vector (dsize - 1 downto 0)
284         );
285 end input_data_latch;
286
287 architecture rtl of input_data_latch is
288
289 component latch
290     generic (
291             dsize : integer := 8
292             );
293     port (  
294             clk     : in std_logic;
295             d       : in std_logic_vector (dsize - 1 downto 0);
296             q       : out std_logic_vector (dsize - 1 downto 0)
297         );
298 end component;
299
300 component tri_state_buffer
301     generic (
302             dsize : integer := 8
303             );
304     port (  
305             oe_n    : in std_logic;
306             d       : in std_logic_vector (dsize - 1 downto 0);
307             q       : out std_logic_vector (dsize - 1 downto 0)
308         );
309 end component;
310
311 signal latch_clk : std_logic;
312 signal latch_buf : std_logic_vector (dsize - 1 downto 0);
313
314 begin
315     latch_clk <= (not we_n) and clk;
316     latch_inst : latch generic map (dsize) 
317                     port map(latch_clk, int_dbus, latch_buf);
318     iput_data_tsb : tri_state_buffer generic map (dsize) 
319                     port map(oe_n, latch_buf, alu_bus);
320
321 end rtl;
322
323 ----------------------------------------
324 --- status register component
325 ----------------------------------------
326
327 library ieee;
328 use ieee.std_logic_1164.all;
329
330 entity processor_status is 
331     generic (
332             dsize : integer := 8
333             );
334     port (  
335             clk         : in std_logic;
336             res_n       : in std_logic;
337             dec_oe_n    : in std_logic;
338             bus_oe_n    : in std_logic;
339             set_flg_n   : in std_logic;
340             flg_val     : in std_logic;
341             load_bus_all_n      : in std_logic;
342             load_bus_nz_n       : in std_logic;
343             set_from_alu_n      : in std_logic;
344             alu_n       : in std_logic;
345             alu_v       : in std_logic;
346             alu_z       : in std_logic;
347             alu_c       : in std_logic;
348             stat_c      : out std_logic;
349             dec_val     : inout std_logic_vector (dsize - 1 downto 0);
350             int_dbus    : inout std_logic_vector (dsize - 1 downto 0)
351         );
352 end processor_status;
353
354 architecture rtl of processor_status is
355
356 component d_flip_flop
357     generic (
358             dsize : integer := 8
359             );
360     port (  
361             clk     : in std_logic;
362             res_n   : in std_logic;
363             set_n   : in std_logic;
364             we_n    : in std_logic;
365             d       : in std_logic_vector (dsize - 1 downto 0);
366             q       : out std_logic_vector (dsize - 1 downto 0)
367         );
368 end component;
369
370 component tri_state_buffer
371     generic (
372             dsize : integer := 8
373             );
374     port (  
375             oe_n    : in std_logic;
376             d       : in std_logic_vector (dsize - 1 downto 0);
377             q       : out std_logic_vector (dsize - 1 downto 0)
378         );
379 end component;
380
381 signal we_n : std_logic;
382 signal d : std_logic_vector (dsize - 1 downto 0);
383 signal status_val : std_logic_vector (dsize - 1 downto 0);
384
385 begin
386     dec_tsb : tri_state_buffer generic map (dsize) 
387                     port map(dec_oe_n, status_val, dec_val);
388     dbus_tsb : tri_state_buffer generic map (dsize) 
389                     port map(bus_oe_n, status_val, int_dbus);
390
391     we_n <= set_flg_n and load_bus_all_n and 
392                 load_bus_nz_n and set_from_alu_n;
393
394     dff_inst : d_flip_flop generic map (dsize) 
395                     port map(clk, '1', res_n, we_n, d, status_val);
396
397     --carry status for adc/sbc.
398     stat_c <= status_val(0);
399
400     main_p : process (clk, res_n, we_n, dec_val, int_dbus, 
401                             alu_n, alu_v, alu_z, alu_c)
402     variable tmp : std_logic_vector (dsize - 1 downto 0);
403     begin
404 --        SR Flags (bit 7 to bit 0):
405 --
406 --        N   ....    Negative
407 --        V   ....    Overflow
408 --        -   ....    ignored
409 --        B   ....    Break
410 --        D   ....    Decimal (use BCD for arithmetics)
411 --        I   ....    Interrupt (IRQ disable)
412 --        Z   ....    Zero
413 --        C   ....    Carry
414     
415       ---only interrupt flag is set on reset.
416         if (res_n = '0') then
417             d <= "00000100";
418         else
419             d <= (others => 'Z');
420         end if;
421
422         ---from flag set/clear instructions
423         if (set_flg_n = '0') then
424             if flg_val = '1' then
425                 tmp := (dec_val and "11111111");
426             else
427                 tmp := "00000000";
428             end if;
429             d <= tmp or (status_val and not dec_val);
430
431         ---status flag set from the data on the internal data bus.
432         ---interpret the input data by the dec_val input.
433         ---load/pop/rti/t[asxy]
434         elsif (load_bus_all_n = '0') then
435             ---set the data bus data as they are.
436             d <= int_dbus;
437         elsif (load_bus_nz_n = '0') then
438             tmp := status_val;
439             d (6 downto 2) <= tmp (6 downto 2);
440             d (0) <= tmp (0);
441
442             ---other case: n/z data must be interpreted.
443             --n bit.
444             if int_dbus(7) = '1' then
445                 d (7) <= '1';
446             else
447                 d (7) <= '0';
448             end if;
449             --z bit.
450             ---nor outputs 1 when all inputs are 0.
451             if  (int_dbus(7) or int_dbus(6) or 
452                     int_dbus(5) or int_dbus(4) or int_dbus(3) or 
453                     int_dbus(2) or int_dbus(1) or int_dbus(0)) = '0' then
454                 d (1) <= '1';
455             else
456                 d (1) <= '0';
457             end if;
458
459         ---status set from alu
460         elsif (set_from_alu_n = '0') then
461             tmp := status_val;
462             d (5 downto 2) <= tmp (5 downto 2);
463
464             --n bit.
465             if (dec_val(7) = '1') then
466                 d (7) <= alu_n;
467             else
468                 d (7) <= tmp (7);
469             end if;
470             --v bit.
471             if (dec_val(6) = '1') then
472                 d (6) <= alu_v;
473             else
474                 d (6) <= tmp (6);
475             end if;
476             --z bit.
477             if (dec_val(1) = '1') then
478                 d (1) <= alu_z;
479             else
480                 d (1) <= tmp (1);
481             end if;
482             --c bit.
483             if (dec_val(0) = '1') then
484                 d (0) <= alu_c;
485             else
486                 d (0) <= tmp (0);
487             end if;
488         end if; --if (set_flg_n = '0') then
489     end process;
490 end rtl;
491
492