Icarus Verilog и медианный фильтр
Усредняющий фильтр Verilog
Усредняющий фильтр — один из видов цифровых фильтров, широко используемый в цифровой обработке сигналов и изображений для уменьшения уровня шума. Медианный фильтр является нелинейным КИХ-фильтром. В данном примере мы рассмотрим его упрощённую реализацию и посмотрим насколько корректно она работает, а также выполним генерацию кода из модели и проверим корректность работы сгенерированного кода при помощи icarus verilog, на рисунке ниже показана сама модель реализованного фильтра для окна фильтрации равного 10.
Далее определим функцию запуска модели и проведём тестирование модели и запись результатов её работы.
function run_model( name_model)
Path = (@__DIR__) * "/" * name_model * ".engee"
if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
model = engee.open( name_model ) # Открыть модель
model_output = engee.run( model, verbose=true ); # Запустить модель
else
model = engee.load( Path, force=true ) # Загрузить модель
model_output = engee.run( model, verbose=true ); # Запустить модель
engee.close( name_model, force=true ); # Закрыть модель
end
sleep(0.1)
return model_output
end
Далее запустим данную модель.
run_model("Averaging_filter") # Запуск модели.
out_model = collect(simout["Averaging_filter/filter_out"]).value
count = collect(simout["Averaging_filter/count"]).value
plot(count, label="Вход фильтра")
plot!(out_model, label="Выход фильтра")
Как мы видим модель работает корректно, значения счётчика усредняются.
Генерация кода
Теперь перейдём к генерации кода из блока счётчика и фильтра из полученных модулей в последствии мы будем собирать итоговый проект.
engee.generate_code(
"$(@__DIR__)/Averaging_filter.engee",
"$(@__DIR__)/Averaging_prj",
subsystem_name="cnt"
)
engee.generate_code(
"$(@__DIR__)/Averaging_filter.engee",
"$(@__DIR__)/Averaging_prj",
subsystem_name="Averaging_filter"
)
Icarus Verilog
Далее для тестирования мы реализуем TestBench и запустим его в Icarus Verilog — это свободный (GPL) симулятор Verilog для Linux и других UNIX-подобных систем. Это полнофункциональный компилятор и симулятор языка Verilog HDL (IEEE-1364).
Основное назначение:
- Верификация цифровых схем перед синтезом
- Тестирование и отладка Verilog-кода
Ключевые возможности:
- Компиляция Verilog в исполняемый код (
iverilog
) - Симуляция с помощью виртуальной машины (
vvp
) - Поддержка большей части стандарта Verilog-2005
- Генерация VCD-файлов для анализа в GTKWave
Основные инструменты:
iverilog
— компилятор (преобразует .v файлы в байт-код)vvp
— симулятор (исполняет скомпилированный байт-код)gtkwave
— вьюер временных диаграмм (отдельная программа)
Типичный workflow:
# Компиляция
iverilog -o sim design.v testbench.v
# Симуляция
vvp sim
# Или с генерацией VCD для визуализации
vvp sim -lxt2
gtkwave waveform.vcd
filename = "$(@__DIR__)/Averaging_prj/tb.v"
try
if !isfile(filename)
println("Файл $filename не найден!")
return
end
println("Содержимое файла $filename:")
println("="^50)
content = read(filename, String)
println(content)
println("="^50)
println("Конец файла")
catch e
println("Ошибка при чтении файла: ", e)
end
Этот код представляет собой тестбенч (testbench) на Verilog для тестирования двух модулей: Averaging_filter_cnt
(счетчик) и Averaging_filter_Averaging_filter
(фильтр).
Тестбенч генерирует тактовый сигнал, сбрасывает модули, затем запускает их работу и выводит первые 8 значений выхода фильтра в формате таблицы с преобразованием fixed-point (формат {1,10,2}) в вещественные числа делением на 4, останавливая симуляцию после вывода 8-го значения.
run(`cd $(@__DIR__)/Averaging_prj`)
# Компиляция
run(`iverilog -o sim tb.v Averaging_filter_cnt.v Averaging_filter_Averaging_filter.v`)
# Запуск симуляции
run(`vvp sim`)
# Вывод заголовка таблицы
println("№\tЗначение")
println("--\t-------")
# Вывод только первых 8 значений
for i in 1:8
println("$i\t$(out_model[i])")
end
Как мы можем видеть результаты практически полностью совпали, но проблема в том, что модуль Averaging_filter_Averaging_filter
имеет внутренние регистры (UnitDelay_state и т.д.), которые требуют времени для инициализации и заполнения конвейера. Первые несколько выходных значений могут быть некорректными или нестабильными, пока фильтр не заполнится данными.
Вывод
В данном примере мы разобрали возможности верификации Verilog кода при помощи встроенного симулятора в Engee, такой подход позволяет нам не просто получить код, но и не покидая среду убедиться в его работоспособности.