Как пройти индукцию в SymbiYosys?

Я новичок в формальной верификации и начал формальную верификацию с SymbiYosys. Я написал некоторый код в System Verilog для изучения формальной проверки, я смог пройти BMC и прикрыть код, но он не работает (НЕИЗВЕСТНО) для индукции.

У меня нет большого понимания формального доказательства, но мое текущее понимание индукционного доказательства таково: мой проект начнется в будущем в состоянии утверждения, и все мои регистры будут установлены в каком-то состоянии, которое вызвало бы мое утверждение, и из этого state Движок SymbiYosys попытается найти допустимое состояние в обратном временном шаге, который бы соответствовал состоянию утверждения. Может быть, мое понимание неправильно.

Мой дизайн передает утверждения, а также охватывает, но в индукции он устанавливает значения регистров RCON в ноль, но регистры RCON инициализируются файлом rcon.mem с использованием $readmemh("box.mem",mem);, тогда, если эта инициализация регистра может быть переопределена с помощью доказательства индукции, то как мне написать свой код, который пройдет индукция. Как лучше всего инициализировать регистр в RTL.

Пожалуйста, помогите в этом, у меня есть код mcve .sv, конфигурация .sby, файл .mem и скриншот .vcd gtkwave.

мой файл журнала ошибок также прилагается

test_mcve_prove/logfile.txt

SBY 21:27:37 [test_mcve_bmc] Removing directory 'test_mcve_bmc'.
SBY 21:27:39 [test_mcve_cover] Removing directory 'test_mcve_cover'.
SBY 21:27:47 [test_mcve_prove] Removing directory 'test_mcve_prove'.
SBY 21:27:47 [test_mcve_prove] Copy 'test_mcve.sv' to 'test_mcve_prove/src/test_mcve.sv'.
SBY 21:27:47 [test_mcve_prove] Copy 'rcon.mem' to 'test_mcve_prove/src/rcon.mem'.
SBY 21:27:47 [test_mcve_prove] engine_0: smtbmc
SBY 21:27:47 [test_mcve_prove] base: starting process "cd test_mcve_prove/src; yosys -ql ../model/design.log ../model/design.ys"
SBY 21:27:47 [test_mcve_prove] base: finished (returncode=0)
SBY 21:27:47 [test_mcve_prove] smt2: starting process "cd test_mcve_prove/model; yosys -ql design_smt2.log design_smt2.ys"
SBY 21:27:47 [test_mcve_prove] smt2: finished (returncode=0)
SBY 21:27:47 [test_mcve_prove] engine_0.basecase: starting process "cd test_mcve_prove; yosys-smtbmc --presat --unroll --noprogress -t 4  --append 0 --dump-vcd engine_0/trace.vcd --dump-vlogtb engine_0/trace_tb.v --dump-smtc engine_0/trace.smtc model/design_smt2.smt2"
SBY 21:27:47 [test_mcve_prove] engine_0.induction: starting process "cd test_mcve_prove; yosys-smtbmc --presat --unroll -i --noprogress -t 4  --append 0 --dump-vcd engine_0/trace_induct.vcd --dump-vlogtb engine_0/trace_induct_tb.v --dump-smtc engine_0/trace_induct.smtc model/design_smt2.smt2"
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Solver: yices
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Solver: yices
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assumptions in step 0..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assertions in step 0..
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Trying induction in step 4..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assumptions in step 1..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assertions in step 1..
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Trying induction in step 3..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assumptions in step 2..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assertions in step 2..
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Trying induction in step 2..
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Trying induction in step 1..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assumptions in step 3..
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Checking assertions in step 3..
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Trying induction in step 0..
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Temporal induction failed!
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Assert failed in test_mcve: test_mcve.sv:111.46-112.39
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Writing trace to VCD file: engine_0/trace_induct.vcd
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: ##   0:00:00  Status: passed
SBY 21:27:48 [test_mcve_prove] engine_0.basecase: finished (returncode=0)
SBY 21:27:48 [test_mcve_prove] engine_0: Status returned by engine for basecase: pass
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Writing trace to Verilog testbench: engine_0/trace_induct_tb.v
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Writing trace to constraints file: engine_0/trace_induct.smtc
SBY 21:27:48 [test_mcve_prove] engine_0.induction: ##   0:00:00  Status: failed
SBY 21:27:48 [test_mcve_prove] engine_0.induction: finished (returncode=1)
SBY 21:27:48 [test_mcve_prove] engine_0: Status returned by engine for induction: FAIL
SBY 21:27:48 [test_mcve_prove] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:01 (1)
SBY 21:27:48 [test_mcve_prove] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:01 (1)
SBY 21:27:48 [test_mcve_prove] summary: engine_0 (smtbmc) returned pass for basecase
SBY 21:27:48 [test_mcve_prove] summary: engine_0 (smtbmc) returned FAIL for induction
SBY 21:27:48 [test_mcve_prove] DONE (UNKNOWN, rc=4)

test_mcve.sv

