vak: (Житель планеты Узм)
[personal profile] vak
Попробовал я собрать симулятор Верилога от ИИ - увы. На маке сборка валится в конце, на нестыковке между Си++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>
  }
}
Ничо так вроде, годно на первый взгляд.

Date: 2026-03-08 02:21 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Зачем 9'd1, если счетчик 8-битный? Почему не написать просто 1?