Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.
21618 Discussions

Max 10 ADC Simulation - Can't get it to work properly

Altera_Forum
Honored Contributor II
2,737 Views

Hi all, 

 

I'm trying to simulate a MAX 10 design using the internal ADC before I get real hardware and I'm only having partial success. 

 

I've now produced my own design and experimented with the design here: https://cloud.altera.com/devstore/platform/15.0.0/adc-and-audio-monitor/ Both use the "Standard sequencer with external sample storage" versions of the "Altera Modular ADC Core". 

 

With both, I can get the designs to successfully compile and simulate but the results aren't as expected. The ADC sequencer has a control register that needs to be set to 0x00000001 to enable the ADC. Both sets of code write this value into the control register and it can be successfully read back. However, the ADC outputs adc_response_valid, adc_response_channel, adc_response_data etc are all stuck at zero. 

 

Now, these results suggest to me that I'm either doing something wrong or that the model for the ADC is only partially complete. 

 

Has anybody produced a successful simulation of a MAX 10 ADC? I'm perfectly happy with it producing 0x000 or 0xXXX for the data but I would like the valid and channel values to toggle. 

 

Thanks for any help.
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
1,373 Views

Is there a way for you to simulate it? how do you simulate an input analog signal to the ADC IP? 

All these while im doing hardware, and I monitor on the stp signals vs adc toolkit. I didnt know there is a way to simulate it.
0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

A good simulation model will allow you to input the analogue value is some way even if it is just a fixed value. This doesn't bother me much, I'm interested in simulating the handshaking on the output so I know my code is ok.

0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

What simulation tools are you using? Modelsim?  

How does the testbench insert analog signal to the ANA input pins?  

How to write the testbench to represent an analog signal (even at fixed value)? 

 

Appreciate if you could shed some light.
0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

I'm using Modelsim though the simulator used doesn't make any difference. 

 

In the Max 10 implementation, the ADC pins aren't exposed in the verilog code so you can't access them directly to feed in a signal which is unfortunate. If it was written differently then for simulation only, then you could have a real data type signal as input to represent the analogue value. 

 

There is lots you can do in a test bench to model analogue stuff. In the past I modelled the currents in the inductor of buck switcher which was being controlled by an FPGA. It enabled me to do a complete end to end sim. The analogue stuff was crude but good enough for what I needed. 

 

Here is a brief code snippet of the test bench to give you an idea, don't worry about the details of what it does, just get a feel. It recalcs the currents every nanosecond. 

 

localparam voltagediffpos = 22.0; localparam voltagediffneg = 2.0; localparam inductance = 3.5E-6; localparam fullscalecurrent = 11.0; localparam voltagelaser = 1.3; localparam resistancelaser = 0.05; localparam capacitancecapacitor = 10E-6; real current_inductor ; real current_laser_capacitor ; real current_laser; real current_target ; real voltage_capacitor ; integer j; initial begin for (j = 0; j < 16; j = j + 1) begin current_inductor <= 0.0; current_laser_capacitor <= 0.0; current_laser <= 0.0; current_target <= 0.0; voltage_capacitor <= 0.0; end end genvar i; generate for (i = 0; i < 16; i = i + 1) begin: current_calc always begin # 1 current_target <= $itor(voltages)*fullscalecurrent/4096.0; current_laser_capacitor <= (short_fet) ? 0.0 : current_inductor; if (buck_fet) begin current_inductor <= current_inductor + voltagediffpos*1E-9/inductance; end else begin if ((current_inductor - voltagediffneg*1E-9/inductance) > 0) begin current_inductor <= current_inductor - voltagediffneg*1E-9/inductance; end else begin current_inductor <= 0.0; end end if (short_fet) begin voltage_capacitor <= 0.0; current_laser <= 0.0; end else begin if (voltage_capacitor < voltagelaser) begin current_laser <= 0.0; end else begin current_laser <= (voltage_capacitor - voltagelaser) / resistancelaser; end voltage_capacitor <= voltage_capacitor + (current_laser_capacitor - current_laser) * 1E-9 / capacitancecapacitor; end end assign comparitor = (current_laser_capacitor > current_target); end endgenerate
0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

Hi, there is a video clip regarding on max 10 ADC measurement perhaps it might give you some ideas 

https://www.youtube.com/watch?v=3i2lv9ssypu
0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

Thanks irish but that vid doesn't mention simulation at all. 

 

I've now got real hardware and can confirm that the simulation doesn't drive the response signals at all though I am setting the ADC up correctly. 

 

To get around my simulation issue I wrote the following. Maybe it is of use to somebody. It is in noway functionally complete. 

 

module ADCModel ( input clock_clk, input reset_sink_reset_n, input adc_pll_clock_clk, input adc_pll_locked_export, input sequencer_csr_address, input sequencer_csr_write, input sequencer_csr_writedata, input sequencer_csr_read, output reg sequencer_csr_readdata = 32'd0, output reg response_valid = 1'd0, output reg response_channel = 5'd0, output reg response_data = 12'd0, output reg response_startofpacket = 1'b0, output reg response_endofpacket = 1'b0 ); wire go = reset_sink_reset_n && adc_pll_locked_export && sequencer_csr_readdata; always @ (posedge clock_clk) begin if (sequencer_csr_write && !sequencer_csr_address) begin sequencer_csr_readdata <= sequencer_csr_writedata; end end localparam NUMBER_OF_CHANNELS = 5'd4; reg adc_clk_store = 2'd0; wire response_channel_next = (response_channel >= NUMBER_OF_CHANNELS - 5'd1) ? 5'd0 : response_channel + 5'd1; always @ (posedge clock_clk) begin adc_clk_store <= {adc_clk_store, adc_pll_clock_clk}; if (go) begin if (adc_clk_store == 2'b10) begin response_valid <= 1'b1; response_channel <= response_channel_next; response_startofpacket <= (response_channel_next == 5'd0); response_endofpacket <= (response_channel_next == NUMBER_OF_CHANNELS - 5'd1); case(response_channel_next) 5'd0: response_data <= 12'h111; 5'd1: response_data <= 12'h222; 5'd2: response_data <= 12'h333; 5'd3: response_data <= 12'h444; endcase end else begin response_valid <= 1'b0; response_channel <= 5'd0; response_data <= 12'd0; response_startofpacket <= 1'd0; response_endofpacket <= 1'd0; end end else begin response_valid <= 1'b0; response_channel <= 5'd0; response_data <= 12'd0; response_startofpacket <= 1'b0; response_endofpacket <= 1'b0; end end endmodule
0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

so, with the modified testbench, will it emulate the analog input signal? 

 

As much as i understand, we can only check the ADC behaviour with hardware testing.  

If there is any kind of simulation that can actually test the behaviour, would very much like to know about it.
0 Kudos
Altera_Forum
Honored Contributor II
1,373 Views

The above code sets the ADC output values to fixed numbers (12'h111, 12'h222 etc) but this could easily be changed to a sinewave or whatever you want. 

 

It is a little harder to control this value from the testbench but I don't believe it is impossible. 

 

In general, if you can model your outside world in the test bench (like I did with my inductor capacitor buck converter model) then you can simulate the whole thing in its operating environment. The biggest issue is that the analogue world tends to work in the milliseconds to seconds realm and that can take a little while to simulate.
0 Kudos
Reply