Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

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

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.

8 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.