Part Number: ADS7952
Tool/software:
Hi.
I am looking for an HDL behavioral model for FPGA simulation of ADS79xx ( ADS7952 ).
Thank you.
David.
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: ADS7952
Tool/software:
Hi.
I am looking for an HDL behavioral model for FPGA simulation of ADS79xx ( ADS7952 ).
Thank you.
David.
Hi David,
Unfortunately we don't have a Verilog/VHDL behavioral model for the digital communications for this device. I will take this inquiry as a request in case this development occurs in the future.
Regards,
Joel
Gemini wrote this:
// Behavioral model for the Texas Instruments ADS7952 ADC
// Not a cycle-accurate model, but provides basic functionality for simulation.
`timescale 1ns / 1ps
module ADS7952_model (
inout SDO,
input CS,
input SCLK,
input SDI,
inout [3:0] GPIO
);
// Internal state
reg [15:0] shift_reg;
reg [ 3:0] bit_count;
reg sdo_oe;
reg [11:0] adc_mem [11:0]; // Memory for 12 channels
reg [ 3:0] current_channel;
reg auto_mode;
// GPIO registers
reg [ 3:0] gpio_dir; // 0 = input, 1 = output
reg [ 3:0] gpio_out;
// GPIO output enables
assign GPIO[0] = gpio_dir[0] ? gpio_out[0] : 1'bz;
assign GPIO[1] = gpio_dir[1] ? gpio_out[1] : 1'bz;
assign GPIO[2] = gpio_dir[2] ? gpio_out[2] : 1'bz;
assign GPIO[3] = gpio_dir[3] ? gpio_out[3] : 1'bz;
// Initialize memory and registers
integer i;
initial begin
for ( i = 0; i < 12; i = i + 1 ) begin
adc_mem[i] <= i * 256;
end
current_channel <= 0;
auto_mode <= 0;
sdo_oe <= 1'b0;
bit_count <= 0;
// Default GPIO to input
gpio_dir <= 4'b0000;
gpio_out <= 4'b0000;
end
assign SDO = sdo_oe ? shift_reg[15] : 1'bz;
always @(negedge CS) begin
// Start of a new transaction
bit_count <= 0;
sdo_oe <= 1'b1;
// Load the shift register with the result of the previous conversion
shift_reg <= { adc_mem[current_channel], 4'b0000 };
end
always @(posedge CS) begin
// End of transaction
sdo_oe <= 1'b0;
// Decode the command received on SDI
case (shift_reg[15:12])
4'b1000: begin // Manual mode channel select
auto_mode <= 0;
current_channel <= shift_reg[11:8];
end
4'b1010: begin // Auto-1 mode
auto_mode <= 1;
end
4'b0100: begin // GPIO programming
gpio_dir <= shift_reg[9:6];
gpio_out <= shift_reg[5:2];
end
// Other modes are not implemented in this simple model
endcase
// In auto mode, increment channel after each conversion
if (auto_mode) begin
current_channel <= (current_channel == 11) ? 0 : current_channel + 1;
end
end
always @(posedge SCLK) begin
if (!CS) begin
// Shift data in on SDI and out on SDO
shift_reg <= { shift_reg[14:0], SDI };
bit_count <= bit_count + 1;
end
end
endmodule
That doesn't look like a bad place to start. I'm sure there are some improvements to be made, but if you are able to use it for preliminary simulations before hardware gets in, I can help by sharing the expected output of the ADC.
Regards,
Joel
I will say, creating a full, accurate behavioral model will undoubtedly be a more advanced state machine. As far as I know, we haven't released any behavioral models of our devices' digital interface to date. Are you able to test with actual hardware? I'd like to understand how the behavioral model would be expected to be used a little more, and what benefits it brings to your development.
Regards,
Joel
As I see it - HDL behavioral model for helping customers integrate TI's products into products - is a very important selling tool.
It is fairly easy to do - with the current AI tools - just open a git project for doing so - and let AI fill it...
Once you find an error - fix it :-)
The Idea is very simple - The task is to write the FPGA code that glue the CPU to the ADC.
So I write a Test Bench to test my implementation and to give the software guys instructions on how the hardware works.
In this test bench I connect my FPGA design ( the CPU interface to an SPI ) to a "behavioral model of the hardware" that include a behavioral model of the ADC.
This test bench then runs in an HDL simulator and show a "success" if the test passed.
Then the software can do the same steps as the test bench and have a good chance of actually working in production...
Now I have a real problem from real hardware:

In the 1 transaction 0001 | 1 | 0001 | 0 | 0 | 0 | 0000 : channel requested is 1
In the 2 transaction 0001 | 1 | 0010 | 0 | 0 | 0 | 0000 : channel requested is 2
In the 3 transaction 0001 | 1 | 0011 | 0 | 0 | 0 | 0000 : channel requested is 3
Expected channel result is 1 but the channel returned is 0
What did I miss?
Thank you
David
Hi David,
Input data format for manual mode looks correct, but I would try configuring the SPI peripheral as SPI Mode 0 (CPHA = 0, CPOL = 0). Given that, the device might only be seeing 15 clocks.
Regards,
Joel
Thank you for your reply - I did what you suggested and now it works better.
This is my current version for a behavioral model for the ADS7952 - hope it make sense ....
// Behavioral model for the Texas Instruments ADS7952 ADC
// Modified to better reflect the one-frame delay for manual mode programming as per the datasheet.
`timescale 1ns / 1ps
module ADS7952_model (
output SDO,
input CS,
input SCLK,
input SDI,
input [ 3:0] GPIO, // inout
input [11:0] adc_in[11:0]
);
// Internal state
reg [15:0] shift_reg;
reg [ 3:0] bit_count;
reg SDO_out;
reg sdo_oe;
reg [ 3:0] mux_channl_requested; // in the end of transaction we know what channel to sample after delay
reg [ 3:0] mux_channl_delay; // save the requested channel
reg [ 3:0] mux_channl_ready2send; // CS pos edg -> move the mux_channl_delay here
reg auto_mode;
// GPIO registers
reg [ 3:0] gpio_dir; // 0 = input, 1 = output
reg [ 3:0] gpio_out;
// GPIO output enables
assign GPIO[0] = gpio_dir[0] ? gpio_out[0] : 1'bz;
assign GPIO[1] = gpio_dir[1] ? gpio_out[1] : 1'bz;
assign GPIO[2] = gpio_dir[2] ? gpio_out[2] : 1'bz;
assign GPIO[3] = gpio_dir[3] ? gpio_out[3] : 1'bz;
assign SDO = sdo_oe ? SDO_out : 1'bz;
// Initialize memory and registers
integer i;
initial begin
auto_mode <= 0;
sdo_oe <= 1'b0;
shift_reg <= 16'd0;
bit_count <= 0;
// Default GPIO to input
gpio_dir <= 4'b0000; // All inputs
gpio_out <= 4'b0000;
#1;
mux_channl_requested <= 4'hB;
mux_channl_delay <= 4'hB;
mux_channl_ready2send <= 4'hB;
end
// At the start of a transaction, load the shift register with the result
// of the *previous* conversion cycle (for the current_channel).
always @(negedge CS) begin
// Start of a new transaction
bit_count <= 0;
sdo_oe <= 1'b1;
// Load the shift register with the result of the previous conversion
shift_reg <= { mux_channl_ready2send, adc_in[ mux_channl_ready2send ] };
SDO_out <= mux_channl_ready2send[3]; // put shift_reg's msb on the output line
// requested -> mux delay
mux_channl_delay <= mux_channl_requested;
end
// At the end of a transaction, decode the command that was just received
// and set up the state for the *next* transaction.
always @(posedge CS) begin
// End of transaction
sdo_oe <= 1'b0;
SDO_out <= 1'b1;
// next ADC step
// mux delay -> ready
mux_channl_ready2send <= mux_channl_delay;
// Decode the command received on SDI
case (shift_reg[15:12])
4'b0001: begin // Manual Mode (DI15-12 = 0001)
auto_mode <= 0;
// DI11 = 1 enables programming of ‘range and GPIO’
if ( 1'b1 == shift_reg[11 ] ) begin
mux_channl_requested <= shift_reg[10:7]; // DI10-7 = binary address of channel
// shift_reg[ 6 ]; // 0 = Vref 1 = 2*Vref
// shift_reg[ 5 ]; // 1 = power down
// shift_reg[ 4 ]; // in next transaction 0 = output samples channel 1 = output GPIO
gpio_out <= shift_reg[ 3:0];
end
end
// Other modes (like Auto-1) would need to be defined based on their DI15-12 patterns
// If no other patterns are defined, they would fall into a default case.
default: begin
// Handle unimplemented or reserved commands
end
endcase
// After decoding, update the current_channel for the next conversion cycle.
// if (auto_mode) begin
// In auto mode, channel increments after each conversion.
// The programmed_channel is ignored.
// current_channel <= (current_channel == 11) ? 0 : current_channel + 1;
// end else begin
// In manual mode, the next channel to be converted is the one we just programmed.
// current_channel <= programmed_channel;
// end
end
always @(posedge SCLK) begin
if (!CS) begin
// Shift data in on SDI and out on SDO
shift_reg <= { shift_reg[14:0], SDI };
bit_count <= bit_count + 1;
end
end
always @(negedge SCLK) begin
if (!CS) begin
if ( sdo_oe ) begin
SDO_out <= shift_reg[15];
end else begin
SDO_out <= 1'b1;
end;
end
end
endmodule
It seems my understanding of the datasheet is not correct.
In manual mode, If I sample the same channel number 8 in all SPI transactions -
the sampling and conversion and sending is happening on the same transaction.
and not as I understood from the datasheet - that sending should happen on the next transaction - but apparently I was wrong.

In the picture you can see the logic analyzer's pickup.
I have an analog MUX connected to channel 8 of the ADC.
Only MUX input number 4 is connect to VCC to get FFF reading. All other external MUX inputs are connected to GND to give 000.
I sample channel 8 of the ADC while MUX is on 3 to get 000 -> then I sample channel 8 another 2 times on MUX on channel 4 & get FFF twice ->
Then other MUX inputs...
There is NO delay of one SPI transaction - the voltage is converted and sent in the same transaction - NOT as could be understood from the datasheet.
What do I miss?
Thank you.
David.
Hi David,
Where are you gathering what channel the output data corresponds to? Are you able to mark up the image to clarify what you are referring to? The first 4 bits of the output word should also contain the channel address for the corresponding data if DI04 is set to 0.
In manual mode, there should actually be a 2 SPI frame delay between when the channel is selected, and when the corresponding conversion is output.
Regards,
Joel
As explained - and you can see in the timing diagram - the channel selected is 8 - and channel received is 8 - in all transactions!
My external MUX has its 3 select bits in the diagram and all inputs connected to GND except 4 which is connected to VCC.
As you can see - there is no delay - the result of the conversion is sent immediately at the same transaction as the sampled.
I get FFF on selecting external MUX to 4 in the two middle transactions... and 000 in all other channels.
Hi David,
Apologies. I misunderstood the setup. I've read more carefully this time.
The internal ADC MUX is set to channel 8. You also have an external MUX connected to channel 8. On the external MUX, input 4 is is connected to VCC (full-scale), while the other inputs are grounded.
The behavior you are seeing is expected. The input is sampled and held on the falling edge of ~CS. See the timing diagram below (Figure 1), specifically the acquisition and conversion plots.

The paragraph below also clarifies the timing. The device outputs data while the conversion is in progress.

The delay I was referring to is the internal channel switching delay.
Regards,
Joel
Joel
I do not see in the figure 1. where you see that the data sent is in the n'th transaction is from the same n's CS falling edge.
If you look at the Acquisition line - you can see that sample starts at clock 13 of n-1 and ends at the falling edge of the n's CS.
It does not say on the SDO line - to what Conversion, the 12-Bit Conversion Results, belong to - the n's or the (n-1)'s?
So I looked at Figure 51:

Here you can see clearly the delay of one sample from conversion i2c transaction to sending i2c transaction - that is not happening in real IC
If I have "non counterfeit" device :-) in my board...
Do you have in your dev board the ability to test this?
Thank you.
David.
Hi David,
It is the combination (acquisition and conversion) of figure 1 and the text that gives the detail.
The data on SDO belongs to the sample acquired immediately before the conversion cycle, per the datasheet.
In your case, you are not sending a command on SDI to change the channel internal to the device, so there is no internal mux switching delay, and figure 51 does not apply.
So acquisition for the input signal begins on the 14th rising edge of SCLK of frame n, and end when ~CS falls to indicate the start of frame n+1. Conversion for the sample happens at the same time that data on SDO is shifted out.
Let me know if that helps explain the operation a little more clearly.
Regards,
Joel
Joel, Thank you!.
How does the chip know what to do after sampling and converting? in one case it sends the data in the same SPI transaction of sampling - and in the other case it sends the sampled data in the next transaction...? ( sampling is happening in start of current transaction CS falling edge... )
This is very unexpected behavior... since it will find out on what case it is in "in it's past" - channel is selected on bits 10 to 7 and data is sent from bit 11 to 0 :-)
Can you please fix my behavioral model above... just to be clear on what you mean...
Thank you!.
David.
Hi David,
I think to clarify, the device always samples on the falling edge of ~CS for the current input that is selected on the mux. The sampling, conversion, and data output will happen within the same SPI frame.
However, the internal mux switching itself is delayed, so the ADC will take more samples of the same channel before switching.
I've linked a post from my colleague below, which might help to clarify further, and I wish I would have thought to phrase it like that earlier. I think the important part is to differentiate the instance the input signal is sampled, and when the mux switches to allow the input signal to be sampled.
ADS7953: Manual Mode Timing Diagram
Regards,
Joel
Joel,
What is clear is that the datasheet is not clear :-)
Keith's explanation is not helping:
"Here is the flow as presented in Figure 50:
(a) Frame n: * SDI : Programming for ‘frame n +1’, DI10..7 = binary address of channel"
(b) Frame n+1: * Mux : Selects channel programmed in ‘frame n’(Manual mode) this channel will be acquired in this
frame and sampled at start of ‘frame n+2’"
NOT used in my case since I use channel 8 always - No change of internal MUX channel.
"(c) Frame n+2: * Sample: Samples and converts channel selected in ‘frame n+1’"
I could guess that in this transaction the data sent is of the same transaction's sampling... - not explicitly written.
The datasheet does not explain that "sampling converting and sending" are happening on the same transaction.
It is very easy to mistake the internal mux delay for sampling-converting to sending delay.
Thank you.
P.S. I fixed the behavioral model I placed above to reflect my new understanding of the datasheet...
David.
I will test this in the morning and send you a capture of my observations. I will help to clarify the wording in the datasheet. Admittedly, this particular one is often confusing and contradictory.
Regards,
Joel
Hi David,
Apologies for the delayed response on this thread. I haven't gotten a chance to verify this with hardware yet. Please expect an update tomorrow.
Regards,
Joel
It is taking me a bit longer to get the capture solution going. I should have it going tomorrow in order to provide an update.
Regards,
Joel
Hi David,
I realize that my capture solution is just reiterating what is already said in the datasheet, and since you are not changing internal ADC mux channels, it will not be applicable. At the moment, I do not have a way of testing for when the input signal is sampled and converted.
With that said, I see that you have updated the reply above. Does the operation seem clearer now? The mux switching is delayed, not the actual sampling of the input. Let me know if I can close out this thread.
Regards,
Joel