I want to call seqence from the task of export “DPI-C” task.
Are there the other method except the inferface?
In reply to birdluo:
Sound a little bit confusing to me.
Do you want to start a sequence from a piece of C-code? Is this right?
This is possible but it complicates the common mechanism.
In reply to chr_sue:
yes.
the mechanism is for c code. the code is from software team.
the function of c code is write and read register.
so the sequence of uvm vip(apb,axi,ahb) should be called by c code.
In reply to birdluo:
the flow is as below:
[] the c code call task.
[] the task call sequence.
how to fix the issue if the interface is not used?
In reply to birdluo:
The DPI allows you to call SV tasks from C-code and c-subroutines from SV tasks and functions.Calling a sequence is impossibel. What is executed during simulation is the body-task of a sequence. You could call in this body-task c-subroutines with your register commands.
In reply to birdluo:
I faced the similar problem recently. I did the following for it.
package dpi_seq_pkg;
import "DPI-C" context task C_Program();
export "DPI-C" task sv_write;
export "DPI-C" task sv_read ;
int Addr, Data;
enum {WRITE, READ} kind;
event cmd_start, seq_done;
task sv_write(input int A, D);
kind = WRITE; Addr = A; Data = D;
->cmd_start;
@(seq_done);
return;
endtask : sv_write
task sv_read(input int A, output int D);
kind = READ; Addr = A;
->cmd_start;
@(seq_done);
D = Data;
return;
endtask : sv_read
endpackage : dpi_seq_pkg
task DPI_sequence::body()
fork
// C Program
dpi_seq_pkg::C_Program();
forever
begin : program_rendering
wait (dpi_seq_pkg::cmd_start.triggered);
if(dpi_seq_pkg::kind == dpi_seq_pkg::WRITE)
begin
agent_write_sequence api_wr_seq = agent_write_sequence::type_id::create("api_wr_seq");
api_wr_seq.Addr = dpi_seq_pkg::Addr;
api_wr_seq.Data = dpi_seq_pkg::Data;
api_wr_seq.start(m_sequencer, this);
end
if(dpi_seq_pkg::kind == dpi_seq_pkg::READ)
begin
agent_read_sequence api_rd_seq = agent_write_sequence::type_id::create("api_rd_seq");
api_rd_seq.Addr = dpi_seq_pkg::Addr;
api_rd_seq.start(m_sequencer, this);
dpi_seq_pkg::Data = api_rd_seq.Data;
end
-> dpi_seq_pkg::seq_done;
end // Program_rending
join_any
disable : fork;
.
.
.
extern "C" void sv_write(int, int );
extern "C" void sv_read (int, int *);
extern "C" void C_Program(void)
{
int * RDATA;
sv_write( 20, 5);
sv_write(100,15);
sv_read (20, RDATA);
cout << " RDATA : " << RDATA << endl;
return;
}
How do you think about this way?
In reply to serizawa:
the example (C_stimulus_pkg.tgz) of dave_59 is ok with cadence tool.
but the code will be modified.
old code
svSetScope(svGetScopeFromName(“c_stimulus_pkg”));
good code
svSetScope(svGetScopeFromName(“c_stimulus_pkg::”));
Maybe this is helpful for you.
In reply to serizawa:
I came up with a better idea.
package dpi_seq_pkg;
import "DPI-C" context task C_Program();
export "DPI-C" task sv_write;
export "DPI-C" task sv_read ;
import uvm_pkg::*;
uvm_sequencer_base sqr;
uvm_sequence seq;
task DPI_start(uvm_sequencer_base sqr_, uvm_sequence seq_);
sqr = sqr_;
seq = seq_;
C_Program();
endtask
import agent_pkg::*;
task sv_write(input int A, D);
agent_write_sequence api_wr_seq = agent_write_sequence::type_id::create("api_wr_seq");
api_wr_seq.Val_A = A;
api_wr_seq.Val_D = D;
api_wr_seq.start(sqr, seq);
endtask : sv_write
.
.
.
endpackage
In an UVM Sequence
task DPI_sequence::body()
// C Program
dpi_seq_pkg::DPI_start(m_sequencer, this);
C program is generating UVM sequence via exported SV tasks inside dpi_seq_pkg. To make it possible, the handles to UVM sequencer and UVM sequence are passed to dpi_seq_pkg in the similar manner of UVM sequence start.
I think this is a simpler and more straightforward way without using a register model.
You can find my example in GitHub here.
I was facing the same issue, so i have taken extra refmodule now i can assign my response of c to the variables of this refmodule, so this can be used for scoreboard comparison.
module refmod;
int paddr,prdata;
endmodule
export "DPI-C" function read1;
function void read1(int paddr, prdata);
refmod.paddr=paddr;
refmod.prdata=prdata;
$display("\n response method paddr=%0d prdata=%0d",paddr,prdata);
endfunction