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

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

Heeft u ooit gewild een VHDL-simulatie draaien die een Quartus IP-kern bevat via het VUnit-verificatieframework?

Dat had FPGA-engineer Konstantinos Paraskevopoulos in gedachten, maar hij kon geen geschikte tutorial vinden. Gelukkig gebruikte hij zijn talent om uit te zoeken hoe en was hij vriendelijk genoeg om het te delen met VHDLwhiz via dit gastartikel.

Laten we het woord aan Konstantinos geven!

Het is vaak wenselijk om vooraf gedefinieerde IP's uit de Quartus IP-catalogus in uw ontwerp te incorporeren bij het simuleren van uw systeem met VUnit. Deze tutorial levert de kennis om te genereren, incorporeren, en externe Quartus IP-bibliotheken te koppelen aan de VUnit-omgeving.

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

Overzicht

Deze tutorial bestaat uit drie hoofddelen:

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

Vereisten

  • Quartus
    • Download Quartus Prime
    • QSYS moet in uw PATH zitten voor STAP 2 (CMD-optie)
  • Intel Modelsim
    • Raadpleeg dit artikel voor hoe ModelSim gratis te installeren
    • ModelSim moet in uw PATH staan
  • VUnit
    • Raadpleeg dit artikel voor hoe VUnit gratis te installeren
  • Python 3.6 of hoger
    • Download Python
    • Python moet in uw pad zitten

Het wordt ook aangenomen dat basiskennis van VHDL en ModelSim aanwezig is.

Ontwerp onder test

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

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

Ons ontwerp accepteert drie 16-bit invoervectoren en geeft het opgetelde resultaat uit in een 17-bit vector.

Stap 1: IP genereren

We genereren onze adder in het IP-catalogusvenster door dubbel te klikken op de parallel adder component onder Library/Basic functions/Arithmetic.

Nadat we een naam opgeven en ons component aanpassen op basis van onze behoeften, klikken we op de Generate HDL-knop rechtsonder.

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

Op dit moment verschijnt een venster, zoals afgebeeld in de volgende figuur.

Let op: We moeten Create simulation model onder de Simulation sectie instellen op VHDL of Verilog om de simulatiebestanden te genereren, aangezien de standaardoptie "none" is. Als we er geen kiezen, wordt het given_ip_name.spd bestand niet gegenereerd, wat de volgende stap doet mislukken.

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

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

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

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

Stap 2: IP-simulatiebestanden genereren

  1. GUI: Selecteer Tools ➤ Generate Simulator Setup Script for IP en specificeer output directory in het prompt-venster,
  2. CMD: Door Qsys-commando's te benutten, kunnen we dezelfde bestanden genereren door in de terminal het volgende commando in te typen:
ip-setup-simulation --quartus-project= <project's_QPF_filepath> \ --output-directory= <my_dir>

Door een van de twee methoden bovenstaand, instrueren we Quartus om een directory voor elke ondersteunde simulator te genereren die een script bevat om de IP-bibliotheken te creëren en compileren.

Stap 3: IP-bibliotheken genereren en compileren voor Modelsim

De volgende stap is het vinden van het msim_setup.tcl script in de mentor map die gegenereerd is door de vorige stap en het dupliceren met de naam setup.tcl. Vervolgens, in het setup.tcl bestand, de geïllustreerde commando's uncommenten en de $QSYS_SIMDIR variabele instellen.

# # 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 aanpassen en opslaan van setup.tcl, kunnen we het Tcl-bestand veilig uitvoeren met het vsim commando.

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

Dit genereert de gecompileerde bibliotheken in de mentor map.

Stap 4: VUnit koppeling

Nu de IP-bibliotheken gegenereerd zijn, moeten we ze koppelen door gebruik te maken van het python run.py script.

Bekijk de onderstaande figuur om de directory-structuur van ons voorbeeld beter te begrijpen. De initiële topologie bestond uit de root-map demo, de tb, vunit, en quartus mappen. Alle submappen en bestanden onder de quartus map zijn gegenereerd via het Quartus-framework na het aanmaken van een project en het voltooien van stappen 1 tot 3.

Let op: Quartus genereert meer bestanden en mappen, maar de onderstaande afbeelding toont die van belang voor ons.

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

Met deze duidelijke topologie als referentie, kunnen we ons ROOT-pad en de paden naar de gegenereerde bibliotheken specificeren, zoals hieronder getoond.

Let op dat sim_files de directory is die we in stap 2 hebben gespecificeerd waar de mentor-map is opgeslagen.

