Difference between revisions of "EDK tutorial 3"

From ift
(New page: == VHDL design i ISE 7.1 for virtex-4 == En enkel steg-for-steg veiledning til implementasjon av en RS232 transmitter på en virtex-4 FPGA Dette er en kort introduksjon til Xilinx ISE og...)
(No difference)

Revision as of 09:19, 2 March 2009

VHDL design i ISE 7.1 for virtex-4

En enkel steg-for-steg veiledning til implementasjon av en RS232 transmitter på en virtex-4 FPGA

Dette er en kort introduksjon til Xilinx ISE og vhdl design i EDK. Vi tar utgangspunkt i det samme prototypekortet (DS-BD-V4LX25MB) som i turtorail 1 og 2. Målet er å lage en enkelt RS232 transmitter som sender koden på DIP-bryterene til en terminal på PC'en. Du vil trenge hyperterminal eller et annet tilsvarende program til å lese COM porten på PC'en.

Lage nytt prosjekt

Start programmet "Project Navigator" under "Xilinx ISE 7.1i" menyen. Når du starter opp vil forrige prosjekt automatisk ligge der hvist noen har brukt ISE før deg. I tilfelle så lukker du prosjektet ved å velge "Close Project" under "File" menyen. Fra "file" menyen velger du så "New Project". Du vil nå få opp et vindu hvor du kan navngi prosjektet og velge plasering. Kall prosjektet "RS232" og finn en passende plasering for prosjektkatalogen. "Top Level Module Type" setter du til VHD. Trykk så "Next"

File:EDK XPS 30.jpg

Du vil nå få opp et vindu hvor du kan velge hviken FPGA du vil bruke, samt vertøyvalg. Sett "Device Family" til Virtex4, "Device" til "xc4vlx25", "Package" til "ff668" og "Speed Grade til -10". "Synthesis Tool" settes til "XST", "Simulator" til "ISE simulator" og simuleringsspråk settes til VHDL. Trykk så "Next".

File:EDK XPS 31.jpg

Du vil nå få opp ett vindu hvor du har muligheten til å få generert en kildefil til prosjektet. Trykk på "New Source".

File:EDK XPS 32.jpg

Velg "VHDL Module" og gi den navnet "RS232_main". Pass på at boksen "Add to Project" er merket og trykk "Next".

File:EDK XPS 33.jpg

Du kan nå legge til porter. Legg inn portene; clk, reset og send som "in". Legg til data som "in" og sett MSB til 7 og LSB til 0. Legg til port tx og opptatt som "out". Trykk så "Next".

File:EDK XPS 34.jpg

Du får nå opp et vindu med et samendrag av kildefilen din. Trykk "Finish". Du kommer nå tilbake til vinduet hvor du kan legge til kildefiler. Trykk "Next".

