OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [pia6821.vhd] - Blame information for rev 74

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 dilbert57
--===========================================================================--
2
--
3
--  S Y N T H E Z I A B L E    I/O Port   C O R E
4
--
5
--  www.OpenCores.Org - May 2004
6
--  This core adheres to the GNU public license  
7
--
8
-- File name      : pia6821.vhd
9
--
10
-- Purpose        : Implements 2 x 8 bit parallel I/O ports
11
--                  with programmable data direction registers
12
--                  
13
-- Dependencies   : ieee.Std_Logic_1164
14
--                  ieee.std_logic_unsigned
15
--
16
-- Author         : John E. Kent      
17
--
18
--===========================================================================----
19
--
20
-- Revision History:
21
--
22
-- Date:          Revision         Author
23
-- 1 May 2004     0.0              John Kent
24
-- Initial version developed from ioport.vhd
25
--
26
--===========================================================================----
27
--
28
-- Memory Map
29
--
30
-- IO + $00 - Port A Data & Direction register
31
-- IO + $01 - Port A Control register
32
-- IO + $02 - Port B Data & Direction Direction Register
33
-- IO + $03 - Port B Control Register
34
--
35
 
36
library ieee;
37
use ieee.std_logic_1164.all;
38
use ieee.std_logic_unsigned.all;
39
 
40
entity pia6821 is
41
        port (
42
         clk       : in    std_logic;
43
    rst       : in    std_logic;
44
    cs        : in    std_logic;
45
    rw        : in    std_logic;
46
    addr      : in    std_logic_vector(1 downto 0);
47
    data_in   : in    std_logic_vector(7 downto 0);
48
         data_out  : out   std_logic_vector(7 downto 0);
49
         irqa      : out   std_logic;
50
         irqb      : out   std_logic;
51
         pa        : inout std_logic_vector(7 downto 0);
52
         ca1       : in    std_logic;
53
         ca2       : inout std_logic;
54
         pb        : inout std_logic_vector(7 downto 0);
55
         cb1       : in    std_logic;
56
         cb2       : inout std_logic
57
         );
58
end;
59
 
60
architecture pia_arch of pia6821 is
61
 
62
signal porta_ddr   : std_logic_vector(7 downto 0);
63
signal porta_data  : std_logic_vector(7 downto 0);
64
signal porta_ctrl  : std_logic_vector(5 downto 0);
65
signal porta_read  : std_logic;
66
 
67
signal portb_ddr   : std_logic_vector(7 downto 0);
68
signal portb_data  : std_logic_vector(7 downto 0);
69
signal portb_ctrl  : std_logic_vector(5 downto 0);
70
signal portb_read  : std_logic;
71
signal portb_write : std_logic;
72
 
73
signal ca1_del     : std_logic;
74
signal ca1_rise    : std_logic;
75
signal ca1_fall    : std_logic;
76
signal ca1_edge    : std_logic;
77
signal irqa1       : std_logic;
78
 
79
signal ca2_del     : std_logic;
80
signal ca2_rise    : std_logic;
81
signal ca2_fall    : std_logic;
82
signal ca2_edge    : std_logic;
83
signal irqa2       : std_logic;
84
signal ca2_out     : std_logic;
85
 
86
signal cb1_del     : std_logic;
87
signal cb1_rise    : std_logic;
88
signal cb1_fall    : std_logic;
89
signal cb1_edge    : std_logic;
90
signal irqb1       : std_logic;
91
 
92
signal cb2_del     : std_logic;
93
signal cb2_rise    : std_logic;
94
signal cb2_fall    : std_logic;
95
signal cb2_edge    : std_logic;
96
signal irqb2       : std_logic;
97
signal cb2_out     : std_logic;
98
 
99
begin
100
 
101
--------------------------------
102
--
103
-- read I/O port
104
--
105
--------------------------------
106
 
107
pia_read : process(  addr,      cs,
108
                     irqa1, irqa2, irqb1, irqb2,
109
                     porta_ddr,  portb_ddr,
110
                                                        porta_data, portb_data,
111
                                                        porta_ctrl, portb_ctrl,
112
                                                   pa,         pb )
113
variable count : integer;
114
begin
115
      case addr is
116
             when "00" =>
117
                    for count in 0 to 7 loop
118
                           if porta_ctrl(2) = '0' then
119
                                  data_out(count) <= porta_ddr(count);
120
                             porta_read <= '0';
121
            else
122
                                  if porta_ddr(count) = '1' then
123
                data_out(count) <= porta_data(count);
124
              else
125
                data_out(count) <= pa(count);
