找了一些veriloga的资料。
主要是veriloga官方手册《Cadence®Verilog®-A Language Reference》

1.基尔霍夫定律撑起了整个电路学的大厦(当然也可以认为基尔霍夫定律只是麦克斯韦方程的简化版),作为模拟电路描述语言Verilog-A,同样将基尔霍夫定律作为其基本,最重要的两个概念便是流量(Flow)和位(Potential),在电学里是电流和电压,在力学里可以是力和距离,在热学里可以是功率和温差,等等。
KCL:基尔霍夫第一定律又称基尔霍夫电流定律,简记为KCL,是电流的连续性在集总参数电路上的体现,其物理背景是电荷守恒公理。基尔霍夫电流定律是确定电路中任意节点处各支路电流之间关系的定律,因此又称为节点电流定律。(一个节点处,输入的=输出的)
KVL:

2.在Verilog-A中,你可以将电阻电容电感等器件用一个方程式来表述,比如I(out) <+ V(out)/R,这样就产生了一个电阻,最后Verilog-A仿真器会用某种算法(迭代是最常见的)将I(out)和V(out)求解出来,然后根据这个解去算下一个时刻的I、V等,当然这仅仅是指时域仿真。

使用Verilog-A,可以创建和使用描述组件和系统的高级行为的模块。它使用模块来描述模拟系统及其组件的结构和行为。利用Verilog-A的模拟陈述,你可以描述范围广泛的保守系统和信号流系统,如电气、机械、流体动力学和热力学系统。

一部分是接口声明,一部分是行为描述。与verilog是有一定相似的。

1.创建模块

module 名字 (模块端口)
endmodule
module res(p, n) ;
inout p, n ;
electrical p, n ;
parameter real r = 0 ;

声明一个名为res的模块、一个名为p和n的端口以及一个名为r的参数。

2.关于端口
input 声明不能设置端口上的信号,尽管可以在表达式中使用它们。
output 声明端口上的信号可以设置,但不能在表达式中使用。
inout 声明该端口是双向的。端口上的信号可以在表达式中设置和使用。inout是默认的端口方向。

module gainer (out, pin) ;  // Declares two ports
output out ;  // Declares port as output
input pin ;  // Declares port as input
voltage out, pin ;  // Declares type of ports
parameter real gain = 2.0 ;
analog
V(out) <+ gain * V(pin) ;
endmodule

module gainer 有两个端口:输出和引脚。输出端口是用output的方向声明的,这样它的值就可以被设置。引脚端口是用input的方向声明的,这样它的值就可以被读取。

3.关于参数

每个参数,必须指定一个默认值。
module sdiode有一个参数area,默认值为1。如果没有为实例指定area,则它将收到一个值1。类似地,其他参数,is, n, cjo, m, phi,和tt,也有指定的默认值。
module sdiode还定义了三个局部变量:vd、id和qd。

4.定义模块模拟行为
以analog开始

module am(in1, in2, outsum, outmult) ;
input in1, in2 ;
output outsum, outmult ;
voltage in1, in2, outsum, outmult ;
analog begin
V(outsum) <+ V(in1) + V(in2) ;
V(outmult) <+ V(in1) * V(in2) ;
end
endmodule

声明完以后,用analog开始模拟。两条语句。

5.定义具有控制流的模拟行为
带有if,else的。

module vdba(in, out);
input in ;
output out ;
electrical in, out ;
parameter real vin_low = -2.0 ;
parameter real vin_high = 2.0 ;
parameter real gain = 1 from (0:inf) ;
analog begin
if (V(in) >= vin_high) begin
V(out) <+ gain*(V(in) - vin_high) ;
end else if (V(in) <= vin_low) begin
V(out) <+ gain*(V(in) - vin_low) ;
end else begin
V(out) <+ 0 ;
end
end
endmodule

5.积分微分
Verilog-A提供了一个时间导数函数ddt和两个时间积分函数idt和idtmod。

analog
V(p, n) <+ ddt(L * I(p, n)) ;
analog begin
V(diff) <+ ddt(V(in)) ;
V(out) <+ ddt(V(diff)) ;
end
analog begin
V(out) <+ idt(V(in), 0) ;
end

idt为积分,第二项为初始条件。
6.模块中使用内部节点

module rlc_behav(in, out, ref) ;
inout in, out, ref ;
electrical in, out, ref ;
parameter real R=1, L=1, C=1 ;
electrical n1 ;
analog begin
V(in, n1) <+ R*I(in, n1) ;
V(n1, out) <+ L*ddt(I(n1, out)) ;
I(out, ref) <+ C*ddt(V(out, ref)) ;
end
endmodule

module rlc_behav使用内部节点n1和端口in, ref, and out,直接定义RLC电路的行为特征。注意,n1没有出现在模块的端口列表中。
7.numbers
veriloga支持实数和整数。

