Quartus и сборка в коммандной строке. Часть II.

Компилировать проекты в графическом интерфейсе, конечно, иногда приятно, но с увеличением количества этих самых проектов и их сложности возникает необходимость в альтернативном решении. Альтернативное решение — использование командной строки — уже было описано в статье Павла Курочкина. И вот эта идея получила некоторое развитие.

Дело в том, что quartus понимает tcl-скрипты, и программисты компании Altera подготовили набор готовых функций и методов для управления проектами. Т.е. с помощью tcl мы можем выполнить абсолютно все то же самое, что и с помощью GUI (при желании нарисовать этот самый GUI), только быстро и автоматизированно. Данное знание не является сакральным и вы можете ознакомиться с ним здесь. Мы, в свою очередь, бегло просмотрели руководство по tcl скриптингу и решили использовать данные возможности при сборке новых проектов. Сразу отметим, что больше всего нам понравилась сборка всего проекта одной строкой, что на фоне Makefile’а выглядит несколько более компактно.

Что получилось в итоге? А в итоге получился файл «files» в котором списком перечислены файлы необходимые для сборки проекта (причем без какого-либо пути к именам этих файлов) и скрипт make.tcl, которому в качестве аргументов передаются имя проекта и пути к бибилиотекам с файлами. Скрипт открывает проект, выполняет очистку .qsf — файла (данный файл содержит все настройки проекта) от прежних подключенных файлов проекта, выполняет поиск указанных в «files» файлов в библиотеках и, в зависимоти от их расширений (чтобы понять, что это — verilog/vhdl/sdc), подключает их к проекту.

После этого запускается сборка проекта всего ОДНОЙ СТРОКОЙ и проект закрывается. На выходе мы получаем .pof файл. Далее ничто нам не мешает использовать этот скрипт в Makefile’е. Т.к. это наш первый опыт tcl скриптинга, то мы будем рады любым предложениям по оптимизации данного скрипта и вообще любым замечаниям.

Скрипт make.tcl (запускаем так: ./make.tcl my_project /lib_path1 /lib_path2 ):

#!/opt/altera/quartus8.0/quartus/bin/quartus_sh -t

load_package flow

#PROJECT - project name to build
set PROJECT [lindex $argv 0]
#others args is paths for lib dirs with sources
set LIB     [string trimleft $argv $PROJECT]

#Opening project
project_open $PROJECT

#Forming list with source files
#List is in "files"
set FILE_LIST "[exec cat files]"

############################
#Array with filetypes
array set file_types {
  VERILOG_FILE 0
  SDC_FILE     1
  VHDL_FILE    2
}

#Clear project files assignments from .qsf
foreach {type count} [array get file_types] {
 exec grep -v $type $PROJECT.qsf > $PROJECT.qsf_tmp
 exec cat $PROJECT.qsf_tmp > $PROJECT.qsf
 exec rm $PROJECT.qsf_tmp
}

##############################
#Adds source files to .qsf
##############################

#Find every file from file list
foreach file $FILE_LIST {
  foreach path $LIB {
    set file_path     [exec find $path -name $file]
    set file_path_num [exec echo $file_path | wc -l]

    #Does file exist?
    if { [llength $file_path] > 0 } {
    #Is there only one file name?
      if { $file_path_num == "1" } {
        #Add assignment for source files
        switch -regexp -- $file {
          {.v}     {
                     puts "set_global_assignment -name VERILOG_FILE $file_path"
                     set_global_assignment -name VERILOG_FILE $file_path
                   }
          {.sdc}   {
                     puts "set_global_assignment -name SDC_FILE $file_path"
                     set_global_assignment -name SDC_FILE $file_path
                   }
          {.vhdl?} {
                     puts "set_global_assignment -name VHDL_FILE $file_path"
                     set_global_assignment -name VHDL_FILE $file_path
                   }
        }
      } else {
        puts "########################################################"
        puts "!!!! Error: files with the same names !!!!"
        puts "file_path=$file_path"
        puts "########################################################"
        exit
      }
    }
  }
}
##############################
#Run flow just with one command
execute_flow -compile
#Closing project
project_close

Пример файла «files»

module1.v
module2.vdh
module3.v
constr.sdc

#############
Алексей Литвинов
Константин Добросолец
Денис Габидуллин

4 комментария

  1. Антон Фельдман:

    здОрово! а почему не на wiki?

    • Алексей Литвинов:

      Как накопим побольше tcl-«вкусностей», так и на wiki запишем.

  2. Павел Курочкин:

    супер!

    нужно с make’ом замешать и будет счастье (полное). тогда хоть зависимости будут отслеживаться и проект не будет собираться, если файлы не менялись.

    кстати, а как этим смогут пользоваться приверженцы ОС Окна?
    как запустить этот tcl-скрипт? в cmd?

    • Алексей Литвинов:

      Да, зависимости можно и Make’ом отслеживать, но актуально это будет только для симуляции в Modelsim’е, что бы библиотека с модулями всегда была свежея, а вот для Quartus’а мало пригодно, т.к. все равно нужно все пересобирать.

      Для работы «скриптега» в Окнах нужна «допилка»=)
      Хотя при наличие qsf и qpf файлов с прописными исходниками компиляцию проекта можно запустить так(либо в tcl-консоли Quartus’а, либо при помощи quartus_sh -t):

      load_package flow
      #Opening project
      project_open $PROJECT_NAME
      #Run flow just with one command
      execute_flow -compile
      #Closing project
      project_close