Neste vindu lar deg legge til ferdige kilderfiler. Ta filene [[Media:rs232_clk.vhd">rs232_clk.vhd</a> og [[Media:rs232_tx.vhd">rs232_tx.vhd</a> og last dem ned på maskinen din.

---------------------------------
--Tor Aleksander Birk Danielsen--
--     klokke til RS232        --
--        10.04.2005           --
---------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity rs232_clk is
   port( 	clk       :  in    std_logic;  --main clk 100MHz
         reset     :  in    std_logic;  --global reset
         clk_tx    :  inout std_logic;  --sendeklokke 16*baudrate
         bit_send  :  out   std_logic); --pulstog 1*baudrate
end rs232_clk;

architecture Behavioral of rs232_clk is
--interne tellere
   signal clk_teller_1 : std_logic_vector(0 to 8);
   signal clk_teller_2 : std_logic_vector(0 to 3);

begin

---------------------------------------
--lage klokkefrekvens på 16xbaudraten--
--   clk/(budrate*16) = tellerverdi*2--
-- 100MHz/(9600*32) = 325 = 101000101--
---------------------------------------
   process (clk)
   begin
   if clk'event and clk='1' then
      if reset = '1' then
         clk_teller_1 <= clk_teller_1 + 1;
         if clk_teller_1 = "101000101" then
            clk_tx <= not clk_tx;
            clk_teller_1 <= "000000000";
         end if;
      else
         clk_teller_1 <= "000000000";
      end if;
   end if;
   end process;

---------------------------------------
--lage 1/16 puls av clk_tx til sender--
--    dvs pulstog med samme frekvens --
--    som baudraten                  --
---------------------------------------
   process (reset, clk_tx)
   begin 
      if reset = '0' then
         bit_send  <= '0';	
         clk_teller_2 <= "0000";
      elsif rising_edge(clk_tx) then
         clk_teller_2 <= clk_teller_2 + 1;
         if clk_teller_2 = "1111" then
            bit_send <= '1';
         elsif	 clk_teller_2 = "0000" then
            bit_send <= '0';
         end if;
      end if;
   end process;

end Behavioral;
---------------------------------
--Tor Aleksander Birk Danielsen--
--       sender RS232          --
--        10.04.2005           --
---------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity rs232_tx is
   port( clk_tx   :  in   std_logic;  --clk 16 * baudrateklokke
         reset    :  in   std_logic;  --global reset
         bit_send :  in   std_logic;  --pulstog 1*baudrate
         send     :  in   std_logic;  --starter transmitt
         data     :  in   std_logic_vector(7 downto 0); --data som skal sendes
         tx       :  out  std_logic;  --transmittpinne
         opptatt  :  out  std_logic); --sender opptatt signal
end rs232_tx;

architecture Behavioral of rs232_tx is
   type 	 tilstander is (idle, start_sending, sender, stop_send);
   signal sende_data :       tilstander := idle;
   signal transmitt_buffer : std_logic_vector(9 downto 0); 	--transmitt buffer (10 bit)
   signal transmitt_data : 	  std_logic_vector(7 downto 0);   	--inneholder databyte som skal sendes
   signal bit_teller:        integer := 9;
begin

-------------------------
--senderutine for rs232--
-------------------------
   sender_rs232: process (reset, clk_tx)
   begin
      if reset='0' then
         opptatt <= '0';
         sende_data <= idle;
         transmitt_buffer <= (others=> '1');
      elsif rising_edge(clk_tx) then
         case sende_data  is
            when idle =>
               if send = '0' then
                  transmitt_data <= data;
                  opptatt <= '1';
                  sende_data <= start_sending;
               else
                  opptatt <= '0';
               end if;

            when start_sending =>
               if bit_send = '1' then
                  sende_data <= sender;
                  bit_teller <= 9;
                  transmitt_buffer <= '1' & transmitt_data & '0';
               end if;

            when sender =>
               if bit_send	= '1' then
                  bit_teller <= bit_teller - 1;
                  transmitt_buffer <= '1' & transmitt_buffer(transmitt_buffer'high downto 1);
                  if bit_teller = 1 then
                     sende_data <= stop_send;
                  end if;
               end if;

            when stop_send =>
               if bit_send = '1' then
                  sende_data <= idle;
               end if;

            When others =>
               sende_data <= idle;
 
         end case;			
      end if;
   end process;
   tx <= transmitt_buffer(0);
end Behavioral;

Trykk så "Add Source" og legg begge filene til prosjektet. På spørsmål om filtype velg "VHDL design file". Trykk så "Next".

File:EDK XPS 35.jpg

Du vil nå få opp et sammendrag av prosjektet ditt. Trykk "Finish" og prosjektet vil bli generert.

Lage koden

Vi har nå en main fil samt en fil med klokkekode og en fil med transisjonskode. Neste steg bli å inkludere klokken og senderen i hovedfilene vår. Dobbeltklikk på filen "RS232_main.vhd" under "Module View" for å åpne filen for editering. Legg til følgende kodebit mellom "architecture .." og "begin":

--legger til komponenter
   component rs232_clk
      port ( clk              : in    std_logic;
             reset            : in    std_logic;
             clk_tx           : out   std_logic; 
             bit_send         : out   std_logic);
   end component;

   component rs232_tx
      port ( clk_tx           : in    std_logic;
             reset            : in    std_logic;  
             bit_send         : in    std_logic;
             send             : in    std_logic;
             data             : in    std_logic_vector(7 downto 0);
             tx               : out   std_logic;
             opptatt          : out   std_logic);
   end component;

--definere interne signaler
   signal bit_send   : std_logic;
   signal clk_tx     : std_logic;             

Etter begin legges følgende kodebit inn:

-- kobler klokke og tx signaler til rs232_main entity sig.
   klokke_gen: rs232_clk
      port map( clk,
                reset,
                clk_tx, 
                bit_send);

   transmitt: rs232_tx
      port map( clk_tx,
                reset,  
                bit_send,
                send,
                data,
                tx,
                opptatt);

Filen Media:RS232_main.vhd kan lastes ned ferdig hvis du er usikker på om du har lagt inn koden korrekt. Når du er ferdig med å redigere main filen tar du å lagrer prosjektet. Neste steg blir å test om koden er korekt. I "prosess View" vinduet går du til "Design Utilities" og dobbelklikker på "Check Syntax for Simulation". Har du gjort alt korekt skal du ikke få noen feilmelding nå. I "Module view" kan du også se at RS232_clk og RS232_tx har blitt underordnet RS232_main.

Legge til pinner

Neste steg er å legge til "user constraints" som i vårt tilfelle betyr å definere hvilke pinner som skal til hviken port. I "Module View" menyen markerer du filen RS232_main.vhd da det er denne filen du ønsker å legge "User Constraints" til. Når filen er markert går du til "Prosess View" vinduet og velger "User Constraints" menyen. Dobbeltklikk på "Assign Package Pins". Du vil nå få spørsmål om du vil legge til en UCF fil til prosjektet. Trykk "Yes". Du får nå opp et nytt vindu. I "Design Object List" vinduet har du en oversikt over alle IO porter i prosjektet ditt. Vi skal nå legge inn pinnr i "Loc" til hver av portene. Legg til følgene:

File:EDK XPS 36.jpg

Når du er ferdig lagrer du og avslutter hele 2Xilinx Pace" vinduet. Du har nå fått generert en UCF fil til prosjektet ditt som inneholder følgende:

#PACE: Start of Constraints generated by PACE

#PACE: Start of PACE I/O Pin Assignments
NET "clk"  LOC = "B13"  ;
NET "data<0>"  LOC = "AD11"  ;
NET "data<1>"  LOC = "AC12"  ;
NET "data<2>"  LOC = "AC13"  ;
NET "data<3>"  LOC = "AD13"  ;
NET "data<4>"  LOC = "AC14"  ;
NET "data<5>"  LOC = "AD14"  ;
NET "data<6>"  LOC = "AC15"  ;
NET "data<7>"  LOC = "AB7"  ;
NET "opptatt"  LOC = "AE9"  ;
NET "reset"  LOC = "AB9"  ;
NET "send"  LOC = "AA11"  ;
NET "tx"  LOC = "T7"  ;

#PACE: Start of PACE Area Constraints

#PACE: Start of PACE Prohibit Constraints

#PACE: End of Constraints generated by PACE

Sythesisering og Implementering

Neste steg blir å Synthesiserer og implementere deisgnet vårt. Marker igjen filen RS232_main.vhd i "Module View" vinduet og dobbeltklikk på "Genreate Programming File" i "Process View". Du vil nå få generert en bit fil som kan lastes over i FPGA'en.

Programering og testing

Vi skal nå programmere FPGA'en. Sørg for at det er strøm på kortet og at programmeringsadapterert er koblet til. Start også hyperterminal med med en baudrate på 9600kbps. Gå til "Process View" og dobeltklikk på "Configure Device(iMPACT). Du åpner nå iMPACT programmet. På spørsmålom konfigurerig velg "Boundary-Scan mode". I neste vindu velger du automatisk tilkobling. Trykk så "Finish". iMPACT vil nå automatisk sjekke hvor mange og hvilke type FPGA'er som er koblet til programmeringsadapterert. Du vil få et vindu som sier at en enhet er funnet. Trykk "Ok". Du får nå opp et vindu der du blir bedt om å tilordne en new configureringsfil. Velg filen rs232_main.bit. Du får nå opp en advarsel. Ignorer denne og trykk "Ok". Høyreklikk på bildet av Virtex4 og velg "porgram...". Trykk så "Ok". Du vil nå programere FPGA'en.

File:EDK XPS 37.jpg

Hvis du nå trykker "Push2" bryteren vil du få bittmønsteret til DIP-bryterene oversendt til hyperterminal som ASCII kode. Du har nå suksessfult laget og implementert VHDL kode med ISE.