277195000
277_195_000  //Same as the previous number
-634  //A negative number
00052.5K  // 2500
1e-6  // 0.000001
-9.6e9
-1e-4
0.1u
50p  // 50 * 10e-12
1.2G  // 1.2 * 10e9
213_116.223_642

8.数据类型和对象
(1)Integer Numbers
例:

integer a[1:64] ;  // Declares array of 64 integers
integer b, c, d[-20:0] ;  // Declares 2 integers and an array
parameter integer max_size = 15 from [1:50] ;
integer cur_vector[1:max_size] ;
/* If the max_size parameter is not overridden, the
previous two statements declare an array of 15 integers. */

(2)Real Numbers
例:

real a[1:64] ;  // Declares array of 64 reals
real b, c, d[-20:0] ;  // Declares 2 reals and an array of reals
parameter integer min_size = 1, max_size = 30 ;
real cur_vector[min_size:max_size] ;

(3)Parameters
例:

parameter integer subord = 8 ;
parameter integer superior = 3 * subord ;

参数是常量,不能在运行时更改参数的值。但是可以通过在编译期间更改参数值来定制模块实例。
(4)Natures
使用属性声明将属性集合定义为属性。性质的属性表征了在模拟过程中求解的模拟量。
例:

nature Mycurrent
units = "A" ;
access = I ;
idt_nature = charge ;
abstol = 1e-12 ;
huge = 1e6 ;
endnature

代码通过指定五个属性来声明当前属性。根据语法要求,与每个属性关联的表达式必须是常量表达式。
(5)Disciplines
在顶层声明一个纪律,不能将规程声明嵌套在其他规程、性质或模块声明中。
例:

discipline electrical
potential Voltage ;
flow Current ;
enddiscipline

(6)Disciplines的兼容

nature Voltage
access = V ;
units = "V" ;
abstol = 1u ;
endnature
nature Current
access = I ;
units = "A" ;
abstol = 1p ;
endnature
discipline emptydis
enddiscipline
discipline electrical
potential Voltage ;
flow Current ;
enddiscipline
discipline sig_flow_v
potential Voltage ;
enddiscipline

electrical和sig_flow_v具有相同的性质,都为potential。里面定义的内容不一样。

nature Position
access = x ;
units = "m" ;
abstol = 1u ;
endnature
nature Force
access = F ;
units = "N" ;
abstol = 1n ;
endnature
discipline mechanical
potential Position ;
flow force ;
enddiscipline

postion的nature和voltage的nature不一样。
electrical 和 mechanical的 disciplines不相容。
这俩的 natures 都是potential. Take the Yes branch.
Position nature 与 Voltage nature不完全相同. Take the No branch
(7)Net Disciplines
未声明范围的网称为标量网。用范围声明的网称为向量网。

magnetic inductor1, inductor2 ;  // Declares two scalar nets
electrical [1:10] node1 ;  // Declares a vector net
wire [3:0] connect1, connect2 ;  // Declares two vector nets
discipline emptydis
enddiscipline
module comp1 (out, in, unknown1, unknown2) ;
output out ;
input in ;
electrical out, in ;
emptydis unknown1 ;  // Declared with an empty discipline
analog
V(out) <+ 2 * V(in)
endmodule

模块comp1有四个端口:out、in、unknown1和unknown2。模块声明out和in作为电子端口,并使用他们在模拟块。端口unknown1是用空规则声明的,不能在模拟块中使用,因为没有办法访问它的信号。但是,unknown1可以在端口列表中使用,它从连接到它的模块实例的端口继承属性。unknown2出现在端口列表中,而没有在模块主体中声明,所以Verilog-A隐式地将unknown2声明为带有默认规则的标量端口。默认规程类型是wire。

module five_inputs( portbus );
input [0:5] portbus;
electrical [0:5] portbus;
real x;
analog begin
generate i ( 0,4 )
V(portbus[i]) <+ 0.0;
end
endmodule

模块comp1和five_input演示了在模块中使用网络的两种方式。
通过在module语句中给出一个网络列表,你可以定义模块的端口。
可以描述一个模块的行为通过声明和使用内部的网模块构造。
(8)branches
显式分支

voltage [5:0] vec1 ;  // Declares a vector net
voltage [1:6] vec2 ;  // Declares a vector net
voltage sca1 ;  // Declares a scalar net
voltage sca2 ;  // Declares a scalar net
branch (vec1[5],vec2[1]) branch1, (sca1,sca2) branch2 ;

branch1是合法声明的,因为每个分支终端都是向量网的单个元素。第二个分支branch2也是合法声明的,因为节点sca1和sca2都是标量网。
隐式分支

