circt-verilog
2026-03-07 13:55Попробовал я собрать симулятор Верилога от ИИ - увы. На маке сборка валится в конце, на нестыковке между Си++17 и Си++20. Какие-то проблемы в скриптах cmake, подозреваю. На Линуксе получилось собрать circt-verilog. Но это только фрондэнд от LLVM. А симулятор circt-sim не компилируется: недостаёт какого-то метода.
Но фрондэнд давайте попробуем. Возьмём простой счётчик для примера:
circt/lib/Dialect/Sim/Transforms/ProceduralizeSim.cpp: In member function ‘llvm::LogicalResult {anonymous}::ProceduralizeSimPass::proceduralizePrintOps(mlir::Value, llvm::ArrayRef)’:
circt/lib/Dialect/Sim/Transforms/ProceduralizeSim.cpp:213:33: error: no matching function for call to ‘circt::sim::PrintFormattedProcOp::create(mlir::OpBuilder&, mlir::Location, mlir::Value&)’
213 | PrintFormattedProcOp::create(builder, printOp.getLoc(), procPrintInput);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Искусство по прежнему в большом долгу...Но фрондэнд давайте попробуем. Возьмём простой счётчик для примера:
module counter (
input logic clk,
input logic reset,
output logic [7:0] count
);
always_ff @(posedge clk or posedge reset) begin
if (reset)
count <= 8'b0;
else
count <= count + 9'd1;
end
endmodule
Превратим Верилог в промежуточное представление:
$ circt-verilog counter.sv
module {
llvm.func @__moore_signal_event_in_slot(i32, !llvm.ptr) -> i1
llvm.func @__moore_wait_event(i32, !llvm.ptr)
hw.module @counter(in %clk : !hw.struct<value: i1, unknown: i1>, in %reset : !hw.struct<value: i1, unknown: i1>, out count : !hw.struct<value: i8, unknown: i8>) attributes {circt.default_time_units = -9 : i32, vpi.all_vars = {clk = 1 : i32, count = 8 : i32, reset = 1 : i32}} {
%0 = llhd.constant_time <0ns, 0d, 1e>
%c-1_i8 = hw.constant -1 : i8
%c0_i8 = hw.constant 0 : i8
%c1_i8 = hw.constant 1 : i8
%1 = hw.aggregate_constant [0 : i8, -1 : i8] : !hw.struct<value: i8, unknown: i8>
%true = hw.constant true
%2 = hw.aggregate_constant [0 : i8, 0 : i8] : !hw.struct<value: i8, unknown: i8>
%value = hw.struct_extract %clk["value"] : !hw.struct<value: i1, unknown: i1>
%unknown = hw.struct_extract %clk["unknown"] : !hw.struct<value: i1, unknown: i1>
%3 = comb.xor %unknown, %true : i1
%4 = comb.and bin %value, %3 : i1
%value_0 = hw.struct_extract %reset["value"] : !hw.struct<value: i1, unknown: i1>
%unknown_1 = hw.struct_extract %reset["unknown"] : !hw.struct<value: i1, unknown: i1>
%5 = comb.xor %unknown_1, %true : i1
%6 = comb.and bin %value_0, %5 : i1
%count = llhd.sig %1 : !hw.struct<value: i8, unknown: i8>
%7:2 = llhd.combinational -> !hw.struct<value: i8, unknown: i8>, i1 {
%10 = llhd.prb %count : !hw.struct<value: i8, unknown: i8>
%value_3 = hw.struct_extract %10["value"] : !hw.struct<value: i8, unknown: i8>
%unknown_4 = hw.struct_extract %10["unknown"] : !hw.struct<value: i8, unknown: i8>
%11 = comb.add %value_3, %c1_i8 : i8
%12 = comb.icmp ne %unknown_4, %c0_i8 : i8
%13 = comb.replicate %12 : (i1) -> i8
%14 = comb.xor %13, %c-1_i8 : i8
%15 = comb.and %11, %14 : i8
%16 = hw.struct_create (%15, %13) : !hw.struct<value: i8, unknown: i8>
llhd.yield %16, %true : !hw.struct<value: i8, unknown: i8>, i1
}
%8 = seq.to_clock %4
%count_2 = seq.firreg %7#0 clock %8 reset async %6, %2 preset 255 {name = "count"} : !hw.struct<value: i8, unknown: i8>
llhd.drv %count, %count_2 after %0 : !hw.struct<value: i8, unknown: i8>
%9 = llhd.prb %count : !hw.struct<value: i8, unknown: i8>
hw.output %9 : !hw.struct<value: i8, unknown: i8>
}
}
Ничо так вроде, годно на первый взгляд.
no subject
Date: 2026-03-08 02:21 (UTC)no subject
Date: 2026-03-08 03:35 (UTC)no subject
Date: 2026-03-08 06:08 (UTC)no subject
Date: 2026-03-08 06:10 (UTC)