2015-08-19 2 views
1

Я пытаюсь написать плагин, который требует оценки комбинаторных схем. Из того, что я могу собрать, ConstEval - это инструмент, который делает это. Однако API мне не очень понятен. Есть ли где-то краткое изложение членов ConstEval и что они делают?Как работает API Yosys ConstEval?

(Asked by jeremysalwen on github).

ответ

1

Использование класса ConstEval на самом деле довольно просто. Вы создаете объект ConstEval для данного модуля и устанавливаете известные значения с помощью метода void ConstEval::set(SigSpec, Const). После того, как все известные сигналы установлены, метод bool ConstEval::eval(SigSpec&, SigSpec&) может использоваться для оценки сетей. Метод eval() возвращает true, когда оценка прошла успешно и заменяет сеть (ы) в первом аргументе постоянными значениями, на которые оценивается сеть. В противном случае он возвращает false и устанавливает второй аргумент в список сетей, которые необходимо установить для продолжения оценки.

Методы push() и pop() могут использоваться для создания локальных контекстов для set(). Метод stop() может использоваться для объявления сигналов, при которых оценка должна прекратиться, даже если есть комбинаторные ячейки, управляющие сетью.

Следующий простой Yosys плагин демонстрирует, как использовать API ConstEval (evaldemo.cc):

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

USING_YOSYS_NAMESPACE 
PRIVATE_NAMESPACE_BEGIN 

struct EvalDemoPass : public Pass 
{ 
    EvalDemoPass() : Pass("evaldemo") { } 

    virtual void execute(vector<string>, Design *design) 
    { 
     Module *module = design->top_module(); 

     if (module == nullptr) 
      log_error("No top module found!\n"); 

     Wire *wire_a = module->wire("\\A"); 
     Wire *wire_y = module->wire("\\Y"); 

     if (wire_a == nullptr) 
      log_error("No wire A found!\n"); 

     if (wire_y == nullptr) 
      log_error("No wire Y found!\n"); 

     ConstEval ce(module); 
     for (int v = 0; v < 4; v++) { 
      ce.push(); 
      ce.set(wire_a, Const(v, GetSize(wire_a))); 
      SigSpec sig_y = wire_y, sig_undef; 
      if (ce.eval(sig_y, sig_undef)) 
       log("Eval results for A=%d: Y=%s\n", v, log_signal(sig_y)); 
      else 
       log("Eval failed for A=%d: Missing value for %s\n", v, log_signal(sig_undef)); 
      ce.pop(); 
     } 
    } 
} EvalDemoPass; 

PRIVATE_NAMESPACE_END 

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

$ cat > evaldemo.v <<EOT 
module main(input [1:0] A, input [7:0] B, C, D, output [7:0] Y); 
    assign Y = A == 0 ? B : A == 1 ? C : A == 2 ? D : 42; 
endmodule 
EOT 

$ yosys-config --build evaldemo.so evaldemo.cc 
$ yosys -m evaldemo.so -p evaldemo evaldemo.v 
... 
-- Running command `evaldemo' -- 
Eval failed for A=0: Missing value for \B 
Eval failed for A=1: Missing value for \C 
Eval failed for A=2: Missing value for \D 
Eval results for A=3: Y=8'00101010 
+0

ли толчок/поп создавать независимые контексты, или контекст совокупными на все в стеке? –

+0

Да, это кумулятивно над всем, что находится в стеке: назначение остается активным до тех пор, пока не будет создан контекст, в котором он был создан. – CliffordVienna