下面以一个16位ADC为例:
建议先看第一节
//头文件
`include "discipline.h"
`include "constants.h"
`define NUM_ADC_BITS 16//有效位数
//模块名
module a2d_ideal (vin, clk, dout);
//输入输出
input vin, clk;
electrical vin, clk;
output [`NUM_ADC_BITS-1:0] dout;
electrical [`NUM_ADC_BITS-1:0] dout;
//定义常量/变量
parameter real vmax = 2.5;
parameter real vmin = 0;
parameter real one = 2.5;
parameter real zero = 0.0;
parameter real vth = 2.5;
parameter real slack = 10.0p from (0:inf);
parameter real trise = 10p from (0:inf);
parameter real tfall = 10p from (0:inf);
parameter real tconv = 10p from [0:inf);
parameter integer traceflag = 0;
real sample, vref, lsb, voffset;
real vd[0:`NUM_ADC_BITS-1];
integer ii, binvalue;
//电路开始
analog begin
@(initial_step or initial_step("dc", "ac", "tran", "xf")) begin
//初始化
vref = (vmax - vmin) / 2.0;
lsb = (vmax - vmin) / (1 << `NUM_ADC_BITS) ;
voffset = vmin;
if (traceflag)
$display("%M ADC range ( %g v ) / %d bits = lsb %g volts.\n",
vmax - vmin, `NUM_ADC_BITS, lsb );
generate i ( `NUM_ADC_BITS-1, 0) begin
vd[i] = 0 ;
end
end
@(cross ( V(clk)-vth, 1, slack, clk.potential.abstol)) begin
//边沿触发事件,1 上升沿运行下面程序
binvalue = 0;
sample = V(vin) - voffset;
for ( ii = `NUM_ADC_BITS -1 ; ii>=0 ; ii = ii -1 ) begin
vd[ii] = 0;
if (sample > vref ) begin
vd[ii] = one;
sample = sample - vref;
binvalue = binvalue + ( 1 << ii );
end
else begin
vd[ii] = zero;
end
sample = sample * 2.0;
end
if (traceflag)
$strobe("%M at %g sec. digital out: %d vin: %g (d2a: %g)\n",
$abstime, binvalue, V(vin), (binvalue*lsb)+voffset);
end
//输出
generate i ( `NUM_ADC_BITS-1, 0) begin
V(dout[i]) <+ transition ( vd[i] , tconv, trise, tfall );
end
end
endmodule
`undef NUM_ADC_BITS
知识点总结:
generate i ( `NUM_ADC_BITS-1, 0) begin//不需要定义i,从大到小循环(习惯上所有循环都是从大到小)
//循环体
end
以上程序是一个16bit理想 ADC程序,按照第一节的步骤在程序中做了标记,在编写其他电路时可以参考以上部分源代码,活学活用。
下面以一个16位ADC为例:
建议先看第一节
//头文件
`include "discipline.h"
`include "constants.h"
`define NUM_ADC_BITS 16//有效位数
//模块名
module a2d_ideal (vin, clk, dout);
//输入输出
input vin, clk;
electrical vin, clk;
output [`NUM_ADC_BITS-1:0] dout;
electrical [`NUM_ADC_BITS-1:0] dout;
//定义常量/变量
parameter real vmax = 2.5;
parameter real vmin = 0;
parameter real one = 2.5;
parameter real zero = 0.0;
parameter real vth = 2.5;
parameter real slack = 10.0p from (0:inf);
parameter real trise = 10p from (0:inf);
parameter real tfall = 10p from (0:inf);
parameter real tconv = 10p from [0:inf);
parameter integer traceflag = 0;
real sample, vref, lsb, voffset;
real vd[0:`NUM_ADC_BITS-1];
integer ii, binvalue;
//电路开始
analog begin
@(initial_step or initial_step("dc", "ac", "tran", "xf")) begin
//初始化
vref = (vmax - vmin) / 2.0;
lsb = (vmax - vmin) / (1 << `NUM_ADC_BITS) ;
voffset = vmin;
if (traceflag)
$display("%M ADC range ( %g v ) / %d bits = lsb %g volts.\n",
vmax - vmin, `NUM_ADC_BITS, lsb );
generate i ( `NUM_ADC_BITS-1, 0) begin
vd[i] = 0 ;
end
end
@(cross ( V(clk)-vth, 1, slack, clk.potential.abstol)) begin
//边沿触发事件,1 上升沿运行下面程序
binvalue = 0;
sample = V(vin) - voffset;
for ( ii = `NUM_ADC_BITS -1 ; ii>=0 ; ii = ii -1 ) begin
vd[ii] = 0;
if (sample > vref ) begin
vd[ii] = one;
sample = sample - vref;
binvalue = binvalue + ( 1 << ii );
end
else begin
vd[ii] = zero;
end
sample = sample * 2.0;
end
if (traceflag)
$strobe("%M at %g sec. digital out: %d vin: %g (d2a: %g)\n",
$abstime, binvalue, V(vin), (binvalue*lsb)+voffset);
end
//输出
generate i ( `NUM_ADC_BITS-1, 0) begin
V(dout[i]) <+ transition ( vd[i] , tconv, trise, tfall );
end
end
endmodule
`undef NUM_ADC_BITS
知识点总结:
generate i ( `NUM_ADC_BITS-1, 0) begin//不需要定义i,从大到小循环(习惯上所有循环都是从大到小)
//循环体
end
以上程序是一个16bit理想 ADC程序,按照第一节的步骤在程序中做了标记,在编写其他电路时可以参考以上部分源代码,活学活用。