module diode (a, c) ;
inout a, c ;
electrical a, c ;
parameter real rs=0, is=1e-14, tf=0, cjo=0, phi=0.7 ;
parameter real kf=0, af=1, ef=1 ;
analog begin
I(a, c) <+ is*(limexp((V(a, c)-rs*I(a, a))/$vt) - 1);
I(a, c) <+ white_noise(2* `P_Q * I(a, c)) ;
I(a, c) <+ flicker_noise(kf*pow(abs(I(a, c)),af),ef);
end
endmodule
module diode (a, c) ;
inout a, c ;
electrical a, c ;
branch (a,c) diode, (a,a) anode ; // Declare named branches
parameter real rs=0, is=1e-14, tf=0, cjo=0, phi=0.7 ;
parameter real kf=0, af=1, ef=1 ;
analog begin
I(diode) <+ is*(limexp((V(diode)-rs*I(anode))/$vt) - 1);
I(diode) <+ white_noise(2* `P_Q * I(diode)) ;
I(diode) <+ flicker_noise(kf*pow(abs(I(diode)),af),ef);
end
endmodule

隐式分支,这俩一样。
9. 赋值符号
=:用作数值赋值,等号左边通常是integer或者real类型
<+:用于对electrical型赋值,需要在仿真器中迭代运算,必须被放在analog begin里面;多个<+等式的运算不存在计算顺序的先后
10.branch assignment
V(out) : V(in) == 0 ;
找到 V(out) 使 V(in) 等于0。
11.序列块语句
希望将两个或多个语句组合在一起,使它们的行为类似于单个语句,请使用顺序块。

integer j ;
...
for ( j = 0 ; j < 10 ; j=j+1 ) begin
if ( j%2 ) begin : odd
integer j ; // Declares a local variable
j = j+1 ;
$display ("Odd numbers counted so far = %d" , j ) ;
end else begin : even
integer j ; // Declares a local variable
j = j+1 ;
$display ("Even numbers counted so far = %d" , j ) ;
end
end

都有integer j,但是因为有各自的begin,所以不影响。
12.条件语句
if-else结构

if ((value > 0)&&(value <= 1)) $strobe("Category A");
else if ((value > 1)&&(value <= 2)) $strobe("Category B");
else if ((value > 2)&&(value <= 3)) $strobe("Category C");
else if ((value > 3)&&(value <= 4)) $strobe("Category D");
else $strobe("Illegal value");

strobe是显示的意思。
13.case语句

real value ;
...
case (1)
((value > 0)&&(value <= 1)) : $strobe("Category A");
((value > 1)&&(value <= 2)) : $strobe("Category B");
((value > 2)&&(value <= 3)) : $strobe("Category C");
((value > 3)&&(value <= 4)) : $strobe("Category D");
value <= 0 , value >= 4 : $strobe("Out of range");
default $strobe("Error. Should never get here.");
endcase

如果值为1.5,则第一次比较失败。第二个test_expression计算为1 (true),它与case表达式匹配,因此运行$strobe(“Category B”)语句。
14.repeat语句

integer i, total ;
...
i = 0 ;
total = 0 ;
repeat (10) begin
i = i + 1 ;
total = total + i ;
end

重复20次。
15.while语句

integer rand, count ;
...
rand = abs($random % 10) ;
count = 0 ;
while (rand) begin
count = count + 1 ;
rand = abs($random % 10) ;
end ;
$strobe ("Count is %d", count) ;

16.for语句

integer j, total ;
...
total = 0 ;
for ( j = 2; j < 22; j = j + 2 )
total = total + j

17.generate语句
generate语句是一个在编译时展开的循环构造。使用generate语句来简化代码,或者当您有一个包含模拟运算符的循环构造时。generate语句只能在模拟块中使用。只支持generate语句的向后兼容性

`define BITS 4
module adc (in, out) ;
input in ;
output [0:`BITS - 1] out ;
electrical in ;
electrical [0:`BITS - 1] out ;
parameter fullscale = 1.0, tdelay = 0.0, trantime = 10n ;
real samp, half ;
analog begin
half = fullscale/2.0 ;
samp = V(in) ;
generate i (`BITS - 1,0) begin  // default increment = -1
V(out[i]) <+ transition(samp > half, tdelay, trantime);
if (samp > half) samp = samp - half ;
samp = 2.0 * samp ;
end
end
endmodule

循环Vout(i)
18.模拟块运算符
常见操作符和顺序。

19.数学函数
标准数学函数

三角函数和双曲函数

20.检测使用events
使用event_expr操作符在特定事件的控制下运行语句

Initial_step Event
如果您没有指定analysis_list,那么模拟器将在每个分析的第一个时间步长或初始DC分析上生成一个initial_step事件。
Final_step Event
模拟器在分析的最后一个时间步上生成一个Final_step事件。使用final_step事件执行应该只在分析结束时发生的操作。
如果analysis_identifier中的字符串与正在运行的分析相匹配,那么模拟器就会在该分析的最后一个时间步骤上生成final_step事件。如果您没有指定analysis_list,那么模拟器会在每次分析的最后一个时间步骤上生成final_step事件。

