OSDN Git Service

b2426cd20471129e8d776566d6a3a43234140e96
[motonesfpga/motonesfpga.git] / simulation / cpu / cpu_registers.vhd
1
2 ----------------------------------------
3 --- program counter register declaration
4 ----------------------------------------
5
6 library ieee;
7 use ieee.std_logic_1164.all;
8 use ieee.std_logic_unsigned.all;
9 use ieee.std_logic_arith.conv_std_logic_vector;
10
11 entity pc is 
12     generic (
13             dsize : integer := 8;
14             reset_addr : integer := 0
15             );
16     port (  
17             clk             : in std_logic;
18             res_n           : in std_logic;
19             pc_type         : in std_logic;     --'0' pcl, '1' pch
20             dbus_we_n       : in std_logic;
21             abus_we_n       : in std_logic;
22             dbus_oe_n       : in std_logic;
23             abus_oe_n       : in std_logic;
24             addr_inc_n      : in std_logic;
25             addr_dec_n      : in std_logic;
26             add_carry       : out std_logic;
27             rel_we_n        : in std_logic;
28             rel_calc_n      : in std_logic;
29             rel_prev        : out std_logic;
30             int_d_bus       : inout std_logic_vector (dsize - 1 downto 0);
31             int_a_bus       : inout std_logic_vector (dsize - 1 downto 0)
32         );
33 end pc;
34
35 architecture rtl of pc is
36
37 component dff
38     generic (
39             dsize : integer := 8
40             );
41     port (  
42             clk         : in std_logic;
43             we_n    : in std_logic;
44             oe_n    : in std_logic;
45             d       : in std_logic_vector (dsize - 1 downto 0);
46             q       : out std_logic_vector (dsize - 1 downto 0)
47         );
48 end component;
49
50 signal val : std_logic_vector (dsize - 1 downto 0);
51 signal rel : std_logic_vector (dsize - 1 downto 0);
52
53 begin
54                 ---increment & page moved case.
55     int_a_bus <= val + 1 when (abus_oe_n = '0' 
56                                 and pc_type = '1' and addr_inc_n = '0') else
57                 val when (abus_oe_n = '0') else
58                 (others => 'Z');
59
60                 ---increment & page moved case.
61     int_d_bus <= val + 1 when (dbus_oe_n = '0' 
62                                 and pc_type = '1' and addr_inc_n = '0') else
63                 val when (dbus_oe_n = '0') else
64                 (others => 'Z');
65
66     set_p : process (clk, res_n)
67     variable add_val : std_logic_vector(dsize downto 0);
68     variable dec_val : std_logic_vector(dsize downto 0);
69     begin
70         if (clk'event and clk = '1') then
71
72             if (addr_inc_n = '0' and abus_we_n = '0') then
73                 --case increment & address set
74                 --for jmp op, abs xy not page crossing case.
75                 add_val := ('0' & int_a_bus) + 1;
76                 val <= add_val(dsize - 1 downto 0);
77                 add_carry <= add_val(dsize);
78                 rel_prev <= '0';
79             elsif (addr_inc_n = '0') then
80                 add_val := ('0' & val) + 1;
81                 val <= add_val(dsize - 1 downto 0);
82                 add_carry <= add_val(dsize);
83                 rel_prev <= '0';
84             elsif (addr_dec_n = '0') then
85                 dec_val := ('0' & val) - 1;
86                 val <= dec_val(dsize - 1 downto 0);
87                 add_carry <= '0';
88                 rel_prev <= '0';
89             elsif (rel_calc_n = '0') then
90                 add_val := ('0' & val) + ('0' & rel);
91                 --relative addressing mode is signed operation.
92                 if (rel(7) = '0') then
93                     --add positive
94                     add_carry <= add_val(dsize);
95                     rel_prev <= '0';
96                 else
97                     --add negative
98                     add_carry <= '0';
99                     if (add_val(7) = '1') then
100                         --negative value > goto preveous page.
101                         rel_prev <= '1';
102                     else
103                         rel_prev <= '0';
104                     end if;
105                 end if;
106                 val <= add_val(dsize - 1 downto 0);
107             elsif (abus_we_n = '0') then
108                 val <= int_a_bus;
109                 add_carry <= '0';
110                 rel_prev <= '0';
111             elsif (dbus_we_n = '0') then
112                 val <= int_d_bus;
113                 add_carry <= '0';
114                 rel_prev <= '0';
115             else
116                 rel_prev <= '0';
117                 add_carry <= '0';
118             end if;
119         elsif (res_n'event and res_n = '0') then
120             val <= conv_std_logic_vector(reset_addr, dsize);
121         end if;
122     end process;
123
124     rel_dff : dff generic map (dsize) 
125                     port map(clk, rel_we_n, '0', int_d_bus, rel);
126 end rtl;
127
128 ----------------------------------------
129 --- normal d-flipflop declaration
130 ----------------------------------------
131
132 library ieee;
133 use ieee.std_logic_1164.all;
134
135 entity dff is 
136     generic (
137             dsize : integer := 8
138             );
139     port (  
140             clk     : in std_logic;
141             we_n    : in std_logic;
142             oe_n    : in std_logic;
143             d       : in std_logic_vector (dsize - 1 downto 0);
144             q       : out std_logic_vector (dsize - 1 downto 0)
145         );
146 end dff;
147
148 architecture rtl of dff is
149 signal val : std_logic_vector (dsize - 1 downto 0);
150 begin
151
152     process (clk)
153     begin
154         if ( clk'event and clk = '1'and we_n = '0') then
155             val <= d;
156         end if;
157     end process;
158
159     q <= val when oe_n = '0' else
160         (others => 'Z');
161 end rtl;
162
163 ----------------------------------------
164 --- normal data latch declaration
165 ----------------------------------------
166
167 library ieee;
168 use ieee.std_logic_1164.all;
169
170 entity latch is 
171     generic (
172             dsize : integer := 8
173             );
174     port (  
175             clk     : in std_logic;
176             oe_n    : in std_logic;
177             d       : in std_logic_vector (dsize - 1 downto 0);
178             q       : out std_logic_vector (dsize - 1 downto 0)
179         );
180 end latch;
181
182 architecture rtl of latch is
183 signal val : std_logic_vector (dsize - 1 downto 0);
184 begin
185
186     process (clk, d)
187     begin
188         if ( clk = '1') then
189             --latch only when clock is high
190             val <= d;
191         end if;
192     end process;
193
194     q <= val when oe_n = '0' else
195         (others => 'Z');
196 end rtl;
197
198 ----------------------------------------
199 --- data bus buffer register
200 ----------------------------------------
201
202 library ieee;
203 use ieee.std_logic_1164.all;
204
205 entity dbus_buf is 
206     generic (
207             dsize : integer := 8
208             );
209     port (  
210             clk         : in std_logic;
211             r_nw        : in std_logic;
212             int_oe_n    : in std_logic;
213             int_dbus : inout std_logic_vector (dsize - 1 downto 0);
214             ext_dbus : inout std_logic_vector (dsize - 1 downto 0)
215         );
216 end dbus_buf;
217
218 architecture rtl of dbus_buf is
219 component latch
220     generic (
221             dsize : integer := 8
222             );
223     port (  
224             clk     : in std_logic;
225             oe_n    : in std_logic;
226             d       : in std_logic_vector (dsize - 1 downto 0);
227             q       : out std_logic_vector (dsize - 1 downto 0)
228         );
229 end component;
230
231 signal rd_clk : std_logic;
232 signal wr_clk : std_logic;
233 begin
234     rd_clk <= r_nw and clk;
235     wr_clk <= (not r_nw) and clk;
236
237     --read from i/o to cpu
238     latch_r : latch generic map (dsize) 
239                     port map(rd_clk, int_oe_n, ext_dbus, int_dbus);
240     --write from cpu to io
241     latch_w : latch generic map (dsize) 
242                     port map(wr_clk, r_nw, int_dbus, ext_dbus);
243 end rtl;
244
245 ----------------------------------------
246 --- input data latch register
247 ----------------------------------------
248
249 library ieee;
250 use ieee.std_logic_1164.all;
251
252 entity input_dl is 
253     generic (
254             dsize : integer := 8
255             );
256     port (  
257             clk         : in std_logic;
258             al_we_n     : in std_logic;
259             ah_we_n     : in std_logic;
260             al_oe_n     : in std_logic;
261             ah_oe_n     : in std_logic;
262             int_dbus    : in std_logic_vector (dsize - 1 downto 0);
263             ea_al       : out std_logic_vector (dsize - 1 downto 0);
264             ea_ah       : out std_logic_vector (dsize - 1 downto 0)
265         );
266 end input_dl;
267
268 architecture rtl of input_dl is
269 component latch
270     generic (
271             dsize : integer := 8
272             );
273     port (  
274             clk     : in std_logic;
275             oe_n    : in std_logic;
276             d       : in std_logic_vector (dsize - 1 downto 0);
277             q       : out std_logic_vector (dsize - 1 downto 0)
278         );
279 end component;
280 signal ll_clk : std_logic;
281 signal lh_clk : std_logic;
282 signal ql : std_logic_vector (dsize - 1 downto 0);
283 signal qh : std_logic_vector (dsize - 1 downto 0);
284 begin
285
286     ll_clk <= (not al_we_n) and clk;
287     lh_clk <= (not ah_we_n) and clk;
288     latch_l : latch generic map (dsize) 
289                     port map(ll_clk, '0', int_dbus, ql);
290     latch_h : latch generic map (dsize) 
291                     port map(lh_clk, '0', int_dbus, qh);
292
293     --tri-state buffer at the output
294     ea_al <= ql when al_oe_n = '0' else
295          (others =>'Z');
296     ea_ah <= qh when ah_oe_n = '0' else
297          (others =>'Z');
298
299 end rtl;
300
301 ----------------------------------------
302 --- stack pointer register
303 ----------------------------------------
304
305 library ieee;
306 use ieee.std_logic_1164.all;
307 use ieee.std_logic_unsigned.all;
308
309 entity sp is 
310     generic (
311             dsize : integer := 8
312             );
313     port (  
314             clk         : in std_logic;
315             we_n        : in std_logic;
316             push_n      : in std_logic;
317             pop_n       : in std_logic;
318             int_d_oe_n  : in std_logic;
319             int_a_oe_n  : in std_logic;
320             int_dbus    : inout std_logic_vector (dsize - 1 downto 0);
321             int_abus_l  : out std_logic_vector (dsize - 1 downto 0);
322             int_abus_h  : out std_logic_vector (dsize - 1 downto 0)
323         );
324 end sp;
325
326 architecture rtl of sp is
327 component dff
328     generic (
329             dsize : integer := 8
330             );
331     port (  
332             clk         : in std_logic;
333             we_n    : in std_logic;
334             oe_n    : in std_logic;
335             d       : in std_logic_vector (dsize - 1 downto 0);
336             q       : out std_logic_vector (dsize - 1 downto 0)
337         );
338 end component;
339 signal oe_n : std_logic;
340 signal dff_we_n : std_logic;
341 signal q : std_logic_vector (dsize - 1 downto 0);
342 signal d : std_logic_vector (dsize - 1 downto 0);
343 signal q_buf : std_logic_vector (dsize - 1 downto 0);
344
345 begin
346     oe_n <= (int_d_oe_n and int_a_oe_n);
347     dff_we_n <= (we_n and push_n and pop_n);
348     int_dbus <= q when int_d_oe_n = '0' else
349          (others =>'Z');
350
351     ---push: address decrement after push is done.
352     ---pop: address increment before pop is done.
353     al_p : process (int_a_oe_n, push_n, clk, q_buf, q)
354     begin
355         if (int_a_oe_n = '0') then
356             if (push_n = '0') then
357                 if (clk = '1') then
358                     int_abus_l <= q_buf;
359                 else
360                     int_abus_l <= q;
361                 end if;
362             elsif (pop_n = '0') then
363                 if (clk = '1') then
364                     int_abus_l <= q_buf;
365                 else
366                     int_abus_l <= q;
367                 end if;
368             else
369                 int_abus_l <= q;
370             end if;
371         else
372             int_abus_l <= (others => 'Z');
373         end if;
374     end process;
375
376     int_abus_h <= "00000001" when int_a_oe_n = '0' else
377          (others =>'Z');
378     d <= int_dbus when we_n = '0' else
379             (q - 1) when push_n = '0' else
380             (q + 1) when pop_n = '0' else
381          (others =>'Z');
382
383     dff_inst : dff generic map (dsize) 
384                     port map(clk, dff_we_n, oe_n, d, q);
385     buf : dff generic map (dsize) 
386                     port map(clk, dff_we_n, '0', q, q_buf);
387 end rtl;
388
389
390 ----------------------------------------
391 --- SR flipflop
392 ----------------------------------------
393
394 library ieee;
395 use ieee.std_logic_1164.all;
396
397 entity srff is 
398     generic (
399             dsize : integer := 8
400             );
401     port (  
402             clk     : in std_logic;
403             res_n   : in std_logic;
404             set_n   : in std_logic;
405             we_n    : in std_logic;
406             oe_n    : in std_logic;
407             d       : in std_logic_vector (dsize - 1 downto 0);
408             q       : out std_logic_vector (dsize - 1 downto 0)
409         );
410 end srff;
411
412 architecture rtl of srff is
413 signal val : std_logic_vector (dsize - 1 downto 0);
414 begin
415
416     q <= val when oe_n = '0' else
417         (others => 'Z');
418
419     main_p : process (clk, res_n, set_n, d)
420     begin
421         if ( clk'event and clk = '1'and we_n = '0') then
422             val <= d;
423         end if;
424         if (res_n'event and res_n = '0') then
425             val <= (others => '0');
426         end if;
427         if (set_n = '0') then
428             val <= d;
429         end if;
430     end process;
431 end rtl;
432
433 ----------------------------------------
434 --- status register component
435 ----------------------------------------
436
437 library ieee;
438 use ieee.std_logic_1164.all;
439
440 entity processor_status is 
441     generic (
442             dsize : integer := 8
443             );
444     port (  
445             clk         : in std_logic;
446             res_n       : in std_logic;
447             dec_oe_n    : in std_logic;
448             bus_oe_n    : in std_logic;
449             set_flg_n   : in std_logic;
450             flg_val     : in std_logic;
451             load_bus_all_n : in std_logic;
452             load_bus_nz_n  : in std_logic;
453             alu_we_n    : in std_logic;
454             alu_n       : in std_logic;
455             alu_v       : in std_logic;
456             alu_z       : in std_logic;
457             alu_c       : in std_logic;
458             decoder     : inout std_logic_vector (dsize - 1 downto 0);
459             int_dbus    : inout std_logic_vector (dsize - 1 downto 0)
460         );
461 end processor_status;
462
463 architecture rtl of processor_status is
464 signal val : std_logic_vector (dsize - 1 downto 0);
465 begin
466     decoder <= val when dec_oe_n = '0' else
467                 (others => 'Z');
468     int_dbus <= val when bus_oe_n = '0' else
469                 (others => 'Z');
470                 
471
472     main_p : process (clk, res_n)
473     variable tmp : std_logic_vector (dsize - 1 downto 0);
474     begin
475 --        SR Flags (bit 7 to bit 0):
476 --
477 --        N   ....    Negative
478 --        V   ....    Overflow
479 --        -   ....    ignored
480 --        B   ....    Break
481 --        D   ....    Decimal (use BCD for arithmetics)
482 --        I   ....    Interrupt (IRQ disable)
483 --        Z   ....    Zero
484 --        C   ....    Carry
485     
486       ---only interrupt flag is set on reset.
487         if (res_n'event and res_n = '0') then
488             val <= "00000100";
489         end if;
490
491         if ( clk'event and clk = '1') then
492             ---from flag set/clear instructions
493             if (set_flg_n = '0') then
494                 if flg_val = '1' then
495                     tmp := (decoder and "11111111");
496                 else
497                     tmp := "00000000";
498                 end if;
499                 val <= tmp or (val and not decoder);
500
501             ---status flag set from the data on the internal data bus.
502             ---interpret the input data by the decoder input.
503             ---load/pop/rti/t[asxy]
504             elsif (load_bus_all_n = '0') then
505                 ---set the data bus data as they are.
506                 val <= int_dbus;
507             elsif (load_bus_nz_n = '0') then
508                 ---other case: n/z data must be interpreted.
509                 --n bit.
510                 if int_dbus(7) = '1' then
511                     val (7) <= '1';
512                 else
513                     val (7) <= '0';
514                 end if;
515                 --z bit.
516                 ---nor outputs 1 when all inputs are 0.
517                 if  (int_dbus(7) or int_dbus(6) or 
518                         int_dbus(5) or int_dbus(4) or int_dbus(3) or 
519                         int_dbus(2) or int_dbus(1) or int_dbus(0)) = '0' then
520                     val (1) <= '1';
521                 else
522                     val (1) <= '0';
523                 end if;
524
525             ---status set from alu/inx/iny etc.
526             elsif (alu_we_n = '0') then
527                 tmp := val;
528                 val (5 downto 2) <= tmp (5 downto 2);
529
530                 --n bit.
531                 if (decoder(7) = '1') then
532                     val (7) <= alu_n;
533                 else
534                     val (7) <= tmp (7);
535                 end if;
536                 --v bit.
537                 if (decoder(6) = '1') then
538                     val (6) <= alu_v;
539                 else
540                     val (6) <= tmp (6);
541                 end if;
542                 --z bit.
543                 if (decoder(1) = '1') then
544                     val (1) <= alu_z;
545                 else
546                     val (1) <= tmp (1);
547                 end if;
548                 --c bit.
549                 if (decoder(0) = '1') then
550                     val (0) <= alu_c;
551                 else
552                     val (0) <= tmp (0);
553                 end if;
554             end if; --if (set_flg_n = '0') then
555         end if;
556     end process;
557 end rtl;
558
559
560 ----------------------------------------
561 --- tri-state buffer
562 ----------------------------------------
563
564 library ieee;
565 use ieee.std_logic_1164.all;
566
567 entity tsb is 
568     generic (
569             dsize : integer := 8
570             );
571     port (  
572             oe_n    : in std_logic;
573             d       : in std_logic_vector (dsize - 1 downto 0);
574             q       : out std_logic_vector (dsize - 1 downto 0)
575         );
576 end tsb;
577
578 architecture rtl of tsb is
579 signal val : std_logic_vector (dsize - 1 downto 0);
580 begin
581     q <= d when oe_n = '0' else
582         (others => 'Z');
583 end rtl;
584
585
586 ----------------------------------------
587 --- accumulator
588 ----------------------------------------
589
590 library ieee;
591 use ieee.std_logic_1164.all;
592
593 entity accumulator is 
594     generic (
595             dsize : integer := 8
596             );
597     port (  
598             clk         : in std_logic;
599             d_we_n      : in std_logic;
600             alu_we_n    : in std_logic;
601             d_oe_n      : in std_logic;
602             int_dbus    : inout std_logic_vector (dsize - 1 downto 0);
603             alu_out     : in std_logic_vector (dsize - 1 downto 0);
604             alu_in      : out std_logic_vector (dsize - 1 downto 0)
605         );
606 end accumulator;
607
608 architecture rtl of accumulator is
609 component dff
610     generic (
611             dsize : integer := 8
612             );
613     port (  
614             clk     : in std_logic;
615             we_n    : in std_logic;
616             oe_n    : in std_logic;
617             d       : in std_logic_vector (dsize - 1 downto 0);
618             q       : out std_logic_vector (dsize - 1 downto 0)
619         );
620 end component;
621
622 signal we_n : std_logic;
623 signal d : std_logic_vector (dsize - 1 downto 0);
624 signal q : std_logic_vector (dsize - 1 downto 0);
625
626 begin
627     we_n <= (d_we_n and alu_we_n);
628     d <= int_dbus when d_we_n = '0' else
629         alu_out when alu_we_n = '0' else
630         (others => 'Z');
631     int_dbus <= q when d_oe_n = '0' else
632         (others => 'Z');
633     alu_in <= q;
634
635     --read from i/o to cpu
636     dff_inst : dff generic map (dsize) 
637                     port map(clk, we_n, '0', d, q);
638 end rtl;
639
640 ----------------------------------------
641 --- index register x/y
642 ----------------------------------------
643
644 library ieee;
645 use ieee.std_logic_1164.all;
646
647 entity index_reg is 
648     generic (
649             dsize : integer := 8
650             );
651     port (  
652             clk         : in std_logic;
653             d_we_n      : in std_logic;
654             d_oe_n      : in std_logic;
655             ea_oe_n     : in std_logic;
656             inc_n       : in std_logic;
657             dec_n       : in std_logic;
658             int_dbus    : inout std_logic_vector (dsize - 1 downto 0);
659             ea_bus      : out std_logic_vector (dsize - 1 downto 0);
660             n           : out std_logic;
661             z           : out std_logic
662         );
663 end index_reg;
664
665 architecture rtl of index_reg is
666 component dff
667     generic (
668             dsize : integer := 8
669             );
670     port (  
671             clk     : in std_logic;
672             we_n    : in std_logic;
673             oe_n    : in std_logic;
674             d       : in std_logic_vector (dsize - 1 downto 0);
675             q       : out std_logic_vector (dsize - 1 downto 0)
676         );
677 end component;
678
679 use ieee.std_logic_1164.all;
680 use ieee.std_logic_unsigned.all;
681
682 signal we_n : std_logic;
683 signal q : std_logic_vector (dsize - 1 downto 0);
684 signal d : std_logic_vector (dsize - 1 downto 0);
685
686 begin
687     int_dbus <= q when d_oe_n = '0' else
688         (others => 'Z');
689     ea_bus <= q when ea_oe_n = '0' else
690         (others => 'Z');
691
692     --for inx/iny/dex/dey instructions...
693     inc_dec_p : process (clk, int_dbus, inc_n, dec_n)
694     variable inc_work : std_logic_vector (dsize downto 0);
695     variable dec_work : std_logic_vector (dsize downto 0);
696     begin
697         inc_work := ('0' & q) + 1;
698         dec_work := ('0' & q) - 1;
699         if inc_n = '0' then
700             d <= inc_work(dsize - 1 downto 0);
701             z <= not (inc_work(7) or inc_work(6) or 
702                     inc_work(5) or inc_work(4) or inc_work(3) or 
703                     inc_work(2) or inc_work(1) or inc_work(0));
704             n <= inc_work(dsize);
705         elsif dec_n = '0' then
706             d <= dec_work(dsize - 1 downto 0);
707             z <= not (dec_work(7) or dec_work(6) or 
708                 dec_work(5) or dec_work(4) or dec_work(3) or 
709                 dec_work(2) or dec_work(1) or dec_work(0)); 
710             n <= dec_work(dsize); 
711         else
712             d <= int_dbus;
713             z <= 'Z';
714             n <= 'Z';
715         end if;
716
717     end process;
718
719     --read from i/o to cpu
720     we_n <= d_we_n and inc_n and dec_n;
721     dff_inst : dff generic map (dsize) 
722                     port map(clk, we_n, '0', d, q);
723
724 end rtl;
725
726