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