Systemverilog DPI-C

In reply to dave_59:
Hi Dave, I am a relative new comer to System Verilog hence the question. The system I have is a test board which uses a DSP and FPGA to test, configure and set coefficients in an ASIC. The ASIC has a continuous interrupt back to the FPGA that starts an SPI transmission, which when completed sends an interrupt to the DSP. I have modelled the DSP interface as per one of your previous examples, DPIExport, and using the DSP C code to pre-integrate the DSP and FPGA in a test bench. The test bench is used to call the required functions within the C source code, all works well so far, thank you for the example. I now have to implement the ISR for the interrupt and came across this example of yours; is it easier to modify this accordingly and keep it UVM or can I add the relevant calls and modules to the DPIExport example and modify this?

The following hopefully shows the main calls, the C functions are started by the test_en and the test_no which are passed in from the main test bench.


module adsp (system_clk, system_reset, test_id, test_en, test_done, dsp_addr, dsp_data, dsp_read, dsp_write, dsp_ack, interrupt);

    input system_clk;
    input system_reset;
    input test_en;
    input [7:0] test_id;
    output test_done;
    output [31:0] dsp_addr;
    inout [31:0] dsp_data;
    output dsp_read;
    output dsp_write;
    input dsp_ack;
    input interrupt;

    import "DPI-C" context task c_adsp (input int);
    import "DPI-C" context task interrupt_handler(int int_set);
    export "DPI-C" task adsp_v_read;
    export "DPI-C" task adsp_v_write;
    export "DPI-C" task sv_clk_posedge;
    export "DPI-C" task sv_delay;
    export "DPI-C" function sv_init_mem;
    export "DPI-C" function sv_debug;
    
    int test_no;

    reg dsp_read_reg;
    reg dsp_write_reg;
    reg halt;
    reg [31:0]   ad_reg;
    reg [31:0]   data_reg;
    reg [15:0]  mem[0:15];

    assign zap_id = zap_otp;
    assign dsp_addr = ad_reg;
    assign dsp_data = data_reg;
    assign dsp_read = dsp_read_reg;
    assign dsp_write = dsp_write_reg;
    assign test_no = test_id;
    assign test_done = halt;

    always @(posedge test_en)
    begin : cpu_run
        halt = 0;
        c_adsp(test_no);
        halt = 1;
        #25;
        halt = 0;
    end

    task sv_clk_posedge;
        @(posedge system_clk);
    endtask : sv_clk_posedge

    task adsp_v_read;
        input  address;
        output data;
        int    address;
        int    data;
    begin
        ad_reg <= address;
        #TDARL
        dsp_read_reg <= 0;
        @(posedge dsp_ack);
        #TRW;
        data = dsp_data;
        dsp_read_reg <= 1;
        #TRWR;
    end
    endtask : adsp_v_read

    task adsp_v_write;
        input address;
        input data;
        int   address;
        int   data;
    begin
        ad_reg <= address;
        data_reg <= data;
        #TDAWL;
        dsp_write_reg <= 0;
        @(posedge dsp_ack);
        #TWW;
        dsp_write_reg <= 1;
        #TDWHD;
        data_reg = 32'bz;
        #TRWR;
    end
    endtask : adsp_v_write

    function void sv_init_mem;
        input     index;
        output    data;
        int   index;
        int   data;
        data = mem[index];
    endfunction : sv_init_mem

    task sv_delay (input int t);
      $display("sv_delay: %d ", t);
      #t;
    endtask

    function void sv_debug(string msg, int addr, int data);
        $display("sv_wr_debug: %s %H %H", msg, addr, data);
    endfunction

    initial
    begin
        halt = 0;
        int_done = 0;
        ad_reg = 32'bz;
        data_reg = 32'bz;
        dsp_write_reg <= 1;
        dsp_read_reg <= 1;
        $readmemh("zap_bytes.dat", mem);
    end // initial begin

endmodule : adsp