------------------------------------------------------------------------------- -- Title : Lecture d'une image en format pgm -- Project : ------------------------------------------------------------------------------- -- File : pgm2pixel.vhd -- Author : -- Company : -- Last update : 1999/11/23 -- Platform : ------------------------------------------------------------------------------- -- Description : lire une image au format pgm et sortir un pixel trie -- : sur une grille 3x3 a la demande -- ------------------------------------------------------------------------------- -- Modification history : -- 1999/10/25 : created ------------------------------------------------------------------------------- LIBRARY std; USE std.textio.ALL; LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY pgm2pixel IS GENERIC ( image : string := "lena.pgm"; periode : time := 101 ns); -- frequence echantillonnage non -- utilisee ici PORT ( init : OUT std_ulogic; pixel : OUT natural RANGE 0 TO 255; dispo : OUT std_ulogic; acquit : IN std_logic); END pgm2pixel; USE work.utils.ALL; ARCHITECTURE pour_cci OF pgm2pixel IS FILE fichier : text IS IN image; SIGNAL he : std_ulogic; -- horloge d'echantillonnage SIGNAL autre_entree : boolean; -- separe les lectures dans le fichier SIGNAL autre_sortie : boolean; -- separe les envois au filtre TYPE tableau_pix IS ARRAY (1 TO 1024) OF natural RANGE 0 TO 255 ; SIGNAL memoire : tableau_pix; SIGNAL etat : natural RANGE 0 TO 3; SIGNAL point : natural RANGE 0 TO 255; SIGNAL initial : std_ulogic; -- generation du init SIGNAL pret : std_ulogic; BEGIN -- pour_cci h1: horloge(he, periode/2, periode/2); init <= initial; initial <= '1', '0' AFTER periode + 2 ns ; -- pour desynchroniser lect : PROCESS VARIABLE ligne : LINE; VARIABLE donnee : NATURAL; VARIABLE en_tete : string (1 TO 2) := "P2"; VARIABLE nx : natural; -- nombre de caracteres par ligne VARIABLE ny : natural; -- nombre de lignes; VARIABLE max : natural; -- intensite max VARIABLE bon : boolean; VARIABLE nbr_pix : natural; CONSTANT motsligne: natural := 17; -- nombre d'octets par ligne du fichier BEGIN WAIT UNTIL initial'event AND initial = '0'; -- demarrage de la lecture ASSERT false REPORT "debut de lecture du fichier image" SEVERITY note; readline(fichier, ligne); -- ouverture du fichier image read(ligne,en_tete,bon); ASSERT bon REPORT "l'en-tete n'est pas trouvee" SEVERITY error; ASSERT en_tete = "P2" REPORT "en-tete differente de P2" SEVERITY error ; readline(fichier, ligne); readline(fichier, ligne); readline(fichier, ligne); read(ligne,nx,bon); ASSERT bon REPORT "erreur de format sur nx" SEVERITY error; read(ligne,ny,bon); ASSERT bon REPORT "erreur de format sur ny" SEVERITY error; readline(fichier, ligne); read(ligne,max,bon); ASSERT bon REPORT "erreur de format sur max" SEVERITY error; nbr_pix := nx * ny; -- 262144 l1: LOOP readline(fichier, ligne); l2: FOR i IN 1 TO motsligne LOOP WAIT UNTIL autre_entree'event AND autre_entree ; read(ligne,donnee); point <= donnee; nbr_pix := nbr_pix -1; IF nbr_pix = 65536 THEN ASSERT false REPORT "Patience ... plus que 25%" SEVERITY note; END IF; IF nbr_pix = 131072 THEN ASSERT false REPORT "Patience ... plus que 50%" SEVERITY note; END IF; IF nbr_pix = 196608 THEN ASSERT false REPORT "Patience ... plus que 75%" SEVERITY note; END IF; EXIT l1 WHEN nbr_pix = 0; END LOOP; END LOOP; ASSERT false REPORT "Ouf !!, c'est fini" SEVERITY NOTE; WAIT; END process ; -- purpose : Compteur par 3 pour tri 3X3 des pixels -- inputs : init, autre_sortie, acquit -- outputs : etat de 0 a 3 fsm : PROCESS (initial, he, acquit ) VARIABLE var_etat : natural RANGE 0 TO 3; BEGIN -- PROCESS fsm IF initial = '1' THEN pret <= '0'; var_etat := 0; ELSIF rising_edge(he) AND autre_sortie THEN IF var_etat < 3 THEN var_etat := var_etat + 1; ELSE var_etat := 1; END IF; pret <= '1'; END IF; IF acquit = '1' THEN pret <= '0'; END IF; etat <= var_etat; END PROCESS fsm; dispo <= pret; autre_sortie <= (pret = '0' AND acquit = '0'); autre_entree <= etat = 1; WITH etat SELECT pixel <= memoire(1024) WHEN 1, memoire(512) WHEN 2, point WHEN 3, 0 WHEN others; GrosRegistre: PROCESS ( autre_entree, initial) BEGIN -- PROCESS IF initial = '1' THEN memoire <= (OTHERS => 0); -- tout a 0 ELSIF autre_entree'event AND autre_entree THEN FOR i IN memoire'high DOWNTO memoire'low + 1 LOOP memoire(i) <= memoire(i-1); END LOOP; -- i memoire(1) <= point; END IF; END PROCESS; END pour_cci;