Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> VHDL

Hoe Quartus Prime IP-bibliotheken aan VUnit te koppelen

Heb je ooit een VHDL-simulatie willen uitvoeren met een Quartus IP-kern via het VUnit-verificatieraamwerk?

Dat was wat FPGA-ingenieur Konstantinos Paraskevopoulos in gedachten had, maar hij kon er geen geschikte tutorial voor vinden. Gelukkig gebruikte hij zijn talent om erachter te komen hoe en was zo vriendelijk om het te delen met VHDLwhiz via dit gastartikel .

Laten we Konstantinos het woord geven!

Het is vaak wenselijk om vooraf gedefinieerde IP's uit de Quartus IP-catalogus in uw ontwerp op te nemen bij het simuleren van uw systeem met VUnit. Daarom is de volgende tutorial bedoeld om de lezer kennis te geven van het genereren, opnemen en koppelen van externe Quartus IP-bibliotheken aan de VUnit-omgeving.

Nieuw bij VUnit? Bekijk deze tutorial:Aan de slag met VUnit

Overzicht

Deze tutorial bestaat uit drie hoofdonderdelen:

  1. Een korte beschrijving van het geselecteerde IP
  2. Vereiste stappen om de juiste bibliotheken te genereren en te koppelen
  3. Verificatie door gebruik te maken van VUnit en Modelsim

Vereisten

  • Kwartus
    • Quartus Prime downloaden
    • QSYS zou in uw PATH moeten staan ​​voor STAP 2 (CMD-optie)
  • Intel Modelsim
    • Raadpleeg dit artikel voor informatie over het gratis installeren van ModelSim
    • ModelSim zou in je PATH moeten staan
  • VUnit
    • Raadpleeg dit artikel voor informatie over het gratis installeren van VUnit
  • Python 3.6 of hoger
    • Python downloaden
    • Python zou op je pad moeten zitten

Het veronderstelt ook basiskennis van VHDL en ModelSim-vaardigheden.

Ontwerp wordt getest

Voor ons scenario gebruiken we de Parallel Adder IP uit de Quartus Integer Arithmetic IP-lijst.

Ons ontwerp accepteert drie 16-bits invoervectoren en voert het toegevoegde resultaat uit in een 17-bits vector.

Stap 1:Genereer IP

We genereren onze opteller in het IP-catalogusvenster door te dubbelklikken op de parallelle optellercomponent onder Bibliotheek/Basisfuncties/Rekenen.

Nadat we een naam hebben gegeven en onze component hebben aangepast op basis van onze behoeften, klikken we rechtsonder op de knop HDL genereren.

Op dit punt verschijnt een venster, zoals weergegeven in de volgende afbeelding.

Opmerking: We moeten de Create simulation model . instellen onder de Simulation sectie naar VHDL of Verilog om de simulatiebestanden te genereren, aangezien de standaardoptie geen is. Als we er geen kiezen, de given_ip_name.spd bestand wordt niet gegenereerd, waardoor de volgende stap mislukt.

Het bovenstaande proces genereert een bestand en een map onder onze quartus map:

  1. Bestand:given_ip_name.ip
  2. Map:given_ip_name

De map bevat .vhd en .v bestanden die later in onze run.py . moeten worden toegevoegd schrift.

Stap 2:Genereer IP-simulatiebestanden

  1. GUI: Selecteer Tools ➤ Genereer Simulator Setup Script voor IP en specificeer de uitvoermap in het promptvenster,
  2. CMD: Door Qsys-opdrachten te gebruiken, kunnen we dezelfde bestanden genereren door de volgende opdracht in de terminal te typen:

ip-setup-simulation --quartus-project= <project's_QPF_filepath>
--output-directory= <my_dir>

Met behulp van een van de twee bovenstaande methoden instrueren we Quartus om een ​​map te genereren voor elke ondersteunde simulator die een script bevat om de IP-bibliotheken te maken en te compileren.

Stap 3:Genereer en compileer IP-bibliotheken voor Modelsim

De volgende stap is het vinden van de msim_setup.tcl script in de mentor map gemaakt door de vorige stap en dupliceer deze met de naam setup.tcl . Dan, in de setup.tcl bestand, verwijder de commentaar bij de geïllustreerde commando's en stel de $QSYS_SIMDIR . in variabel.


# # QSYS_SIMDIR is used in the Quartus-generated IP simulation script to
# # construct paths to the files required to simulate the IP in your Quartus
# # project. By default, the IP script assumes that you are launching the
# # simulator from the IP script location. If launching from another
# # location, set QSYS_SIMDIR to the output directory you specified when you
# # generated the IP script, relative to the directory from which you launch
# # the simulator.
# #
 set QSYS_SIMDIR <script generation output directory>
# #
# # Source the generated IP simulation script.
 source $QSYS_SIMDIR/mentor/msim_setup.tcl
