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

Subversion Repositories vhdl_6530_rriot

[/] [vhdl_6530_rriot/] [trunk/] [R6530.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 noflip95
-------------------------------------------------------------------------------
2
-- File       : R6530.vhd
3
-- Author     : Thierry DAVROUX
4
-- Company    : Flipprojets
5
-- Created    : 03-01-2017
6
-------------------------------------------------------------------------------
7
-- Description: Version simplifiee d'un 6530.
8
--              Avec uniquement les ports A et B et le timer.
9
--              La RAM et la ROM ne sont pas integrees dans ce module.
10
--              La selection est simplifiee avec un seul "Chip Select".
11
--              Pas de detection de front sur PA7 (contrairement au 6532).
12
--              Bus d'adresses sur 4 bits (A3..A0).
13
-------------------------------------------------------------------------------
14
-- Copyright (c) Flipprojets François et Thierry DAVROUX - 2018
15
--               (contact@flipprojets.fr)
16
--
17
-- Concédée sous licence EUPL, version 1.2 ou – dès leur approbation par la
18
-- Commission européenne - versions ultérieures de l’EUPL (la «Licence»).
19
-- Vous ne pouvez utiliser la présente œuvre que conformément à la Licence.
20
-- Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
21
--
22
-- https://joinup.ec.europa.eu/software/page/eupl
23
--
24
-- Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
25
-- la Licence est distribué «en l’état», SANS GARANTIES OU CONDITIONS QUELLES
26
-- QU’ELLES SOIENT, expresses ou implicites. Consultez la Licence pour les
27
-- autorisations et les restrictions linguistiques spécifiques relevant de la
28
-- Licence. 
29
-------------------------------------------------------------------------------
30
-- Revisions  :
31
-- Date        Version  Author   Description
32
-- 03-01-2017  1.0      TDX      Creation
33
-- 27-03-2017  1.1      TDX      Amelioration presentation (tabulations)
34
-------------------------------------------------------------------------------
35
 
36
library  IEEE ;
37
use      IEEE.std_logic_1164.all ;
38
use      IEEE.numeric_std.all ;
39
 
40
entity  R6530 is
41
        port (
42
            phi2   : in  std_logic                     ; -- PHI2     horloge
43
            rst_n  : in  std_logic                     ; -- RST      reset negatif
44
            cs     : in  std_logic                     ; -- CS       chip select
45
            rw_n   : in  std_logic                     ; -- RW       read/write
46
            irq_n  : out std_logic                     ; -- IRQ      interruption
47
 
48
            add    : in  std_logic_vector (3 downto 0) ; -- A3..A0   Bus d'adresses
49
            din    : in  std_logic_vector (7 downto 0) ; -- DI7..DI0 Bus de donnees (entrees)
50
            dout   : out std_logic_vector (7 downto 0) ; -- DO7..DO0 Bus de donnees (sorties)
51
 
52
            pa_in  : in  std_logic_vector (7 downto 0) ; -- PORT A   entrees
53
            pa_out : out std_logic_vector (7 downto 0) ; -- PORT A   sorties
54
            pb_in  : in  std_logic_vector (7 downto 0) ; -- PORT B   entrees
55
            pb_out : out std_logic_vector (7 downto 0)   -- PORT B   sorties
56
        );
57
end entity;
58
 
59
architecture RTL of R6530 is
60
 
61
            signal s_ddra               : std_logic_vector (7 downto 0) ; -- Registre DDRA
62
            signal s_ddrb               : std_logic_vector (7 downto 0) ; -- Registre DDRB
63
            signal s_ora                : std_logic_vector (7 downto 0) ; -- Registre ORA
64
            signal s_orb                : std_logic_vector (7 downto 0) ; -- Registre ORB
65
 
66
            signal s_dout               : std_logic_vector (7 downto 0) ; -- Sortie du bus de donnees
67
 
68
            signal s_irq_timer          : std_logic                     ; -- Etat de l'interruption par le timer
69
            signal s_irq_timer_en       : std_logic                     ; -- Autorisation interruption par le timer
70
            signal s_divider            : unsigned (9 downto 0)         ; -- Prediviseur             (valeur maxi)
71
            signal s_count              : unsigned (9 downto 0)         ; -- Compteur du prediviseur (compteur)
72
            signal s_timer              : unsigned (7 downto 0)         ; -- Decompteur du timer     (valeur en cours)
73
 
74
begin
75
 
76
    ------------------------------------------------------------------------
77
    -- Fonctionnement principal dependant de PHI2
78
    ------------------------------------------------------------------------
79
 
80
    process(phi2)
81
    begin
82
 
83
        if (rising_edge(phi2)) then
84
 
85
            ------------------------------------------------------------------------
86
            -- Tout le circuit fonctionne sur front montant du PHI2
87
            -- y compris la prise en compte du RESET
88
            ------------------------------------------------------------------------
89
 
90
            if (rst_n = '0') then
91
 
92
                ------------------------------------------------------------------------
93
                -- RESET, init de la sortie de donnees et des ports A/B
94
                ------------------------------------------------------------------------
95
                s_dout          <= (others => '1')         ; -- Sortie FF
96
                s_ddra          <= (others => '0')         ; -- DDRA a zero
97
                s_ddrb          <= (others => '0')         ; -- DDRB a zero
98
                s_ora           <= (others => '0')         ; --  ORA a zero
99
                s_orb           <= (others => '0')         ; --  ORB a zero
100
 
101
                ------------------------------------------------------------------------
102
                -- RESET, init du timer/diviseur et du flag d'interruption
103
                ------------------------------------------------------------------------
104
                s_timer         <= (others => '0')         ; -- Remise a zero du decompteur du timer
105
                s_divider       <= "0000000000"            ; -- Remise a zero du prediviseur (mode 1T)
106
                s_count         <= (others => '0')         ; -- Remise a zero du compteur du prediviseur
107
                s_irq_timer     <= '0'                     ; -- Remise a zero de l'interruption
108
                s_irq_timer_en  <= '0'                     ; -- Interruption non autorisee
109
 
110
            else
111
 
112
                ------------------------------------------------------------------------
113
                -- Traitement du timer, sur front montant du PHI2
114
                ------------------------------------------------------------------------
115
 
116
                if (s_count = s_divider) then
117
                    s_timer    <= s_timer - 1              ; -- On decremente le timer
118
                    s_count    <= (others => '0')          ; -- et on reinitialise le compteur du prediviseur
119
                    if (s_timer = "00000000") then           -- Si le timer est arrive a zero
120
                        s_divider   <= "0000000000"        ; --    on remet le diviseur a 1T
121
                        s_irq_timer <= '1'                 ; --    et on leve le flag d'interruption
122
                    end if ;
123
                else
124
                    s_count <= s_count + 1                 ; -- On incremente le compteur du prediviseur
125
                end if ;
126
 
127
                ------------------------------------------------------------------------
128
                -- Acces aux registres, sur front montant du PHI2
129
                ------------------------------------------------------------------------
130
 
131
                if (cs = '1') then
132
                    -------------------------------------------------------------------------------
133
                    -- A condition que le CHIP SELECT soit actif, l'adressage est le suivant :   --
134
                    -- RW   x000 - Read/Write    ORA                                             --  
135
                    -- RW   x001 - Read/Write   DDRA                                             --
136
                    -- RW   x010 - Read/Write    ORB                                             --
137
                    -- RW   x011 - Read/Write   DDRB                                             --
138
                    --  W   .100 - Write Timer    1T                                             --
139
                    --  W   .101 - Write Timer    8T                                             --
140
                    --  W   .110 - Write Timer   64T                                             --
141
                    --  W   .111 - Write Timer 1024T                                             --
142
                    -- R    x1x0 - Read Timer                                                    --
143
                    -- R    x1x1 - Read Status (interrupt flag)                                  --
144
                    -------------------------------------------------------------------------------
145
 
146
                    if (rw_n = '0') then
147
                        --------------
148
                        -- Ecriture --
149
                        --------------                  
150
 
151
                        if (add(2) = '0') then
152
                            ---------------------------------------------
153
                            -- Acces aux registres I/O    quand A2 = 0 --
154
                            ---------------------------------------------
155
 
156
                            case add(1 downto 0) is
157
                                when "00" =>
158
                                    ------------------------------
159
                                    -- 000 : Ecriture dans ORA  --
160
                                    ------------------------------
161
                                    s_ora <= din ;
162
                                when "01" =>
163
                                    ------------------------------
164
                                    -- 001 : Ecriture dans DDRA --
165
                                    ------------------------------
166
                                    s_ddra <= din ;
167
                                when "10" =>
168
                                    ------------------------------
169
                                    -- 010 : Ecriture dans ORB  --
170
                                    ------------------------------
171
                                    s_orb <= din ;
172
                                when "11" =>
173
                                    ------------------------------
174
                                    -- 011 : Ecriture dans DDRB --
175
                                    ------------------------------
176
                                    s_ddrb <= din ;
177
                                when others =>
178
                                    null ;
179
                            end case ;
180
 
181
                        else
182
                            -------------------------------------------------
183
                            -- Acces aux registres Timer      quand A2 = 1 --
184
                            -------------------------------------------------
185
 
186
                            ---------------------------------------------
187
                            -- A3 active ou non les interruptions      --
188
                            ---------------------------------------------
189
 
190
                            s_irq_timer_en <= add(3)     ; -- Autorisation des interruptions selon le bit A3
191
                            s_irq_timer    <= '0'        ; -- Efface le flag d'interruption
192
                            s_timer <= unsigned(din) - 1 ; -- Valeur initiale du timer
193
                            s_count <= (others => '0')   ; -- Mise a zero du compteur du prediviseur
194
 
195
                            case add(1 downto 0) is
196
                                when "00" =>
197
                                    --------------------------
198
                                    -- 100 : diviseur    1T --
199
                                    --------------------------
200
                                    s_divider <= "0000000000" ; -- Valeur maxi du compteur = 0
201
                                when "01" =>
202
                                    --------------------------
203
                                    -- 101 : diviseur    8T --
204
                                    --------------------------
205
                                    s_divider <= "0000000111" ; -- Valeur maxi du compteur = 7
206
                                when "10" =>
207
                                    --------------------------
208
                                    -- 110 : diviseur   64T --
209
                                    --------------------------
210
                                    s_divider <= "0000111111" ; -- Valeur maxi du compteur = 63
211
                                when "11" =>
212
                                    --------------------------
213
                                    -- 111 : diviseur 1024T --
214
                                    --------------------------
215
                                    s_divider <= "1111111111" ; -- Valeur maxi du compteur = 1023
216
                                when others =>
217
                                    null ;
218
                            end case ;
219
 
220
                        end if ; -- Fin des ecritures --
221
 
222
                    else
223
                        -------------
224
                        -- Lecture --
225
                        -------------
226
 
227
                        if (add(2) = '0') then
228
                            ---------------------------------------------
229
                            -- Acces aux registres I/O    quand A2 = 0 --
230
                            ---------------------------------------------
231
 
232
                            case add(1 downto 0) is
233
                                when "00" =>
234
                                    ---------------------------
235
                                    -- 000 : Lecture de ORA  --
236
                                    ---------------------------
237
                                    s_dout <= ((s_ddra and s_ora) or (pa_in and not(s_ddra))) ; -- Lecture du port en entree ou des latches de sortie
238
                                when "01" =>
239
                                    ---------------------------
240
                                    -- 001 : Lecture de DDRA --
241
                                    ---------------------------
242
                                    s_dout <= s_ddra ;
243
                                when "10" =>
244
                                    ---------------------------
245
                                    -- 010 : Lecture de ORB  --
246
                                    ---------------------------
247
                                    s_dout <= ((s_ddrb and s_orb) or (pb_in and not(s_ddrb))) ; -- Lecture du port en entree ou des latches de sortie
248
                                when "11" =>
249
                                    ---------------------------
250
                                    -- 011 : Lecture de DDRB --
251
                                    ---------------------------
252
                                    s_dout <= s_ddrb ;
253
                                when others =>
254
                                    null ;
255
 
256
                            end case ;
257
 
258
                        else
259
                            ---------------------------------------------
260
                            -- Acces au timer et status quand A2 = 1   --
261
                            ---------------------------------------------
262
 
263
                            if (add(0) = '0') then
264
                                ----------------------------------------
265
                                -- 1x0 : Lecture du TIMER             --
266
                                -- A3 active ou non les interruptions --
267
                                ----------------------------------------
268
                                s_irq_timer_en <= add(3)            ; -- Autorisation des interruptions selon le bit A3
269
 
270
                                s_dout <= std_logic_vector(s_timer) ; -- Valeur courante du timer
271
                                if not (s_timer = "00000000") then
272
                                    s_irq_timer <= '0'              ; -- Efface le flag d'interruption du timer, sauf si interruption en cours
273
                                end if ;
274
                            else
275
                                -----------------------------
276
                                -- 1x1 : Lecture du STATUS --
277
                                -----------------------------
278
                                s_dout <= s_irq_timer & "0000000"   ; -- Registre de status (flag d'interruption)
279
                            end if ;
280
 
281
                        end if ;
282
 
283
                    end if ; -- Fin des lectures --
284
 
285
                end if ; -- Fin des acces dependant du chip select --
286
 
287
            end if ; -- Fin des traitements hors RESET
288
 
289
            ------------------------------------------------------------------------
290
            -- Signal d'interruption en sortie, si interruption generee et autorisee
291
            ------------------------------------------------------------------------
292
 
293
            irq_n <= not (s_irq_timer and s_irq_timer_en) ;
294
 
295
        end if ; -- Fin du traitement sur front montant de PHI2
296
 
297
        ------------------------------------------------------------------------
298
        -- Sorties sur les ports A et B, sur front descendant du PHI2
299
        ------------------------------------------------------------------------
300
 
301
        if (falling_edge(phi2)) then
302
            pa_out <= ((s_ora and s_ddra) or (pa_in and not(s_ddra))) ; -- Sortie sur PORT A, uniquement pour les bits en sorties (a "1" dans DDRA) + copie des entrees
303
            pb_out <= ((s_orb and s_ddrb) or (pb_in and not(s_ddrb))) ; -- Sortie sur PORT B, uniquement pour les bits en sorties (a "1" dans DDRB) + copie des entrees
304
        end if ;
305
 
306
    end process ;
307
 
308
    ------------------------------------------------------------------------
309
    -- Sortie sur le bus de donnees
310
    ------------------------------------------------------------------------
311
 
312
    dout <= s_dout when ((cs = '1') and (rw_n = '1')) else (others => '1') ; -- Si lecture et chip select, sinon FF
313
 
314
end architecture;
315
 

powered by: WebSVN 2.1.0

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