`default_nettype    none

module test_mcve(ext_Clk,ext_Resetn,ext_Start,ext_round,ext_next_round,xor_in_if);
//parameter for module

parameter WIDTH = 8;
parameter NUMBER_OF_ROUNDS = 10;



//external interface signals
input ext_Clk,ext_Resetn,ext_Start; //clk , reset, start
input  [3:0] ext_round;
output logic [3:0] ext_next_round;
output logic [WIDTH-1:0] xor_in_if;

//input round register
logic [3:0] round;
logic [1:0]index_sel;

//Round constant 8 bits
reg [WIDTH-1:0]RCON[(NUMBER_OF_ROUNDS-1):0] /* synthesis ram_init_file = "rcon.mif" */; 
initial begin
    $readmemh("rcon.mem", RCON);
end


//state machine states
typedef enum logic[1:0] {Idle_s,Comput_s} state_t;
state_t state,next_state;

//###################################################### state register
logic reset;
assign reset = !ext_Resetn;
always_ff@(posedge ext_Clk,posedge reset) begin
    if(reset) state <= Idle_s;
    else      state <= next_state;
end

//###################################################### next state logic
always_comb begin
    case (state)
        Idle_s: if ((ext_Start == 1)&&(ext_round == ext_next_round)&&(ext_round<NUMBER_OF_ROUNDS)&&(reset == 0)) next_state = Comput_s;
                else next_state = Idle_s;

        Comput_s: if (index_sel==3) next_state = Idle_s;
                else next_state = Comput_s;

        default: next_state = Idle_s;

    endcase
end
//####################################################### output logic



logic [WIDTH-1:0] temp_rcon;
assign xor_in_if = (index_sel == 3)?temp_rcon:0;



//next round output logic
always@(posedge ext_Clk,posedge reset)begin
    if(reset) ext_next_round<=0;
    else if(index_sel==3) ext_next_round<=ext_next_round+1;
end



//output logic
always@(posedge ext_Clk) begin
    case (state)
        Idle_s: begin
            index_sel<=0;
            if(ext_round<10)
                round <= ext_round;
            else
                round <= NUMBER_OF_ROUNDS;
        end
        Comput_s: begin
            index_sel<=index_sel+1;
            temp_rcon<=RCON[round];
        end
        default:begin
            
        end
    endcase
end

//#########################################################
//################### FORMAL VERIFICATION #################
//#########################################################
`ifdef FORMAL
  //Using Immediate assertion

  
logic verf_valid;

initial begin
    assume(verf_valid==0);
    assume(ext_Resetn == 0);
end
always @(posedge(ext_Clk))begin
    verf_valid<=1;
end

// verification
always@(posedge(ext_Clk)) begin
    if((verf_valid==1) && (ext_Resetn != 0))begin
        if((round==0)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h01);
            cover(xor_in_if == 8'h01);
        end
         if((round==1)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h02);
            cover(xor_in_if == 8'h02);
        end
        if((round==2)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h04);
            cover(xor_in_if == 8'h04);
        end
        if((round==3)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h08);
            cover(xor_in_if == 8'h08);
        end
        if((round==4)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h10);
            cover(xor_in_if == 8'h10);
        end
        if((round==5)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h20);
            cover(xor_in_if == 8'h20);
        end
        if((round==6)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h40);
            cover(xor_in_if == 8'h40);
        end
        if((round==7)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h80);
            cover(xor_in_if == 8'h80);
        end
        if((round==8)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h1b);
            cover(xor_in_if == 8'h1b);
        end
        if((round==9)&&(index_sel == 3))begin
            assert(xor_in_if == 8'h36);
            cover(xor_in_if == 8'h36);
        end
          
    end
 end

`endif

endmodule 

test_mcve.sby

[tasks]
bmc d_12
cover d_120
prove d_4

[options]
bmc:mode bmc
cover:mode cover
prove:mode prove
d_120:depth 120
d_12:depth 12
d_4:depth 4

[engines]
smtbmc

[script]
read -formal -sv test_mcve.sv
prep -top test_mcve

[files]
test_mcve.sv
rcon.mem

rcon.mem

01 02 04 08 10 
20 40 80 1B 36

Снимок экрана trace_induct.vcd введите здесь описание изображения


person Shashidhar B    schedule 09.10.2020    source источник


Ответы (1)


Я просматривал слайды Клиффорда Вольфа (ссылка ниже) и нашел слайд-29, где он проиллюстрировал пример memcmp.v для демонстрации индукционного доказательства для двух модулей памяти с использованием файла .smtc в его файле .sby. Затем я использовал тот же метод для инициализации моего регистра RCON, после чего моя проверка индукции прошла (мои файлы .sby и .smtc прилагаются)

Я не знаю, является ли использование файла .smtc для инициализации моих регистров хорошей практикой для индукционного доказательства. Если у вас есть лучший ответ, пожалуйста, предложите мне.

Ссылка на слайды Клиффорда Вульфа (см. слайд-29)

Мой файл initialize_RCON.smtc (я только что скопировал операторы предположения из файла engin0 .smtc каталога покрытия, который будет создан, если бы у нас были операторы покрытия для инициализации памяти и все проходы оператора покрытия. То же самое копируется в раздел утверждения):

initial
assume (= (select [RCON] #b0000) #b00000001)
assume (= (select [RCON] #b1000) #b00011011)
assume (= (select [RCON] #b0001) #b00000010)
assume (= (select [RCON] #b0010) #b00000100)
assume (= (select [RCON] #b0011) #b00001000)
assume (= (select [RCON] #b0100) #b00010000)
assume (= (select [RCON] #b0101) #b00100000)
assume (= (select [RCON] #b0110) #b01000000)
assume (= (select [RCON] #b0111) #b10000000)
assume (= (select [RCON] #b1001) #b00110110)

Мой test_mcve.sby

[tasks]
bmc d_12
cover d_120
prove d_12 smtc_prove

[options]
bmc:mode bmc
cover:mode cover
prove:mode prove
d_120:depth 120
d_12:depth 12
smtc_prove:smtc initialize_RCON.smtc

[engines]
smtbmc

[script]
read -formal -sv test_mcve.sv
prep -top test_mcve

[files]
initialize_RCON.smtc
test_mcve.sv
rcon.mem

Чтобы запустить только индукционный тест, я использую задачу проверки, как показано ниже:

sby -f test_mcve.sby prove 
person Shashidhar B    schedule 10.10.2020