Как дождаться завершения моделирования Modelsim перед продолжением сценария TCL

Я пытаюсь выполнить регрессионный тест в Modelsim. Я вызываю сценарий TCL, который компилирует мои исходные файлы и запускает vsim. Я запускаю файл .do, и он запускает серию тестовых стендов, которые все выводят файлы результатов. Я добавляю автоматическую программу проверки, которая проверяет соответствие файлов результатов заведомо удачным запускам. Проблема в том, что после запуска modelsim скрипт TCL не дожидается завершения симуляции перед запуском чекера «results_pass.py».

set nice_pid [open "|$modelsim_dir/vsim.exe -do do_files/vsim.do -novopt -gui"]
cd ../../Scripts
set script_name "results_pass.py"
set tb_name "rcp"
call_python $script_name $tb_name
vwait forever

Для тех, кто задается вопросом, почему я вызываю скрипт Python. В основном потому, что я очень мало знаю TCL, но у меня нет времени переходить и менять устаревший скрипт TCL на Python.

В любом случае, я уверен, что есть что-то, что я могу вставить между строками 1 и 2, что будет ждать некоторого указания от modelsim, что он завершил выполнение моего файла .do. Любой совет приветствуется.


person jarickc    schedule 08.06.2015    source источник
comment
Это не прямой ответ на ваш вопрос, но это способ полностью запустить vsim из Python. Я управляю Model- / QuestaSIM с помощью моего скрипта testbench.py, который выбирает тестовый стенд, например. PoC.arith.prng и симулятор (vSim / xSim / ...). Он вызывает vlib, vcom и vsim через subprocess. Подпрограммы для QuestaSIM находятся в файле QuestaSimulator.py < / а>. Результат теста записан Simulation.vhdl в STDOUT и проверяется скриптом.   -  person Paebbels    schedule 08.06.2015
comment
vsim вызывается с помощью общего сценария TCL который ждет остановки всех процессов. Не стесняйтесь применять эти сценарии для нескольких запусков одновременно или параллельно.   -  person Paebbels    schedule 08.06.2015
comment
Команда open всегда возвращает канал (в случае успеха). Вы можете получить PID из одного из конвейеров подпроцесса Tcl, используя команду pid: set subprocesses [pid $pipechannel]   -  person Donal Fellows    schedule 09.06.2015
comment
если это для регрессии, можно использовать -c (cmd) или -batch и нет -gui   -  person vermaete    schedule 09.06.2015
comment
@vermaete Спасибо за замечание о запуске без графического интерфейса. На самом деле я пробовал это пару раз, и, похоже, что модели никогда не запускаются. Это то, над чем я буду больше работать в будущем.   -  person jarickc    schedule 10.06.2015
comment
@jarickc Добавление 'onbreak {exit -f};', 'run -all' и 'exit -f' (в конце файла do) может помочь.   -  person vermaete    schedule 10.06.2015


Ответы (5)


Вы пробовали VUnit? https://github.com/LarsAsplund/vunit

Это тестовая среда VHDL с открытым исходным кодом, которая уже делает то, что вы хотите.

Он может запускать тесты параллельно, а также с разными значениями универсальных шаблонов.

На испытательном стенде может быть несколько тестов, которые можно запускать как в независимом, так и в одном и том же моделировании.

Он может генерировать отчет о тестировании, понятный Jenkins, содержащий тестовые выходные данные, время выполнения и статус.

Он поставляется с библиотекой удобных функций VHDL, таких как check_equal.

Он имеет полное сканирование зависимостей VHDL, так что файлы могут быть просто добавлены, а VUnit будет знать, что инкрементально компилировать, чтобы ускорить цикл редактирования / компиляции / выполнения.

Может запускать определяемые пользователем проверки имитации пост-обработки, чтобы, например, проверить выходной файл на соответствие золотым данным.

В дополнение к запуску в пакетном режиме он может запускать тест в графическом интерфейсе с одним флагом.

Он поддерживает Modelsim и GHDL, скоро появятся Aldec и NVC.

Я лично использовал его для управления более чем 200 тестовыми случаями.

Заявление об ограничении ответственности Я являюсь одним из основных авторов. Он был создан для того, чтобы каждая команда VHDL в мире не изобретала колесо заново с помощью собственных скриптов разного качества.

person kraigher    schedule 11.06.2015

Отвечая на свой вопрос, я заставил это работать до того, как получил ответы. Другие предлагаемые решения могут быть лучше.