module bit_error_rate (in, ref) ;
input in, ref ;
electrical in, ref ;
parameter real period=1, thresh=0.5 ;
integer bits, errors ;
analog begin
@(initial_step) begin
bits = 0 ;
errors = 0 ;  // Initialize the variables
end
@(timer(0, period)) begin
if ((V(in) > thresh) != (V(ref) > thresh))
errors = errors + 1;  // Check for errors each period
bits = bits + 1 ;
end
@(final_step)
$strobe("Bit error rate = %f%%", 100.0 * errors/bits );
end
endmodule

bit_error_rate模块测量信号的位错,并在分析结束时打印出结果
Cross Event
根据设置的标准,当表达式在指定方向上越过零点时,模拟器可以生成交叉事件。使用交叉函数指定哪些交叉生成交叉事件。

module samphold (in, out, sample) ;
output out ;
input in, sample ;
electrical in, out, sample ;
real hold ;
analog begin
@(cross(V(sample)-2.5, +1, 0.01n, sample.potential.abstol))
hold = V(in) ;
V(out) <+ transition(hold, 0, 10n) ;
end
endmodule

每次当样本电压增加到2.5时,交叉函数都会产生一个交叉事件。expr_tol被指定为与网络样本的潜在性质相关联的abstol。

Above Event
使用above函数指定模拟器何时生成上述事件。可以在初始化过程中生成和检测上述事件。

connectmodule elect2logic_2(aVal, dVal);
input aVal;
output dVal;
electrical aVal;
logic dVal;
parameter real thresholdLo = 1.5;
parameter real thresholdHi = 3.5;
integer iVal;
assign dVal = iVal; // direct driver/receiver propagation
always @(above(V(aVal) - thresholdHi))
iVal = 1’b1;
always @(above(thresholdLo - V(aVal)))
iVal = 1’b0;
endmodule

下面的示例演示如何使用上述函数。每当模拟电压通过3.5值增加或通过1.5值减少时,函数产生above事件。
Timer Event

模拟器可以在模拟过程中在指定的时间生成计时器事件。使用timer函数来指定模拟器何时生成计时器事件。

module squarewave (out)
output out ;
electrical out ;
parameter period = 1.0 ;
integer x ;
analog begin
@(initial_step) x = 1 ;
@(timer(0, period/2)) x = -x ;
V(out) <+ transition(x, 0.0, period/100.0 ) ;
end
endmodule

模块squarewave演示了如何使用timer函数来生成计时器事件。在squarewave中,输出电压在周期/2的每一个时间间隔都由正变为负或由负变为正。
21.模拟器的功能。
(1)$discontinuity 函数

使用$discontinuity 函数告诉模拟器信号行为的不连续。

module trisource (vout) ;
output vout ;
voltage vout ;
parameter real wavelength = 10.0, amplitude = 1.0 ;
integer slope ;
real wstart ;
analog begin
@(timer(0, wavelength)) begin
slope = +1 ;
wstart = $abstime ;
$discontinuity (1);  // Change from neg to pos slope
end
@(timer(wavelength/2, wavelength)) begin
slope = -1 ;
wstart = $abstime ;
$discontinuity (1);  // Change from pos to neg slope
end
V(vout) <+ amplitude * slope * (4 * ($abstime - wstart) / wavelength-1) ;
end
endmodule

trisource中的两个$discontinuity函数告诉模拟器关于导数的不连续。并规定何时不连续,不连续时取什么值。

(2)$bound_step函数

module sinwave (outsig) ;
output outsig ;
voltage outsig ;
parameter real freq = 1.0, ampl = 1.0 ;
analog begin
V(outsig) <+ ampl * sin(2.0 * ‘M_PI * freq * $abstime) ;
$bound_step(0.02 / freq) ;  // Max time step = 1/50 period
end
endmodule

通过指定适当的时间步长,您可以强制模拟器按照您的模型的要求跟踪信号。例如,模块sinwave迫使模拟器在每个周期中模拟至少50个时间点
(3)$last_crossing函数
使用last_crossing函数来找出信号表达式最后越过零点时的模拟时间

module period (in) ;
input in ;
voltage in ;
integer crosscount ;
real latest, earlier ;
analog begin
@(initial_step) begin
crosscount = 0 ;
earlier = 0 ;
end
@(cross(V(in), +1)) begin
crosscount = crosscount + 1 ;
earlier = latest ;
end
latest = last_crossing(V(in), +1) ;
@(final_step) begin
if (crosscount < 2)
$strobe("Could not measure the period.") ;
else
$strobe("Period = %g, Crosscount = %d", latest-earlier, crosscount) ;
end
end
endmodule

Thelast_crossingfunction不控制时间步长来获得准确的结果,而是使用插值来估计最后一次交叉的时间。为了提高准确性,您可能需要将last_crossing函数与cross函数一起使用。例如,模块period计算输入信号的周期,使用交叉函数来精确求解时间。
(4)模拟环境函数
获取当前模拟时间
1)abstime_function ::=
$abstime
2)realtime_function ::=
$realtime[(time_scale)]

