Документация Engee
Notebook

Бинарная логика

В данном примере мы исследуем применение бинарной логики для решения логических задач, используя уравнение, написанное на языке программирования Julia, и его реализацию в модели для генерации кода Verilog и верификации этого кода. Более детально сам пример и его реализация разобраны по следующей ссылке: https://engee.com/community/ru/catalogs/projects/binarnaia-logika.

Цель этой демонстрации — показать возможности генератора и оптимизации кода на простом примере.

Описание бинарного уравнения

Зададим состояния нашей системы, которых в данном случае будет три: 𝐴, 𝐵 и 𝐶. При этом состояние 𝐴 будет определяться случайным образом: если случайное значение 𝑋 больше 0.5, то 𝐴 истина, иначе ложь.

Наша логика определяется следующим уравнением: Z = ((A and B) or (C and B)).

In [ ]:
A = rand() > 0.5
println("A = $(A)")
B = false
C = true
println("B = $(B)")
println("C = $(C)")

Z = ((A && B) || (C && B))
println("Z = $(Z)")
A = false
B = false
C = true
Z = false

Моделирование бинарной логики и генерация кода

In [ ]:
# Подключение вспомогательной функции запуска модели.
function run_model( name_model)
    
    Path = (@__DIR__) * "/" * name_model * ".engee"
    
    if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
        model = engee.open( name_model ) # Открыть модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
    else
        model = engee.load( Path, force=true ) # Загрузить модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
        engee.close( name_model, force=true ); # Закрыть модель
    end
    sleep(0.1)
    return model_output
end

run_model("Logical_Operator") # Запуск модели.
Z_model = collect(Z_model).value[end]
println()
println("Z_model = $(Z_model)")
Building...
Progress 0%
Progress 100%
Progress 100%

Z_model = false

Теперь выполним генерацию кода из модели и проанализируем результат.

In [ ]:
engee.generate_code(
"$(@__DIR__)/Logical_Operator.engee",
"$(@__DIR__)/V_Code",
subsystem_name="Logical"
)
// Generated by CIRCT firtool-1.62.1
module Logical_Operator_Logical(
  input  clock,
         reset,
  output io_Out1
);

  assign io_Out1 = 1'h0;
endmodule

[ Info: Generated code and artifacts: /user/my_projects/Demo/Work/logical_operator/V_Code

Вывод

In [ ]:
open("$(@__DIR__)/V_Code/Logical_Operator_Logical.v", "r") do file
    for line in eachline(file)
        println(line)
    end
end
// Generated by CIRCT firtool-1.62.1
module Logical_Operator_Logical(
  input  clock,
         reset,
  output io_Out1
);

  assign io_Out1 = 1'h0;
endmodule

Как мы видим, оптимизатор кода убрал всю логику, кроме выходного значения. Это связано с тем, что мы явно задали параметры констант. Соответственно, все значения внутри кода статичны, поэтому выполнять генерацию кода из них — не оптимальное решения с точки зрения затрачиваемых ресурсов ПЛИС. Тот же самый эфект мы получим, если воспользуемся блоком Terminator. Любая ветка решения модели, заканчивающаяся этим блоком, будет отброшена из итогового сгенерированного кода.

Блоки, использованные в примере