Сначала я изменил свой файл .do, добавив строку три ниже.

project open my_project.mpf
do do_files/regression.do
file delete -force "lock.txt"

Затем я изменил свой сценарий TCL следующим образом.

set nice_pid [open "|$modelsim_dir/vsim.exe -do do_files/vsim.do -novopt -gui"]

,# Create a "lock file" that is cleared at the completion of the .do file.
set lock_file "lock.txt"
set lock_PID [open $lock_file w]
close $lock_PID  

while {[file exists $lock_file]} 
    {after 1000}

cd ../../Scripts
set script_name "results_pass.py"
set tb_name "my_tb"
call_python $script_name $tb_name
vwait forever

Таким образом, вызывающий процесс ожидает завершения Modelsim, прежде чем продолжить.

Для тех, кто хочет использовать это, здесь есть call_python proc, который я нашел здесь здесь

;#----------------------------------------------------------------------------;
;# Procedure to call python scripts. Include ".py" extention.
;#----------------------------------------------------------------------------;

proc call_python {script_name tb_name} {
    set output [exec python $script_name $tb_name]
    print $output
}

$ tb_name - это просто аргумент для моего скрипта Python.

person jarickc    schedule 10.06.2015

TCL фактически возвращает канал из открытого вызова, а не pid. Вы можете сделать следующее:

  1. Используйте команду exec вместо открытия канала, потому что вам явно не нужен асинхронный ввод-вывод.
  2. Используйте команду close, чтобы закрыть канал, который, как мне кажется, ожидает закрытия процесса с помощью системного вызова wait ().
person GNSL    schedule 08.06.2015

Вы должны открыть подпроцесс с помощью чтения-записи и установить файловое событие для прослушивания доступных для чтения событий из канала подпроцесса. Когда подпроцесс завершается, он закрывает свой стандартный вывод, и вы получите читаемое событие, где [eof] будет истинным при чтении из этого канала.

Если вы не слишком знакомы с tcl и обработкой асинхронных каналов, я сделал быстрый пример, в котором используются два сценария tcl, причем клиент управляет серверным процессом. Когда сервер получает «выход» на стандартном вводе, он завершает работу. Клиентский процесс видит, что канал закрывается, очищает его и завершает работу. Ключевые команды: fconfigure для установки неблокирующего канала и _ 3_, чтобы установить процедуру, которая будет вызываться всякий раз, когда в канале происходит что-то читаемое.

server.tcl

proc main {} {
    while {[gets stdin line] != -1} {
        if {[string match "quit" [string trim $line]]} {
            break
        }
        puts "ECHO $line"
    }
    return 0
}
main

client.tcl

proc Read {chan} {
    set len [gets $chan line]
    if {[eof $chan]} {
        puts stderr "eof received"
        set ::forever quit
        fileevent $pipe readable {}
    }
    puts stderr "RECV: $len '$line'"
}
proc main {} {
    set pipe [open |[list tclsh server.tcl] r+]
    fconfigure $pipe -blocking 0 -buffering line -translation auto
    fileevent $pipe readable [list Read $pipe]
    after 500 [list puts $pipe begin]
    after 1000 [list puts $pipe quit]
    after 2000 [list set ::forever timeout]
    vwait ::forever
    puts "exit with status '$::forever'"
    return 0
}
main

ожидаемый результат

c:\src>tclsh client.tcl
RECV: 10 'ECHO begin'
eof received
exit quit
person patthoyts    schedule 08.06.2015

Я справился с этой проблемой автоматизации Modelsim из Python, определив фиктивную сигнальную процедуру в Tcl. vsim работает с трубами для каналов ввода / вывода. Команда sentinel отправляется после каждой команды, которую я хочу запустить. Затем я жду, чтобы в выходном потоке появился текст «дозорного», который гарантирует выполнение предыдущей команды.

# Define a dummy sentinel proc
self.p.stdin.write('proc sentinel {} {}\n')
self.p.stdin.write(cmd + '\n')
self.p.stdin.write('sentinel\n')
self.p.stdin.flush()
while True:
  if self.process_done(): break  # The process died

  out.append(get_output(self.outq))
  if '> sentinel' in out[-1]: break # Stop when we see the prompt with the sentinel

Вы можете увидеть полный код автоматизации здесь. Аналогичный подход можно использовать при управлении Modelsim из отдельного интерпретатора Tcl.

person Kevin Thibedeau    schedule 09.06.2015