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

Subversion Repositories vhdl_6530_rriot

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/vhdl_6530_rriot/trunk/R6530.vhd
0,0 → 1,315
-------------------------------------------------------------------------------
-- File : R6530.vhd
-- Author : Thierry DAVROUX
-- Company : Flipprojets
-- Created : 03-01-2017
-------------------------------------------------------------------------------
-- Description: Version simplifiee d'un 6530.
-- Avec uniquement les ports A et B et le timer.
-- La RAM et la ROM ne sont pas integrees dans ce module.
-- La selection est simplifiee avec un seul "Chip Select".
-- Pas de detection de front sur PA7 (contrairement au 6532).
-- Bus d'adresses sur 4 bits (A3..A0).
-------------------------------------------------------------------------------
-- Copyright (c) Flipprojets François et Thierry DAVROUX - 2018
-- (contact@flipprojets.fr)
--
-- Concédée sous licence EUPL, version 1.2 ou – dès leur approbation par la
-- Commission européenne - versions ultérieures de l’EUPL (la «Licence»).
-- Vous ne pouvez utiliser la présente œuvre que conformément à la Licence.
-- Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
--
-- https://joinup.ec.europa.eu/software/page/eupl
--
-- Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
-- la Licence est distribué «en l’état», SANS GARANTIES OU CONDITIONS QUELLES
-- QU’ELLES SOIENT, expresses ou implicites. Consultez la Licence pour les
-- autorisations et les restrictions linguistiques spécifiques relevant de la
-- Licence.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 03-01-2017 1.0 TDX Creation
-- 27-03-2017 1.1 TDX Amelioration presentation (tabulations)
-------------------------------------------------------------------------------
 
library IEEE ;
use IEEE.std_logic_1164.all ;
use IEEE.numeric_std.all ;
 
entity R6530 is
port (
phi2 : in std_logic ; -- PHI2 horloge
rst_n : in std_logic ; -- RST reset negatif
cs : in std_logic ; -- CS chip select
rw_n : in std_logic ; -- RW read/write
irq_n : out std_logic ; -- IRQ interruption
add : in std_logic_vector (3 downto 0) ; -- A3..A0 Bus d'adresses
din : in std_logic_vector (7 downto 0) ; -- DI7..DI0 Bus de donnees (entrees)
dout : out std_logic_vector (7 downto 0) ; -- DO7..DO0 Bus de donnees (sorties)
pa_in : in std_logic_vector (7 downto 0) ; -- PORT A entrees
pa_out : out std_logic_vector (7 downto 0) ; -- PORT A sorties
pb_in : in std_logic_vector (7 downto 0) ; -- PORT B entrees
pb_out : out std_logic_vector (7 downto 0) -- PORT B sorties
);
end entity;
 
architecture RTL of R6530 is
 
signal s_ddra : std_logic_vector (7 downto 0) ; -- Registre DDRA
signal s_ddrb : std_logic_vector (7 downto 0) ; -- Registre DDRB
signal s_ora : std_logic_vector (7 downto 0) ; -- Registre ORA
signal s_orb : std_logic_vector (7 downto 0) ; -- Registre ORB
signal s_dout : std_logic_vector (7 downto 0) ; -- Sortie du bus de donnees
signal s_irq_timer : std_logic ; -- Etat de l'interruption par le timer
signal s_irq_timer_en : std_logic ; -- Autorisation interruption par le timer
signal s_divider : unsigned (9 downto 0) ; -- Prediviseur (valeur maxi)
signal s_count : unsigned (9 downto 0) ; -- Compteur du prediviseur (compteur)
signal s_timer : unsigned (7 downto 0) ; -- Decompteur du timer (valeur en cours)
 
begin
 
------------------------------------------------------------------------
-- Fonctionnement principal dependant de PHI2
------------------------------------------------------------------------
process(phi2)
begin
if (rising_edge(phi2)) then
------------------------------------------------------------------------
-- Tout le circuit fonctionne sur front montant du PHI2
-- y compris la prise en compte du RESET
------------------------------------------------------------------------
 
if (rst_n = '0') then
------------------------------------------------------------------------
-- RESET, init de la sortie de donnees et des ports A/B
------------------------------------------------------------------------
s_dout <= (others => '1') ; -- Sortie FF
s_ddra <= (others => '0') ; -- DDRA a zero
s_ddrb <= (others => '0') ; -- DDRB a zero
s_ora <= (others => '0') ; -- ORA a zero
s_orb <= (others => '0') ; -- ORB a zero
------------------------------------------------------------------------
-- RESET, init du timer/diviseur et du flag d'interruption
------------------------------------------------------------------------
s_timer <= (others => '0') ; -- Remise a zero du decompteur du timer
s_divider <= "0000000000" ; -- Remise a zero du prediviseur (mode 1T)
s_count <= (others => '0') ; -- Remise a zero du compteur du prediviseur
s_irq_timer <= '0' ; -- Remise a zero de l'interruption
s_irq_timer_en <= '0' ; -- Interruption non autorisee
else
------------------------------------------------------------------------
-- Traitement du timer, sur front montant du PHI2
------------------------------------------------------------------------
if (s_count = s_divider) then
s_timer <= s_timer - 1 ; -- On decremente le timer
s_count <= (others => '0') ; -- et on reinitialise le compteur du prediviseur
if (s_timer = "00000000") then -- Si le timer est arrive a zero
s_divider <= "0000000000" ; -- on remet le diviseur a 1T
s_irq_timer <= '1' ; -- et on leve le flag d'interruption
end if ;
else
s_count <= s_count + 1 ; -- On incremente le compteur du prediviseur
end if ;
------------------------------------------------------------------------
-- Acces aux registres, sur front montant du PHI2
------------------------------------------------------------------------
if (cs = '1') then
-------------------------------------------------------------------------------
-- A condition que le CHIP SELECT soit actif, l'adressage est le suivant : --
-- RW x000 - Read/Write ORA --
-- RW x001 - Read/Write DDRA --
-- RW x010 - Read/Write ORB --
-- RW x011 - Read/Write DDRB --
-- W .100 - Write Timer 1T --
-- W .101 - Write Timer 8T --
-- W .110 - Write Timer 64T --
-- W .111 - Write Timer 1024T --
-- R x1x0 - Read Timer --
-- R x1x1 - Read Status (interrupt flag) --
-------------------------------------------------------------------------------
if (rw_n = '0') then
--------------
-- Ecriture --
--------------
 