126
              end if;
127
                             porta_read <= cs;
128
            end if;
129
                         end loop;
130
                         portb_read <= '0';
131
 
132
             when "01" =>
133
                    data_out <= irqa1 & irqa2 & porta_ctrl;
134
                         porta_read <= '0';
135
                         portb_read <= '0';
136
 
137
                  when "10" =>
138
                    for count in 0 to 7 loop
139
                           if portb_ctrl(2) = '0' then
140
                                  data_out(count) <= portb_ddr(count);
141
                                  portb_read <= '0';
142
            else
143
                                  if portb_ddr(count) = '1' then
144
                data_out(count) <= portb_data(count);
145
              else
146
                data_out(count) <= pb(count);
147
                                  end if;
148
                                  portb_read <= cs;
149
            end if;
150
                         end loop;
151
                         porta_read <= '0';
152
 
153
                  when "11" =>
154
                    data_out <= irqb1 & irqb2 & portb_ctrl;
155
                         porta_read <= '0';
156
                         portb_read <= '0';
157
 
158
                  when others =>
159
                    data_out <= "00000000";
160
                         porta_read <= '0';
161
                         portb_read <= '0';
162
 
163
                end case;
164
end process;
165
 
166
---------------------------------
167
--
168
-- Write I/O ports
169
--
170
---------------------------------
171
 
172
pia_write : process( clk, rst, addr, cs, rw, data_in,
173
                        porta_ctrl, portb_ctrl,
174
                        porta_data, portb_data,
175
                                                                porta_ctrl, portb_ctrl,
176
                                                                porta_ddr, portb_ddr )
177
begin
178
  if rst = '1' then
179
      porta_ddr   <= "00000000";
180
      porta_data  <= "00000000";
181
      porta_ctrl  <= "000000";
182
      portb_ddr   <= "00000000";
183
      portb_data  <= "00000000";
184
                portb_ctrl  <= "000000";
185
                portb_write <= '0';
186
  elsif clk'event and clk = '1' then
187
    if cs = '1' and rw = '0' then
188
      case addr is
189
             when "00" =>
190
                    if porta_ctrl(2) = '0' then
191
                       porta_ddr  <= data_in;
192
                       porta_data <= porta_data;
193
                         else
194
                       porta_ddr  <= porta_ddr;
195
                       porta_data <= data_in;
196
                         end if;
197
                         porta_ctrl  <= porta_ctrl;
198
                    portb_ddr   <= portb_ddr;
199
                    portb_data  <= portb_data;
200
                         portb_ctrl  <= portb_ctrl;
201
                         portb_write <= '0';
202
                  when "01" =>
203
                    porta_ddr   <= porta_ddr;
204
                    porta_data  <= porta_data;
205
                         porta_ctrl  <= data_in(5 downto 0);
206
                    portb_ddr   <= portb_ddr;
207
                    portb_data  <= portb_data;
208
                         portb_ctrl  <= portb_ctrl;
209
                         portb_write <= '0';
210
             when "10" =>
211
                    porta_ddr   <= porta_ddr;
212
                    porta_data  <= porta_data;
213
                         porta_ctrl  <= porta_ctrl;
214
                    if portb_ctrl(2) = '0' then
215
                       portb_ddr   <= data_in;
216
                       portb_data  <= portb_data;
217
                            portb_write <= '0';
218
                         else
219
                       portb_ddr   <= portb_ddr;
220
                       portb_data  <= data_in;
221
                            portb_write <= '1';
222
                         end if;
223
                         portb_ctrl  <= portb_ctrl;
224
                  when "11" =>
225
                    porta_ddr   <= porta_ddr;
226
                    porta_data  <= porta_data;
227
                         porta_ctrl  <= porta_ctrl;
228
                    portb_ddr   <= portb_ddr;
229
                    portb_data  <= portb_data;
230
                         portb_ctrl  <= data_in(5 downto 0);
231
                         portb_write <= '0';
232
                  when others =>
233
                    porta_ddr   <= porta_ddr;
234
                    porta_data  <= porta_data;
235
                         porta_ctrl  <= porta_ctrl;
236
                    portb_ddr   <= portb_ddr;
237
                    portb_data  <= portb_data;
238
                         portb_ctrl  <= portb_ctrl;
239
                         portb_write <= '0';
240
                end case;
241
         else
242
                    porta_ddr   <= porta_ddr;
243
                    porta_data  <= porta_data;
244
                         porta_ctrl  <= porta_ctrl;
245
                    portb_data  <= portb_data;
246
                    portb_ddr   <= portb_ddr;
