Настройка Sublime Text 3 для работы с VHDL файлами

Работа с VHDL в Sublime Text 3


Редактор Sublime Text существенно экономит время при работе с vhdl и verilog файлами. Для тех, кто не работал с редакторами типа Sublime Text, Notepad++ и т.п. опишу основные полезные функции данных редакторов:

  • множественное выделение/редактирование строк кода (нажатие средней кнопки мыши или при зажатой клавише Ctrl)
  • установка меток (закладок) в коде, помогает ориентироваться в больших файлах. (Ctrl + F2 или через пункт меню Goto→ Bookmarks)
  • возможность разделения рабочей области на несколько окон (Alt + Shift + 2 или из меню View→ Layout)
  • открытие одного файла несколько раз (File→ New View into File)
  • комментирование выделенных строк кода (Ctrl + /)
  • поиск и замена (Ctrl + h)
  • поиск по всем открытым файлам (Ctrl+Shift+f)
  • вставка сниппетов (шаблонов кода) (написать ключевое слово + клавиша Tab)
  • написание и использование функций на языке python
  • возможность установки различных дополнений
  • гибкая настройка

Интеграция Sublime Text


Для начала состыкуем САПР для работы с ПЛИС и редактор Sublime.

  • Интеграция Sublime Text с Xilinx ISE:
    в ISE идем в меню Edit → Preferences → Editors: Text Editor → Editor = Custom
    Вставляем строку в окно «Command line syntax»:

    {C:\Program Files\Sublime Text 3\sublime_text.exe} $1
  • Интеграция Sublime Text с Xilinx Vivado:
    Tools → Options → Text Editor → Current Editor: Sublime
    или
    Tools → Options → Text Editor → Current Editor: Custom Editor
    Указываем путь до редактора, например:
    C:\Program Files\Sublime Text 3\sublime_text.exe [file name]

Плагины


Различные плагины (packages) расширяют функциональность редактора. Packages можно
устанавливать как в онлайн так и оффлайн-режиме.

Для установки плагинов в офлайн-режиме нужно проделать нехитрые манипуляции:

  1. Скачиваем нужный плагин с GitHub
  2. Извлекаем из архива
  3. Переименовываем папку, например, «Sublime-HDL-master» в «Sublime HDL»
  4. Полученные папки копируем в папку Packages (расположение данной папки легко найти, выбрав в Sublime Text пункт меню Preferences → Browse Packages)

SyncViewScroll — плагин для синхронизации вертикальной и горизонтальной прокрутки при работе в нескольких окнах. Для работы плагина надо для каждого окна выбрать в меню View→ Sync Scroll.

Text Pastry – плагин для автоматической множественной нумерации. Очень помогает при работе с большим количеством нумерованных сигналов/портов.

Как работать с Text Pastry
  1. Выделяем нужные участки строк
  2. Вызываем меню Ctrl+Shift+P
  3. Ищем пункт “Text Pasty Command Line”
  4. В появившемся окне, расположенном в нижней части экрана, вводим:
    • 0 — нумерация от 0
    • \i(1,10) — нумерация от 1 с инкрементом 10
    • 1 end=4 — нумерация 1, 2, 3, 4, 1, 2, 3, 4 и т.д.
    • letters a-c upper — A, B, C, A, B, C, и т.д.
    • letters a-c upper x3 — A, A, A, B, B, B, C, C, C и т.д.
    • 1 x3 — 1, 1, 1, 2, 2, 2, 3, 3, 3, и т.д.
    • x y z — x, y, z, x, y, z, x, y, z, и т.д.



Sublime Verilog — поддержка синтаксиса языка Verilog

Verilog Gadget – набор функций и сниппетов для работы с Verilog файлами.

SmartVHDL — поддержка синтаксиса языка VHDL. Также при наведении на сигнал или порт в коде появится окно с подсказкой о типе (количество бит) данного сигнала/порта. При наведении на сигнал в контекстном меню появится пункт “Goto Definishion” — переход к месту объявления сигнала.

VHDL Mode – набор функций и сниппетов для работы с VHDL файлами. Основная часть функций запускается, например, сочетанием клавиш Atl+K, C, P, где C и P нажимаются поочередно. Основные функции:

  • Копирование данных портов (названия портов, типы данных)
  • Вставка данных портов как объявление сигналов
  • Вставка данных портов как объявление компонента
  • Генерация тестбенча по скопированным данным портов
  • Автоформатирование кода (выравнивание табуляции и т.п.)

Поддержка ucf файлов


По умолчанию редактор Sublime не у меет работать с ucf-файлами. Разметка ucf эквивалентна разметке языка tcl. Осталось только объяснить это редактору:

  • Создадим в папке Packages новый файл Tcl.sublime-settings
  • Заполним файл строкой
    {"extensions" : ["ucf"]}
  • Сохраним файл