if (add(2) = '0') then
---------------------------------------------
-- Acces aux registres I/O quand A2 = 0 --
---------------------------------------------
 
case add(1 downto 0) is
when "00" =>
------------------------------
-- 000 : Ecriture dans ORA --
------------------------------
s_ora <= din ;
when "01" =>
------------------------------
-- 001 : Ecriture dans DDRA --
------------------------------
s_ddra <= din ;
when "10" =>
------------------------------
-- 010 : Ecriture dans ORB --
------------------------------
s_orb <= din ;
when "11" =>
------------------------------
-- 011 : Ecriture dans DDRB --
------------------------------
s_ddrb <= din ;
when others =>
null ;
end case ;
else
-------------------------------------------------
-- Acces aux registres Timer quand A2 = 1 --
-------------------------------------------------
 
---------------------------------------------
-- A3 active ou non les interruptions --
---------------------------------------------
 
s_irq_timer_en <= add(3) ; -- Autorisation des interruptions selon le bit A3
s_irq_timer <= '0' ; -- Efface le flag d'interruption
s_timer <= unsigned(din) - 1 ; -- Valeur initiale du timer
s_count <= (others => '0') ; -- Mise a zero du compteur du prediviseur
case add(1 downto 0) is
when "00" =>
--------------------------
-- 100 : diviseur 1T --
--------------------------
s_divider <= "0000000000" ; -- Valeur maxi du compteur = 0
when "01" =>
--------------------------
-- 101 : diviseur 8T --
--------------------------
s_divider <= "0000000111" ; -- Valeur maxi du compteur = 7
when "10" =>
--------------------------
-- 110 : diviseur 64T --
--------------------------
s_divider <= "0000111111" ; -- Valeur maxi du compteur = 63
when "11" =>
--------------------------
-- 111 : diviseur 1024T --
--------------------------
s_divider <= "1111111111" ; -- Valeur maxi du compteur = 1023
when others =>
null ;
end case ;
end if ; -- Fin des ecritures --
else
-------------
-- Lecture --
-------------
if (add(2) = '0') then
---------------------------------------------
-- Acces aux registres I/O quand A2 = 0 --
---------------------------------------------
 
case add(1 downto 0) is
when "00" =>
---------------------------
-- 000 : Lecture de ORA --
---------------------------
s_dout <= ((s_ddra and s_ora) or (pa_in and not(s_ddra))) ; -- Lecture du port en entree ou des latches de sortie
when "01" =>
---------------------------
-- 001 : Lecture de DDRA --
---------------------------
s_dout <= s_ddra ;
when "10" =>
---------------------------
-- 010 : Lecture de ORB --
---------------------------
s_dout <= ((s_ddrb and s_orb) or (pb_in and not(s_ddrb))) ; -- Lecture du port en entree ou des latches de sortie
when "11" =>
---------------------------
-- 011 : Lecture de DDRB --
---------------------------
s_dout <= s_ddrb ;
when others =>
null ;
 
end case ;
else
---------------------------------------------
-- Acces au timer et status quand A2 = 1 --
---------------------------------------------
 
if (add(0) = '0') then
----------------------------------------
-- 1x0 : Lecture du TIMER --
-- A3 active ou non les interruptions --
----------------------------------------
s_irq_timer_en <= add(3) ; -- Autorisation des interruptions selon le bit A3
s_dout <= std_logic_vector(s_timer) ; -- Valeur courante du timer
if not (s_timer = "00000000") then
s_irq_timer <= '0' ; -- Efface le flag d'interruption du timer, sauf si interruption en cours
end if ;
else
-----------------------------
-- 1x1 : Lecture du STATUS --
-----------------------------
s_dout <= s_irq_timer & "0000000" ; -- Registre de status (flag d'interruption)
end if ;
end if ;
end if ; -- Fin des lectures --
end if ; -- Fin des acces dependant du chip select --
end if ; -- Fin des traitements hors RESET
 
------------------------------------------------------------------------
-- Signal d'interruption en sortie, si interruption generee et autorisee
------------------------------------------------------------------------
irq_n <= not (s_irq_timer and s_irq_timer_en) ;
end if ; -- Fin du traitement sur front montant de PHI2
------------------------------------------------------------------------
-- Sorties sur les ports A et B, sur front descendant du PHI2
------------------------------------------------------------------------
 
if (falling_edge(phi2)) then
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
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
end if ;
end process ;
------------------------------------------------------------------------
-- Sortie sur le bus de donnees
------------------------------------------------------------------------
dout <= s_dout when ((cs = '1') and (rw_n = '1')) else (others => '1') ; -- Si lecture et chip select, sinon FF
 
end architecture;
 

powered by: WebSVN 2.1.0

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