4)获取环境温度
temperature_function ::=
$temperature
5)获取热电压
vt_function ::=
$vt[(temp)]
6)获取和设置信号值

(5)访问属性函数

使用分层引用操作符来访问节点或分支的属性。

electrical a, b, n1, n2;
branch (n1, n2) cap ;
parameter real c= 1p;
analog begin
I(a,b) <+ c*ddt(V(a,b), a.potential.abstol) ;  // Access abstol for node
I(cap) <+ c*ddt(V(cap), n1.potential.abstol) ; // Access abstol for branch
end

访问节点和分支的abstol值。
(6)分析相关函数
与分析相关的函数会根据所执行的分析类型改变它们的行为
1)确定当前分析类型
使用analysis函数确定当前分析类型是否与指定类型匹配
analysis ( analysis_list )
analysis_list ::=
analysis_name { , analysis_name }
analysis_name ::=
“analysis_type”


if (analysis("dc", "ic"))
out = ! V(in) > 0.0 ;
else
@(cross (V(in),0)) out = ! out
V(out) <+ transition (out, 5n, 1n, 1n) ;

2)小信号交流源
ac_stim ( [ “analysis_type” [ , mag [ , phase]]] )
3)小信号噪声源
1°白噪声函数
white_noise( power [ , “name”])

(diode) <+ white_noise( 2 * ‘P_Q * I(diode), "source1" ) ;

2°闪烁噪声函数
flicker_noise( power, exp [ , “name”])

I(diode) <+ flicker_noise( kf * pow(abs(I(diode)),af),ef) ;

3°noise_table函数
noise_table(vector [ , “name” ])
22.生成随机数函数
$random [ ( seed ) ] ;

// There is a 5% chance of signal loss.
module randloss (pinout) ;
electrical pinout ;
integer randseed, randnum;
analog begin
@ (initial_step) begin
randseed = 123 ;  // Initialize the seed just once
end
randnum = abs($random(randseed) % 100) ;
if (randnum < 5)
V(pinout) <+ 0.0 ;
else
V(pinout) <+ 3.0 ;
end // of analog block
endmodule

23.生成指定分布中的随机数函数
(1)均匀分布
$rdist_uniform ( seed , start , end ) ;生成随机实数
$dist_uniform ( seed , start , end ) ;生成随机整数

module distcheck (pinout) ;
electrical pinout ;
parameter integer start_range = 20 ;  // A parameter
integer seed, end_range;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;  // Initialize the seed just once
end_range = 60 ;  // A variable
end
rrandnum = $rdist_uniform(seed, start_range, end_range);
$display ("Random number is %g", rrandnum ) ;
// The next line shows how the seed changes at each
// iterative use of the distribution function.
$display ("Current seed is %d", seed) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

(2)正态(高斯)分布
$rdist_normal ( seed , mean , standard_deviation ) ;
$dist_normal ( seed , mean , standard_deviation ) ;

module distcheck (pinout) ;
electrical pinout ;
integer seed ;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;
end
rrandnum = $rdist_normal( seed, 0, 1 ) ;
$display ("Random number is %g", rrandnum ) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

(3)指数分布
$rdist_exponential ( seed , mean ) ;
$dist_exponential ( seed , mean ) ;

module distcheck (pinout) ;
electrical pinout ;
integer seed, mean ;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;
mean = 5 ;  // Mean must be > 0
end
rrandnum = $rdist_exponential(seed, mean) ;
$display ("Random number is %g", rrandnum ) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

(4)泊松分布
$rdist_poisson ( seed , mean ) ;
$dist_poisson ( seed , mean ) ;

module distcheck (pinout) ;
electrical pinout ;
integer seed, mean ;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;
mean = 5 ;  // Mean must be > 0
end
rrandnum = $rdist_poisson(seed, mean) ;
$display ("Random number is %g", rrandnum ) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

(5)卡方分布
$rdist_chi_square ( seed , degree_of_freedom ) ;
$dist_chi_square ( seed , degree_of_freedom ) ;

module distcheck (pinout) ;
electrical pinout ;
integer seed, dof ;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;
dof = 5 ;  // Degree of freedom must be > 0
end
rrandnum = $rdist_chi_square(seed, dof) ;
$display ("Random number is %g", rrandnum ) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

(5)T分布
$rdist_t ( seed , degree_of_freedom ) ;
$dist_t ( seed , degree_of_freedom ) ;

module distcheck (pinout) ;
electrical pinout ;
integer seed, dof ;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;
dof = 15 ; // Degree of freedom must be > 0
end
rrandnum = $rdist_t(seed, dof) ;
$display ("Random number is %g", rrandnum ) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

(6)二狼分布
$rdist_erlang ( seed , k , mean ) ;
$dist_erlang ( seed , k , mean ) ;

module distcheck (pinout) ;
electrical pinout ;
integer seed, k, mean ;
real rrandnum ;
analog begin
@ (initial_step) begin
seed = 23 ;
k = 20 ;  // k must be > 0
mean = 15 ;  // Mean must be > 0
end
rrandnum = $rdist_erlang(seed, k, mean) ;
$display ("Random number is %g", rrandnum ) ;
V(pinout) <+ rrandnum ;
end // of analog block
endmodule