247
                         portb_ctrl  <= portb_ctrl;
248
                         portb_write <= '0';
249
         end if;
250
  end if;
251
end process;
252
 
253
---------------------------------
254
--
255
-- direction control port a
256
--
257
---------------------------------
258
porta_direction : process ( porta_data, porta_ddr )
259
variable count : integer;
260
begin
261
  for count in 0 to 7 loop
262
    if porta_ddr(count) = '1' then
263
      pa(count) <= porta_data(count);
264
    else
265
      pa(count) <= 'Z';
266
    end if;
267
  end loop;
268
end process;
269
 
270
---------------------------------
271
--
272
-- CA1 Edge detect
273
--
274
---------------------------------
275
ca1_input : process( clk, rst, ca1, ca1_del,
276
                     ca1_rise, ca1_fall, ca1_edge,
277
                                                        irqa1, porta_ctrl, porta_read )
278
begin
279
  if rst = '1' then
280
    ca1_del  <= '0';
281
         ca1_rise <= '0';
282
    ca1_fall <= '0';
283
         ca1_edge <= '0';
284
         irqa1    <= '0';
285
  elsif clk'event and clk = '0' then
286
    ca1_del  <= ca1;
287
    ca1_rise <= (not ca1_del) and ca1;
288
    ca1_fall <= ca1_del and (not ca1);
289
         if ca1_edge = '1' then
290
            irqa1 <= '1';
291
         elsif porta_read = '1' then
292
            irqa1 <= '0';
293
    else
294
            irqa1 <= irqa1;
295
    end if;
296
  end if;
297
 
298
  if porta_ctrl(1) = '0' then
299
         ca1_edge <= ca1_fall;
300
  else
301
         ca1_edge <= ca1_rise;
302
  end if;
303
end process;
304
 
305
---------------------------------
306
--
307
-- CA2 Edge detect
308
--
309
---------------------------------
310
ca2_input : process( clk, rst, ca2, ca2_del,
311
                     ca2_rise, ca2_fall, ca2_edge,
312
                                                        irqa2, porta_ctrl, porta_read )
313
begin
314
  if rst = '1' then
315
    ca2_del  <= '0';
316
         ca2_rise <= '0';
317
    ca2_fall <= '0';
318
         ca2_edge <= '0';
319
         irqa2    <= '0';
320
  elsif clk'event and clk = '0' then
321
    ca2_del  <= ca2;
322
    ca2_rise <= (not ca2_del) and ca2;
323
    ca2_fall <= ca2_del and (not ca2);
324
         if porta_ctrl(5) = '0' and ca2_edge = '1' then
325
            irqa2 <= '1';
326
         elsif porta_read = '1' then
327
            irqa2 <= '0';
328
    else
329
            irqa2 <= irqa2;
330
    end if;
331
  end if;
332
 
333
  if porta_ctrl(4) = '0' then
334
         ca2_edge <= ca2_fall;
335
  else
336
         ca2_edge <= ca2_rise;
337
  end if;
338
end process;
339
 
340
---------------------------------
341
--
342
-- CA2 output control
343
--
344
---------------------------------
345
ca2_output : process( clk, rst, porta_ctrl, porta_read, ca1_edge, ca2_out )
346
begin
347
  if rst='1' then
348
    ca2_out <= '0';
349
  elsif clk'event and clk='0' then
350
    case porta_ctrl(5 downto 3) is
351
    when "100" => -- read PA clears, CA1 edge sets
352
      if porta_read = '1' then
353
             ca2_out <= '0';
354
      elsif ca1_edge = '1' then
355
             ca2_out <= '1';
356
      else
357
             ca2_out <= ca2_out;
358
      end if;
359
    when "101" => -- read PA clears, E sets
360
      ca2_out <= not porta_read;
361
    when "110" =>       -- set low
362
           ca2_out <= '0';
363
    when "111" =>       -- set high
364
           ca2_out <= '1';
365
    when others => -- no change
366
           ca2_out <= ca2_out;
367
    end case;
368
  end if;
369
end process;
370
 
371
---------------------------------
372
--
373
-- CA2 direction control
374
--
375
---------------------------------
376
ca2_direction : process( porta_ctrl, ca2, ca2_out )
377
begin
378
  if porta_ctrl(5) = '0' then
379
    ca2 <= 'Z';
380
  else
381
    ca2 <= ca2_out;
382
  end if;
383
end process;
384
 
385
---------------------------------
386
--
387
-- direction control port b
388
--
389
---------------------------------
390
portb_direction : process ( portb_data, portb_ddr )
391
variable count : integer;
392
begin
393
  for count in 0 to 7 loop