from vunit import VUnit from os.path import join, dirname, abspath # ROOT root = join(dirname(__file__), '../') # Pad naar gegenereerde bibliotheken path_2_lib = '/quartus/sim_files/mentor/libraries/' # ROOT

Na het aanmaken van een VUnit-instantie genaamd vu, kunnen we een ontwerpbibliotheek voor onze VHDL-code specificeren en eventuele vereiste externe bibliotheken koppelen:

# Maak VUnit-instantie door commandoregelargumenten te parsen vu = VUnit.from_argv() # maak ontwerpbibliotheek my_lib = vu.add_library('my_lib') # Koppel externe bibliotheek vu.add_external_library("parallel_adder", root + path_2_lib + "parallel_adder")

En ten slotte voegen we onze bronbestanden toe. Deze bevinden zich in drie submappen onder de given_ip_name directory:

  1. parallel_add_191
  2. synth
  3. sim

De synth en sim mappen bevatten dezelfde informatie, namelijk het top-level ontwerp van onze IP. De formatting van deze bestanden in ons geval is in VHDL. Ze kunnen in Verilog zijn, en dit hangt af van de gekozen taal in stap 1.

In het geval ons top-level ontwerp sub-componenten omvat, moeten we ook hun bronbestanden includen. 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()

Testbench

Om te beginnen, kunt u deze link bekijken om te leren over de basis van VUnit-testbenchvorming.

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

Let op: Procesuitvoering in ons voorbeeld is sequentieel. Dus controle-signalen (aangeduid als vlaggen) worden gebruikt om een proces te notificeren of het moet starten of stoppen.

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 component-instantiatievoorbeelden voor VHDL en Verilog onder de bestandsconventies 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 starten zijn clk_process en reset_rel. Terwijl de laatste geschorst wordt na resetten en het drijven van de reset_done vlag naar true, werkt de clk_process door de hele simulatie-tijd.

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 klaar is, kunnen we het test_runner proces aanroepen voor het uitvoeren van onze tests. Verder blijft de test runner actief tot de sim_done vlag naar true gedreven wordt, wat 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; 

Ten slotte voert het data_generator proces diverse optellingen uit door waarden toe te kennen aan de drie invoeren van onze parallel adder door gebruik te maken van een for lus.

Let op: Dit proces wordt getriggerd wanneer het test_runner proces dit instruereert door de start_sim vlag op te zetten. Aan het einde van dit proces, zet het de sim_done vlag, wat de test runner opdracht geeft 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 verifiëren dat alles werkt zoals verwacht, kunnen we het run.py script uitvoeren vanuit de directory waar het zich bevindt door simpelweg in de terminal het volgende commando in te typen.

python ./run.py -v

Let op: Een aangepaste logger is gebruikt voor betere illustratie in onze output die zichtbaar is door de verbose -v optie te geven. Daarnaast, aangezien slechts één testcase gedefinieerd is, hoeven we geen optie op te geven om het te specificeren.

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

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

python ./run.py --gui

Quartus Prime IP-bibliotheken integreren in VUnit: een stapsgewijze handleiding

(Klik de afbeelding om hem groter te maken)

Conclusie

Ter afsluiting, hebben we geleerd hoe Quartus IPs die in de IP-catalogus resideren, te incorporeren en testen binnen een VUnit-omgeving. Hoewel deze tutorial een vooraf gedefinieerde IP gebruikte, geldt hetzelfde proces voor custom gepackageerde IPs.

Bekijk deze VUnit tutorial als u dat nog niet gedaan hebt:
Aan de slag met VUnit

VHDL

  1. Kettinglinkheiningmachine: Hoe het werkt en de voordelen
  2. Technologie: De sleutel tot transparante, ethische toeleveringsketens
  3. Hoe Een Hydraulische Tandwielpomp Te Vullen Voor Optimale Prestaties
  4. Stap-voor-Stap Handleiding Voor Het Vullen Van Een Ford Trekker Hydraulische Pomp
  5. SigFox uitgelegd: Technologie, marktimpact en vergelijking met Link Labs
  6. VUnit 101: Een praktische gids voor geautomatiseerde VHDL-verificatie
  7. Dynamische string-lijsten in VHDL: Best Practices & Voorbeeld
  8. Een VHDL-testbench netjes beëindigen: methoden en best practices
  9. Een PWM-controller implementeren in VHDL: Ontwerp, Simulatie en FPGA-demo
  10. Willekeurige getallen genereren in VHDL: Van Uniform naar OSVVM
  11. Een self-checking testbench in VHDL bouwen – Een praktische gids