24.使用表模型进行插值
使用$table_model函数通过在数据点之间插入和外推来建模设计行为。

‘include "disciplines.vams"
‘include "constants.vams"
module mynmos (g, d, s);
electrical g, d, s;
inout g, d, s;
analog begin
I(d, s) <+ $table_model (V(g, s), V(d, s), "nmos.tbl", "3CL,3CL");
end
endmodule

在这个例子中,自变量是V(g,s)和V(d,s)。用于插值的样条的度数对于两个维度中的每一个都是3。对于两个维度中的每一个,对低端的外推方法是夹紧,对高端的外推方法是线性的。
25.模拟运算符
(1)有限的指数函数
limexp( expr )
(2)时间导数算子
ddt( input [ , abstol | nature ] )
(3)时间积分算子
idt( input [ , ic [ , assert [ , abstol | nature ] ] ] )


(4)循环积分器算子
idtmod(expr [ , ic [ , modulus [, offset [, abstol | nature ] ] ] ] )

可以用到VCO里。
(5)延迟算子
使用absdelay算子来延迟一个连续值波形的整个信号
absdelay( expr , time_delay [ , max_delay ] )

V(out) <+ absdelay(V(in), 5u) ;

(6)过渡滤波器
transition(input [, delay [, rise_time [, fall_time [, timetol ]]]])
使用transition filter,您可以通过设置信号转换的上升时间和下降时间来控制离散信号电平之间的转换。

// comparator model
analog begin
if ( V(in) > 0 ) begin
Vout = 5 ;
end
else begin
Vout = 0 ;
end
V(out) <+ transition(Vout) ;
end
module d_ff(vin_d, vclk, vout_q, vout_qbar) ;
input vclk, vin_d ;
output vout_q, vout_qbar ;
electrical vout_q, vout_qbar, vclk, vin_d ;
parameter real vlogic_high = 5 ;
parameter real vlogic_low = 0 ;
parameter real vtrans_clk = 2.5 ;
parameter real vtrans = 2.5 ;
parameter real tdel = 3u from [0:inf) ;
parameter real trise = 1u from (0:inf) ;
parameter real tfall = 1u from (0:inf) ;
integer x ;
analog begin
@ (cross( V(vclk) - vtrans_clk, +1 )) x = (V(vin_d) > vtrans) ;
V(vout_q) <+ transition( vlogic_high*x + vlogic_low*!x,tdel, trise, tfall );
V(vout_qbar) <+ transition( vlogic_high*!x + vlogic_low*x, tdel,
trise, tfall ) ;
end
endmodule


一个上升的转换在完成大约四分之三的时候被中断,并且新目的地的值低于中断点的值。转换过滤器计算将从指定fall_time的新原点(而不是中断点的值)完成转换的斜率。然后,转换过滤器使用计算得到的斜率从当前值转换到新的目标。
(7)回转滤波器
使用回转滤波器来控制波形的变化率。转换的一个典型用途是从分段连续信号中产生连续信号。对于离散信号,考虑使用过渡滤波器代替。
slew(input [ , max_pos_rate [ , max_neg_rate ] ] )

module dac4(d, out) ;
input [0:3] d ;
inout out ;
electrical [0:3] d ;
electrical out ;
parameter real slewrate = 0.1e6 from (0:inf) ;
real Ti ;
real Vref ;
real scale_fact ;
analog begin
Ti = 0 ;
Vref = 1.0 ;
scale_fact = 2 ;
generate ii (3,0,-1) begin
Ti = Ti + ((V(d[ii]) > 2.5) ? (1.0/scale_fact) : 0);
scale_fact = scale_fact/2 ;
end
V(out) <+ slew( Ti*Vref, slewrate ) ;
end
endmodule

4位数字到模拟转换器使用转换功能来控制其输出模拟信号的变化率。
(8)拉普拉斯变换
拉普拉斯变换滤波器不能在任何情况下在if或case构造中使用。
1)Zero-Pole Laplace Transforms
laplace_zp(expr, ζ, ρ [ , ε ])

2)Zero-Denominator Laplace Transforms
laplace_zd(expr, ζ, d [ , ε ])

3)Numerator-Pole Laplace Transforms
laplace_np(expr, n, ρ [ , ε ])

4)Numerator-Denominator Laplace Transforms
laplace_nd(expr, n, d [ , ε ])

两种表达:
V(out) <+ laplace_zp(V(in), {0,0}, {1,2,1,-2});
V(out) <+ laplace_nd(V(in), {0,1}, {1,-0.4,0.2});

(9)Z变换
1)Zero-Pole Z-Transforms
zi_zp(expr, ζ, ρ, T [ , τ [ , t0] ])

