Хочу рассказать немного про симуляцию цифровых проектов. Да-да. Тема эта уже поднималась несколько раз, и, конечно – это неисчерпаемая тема. Я уже когда-то писал про симуляцию средствами Quartus II версии 9, но в последней версии Quartus II v10 этого «родного» альтеровского симулятора уже нет. Сказать по правде я расстроился. Для маленьких проектов этого симулятора вполне хватало. Потом я написал статью про симулятор iverilog – это простой open source симулятор – вполне приличная вещь. И вот теперь хочу кратко рассказать о программе ModelSim:
ModelSim – это продукт компании MentorGraphics.
Я буду рассказывать об одной из его версий, а именно ModelSim Altera Starter Edition…
Итак, что нам нужно сделать, чтобы познакомиться с этой программой? Конечно, прежде всего нужно ее выкачать с сайта Альтеры. Зайдем на сайт компании Альтера: https://www.altera.com/products/software/quartus-ii/modelsim/qts-modelsim-index.html
Там увидите таблицу сравнительных характеристик различных версий ModelSim:
- ModelSIm Web Edition – больше не поддерживается компанией Альтера.
- ModelSim Altera Starter Edition — чуть медленне, чем Altera Editon и есть ограничение на размер проекта.
- ModelSim Altera Edition – самая быстрая версия симулятора, без ограничений на размер проекта. Стоимость $945 на сегодня (13 декабря 2010 года).
Мы выбираем Starter Edition — она бесплатна, не требует лицензии, может использоваться на небольших проектах до 10000 строк кода. Я думаю, что нам это с головой хватит. Переходим по ссылке Download. Я выбираю версию для Windows. Размер файла, который нужно загрузить – 586Мб. Это не мало, но и не слишком много по нынешним временам. В общем качаю и устанавливаю..
Теперь запускаем программу ModelSim. Если вы еще не успели выучить английский язык, то сделайте это сейчас (шутка). У программы ModelSim очень хорошая документация, но на английском языке. К счастью мир не без добрых людей. Я очень рекомендую сайт http://www.modelsim.ru – здесь вы найдете очень качественный перевод на русский язык практически всей документации ModelSim. Ну просто море полезной информации!
Я сейчас хочу просимулировать тот же пример, который я уже успешно пробовал симулировать с помощью iverilog. Это два файла counter.v и tcounter.v – они расположены у меня в папке c:altera10.0projectsfirst.
Содержимое этих файлов вот такое:
counter.v — это счетчик с возможностью параллельной загрузки. Если сигнал wr активен в момент фронта clk, то в регистр счетчика будет записано число с входной шины wdata. Иначе значение счетчика будет увеличиваться на единицу каждый фронт clk.
module counter (
input wire reset,
input wire clk,
input wire [7:0]wdata,
input wire wr,
output reg [7:0]data
);
always @ (posedge clk or posedge reset)
if (reset)
data <= 8’h00;
else
if(wr)
data <= wdata;
else
data <= data + 8’h01;
endmodule
А вот это — vcounter.v — «тестбенч» для моего счетчика. Эта программа служит для проверки правильности работы модуля counter.
`timescale 1ns / 100ps
module test_counter;
reg reset, clk, wr;
reg [7:0]wdata;
wire [7:0] data_cnt;
counter counter_inst(reset, clk, wdata, wr, data_cnt);
always
#10 clk = ~clk;
initial
begin
clk = 0;
reset = 0;
wdata = 8’h00;
wr = 1’b0;
#50 reset = 1;
#4 reset = 0;
#50;
@(posedge clk)
#0
begin
wdata = 8’h55;
wr = 1’b1;
end
@(posedge clk)
#0
begin
wdata = 8’h00;
wr = 1’b0;
end
end
initial
begin
#400 $finish;
end
initial
begin
$dumpfile(«out.vcd»);
$dumpvars(0,test_counter);
$dumpvars(0,counter_inst);
end
initial
$monitor($stime,, reset,, clk,,, wdata,, wr,, data_cnt);
endmodule
Вот эти файлы я попробую использовать для демонстрации работы ModelSim.
Приступим!
При запуске программы ModelSim мы видим примерно вот такой экран (кликните на изображение, чтобы увидеть его крупнее):
Первое, что нам нужно сделать — это перейти в рабочую папку. Для этого выбираем пункт меню File/Change Directory…
В открывшемся диалоге указываем путь к нашему проекту:
После выбора папки нужно скомпилировать проект в библиотеку. Выбираем пенкт меню Compile/Compile…
Здесь нужно выбрать все файлы нашего проекта. Диалог позволяет выбирать одновременно несколько файлов.
Выбрали файлы — нажимаем кнопку Compile.
ModelSim спрашивает имя библиотеки, которая будет создана. По умолчанию предлагается имя work, ну вот пусть такое и будет. Отвечаем Yes. После компиляции в окне Transcript проверяйте, нет ли ошибок в исходных файлах.
Обратите внимание, что в окне Library появилась новая библиотека work. так и должно быть. Теперь выбираем пункт меню Simulate/Start Simulation…
После этого откроем для просмотра еще два окна с помощью пунктов меню ViewObjects… и ViewWave…
В окне Objects нужно выбрать интересующие нас сигналы (можно все) и добывить их в окно просмотра формы сигналов Wave.
Вот теперь и посмотрим, что у нас получается в симуляции. Делаем несколько шагов симуляции вперед с помощью пункта меню SimulateRunRun100…
А вот и результат симуляции:
Обратите внимание, что и текстовый вывод в окне Transcript и сами сигналы в окне Wave точно такие же как и в случае симуляции с помощью open source icarus-verilog.
Ну и вот — по форме сигналов мы видим, что наш счетчик работает правильно — так как и задумывалось нами!
Запускаем моделирование в среде ModelSim фирмы Altera, имея готовый проект в Quartus II и модуль теста (testbench).
Инструкция по работе с инструментом ModelSim Altera
1 Указание пути к инструменту симуляции ModelSim
Первым делом нужно удостовериться, что в среде разработки Quartus II указан путь к инструменту ModelSim. Для этого открываем меню Tools Options. В опциях переходим к пункту General EDA Tool options. Находим поле ModelSim-Altera, и впечатываем в него C:altera13.0sp1modelsim_asewin32aloem или, нажав, на кнопку с тремя точками, ищем эту директорию у себя на компьютере.
Естественно, для версии Quartus, отличной от моей, у вас будет свой путь к директории win32aloem.
2Добавление в проект модулей тестов (тестбенчей)
У вас есть проект для ПЛИС в Quartus II. Как писать тесты, или тестбенчи (testbench) – это тема для отдельной статьи. Сейчас же предположим, что ваш тестбенч уже написан. Теперь нужно указать среде разработки, какой тест вы хотите использовать при симулировании. Для этого открываем настройки через меню Assignements Settings…
В открывшемся окне настроек симуляции в поле Tool name выберем ModelSim — Altera, а в поле Format for output netlist выберем тот язык, на котором написан тестбенч. Я использую Verilog.
Теперь в разделе EDA Tool Settings Simulation, нажимаем кнопку Test Benches… Открылось окно редактирования тестов Test Benches. Пока что мы не создали ни одного тестбенча, поэтому список пустой. Нажимаем кнопку New… В открывшемся окне New Test Bench Settings нужно задать настройки теста.
Слева от поля File name нажимаем на кнопку с тремя точками. Выбираем файл с кодом тестбенча и нажимаем Open. Теперь нажимаем кнопку Add. Тест появился в списке тестов.
После этого в поле Top level module in test bench зададим название модуля верхнего уровня, который определён в вашем тестбенче. Имя в поле Test bench name можете вписать любое, по умолчанию оно будет автоматически создано таким же, как имя модуля.
Здесь, кстати, можно задать несколько тестов, и при компиляции проекта переключаться на нужный.
Всё, мы задали основные настройки теста. Нажимаем два раза ОК. Теперь наш тест появился в выпадающем списке тестбенчей. Ещё раз нажимаем ОК.
3Анализ и синтез проекта в Quartus II
Если вы ещё не сделали синтез проекта, то пора это сделать. Выберите в меню Processing Start Start Analysis & Synthesis, или нажмите комбинацию клавиш Ctrl+K, или просто кликните соответствующую иконку в верхней панели.
Синтезатор среды Quartus II сообщит об успешном (или нет) завершении процесса синтеза.
4Запуск симулирования в ModelSim Altera
Можно запускать симулирование. Выбираем в меню Tools Run Simulation Tool RTL Simulation (1) или нажимаем иконку RTL Simulation в верхней панели (2).
Запустится инструмент ModelSim, который выполнит все инструкции, прописанные в вашем тестбенче, и остановится (если вы специально указали это директивой $stop в коде теста). На экране появятся диаграммы уровней входных и выходных сигналов ПЛИС, которые вы описали в вашем проекте.
В окне Transcript (меню View Transcript) отображаются все операции, которые производит ModelSim. Если симулирование завершилось с ошибкой, вы увидите сообщение об этом. Причём, будет указан даже номер строки в коде вашего теста, который вызвал ошибку ModelSim. Эта информация очень полезна для локализации и устранения ошибок.
Время на прочтение
10 мин
Количество просмотров 25K
Меня всегда интересовала цифровая схемотехника, а в частности языки описания аппаратуры — HDL. У меня давно лежала в списке будущего чтения книга Дэвида М. Хэррис и Сары Л. Хэррис «Цифровая схемотехника и архитектура компьютера», воспользовавшись свободным временем на самоизоляции, я добрался до этой замечательной книги. В процессе чтения я столкнулся с некоторыми трудностями, а в частности, как именно писать и отлаживать код в Quartus Prime. В процессе поисков мне очень помог сайт marsohod.org, но вот процесс симуляции схемы на этом сайте описан с использованием встроенных средств Quartus и в современных версиях программы, этих встроенных средств нет и необходимо использовать ModelSim. Чтобы как-то систематизировать те знания, которые я получил, используя Quartus и ModelSim, я решил написать эту статью. В процессе этой статьи я в качестве примера разберу задачу из книги Дэвида М. Хэррис и Сары Л. Хэррис «Цифровая схемотехника и архитектура компьютера», а конкретно задачу 3.26 про автомат газированной воды. На протяжении статьи я покажу, как установить Quartus, создать проект, написать код и произвести его симуляцию. Всем кому это будет интересно, добро пожаловать под кат.

Постановка задачи
Вас уговорили спроектировать автомат с прохладительными напитками для офиса. Расходы на напитки частично покрывает профсоюз, поэтому они стоят всего по 5 рублей. Автомат принимает монеты в 1, 2 и 5 рублей. Как только покупатель внесет необходимую сумму, автомат выдаст напиток и сдаст сдачу. Спроектируйте конечный автомат для автомата с прохладительными напитками. Входами автомата являются 1, 2 и 5 рублей, а именно, какая из этих монет вставлена.
Предположим, что по каждому тактовому сигналу вставляется только одна монета. Автомат имеет выходы: налить газировку, вернуть 1 рубль, вернуть 2 рубля, вернуть 2 по 2 рубля. Как только в автомате набирается 5 рублей (или больше), он выставляет сигнал «НАЛИТЬ ГАЗИРОВКУ», а также сигналы, возврата соответствующей сдачи. Затем автомат должен быть готов опять принимать монеты.
Теория
Конечные автоматы или finite state machine (FSM) относятся к классу синхронных последовательных схем, которые представляют подавляющее большинство схем цифровой схемотехники. Именно таким образом следует реализовывать свои проекты (по крайней мере на первых порах). Такой способ обеспечивает повторяемость и верифицированость схемы и не зависит от отношений задержек различных элементов схемы. Правила построения синхронных последовательных схем гласят, что схема является синхронной последовательной схемой, если ее элементы удовлетворяют следующим условиям:
- Каждый элемент схемы является либо регистром, либо комбинационной схемой.
- Как минимум один элемент схемы является регистром.
- Все регистры тактируются единственным тактовым сигналом.
- В каждом циклическом пути присутствует как минимум один регистр.
Конечный автомат имеет несколько состояний, которое он хранит в регистрах. При поступлении тактового сигнала, конечный автомат может изменять свое состояние, причем как именно изменится состояние зависит от входных сигналов и текущего состояния. В простейшем случае входных сигналов может не быть вовсе, таким образом работает делитель частоты. Существуют два основных класса конечных автоматов: автомат Мура, в котором выходные сигналы зависят только от текущего состояния автомата и автомат Мили, в котором выходные сигналы зависят от текущего состояния и входных сигналов. В принципе любой конечный автомат можно реализовать как по схеме Мура, так и по схеме Мили, отличие между ними будет в том, что у автомата Мура будет больше состояний и он будет отставать на один такт от автомата Мили. Для схемы автомата газированной воды я буду использовать схему Мили. Распишем состояния конечного автомата:
В качестве входного сигнала, будет выступать двухбитная шина, со следующим кодированием номинала монеты:
Нарисуем диаграмму состояний нашего автомата (на диаграммах состояния автомата Мили, необходимо указывать выходные сигналы на стрелках перехода состояния, я этого делать не буду, чтобы не загромождать диаграмму, все выходные сигнала будут расписаны в таблице ниже):
Распишем таблицу изменения состояний и выходных сигналов:
Практика
Установка Quartus Prime
Quartus имеет бесплатную Lite Edition, которая имеет некоторые ограничения по сравнению с профессиональной редакцией, основное ограничение это не более 10000 строк исходного кода для симуляции проекта. Скачать её, после регистрации, можно по ссылке, на момент написания статьи наиболее свежая версия была 19.1, на основе работы с этой версией я писал статью. Выбираем Lite Edition, версия 19.1, операционная система Windows (надо отметить, что существует версия Quartus для Linux и она отлично работает, проблемы возникают с ModelSim, которая 32 битная и использует старую версию библиотеки отображения шрифтов, поэтому на первых порах я рекомендую использовать Windows версию), выбираем вкладку Combined Files. Размер архива для скачки весьма большой — 5.6 Gb, учитывайте это. Разворачиваем скаченный архив и запускаем setup.bat. Установка проходит стандартным образом, используем выбор компонентов по умолчанию.
Создание проекта
Для создания нового проекта выберем File -> New Project Wizard…. Первое окно Wizard’а информационное, жмем Next, на втором окне выбираем где будет располагаться проект, его название «soda_machine» и элемент дизайна верхнего уровня «soda_machine», как на рисунке:
В следующем окне выбираем «Empty project». Окно добавление файлов «Add files», ничего не добавляем. Окно выбора устройства «Family, Devices & Board Settings», для реального проекта очень важное, но так как, наш проект учебный и до реального ему далеко, здесь оставляем настройки по умолчанию, как на рисунке:
Окно выбора настроек других инструментов «EDA Tool Settings», выбираем для симуляции проекта использовать «ModelSim-Altera» и формат «System Verilog HDL» как на рисунке:
Последнее окно информационное «Summary», жмем Finish.
Написание исходного кода
У нас будет два основных файла с исходным кодом, это собственно модуль soda_machine и его test bench, оба эти файла будут использовать тип данных insert_type, который описывает как мы кодируем номиналы монет и его логично выделить в отдельный файл. Но есть некоторые трудности, связанные с особенностями компиляции Quartus и ModelSim. Quartus компилирует все файлы с исходным кодом за один проход, а ModelSim каждый файл компилирует отдельно, для того, что бы при компиляции Quartus’ом не возникало переопределения типа insert_type, я использовал технику из C/C++ include guard, основанную на директивах макропроцессора. Кроме того, что бы ModelSim был уверен что тип insert_type, используемый в модуле soda_machine и в test bench’е, один и тот же, поместил его описание внутри пакета soda_machine_types. С учетом этих требований файл soda_machine_types.sv выглядит следующим образом:
soda_machine_types.sv
`ifndef soda_machine_types_sv_quard
package soda_machine_types;
typedef enum logic [1:0] {I1=2'b01, I2=2'b10, I5=2'b11} insert_type;
endpackage
`define soda_machine_types_sv_quard
`endif
Теперь собственно модуль soda_machine, находится в файле soda_machine.sv:
soda_machine.sv
`include "soda_machine_types.sv"
import soda_machine_types::*;
module soda_machine(
input logic clk, // Clock
input logic reset, // Active high level
input insert_type insert,
output logic pour_water,
output logic change1,
output logic change2,
output logic change22);
typedef enum logic [2:0] {S0, S1, S2, S3, S4} state_type;
(* syn_encoding = "default" *) state_type state, nextstate;
// Логика сброса и хранения состояния конечного автомата
always_ff @(posedge clk, posedge reset)
if (reset)
state <= S0;
else
state <= nextstate;
// Логика вычисления следующего состояния в зависимости от текущего состояния и входных сигналов
always_comb
case (state)
S0:
case (insert)
I1:
nextstate = S1;
I2:
nextstate = S2;
I5:
nextstate = S0;
endcase
S1:
case (insert)
I1:
nextstate = S2;
I2:
nextstate = S3;
I5:
nextstate = S0;
endcase
S2:
case (insert)
I1:
nextstate = S3;
I2:
nextstate = S4;
I5:
nextstate = S0;
endcase
S3:
if (insert == I1)
nextstate = S4;
else
nextstate = S0;
S4:
nextstate = S0;
endcase
// Логика получения выходных сигналов
assign pour_water = (state == S4) | (insert == I5) | (state == S3) & (insert == I2);
assign change1 = (state == S1) & (insert == I5) | (state == S3) & (insert == I5) | (state == S4) & (insert == I2);
assign change2 = (state == S2) & (insert == I5) | (state == S3) & (insert == I5);
assign change22 = (state == S4) & (insert == I5);
endmodule
Каким образом будут производится кодирование состояний конечного автомата, я оставил на усмотрение Quartus. Для того что бы указать, как именно следует производить кодирование, используется атрибут (* syn_encoding = «default» *), другие варианты кодирования можно увидеть здесь.
Необходимо заметить, что в реальном проекте выходные сигналы комбинационной логики автомата Мили, необходимо сохранять в регистрах и уже с выхода регистров подавать на выход ПЛИС. Входные сигналы необходимо синхронизировать с тактовой частотой с помощью синхронизаторов, во избежании попадания в метастабильное состояние.
Для добавления файлов в проект используется File -> New «SystemVerilog HDL File» и при сохранении дать соответствующее имя. После добавления этих двух файлов, проект можно скомпилировать Processing -> Start Compilation. После успешной компиляции можно посмотреть полученную схему Tools -> Netlist Viewers -> RTL Viewer:
RTL Viewer

Для просмотра диаграммы состояний конечного автомата Tools -> Netlist Viewers -> State Machine Viewer
State Machine Viewer

На вкладке Encoding видно, что Quartus применил схему кодирования «one-hot», это когда для каждого состояния используется отдельный D-триггер, причем состояние S0 кодируется 0, а не 1 как для других состояний, делается это для упрощения схемы сброса в начальное состояние. Можно заметить, что RTL Viewer показывает не совсем принципиальную схему, это скорее концепт. Для просмотра принципиальной схемы использовать Tools -> Netlist Viewrs -> Technology Map Viewer (Post-Fitting)
Симуляция
В принципе на текущий момент у нас есть схема автомата по продаже газированной воды, но необходимо убедится, что она работает правильно, для этого напишем test bench и разместим его в файле soda_machine_tb.sv:
soda_machine_tb.sv
`include "soda_machine_types.sv"
import soda_machine_types::*;
module soda_machine_tb;
insert_type insert;
logic [5:0] testvectors[10000:0];
int vectornum, errors;
logic clk, reset, pour_water, change1, change2, change22;
logic pour_water_expected, change1_expected, change2_expected, change22_expected;
// Тестируемый модуль
soda_machine dut(
.clk(clk),
.reset(reset),
.insert(insert),
.pour_water(pour_water),
.change1(change1),
.change2(change2),
.change22(change22)
);
// Эмуляция тактовой частоты
always
#5 clk = ~clk;
// Начальная установка сигналов
initial begin
// Чтение файла с тестовыми векторами
$readmemb("../../soda_machine.tv", testvectors);
vectornum = 0;
errors = 0;
clk = 1;
// Выполним сброс схемы
reset = 1; #13; reset = 0;
end
// Установка тестового воздействия
always @(posedge clk) begin
#1; {insert, pour_water_expected, change1_expected, change2_expected, change22_expected} = testvectors[vectornum];
end
// Проверка, соответствуют ли выходные сигналы нашим ожиданиям
always @(negedge clk)
if (~reset) begin
if ((pour_water !== pour_water_expected) || (change1 !== change1_expected) || (change2 !== change2_expected) ||
(change22 !== change22_expected)) begin
$error("%3d test insert=%bnoutputs pour_water=%b (%b expected), change1=%b (%b expected), change2=%b (%b expected), change22=%b (%b expected)",
vectornum + 1, insert, pour_water, pour_water_expected, change1, change1_expected, change2, change2_expected, change22, change22_expected);
errors = errors + 1;
end
vectornum = vectornum + 1;
if (testvectors[vectornum] === 6'bx) begin
$display("Result: %3d tests completed with %3d errors", vectornum, errors);
$stop;
end
end
endmodule
Для проверки нашего модуля используется файл тестовых векторов soda_machine.tv:
soda_machine.tv
01_0_0_0_0
01_0_0_0_0
01_0_0_0_0
01_0_0_0_0
01_1_0_0_0
10_0_0_0_0
10_0_0_0_0
10_1_1_0_0
11_1_0_0_0
10_0_0_0_0
10_0_0_0_0
11_1_0_0_1
10_0_0_0_0
11_1_0_1_0
01_0_0_0_0
01_0_0_0_0
01_0_0_0_0
11_1_1_1_0
Первые два бита это входной сигнал insert, следующие 4 бита, это наши ожидания выходных сигналов: pour_water, change1, change2, change22. Например в начале файла 5 раз подряд вставляется рублевая монета, на пятой монете, мы ожидаем появления сигнала pour_water, при этом сигналы выдачи сдачи неактивны. Файл soda_machine.tv добавляется в проект File -> New «Text File»
Для удобства работы с ModelSim добавим файл soda_machine_run_simulation.do следующего содержания:
soda_machine_run_simulation.do
add wave /soda_machine_tb/dut/clk
add wave /soda_machine_tb/dut/reset
add wave /soda_machine_tb/dut/insert
add wave /soda_machine_tb/dut/state
add wave /soda_machine_tb/dut/nextstate
add wave /soda_machine_tb/dut/pour_water
add wave /soda_machine_tb/dut/change1
add wave /soda_machine_tb/dut/change2
add wave /soda_machine_tb/dut/change22
view structure
view signals
run -all
wave zoom full
Он запустит нашу симуляцию и выведет графики сигналов в ModelSim. Файл soda_machine_run_simulation.do добавляется в проект File -> New «Tcl script File»
Теперь настроим проект, что бы автоматически запускалась симуляция. Выбираем пункт меню Assignments -> Settings, выбираем категорию EDA Tool Settings -> Simulation. В настройках NativeLink settings выбираем Compile test bench: и нажимаем кнопку Test Benches… в открывшемся окне Test Benches нажимаем кнопку New… В открывшемся окне New Test Bench Settings заполняем поле Test bench name: soda_machine_tb и нажимаем кнопку выбора файла … в нижней части окна, выбираем наш файл soda_machine_tb.sv и нажимаем кнопку Add. Должно получиться как на рисунке:
В окне New Test Bench Settings нажимаем OK. Окно Test Benches должно получить следующий вид:
В окне Test Benches нажимаем OK. В NativeLink settings устанавливаем галочку Use script to set up simulation и выбираем файл soda_machine_run_simulation.do. Окно Settings
должно иметь вид:
В окне Settings нажимаем OK, производим компиляцию проекта Processing -> Start Compilation, производим запуск симуляции Tools -> Run Simulation Tool -> RTL Simulation. Должен запустится ModelSim и произойти симуляция проекта. Внешний вид вкладки Transcript:
ModelSim вкладка Transcript

Красной рамкой выделен вывод нашего test bench’а о количестве выполненных тестов и обнаруженных ошибках. Внешний вид вкладки Wave:
ModelSim вкладка Wave

Исходный код проекта
Исходный код проекта находится в github.com/igoral5/soda_machine Клонировать проект, затем открыть проект при помощи Quartus File -> Open Project…
выбрать файл soda_machine.qpf. Затем скомпилировать проект Processing -> Start Compilation и запустить симуляцию Tools -> Run Simulation Tool -> RTL Simulation.
Начните сейчас, чтобы шаг за шагом приступить к работе с ModelSim и реализовать моделирование, легко подключившись к Quartus. В этой статье используется ModelSim10.0c + QuartusII 10.0, другие версии в основном такие же, пожалуйста, исследуйте сами.
Если вы не видите картинку, нажмите, чтобы увидеть большую картину!
1. Установите сторонний инструмент EDA.
Задайте путь установки ModelSim в Инструменты -> Параметры и обратите внимание на папку win32 (64-битное программное обеспечение соответствует win64).
Создайте проект (все же на примере сумматора). Установите инструмент моделирования на ModelSim в Assignments -> Settings. Таким образом, Quartus может беспрепятственно вызывать ModelSim.
Конечно, вы также можете настроить инструмент моделирования при создании проекта.
2. Написание Testbench
Говоря о Testbench, вы можете называть его Testbench или Testbenches, но неTest Скамья. Кстати, даже Quartus не обратил внимания на эту проблему, о причинах читайте в статье Общие ошибки в технических текстах. В статье также перечислены некоторые другие неправильные слова, в том числе Flip-flop не может быть записан как Flipflop и т. Д. Ссылка на статью:
http://www.sunburst-design.com/papers/Technical_Text_Mistakes.pdf
Мы можем автоматически сгенерировать шаблон Testbench через Quartus, выберите Processing -> Start -> Start TestBench Template Writer, дождитесь завершения и откройте только что сгенерированный тестовый стенд. По умолчанию он сохраняется в моделирование modelsimФайл в формате .vt в папке. Чтобы
После открытия файла vt мы видим, что Quartus выполнил для нас некоторую базовую работу, включая часть кода порта и объявление переменных интерфейса. Что нам нужно сделать, так это добавить тестовый код, который нам нужен, в готовую форму. .
Базовый тестовый стенд состоит из трех частей: определения сигнала, интерфейса модуля и кода функции.
«Шкала времени 1 нс / 1 сек. Означает, что единичное время моделирования составляет 1 нс, а точность — 1 пс. Если вы хотите выполнить моделирование, вы должны сначала указать единицу времени, и лучше указать единицу времени в Testbench, а не определять ее в инженерном коде, потому что разные модули могут вызвать некоторые проблемы при моделировании, если время единица измерения отличается, и сама шкала времени верна. Синтез означает, что реальная схема не имеет никакого эффекта.
Фактически, сам Testbench можно рассматривать как модуль или устройство (имя модуля в этом примере — add_vlg_tst), которое взаимодействует с модулем, который вы пишете. Используйте модуль Testbench, чтобы вывести сигнал на тестируемый модуль в качестве стимула, и в то же время получить выходной сигнал от тестируемого модуля для просмотра результатов. Следовательно, сигнал типа reg в тестируемом модуле становится проводным в Testbench, а сигнал типа провода в тестируемом модуле соответствует типу reg в Testbench. Итак, что делать с inout, сигнал inout должен быть настроен на провод, а сигнал reg должен использоваться в качестве выходного регистра, и должен быть установлен вентиль с тремя состояниями, который управляется сигналом включения, например: назначить inout_sig = out_en? ‘bz;
После обработки интерфейса и объявления вам необходимо самостоятельно установить некоторые сигналы возбуждения.Содержимое сигнала возбуждения — это форма волны, которая будет вводиться в тестируемый модуль. Напишем простую тестовую программу ниже.
Во-первых, нужен сигнал сброса:
initial
begin
rst_n = 0;
#100 rst_n = 1;
end
Процесс в начале начального выполняется только один раз в Testbench. # 100 означает задержку в 100 единиц времени. Мы уже установили его через шкалу времени раньше, и здесь задержка составляет 100 нс. Это немного похоже на язык C, код выполняется последовательно через задержку, rst_n имеет низкий уровень в момент времени 0 (то есть логический 0) и становится высоким после 100 нс, таким образом формируя сброс при включении питания.
Второй — это часы, которые выполняются с помощью модуля always:
initial
begin
mclk = 0;
end
always
begin
#10 mclk = ~mclk;
end
Код в модуле always будет выполняться многократно.Пользуясь преимуществом этой функции, mclk переворачивается каждые 10 нс, но этого недостаточно, и необходимо указать начальное значение для mclk, которое является начальным утверждением выше. Таким образом, прямоугольный сигнал с периодом 20 нс и частотой 50 МГц может быть сгенерирован в качестве системных часов в этом примере.
Конечно, эти часы можно реализовать и через начальный модуль. Просто добавьте while (1) — бесконечный цикл.
initial
begin
mclk = 0;
while(1)
#10 mclk = ~mclk;
end
Многие операции в Testbench не интегрированы, и его стиль может быть более случайным.
После установки часов и сброса необходимо установить входной сигнал:
initial
begin
a_in = 1;
b_in = 3;
#200 a_in = 2;
b_in = 0;
#200 a_in = 3;
b_in = 3;
end
Обратите внимание, что здесь a_in = 1 и b_in = 3 происходят одновременно, то есть параллельно, после чего задержка составляет 200 нс, a_in = 2 и b_in = 0, как упоминалось выше, если вы хотите добиться последовательной работы, вам нужно для использования задержки. Между двумя операторами нет задержки, что означает, что они выполняются одновременно. Другой момент заключается в том, что этот начальный блок операторов и начальный блок операторов, ответственный за сброс, также параллельны, и оба начинаются в момент времени 0. Другими словами, после сброса rst_n 100 нс после 0 времени, а затем после 100 нс (с момента 0) выполняется a_in = 2.
На этом тестовая программа тоже завершена, приступим к моделированию.
3. Настройте Quartus и вызовите инструмент моделирования.
Перед запуском моделирования вам необходимо настроить его. Настройте параметры моделирования на вкладке «Моделирование», вы можете настроить язык моделирования, формат времени моделирования и выходной каталог. Выберите тестовый стенд mpile, нажмите Test Benches, чтобы открыть диалоговое окно Test Benches.
Нажмите New, чтобы создать новый TestBenchSetting, введите имя модуля Testbench (здесь add_vlg_tst) и установите время работы симуляции соответствующим образом (здесь установлено 800 нс, просто время для автоматического выполнения симуляции после входа в ModelSim, а не установить или произвольно установить), и добавить только что написанный Testbench.
После того, как все в порядке, выберите Инструменты -> Запустить инструменты моделирования EDA, есть два варианта, Моделирование RTL — это моделирование поведения RTL, оно только проверяет правильность функции, это не имеет никакого отношения к тому, на каком чипе оно работает. Необходимо выполнить анализ и синтез хотя бы один раз перед симуляцией; имитация на уровне логических элементов — это моделирование на уровне логических элементов, включающее определенные микросхемы, и проект необходимо скомпилировать перед симуляцией. размещение и маршрутизация в форме волны.При тестировании конкретного инженерного модуля вы должны сначала выполнить моделирование RTL, а затем выполнить моделирование на уровне ворот.
4. Основные операции инструмента ModelSim
Запустите RTL Simulation, чтобы войти в интерфейс ModelSim. Вот еще несколько важных частей.
В меню просмотра вы можете отображать и скрывать различные окна инструментов. В окне «Структура» отображается структура тестового модуля и тестируемого модуля:
Щелкните другой модуль, вы можете просмотреть сигналы в выбранном модуле в окне «Объекты», поскольку помимо портов существует множество внутренних сигналов, которые по умолчанию не отображают формы сигналов. Перетаскивая нужный сигнал в окно «Волна», вы может отображать.
На панели инструментов
Если вы чувствуете головокружение при столкновении с большим количеством 0101, вы можете выбрать сигнал в списке сигналов, щелкнуть правой кнопкой мыши и выбрать формат данных для отображения.
В нижнем левом углу окна Wave есть несколько маленьких кнопок, которые используются для установки курсора.Путем добавления курсора вы можете измерить соответствующее время, а также вы можете настроить здесь формат шкалы времени.
На графике осциллограммы вы можете использовать колесо прокрутки и правую кнопку мыши, чтобы легко увеличить или выбрать область сигнала. На рисунке ниже показан график осциллограммы этого полного проекта сумматора. После сброса значение c_out равно сумма a_in и b_in, и отображается в выходном сигнале нарастающего фронта.




























