例子中最初dut和环境见上篇low power-upf-vcsnlp(二)
例子中dut和环境在上篇基础上修改low power-upf-vcsnlp(三)
4.create_power_switch

-switch_type 指定switch类型,如果是粗粒度或者both,则output_supply_port必须指定否则报错。细粒度的则会忽略output_supply_port。
-output_supply_port指定output port name以及连接的net name
-input_supply_port指定input port name以及连接的net name
-control_port指定control port name和连接的net name。net负责开关的。
-on/off_state指定state,和对应的布尔表达式。
-ack_port -ack_delay指定响应port和延时。
(1)添加PD0的power switch
set_design_top top/dut_u
#create_power_domain PD_TOP -include_scope
create_power_domain PD_TOP -elements {.} \
-exclude_elements {inst0}
create_supply_port VDD_TOP
create_supply_port VSS_TOP
create_supply_net VDD_TOP
create_supply_net VSS_TOP
connect_supply_net VDD_TOP -ports VDD_TOP
connect_supply_net VSS_TOP -ports VSS_TOP
create_supply_set PD_TOP_SET \
-function {power VDD_TOP} \
-function {power VSS_TOP}
create_power_domain PD_TOP \
-supply {primary PD_TOP_SET} \
-update
create_supply_port VDD_TOP0
create_supply_net VDD_TOP0
connect_supply_net VDD_TOP0 -ports VDD_TOP0
#PD0
set_scope inst0
create_power_domain PD0 -elements {.}
create_supply_port VDD0_i
create_supply_port VSS0
create_supply_net VDD0_i
create_supply_net VSS0
#这个net是接到power switch中的output_supply_port上,并且作为PD0的supply_net.
create_supply_net VDD0_o
connect_supply_net VDD0_i -ports VDD0_i
connect_supply_net VSS0 -ports VSS0
create_power_switch PD0_SWITCH -domain PD0 \
-input_supply_port {in0 VDD0_i} \
-output_supply_port {out0 VDD0_o } \
-control_port {en0 pwr_en} \
-on_state {PD0_on in0 {en0}} \
-off_state {PD0_off {!en0}}
create_supply_set PD0_SET \
-function {power VDD0_o} \
-function {ground VSS0}
create_power_domain PD0 \
-supply {primary PD0_SET} \
-update
set_scope ..
connect_supply_net VSS_TOP -ports inst0/VSS0
connect_supply_net VDD_TOP0 -ports inst0/VDD0_i
仿真结果的power map如下,其中PD0的power supply port和power switch的 output supply port使用VDD0_o连接起来,power switch通过pwr_en进行控制:

(2)在增加一个PD1的power domain,并为其增加一个power switch。
set_design_top top/dut_u
#create_power_domain PD_TOP -include_scope
create_power_domain PD_TOP -elements {.} \
-exclude_elements {inst0}
create_supply_port VDD_TOP
create_supply_port VSS_TOP
create_supply_net VDD_TOP
create_supply_net VSS_TOP
connect_supply_net VDD_TOP -ports VDD_TOP
connect_supply_net VSS_TOP -ports VSS_TOP
create_supply_set PD_TOP_SET \
-function {power VDD_TOP} \
-function {power VSS_TOP}
create_power_domain PD_TOP \
-supply {primary PD_TOP_SET} \
-update
create_supply_port VDD_TOP0
create_supply_net VDD_TOP0
connect_supply_net VDD_TOP0 -ports VDD_TOP0
#PD0
set_scope inst0
create_power_domain PD0 -elements {.}
create_supply_port VDD0_i
create_supply_port VSS0
create_supply_net VDD0_i
create_supply_net VSS0
#这个net是接到power switch中的output_supply_port上,并且作为PD0的supply_net.
create_supply_net VDD0_o
connect_supply_net VDD0_i -ports VDD0_i
connect_supply_net VSS0 -ports VSS0
create_power_switch PD0_SWITCH -domain PD0 \
-input_supply_port {in0 VDD0_i} \
-output_supply_port {out0 VDD0_o } \
-control_port {en0 pwr_en} \
-on_state {PD0_on in0 {en0}} \
-off_state {PD0_off {!en0}}
create_supply_set PD0_SET \
-function {power VDD0_o} \
-function {ground VSS0}
create_power_domain PD0 \
-supply {primary PD0_SET} \
-update
set_scope ..
connect_supply_net VSS_TOP -ports inst0/VSS0
connect_supply_net VDD_TOP0 -ports inst0/VDD0_i
create_supply_port VDD_TOP1
create_supply_port VDD_TOP1
connect_supply_net VDD_TOP1 -ports VDD_TOP1
#PD1
set_scope inst1/buf_u
create_power_domain PD1 -elements {.}
create_supply_port VDD1_i
create_supply_port VSS1
create_supply_net VDD1_i
create_supply_net VSS1
create_supply_net VDD1_o
connect_supply_net VDD1_i -ports VDD1_i
connect_supply_net VSS1 -ports VSS1
create_power_switch PD1_SWITCH -domain PD1 \
-input_supply_port {in1 VDD1_i} \
-output_supply_port {out1 VDD1_o } \
-control_port {en1 pwr_en} \
-on_state {PD1_on in1 {en1}} \
-off_state {PD1_off {!en1}}
create_supply_set PD1_SET \
-function {power VDD1_o} \
-function {ground VSS1}
create_power_domain PD1 \
-supply {primary PD1_SET} \
-update
set_scope ..
connect_supply_net VSS_TOP -ports inst1/buf_u/VSS1
connect_supply_net VDD_TOP1 -ports inst1/buf_u/VDD1_i
仿真结果的power map如下,此时有三个power domain,PD_TOP,PD0,PD1,其中PD0和PD1都有power switch控制:

层次:

(3)power switch的开关实验。
我们将tb进行修改,将PD0和PD1的power switch进行开关,并分析波形。下面代码我们在520ns处将两个power en 拉低,在620ns时将PD1的power en打开,在720ns时将两个pwer en都打开。
`timescale 1ns/1ps
module top();
import UPF::*;
reg clk;
reg rstn;
reg [1:0] iso_en;
reg [1:0] pwr_en;
initial begin
clk = 0;
rstn = 0;
iso_en = 0;
pwr_en = 3;
#20ns rstn = 1;
#400ns;
#100ns pwr_en = 0;
#100ns pwr_en = 2;
#100ns pwr_en = 3;
#100ns;
$finish;
end
initial begin
$fsdbDumpfile("top.fsdb");
$fsdbDumpvars();
$fsdbDumpvars("+power");
end
initial begin
reg0=0;
reg1=0;
#100ns reg0 = 1;
#100ns reg1 = 1;
#200ns;
end
initial begin
//supply
end
dut dut_u(.in0(reg0), .in1(reg1), .clk(clk), .rstn(rstn), .iso_en(iso_en), .pwr_en(pwr_en));
endmodule
波形结果如下,可以看到在掉电之后PD0,PD1 两个domain输出都是不定,所以需要加上isolation cell 防止这种不定输出对其他模块造成影响:
(3)把ack_port和ack_delay加上
我们在inst.v的inst端口上加一个pwr_ack信号,这个信号可以接出去。
module inst (input reg_i,input ido_en,input pwr_en,output reg_o,output pwr_ack);
wire reg_o1 = ~reg_i;
Buf buf_u(.in(reg_o1),.pwr_en(pwr_en).out(reg_o));
endmodule
module Buf(input in,input pwr_en,output out);
assign out = in;
endmodule
然后在test.upf中对PD0加上ack_port和ack_delay。
set_design_top top/dut_u
#create_power_domain PD_TOP -include_scope
create_power_domain PD_TOP -elements {.} \
-exclude_elements {inst0}
create_supply_port VDD_TOP
create_supply_port VSS_TOP
create_supply_net VDD_TOP
create_supply_net VSS_TOP
connect_supply_net VDD_TOP -ports VDD_TOP
connect_supply_net VSS_TOP -ports VSS_TOP
create_supply_set PD_TOP_SET \
-function {power VDD_TOP} \
-function {power VSS_TOP}
create_power_domain PD_TOP \
-supply {primary PD_TOP_SET} \
-update
create_supply_port VDD_TOP0
create_supply_net VDD_TOP0
connect_supply_net VDD_TOP0 -ports VDD_TOP0
#PD0
set_scope inst0
create_power_domain PD0 -elements {.}
create_supply_port VDD0_i
create_supply_port VSS0
create_supply_net VDD0_i
create_supply_net VSS0
#这个net是接到power switch中的output_supply_port上,并且作为PD0的supply_net.
create_supply_net VDD0_o
connect_supply_net VDD0_i -ports VDD0_i
connect_supply_net VSS0 -ports VSS0
create_power_switch PD0_SWITCH -domain PD0 \
-input_supply_port {in0 VDD0_i} \
-output_supply_port {out0 VDD0_o } \
-control_port {en0 pwr_en} \
-on_state {PD0_on in0 {en0}} \
-off_state {PD0_off {!en0}} \
-ack_port {en_ack pwr_ack {en0}} \
-ack_delay {en_ack 10ns}
.......
......
....
然后其他不变,仿真波形如下,可以看见en_ack是pwr_en(也就算是port en0)的响应,而且响应的布尔表达式是en0,延时10ns,也就是en_ack和en0的值是一样的,并比en0晚10ns变化。并且注意代码窗口中inst0的pwr_ack上有ack的标志:

参考[0]:IEEE 1801-2015 IEEE Standard for Design and Verification of Low-Power, Energy-Aware Electronic Systems
verdi版本:R-2020.12-SP2
vcs版本: Q-2020.03-SP2
参考[1]: VCS Native Low Power (NLP)User Guide.

本文介绍了如何在低功耗设计中创建和使用电源开关,详细阐述了在Verilog和SystemVerilog中为PD0和PD1添加电源开关的过程,并进行了开关实验,分析了波形和响应。内容包括开关类型、控制端口、ack_port和ack_delay的设置。
3259

被折叠的 条评论
为什么被折叠?



