Processeur/Processeur.srcs/sources_1/new/Ecran.vhd
2021-07-30 10:09:20 +02:00

133 lines
6.9 KiB
VHDL

----------------------------------------------------------------------------------
-- Company: INSA-Toulouse
-- Engineer: Paul Faure
--
-- Create Date: 28.06.2021 09:20:00
-- Module Name: Ecran - Behavioral
-- Project Name: Processeur sécurisé
-- Target Devices: Basys 3 ARTIX7
-- Tool Versions: Vivado 2016.4
-- Description: Tableau des caractères à afficher à l'écran
-- - Ajoute les caractère a la suite les un des autres (comme un fichier avec un curseur)
-- - Prends des coordonnées (X,Y) et renvoi l'état du pixel associé
--
-- Dependencies:
-- - TableASCII
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.font.all;
use work.ScreenProperties.all;
entity Ecran is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
Data_Av : in STD_LOGIC; -- Un caractère doit être ajouté au tableau
Data_IN : in STD_LOGIC_VECTOR (0 to 6); -- Caractère à ajouter
X : in X_T; -- Position X
Y : in Y_T; -- Position Y
OUT_ON : out STD_LOGIC); -- Valeur du pixel (X,Y)
end Ecran;
architecture Behavioral of Ecran is
component TableASCII is
Port ( CodeASCII : STD_LOGIC_VECTOR (0 to 6);
Font : out STD_LOGIC_VECTOR (0 to (font_width * font_height) - 1));
end component;
constant Flush : STD_LOGIC_VECTOR (0 to 6) := "0000000"; -- Code ASCII du flush
constant RetourChariot : STD_LOGIC_VECTOR (0 to 6) := "0001010"; -- Code ASCII du retour chariot
constant Delete : STD_LOGIC_VECTOR (0 to 6) := "1111111"; -- Code ASCII du Delete
signal Ecran : STD_LOGIC_VECTOR (0 to Ecran_Taille - 1) := (others => '0'); -- Tableau des caractères de l'écran
signal L : STD_LOGIC_VECTOR (0 to 6) := "0000000"; -- Ligne du tableau dans laquelle il faut écrire (position Y du curseur)
signal L_inc : STD_LOGIC_VECTOR (0 to 6); -- L+1 mod Nb_Lignes
signal C : STD_LOGIC_VECTOR (0 to 6) := "0000000"; -- Colone du tableau dans laquelle il faut écrire (position X du curseur)
signal InitialL : STD_LOGIC_VECTOR (0 to 6) := "0000000"; -- Le tableau fonctionne comme un buffer circulaire, il faut donc garder en mémoire la première ligne
signal InitialL_inc : STD_LOGIC_VECTOR (0 to 6); -- InitialL+1 mod Nb_Lignes
signal Full : STD_LOGIC := '0'; -- Si le tableau est plein
signal L_Lecture : L_T := 0; -- Ligne pour la lecture dans le tableau
signal point_dereferencement : Natural := 0; -- Index dans le tableau ou est stocké le code ASCII correspondant à (X,Y)
signal point_dereferencement_ecriture : Natural := 0; -- Index dans le tableau ou la valeur doit être écrite
signal CurrentCodeASCII : STD_LOGIC_VECTOR (0 to 6) := "0000000"; -- Le code ASCII actuellement lu
signal CurrentFont : STD_LOGIC_VECTOR (0 to (font_width * font_height) - 1) := (others => '0'); -- La font correspondante a ce Code
signal position_X : X_T := 0; -- Signal pour décaler X de manière a introduire une marge
signal position_Y : Y_T := 0; -- Signal pour décaler Y de manière a introduire une marge
signal active : Boolean := false; -- Nous sommes (ou non) dans la zone active de l'écran
begin
instance_TableASCII : TableASCII
port map (CodeASCII => CurrentCodeASCII,
Font => CurrentFont);
process
begin
wait until CLK'event and CLK='1';
if (RST = '0' or (Data_Av = '1' and Data_IN = Flush)) then
-- Reset ou FLUSH
Ecran <= (others => '0');
L <= "0000000";
C <= "0000000";
InitialL <= "0000000";
Full <= '0';
elsif (Data_Av = '1') then
-- Data disponible
if (Data_IN = Delete) then
-- Un Delete, on efface un caractère sur la ligne (Nb : on ne peut effacer que la ligne courante)
if (C > 0) then
C <= C - 1;
Ecran(7 * (C_Blocks * to_integer(unsigned(L)) + to_integer(unsigned(C)) - 1) to 7 * (C_Blocks * to_integer(unsigned(L)) + to_integer(unsigned(C))) - 1) <= "0000000";
end if;
elsif (Data_In /= RetourChariot) then
-- Un caractère lamda, on l'écrit
Ecran(point_dereferencement_ecriture to point_dereferencement_ecriture + 6) <= Data_IN;
C <= C + 1;
end if;
if (Data_IN = RetourChariot or (C + 1 = C_Blocks and Data_IN /= Delete)) then
-- Si besoin on saute a la ligne suivant
C <= "0000000";
L <= L_inc;
if (L_inc = "0000000" or Full = '1') then
Full <= '1';
InitialL <= InitialL_inc;
Ecran(7 * C_Blocks * to_integer(unsigned(L_inc)) to 7 * C_Blocks * (to_integer(unsigned(L_inc)) + 1) - 1) <= Zero_Line;
end if;
end if;
end if;
end process;
-- Gestion des signaux d'écriture
L_inc <= "0000000" when L + 1 = L_Blocks else L + 1;
InitialL_inc <= "0000000" when InitialL + 1 = L_Blocks else InitialL + 1;
point_dereferencement_ecriture <= 7 * (C_Blocks * to_integer(unsigned(L)) + to_integer(unsigned(C)));
-- Gestion des signaux de lecture
position_X <= X - margin when X >= 0 + margin and X < screen_width - margin else 0; -- Prise en compte des marges
position_Y <= Y - margin when Y >= 0 + margin and Y < screen_height - margin else 0; -- Prise en compte des marges
active <= X >= 0 + margin and X < screen_width - margin and Y >= 0 + margin and Y < screen_height - margin; -- Fenetre active ?
L_Lecture <= position_Y/Display_CaracterHeight + to_integer(unsigned(InitialL)) - L_Blocks when (position_Y/Display_CaracterHeight + to_integer(unsigned(InitialL))) >= L_Blocks else position_Y/Display_CaracterHeight + to_integer(unsigned(InitialL)); -- Calcul de la ligne de lecture
point_dereferencement <= (7 * (C_Blocks * L_Lecture + (position_X/Display_CaracterWidht))); -- Calcul du point de déréférencement
CurrentCodeASCII <= Ecran(point_dereferencement to point_dereferencement + 6); -- Recupération du code ASCII
OUT_ON <= CurrentFont(((position_Y mod Display_CaracterHeight) / (Display_CaracterHeight / font_height)) * font_width + ((Display_CaracterWidht - 1) - (position_X mod Display_CaracterWidht)) / (Display_CaracterWidht / font_width)) when active else '0'; -- Calcul de l'état du pixel
end Behavioral;