OSDN Git Service

- stack push ok.
[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             trig_clk        : in std_logic;
18             res_n           : in std_logic;
19             dbus_we_n       : in std_logic;
20             abus_we_n       : in std_logic;
21             dbus_oe_n       : in std_logic;
22             abus_oe_n       : in std_logic;
23             addr_inc_n      : in std_logic;
24             add_carry       : in std_logic;
25             inc_carry       : out std_logic;
26             int_d_bus       : inout std_logic_vector (dsize - 1 downto 0);
27             int_a_bus       : inout std_logic_vector (dsize - 1 downto 0)
28         );
29 end pc;
30
31 architecture rtl of pc is
32
33 signal val : std_logic_vector (dsize - 1 downto 0);
34
35 begin
36     int_a_bus <= (val + add_carry) when 
37                     (abus_oe_n = '0' and add_carry = '1') else
38                   val when 
39                     (abus_oe_n = '0' and add_carry /= '1') else
40                 (others => 'Z');
41     int_d_bus <= (val + add_carry) when 
42                     (dbus_oe_n = '0' and add_carry = '1') else
43                   val when 
44                     (dbus_oe_n = '0' and add_carry /= '1') else
45                 (others => 'Z');
46
47     set_p : process (trig_clk, res_n)
48     variable add_val : std_logic_vector(dsize downto 0);
49     begin
50         if ( trig_clk'event and trig_clk = '1') then
51             if (addr_inc_n = '0') then
52                 add_val := ('0' & val) + 1;
53                 inc_carry <= add_val(dsize);
54                 val <= add_val(dsize - 1 downto 0);
55             end if;
56             if (dbus_we_n = '0') then
57                 val <= int_d_bus;
58             end if;
59             if (abus_we_n = '0') then
60                 val <= int_a_bus;
61             end if;
62         elsif (res_n'event and res_n = '0') then
63             val <= conv_std_logic_vector(reset_addr, dsize);
64         end if;
65     end process;
66 end rtl;
67
68 ----------------------------------------
69 --- normal d-flipflop declaration
70 ----------------------------------------
71
72 library ieee;
73 use ieee.std_logic_1164.all;
74
75 entity dff is 
76     generic (
77             dsize : integer := 8
78             );
79     port (  
80             clk     : in std_logic;
81             we_n    : in std_logic;
82             oe_n    : in std_logic;
83             d       : in std_logic_vector (dsize - 1 downto 0);
84             q       : out std_logic_vector (dsize - 1 downto 0)
85         );
86 end dff;
87
88 architecture rtl of dff is
89 signal val : std_logic_vector (dsize - 1 downto 0);
90 begin
91
92     process (clk)
93     begin
94         if ( clk'event and clk = '1'and we_n = '0') then
95             val <= d;
96         end if;
97     end process;
98
99     q <= val when oe_n = '0' else
100         (others => 'Z');
101 end rtl;
102
103 ----------------------------------------
104 --- normal data latch declaration
105 ----------------------------------------
106
107 library ieee;
108 use ieee.std_logic_1164.all;
109
110 entity latch is 
111     generic (
112             dsize : integer := 8
113             );
114     port (  
115             we_n    : in std_logic;
116             oe_n    : in std_logic;
117             d       : in std_logic_vector (dsize - 1 downto 0);
118             q       : out std_logic_vector (dsize - 1 downto 0)
119         );
120 end latch;
121
122 architecture rtl of latch is
123 signal val : std_logic_vector (dsize - 1 downto 0);
124 begin
125
126     process (we_n, d)
127     begin
128         if ( we_n = '0') then
129             val <= d;
130         end if;
131     end process;
132
133     q <= val when oe_n = '0' else
134         (others => 'Z');
135 end rtl;
136
137 ----------------------------------------
138 --- data bus buffer register
139 ----------------------------------------
140
141 library ieee;
142 use ieee.std_logic_1164.all;
143
144 entity dbus_buf is 
145     generic (
146             dsize : integer := 8
147             );
148     port (  
149             clk         : in std_logic;
150             r_nw        : in std_logic;
151             int_oe_n    : in std_logic;
152             int_dbus : inout std_logic_vector (dsize - 1 downto 0);
153             ext_dbus : inout std_logic_vector (dsize - 1 downto 0)
154         );
155 end dbus_buf;
156
157 architecture rtl of dbus_buf is
158 component dff
159     generic (
160             dsize : integer := 8
161             );
162     port (  
163             clk     : in std_logic;
164             we_n    : in std_logic;
165             oe_n    : in std_logic;
166             d       : in std_logic_vector (dsize - 1 downto 0);
167             q       : out std_logic_vector (dsize - 1 downto 0)
168         );
169 end component;
170
171 component latch
172     generic (
173             dsize : integer := 8
174             );
175     port (  
176             we_n    : in std_logic;
177             oe_n    : in std_logic;
178             d       : in std_logic_vector (dsize - 1 downto 0);
179             q       : out std_logic_vector (dsize - 1 downto 0)
180         );
181 end component;
182
183 signal not_r_nw : std_logic;
184
185 begin
186
187     not_r_nw <= not r_nw;
188     --read from i/o to cpu
189     dff_r : dff generic map (dsize) 
190                     port map(clk, not_r_nw, int_oe_n, ext_dbus, int_dbus);
191     --write from cpu to io
192     latch_w : latch generic map (dsize) 
193                     port map(r_nw, r_nw, int_dbus, ext_dbus);
194 end rtl;
195
196 ----------------------------------------
197 --- input data latch register
198 ----------------------------------------
199
200 library ieee;
201 use ieee.std_logic_1164.all;
202
203 entity input_dl is 
204     generic (
205             dsize : integer := 8
206             );
207     port (  
208             we_n        : in std_logic;
209             int_d_oe_n  : in std_logic;
210             int_al_oe_n : in std_logic;
211             int_ah_oe_n : in std_logic;
212             int_dbus    : inout std_logic_vector (dsize - 1 downto 0);
213             int_abus_l  : out std_logic_vector (dsize - 1 downto 0);
214             int_abus_h  : out std_logic_vector (dsize - 1 downto 0)
215         );
216 end input_dl;
217
218 architecture rtl of input_dl is
219 component latch
220     generic (
221             dsize : integer := 8
222             );
223     port (  
224             we_n    : 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 signal oe_n : std_logic;
231 signal q : std_logic_vector (dsize - 1 downto 0);
232 begin
233     oe_n <= (int_d_oe_n and int_al_oe_n and int_ah_oe_n);
234     int_dbus <= q when int_d_oe_n = '0' else
235          (others =>'Z');
236     int_abus_l <= q when int_al_oe_n = '0' else
237          (others =>'Z');
238     int_abus_h <= q when int_ah_oe_n = '0' else
239          (others =>'Z');
240     latch_inst : latch generic map (dsize) 
241                     port map(we_n, oe_n, int_dbus, q);
242 end rtl;
243
244 ----------------------------------------
245 --- stack pointer register
246 ----------------------------------------
247
248 library ieee;
249 use ieee.std_logic_1164.all;
250 use ieee.std_logic_unsigned.all;
251
252 entity sp is 
253     generic (
254             dsize : integer := 8
255             );
256     port (  
257             clk         : in std_logic;
258             we_n        : in std_logic;
259             push_n      : in std_logic;
260             pop_n       : in std_logic;
261             int_d_oe_n  : in std_logic;
262             int_a_oe_n  : in std_logic;
263             int_dbus    : inout std_logic_vector (dsize - 1 downto 0);
264             int_abus_l  : out std_logic_vector (dsize - 1 downto 0);
265             int_abus_h  : out std_logic_vector (dsize - 1 downto 0)
266         );
267 end sp;
268
269 architecture rtl of sp is
270 component dff
271     generic (
272             dsize : integer := 8
273             );
274     port (  
275             clk         : in std_logic;
276             we_n    : in std_logic;
277             oe_n    : in std_logic;
278             d       : in std_logic_vector (dsize - 1 downto 0);
279             q       : out std_logic_vector (dsize - 1 downto 0)
280         );
281 end component;
282 signal oe_n : std_logic;
283 signal dff_we_n : std_logic;
284 signal q : std_logic_vector (dsize - 1 downto 0);
285 signal d : std_logic_vector (dsize - 1 downto 0);
286 signal q_buf : std_logic_vector (dsize - 1 downto 0);
287
288 begin
289     oe_n <= (int_d_oe_n and int_a_oe_n);
290     dff_we_n <= (we_n and push_n and pop_n);
291     int_dbus <= q when int_d_oe_n = '0' else
292          (others =>'Z');
293 --    int_abus_l <= q when int_a_oe_n = '0' else
294 --         (others =>'Z');
295
296     ---push: address decrement after push is done.
297     ---pop: address increment before pop is done.
298     al_p : process (int_a_oe_n, push_n, clk, q_buf, q)
299     begin
300         if (int_a_oe_n = '0') then
301             if (push_n = '0') then
302                 if (clk = '1') then
303                     int_abus_l <= q_buf;
304                 else
305                     int_abus_l <= q;
306                 end if;
307             elsif (pop_n = '0') then
308                 if (clk = '1') then
309                     int_abus_l <= q;
310                 else
311                     int_abus_l <= q + 1;
312                 end if;
313             else
314                 int_abus_l <= q;
315             end if;
316         else
317             int_abus_l <= (others => 'Z');
318         end if;
319     end process;
320
321     int_abus_h <= "00000001" when int_a_oe_n = '0' else
322          (others =>'Z');
323     d <= int_dbus when we_n = '0' else
324             (q - 1) when push_n = '0' else
325             (q + 1) when pop_n = '0' else
326          (others =>'Z');
327
328     dff_inst : dff generic map (dsize) 
329                     port map(clk, dff_we_n, oe_n, d, q);
330     buf : dff generic map (dsize) 
331                     port map(clk, dff_we_n, '0', q, q_buf);
332 end rtl;
333
334
335 ----------------------------------------
336 --- SR flipflop
337 ----------------------------------------
338
339 library ieee;
340 use ieee.std_logic_1164.all;
341
342 entity srff is 
343     generic (
344             dsize : integer := 8
345             );
346     port (  
347             clk     : in std_logic;
348             res_n   : in std_logic;
349             set_n   : in std_logic;
350             we_n    : in std_logic;
351             oe_n    : in std_logic;
352             d       : in std_logic_vector (dsize - 1 downto 0);
353             q       : out std_logic_vector (dsize - 1 downto 0)
354         );
355 end srff;
356
357 architecture rtl of srff is
358 signal val : std_logic_vector (dsize - 1 downto 0);
359 begin
360
361     q <= val when oe_n = '0' else
362         (others => 'Z');
363
364     main_p : process (clk, res_n, set_n, d)
365     begin
366         if ( clk'event and clk = '1'and we_n = '0') then
367             val <= d;
368         end if;
369         if (res_n'event and res_n = '0') then
370             val <= (others => '0');
371         end if;
372         if (set_n = '0') then
373             val <= d;
374         end if;
375     end process;
376 end rtl;
377
378 ----------------------------------------
379 --- status register component
380 --- status register is subtype of SR FF.
381 ----------------------------------------
382
383 library ieee;
384 use ieee.std_logic_1164.all;
385
386 entity processor_status is 
387     generic (
388             dsize : integer := 8
389             );
390     port (  
391             clk         : in std_logic;
392             res_n       : in std_logic;
393             dec_we_n    : in std_logic;
394             bus_we_n    : in std_logic;
395             dec_oe_n    : in std_logic;
396             bus_oe_n    : in std_logic;
397             alu_c       : in std_logic;
398             alu_v       : in std_logic;
399             decoder     : inout std_logic_vector (dsize - 1 downto 0);
400             int_dbus    : inout std_logic_vector (dsize - 1 downto 0)
401         );
402 end processor_status;
403
404 architecture rtl of processor_status is
405 signal val : std_logic_vector (dsize - 1 downto 0);
406 begin
407     decoder <= val when dec_oe_n = '0' else
408                 (others => 'Z');
409     int_dbus <= val when bus_oe_n = '0' else
410                 (others => 'Z');
411                 
412
413     main_p : process (clk, res_n, decoder, int_dbus, bus_we_n)
414     variable tmp : std_logic_vector (dsize - 1 downto 0);
415     begin
416 --        SR Flags (bit 7 to bit 0):
417 --
418 --        N   ....    Negative
419 --        V   ....    Overflow
420 --        -   ....    ignored
421 --        B   ....    Break
422 --        D   ....    Decimal (use BCD for arithmetics)
423 --        I   ....    Interrupt (IRQ disable)
424 --        Z   ....    Zero
425 --        C   ....    Carry
426     
427       ---only interrupt flag is set on reset.
428         if (res_n'event and res_n = '0') then
429             val <= "00000100";
430         end if;
431
432         if ( clk'event and clk = '1'and dec_we_n = '0') then
433             val <= decoder;
434         end if;
435 --        if ( clk'event and clk = '1'and bus_we_n = '0') then
436 --            val <= int_dbus;
437 --        end if;
438
439         ---status flag set from the internal data bus.
440         ---interpret the input data by the decoder input.
441         if ( clk'event and clk = '1'and bus_we_n = '0') then
442             if ((decoder(0) and decoder(1) and decoder(2) and decoder(3) and 
443                     decoder(4) and decoder(5) and decoder(6) and decoder(7)) = '1' ) 
444             then
445                 ---only plp (pull status) sets the data bus data as they are.
446                 val <= int_dbus;
447             else
448                 ---other case: n/z/c/v data must be interpreted.
449                 tmp := val;
450                 val (5 downto 2) <= tmp (5 downto 2);
451
452                 --n bit.
453                 if (decoder(7) = '1') then
454                     val (7) <= int_dbus(7);
455                 else
456                     val (7) <= tmp (7);
457                 end if;
458                 --v bit.
459                 if (decoder(6) = '1') then
460                     val (6) <= alu_v;
461                 else
462                     val (6) <= tmp (6);
463                 end if;
464                 --z bit.
465                 if (decoder(1) = '1') then
466                     ---nor outputs 1 when all inputs are 0.
467                     val (1) <= not (int_dbus(7) or int_dbus(6) or 
468                             int_dbus(5) or int_dbus(4) or int_dbus(3) or 
469                             int_dbus(2) or int_dbus(1) or int_dbus(0));
470                 else
471                     val (1) <= tmp (1);
472                 end if;
473                 --c bit.
474                 if (decoder(0) = '1') then
475                     val (0) <= alu_c;
476                 else
477                     val (0) <= tmp (0);
478                 end if;
479             end if;
480         end if;
481     end process;
482 end rtl;
483
484
485 ----------------------------------------
486 --- tri-state buffer
487 ----------------------------------------
488
489 library ieee;
490 use ieee.std_logic_1164.all;
491
492 entity tsb is 
493     generic (
494             dsize : integer := 8
495             );
496     port (  
497             oe_n    : in std_logic;
498             d       : in std_logic_vector (dsize - 1 downto 0);
499             q       : out std_logic_vector (dsize - 1 downto 0)
500         );
501 end tsb;
502
503 architecture rtl of tsb is
504 signal val : std_logic_vector (dsize - 1 downto 0);
505 begin
506     q <= d when oe_n = '0' else
507         (others => 'Z');
508 end rtl;
509