Search code examples
microcontrollerpicmicrochipmplabadc

How do you run a SCL file in MPLAB without a "Run SCL" button


I have an assembly code for PIC18F458 that gets data from channel 0 (RA0) of ADC and displays the result on PORTC and PORTD.

Therefore, I am trying to stimulate the RA0 pin on a PIC18F458 using a SCL file in the MPLAB X V5.05 Stimulus window.

Although, the file is successfully attached (see Image 1); when I run the simulation, there is no way of confirming if the SCL is actually being ran, aside from the ADRESL and ADRESH regsiters not containing any values (see image 2).

Simulator Window without Run SCL button

Simulator Window without Run SCL button

No data in ADRESH and ADRESL registers

No data in ADRESH and ADRESL registers

Additionally, I do not have a "Run SCL" button; unlike the other examples that I have seen online. (Please see image 1 above)

UPDATE:

Slightly modifying the examples provided by @Kozmotronik, I have been able to confirm that the SCL file is running and the injection of data onto the AIO pin. Therefore, this particular question can now be considered closed!!


Solution

  • After some research in SCL Code Repo and SCL User's guide that is provided within MPLAB IDE help, and also after some test, I couldn't manage to get values from a file even with a direct SCL code. The SCL code I used first is the following:

    configuration for "pic18f458" is
    end configuration;
    
    testbench for "pic18f458" is
    begin
        // Register Injection
        process is
        file fileVar : text;
        variable status : file_open_status;
        variable val : integer;
        begin
            report("Analog injection started...");
            file_open(status, fileVar, "<data_file_path>", read_mode);
            if status == open_ok then
                report("Reading the values file...");
                while endfile(fileVar) == false loop
                    read(fileVar, val);
                    wait until ADCON0.GO_nDONE == '1';
                    report("Conversion started");
                    wait until ADCON0.GO_nDONE == '0';
                    report("Conversion ended");
                    if ADCON1.ADFM == '0' then  -- left justified
                        ADRESH <= val / 4;
                        ADRESL <= val * 64;
                    else                        -- right justified
                        ADRESH <= val / 256;
                        ADRESL <= val;
                    end if;
                end loop;
            file_close(fileVar);
            wait;
            end if;
        end process;
    
    end testbench;
    

    I did saw the report strings in the simulator output but the ADRES registers are always injected with 0xFFFF value. I tried modified versions with no success.


    However, when I decided to modify the SCL code and give it a try with an in-code variable it did worked. The values of the in-code variable were injected correctly. From this case I figured out that the file read operation fails in somewhere and can't get the value from the file correctly. The latter working SCL code is the following:

    configuration for "pic18f458" is
    end configuration;
    
    testbench for "pic18f458" is
    begin
        // Register Injection
        process is
        file fileVar : text;
        variable status : file_open_status;
        variable val : integer;
        begin
            report("Analog injection started...");
            val := 7;
            while val < 1024 loop
                wait until ADCON0.GO_nDONE == '1';
                report("Conversion started");
                wait until ADCON0.GO_nDONE == '0';
                report("Conversion ended");
                if ADCON1.ADFM == '0' then  -- left justified
                    ADRESH <= val / 4;
                    ADRESL <= val * 64;
                else                        -- right justified
                    ADRESH <= val / 256;
                    ADRESL <= val;
                end if;
                val := val * 8;
            end loop;
            report("Analog injection ended...");
            wait;
        end process;
    
    end testbench;
    

    The above SCL code will inject the actual value of the val variable everytime an ADC conversion ends (GO_nDONE bit first goes high and when the conversion is completed goes low). The value injection is made depending on the ADFM bit. if it is set to 0 the value will be left justified, otherwise will be right justified.

    So I have posted an issue in the microchip forums regarding this matter. Let's see how it will be resolved.


    Well if the values need not to be very specific you can make use of the second SCL code. However, in order to enable register injection in MPLABX IDE you need to configure the simulator first. To do this

    1. Open the project properties window by clicking File -> Project Properties in the menu.
    2. Then from categories section select Simulator.
    3. Select Periph: ADC1 from the Option categories in the right pane.
    4. Finally make sure that Use MPLAB 8 Style Stimulus/SCL for ADCxBUF0 is checked as in the following image.

    enter image description here

    Once you've configured it open the stimulus window, first start the simulation once so that it shows its content and then click on Attach SCL file icon to attach your SCL file and finally restart the simulation with the newly attached SCL.


    UPDATE

    I just simplified this example from the SCL repository and boom it works!

    What I change in the code is; I was reading from the text file directly into the SCL variable which gives me no success, with the help of the SCL repo example, I created a line variable called dline, I read from a file into the dline using readline() builtin function, then I read from dline into the val variable using the read() function which resulted with success. The ADRES registers did injected with the correct values by each reading. Here is the updated code:

    end configuration;
    
    testbench for "pic18f458" is
    begin
        // Register Injection
        process is
        file fileVar : text;
        variable status : file_open_status;
        variable dline : line;
        variable val : integer;
        begin
            report("Analog injection started...");
            file_open(status, fileVar, "<data_file_path>", read_mode);
            if status == open_ok then
                report("Reading the values file...");
                while endfile(fileVar) == false loop
                    wait until ADCON0.GO_nDONE == '1';
                    readline(fileVar, dline);
                    read(dline, val);
                    report("Conversion started");
                    wait until ADCON0.GO_nDONE == '0';
                    report("Conversion ended");
                    if ADCON1.ADFM == '0' then  -- left justified
                        ADRESH <= val / 4;
                        ADRESL <= val * 64;
                    else                        -- right justified
                        ADRESH <= val / 256;
                        ADRESL <= val;
                    end if;
                end loop;
            file_close(fileVar);
            wait;
            end if;
        end process;
    
    end testbench;
    

    Here is the data file. Note that the values are separated with new lines:

    1
    3
    7
    15
    31
    63
    127
    255
    511
    755
    927
    1023
    1015
    988
    775
    550
    285
    137
    79
    47
    24
    12
    5
    1