ПЦУСБ/Лекция 6 — различия между версиями
Материал из Wiki
< ПЦУСБ
ANA (обсуждение | вклад) (Новая страница: «{{ПЦУСБ TOC}} <slideshow style="custis" headingmark="Слайд:" incmark=":step" scaled="true"> ;title: Операторы языка VHDL ;author: Авд…») |
ANA (обсуждение | вклад) м |
||
(не показана 1 промежуточная версия 1 участника) | |||
Строка 13: | Строка 13: | ||
* работа с файлами | * работа с файлами | ||
* конфигурация | * конфигурация | ||
+ | |||
+ | |||
+ | == Тестбенч для блока доступа == | ||
+ | |||
+ | * [http://simhard.com/websvn/listing.php?repname=osvvm&path=%2Fbsuir%2Ftrunk%2Ffinal_project%2Ftb%2F&#acafe1d810f0ee0fa65683acb69f49977 prj] | ||
+ | |||
+ | === Структура папок в проекте === | ||
+ | |||
+ | * /final_project — Папка проекта. Создаётся переменная среды <code>$final_project=<путь к папке>/final_project</code> | ||
+ | ** /tb — файлы, относящиеся к среде верификации (тестбенчу) | ||
+ | *** block1_model.vhd | ||
+ | *** block1_pkg.vhd | ||
+ | *** block1_tb2.vhd | ||
+ | *** block1_TestCtrl.vhd | ||
+ | ** ''/testplan'' — тестовый план | ||
+ | ** /tmp — для логов, временных диаграмм и других временных файлов | ||
+ | ** ''/tst'' — тесты (входные или выходные) | ||
+ | ** /vhd — исходные тексты VHDL-модели тестируемого блока | ||
+ | *** block1_beh2_a.vhd | ||
+ | *** block1.vhd | ||
+ | ** /vsim — скрипты для запуска моделирования в ModelSim/Questa | ||
+ | *** compile.tcl — скрипт для компиляции проекта | ||
+ | *** sim.tcl — скрипт для запуска моделирования | ||
+ | *** wave.do — скрипт для добавления сигналов на временные диаграммы | ||
+ | ** /work — папка для хранения библиотек ModelSim/Questa | ||
+ | *** /work — библиотека work | ||
+ | * modelsim.ini — файл настроек для ModelSim/Questa | ||
+ | |||
+ | |||
+ | ==== Файл настроек modelsim.ini ==== | ||
+ | |||
+ | ['''Library'''] | ||
+ | final_prj = work/final_prj | ||
+ | work = work/final_prj | ||
+ | . . . | ||
+ | ['''vcom'''] | ||
+ | ; Value of 1 or 1993 for VHDL-1993. | ||
+ | ; Default or value of 2 or 2002 for VHDL-2002. | ||
+ | ; Value of 3 or 2008 for VHDL-2008 | ||
+ | VHDL93 = 2008 | ||
+ | . . . | ||
+ | ['''vsim'''] | ||
+ | ; vopt flow | ||
+ | ; Set to turn on automatic optimization of a design. | ||
+ | VoptFlow = 0 | ||
+ | ; Simulator resolution | ||
+ | ; Set to fs, ps, ns, us, ms, or sec with optional prefix of 1, 10, or 100. | ||
+ | Resolution = ns | ||
+ | ; Default run length | ||
+ | RunLength = 100 | ||
+ | ; Maximum iterations that can be run without advancing simulation time | ||
+ | IterationLimit = 5000 | ||
+ | |||
+ | |||
+ | === Скрипты для запуска моделирования === | ||
+ | |||
+ | Листинг файла compile.tcl | ||
+ | <source lang="tcl"> | ||
+ | set wlibname final_prj | ||
+ | set wlibpath vhd | ||
+ | |||
+ | # Create the library. | ||
+ | if [file exists work/$wlibname] { | ||
+ | # vdel -all | ||
+ | } else { | ||
+ | vlib work/$wlibname | ||
+ | # vmap $wlibname work/$wlibname | ||
+ | # Create link "work" on main library | ||
+ | # vmap work work/$wlibname | ||
+ | } | ||
+ | #foreach name [glob "${wlibpath}/*.vhd"] {vcom +cover=bcefsx -work $wlibname $name} | ||
+ | vcom +cover=bcefsx -work $wlibname vhd/block1.vhd | ||
+ | vcom +cover=bcefsx -work $wlibname vhd/block1_beh2_a.vhd | ||
+ | |||
+ | vcom -reportprogress 300 -work $wlibname tb/block1_pkg.vhd | ||
+ | vcom -reportprogress 300 -work $wlibname tb/block1_model.vhd | ||
+ | vcom -reportprogress 300 -work $wlibname tb/block1_TestCtrl.vhd | ||
+ | vcom -reportprogress 300 -work $wlibname tb/block1_tb2.vhd | ||
+ | |||
+ | if {[batch_mode]} { | ||
+ | quit -f | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Листинг файла sim.tcl | ||
+ | |||
+ | vsim -novopt -coverage work.block1_tb(tb2) | ||
+ | do vsim/wave.do | ||
+ | run -all | ||
+ | |||
+ | |||
+ | {{Hider|Листинг файла wave.do для вывода временных диаграмм}} | ||
+ | <source lang="text"> | ||
+ | onerror {resume} | ||
+ | quietly WaveActivateNextPane {} 0 | ||
+ | add wave -noupdate /block1_tb/SetPassword | ||
+ | add wave -noupdate /block1_tb/DigitalKey | ||
+ | add wave -noupdate /block1_tb/Esc | ||
+ | add wave -noupdate /block1_tb/rst | ||
+ | add wave -noupdate /block1_tb/LedOpen | ||
+ | add wave -noupdate /block1_tb/Speaker | ||
+ | add wave -noupdate /block1_tb/Clk | ||
+ | add wave -noupdate /block1_tb/DUT/SetPassword | ||
+ | add wave -noupdate /block1_tb/DUT/DigitalKey | ||
+ | add wave -noupdate /block1_tb/DUT/Esc | ||
+ | add wave -noupdate /block1_tb/DUT/clk | ||
+ | add wave -noupdate /block1_tb/DUT/rst | ||
+ | add wave -noupdate /block1_tb/DUT/LedOpen | ||
+ | add wave -noupdate /block1_tb/DUT/Speaker | ||
+ | add wave -noupdate /block1_tb/DUT/count | ||
+ | add wave -noupdate /block1_tb/DUT/KeyCode | ||
+ | add wave -noupdate -radix hexadecimal /block1_tb/DUT/Password | ||
+ | add wave -noupdate -radix hexadecimal /block1_tb/DUT/InputCode | ||
+ | add wave -noupdate /block1_tb/DUT/Delay05s | ||
+ | add wave -noupdate /block1_tb/DUT/Delay3s | ||
+ | add wave -noupdate /block1_tb/DUT/Delay5s | ||
+ | add wave -noupdate /block1_tb/block1_model_1/SetPassword | ||
+ | add wave -noupdate /block1_tb/block1_model_1/DigitalKey | ||
+ | add wave -noupdate /block1_tb/block1_model_1/Esc | ||
+ | add wave -noupdate /block1_tb/block1_model_1/clk | ||
+ | add wave -noupdate /block1_tb/block1_model_1/rst | ||
+ | add wave -noupdate /block1_tb/block1_model_1/LedOpen | ||
+ | add wave -noupdate /block1_tb/block1_model_1/Speaker | ||
+ | add wave -noupdate /block1_tb/DUT/DigitalPanel | ||
+ | add wave -noupdate /block1_tb/block1_TestCtrl_1/Clk | ||
+ | add wave -noupdate /block1_tb/DUT/state | ||
+ | add wave -noupdate -expand /block1_tb/block1_TestCtrl_1/PortsInRec | ||
+ | add wave -noupdate -expand /block1_tb/block1_TestCtrl_1/PortsOutRec | ||
+ | TreeUpdate [SetDefaultTree] | ||
+ | WaveRestoreCursors {{Cursor 1} {136088 ns} 0} | ||
+ | quietly wave cursor active 1 | ||
+ | configure wave -namecolwidth 150 | ||
+ | configure wave -valuecolwidth 100 | ||
+ | configure wave -justifyvalue left | ||
+ | configure wave -signalnamewidth 1 | ||
+ | configure wave -snapdistance 10 | ||
+ | configure wave -datasetprefix 0 | ||
+ | configure wave -rowmargin 4 | ||
+ | configure wave -childrowmargin 2 | ||
+ | configure wave -gridoffset 0 | ||
+ | configure wave -gridperiod 1 | ||
+ | configure wave -griddelta 40 | ||
+ | configure wave -timeline 0 | ||
+ | configure wave -timelineunits ns | ||
+ | update | ||
+ | WaveRestoreZoom {0 ns} {669291 ns} | ||
+ | </source> | ||
+ | {{Hider|end}} | ||
+ | |||
+ | |||
+ | === Структура тестирующей программы === | ||
+ | |||
+ | {| align=center | ||
+ | !<html><img src="https://docs.google.com/drawings/d/1Bu-uQn3QcHt-6MXOvrHi7momzcMtCRNRmUKKAH95hbI/pub?w=800"></html> | ||
+ | |- | ||
+ | ! Рисунок - Структурная схема тестбенча | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | |||
+ | === Листинги файлов тестбенча === | ||
+ | |||
+ | {{Hider|Листинг файла block1_tb2.vhd }} | ||
+ | <source lang="vhdl"> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use work.block1_pkg.all; | ||
+ | |||
+ | ------------------------------------------------------------------------------- | ||
+ | |||
+ | entity block1_tb is | ||
+ | |||
+ | end entity block1_tb; | ||
+ | |||
+ | ------------------------------------------------------------------------------- | ||
+ | |||
+ | architecture tb2 of block1_tb is | ||
+ | |||
+ | component block1_model is | ||
+ | port ( | ||
+ | PortsInRec : in PortsInRecType; | ||
+ | PortsOutRec : out PortsOutRecType; | ||
+ | SetPassword : out std_logic; | ||
+ | DigitalKey : out std_logic_vector(9 downto 0); | ||
+ | Esc : out std_logic; | ||
+ | clk : out std_logic; | ||
+ | rst : out std_logic; | ||
+ | -- DigitalPanel : out std_logic_vector(15 downto 0); | ||
+ | LedOpen : in std_logic; | ||
+ | Speaker : in std_logic); | ||
+ | end component block1_model; | ||
+ | |||
+ | component block1_TestCtrl is | ||
+ | port ( | ||
+ | PortsInRec : out PortsInRecType; | ||
+ | PortsOutRec : in PortsOutRecType); | ||
+ | end component block1_TestCtrl; | ||
+ | |||
+ | -- component ports | ||
+ | signal SetPassword : std_logic; | ||
+ | signal DigitalKey : std_logic_vector(9 downto 0); | ||
+ | signal Esc : std_logic; | ||
+ | signal rst : std_logic; | ||
+ | signal LedOpen : std_logic; | ||
+ | signal Speaker : std_logic; | ||
+ | signal DigitalPanel : std_logic_vector(15 downto 0); | ||
+ | |||
+ | signal Clk : std_logic; | ||
+ | |||
+ | signal PortsInRec : PortsInRecType; | ||
+ | signal PortsOutRec : PortsOutRecType; | ||
+ | |||
+ | begin -- architecture tb | ||
+ | |||
+ | -- component instantiation | ||
+ | DUT: entity work.block1(beh2) | ||
+ | port map ( | ||
+ | SetPassword => SetPassword, | ||
+ | DigitalKey => DigitalKey, | ||
+ | Esc => Esc, | ||
+ | clk => clk, | ||
+ | rst => rst, | ||
+ | DigitalPanel => DigitalPanel, | ||
+ | LedOpen => LedOpen, | ||
+ | Speaker => Speaker); | ||
+ | |||
+ | block1_model_1: block1_model | ||
+ | port map ( | ||
+ | PortsInRec => PortsInRec, | ||
+ | PortsOutRec => PortsOutRec, | ||
+ | SetPassword => SetPassword, | ||
+ | DigitalKey => DigitalKey, | ||
+ | Esc => Esc, | ||
+ | clk => clk, | ||
+ | rst => rst, | ||
+ | LedOpen => LedOpen, | ||
+ | Speaker => Speaker); | ||
+ | |||
+ | block1_TestCtrl_1: block1_TestCtrl | ||
+ | port map ( | ||
+ | PortsInRec => PortsInRec, | ||
+ | PortsOutRec => PortsOutRec); | ||
+ | |||
+ | end architecture tb2; | ||
+ | </source> | ||
+ | {{Hider|end}} | ||
+ | |||
+ | |||
+ | {{Hider|Листинг файла block1_model.vhd}} | ||
+ | <source lang="vhdl"> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use work.block1_pkg.all; | ||
+ | |||
+ | |||
+ | use work.block1_pkg. all; | ||
+ | |||
+ | entity block1_model is | ||
+ | |||
+ | port ( | ||
+ | PortsInRec : In PortsInRecType; | ||
+ | PortsOutRec : out PortsOutRecType; | ||
+ | |||
+ | SetPassword : out std_logic; | ||
+ | DigitalKey : out std_logic_vector(9 downto 0); | ||
+ | Esc : out std_logic; | ||
+ | clk : out std_logic; -- синхросигнал 25 МГц | ||
+ | rst : out std_logic; | ||
+ | LedOpen : in std_logic; | ||
+ | Speaker : in std_logic | ||
+ | ); | ||
+ | |||
+ | end entity block1_model; | ||
+ | |||
+ | architecture beh of block1_model is | ||
+ | |||
+ | begin -- architecture beh | ||
+ | |||
+ | SetPassword <= PortsInRec.SetPassword; | ||
+ | DigitalKey <= PortsInRec.DigitalKey; | ||
+ | Esc <= PortsInRec.Esc; | ||
+ | clk <= PortsInRec.clk; | ||
+ | rst <= PortsInRec.rst; | ||
+ | PortsOutRec.LedOpen <= LedOpen; | ||
+ | PortsOutRec.Speaker <= Speaker; | ||
+ | |||
+ | end architecture beh; | ||
+ | </source>{{Hider|end}} | ||
+ | |||
+ | |||
+ | {{Hider|Листинг файла block1_pkg.vhd}} | ||
+ | <source lang="vhdl"> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | package block1_pkg is | ||
+ | |||
+ | |||
+ | -- subtype String100 is string(1 to 100); | ||
+ | -- FUNCTION resolved ( s : resolved_character ) RETURN character; | ||
+ | -- subtype TString is resolved String100; | ||
+ | subtype TString is string(1 to 100); | ||
+ | |||
+ | type PortsInRecType is record | ||
+ | SetPassword : std_logic; | ||
+ | DigitalKey : std_logic_vector(9 downto 0); | ||
+ | Esc : std_logic; | ||
+ | clk : std_logic; | ||
+ | rst : std_logic; | ||
+ | -- LedOpen : std_logic; | ||
+ | -- Speaker : std_logic; | ||
+ | Info : TString; | ||
+ | end record PortsInRecType; | ||
+ | |||
+ | type PortsOutRecType is record | ||
+ | LedOpen : std_logic; | ||
+ | Speaker : std_logic; | ||
+ | end record PortsOutRecType; | ||
+ | |||
+ | |||
+ | type KeyType is (D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, | ||
+ | Esc, rst, clk, SetPass, SetPassword, Pass, clean); | ||
+ | |||
+ | type time_vec is array (1 to 3) of time; | ||
+ | |||
+ | procedure Init ( signal PortsRec : out PortsInRecType); | ||
+ | procedure SetSignal ( | ||
+ | signal PortsRec : out PortsInRecType; | ||
+ | SignalName : in KeyType; | ||
+ | value : std_logic); | ||
+ | procedure PressKey ( | ||
+ | signal PortsRec : out PortsInRecType; | ||
+ | KeyCode : in KeyType; | ||
+ | PressDelay : in time := 50 ns; | ||
+ | WaitAfterPress : in time := 50 ns | ||
+ | ); | ||
+ | procedure EnterPass ( | ||
+ | signal PortsInRec : out PortsInRecType; | ||
+ | signal PortsOutRec : in PortsOutRecType; | ||
+ | Pass : in string(1 to 3) := "000"; | ||
+ | PressDelay : in time_vec := (others => 50 ns); | ||
+ | WaitAfterPress : in time_vec := (others => 50 ns) | ||
+ | ); | ||
+ | |||
+ | end package block1_pkg; | ||
+ | |||
+ | package body block1_pkg is | ||
+ | |||
+ | procedure Init ( | ||
+ | signal PortsRec : out PortsInRecType) is | ||
+ | begin -- procedure Init | ||
+ | PortsRec.SetPassword <= '0'; | ||
+ | PortsRec.DigitalKey <= (others => '0'); | ||
+ | PortsRec.Esc <= '0'; | ||
+ | PortsRec.rst <= '1'; | ||
+ | PortsRec.clk <= 'Z'; | ||
+ | -- PortsRec.LedOpen <= 'Z'; | ||
+ | -- PortsRec.Speaker <= 'Z'; | ||
+ | -- PortsRec.Info <= (others => ' '); | ||
+ | wait for 21 ns; | ||
+ | PortsRec.rst <= '0'; | ||
+ | end procedure Init; | ||
+ | |||
+ | procedure SetSignal ( | ||
+ | signal PortsRec : out PortsInRecType; | ||
+ | SignalName : in KeyType; | ||
+ | value : std_logic) is | ||
+ | begin -- procedure Init | ||
+ | case SignalName is | ||
+ | when D0 => PortsRec.DigitalKey(0) <= value; | ||
+ | when D1 => PortsRec.DigitalKey(1) <= value; | ||
+ | when D2 => PortsRec.DigitalKey(2) <= value; | ||
+ | when D3 => PortsRec.DigitalKey(3) <= value; | ||
+ | when D4 => PortsRec.DigitalKey(4) <= value; | ||
+ | when D5 => PortsRec.DigitalKey(5) <= value; | ||
+ | when D6 => PortsRec.DigitalKey(6) <= value; | ||
+ | when D7 => PortsRec.DigitalKey(7) <= value; | ||
+ | when D8 => PortsRec.DigitalKey(8) <= value; | ||
+ | when D9 => PortsRec.DigitalKey(9) <= value; | ||
+ | when Esc => PortsRec.Esc <= value; | ||
+ | when rst => PortsRec.rst <= value; | ||
+ | -- when clk => PortsRec.clk <= value; | ||
+ | when SetPass|SetPassword|Pass | ||
+ | => PortsRec.SetPassword <= value; | ||
+ | when clean => | ||
+ | PortsRec.SetPassword <= '0'; | ||
+ | PortsRec.DigitalKey <= (others => '0'); | ||
+ | PortsRec.Esc <= '0'; | ||
+ | PortsRec.rst <= '0'; | ||
+ | when others => null; | ||
+ | end case; | ||
+ | end procedure SetSignal; | ||
+ | |||
+ | |||
+ | procedure PressKey ( | ||
+ | signal PortsRec : out PortsInRecType; | ||
+ | KeyCode : in KeyType; | ||
+ | PressDelay : in time := 50 ns; | ||
+ | WaitAfterPress : in time := 50 ns | ||
+ | ) is | ||
+ | begin -- procedure Init | ||
+ | |||
+ | SetSignal(PortsRec, KeyCode, '1'); | ||
+ | wait for PressDelay ; | ||
+ | SetSignal(PortsRec, KeyCode, '0'); | ||
+ | wait for WaitAfterPress ; | ||
+ | end procedure PressKey; | ||
+ | |||
+ | function CharToKeyCode (KeyCodeChar : character) return KeyType is | ||
+ | variable KeyCode : KeyType := D0; | ||
+ | begin | ||
+ | |||
+ | case KeyCodeChar is | ||
+ | when '0' => KeyCode := D0; | ||
+ | when '1' => KeyCode := D1; | ||
+ | when '2' => KeyCode := D2; | ||
+ | when '3' => KeyCode := D3; | ||
+ | when '4' => KeyCode := D4; | ||
+ | when '5' => KeyCode := D5; | ||
+ | when '6' => KeyCode := D6; | ||
+ | when '7' => KeyCode := D7; | ||
+ | when '8' => KeyCode := D8; | ||
+ | when '9' => KeyCode := D9; | ||
+ | when 'E'|'e' => KeyCode := Esc; | ||
+ | when 'S'|'s' => KeyCode := SetPassword; | ||
+ | when others => null; | ||
+ | end case; | ||
+ | return KeyCode; | ||
+ | |||
+ | end function CharToKeyCode; | ||
+ | |||
+ | procedure EnterPass ( | ||
+ | signal PortsInRec : out PortsInRecType; | ||
+ | signal PortsOutRec : in PortsOutRecType; | ||
+ | Pass : in string(1 to 3) := "000"; | ||
+ | PressDelay : in time_vec := (others => 50 ns); | ||
+ | WaitAfterPress : in time_vec := (others => 50 ns) | ||
+ | ) is | ||
+ | variable KeyCode : KeyType; | ||
+ | begin -- procedure Init | ||
+ | -- PortsRec.DigitalKey <= (others => 'Z'); | ||
+ | for i in 1 to 3 loop | ||
+ | KeyCode := CharToKeyCode(Pass(i)); | ||
+ | --PortsInRec.Info <= ( & Pass & " " , others => ' '); | ||
+ | PortsInRec.Info <= (Pass & " - ("& pass(i) & ")", others => ' ' ); | ||
+ | |||
+ | PressKey(PortsInRec, KeyCode, PressDelay(i), WaitAfterPress(i)); | ||
+ | |||
+ | end loop; -- i | ||
+ | -- ожидание перехода в start | ||
+ | PortsInRec.Info <= ("wait Start", others => ' ' ); | ||
+ | wait | ||
+ | until (PortsOutRec.LedOpen = '0' and PortsOutRec.LedOpen'event) | ||
+ | or (PortsOutRec.Speaker = '0' and PortsOutRec.Speaker'event) | ||
+ | for 100000 ns; | ||
+ | |||
+ | end procedure EnterPass; | ||
+ | |||
+ | end package body block1_pkg; | ||
+ | </source> | ||
+ | {{Hider|end}} | ||
+ | |||
+ | |||
+ | {{Hider|Листинг файла block1_TestCtrl.vhd }} | ||
+ | <source lang="vhdl"> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | use work.block1_pkg.all; | ||
+ | |||
+ | entity block1_TestCtrl is | ||
+ | |||
+ | port ( | ||
+ | PortsInRec : out PortsInRecType; | ||
+ | PortsOutRec : in PortsOutRecType | ||
+ | ); | ||
+ | |||
+ | end entity block1_TestCtrl; | ||
+ | |||
+ | architecture Test1 of block1_TestCtrl is | ||
+ | |||
+ | signal Clk : std_logic := '1'; | ||
+ | |||
+ | |||
+ | begin -- architecture Test1 | ||
+ | |||
+ | |||
+ | -- clock generation | ||
+ | Clk <= not Clk after 5 ns; | ||
+ | PortsInRec.clk <= clk; | ||
+ | |||
+ | -- waveform generation | ||
+ | WaveGen_Proc: process | ||
+ | begin | ||
+ | -- insert signal assignments here | ||
+ | |||
+ | Init(PortsInRec); | ||
+ | --wait for 50 ns; | ||
+ | |||
+ | EnterPass(PortsInRec, PortsOutRec, "123"); | ||
+ | EnterPass(PortsInRec, PortsOutRec, "000"); | ||
+ | EnterPass(PortsInRec, PortsOutRec, "1ee"); | ||
+ | EnterPass(PortsInRec, PortsOutRec, "12e"); | ||
+ | EnterPass(PortsInRec, PortsOutRec, "123", (others => 100 ns), (others => 100000 ns)); | ||
+ | wait for 1000 ns; | ||
+ | |||
+ | assert false report "END Simulation" severity failure; | ||
+ | wait; | ||
+ | end process WaveGen_Proc; | ||
+ | |||
+ | end architecture Test1; | ||
+ | </source> | ||
+ | {{Hider|end}} | ||
+ | |||
+ | |||
+ | == NEW == |
Текущая версия на 22:35, 22 ноября 2013
- Заголовок
- Операторы языка VHDL
- Автор
- Авдеев Н.А.
- Нижний колонтитул
- ПЦУСБ/Лекция 6
- Дополнительный нижний колонтитул
- Авдеев Н.А., 22:35, 22 ноября 2013
Содержание |
Слайд: Содержание
- типы (type), подтипы (subtype)
- записи (record)
- Разрешающая функция (resolved)
- работа с файлами
- конфигурация
Тестбенч для блока доступа
Структура папок в проекте
- /final_project — Папка проекта. Создаётся переменная среды
$final_project=<путь к папке>/final_project
- /tb — файлы, относящиеся к среде верификации (тестбенчу)
- block1_model.vhd
- block1_pkg.vhd
- block1_tb2.vhd
- block1_TestCtrl.vhd
- /testplan — тестовый план
- /tmp — для логов, временных диаграмм и других временных файлов
- /tst — тесты (входные или выходные)
- /vhd — исходные тексты VHDL-модели тестируемого блока
- block1_beh2_a.vhd
- block1.vhd
- /vsim — скрипты для запуска моделирования в ModelSim/Questa
- compile.tcl — скрипт для компиляции проекта
- sim.tcl — скрипт для запуска моделирования
- wave.do — скрипт для добавления сигналов на временные диаграммы
- /work — папка для хранения библиотек ModelSim/Questa
- /work — библиотека work
- /tb — файлы, относящиеся к среде верификации (тестбенчу)
- modelsim.ini — файл настроек для ModelSim/Questa
Файл настроек modelsim.ini
[Library] final_prj = work/final_prj work = work/final_prj . . . [vcom] ; Value of 1 or 1993 for VHDL-1993. ; Default or value of 2 or 2002 for VHDL-2002. ; Value of 3 or 2008 for VHDL-2008 VHDL93 = 2008 . . . [vsim] ; vopt flow ; Set to turn on automatic optimization of a design. VoptFlow = 0 ; Simulator resolution ; Set to fs, ps, ns, us, ms, or sec with optional prefix of 1, 10, or 100. Resolution = ns ; Default run length RunLength = 100 ; Maximum iterations that can be run without advancing simulation time IterationLimit = 5000
Скрипты для запуска моделирования
Листинг файла compile.tcl
set wlibname final_prj set wlibpath vhd # Create the library. if [file exists work/$wlibname] { # vdel -all } else { vlib work/$wlibname # vmap $wlibname work/$wlibname # Create link "work" on main library # vmap work work/$wlibname } #foreach name [glob "${wlibpath}/*.vhd"] {vcom +cover=bcefsx -work $wlibname $name} vcom +cover=bcefsx -work $wlibname vhd/block1.vhd vcom +cover=bcefsx -work $wlibname vhd/block1_beh2_a.vhd vcom -reportprogress 300 -work $wlibname tb/block1_pkg.vhd vcom -reportprogress 300 -work $wlibname tb/block1_model.vhd vcom -reportprogress 300 -work $wlibname tb/block1_TestCtrl.vhd vcom -reportprogress 300 -work $wlibname tb/block1_tb2.vhd if {[batch_mode]} { quit -f }
Листинг файла sim.tcl
vsim -novopt -coverage work.block1_tb(tb2) do vsim/wave.do run -all
Листинг файла wave.do для вывода временных диаграмм
onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate /block1_tb/SetPassword add wave -noupdate /block1_tb/DigitalKey add wave -noupdate /block1_tb/Esc add wave -noupdate /block1_tb/rst add wave -noupdate /block1_tb/LedOpen add wave -noupdate /block1_tb/Speaker add wave -noupdate /block1_tb/Clk add wave -noupdate /block1_tb/DUT/SetPassword add wave -noupdate /block1_tb/DUT/DigitalKey add wave -noupdate /block1_tb/DUT/Esc add wave -noupdate /block1_tb/DUT/clk add wave -noupdate /block1_tb/DUT/rst add wave -noupdate /block1_tb/DUT/LedOpen add wave -noupdate /block1_tb/DUT/Speaker add wave -noupdate /block1_tb/DUT/count add wave -noupdate /block1_tb/DUT/KeyCode add wave -noupdate -radix hexadecimal /block1_tb/DUT/Password add wave -noupdate -radix hexadecimal /block1_tb/DUT/InputCode add wave -noupdate /block1_tb/DUT/Delay05s add wave -noupdate /block1_tb/DUT/Delay3s add wave -noupdate /block1_tb/DUT/Delay5s add wave -noupdate /block1_tb/block1_model_1/SetPassword add wave -noupdate /block1_tb/block1_model_1/DigitalKey add wave -noupdate /block1_tb/block1_model_1/Esc add wave -noupdate /block1_tb/block1_model_1/clk add wave -noupdate /block1_tb/block1_model_1/rst add wave -noupdate /block1_tb/block1_model_1/LedOpen add wave -noupdate /block1_tb/block1_model_1/Speaker add wave -noupdate /block1_tb/DUT/DigitalPanel add wave -noupdate /block1_tb/block1_TestCtrl_1/Clk add wave -noupdate /block1_tb/DUT/state add wave -noupdate -expand /block1_tb/block1_TestCtrl_1/PortsInRec add wave -noupdate -expand /block1_tb/block1_TestCtrl_1/PortsOutRec TreeUpdate [SetDefaultTree] WaveRestoreCursors {{Cursor 1} {136088 ns} 0} quietly wave cursor active 1 configure wave -namecolwidth 150 configure wave -valuecolwidth 100 configure wave -justifyvalue left configure wave -signalnamewidth 1 configure wave -snapdistance 10 configure wave -datasetprefix 0 configure wave -rowmargin 4 configure wave -childrowmargin 2 configure wave -gridoffset 0 configure wave -gridperiod 1 configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update WaveRestoreZoom {0 ns} {669291 ns}
Структура тестирующей программы
Рисунок - Структурная схема тестбенча |
---|
Листинги файлов тестбенча
Листинг файла block1_tb2.vhd
library ieee; use ieee.std_logic_1164.all; use work.block1_pkg.all; ------------------------------------------------------------------------------- entity block1_tb is end entity block1_tb; ------------------------------------------------------------------------------- architecture tb2 of block1_tb is component block1_model is port ( PortsInRec : in PortsInRecType; PortsOutRec : out PortsOutRecType; SetPassword : out std_logic; DigitalKey : out std_logic_vector(9 downto 0); Esc : out std_logic; clk : out std_logic; rst : out std_logic; -- DigitalPanel : out std_logic_vector(15 downto 0); LedOpen : in std_logic; Speaker : in std_logic); end component block1_model; component block1_TestCtrl is port ( PortsInRec : out PortsInRecType; PortsOutRec : in PortsOutRecType); end component block1_TestCtrl; -- component ports signal SetPassword : std_logic; signal DigitalKey : std_logic_vector(9 downto 0); signal Esc : std_logic; signal rst : std_logic; signal LedOpen : std_logic; signal Speaker : std_logic; signal DigitalPanel : std_logic_vector(15 downto 0); signal Clk : std_logic; signal PortsInRec : PortsInRecType; signal PortsOutRec : PortsOutRecType; begin -- architecture tb -- component instantiation DUT: entity work.block1(beh2) port map ( SetPassword => SetPassword, DigitalKey => DigitalKey, Esc => Esc, clk => clk, rst => rst, DigitalPanel => DigitalPanel, LedOpen => LedOpen, Speaker => Speaker); block1_model_1: block1_model port map ( PortsInRec => PortsInRec, PortsOutRec => PortsOutRec, SetPassword => SetPassword, DigitalKey => DigitalKey, Esc => Esc, clk => clk, rst => rst, LedOpen => LedOpen, Speaker => Speaker); block1_TestCtrl_1: block1_TestCtrl port map ( PortsInRec => PortsInRec, PortsOutRec => PortsOutRec); end architecture tb2;
Листинг файла block1_model.vhd
library ieee; use ieee.std_logic_1164.all; use work.block1_pkg.all; use work.block1_pkg. all; entity block1_model is port ( PortsInRec : In PortsInRecType; PortsOutRec : out PortsOutRecType; SetPassword : out std_logic; DigitalKey : out std_logic_vector(9 downto 0); Esc : out std_logic; clk : out std_logic; -- синхросигнал 25 МГц rst : out std_logic; LedOpen : in std_logic; Speaker : in std_logic ); end entity block1_model; architecture beh of block1_model is begin -- architecture beh SetPassword <= PortsInRec.SetPassword; DigitalKey <= PortsInRec.DigitalKey; Esc <= PortsInRec.Esc; clk <= PortsInRec.clk; rst <= PortsInRec.rst; PortsOutRec.LedOpen <= LedOpen; PortsOutRec.Speaker <= Speaker; end architecture beh;
Листинг файла block1_pkg.vhd
library ieee; use ieee.std_logic_1164.all; package block1_pkg is -- subtype String100 is string(1 to 100); -- FUNCTION resolved ( s : resolved_character ) RETURN character; -- subtype TString is resolved String100; subtype TString is string(1 to 100); type PortsInRecType is record SetPassword : std_logic; DigitalKey : std_logic_vector(9 downto 0); Esc : std_logic; clk : std_logic; rst : std_logic; -- LedOpen : std_logic; -- Speaker : std_logic; Info : TString; end record PortsInRecType; type PortsOutRecType is record LedOpen : std_logic; Speaker : std_logic; end record PortsOutRecType; type KeyType is (D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, Esc, rst, clk, SetPass, SetPassword, Pass, clean); type time_vec is array (1 to 3) of time; procedure Init ( signal PortsRec : out PortsInRecType); procedure SetSignal ( signal PortsRec : out PortsInRecType; SignalName : in KeyType; value : std_logic); procedure PressKey ( signal PortsRec : out PortsInRecType; KeyCode : in KeyType; PressDelay : in time := 50 ns; WaitAfterPress : in time := 50 ns ); procedure EnterPass ( signal PortsInRec : out PortsInRecType; signal PortsOutRec : in PortsOutRecType; Pass : in string(1 to 3) := "000"; PressDelay : in time_vec := (others => 50 ns); WaitAfterPress : in time_vec := (others => 50 ns) ); end package block1_pkg; package body block1_pkg is procedure Init ( signal PortsRec : out PortsInRecType) is begin -- procedure Init PortsRec.SetPassword <= '0'; PortsRec.DigitalKey <= (others => '0'); PortsRec.Esc <= '0'; PortsRec.rst <= '1'; PortsRec.clk <= 'Z'; -- PortsRec.LedOpen <= 'Z'; -- PortsRec.Speaker <= 'Z'; -- PortsRec.Info <= (others => ' '); wait for 21 ns; PortsRec.rst <= '0'; end procedure Init; procedure SetSignal ( signal PortsRec : out PortsInRecType; SignalName : in KeyType; value : std_logic) is begin -- procedure Init case SignalName is when D0 => PortsRec.DigitalKey(0) <= value; when D1 => PortsRec.DigitalKey(1) <= value; when D2 => PortsRec.DigitalKey(2) <= value; when D3 => PortsRec.DigitalKey(3) <= value; when D4 => PortsRec.DigitalKey(4) <= value; when D5 => PortsRec.DigitalKey(5) <= value; when D6 => PortsRec.DigitalKey(6) <= value; when D7 => PortsRec.DigitalKey(7) <= value; when D8 => PortsRec.DigitalKey(8) <= value; when D9 => PortsRec.DigitalKey(9) <= value; when Esc => PortsRec.Esc <= value; when rst => PortsRec.rst <= value; -- when clk => PortsRec.clk <= value; when SetPass|SetPassword|Pass => PortsRec.SetPassword <= value; when clean => PortsRec.SetPassword <= '0'; PortsRec.DigitalKey <= (others => '0'); PortsRec.Esc <= '0'; PortsRec.rst <= '0'; when others => null; end case; end procedure SetSignal; procedure PressKey ( signal PortsRec : out PortsInRecType; KeyCode : in KeyType; PressDelay : in time := 50 ns; WaitAfterPress : in time := 50 ns ) is begin -- procedure Init SetSignal(PortsRec, KeyCode, '1'); wait for PressDelay ; SetSignal(PortsRec, KeyCode, '0'); wait for WaitAfterPress ; end procedure PressKey; function CharToKeyCode (KeyCodeChar : character) return KeyType is variable KeyCode : KeyType := D0; begin case KeyCodeChar is when '0' => KeyCode := D0; when '1' => KeyCode := D1; when '2' => KeyCode := D2; when '3' => KeyCode := D3; when '4' => KeyCode := D4; when '5' => KeyCode := D5; when '6' => KeyCode := D6; when '7' => KeyCode := D7; when '8' => KeyCode := D8; when '9' => KeyCode := D9; when 'E'|'e' => KeyCode := Esc; when 'S'|'s' => KeyCode := SetPassword; when others => null; end case; return KeyCode; end function CharToKeyCode; procedure EnterPass ( signal PortsInRec : out PortsInRecType; signal PortsOutRec : in PortsOutRecType; Pass : in string(1 to 3) := "000"; PressDelay : in time_vec := (others => 50 ns); WaitAfterPress : in time_vec := (others => 50 ns) ) is variable KeyCode : KeyType; begin -- procedure Init -- PortsRec.DigitalKey <= (others => 'Z'); for i in 1 to 3 loop KeyCode := CharToKeyCode(Pass(i)); --PortsInRec.Info <= ( & Pass & " " , others => ' '); PortsInRec.Info <= (Pass & " - ("& pass(i) & ")", others => ' ' ); PressKey(PortsInRec, KeyCode, PressDelay(i), WaitAfterPress(i)); end loop; -- i -- ожидание перехода в start PortsInRec.Info <= ("wait Start", others => ' ' ); wait until (PortsOutRec.LedOpen = '0' and PortsOutRec.LedOpen'event) or (PortsOutRec.Speaker = '0' and PortsOutRec.Speaker'event) for 100000 ns; end procedure EnterPass; end package body block1_pkg;
Листинг файла block1_TestCtrl.vhd
library ieee; use ieee.std_logic_1164.all; use work.block1_pkg.all; entity block1_TestCtrl is port ( PortsInRec : out PortsInRecType; PortsOutRec : in PortsOutRecType ); end entity block1_TestCtrl; architecture Test1 of block1_TestCtrl is signal Clk : std_logic := '1'; begin -- architecture Test1 -- clock generation Clk <= not Clk after 5 ns; PortsInRec.clk <= clk; -- waveform generation WaveGen_Proc: process begin -- insert signal assignments here Init(PortsInRec); --wait for 50 ns; EnterPass(PortsInRec, PortsOutRec, "123"); EnterPass(PortsInRec, PortsOutRec, "000"); EnterPass(PortsInRec, PortsOutRec, "1ee"); EnterPass(PortsInRec, PortsOutRec, "12e"); EnterPass(PortsInRec, PortsOutRec, "123", (others => 100 ns), (others => 100000 ns)); wait for 1000 ns; assert false report "END Simulation" severity failure; wait; end process WaveGen_Proc; end architecture Test1;