Would someone help me please?
I don't claim to be a Verilog modelling expert, but I once wrote a vco model
in Verilog to prove to some people that it could be done.
To pass an analog value into a Verilog module, you have to create a 64-bit wire
port. You then use system functions like $bitstoreal to convert the wire at
the port to a real number inside the module. Once you have real numbers inside
the module, you can do anything you want.
/Steve
The following are 2 limited-capability analogue models for
1. Analog-To-Digital and
2. Digital-to-analog
that show some of the limited capability of verilog for
analog modeling. The capability is limited and
the model shows
a. The existence and the use of system tasks for transferring
"binary equivalents" to real numbers, which can then be
used for writing behavioral models in Verilog (i.e. using
$bitstoreal...)
However, the models does not demonstrate the weakness of
Verilog to describe some important analog behavior such as
1. continuous-time/analog signals, binary equivalents are
used for behavioral representation.
2. Limitations of Verilog-HDL to represent KCL, KVL node equations.
3. Absence of differentiator-integrator operators.
4. Absence of Analog components (inductors, voltage source
... etc.) and functional-blocks/templates.
5. Difficult to model transfer (Laplace and Z-domain)
functions.
6. Difficult to model non-linear voltage/current dependant
sources.
7. Control flow mechanisms that exist with current
Verilog-HDL are not sufficient to meet the control
requirements for both time-domain and frequency-domain
analysis.
(of course similar arguments apply to CURRENT VHDL -- 1076)
The models are described below -: Please note, I do not have
access to a Verilog simulator at present and hence the models
have not been tested lately. A better solution, as someone has
already pointed out is to look at Mixed-mode solutions (for
time-domain behavioral modeling) -- assuming that you want
to do some analog+digital.
/************************************************************************
Analog to Digital convertor
Parameters:
N - Number of bits (compiled into model)
Inputs:
Vin (analog) - Input voltage to be converted
Vref (analog) - Reference voltage
Clk (digital) - clock
StartConv (digital) - Start conversion
Outputs:
Dout [N-1:0] (digital) - digital output
Eoc (digital) - end of conversion
Operation:
On the falling edge of StartConv, the input Vin
is sampled and the conversion is started. If StartConv
rises before the conversion is complete, the conversion
will not complete and the output will show the incomplete
conversion.
The conversion requires N+1 falling edges of clk to
complete. On the last falling edge of clk, eoc will be set
to 0. Eoc will remain 0 until StartConv is reset to 1.
With Vin <= 0, the output will be zero. With Vin >= Vref,
the output will have all bits set. In between, the output
is linear with the input. The output will change during
the conversion until the eoc. It will then hold that value
until the next StartConv.
The block represents the Verilog behavioral model for the
ADC, where vin_bits is the "binary equivalent" of the
analog input, vref_bits is the "binary equivalent" of the
analog reference voltage, Dout is the binary output
signal, eoc is the end-of-conversion flag, StartConv is
the signal used to start/end the operations of the Verilog
module, vin_d_bits and vin_t_bits are used to determine
the value of vin at any time ($time in Verilog).
The Verilog task "ADConversion" uses $bitstoreal to
convert binary versions of the analog signals to real
numbers and determines the digital output Dout (if vin >
vref the output Dout will have all bits set to 1 and if
vin <= 0 the digital output bits are set to 0, if (0 < vin
< vref) the output is linear with the input). The
behavioral models utilize the ability to model
mathematical equations in Verilog (using real numbers).
The model uses only binary equivalents and demonstrates
the weakness of Verilog to represent real analog
(continuous) signals.
I am not sure whether $bitstoreal ..etc are part of the
OVI Language Reference Manual -- do not have one handy!
***********************************************************/
`timescale 1ns / 1ns
`define N 16 /* Number of bits of the ADC */
`define N1 15
module adc( startConv, clk, eoc, Vin_bits, Vin_d_bits, Vin_t_bits,
Vref_bits, Dout );
/*
* startConv : start conversion signal; conversion starts at falling edge
* clk : clock signal; digital signal
* eoc : end of conversion; goes low when conversion done;
* Vin_bits : binary version of real input data
* Vref_bits : binary version of reference voltage
* stobe : samples input data on rising edge of strobe
* Dout : binary output data
*/
input startConv, clk, Vin_bits, Vin_d_bits, Vin_t_bits, Vref_bits;
output Dout, eoc;
wire [63:0] Vin_bits, Vin_d_bits, Vin_t_bits;
wire [63:0] Vref_bits;
reg [`N1:0] Dout;
reg eoc;
real Vin, Vin_d, Vin_t, Vsample, Vref, Vdac, Vbit;
integer i;
reg [`N1:0] bit;
reg [`N1:0] fullScale;
initial begin
eoc = 1;
Dout= `N'b0;
end
always @ (negedge startConv) ADconversion;
always @ (posedge startConv) begin
disable ADconversion;
eoc = 1;
end
task ADconversion;
begin
eoc = 1;
Dout= `N'b0;
fullScale= 'b0;
fullScale= ~fullScale ;
Vin = $bitstoreal( Vin_bits );
Vin_d = $bitstoreal( Vin_d_bits );
Vin_t = $bitstoreal( Vin_t_bits );
// find the value of Vin corresponding to the present time.
Vsample = Vin + Vin_d * ($time - Vin_t);
Vref = $bitstoreal( Vref_bits );
// $display("%0d start ADC, input = %g", $time, Vin);
Vdac = 0.0;
bit = `N'b1 << (`N1);
i = `N1;
repeat (`N) begin
@ (negedge clk) Vbit= (bit*Vref)/fullScale;
Vdac= Vdac + Vbit;
if (Vdac >= Vsample) begin
Dout[i] = 1'b0;
Vdac = Vdac - Vbit;
end
else begin
Dout[i] = 1'b1;
end
// $display("%0d clk= %b startConv= %b eoc= %b bit= %b Dout= %h Vdac= %g",
// $time, clk, startConv, eoc, bit, Dout, Vdac);
bit = bit >> 1;
i = i - 1;
end
@ (negedge clk) eoc = 0;
end
endtask
endmodule
/********************************************************************
Parameters: N - Number of bits (compiled into model)
Inputs:
Din [N-1:0] (digital) - digital input
Vref (analog) - Reference voltage
Clk (digital) - clock
StartConv (digital) - Start conversion
Outputs:
Vout (analog) - Input voltage to be converted
Eoc (digital) - end of conversion
Operation:
On the falling edge of StartConv, the input Din is
sampled and the conversion is started. If StartConv rises
before the conversion is complete, the conversion will not
complete and the output will not change. The conversion
requires N+1 falling edges of clk to complete. On the last
falling edge of clk, eoc will be set to 0 and the output
will appear. Eoc will remain 0 until StartConv is reset to
1.
The output will be linear with the input, and in the
range 0 to Vref. The output will change only at the eoc.
It will then hold that value until the next eoc.
The Verilog task DAConversion is enabled at the negedge of
StartConv and uses $bitstoreal and $realtobits (to convert
the real numbers to binary equivalents of the analog
output).
DAC Verilog Behavioral model
************************************************************/
`timescale 1ns / 1ns
`define N 16 /* Number of bits of the ADC */
`define N1 15
`define TTIME 10 /* output transition time */
module dac( startConv, clk, eoc, Din, Vref_bits,
Vout_bits, Vout_d_bits, Vout_t_bits );
/*
* startConv : start conversion signal; conversion starts at falling edge
* clk : clock signal;
* eoc : end of conversion; goes low when conversion done;
* Din : digital input vector
* Vref_bits : binary version of reference voltage
* Vout_bits : analog output (in binary form)
*/
input startConv, clk, Din, Vref_bits;
output Vout_bits, Vout_d_bits, Vout_t_bits, eoc;
reg [63:0] Vout_bits, Vout_d_bits, Vout_t_bits;
reg eoc;
wire [63:0] Vref_bits;
wire [`N1:0] Din;
reg [`N1:0] Din_sample;
real Vin, Vref, Vdac, Vbit, Vout_d, tmp_time;
integer i;
reg [`N1:0] bit;
reg [`N1:0] fullScale;
initial begin
eoc = 1;
Vdac=0.0;
Vout_bits= $realtobits(Vdac);
end
always @ (negedge startConv) DAconversion;
always @ (posedge startConv) begin
disable DAconversion;
eoc = 1;
end
task DAconversion;
begin
// $display("%0d start DAC, input = %h", $time, Din);
eoc = 1;
Vdac=0.0;
Din_sample = Din;
fullScale= 'b0;
fullScale= ~fullScale ;
bit=1'b1 << (`N1);
Vref = $bitstoreal( Vref_bits );
Vdac = 0.0;
i = `N1;
Vbit= Vref / fullScale;
repeat (`N) begin
@ (negedge clk)
if (Din_sample[i]) Vdac= Vdac + (bit*Vbit);
// $display("%0d clk= %b startConv= %b eoc= %b bit= %b Vdac= %g ",
// $time, clk, startConv, eoc, bit, Vdac);
i = i - 1;
bit = bit >> 1;
end
@ (negedge clk)
Vout_d = (Vdac - $bitstoreal(Vout_bits)) / `TTIME;
Vout_d_bits = $realtobits(Vout_d);
tmp_time = $time;
Vout_t_bits = $realtobits(tmp_time);
#`TTIME
Vout_bits = $realtobits(Vdac);
Vout_d_bits = $realtobits(0.0);
tmp_time = $time;
Vout_t_bits = $realtobits(tmp_time);
eoc = 0;
end
endtask
endmodule