2017-02-20 26 views
1

мне нужно реализовать блок (поведенческий, чтобы не быть синтезированы), которое либо вызваносамостоятельно срабатывает всегда блокировать с помощью задержки

а) внешний eflag события, или, б) в зависимости от его состояния, в внутреннее событие iflag, запланированное через несколько секунд, в зависимости от того, что наступит раньше.

Мои испытания с использованием оператора задержки (#) приводили к поведению блокировки, например. длинный dt блокировал следующий eflag. Если возможно, я бы избегал dtmax, считая накладные расходы длинным dt.

Работа и предназначена, но, не код:

`timescale 1ns/100fs 
`define tick 1.0e-9 

parameter real dtmax = 1; 

initial iflag=1'b0; 
initial toggle=1'b0; 

always @(eflag, iflag) begin  
    // time step control 

    dt = ...; 
    iticks = dt/`tick; 
    toggle = !toggle; 
end 

//------------------------------------------------------ 
/* 
a) time step counter - working 
always #1 begin 
    iticks = iticks - 1; 
    if (iticks < 1) begin 
     iflag = !iflag; 
     iticks=dtmax/`tick; 
    end 
end 
*/ 

// b) intended 
always @(toggle) begin 
    #(iticks) iflag <= !iflag;   // failing, not changing iflag 
// #(iticks) iflag = !iflag;   // failing, blocking simulation 
end 

Вы можете попробовать его на edaplayground link

Thx

ответ

0

Я chanaged свой код, и этот новый код отлично работает для меня. Если вы считаете, что это не работает, возможно, вы ошибаетесь в понимании моделирования Verilog. Неблокирующие задержки планируют событие на сигнале. Если до истечения времени назначения этого планирования другое событие запланировано с другим значением, оно переопределяет первое. Если новое событие имеет одно и то же значение, первый сохраняется.

// Verilog 
// self-triggered always block 
// block should take time steps <= dtmax 


`define tick 1.0e-9 

module dut(eflag); 

    input eflag; 
reg iflag; 
reg toggle; 
    integer iticks; 
    real last_time; 
    real now; 
    real dtlast; 
    real dtmax; 

    always @(eflag, iflag) begin 

    now = $time*`tick; 
    dtlast = now - last_time; 
    dtmax = iticks*`tick; // from last call 

    $display( "dtlast: %g",dtlast); 
    $display( "err:  %d",dtlast > dtmax); // giving wrong value in sim? 
    $display("\nnow:  %g",now); 
    $display( "dtmax: %g",dtmax); 


    // time step control dummy 
    iticks <= 7 + $random % 5; //changed because in previous one eflag and toggle always changed at the same time 
    toggle = !toggle; 

    last_time = now; 
    end 

    initial toggle = 0; 
    initial iflag = 0; 
    always @(toggle) begin 
    #(iticks) iflag <= !iflag; 
    end 

endmodule 
+0

спасибо за ваш ответ, на самом деле я хотел избавиться от пешеходного стиля декрементации. См. Мой отредактированный код в вопросе. – bardo

+1

Что делать, если вы измените его на iflag <= # (iticks)! Iflag; – Laleh

+0

Можете изменить свой вопрос, чтобы быть более ясным и опубликовать весь свой код, чтобы я мог его отладить. – Laleh