Создание шаблонов кода (snippets)


Пусть нам надо вставить шаблон кода:

My_proc : Process(clk, rst, data_in) 
begin
  if(clk'event and clk = '1') then
    if(rst = '1') then    
  			
    else then -- rst = 0
        
    end if; -- data_in
  end if;--clk
end process My_proc;

Причем нам бы хотелось, чтобы после вставки текста по нажатию Tab курсор устанавливался на позиции My_proc, clk, rst, data_in, для быстрого изменения значений этих данных. Для этого создадим новый сниппет:Tools → Developer → New Snippet. Редактируем данные:

<snippet>
  <description>process rst</description>
  <content><![CDATA[
${1:<PROCESS_NAME>} : Process(${2:clk}, ${3:rst}, ${4:data_in}) 
begin
  if($2'event and $2 = '1') then
    if($3 = '1') then    
      ${5}	
    else then -- $3 = 0
      $0
    end if; -- $4
  end if;--$2
end process $1;
]]></content>
  <tabTrigger>procrst</tabTrigger>
  <scope>source.vhdl</scope>
</snippet> 

Сохраняем данный сниппет. Теперь при написании ключевого слова procrst в текущую позицию курсора будет вставлен наш шаблон.

Подробнее о создании шаблонов читайте в статье «Как создать сниппет?».

Написание собственных функций на языке python


Подробно о создании функций (плагинов) описывалось в статьях «Как написать простой плагин», «Как написать сложный плагин».

Вставка сниппетов это, конечно хорошо, но хотелось бы, например, чтобы тот же шаблон создания процесса заполнялся автоматически в зависимости от входных сигналов, а также чтобы процесс модифицировался при наличии таких сигналов как rst и ce. Еще обычно после процесса идет присвоение внешним портам модуля значений внутренних сигналов, пусть тоже делается автоматически.

Для парсинга данных файла VHDL воспользуемся функциями плагина Vhdl mode.

Примерный алгоритм наших действий:

  1. Получить данные о всех портах модуля
  2. Все порты типа «in» включить в шапку процесса
  3. Если есть порты с названием ce и/или rst, то добавить соответствующие условия if else в процесс
  4. За процессом вставить строки присвоения выходным портам значений внутренних сигналов (обычно такие сигналы называют также как и порт, добавляя приставку «s_» или "_net")

Для начала создадим новый сниппет:

<snippet>
  <tabTrigger>procclk</tabTrigger>
  <scope>source.vhdl</scope>
  <content><![CDATA[
${DATAINPORTS}

${OUTPORTS}
]]></content>
  <description>process clk</description>
</snippet>

Здесь ${DATAINPORTS} – метка, куда будет вставлено описание процесса,
${OUTPORTS} — метка, где будет присвоение внешним выходным портам значений внутренних сигналов.

Сохраним его под именем, например, test.sublime-snippet в папку VHDL Mode/Snippets.
Воспользуемся написанными функциями в папке VHDL Mode. Так как знания языка python у меня начальные, то будем модифицировать функции плагина, по аналогии с уже описанными в нем.

Создадим в файле vhdl_lang.py новые функции в классе Interface(), назовем их in_port и out_port:

Функции
def in_port(self):
  """
  Generate Process depending on the input ports
  """
  lines = []
  bus_index = ""       
  
  max_data = ""
  my_ports = ""
  is_clk = False
  is_ce = False
  is_rst = False
  if self.if_ports:            
      for port in self.if_ports:            
          if port.mode.lower() == 'in':
              if port.name.lower() == ('clk'):                       
                  is_clk = True
                  my_ports = port.name                        
              else: 
                  if port.name.lower() == ('ce'):
                      is_ce = True                           
                  elif port.name.lower() == ('rst'):
                      is_rst = True                                                   
                  my_ports = my_ports + ", " + port.name                
                
      lines.append("Process("+ my_ports +')' )
      lines.append("begin")
      if is_clk:            
          lines.append("  if(clk'event and clk = '1') then")
          lines.append("")
          if is_rst and is_ce:
              lines.append("if(rst = '1') then")
              lines.append("")
              lines.append("elsif (ce = '1') then")
              lines.append("")
              lines.append("end if; -- rst")
          elif is_rst:
              lines.append("if(rst = '1') then")
              lines.append("")
              lines.append("else -- working body ")
              lines.append("")
              lines.append("end if; -- rst")
          elif is_ce:
              lines.append("if (ce = '1') then")
              lines.append("")
              lines.append("end if; -- 
          lines.append("  end if;--clk")
      lines.append("end process;")
      # lines.append(str(testind
      indent_vhdl(lines, 1)
      return '\n'.join(lines)
  else:
      return None


def out_port(self):
  """
  Generate data after Process
  """
  lines = []
  if self.if_ports:            
      for port in self.if_ports:            
          if port.mode.lower() == 'out':
              lines.append("{} <= {}_net;".format(port.name, port.name))
      indent_vhdl(lines, 1)
      return '\n'.join(lines)
  else:
      return None 


Функция out_port вставляет за процессом строки, например:
data_out1 <= data_out1_net;
data_out2 <= data_out2_net;

Создадим в папке VHDL Mode новый файл, назовем его my_func.py, вставим текст:
import sublime
import sublime_plugin
from.import vhdl_interface as face

class PasteAsProcess(sublime_plugin.TextCommand):
    def run(self, edit):
        snippet_clk = "Packages/VHDL Mode/Snippets/test.sublime-snippet"
        in_port_str = face._interface.in_port()
        out_port_str = face._interface.out_port()

        self.view.run_command("insert_snippet",
            {
              "name"     : snippet_clk,
              "DATAINPORTS" : in_port_str,
              "OUTPORTS" : out_port_str
            })

        print('paste_as_process')

Осталось присвоить горячие клавиши. Так как наш класс называется PasteAsProcess, то команда должна называться paste_as_process (перед символами, кроме первого, написанными в верхнем регистре нужно поставить знак нижнего подчеркивания).

Идем Preferences → Key Bildings. Вставляем строку:

{"keys": ["alt+k", "p", "z"], "command": "paste_as_process",    "context": [{"key": "selector", "operand": "source.vhdl"}] },

Теперь для работы нам надо сначала скопировать значения портов vhdl файла сочетанием клавиш «alt+k», «p», «w» (по умолчанию). Затем вызвать нашу функцию клавишами «alt+k», «p», «z».

Вывод


Сниппеты и функции значительно упрощают работу с vhdl файлами.

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

P.S.: Оставлю ссылку на папку с моими настройками. Для работы, надо заменить папку Sublime Text 3 по адресу: C:\Users\User\AppData\Roaming\

Мои сниппеты:

  • sint (Signal integer), sstd, svector — шаблоны описания сигналов соответствующего типа
  • ibuf, ibufds и т.д. — описание буферов
  • generichelp — подсказка пример, как правильно применить generic
  • teststd, testvector и т.д. — процессы для тестбенча с сответствующими типами данных
  • procclk, procce, procrst — процессы с сигналами clk, ce, rst
  • clk, net, inst — шаблоны для ucf файлов

Мои функции:

  • Cвязка Alt+K,C,P (Copy Ports), Alt+K,P,Z — вставка процесса описанного с этой статье
  • Cвязка Alt+K,C,P (Copy Ports), Alt+K,P,T (Paste Testbench) — переделал функцию плагина VHDL MODE, теперь генерируются тестовые процессы для всех входных сигналов
  • +17
  • 3,7k
  • 6
Поделиться публикацией
Комментарии 6
    +1

    Хорошая статья, доходчиво написано. Может имеет смысл дополнить примерами шаблонов для тестбенчей. Думаю Vivado всем дико доставляет отсутствием возможности автоматической генерации шаблона тестбенча модуля.


    Я надеюсь что не заминусуют за это, но при описании синхронного процесса с синхронным сбросом My_proc в листе чувствительности кроме сигнала clk другие сигналы указывать не обязательно.


    Сам пользуюсь стандартным редактором Vivado, надеюсь за это тоже не заминусуют.
    Ждём новых полезных сниппетов и руководств. Спасибо.

      0
      Если нужен процесс только с сигналом clk или ce или rst я использую шаблоны procclk, procce, procrst. Шаблоны для тестбенчей вызываются по ключевым словам teststd, testfor, testvector, testrand, testfile. В ссылке на мои настройки на GitHub можно посмотреть соответствующие сниппеты.
        0
        Пока не читал (обязательно буду читать и подробно), но заранее большое спасибо! Для меня это проблема. Раньше писал код на верилоге в SVEditor (это плагин для eclipse). Он страшный, но другое что пробовал ещё хуже. Сейчас у меня проект для альтеры. И неожиданно оказалось что более не менее приемлемый редактор в квартусе. Хотя именно что более не менее. Ничего хорошего. А вообще меня поражает, почему для верилога нет нормальных редакторов? Казалось бы есть серьёзные продукты, такие как например ActiveHDL. Почему не сделали нормальный редактор! Кстати вопрос читателям этого хаба. Кто каким редактором пользуется?
          0
          Sublime Text 3 с плагином SystemVerilog, который сейчас активно поддерживается и развивается.
          До этого использовал Kate(Kwrite), который есть в том числе для Linux.
            0
            Спасибо, глянул выглядит и правда симпатично. Надо будет попробовать. Kate я тоже пробовал (он в Krusader редактор по умолчанию) что-то не очень.
          0
          в спойлере «Функции»:
                        lines.append("end if; -- 
                    lines.append("  end if;--clk")

          чего-то здесь не то с кодом в 1-ой строке.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое