OBSERVERA!! Dessa sidor är numera utdaterade. Kursens websidor finns i Lisam.
Institutionen för systemteknik
Göm meny

FPGA-kortet NEXYS3 TSEA83

Vi har några ex av följande expansionskort:

Ett litet exempel

Detta exempel är skrivet av Andreas Ehliar och är just nu en lite mindre preliminär version. För att detta ska gå i gång i Muxen 1, gör du module add TSEA83 .

  1. Jag antar att du sitter vid en Linux-dator. För att detta ska fungera måste du ha följande installerat: ModelSim, Xilinx ISE och Adept. Den sistnämnda kan laddas ner från Digilents sida .
  2. Se till att bygeln JP1 står i läget USB.
  3. Koppla in USB-sladden till en PC och för skjutomkopplaren Power till ON. Kortet spänningsmatas nu via USB och lysdioden vid JP1 tänds. Sedan startar en testsekvens och diverse intressanta saker skrivs ut på displayen.
  4. Ladda ner den här filen och packa upp den med tar xzvf ae_synth_v2.tar.gz.
  5. Katalogen innehåller ett litet exempel i lab.vhd och leddriver.vhd, en testbänk i lab_tb.vhd och en UCF i lab.ucf.
  6. Nu kan du simulera med: make lab.sim
  7. och syntetisera med: make lab.synth
  8. och göra en bit-fil med: make lab.bitgen
  9. och programmera FPGA-n med: make lab.prog

Apropos VGA

Klockfrekvensen ( clk i VHDL) är 100 MHz. Exemplet i Reference Manual är gjort för en pixelklocka på 25 MHz och ger bild direkt! Vad skönt att ha 4 klockcykler på sig för varje pixel, som ska ut!

Apropos block RAM

Det finns 32 Block RAM inuti FPGA-kretsen. De har följande egenskaper:

  • Äkta två-port. Det går alltså att läsa/skriva två data samtidigt.
  • Godycklig organisation, men det måste gå att tillverka av: 2 kB per styck med variabel organisation (512x32, 1024x16, ...).
  • Synkron läsning och synkron skrivning.

type mem_t is array of (0 to 15) of std_logic_vector(7 downto 0);
constant grr : mem_t :=
        ("0000000000000000",
         "0000000000000000",
         "0000000000000000",
         "0000000000000110",
         "1000100001100000",
         "0110000000010000",
         "0110000000010001",
         "0000000000000000",
         "0000000000000000",
         "0000000000000000",
         "0000000000000110",
         "1000100001100000",
         "0110000000010000",
         "0110000000010001",
         "0110000000010000",
         "0110000000010001");
signal mem: mem_t := grr;
process(clk)
begin
if rising_edge(clk) then
  if wea='0' then
    mem(conv_integer(addra)) <= dataina;
  end if;
  if web='0' then
    mem(conv_integer(addrb)) <= datainb;
  end if;
  datauta <= mem(conv_integer(addra));
  datautb <= mem(conv_integer(addrb));
end if;
end process;

Apropos distributed RAM

Verktyget kan också göra minne av LUT-arna inuti FPGA-n. Det kallas distributed RAM, eftersom det minnet kommer att vara utsmetat på flera logikceller. Ett distributed RAM har följande egenskaper:

  • Vilken organisation som helst.
  • Asynkron läsning och synkron skrivning.
Det finns 9112 st 64x1 LUT-ar. OBS, LUT-arna är ju främst till för att göra Booleska uttryck med. Men det går även att göra små minnen, typ registerfil i en CPU.

Apropos BlueTooth

  • Vår BlueTooth-modul är ett litet kretskort med UART-gränsnitt (Rx och Tx). BT ersätter alltså en serie-kabel (cable replacement). Se här .
  • FPGA-kortet har en "UART-kontakt" i form av en USB-kontakt. Hit går det inte att ansluta BT-modulen.
  • Det finns virkort , som ansluts till FPGA-kortet. På virkortet borde det gå att vira in BT-modulen. Detta är just nu (29/3) helt otestat. Vi kan tänka oss att vira ihop en sådan modul, som ni får använda.

Apropos PmodI2S - Stereo Audio Output

Om man sätter kortet på Pmod anslutning JA, övre raden:

