Илья ТАРАСОВ
Введение
Устоявшейся тенденцией стало увеличение логического объема FPGA с каждым последующим поколением, с одновременным снижением стоимости на единицу программируемых логических ресурсов. При этом выразительные возможности основных языков описания аппаратуры (VHDL, Verilog) остаются на том же уровне, что в результате приводит к увеличению трудоемкости разработки проектов на базе FPGA. Например, если допустимая в некоторой сфере применения стоимость элементной базы остается примерно одинаковой, то появление нового поколения FPGA позволяет использовать ПЛИС большего объема и таким образом привнести в изделие новые функциональные возможности и повышенную производительность. Однако это означает, что для заполнения соответствующей ПЛИС разработчик должен будет реализовать больший объем HDL-описаний, использовать большее количество IP-ядер и затратить больше времени на верификацию проекта. На этом пути эффективным способом повышения производительности труда является использование инструментов разработки системного уровня (system-level design tools), в том числе математических пакетов (например, сочетание MATLAB+Xilinx System Generator for DSP). В этом случае возможна ситуация, когда отдельные составляющие проекта разрабатываются в виде математи-
Инструменты автоматизации процессов моделирования и конфигурирования ПЛИС
в САПР ^Е
Рост логических объемов современных FPGA влечет за собой необходимость более эффективной организации труда разработчиков. Это касается, например, моделирования и верификации проектов путем запуска комплексных тестов, получающих данные от сторонних программ и имеющих встроенные средства контроля правильности своего исполнения. Кроме того, возрастание сложности инструментов проектирования влечет за собой необходимость проверки различных вариантов их настройки для получения наилучших характеристик проекта. В статье рассматриваются подходы к разработке моделей, использующих тестовые последовательности, задаваемые в отдельных файлах, и возможности языка Тс1 для создания текстовых сценариев, автоматизирующих запуск отдельных процессов САПР ^Е с различными настройками для получения оптимальной конфигурации. Сочетание этих приемов проектирования позволяет в конечном итоге добиться большой степени автоматизации работы с САПР ^Е.
ческих моделей разной степени сложности, параметры которых затем используются для настройки IP-ядер.
В качестве примера можно рассмотреть систему цифровой обработки данных, получаемых с АЦП или из сети. Цифровая часть может быть смоделирована с помощью таких средств, как ModelSim или ISim, однако в этом случае входной поток данных должен быть задан отдельно. Вероятно, что его можно будет получить с помощью отдельного программного продукта, в котором выполнялось моделирование объекта — источника данных. Соответственно, возникает вопрос, можно ли обеспечить удобную интеграцию этих инструментов, чтобы результаты моделирования потока данных могли быть автоматически использованы в качестве тестовой последовательности для ПЛИС. Далее в статье будут рассмотрены возможности библиотеки textio для написания тестов на языке VHDL, использующих загрузку тестовых последовательностей из файлов, которые могут быть созданы сторонними программами.
Схожую цель преследует разработчик, используя второй аспект создаваемых им сценариев. В данном случае будут рассмотрены возможности языка программирования Tool Command Language (Tcl), который включен в состав САПР ISE и достаточно широко распространен среди программных продуктов в качестве языка обработки сценариев. Его возможности, расширенные стандартными
сценариями, добавленными в САПР ISE, позволяют автоматизировать процесс проверки характеристик разрабатываемого проекта при смене настроек средств синтеза и трассировки, смены семейства ПЛИС и градации скорости и т. п. Это освобождает разработчика от необходимости производить подобные настройки вручную, что не только ускоряет процесс проверки разных вариантов реализации проекта, но и освобождает от ошибок, связанных с невнимательностью при смене настроек или случайным пропуском варианта, который мог дать оптимальное решение. Можно также представить, что 7-9 вариантов настроек средств синтеза и трассировки (цифры приведены для инструментов Smart XPlorer и PlanAhead и являются минимальными), реализуемых для 2-3 семейств FPGA, в каждом из которых можно также проверить несколько градаций скорости, для разработчика изначально выглядят как длительная рутинная работа. Тем не менее вполне может оказаться, что какой-то проект вполне может быть реализован на более дешевом варианте FPGA, при определенном сочетании настроек средств синтеза и трассировки.
Анонс FPGA 7-й серии, состоявшийся в середине 2010 года, несколько усугубил эту проблему. Можно представить, что с началом поставок 28-нм FPGA на рынке будут присутствовать одновременно и существующие ПЛИС Virtex-6/Spartan-6, и новые семейства Artix-7/Kintex-7/Virtex-7. Насколько оправ-
данным будет переход к новой элементной базе с точки зрения улучшения характеристик проектируемых устройств? Ответ на этот вопрос можно будет дать только после проведения многократных запусков процессов синтеза и трассировки с различными вариантами элементной базы.
Последовательный запуск отдельных процессов синтеза и трассировки с изменением их настроек может быть организован с помощью сценариев на языке Tcl. Автоматизация перебора параметров проекта, в том числе смена микросхемы, позволит ускорить процесс проверки характеристик проекта, реализуемого с помощью различных семейств FPGA.
Параметризуемые описания синтезируемых конструкций
Одним из способов эффективного использования выразительных возможностей языков описания аппаратуры является разработка параметризуемых модулей. Рассмотрим код на VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity reg_any is
generic (DATA_WIDTH : integer := 8);
Port (clk : in STD_LOGIC;
d : in STD_LOGIC_VECTOR(DATA_WIDTH - 1 downto 0); q : out STD_LOGIC_VECTOR(DATA_WIDTH - 1 downto 0)); end reg_any;
architecture Behavioral of reg_any is begin
process(clk)
begin
if clk’event and clk = ‘1’ then
q <= d;
end if; end process; end Behavioral;
В этом примере реализуется регистр, разрядность которого можно настраивать с помощью параметра DATA_WIDTH, определенного в разделе generic. При синтезе такого модуля значение, присвоенное этому параметру, будет подставлено в местах его упоминания. Можно заметить, что везде, где требуется указать разрядность сигналов, используется именно мнемоническое обозначение параметра, а не его конкретное значение. Аналогичного эффекта можно добиться в языке Verilog:
'define DATA_WIDTH 8 module reg8( input clk,
input ['DATA_WIDTH - 1:0] d, output reg ['DATA_WIDTH - 1:0] q);
always @ (posedge clk) q <= d; endmodule
При необходимости использования в проекте нескольких модулей с различным значением параметра, описанного как generic, можно временно переопределить это значение. Например:
component1 : my_component generic map (
DATA_WIDTH => 16 );
component2 : my_component generic map (
DATA_WIDTH => 32 );
В этом примере в проект устанавливаются два компонента типа my_component. Однако для каждого экземпляра такого компонента устанавливается собственное значение параметра DATA_WIDTH.
Для сложных проектов, состоящих из большого количества синтезируемых модулей, рекомендуется группировать параметры в отдельных файлах. Для VHDL это может быть файл особого типа — VHDL package, язык Verilog не предусматривает специального типа модуля, а размещение настроек можно выполнить в обычном файле, подключаемом директивой 'include:
'include <«имя файла»>
Использование этой директивы равносильно вставке текста из упоминаемого файла непосредственно в месте расположения директивы. Имя файла при этом задается в двойных кавычках, файл должен быть доступен из рабочего каталога в соответствии с общими правилами для данной ОС (то есть файл, в котором упоминается директива, должен находиться в том же каталоге, или путь к подключаемому файлу должен быть указан явно). Использование 'include схоже с применением аналогичной директивы в языке Си, а подключаемые таким образом файлы Verilog можно сопоставить с заголовочными файлами Си (header files), в которых обычно размещаются константы, задачи и функции общего пользования. На имя подключаемого таким образом файла не накладывается специальных ограничений.
Приведем структуру пакета VHDL:
package MY_PACK is constant ... function ... component ... alias... type ...
end package MY_PACK;
Пакет подключается к модулям с помощью строки вида:
use work.MY_PACK.all;
При необходимости подключить конкретные элементы, описанные в пакете, вместо идентификатора all используется имя этого элемента. Например, если в пакете определена константа DATAWIDTH, подключить только ее можно следующим образом:
use work.MY_PACK.DATAWIDTH;
Эта возможность полезна, если в пакете есть множество объявлений, которые по каким-либо соображениям нежелательно помещать в область видимости VHDL-модуля.
Для повышения переносимости и масштабируемости модулей также могут быть полезны атрибуты. Они позволяют обращаться к отдельным характеристикам сигналов композитного типа. Например, если определить сигнал a: std_logic_vector (7 downto 0), то следующие атрибуты дадут такие результаты:
a’left - 7 a’right - 0 a’low - 0 a’high - 7
a’range - 7 downto 0 a’length - 8 a’ascending - FALSE a’reverse_range - 0 to 7.
Атрибуты left/right и high/low дают в приведенном примере одинаковые результаты. Разница состоит в том, что left и right возвращают значения, указанные в левой и правой частях объявления размера (7 downto 0), а high и low вернут наибольший и наименьший индекс, независимо от того, находится он слева (например, в выражении 7 downto 0) или справа (при записи в виде 0 to 7).
Атрибуты range и reverse_range возвращают интервал изменения индексов в порядке объявления (range) или в обратном порядке (reverse_range).
Атрибут ascending возвращает логическое выражение, равное ИСТИНЕ, если интервал композитного типа объявлен в порядке возрастания индексов (то есть 0 to 7). В приведенном примере этот атрибут вернет ЛОЖЬ, поскольку использовано объявление с ключевым словом downto.
Приведенные выше атрибуты являются предопределенными. В синтезаторе XST можно также использовать атрибуты, определенные пользователем или добавленные Xilinx при адаптации языка VHDL для проектирования ПЛИС. Например, следующая строка укажет синтезатору, что для блока RAM1 следует использовать реализацию в виде блочной памяти:
attribute RAM_STYLE of RAM1: entity is “BLOCK”;
Такая запись предоставляет разработчику важное преимущество: правила трансляции текстов на HDL перестают зависеть от текущих настроек САПР, таким образом, результаты становятся более предсказуемыми. Подробный список атрибутов и правила их использования приведены в справочной системе САПР ISE.
Параметризация широко распространена для IP-ядер, которые также являются эффективным способом существенно повысить производительность труда разработчика.
Файл верхнего уровня
Пакет VHDL/ файл с настройками Verilog
elk univ
cl k_______in
clk_in clk_out
clk_2x
elk div2
Рис. 1. Структура проекта для ПЛИС, ориентированного на использование параметризуемых модулей и ^-ядер
Проект, составленный в основном из 1Р-ядер, соединенных и настроенных на верхнем уровне иерархии, с большой степенью вероятности будет иметь хорошие характеристики производительности (поскольку 1Р-ядра, как правило, выполняются с тщательной привязкой к топологии ПЛИС), а основная работа разработчика сведется к установке параметров уже имеющихся модулей, а не к их проектированию «с чистого листа».
Структура проекта с высокой долей повторного использования кода показана на рис. 1. В представленном примере файл верхнего уровня содержит в основном структурные описания — порядок подключения и соединения модулей. Требуемые для настройки модуля и 1Р-ядер параметры сгруппированы в пакете VHDL (или отдельном файле Verilog), а основные функции реализованы в библиотечных 1Р-ядрах или отдельных параметризуемых модулях, разработанных специально для этого проекта.
В приведенном ниже листинге показан пример описания тактового генератора (рис. 2), который может быть реализован в различных семействах FPGA. После задания параметра
FPGA_FAMILY модуль выбирает такой компонент генератора, который соответствует выбранному семейству ПЛИС. Параметр может быть вынесен в глобальный файл типа VHDL package, где он может быть прочитан и другими перенастраиваемыми модулями проекта. Для условной генерации используется конструкция if... generate. В листинге показан пример только для одного семейства ПЛИС:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.aH;
entity clk_univ is
generic (FPGA_FAMILY : string := “Spartan-3”);
-- Spartan-3 Spartan-3E Spartan-3A Spartan-3ADSP Spartan-6 -- Virtex-4 Virtex-5 Virtex-6 Port ( clk_in : in STD_LOGIC; clk_out : out STD_LOGIC; clk_2x : out STD_LOGIC; clk_div2 : out STD_LOGIC); end clk_univ;
architecture Behavioral of clk_univ is signal clk0, clk_fb, clk_fbout : std_logic; begin
Рис. 3. Расположение шаблонов тактовых генераторов в библиотеке компонентов
Рис. 2. Графическое изображение параметризуемого тактового генератора
sp3: if FPGA_FAMILY = “Spartan-3” generate begin
DCM_inst : DCM generic map (
CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5, 5.0,5.5,6.0,6.5
-- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 CLKFX_MULTIPLY => 4, -- Can be any integer from 1 to 32 CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature
CLKIN_PERIOD => 20.0, -- Specify period of input clock CLKOUT_PHASE_SHIFT => “NONE”, -- Specify phase shift of NONE, FIXED or VARIABLE
CLK_FEEDBACK => “1X”, -- Specify clock feedback of NONE, 1X or 2X
DESKEW_ADJUST => “SYSTEM_SYNCHRONOUS”, --SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or -- an integer from 0 to 15 DFS_FREQUENCY_MODE => “LOW”, -- HIGH or LOW frequency mode for frequency synthesis
DLL_FREQUENCY_MODE => “LOW”, -- HIGH or LOW frequency mode for DLL
DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE
FACTORY_JF => X”C080”, -- FACTORY JF Values PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255
to 255
SIM_MODE => “SAFE”, -- Simulation: “SAFE” vs “FAST”, see “Synthesis and Simulation
-- Design Guide” for details STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE port map (
CLK0 => clk0, -- 0 degree DCM CLK ouptput
CLK180 => open, -- 180 degree DCM CLK output
CLK270 => open, -- 270 degree DCM CLK output
CLK2X => clk_2x, -- 2X DCM CLK output
CLK2X180 => open, -- 2X, 180 degree DCM CLK out
CLK90 => open, -- 90 degree DCM CLK output
CLKDV => dk_div2, -- Divided DCM CLK out (CLKDV_DIVIDE)
CLKFX => open, -- DCM CLK synthesis out (M/D)
CLKFX180 => open, -- 180 degree CLK synthesis out
LOCKED => open, -- DCM LOCK status output
PSDONE => open, -- Dynamic phase adjust done output
STATUS => open, -- 8-bit DCM status bits output
CLKFB => clk_fb, -- DCM clock feedback
CLKIN => clk_in, -- Clock input (from IBUFG, BUFG or DCM)
PSCLK => ‘0’, -- Dynamic phase adjust clock input
PSEN => ‘0’, -- Dynamic phase adjust enable input
PSINCDEC => ‘0’, -- Dynamic phase adjust increment/decrement
RST => ‘0’ -- DCM asynchronous reset input
);
BUFG_inst : BUFG port map (
0 => clk_fb, -- Clock buffer output
1 => clk0 -- Clock buffer input
);
end generate;
sp3a: if FPGA_FAMILY = “Spartan-3E” or FPGA_FAMILY = “Spartan-3A”
or FPGA_FAMILY = “Spartan-3ADSP” generate
begin
DCM_SP_inst : DCM_SP
BUFG_inst : BUFG port map (
0 => clk_fb, -- Clock buffer output
1 => clk0 -- Clock buffer input );
end generate; clk_out <= clk0; end Behavioral;
В модуле использованы шаблоны тактовых генераторов, предлагаемых в ISE для подклю-
чения аппаратных модулей DCM. Шаблоны можно скопировать из справочной системы, встроенной в ISE, как показано на рис. 3.
Самотестирующиеся модели
Использованный термин «самотестирующиеся модели» относится к моделям, в которые добавлены операторы верификации ключевых состояний и диагностические сообщения, помогающие определить суть возникшей проблемы. Несмотря на то, что программы моделирования предоставляют удобные возможности для построения и изучения временных диаграмм сигналов, для сложного проекта не стоит надеяться на полноту и надежность визуальной верификации. Можно говорить о том, что разработчик способен идентифицировать отдельные проблемы, рассматривая временные диаграммы, но следует признать, что способности человека к анализу потока графической информации имеют естественные ограничения. С другой стороны, процесс моделирования, выходом которого и являются диаграммы, может включать в себя и автоматическую проверку требуемых условий, представляемых в текстовом виде. Для этого используется оператор assert в VHDL:
Оператор assert задает логическое выражение, которое должно выполняться для успешного прохождения проверки. В противном случае будет выведено сообщение, указанное после ключевого слова report. После слова severity указывается уровень значимости ошибки, который может принимать следующие значения:
• note — информационное сообщение, невыполнение условия не является ошибкой, служит для формирования сообщений пользователю;
• warning — предупреждение, выполнение теста продолжается, наличие сообщений такого уровня не является признаком неудачного выполнения теста в целом;
• error — ошибка, выполнение теста продолжается, но наличие хотя бы одной ошибки свидетельствует о неудачном прохождении теста;
• failure — сбой, выполнение немедленно прекращается.
Добавив в тест соответствующее количество операторов assert, можно обеспечить подробную диагностику возникшей аварийной ситуации.
В качестве примера можно привести простейший модуль, представляющий собой логический вентиль 2И. Внесем в этот вентиль задержку распространения сигнала в 5 нс. Необходимо сразу заметить, что эта задержка является искусственной, то есть не соот-
ветствует реальным параметрам какой-либо ПЛИС. Действительные значения задержек могут быть получены только после выполнения трассировки проекта. Однако для демонстрационных целей можно использовать и представленный пример:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity simple_gate is
Port ( a : in STD_LOGIC; b : in STD_LOGIC; c : out STD_LOGIC); end simple_gate;
architecture Behavioral of simple_gate is begin
c <= a and b after 5 ns; end Behavioral;
Тест для такого модуля имеет следующий вид:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY simple_tb IS END simple_tb;
ARCHITECTURE behavior OF simple_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT simple_gate PORT( a : IN std_logic; b : IN std_logic; c : OUT std_logic );
END COMPONENT;
--Inputs
signal a : std_logic := ‘0’; signal b : std_logic := ‘0’;
--Outputs signal c : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT) uut: simple_gate PORT MAP ( a => a, b => b, c => c
);
-- Stimulus process stim_proc: process begin a <= ‘1’; b <= ‘1’; wait for 4 ns;
assert c = ‘1’ report “Output does not goes HIGH. You may not achieve desired performance. “ severity warning; wait for 2 ns;
assert c = ‘1’ report “Output does not goes HIGH. This is a serious error. “ severity error;
wait for 100 ns; wait; end process;
END;
Тестирование вентиля заключается в следующем. После установки входных сигналов в высокий логический уровень тестовый модуль ожидает 4 нс, имитируя интервал времени, который, как мы предполагаем, нормален для высокопроизводительной системы. Отсутствие выходного сигнала через это время еще не является признаком неработоспособности (поскольку сигнал может просто не успеть распространиться), однако слу-
жит предупреждением о том, что выбранная ПЛИС не сможет обеспечить требуемые характеристики производительности. В этом случае можно перейти к ПЛИС, имеющей большее быстродействие, или ослабить требования по производительности, поэтому данную ситуацию можно трактовать как предупреждение (warning). Однако в течение последующих 2 нс выходной сигнал должен обязательно перейти в состояние логической единицы, поскольку в противном случае исполнение проекта бесполезно (задержки слишком велики). Можно установить заведомо большой интервал времени, в течение которого можно ожидать срабатывания любых компонентов на кристалле FPGA. В этом случае отсутствие требуемого выходного сигнала однозначно будет свидетельствовать о нарушении логики работы проектируемой схемы.
В соответствии с нашими предположениями в консоли программы моделирования будет выведено сообщение:
at 4 ns, Instance /simple_tb/ : Warning: Output does not goes HIGH.
You may not achieve desired performance.
Увеличим задержку в основном модуле до 100 нс, что является заведомо завышенной величиной. Таким способом имитируется ситуация, когда в проверяемом модуле имеется логическая ошибка и ожидаемое значение логической единицы никогда не появится. В этом случае программа моделирования выведет следующее:
at 4 ns, Instance /simple_tb/ : Warning: Output does not goes HIGH.
You may not achieve desired performance.
at 6 ns: Error: Output does not goes HIGH. This is a serious error.
Вместо искусственной задержки вида after 5 ns можно провести трассировку проекта и запустить процесс Simulate Post-Route Model. В этом случае программа моделирования покажет реальные задержки для выбранного кристалла с учетом размещения и трассировки компонентов.
Описанный выше порядок действий служит иллюстрацией возможностей языков описания аппаратуры при выполнении всестороннего моделирования. При практической работе желательно использовать синхронный стиль проектирования в сочетании с заданием проектных ограничений. В этом случае указание требуемого периода тактового сигнала приведет к автоматической проверке задержек между всеми компонентами, тактируемыми этим сигналом, и индивидуальная проверка отдельных цепей уже не потребуется. Также при проектировании рекомендуется сочетать моделирование на поведенческом уровне для регулярной проверки логики работы устройства и моделирование на физическом (Post-Route) уровне для финального тестирования проекта.
Таким образом, при достаточно подробном описании возможного поведения
assert SUM_EXPECTED = SUM_OUT report “ERROR: output SUM is incorrect” severity warning;
ПЛИС оказывается возможным провести глубокую диагностику возникающих проблем. Тестовые программы, разработанные с учетом описанных выше требований, дадут разработчику достаточно информации для идентификации проблемы и быстрого принятия правильного решения.
Моделирование при помощи текстовых файлов в VHDL и Verilog
При комплексном тестировании проектов в ПЛИС может потребоваться интеграция со сторонними средствами разработки. Например, при разработке устройств цифровой обработки сигналов часто используются такие средства проектирования, как MATLAB или C++, с помощью которых производится математическое моделирование процессов обработки сигналов заданного вида. После проверки правильности алгоритма с помощью MATLAB/C++ требуется максимально адекватное воспроизведение полученного результата в модели на HDL, для чего желательно было бы выполнить передачу в HDL-модель входного сигнала, предназначенного для обработки. Можно представить, что задавать несколько тысяч входных отсчетов с помощью оператора <= ... after непроизводительно. Однако VHDL и Verilog позволяют использовать текстовый ввод из файлов, что показано в следующем листинге для VHDL, моделирующем поступление входного потока данных с АЦП, тактируемых сигналом adc_clk.
В заголовке модели следует подключить библиотеку textio:
Тогда можно использовать такой процесс:
В представленном листинге объявляется специальная переменная файлового типа с именем т^1е. Этот файл открывается для чтения командой file_open. Параметрами этой команды являются идентификатор файла, имя файла, которое должно быть связано с этим идентификатором, и режим доступа (в данном случае КБАО_МОВЕ). Затем формируется цикл, срабатывающий по каждому фронту тактового сигнала adc_clk. В этом цикле проверяется условие достижения кон-
ца файла infile, и если в нем еще есть данные для чтения, выполняется чтение очередной строки командой readline. Впоследствии с прочитанной текстовой строкой можно выполнить несколько операций чтения данных. В приведенном примере читается только одно число с помощью команды read. Обратите внимание, что readline читает строку из файла, а read — переменную a_input_str из ранее прочитанной строки (то есть ее параметром является file_line — очередная строка, прочитанная из файла). После этого сигналу adc можно присвоить значение a_input_str.
Таким образом, имея текстовый файл, в каждой строке которого записано одно число, можно смоделировать процесс задания входных значений, поступающих с АЦП или иного источника данных. Возможности VHDL с точки зрения выполнения файловых операций делают такую работу достаточно удобной: например, не требуется задавать количество читаемых данных, поскольку можно организовать чтение до конца файла.
В языке Verilog набор моделирующих конструкций несколько отличается.
Команда $display имеет вид в соответствии с примером:
$display (“Во время %d сигнал а равен %b”, $time, a)
При этом в отчет выводится указанное в кавычках текстовое сообщение в соответствии с заданными форматными модификаторами. В примере это %d и %b, которые задают, соответственно, вывод числа в десятичном и двоичном виде. Приведенное далее выражение $time соответствует времени модели, а переменная a указана в качестве примера. Кроме $time, можно использовать команду $realtime.
В процессе исполнения в отчете (консоли вывода средств моделирования) будет сформирована строка вида «Во время 5 сигнал a равен 1».
Команда $write аналогична $display, однако не выполняет перевод строки после завершения.
Команда $strobe также аналогична $display, но выводит сообщения по завершении текущего цикла моделирования.
Наконец, $monitor является еще одним аналогом $display, но с этой командой связаны также $monitoroff и $monitoron, которые, соответственно, выключают и включают вывод отчетов с помощью $monitor. Таким образом, с помощью этой команды можно задавать более подробные сообщения о состоянии модели, которые могут включаться по мере необходимости и выключаться, когда их постоянный вывод перегружает отчет о моделировании.
Возможен вывод сообщений в текстовый файл, задаваемый пользователем. Для этого предназначены команды $fdisplay, $fmonitor, $fstrobe, $fwrite.
Форматные модификаторы для приведенных выше команд показаны в таблице.
Таблица. Форматные модификаторы в языке Verilog
Название Действие
%h, %H Шестнадцатеричный формат
%b, %B Двоичный формат
%d, %D Десятичный формат
%s, %S Текстовая строка
%c, %C Символ ASCII
%t, %T Время
%o, %O Восьмеричный формат
%v, %V Сила сигнала (power/strong/weak и т. п.)
%e, %E Вещественное число в инженерном формате
%f, %F Вещественное число в обычном формате
%m, %M Иерархическое имя
Форматный модификатор 0М отличается от тем, что выводит время в единицах, основанных на директиве 'timescale. Формат вывода может также быть задан командой вида $timeformat (-9,3, “ns”, 8). Здесь -9 означает десятичный порядок единицы измерения времени (в данном случае 10-9 означает наносекунду), 3 определяет число знаков, выводимых после десятичной точки, далее следует строка, которую необходимо вывести после значения времени, и наконец, 8 задает минимальное количество символов для вывода.
Команда $stop приостанавливает моделирование и возвращает управление оператору. В это время можно, например, изменить значения входных сигналов и возобновить процесс моделирования.
Команда $finish завершает моделирование, закрывая все открытые файлы.
При создании моделей на Verilog также можно использовать файловые операции — заполнение массивов из текстовых файлов, открытие, создание, чтение и запись.
Команды $readmemh и $readmemb заполняют массив памяти из текстового файла, данные в котором представлены в шестнадцатеричном ($readmemh) или двоичном ($readmemb) форматах. Например, если объявлен массив reg [7:0] аггау1 [0:1023] и имеется файл array1_data.txt, в котором размещены строки вида:
0000
1234
FA45
то можно заполнить массив значениями из файла с помощью вызова:
$readmemh(“array1_data.txt”, аггау1);
Каждая строка соответствует одной ячейке массива памяти.
При использовании команды $readmemb в файле должны быть размещены двоичные значения.
Команда $fopen возвращает целочисленный индекс открытого файла. Этот индекс можно будет впоследствии указать в каче-
use IEEE.std_logic_textio.all; use STD.textio.all;
read_input: process file infile: text; variable file_line: line; variable a_input_str: integer; begin
file_open(infile, “infile.txt”, READ_MODE);
wait until rising_edge(adc_clk); while not endfile(infile) loop readline (infile, file_line); read(file_line, a_input_str);
adc <= conv_std_logic_vector(a_input_str, 12); wait until fa11ing_edge(ad.c_c1k); end loop; file_close(infile); wait;
end process;
стве аргумента одной из команд $fdisplay, $fmonitor, $fwrite, $fstrobe. Например:
integer hLog;
initial
begin
hLog = $fopen(“file1.log”, “w”);
$fdisplay ( hLog, “Текстовое сообщение, выводимое в файл”);
$fclose(hLog);
Команда $fclose, соответственно, закрывает ранее открытый файл.
Сценарии управления работой САПР ПЛИС
С помощью скриптового языка Tcl, устанавливаемого вместе с САПР ISE, можно составить исчерпывающий сценарий запуска процессов с различными настройками, включающими, пожалуй, все аспекты разработки — смену типа ПЛИС, ее корпуса и класса быстродействия, изменение тех или иных настроек синтеза и трассировки и т. д.
В САПР ISE получить сценарий для текущего проекта можно с помощью пункта меню Project^ Generate TCL script... Если выбрать свойство All properties with complete script, в выходном файле окажутся все текущие настройки САПР, включая процессы синтеза, трассировки и программирования. Запуск такого сценария из командной строки (xtclsh.exe <имя файла сценария>) приведет к точному воспроизведению всех настроек САПР.
Генерируемый сценарий при запуске запрашивает код действия, которое необходимо выполнить. Однако такое поведение текстового сценария не всегда удобно для пользователя, поскольку от командного файла естественно ожидать непрерывной работы с получением результата без дополнительных запросов. Рассмотрим модификацию сценария tcl, который после запуска проводит все процессы трансляции проекта с получением конфигурационного файла:
set myProject “my_project.ise” set myScript “script.tcl” proc main {} {
global myScript global myProject
puts “\n$myScript: running ($myProject)...\n” if { [ file exists “my_project.ise”] } { file delete “my_project.ise”
}
project new my_project puts “$myScript: Setting project properties... ” project clean
project set family “Spartan3E”
project set device “xc3s500e”
project set package “fg320”
project set speed “-4”
project set top_level_module_type “HDL”
project set synthesis_tool “XST (VHDL/Verilog)”
project set simulator “ISE Simulator (VHDL/Verilog)”
puts “$myScript: Adding sources to project...”
xfile add top_level.vhd
xfile add <file1.vhd>
xfile add <file2.vhd>
xfile add <file.ucf>
project set top Behavioral top_level
puts “$myScript: project sources reloaded.”
puts “Running Synthesis”
process run “Synthesize”
process run “Translate”
process run “Map”
process run “Place & Route”
process run “Generate Programming File”
}
main
Сценарий использует добавленные в tcl команды, позволяющие управлять процессами в САПР ISE. Например, команда project new <имя> создает новый проект с заданным именем. Затем команда project clean удаляет промежуточные файлы, которые, возможно, находятся в папке проекта в результате выполнения предыдущих итераций. Группа команд project set позволяет устанавливать значения различных свойств проекта, таких как семейство, наименование, корпус и класс скорости ПЛИС, значения свойств процессов и т. п. Список свойств, подлежащих установке, и их возможных значений, а также перечень доступных команд tcl приведены в документе Development System Reference Guide. После установки свойств САПР можно добавить файлы к проекту с помощью команд xfile add. Добавляются как файлы VHDL/Verilog, так и файлы проектных
ограничений (ucf). После этого можно запустить основные процессы:
process run “Synthesize”
process run “Translate”
process run “Map”
process run “Place & Route”
process run “Generate Programming File”
Таким образом, с помощью сценария на языке tcl можно организовать проект так, чтобы его трансляция осуществлялась запуском единственного командного файла, при сохранении всех требуемых настроек. Более того, имея несколько модификаций сценария, можно оперативно сравнивать результаты, получаемые для различных семейств ПЛИС, градаций скорости, установок синтеза и трассировки.
Язык tcl используется для связывания отдельных процессов в САПР ISE. Кроме того, приложение PlanAhead организует с помощью сценариев tcl поиск оптимального сочетания настроек синтеза и трассировки, что можно реализовать и самостоятельно.
Заключение
Рассмотренные в статье материалы дают основные сведения о способах автоматизации процессов трансляции проекта на базе ПЛИС и его верификации. Переносимые между семействами синтезируемые модули, а также модели, выполняющие диагностику проекта и сценарии управления работой САПР, позволяют автоматизировать выполнение рутинных операций по сборке большого проекта на базе ПЛИС. Это становится особенно актуально с увеличением логической емкости современных семейств и при регулярной смене поколений FPGA (включая и состоявшийся анонс FPGA Xilinx «серии 7»). Трансляция и верификация проекта «одной командой» в подобной ситуации может оказаться существенным подспорьем для разработчика, что повышает производительность его труда и облегчает отладку и верификацию проекта. ■