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

Subversion Repositories vhdl_6532_riot

[/] [vhdl_6532_riot/] [trunk/] [R6532.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 noflip95
-------------------------------------------------------------------------------
2
-- File       : R6532.vhd
3
-- Author     : Thierry DAVROUX
4
-- Company    : Flipprojets
5
-- Created    : 12-01-2017
6
-------------------------------------------------------------------------------
7
-- Description: Version simplifiee d'un 6532.
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
--              Detection de front sur PA7.
12
--              Bus d'adresses sur 5 bits (A4..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
-- 12-01-2017  1.0      TDX      Creation
33
-- 27-03-2017  1.1      TDX      Correction bug detection front PA7
34
-------------------------------------------------------------------------------
35
 
36
library  IEEE ;
37
use      IEEE.std_logic_1164.all ;
38
use      IEEE.numeric_std.all ;
39
 
40
entity  R6532 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 (4 downto 0) ; -- A4..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 R6532 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
            signal s_irq_pa7            : std_logic                     ; -- Etat de l'interruption par PA7
75
            signal s_irq_pa7_en         : std_logic                     ; -- Autorisation interruption par PA7
76
            signal s_edge               : std_logic                     ; -- Detection front sur PA7 (0 negatif, 1 positif)
77
            signal s_PA7                : std_logic                     ; -- Etat du PA7 memorise, pour detection front           
78
 
79
begin
80
 
81
    ------------------------------------------------------------------------
82
    -- Fonctionnement principal dependant de PHI2
83
    ------------------------------------------------------------------------
84
 
85
    process(phi2)
86
    begin
87
 
88
        if (rising_edge(phi2)) then
89
 
90
            ------------------------------------------------------------------------
91
            -- Tout le circuit fonctionne sur front montant du PHI2
92
            -- y compris la prise en compte du RESET
93
            ------------------------------------------------------------------------
94
 
95
            if (rst_n = '0') then
96
 
97
                ------------------------------------------------------------------------
98
                -- RESET, init de la sortie de donnees et des ports A/B
99
                ------------------------------------------------------------------------
100
                s_dout          <= (others => '1')         ; -- Sortie FF
101
                s_ddra          <= (others => '0')         ; -- DDRA a zero
102
                s_ddrb          <= (others => '0')         ; -- DDRB a zero
103
                s_ora           <= (others => '0')         ; --  ORA a zero
104
                s_orb           <= (others => '0')         ; --  ORB a zero
105
 
106
                ------------------------------------------------------------------------
107
                -- RESET, init du timer/diviseur et du flag d'interruption
108
                ------------------------------------------------------------------------
109
                s_timer         <= (others => '0')         ; -- Remise a zero du decompteur du timer
110
                s_divider       <= "0000000000"            ; -- Remise a zero du prediviseur (mode 1T)
111
                s_count         <= (others => '0')         ; -- Remise a zero du compteur du prediviseur
112
                s_irq_timer     <= '0'                     ; -- Remise a zero de l'interruption
113
                s_irq_timer_en  <= '0'                     ; -- Interruption non autorisee
114
 
115
                ------------------------------------------------------------------------
116
                -- RESET, init du pa7 et du flag d'interruption
117
                ------------------------------------------------------------------------
118
                s_irq_pa7       <= '0'                     ; -- Remise a zero de l'interruption
119
                s_irq_pa7_en    <= '0'                     ; -- Interruption non autorisee
120
                s_edge          <= '0'                     ; -- Detection sur front negatif par defaut
121
 
122
            else
123
 
124
                ------------------------------------------------------------------------
125
                -- Traitement du timer, sur front montant du PHI2
126
                ------------------------------------------------------------------------
127
 
128
                if (s_count = s_divider) then
129
                    s_timer    <= s_timer - 1              ; -- On decremente le timer
130
                    s_count    <= (others => '0')          ; -- et on reinitialise le compteur du prediviseur
131
                    if (s_timer = "00000000") then           -- Si le timer est arrive a zero
132
                        s_divider   <= "0000000000"        ; --    on remet le diviseur a 1T
133
                        s_irq_timer <= '1'                 ; --    et on leve le flag d'interruption
134
                    end if ;
135
                else
136
                    s_count <= s_count + 1                 ; -- On incremente le compteur du prediviseur
137
                end if ;
138
 
139
                ------------------------------------------------------------------------
140
                -- Traitement du PA7, sur front montant du PHI2
141
                ------------------------------------------------------------------------
142
 
143
                if (not(pa_in(7) = s_PA7)) then              -- Changement d'etat par rapport au dernier etat memorise
144
                    if (pa_in(7) = s_edge) then              -- Detection du front positif ou negatif selon programmation
145
                        s_irq_pa7 <= '1'                   ; -- Si oui, on leve le flag d'interruption pour PA7                        
146
                    end if ;
147
                end if ;
148
                s_PA7 <= pa_in(7)                          ; -- Memorisation de l'etat actuel du PA7
149
 
150
                ------------------------------------------------------------------------
151
                -- Acces aux registres, sur front montant du PHI2
152
                ------------------------------------------------------------------------
153
 
154
                if (cs = '1') then
155
                    -------------------------------------------------------------------------------
156
                    -- A condition que le CHIP SELECT soit actif, l'adressage est le suivant :   --
157
                    -- RW  xx000 - Read/Write    ORA                                             --  
158
                    -- RW  xx001 - Read/Write   DDRA                                             --
159
                    -- RW  xx010 - Read/Write    ORB                                             --
160
                    -- RW  xx011 - Read/Write   DDRB                                             --
161
                    --  W  1.100 - Write Timer    1T                                             --
162
                    --  W  1.101 - Write Timer    8T                                             --
163
                    --  W  1.110 - Write Timer   64T                                             --
164
                    --  W  1.111 - Write Timer 1024T                                             --
165
                    --  W  0x1.. - Write Edge Detect Control                                     --
166
                    -- R   xx1x0 - Read Timer                                                    --
167
                    -- R   xx1x1 - Read Status (interrupt flag)                                  --
168
                    -------------------------------------------------------------------------------
169
 
170
                    if (rw_n = '0') then
171
                        --------------
172
                        -- Ecriture --
173
                        --------------                  
174
 
175
                        if (add(2) = '0') then
176
                            ---------------------------------------------
177
                            -- Acces aux registres I/O    quand A2 = 0 --
178
                            ---------------------------------------------
179
 
180
                            case add(1 downto 0) is
181
                                when "00" =>
182
                                    ------------------------------
183
                                    -- 000 : Ecriture dans ORA  --
184
                                    ------------------------------
185
                                    s_ora <= din ;
186
                                when "01" =>
187
                                    ------------------------------
188
                                    -- 001 : Ecriture dans DDRA --
189
                                    ------------------------------
190
                                    s_ddra <= din ;
191
                                when "10" =>
192
                                    ------------------------------
193
                                    -- 010 : Ecriture dans ORB  --
194
                                    ------------------------------
195
                                    s_orb <= din ;
196
                                when "11" =>
197
                                    ------------------------------
198
                                    -- 011 : Ecriture dans DDRB --
199
                                    ------------------------------
200
                                    s_ddrb <= din ;
201
                                when others =>
202
                                    null ;
203
                            end case ;
204
 
205
                        else
206
                            -------------------------------------------------
207
                            -- Acces aux registres Timer/Edge quand A2 = 1 --
208
                            -------------------------------------------------
209
 
210
                            if (add(4) = '1') then
211
                                ---------------------------------------------
212
                                -- Acces au timer/prediviseur quand A4 = 1 --
213
                                ---------------------------------------------
214
 
215
                                ---------------------------------------------
216
                                -- A3 active ou non les interruptions      --
217
                                ---------------------------------------------
218
 
219
                                s_irq_timer_en <= add(3)     ; -- Autorisation des interruptions selon le bit A3
220
                                s_irq_timer    <= '0'        ; -- Efface le flag d'interruption
221
                                s_timer <= unsigned(din) - 1 ; -- Valeur initiale du timer
222
                                s_count <= (others => '0')   ; -- Mise a zero du compteur du prediviseur
223
 
224
                                case add(1 downto 0) is
225
                                    when "00" =>
226
                                        --------------------------
227
                                        -- 100 : diviseur    1T --
228
                                        --------------------------
229
                                        s_divider <= "0000000000" ; -- Valeur maxi du compteur = 0
230
                                    when "01" =>
231
                                        --------------------------
232
                                        -- 101 : diviseur    8T --
233
                                        --------------------------
234
                                        s_divider <= "0000000111" ; -- Valeur maxi du compteur = 7
235
                                    when "10" =>
236
                                        --------------------------
237
                                        -- 110 : diviseur   64T --
238
                                        --------------------------
239
                                        s_divider <= "0000111111" ; -- Valeur maxi du compteur = 63
240
                                    when "11" =>
241
                                        --------------------------
242
                                        -- 111 : diviseur 1024T --
243
                                        --------------------------
244
                                        s_divider <= "1111111111" ; -- Valeur maxi du compteur = 1023
245
                                    when others =>
246
                                        null ;
247
                                end case ;
248
 
249
                            else
250
                                ---------------------------------------------
251
                                -- Acces au Edge              quand A4 = 0 --
252
                                ---------------------------------------------
253
 
254
                                ---------------------------------------------------------
255
                                -- A1 active ou non les interruptions                  --
256
                                -- A0 indique le sens de la transition                 --
257
                                ---------------------------------------------------------
258
 
259
                                s_irq_pa7_en <= add(1)     ; -- Autorisation des interruptions selon le bit A1
260
                                s_edge       <= add(0)     ; -- Transition front positif ou negatif
261
                                s_irq_pa7    <= '0'        ; -- Efface le flag d'interruption                                
262
 
263
                            end if ;
264
 
265
                        end if ; -- Fin des ecritures --
266
 
267
                    else
268
                        -------------
269
                        -- Lecture --
270
                        -------------
271
 
272
                        if (add(2) = '0') then
273
                            ---------------------------------------------
274
                            -- Acces aux registres I/O    quand A2 = 0 --
275
                            ---------------------------------------------
276
 
277
                            case add(1 downto 0) is
278
                                when "00" =>
279
                                    ---------------------------
280
                                    -- 000 : Lecture de ORA  --
281
                                    ---------------------------
282
                                    s_dout <= ((s_ddra and s_ora) or (pa_in and not(s_ddra))) ; -- Lecture du port en entree ou des latches de sortie
283
                                when "01" =>
284
                                    ---------------------------
285
                                    -- 001 : Lecture de DDRA --
286
                                    ---------------------------
287
                                    s_dout <= s_ddra ;
288
                                when "10" =>
289
                                    ---------------------------
290
                                    -- 010 : Lecture de ORB  --
291
                                    ---------------------------
292
                                    s_dout <= ((s_ddrb and s_orb) or (pb_in and not(s_ddrb))) ; -- Lecture du port en entree ou des latches de sortie
293
                                when "11" =>
294
                                    ---------------------------
295
                                    -- 011 : Lecture de DDRB --
296
                                    ---------------------------
297
                                    s_dout <= s_ddrb ;
298
                                when others =>
299
                                    null ;
300
 
301
                            end case ;
302
 
303
                        else
304
                            ---------------------------------------------
305
                            -- Acces au timer et status quand A2 = 1   --
306
                            ---------------------------------------------
307
 
308
                            if (add(0) = '0') then
309
                                ----------------------------------------
310
                                -- 1x0 : Lecture du TIMER             --
311
                                -- A3 active ou non les interruptions --
312
                                ----------------------------------------
313
                                s_irq_timer_en <= add(3)            ; -- Autorisation des interruptions selon le bit A3
314
 
315
                                s_dout <= std_logic_vector(s_timer) ; -- Valeur courante du timer
316
                                if not (s_timer = "00000000") then
317
                                    s_irq_timer <= '0'              ; -- Efface le flag d'interruption du timer, sauf si interruption en cours
318
                                end if ;
319
                            else
320
                                -----------------------------
321
                                -- 1x1 : Lecture du STATUS --
322
                                -----------------------------
323
                                s_dout <= s_irq_timer & s_irq_pa7 & "000000"   ; -- Registre de status (flag d'interruption)
324
                                s_irq_pa7 <= '0'                               ; -- Efface le flag d'interruption PA7
325
                            end if ;
326
 
327
                        end if ;
328
 
329
                    end if ; -- Fin des lectures --
330
 
331
                end if ; -- Fin des acces dependant du chip select --
332
 
333
            end if ; -- Fin des traitements hors RESET
334
 
335
            ------------------------------------------------------------------------
336
            -- Signal d'interruption en sortie, si interruption generee et autorisee
337
            ------------------------------------------------------------------------
338
 
339
            irq_n <= not ((s_irq_timer and s_irq_timer_en) or (s_irq_pa7 and s_irq_pa7_en)) ;
340
 
341
        end if ; -- Fin du traitement sur front montant de PHI2
342
 
343
        ------------------------------------------------------------------------
344
        -- Sorties sur les ports A et B, sur front descendant du PHI2
345
        ------------------------------------------------------------------------
346
 
347
        if (falling_edge(phi2)) then
348
            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
349
            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
350
        end if ;
351
 
352
    end process ;
353
 
354
    ------------------------------------------------------------------------
355
    -- Sortie sur le bus de donnees
356
    ------------------------------------------------------------------------
357
 
358
    dout <= s_dout when ((cs = '1') and (rw_n = '1')) else (others => '1') ; -- Si lecture et chip select, sinon FF
359
 
360
end architecture;
361
 

powered by: WebSVN 2.1.0

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