2015-08-19 2 views
2

Сохраняет ли yosys порядок ввода/вывода портов для модулей/ячеек? Является ли упорядочение в RTL гарантией соответствия порядку верилога при его чтении/записи? Будет ли заказ когда-либо изменен «неожиданно» yosys?Сохраняет ли yosys порядок портов?

ответ

2

Yosys хранит заказ, в котором порты модулей объявлены в RTLIL::Wire::port_id. Позиционные параметры для экземпляров переименовываются в $1, $2, $3, .... Затем команда hierarchy использует свойство port_id для правильного переименования портов на экземплярах ячеек при разработке дизайна.

При написании модуля в виде файла verilog проводное свойство port_id используется для определения порядка, в котором порты объявлены в заголовке модуля.

Итак, да: Yosys сохраняет порядок ввода/вывода портов для модулей и разрешает имена позиционных параметров в экземплярах ячеек.

Когда hierarchy не запущен или объявление типа ячейки недоступно, тогда позиционные параметры в этих экземплярах ячейки не разрешаются, и они снова сбрасываются как позиционные параметры, когда проект написан как файл verilog.

Edit: В ответ на комментарий: Следующий пример плагина (portsigdemo.cc) демонстрирует, как создать SigSpec, содержащий все модули портов/порты ячейки в порядке деклараций порта в соответствующем модуле:

#include "kernel/yosys.h" 
#include "kernel/consteval.h" 

USING_YOSYS_NAMESPACE 
PRIVATE_NAMESPACE_BEGIN 

SigSpec get_portsig(Module *module, string direction, Cell *cell = nullptr) 
{ 
    if (cell) 
     log_assert(cell->type == module->name); 

    SigSpec sig; 
    dict<int, SigSpec> sigs; 

    for (auto wire : module->wires()) 
    { 
     bool selected = false; 

     if (direction == "in") 
      selected = wire->port_input; 
     else if (direction == "out") 
      selected = wire->port_output; 
     else 
      log_abort(); 

     if (selected) { 
      if (cell) { 
       if (cell->hasPort(wire->name)) 
        sigs[wire->port_id] = cell->getPort(wire->name); 
       else if (cell->hasPort(stringf("$%d", wire->port_id))) 
        sigs[wire->port_id] = cell->getPort(stringf("$%d", wire->port_id)); 
       else 
        log_abort(); 
      } else { 
       sigs[wire->port_id] = wire; 
      } 
     } 
    } 

    sigs.sort(); 
    for (auto &it : sigs) 
     sig.append(it.second); 

    return sig; 
} 

struct PortsigDemoPass : public Pass 
{ 
    PortsigDemoPass():Pass("portsigdemo") { } 

    virtual void execute(vector <string>, Design * design) 
    { 
     for (auto module : design->modules()) 
     { 
      log("Module %s:\n", log_id(module)); 
      log(" Inputs: %s\n", log_signal(get_portsig(module, "in"))); 
      log(" Outputs: %s\n", log_signal(get_portsig(module, "out"))); 

      for (auto cell : module->cells()) 
      { 
       auto cell_type_mod = cell->module->design->module(cell->type); 
       if (cell_type_mod) { 
        log(" Cell %s (%s):\n", log_id(cell), log_id(cell->type)); 
        log(" Inputs: %s\n", log_signal(get_portsig(cell_type_mod, "in", cell))); 
        log(" Outputs: %s\n", log_signal(get_portsig(cell_type_mod, "out", cell))); 
       } 
      } 
     } 
    } 
} PortsigDemoPass; 

PRIVATE_NAMESPACE_END 

Пример использования:

$ cat > portsigdemo.v << EOT 
module mod1 (input [3:0] A, B, output [3:0] Y); 
    mod2 mod2_inst0 (.P(A[0]), .Q(B[0]), .X(Y[0])); 
    mod2 mod2_inst1 (.P(B[1]), .Q(A[1]), .X(Y[1])); 
    mod2 mod2_inst2 (A[2], B[2], Y[2]); 
    mod2 mod2_inst3 (B[3], A[3], Y[3]); 
endmodule 

module mod2 (input P, Q, output X); 
    assign X = P^Q; 
endmodule 
EOT 

$ yosys-config --build portsigdemo.so portsigdemo.cc 
$ yosys -m portsigdemo.so -p portsigdemo portsigdemo.v 
... 
-- Running command `portsigdemo' -- 
Module mod2: 
    Inputs: { \Q \P } 
    Outputs: \X 
Module mod1: 
    Inputs: { \B \A } 
    Outputs: \Y 
    Cell mod2_inst3 (mod2): 
    Inputs: { \A [3] \B [3] } 
    Outputs: \Y [3] 
    Cell mod2_inst2 (mod2): 
    Inputs: { \B [2] \A [2] } 
    Outputs: \Y [2] 
    Cell mod2_inst1 (mod2): 
    Inputs: { \A [1] \B [1] } 
    Outputs: \Y [1] 
    Cell mod2_inst0 (mod2): 
    Inputs: { \B [0] \A [0] } 
    Outputs: \Y [0] 

PS: portsigdemo.v клетки (экземпляры модуль) mod1.mod2_inst0 и mod1.mod2_inst1 используют именованные параметры (название мода ule), а ячейки mod1.mod2_inst2 и mod1.mod2_inst3 используют позиционные параметры (порт модуля определяется порядком параметров).

+0

Что означает «Позиционные параметры на экземплярах»? Я не понимаю большую часть этого ответа за пределами существования port_id. То, что я действительно пытаюсь сделать, это получить SigSpec для всех входов ячеек и SigSpec для всех выходов ячеек, где они упорядочены в соответствии с определением Verilog. –

+0

@JeremySalwen См. Редактирование. – CliffordVienna

+1

@ClifforVienna Большое спасибо, теперь я понимаю, но по-прежнему кажется, что это не относится к встроенным типам ячеек. Где порты, определенные для встроенных ячеек, и имеют ли они связанный порядок? –

 Смежные вопросы

  • Нет связанных вопросов^_^