2)Zero-Denominator Z-Transforms
zi_zd(expr, ζ, d, T [ , τ [ , t0] ])

3)Numerator-Pole Z-Transforms
zi_np(expr, n, ρ, T [ , τ [ , t0] ])

4)Numerator-Denominator Z-Transforms
zi_nd(expr, n, d, T [ , τ [ , t0] ])

module ideal_int (in, out) ;
electrical in, out ;
parameter real T = 0.1m ;
parameter real tt = 0.02n ;
parameter real td = 0.04m ;
analog begin
// The filter is defined with constant array literals.
V(out) <+ zi_nd(V(in), {0,1}, {1,-1}, T, tt, td) ;
end
endmodule


26.显示结果
:strobe、strobe、strobe、display和$write。
(1)
strobe_task ::=
$strobe [ ( { list_of_arguments } )

module format_module ;
integer ival ;
real rval ;
analog begin
ival = 98 ;
rval = 123.456789 ;
$strobe("Format c gives %c" , ival) ;
$strobe("Format C gives %C" , ival) ;
$strobe("Format d gives %d" , ival) ;
$strobe("Format D gives %D" , ival) ;
$strobe("Format e (real) gives %e" , rval) ;
$strobe("Format E (real) gives %E" , rval) ;
$strobe("Format f (real) gives %f" , rval) ;
$strobe("Format F (real) gives %F" , rval) ;
$strobe("Format g (real)gives %g" , rval) ;
$strobe("Format G (real)gives %G" , rval) ;
$strobe("Format h gives %h" , ival) ;
$strobe("Format H gives %H" , ival) ;
$strobe("Format m gives %m") ;
format_
character
Type of
Argument
Output  Example Output
c or C Integer  ASCII character format
d or D Integer  Decimal format  191, 48, -567
e or E Real  Real, exponential format  -1.0, 4e8,
34.349e-12
f or F Real  Real, fixed-point format 191.04, -4.789
g or G Real  Real, exponential, or decimal format,
whichever format results in the
shortest printed output
9.6001, 7.34E-8,
-23.1E6
h or H Integer  Hexadecimal format  3e, 262, a38, fff, 3E,
A38
o or O Integer  Octal format  127, 777
s or S String
constant
String format
January 2004  144  Product Version 5.1
$strobe("Format M gives %M") ;
$strobe("Format o gives %o" , ival) ;
$strobe("Format O gives %O" , ival) ;
$strobe("Format s gives %s" , "s string") ;
$strobe("Format S gives %S" , "S string") ;
$strobe("newline,\ntab,\tback-slash, \\") ;
$strobe("doublequote,\"") ;
end
endmodule

(2)
display_task ::=
$display [ ( { list_of_arguments } ) ]
(3)
write_task ::=
$write [ ( { list_of_arguments } ) ]

27.指定功耗
pwr_task ::=
$pwr( expression )

// Resistor with power contribution
‘include "disciplines.vams"
Cadence Verilog-A Language Reference
module Res(pos, neg);
inout pos, neg;
electrical pos, neg;
parameter real r=5;
analog begin
V(pos,neg) <+ r * I(pos,neg);
$pwr(V(pos,neg)*I(pos,neg));
end
endmodule

28.处理文件
(1)打开文件
fopen_function ::=
multi_channel_descriptor = $fopen ( “file_name” ) ;

integer myChanDesc ;
myChanDesc = $fopen ( "myfile" ) ;


$fopen("%I:h.freq_dat") ;

打开一个名为.freq_dat的文件。

(2)写入文件
Verilog-A提供了三个用于写入文件的输入/输出函数:fstrobe、fstrobe、fstrobe、fdisplay和$fwrite

1)
fstrobe_function ::=
$fstrobe (multi_channel_descriptor {,list_of_arguments })

integer mcd1 ;
integer mcd2 ;
integer mcd ;
@(initial_step) begin
mcd1 = $fopen("file1.dat") ;
mcd2 = $fopen("file2.dat") ;
end
.
.
.
mcd = mcd1 | mcd2 ; // Bitwise OR combines two channels
$fstrobe(mcd, "This is written to both files") ;

$fdisplay
fdisplay_function ::=
$fdisplay (multi_channel_descriptor {,list_of_arguments })
3)
$fwrite
fwrite_function ::=
$fwrite (multi_channel_descriptor {,list_of_arguments })
(3)关闭文件
Closing a File

file_close_function ::=
$fclose ( multi_channel_descriptor ) ;
29.退出系统
finish_function ::=
$finish [( msg_level )]

30.用户自定义函数
(1)创建
analog_function_declaration ::=
analog function [ type ] function_identifier ;
function_item_declaration {function_item_declaration}
statement
endfunction
(2)调用
analog_function_call ::=
function_identifier ( expression { , expression } )

module phase_detector(lo, rf, if0) ;
inout lo, rf, if0 ;
electrical lo, rf, if0 ;
parameter real gain = 1 ;
function real chopper;
input sw, in;
real sw, in;
chopper = ((sw > 0) ? in : -in);
endfunction
analog
V(if0) <+ gain * chopper(V(lo),V(rf));  //Call from within the analog block.
endmodule

