[Из песочницы] Настройка Sublime Text 3 для работы с VHDL файлами

habr.png

Работа с 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×3 — 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. Редактируем данные:


  process rst
  } : 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;
]]>
  procrst
  source.vhdl
 


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

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

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


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

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

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

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

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


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


  procclk
  source.vhdl
  
  process clk


Здесь ${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 и т.д. — процессы для тестбенча с сответствующими типами данных


Мои функции:

  • 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, теперь генерируются тестовые процессы для всех входных сигналов
  • clk, net, inst — шаблоны для ucf файлов

© Habrahabr.ru