# #
# # Set any compilation options you require (this is unusual).
# set USER_DEFINED_COMPILE_OPTIONS <compilation options>
# set USER_DEFINED_VHDL_COMPILE_OPTIONS <compilation options for VHDL>
# set USER_DEFINED_VERILOG_COMPILE_OPTIONS <compilation options for Verilog>
# #
# # Call command to compile the Quartus EDA simulation library.
 dev_com
# #
# # Call command to compile the Quartus-generated IP simulation files.
 com
# #

Na het wijzigen en opslaan van de setup.tcl , kunnen we het Tcl-bestand veilig uitvoeren met behulp van de vsim commando.


vsim -c -do "do setup.tcl; quit"

Dat genereert de gecompileerde bibliotheken in de mentor map.

Stap 4:VUnit-link

Nu de IP-bibliotheken zijn gegenereerd, moeten we ze koppelen met behulp van de python run.py schrift.

Bekijk de onderstaande afbeelding om de directorystructuur van ons voorbeeld beter te begrijpen. De initiële topologie bestond uit de hoofdmap demo , de tb , vunit , en quartus mappen. Alle submappen en bestanden onder de quartus map worden gegenereerd via het Quartus-framework na het maken van een project en het voltooien van stap 1 tot 3.

Opmerking: Quartus genereert meer bestanden en mappen, maar de afbeelding hieronder toont de bestanden die voor ons interessant zijn.

Door deze duidelijke weergave van de topologie als referentie te gebruiken, kunnen we ons ROOT-pad en de paden naar de gegenereerde bibliotheken specificeren, zoals hieronder weergegeven.

Merk op dat sim_files is de map die we in stap 2 hebben opgegeven waar de mentormap is opgeslagen.


from vunit import VUnit
from os.path 
import join, dirname, abspath
# ROOT
root = join(dirname(__file__), '../')
# Path to generated libraries
path_2_lib = '/quartus/sim_files/mentor/libraries/'
# ROOT


Na het maken van een VUnit-instantie met de naam vu , kunnen we een ontwerpbibliotheek voor onze VHDL-code specificeren en alle vereiste externe bibliotheken koppelen:

# Create VUnit instance by parsing command line arguments
vu = VUnit.from_argv()
# create design's library
my_lib = vu.add_library('my_lib')
# Link external library
vu.add_external_library("parallel_adder", root + path_2_lib + "parallel_adder")

En tot slot, voeg onze bronbestanden toe. Deze bevinden zich in drie submappen onder de given_ip_name map:

  1. parallel_add_191
  2. synth
  3. sim

De synth en sim dirs bevatten dezelfde informatie, namelijk het ontwerp op het hoogste niveau van onze IP. De opmaak van deze bestanden is in ons geval echter in VHDL. Ze kunnen in Verilog staan, en dit hangt af van de gekozen taal bij stap 1.

Als ons ontwerp op het hoogste niveau subcomponenten bevat, moeten we ook hun bronbestanden opnemen. Ze bevinden zich onder submappen in de given_ip_name directory, zoals de parallel_add_191 component in ons geval.

 
my_lib.add_source_files(join(root,'quartus','parallel_adder','sim','parallel_adder.vhd'))
my_lib.add_source_files(join(root,'quartus','parallel_adder','parallel_add_191','sim','parallel_adder_parallel_add_191_oh4guxa.vhd'))
my_lib.add_source_files(join(root,'tb','tb_demo.vhd'))
testbench = my_lib.entity("tb_demo") 
vu.main()

Testbank

Om te beginnen kun je deze link bekijken om meer te weten te komen over de basisprincipes van VUnit-testbench-formatie.

Terug naar onze testbank voegen we de benodigde VUnit-bibliotheken toe, samen met elke andere bibliotheek die we zouden willen gebruiken en definiëren onze signalen.

Opmerking: De procesuitvoering in ons voorbeeld is sequentieel. Dus stuursignalen (aangeduid als vlaggen ) worden gebruikt om een ​​proces te melden of het zal beginnen of eindigen.

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
library vunit_lib;
context vunit_lib.vunit_context;

entity tb_demo is 
generic ( runner_cfg : string:= runner_cfg_default); 
end tb_demo;
architecture sim of tb_demo is
constant clk_period : time := 10 ns;
signal clk : std_logic := '0';
signal rst : std_logic := '0';
-- INPUTS
signal data_a : std_logic_vector(0 to 15):= (others => '0');
signal data_b : std_logic_vector(0 to 15):= (others => '0');
signal data_c : std_logic_vector(0 to 15):= (others => '0');
-- OUTPUTS
signal result : std_logic_vector(0 to 16);
-- CONTROL FLAGS
signal reset_done :boolean := false;
signal sim_done   :boolean := false;
signal start_sim  :boolean := false;

Vervolgens instantiëren we onze UUT. Quartus levert voorbeelden van componentinstantiatie voor VHDL en Verilog onder de bestandsnaamconventies ip_name_inst.vhd en ip_name_inst.v .

begin 
-- Unit Under Test 
UUT : entity work.parallel_adder
port map ( 
data0x => data_a, -- parallel_add_input.data0x 
data1x => data_b, --                   .data1x 
data2x => data_c, --                   .data2x 
result => result  -- parallel_add_output.result
); 

De eerste twee processen die beginnen zijn clk_process en reset_rel . Terwijl de laatste wordt onderbroken na het resetten en besturen van de reset_done markeer naar true , de clk_process werkt gedurende de hele simulatietijd.

clk_process : process
begin 
  clk <= '1';
  wait for clk_period/2;
  clk <= '0'; 
  wait for clk_period/2; 
end process clk_process;

reset_rel : process
begin
  rst <= '1'; 
  wait for clk_period*2; 
  wait until rising_edge(clk); 
  rst <= not rst; 
  reset_done <= true; 
  wait; 
end process reset_rel;

Nu de reset is voltooid, kunnen we de test_runner . aanroepen proces voor het uitvoeren van onze tests. Verder blijft de testloper actief tot de sim_done vlag wordt gestuurd naar true , die plaatsvindt in het laatste proces.

test_runner : process
begin
  test_runner_setup(runner, runner_cfg);
  wait until reset_done and rising_edge(clk);

  iterate : while test_suite loop
    start_sim <= true;
    if run("test_case_1") then
      info ("Start");
      info (running_test_case);
      wait until sim_done;
    end if;
  end loop;
  test_runner_cleanup(runner);
end process test_runner;

Eindelijk, de data_generator proces voert verschillende toevoegingen uit door waarden toe te kennen aan de drie ingangen van onze parallelle opteller door gebruik te maken van een for lus.

Opmerking: Dit proces wordt geactiveerd wanneer de test_runner proces instrueert dit door de start_sim . in te stellen vlag. Aan het einde van dit proces verhoogt het de sim_done vlag, die de testloper opdracht geeft om de simulatie te pauzeren.

data_generator : process 
  constant tag2 : log_level_t := new_log_level("INFO", fg => blue, bg => black, style => bright);
  variable a,b,c,d : integer; 
begin 
  wait until start_sim;
   wait until rising_edge(clk); 
   show(display_handler, tag2);
   if running_test_case = "test_case_1" then
     for i in 0 to 10 loop
       data_a <= std_logic_vector(to_unsigned(i+10,data_a'length));
       data_b <= std_logic_vector(to_unsigned(i+20,data_a'length));
       data_c <= std_logic_vector(to_unsigned(i+30,data_a'length)); 
       wait until rising_edge(clk); 
       a := to_integer(unsigned(data_a)); 
       b := to_integer(unsigned(data_b)); 
       c := to_integer(unsigned(data_c)); 
       d := to_integer(unsigned(result)); 
       log( integer'image(a) &" + "& integer'image(b) &" + "& integer'image(c) 
          &" = "& integer'image(d), tag2); 
     end loop;
   end if; 
   sim_done <= true;
end process data_generator;

Verificatie

Om de testcase uit te voeren en te controleren of alles werkt zoals verwacht, kunnen we de run.py . uitvoeren script uit de map waarin het zich bevindt door simpelweg de volgende opdracht in de terminal te typen.


python ./run.py -v

Opmerking: Er is een aangepaste logger gebruikt voor een betere illustratie in onze uitvoer die zichtbaar is door de uitgebreide -v te leveren keuze. Omdat er slechts één testcase is gedefinieerd, hoeven we bovendien geen optie te bieden om deze te specificeren.

Ten slotte, om onze resultaten in ModelSim te verifiëren, kunnen we het volgende commando typen:

python ./run.py --gui

(Klik op de afbeelding om deze groter te maken)

Conclusie

Tot slot hebben we in deze tutorial geleerd hoe je Quartus IP's die zich in de IP-catalogus bevinden, in VUnit kunt opnemen en testen. We hebben een vooraf gedefinieerd IP-adres gebruikt. We kunnen echter ook verpakte aangepaste IP's op deze manier integreren in onze VUnit-omgeving.


Bekijk deze VUnit-zelfstudie als je dat nog niet hebt gedaan:
Aan de slag met VUnit


VHDL

  1. Wat is SigFox?
  2. Aan de slag met VUnit
  3. Een lijst met strings maken in VHDL
  4. Simulatie stoppen in een VHDL-testbench
  5. Een PWM-controller maken in VHDL
  6. Hoe willekeurige getallen te genereren in VHDL
  7. Hoe maak je een zelfcontrolerende testbank aan
  8. Hoe technologie een cruciale schakel vormt in ethische toeleveringsketens
  9. Chain Link Fencing Machine:hoe het werkt en de begunstigde
  10. hydraulische tandwielpomp vullen
  11. hoe de hydraulische pomp van een ford-tractor te vullen