Nicolae Adrian
New Member
Offline
Posts: 2
|
Hello, I'm trying to develop a hidden state-free behavioral model for a buck converter digital compensator. I tried to follow the directions from "Hidden State in SpectreRF" by Ken Kundert, therefore I used idt operators to store the values of the variables. However, I noticed that some variables or events will not update or execute, and even so, the hidden state error is still present.
To show an example of the problem, the following code tries to implement a digital averaging block that can be used to sense the output of the converter. What was noticed is that: - if the 0.25 value is remove from "var_v1 = 0.25*var_adc;"(last timer event) the whole event will no longer be executed.
- the idt storage variables were seen as hidden states
- if I move the timer storage variable asignement "ev_clk_rise_t_idt = idt(0, ev_clk_rise_t, ev_clk_rise_ack);" before the first timer event, the this particular variable will no longer be seen as hidden and the code will still work.
virtuoso version 6.1.8-64b 11/10/2020
`include "constants.vams" `include "disciplines.vams"
module BNA_210307_Hidden_state_sum_test(adc_in, clk, avrg_out); input adc_in; input clk; output avrg_out;
electrical adc_in; electrical clk; electrical avrg_out;
real ev_clk_rise_t = 0;
real var_avrg = 0; real var_avrg_idt = 0;
real var_v1 = 0; real var_v2 = 0; real var_v3 = 0; real var_v4 = 0; real var_v5 = 0; real var_v6 = 0; real var_v7 = 0;
real var_v1_idt = 0; real var_v2_idt = 0; real var_v3_idt = 0; real var_v4_idt = 0; real var_v5_idt = 0; real var_v6_idt = 0; real var_v7_idt = 0;
real ev_clk_rise_t_idt = 0;
integer var_adc = 0;
integer ev_clk_rise_ack = 0;
integer ev_var_v_ack1 = 0; integer ev_var_v_ack2 = 0; integer ev_var_v_ack3 = 0; integer ev_var_v_ack4 = 0; integer ev_var_v_ack5 = 0; integer ev_var_v_ack6 = 0; integer ev_var_v_ack7 = 0;
analog begin
var_v1 = 0; var_v2 = 0; var_v3 = 0; var_v4 = 0; var_v5 = 0; var_v6 = 0; var_v7 = 0;
ev_clk_rise_ack = 0; ev_clk_rise_t = 0; var_avrg = 0;
var_adc = 0;
ev_var_v_ack7 = 0; ev_var_v_ack6 = 0; ev_var_v_ack5 = 0; ev_var_v_ack4 = 0; ev_var_v_ack3 = 0; ev_var_v_ack2 = 0; ev_var_v_ack1 = 0;
//the average value should only be updated on the rising edge of the clock @(cross(V(clk) - 0.5,+1)) begin ev_clk_rise_t = $abstime;
var_avrg = (var_v1_idt + var_v2_idt + var_v3_idt + var_v4_idt + var_v5_idt + var_v6_idt + var_v7_idt)/7;
ev_clk_rise_ack = 1; end
//the adc input should be read after 3us from the clock rising edge @(timer(ev_clk_rise_t_idt + 2.94u)) begin var_v7 = var_v6; ev_var_v_ack7 = 1; end
@(timer(ev_clk_rise_t_idt + 2.95u)) begin var_v6 = var_v5; ev_var_v_ack6 = 1; end
@(timer(ev_clk_rise_t_idt + 2.96u)) begin var_v5 = var_v4; ev_var_v_ack5 = 1; end
@(timer(ev_clk_rise_t_idt + 2.97u)) begin var_v4 = var_v3; ev_var_v_ack4 = 1; end
@(timer(ev_clk_rise_t_idt + 2.98u)) begin var_v3 = var_v2; ev_var_v_ack3 = 1; end
@(timer(ev_clk_rise_t_idt + 2.99u)) begin var_v2 = var_v1; ev_var_v_ack2 = 1; end
@(timer(ev_clk_rise_t_idt + 3u)) begin
var_adc = 4095*V(adc_in);
if(var_adc > 4095) var_adc = 4095; if(var_adc < 0) var_adc = 0;
var_v1 = 0.25*var_adc;
ev_var_v_ack1 = 1; end
// the idt storage variables ev_clk_rise_t_idt = idt(0, ev_clk_rise_t, ev_clk_rise_ack);
var_v7_idt = idt(0, var_v7,ev_var_v_ack7); var_v6_idt = idt(0, var_v6,ev_var_v_ack6); var_v5_idt = idt(0, var_v5,ev_var_v_ack5); var_v4_idt = idt(0, var_v4,ev_var_v_ack4); var_v3_idt = idt(0, var_v3,ev_var_v_ack3); var_v2_idt = idt(0, var_v2,ev_var_v_ack2); var_v1_idt = idt(0, var_v1,ev_var_v_ack1);
var_avrg_idt = idt(0, var_avrg, ev_clk_rise_ack);
V(avrg_out) <+ transition(var_avrg_idt,0, 100n);
end endmodule
|