394
    if portb_ddr(count) = '1' then
395
      pb(count) <= portb_data(count);
396
    else
397
      pb(count) <= 'Z';
398
    end if;
399
  end loop;
400
end process;
401
 
402
---------------------------------
403
--
404
-- CB1 Edge detect
405
--
406
---------------------------------
407
cb1_input : process( clk, rst, cb1, cb1_del,
408
                     cb1_rise, cb1_fall, cb1_edge,
409
                                                        irqb1, portb_ctrl, portb_read )
410
begin
411
  if rst = '1' then
412
    cb1_del  <= '0';
413
         cb1_rise <= '0';
414
    cb1_fall <= '0';
415
         cb1_edge <= '0';
416
         irqb1    <= '0';
417
  elsif clk'event and clk = '0' then
418
    cb1_del  <= cb1;
419
    cb1_rise <= (not cb1_del) and cb1;
420
    cb1_fall <= cb1_del and (not cb1);
421
         if cb1_edge = '1' then
422
            irqb1 <= '1';
423
         elsif portb_read = '1' then
424
            irqb1 <= '0';
425
    else
426
            irqb1 <= irqb1;
427
    end if;
428
  end if;
429
 
430
  if portb_ctrl(1) = '0' then
431
         cb1_edge <= cb1_fall;
432
  else
433
         cb1_edge <= cb1_rise;
434
  end if;
435
end process;
436
 
437
---------------------------------
438
--
439
-- CB2 Edge detect
440
--
441
---------------------------------
442
cb2_input : process( clk, rst, cb2, cb2_del,
443
                     cb2_rise, cb2_fall, cb2_edge,
444
                                                        irqb2, portb_ctrl, portb_read )
445
begin
446
  if rst = '1' then
447
    cb2_del  <= '0';
448
         cb2_rise <= '0';
449
    cb2_fall <= '0';
450
         cb2_edge <= '0';
451
         irqb2    <= '0';
452
  elsif clk'event and clk = '0' then
453
    cb2_del  <= cb2;
454
    cb2_rise <= (not cb2_del) and cb2;
455
    cb2_fall <= cb2_del and (not cb2);
456
         if portb_ctrl(5) = '0' and cb2_edge = '1' then
457
            irqb2 <= '1';
458
         elsif portb_read = '1' then
459
            irqb2 <= '0';
460
    else
461
            irqb2 <= irqb2;
462
    end if;
463
  end if;
464
 
465
  if portb_ctrl(4) = '0' then
466
         cb2_edge <= cb2_fall;
467
  else
468
         cb2_edge <= cb2_rise;
469
  end if;
470
 
471
end process;
472
 
473
---------------------------------
474
--
475
-- CB2 output control
476
--
477
---------------------------------
478
cb2_output : process( clk, rst, portb_ctrl, portb_write, cb1_edge, cb2_out )
479
begin
480
  if rst='1' then
481
    cb2_out <= '0';
482
  elsif clk'event and clk='0' then
483
    case portb_ctrl(5 downto 3) is
484
    when "100" => -- write PB clears, CA1 edge sets
485
      if portb_write = '1' then
486
             cb2_out <= '0';
487
      elsif cb1_edge = '1' then
488
             cb2_out <= '1';
489
      else
490
             cb2_out <= cb2_out;
491
      end if;
492
    when "101" => -- write PB clears, E sets
493
      cb2_out <= not portb_write;
494
    when "110" =>       -- set low
495
           cb2_out <= '0';
496
    when "111" =>       -- set high
497
           cb2_out <= '1';
498
    when others => -- no change
499
           cb2_out <= cb2_out;
500
    end case;
501
  end if;
502
end process;
503
 
504
---------------------------------
505
--
506
-- CB2 direction control
507
--
508
---------------------------------
509
cb2_direction : process( portb_ctrl, cb2, cb2_out )
510
begin
511
  if portb_ctrl(5) = '0' then
512
    cb2 <= 'Z';
513
  else
514
    cb2 <= cb2_out;
515
  end if;
516
end process;
517
 
518
---------------------------------
519
--
520
-- IRQ control
521
--
522
---------------------------------
523
pia_irq : process( irqa1, irqa2, irqb1, irqb2, porta_ctrl, portb_ctrl )
524
begin
525
  irqa <= (irqa1 and porta_ctrl(0)) or (irqa2 and porta_ctrl(3));
526
  irqb <= (irqb1 and portb_ctrl(0)) or (irqb2 and portb_ctrl(3));
527
end process;
528
 
529
end pia_arch;
530
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.