先到这。

8-25 26 veriloga语言相关推荐

  1. 蓝桥杯 算法训练 - 连续正整数的和 78这个数可以表示为连续正整数的和,1+2+3,18+19+20+21,25+26+27。   输入一个正整数 n(<=10000)   输出 m 行(n有m

    问题描述 78这个数可以表示为连续正整数的和,1+2+3,18+19+20+21,25+26+27. 输入一个正整数 n(<=10000) 输出 m 行(n有m种表示法),每行是两个正整数a,b ...

  2. 演示:为思科25/26系列的路由器升级IOS镜像

    IOS是思科路由器和交换机的操作系统,也是思科网络设备的灵魂,完整名称Internet OperatingSystem 取其各个英文单词的首字母故得名IOS.如果说是思科的路由器或交换机功能的强大,不 ...

  3. 告别翻译机和第三方软件,微信自带3个功能轻松翻译26种语言!

    出国留学.境外出差.旅游.社交办公等学习.工作和娱乐,如果自己不懂对方的语言,一般都会用 到翻译机和第三方翻译软件,当然了如果你的工作为你专门配备了一名翻译可以忽略了. 废话不多说,下面带大家看看微信 ...

  4. 2017年4月28日 星期五 --出埃及记 Exodus 25:26

    2017年4月28日 星期五 --出埃及记 Exodus 25:26 Make four gold rings for the table and fasten them to the four co ...

  5. 【2023华为OD笔试必会25题--C语言版】目录

    本专栏收录了华为OD 2022 Q4和2023Q1笔试题目,100分类别中的出现频率最高(至少出现100次)的25道,每篇文章包括题目和我亲自编写并在Visual Studio中运行成功的C语言代码. ...

  6. python入门编程题库-Python随笔30:Python基础编程练习题25~26

    注:本文所有代码均经过Python 3.7实际运行检验,保证其严谨性. 注:本文所有代码均经过Python 3.7实际运行检验,保证其严谨性. Python编程 Python基础练习题25:合并两个列 ...

  7. 银行业务队列简单模拟 (25 分)c语言c++

    7-2 银行业务队列简单模拟 (25 分) 设某银行有A.B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 -- 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客.给定到达银 ...

  8. 11-散列1 电话聊天狂人 (25 分) (C语言)

    浙大版<C语言程序设计实验与习题指导(第3版)>题目集 11-散列1 电话聊天狂人 (25 分) 二.题解 c代码 11-散列1 电话聊天狂人 (25 分) 给定大量手机用户通话记录,找出 ...

  9. ACMNO.26 C语言-字符统计2 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。

    题目描述 编写一函数,由实参传来一个字符串,统计此字符串中字母.数字.空格和其它字符的个数, 在主函数中输入字符串以及输出上述结果. 只要结果,别输出什么提示信息. 输入 一行字符串 输出 统计数据, ...

最新文章

  1. GANs和ODEs:数学建模的终结?
  2. Oracke nls Parameters
  3. 参数估计Bayesian方法的困惑点
  4. Linux内核:关于中断你需要知道的【转】
  5. hadoop学习——Hadoop核心组件
  6. 【图像处理】MATLAB:空间滤波
  7. 8 年经验面试官详解 Java 面试秘诀!
  8. php 对象转xml字符串_php方法simplexml_load_string()解析xml转数组失败
  9. 【数字通信】Matlab实现16QAM调制与解调,判决,误码率计算
  10. Linux系统下查看网卡相关数据
  11. springboot maven项目打包SAPJCO3.JAR
  12. 使用青花瓷对Android app 抓包
  13. 重磅发布:《AI产品经理的实操手册(2021版)——AI产品经理大本营的4年1000篇干货合辑》(PDF)...
  14. CDN 技术研究——Cache集群通信
  15. 内容协商 Spring ContentNegotiation
  16. 微机大作业—— 24秒倒计时器
  17. NANK南卡降噪耳机和OPPO蓝牙耳机哪个更好呢?哪款更能打?
  18. 博士 关于如何做科研?如何阅读文章?如何写综述?等问题……
  19. Person表并添加数据 实例01
  20. 传感器通道波长单位换算

热门文章

  1. 数据库表设计-第三方登录用户表结构设计
  2. javascript中this的工作原理以及注意事项
  3. 三维空间无人机均匀分布——球体包围
  4. 企业微信开源系统,让开发者快速搭建基于企业微信的私域流量运营系统
  5. 几种国内芯片测序格式和 Illumina Omni 位点集格式的对比
  6. 关于某某大学校园网认证系统的一些工作
  7. rainkin教你如何下载flash中的视频
  8. 如何下载网页上的视频和flash的方法
  9. 读研2年,我选择从中科院退学转行写代码
  10. 图像算法工程师需要这样