Net "MCLK" LOC = T12 | IOSTANDARD = LVCMOS33; #Bank = 2, pin name = IO_L19P, Sch name = JA1
Net "LRCK" LOC = V12 | IOSTANDARD = LVCMOS33; #Bank = 2, pin name = IO_L19N, Sch name = JA2
Net "SCLK" LOC = N10 | IOSTANDARD = LVCMOS33; #Bank = 2, pin name = IO_L20P, Sch name = JA3
Net "SDIN" LOC = P11 | IOSTANDARD = LVCMOS33; #Bank = 2, pin name = IO_L20N, Sch name = JA4

Observera att Digilents dokumentation är felaktig.

Apropos klockfrekvens

Nexys3-kortet har en grundklocka på 100 MHz. Den kan generera en annan frekvens, mellan 4 MHz och 400 MHz, att användas som klocka inne i FPGA:n. För att göra det behöver man konstruera en klock-komponent, vilket görs med ett grafiskt verktyg som heter Clocking Wizard som ingår i Xilinx ISE.

I Xilinx ISE behöver man skapa ett projekt för de ingående filerna i projektet och sedan bara spara projektet. Projekfilen behövs sedan i Core Generator.

Windows:Clocking Wizard startas från Core Generator som man hittar i Xilinx ISE (grafiska verktyg) under "Tools / Core generator ...". I Core Generator expanderar man "FGPA Features and Design" och sedan "Clocking" och dubbelklickar därefter på "Clocking Wizard".

Linux:Ladda modulen TSEA83. Xilinx ISE startas i en terminal med kommandot:
ise
och verktyget Core Generator startas i en terminal med kommandot:
coregen

I Clocking Wizard anger man på page 2 ny önskad frekvens för CLK_OUT1, och klickar sedan på Generate. Då skapas ett antal filer, bl a den nya klock-komponent i form av en VHDL-fil (clk_wiz_v3_6.vhd) som behöver inkluderas i projektet. Utöver det behöver projektet UCF-fil uppdateras på några rader, samt att projektets topp-modul behöver använda själva klock-komponenten.
Här finns en färdig clk_wiz_v3_6.vhd som sänker klockfrekvensen till 50MHz.
Glöm inte att inkludera clk_wiz_v3_6.vhd i Makefile, bland övriga filer i projektet.

Topp-modulen behöver anpassas ungefär på följande sätt:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity top_module is
generic (TCQ : in time := 100 ps);
  port (
    CLK_IN1 : IN std_logic;
    RESET : in std_logic;
    ...
    );
end top_module;


architecture Behavioral of top_module is
signal locked_int : std_logic;  -- 1 when PLL has locked internal clock
signal clk_int : std_logic;     -- internal clock
signal clk : std_logic;         -- clock for original design
signal rst : std_logic;         -- reset for original design

component clk_wiz_v3_6 is
port (

  CLK_IN1 : in std_logic;
  CLK_OUT1 : out std_logic;
  RESET : in std_logic;
  LOCKED : out std_logic;
);
end component;

begin
  clknetwork : clk_wiz_v3_6
  port map (CLK_IN1 => CLK_IN1, CLK_OUT1 => clk_int, RESET => RESET, LOCKED => locked_int);
  
  clk <= clk_int;
  rst <= (not locked_int or RESET);

  -- Here follows the rest of the design
  process (clk)
  begin
    if rising_edge(clk) then
      if (rst = '1') then
  ...

Projektets UCF-fil behöver anpassas ungefär på följande sätt:

##Clock signal
#Net "clk" LOC=V10 | IOSTANDARD=LVCMOS33;
#Net "clk" TNM_NET = sys_clk_pin;
#TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;

Net "CLK_IN1" LOC=V10 | IOSTANDARD=LVCMOS33;
NET "CLK_IN1" TNM_NET = "CLK_IN1";
TIMESPEC "TS_CLK_IN1" = PERIOD "CLK_IN1" 10.0 ns HIGH 50% INPUT_JITTER 100.0ps;

# FALSE PATH constraints
Net "RESET" TIG;

## Reset signal
#Net "rst" LOC = B8 | IOSTANDARD = LVCMOS33;
Net "RESET" LOC = B8 | IOSTANDARD = LVCMOS33;
...

Informationsansvarig: Anders Nilsson
Senast uppdaterad: 2022-05-30