Sie sind auf Seite 1von 14

`ifndef AL_ICAS_SLV_SM

`define AL_ICAS_SLV_SM

`include "icas_macros.svh"
class icas_slv_sm extends uvm_object;

`uvm_object_utils(icas_slv_sm)
//uvm macro
virtual interface icas_interface.icas_monitor_if icas_intf;
//interface handle
icas_configuration cfg;

bit [9:0] addr;


//Signals
bit rnw;
bit [7:0] icmd;
bit rcv_tbit;
bit chk_ack_n;
bit local_ack_n;
bit [7:0] rcv_byte;
bit wr_data_state;
bit rd_data_state;
bit ack_state;
bit check_arb;
bit arb_lost;

//Events

uvm_event start_ev;
uvm_event stop_ev;
uvm_event arb_loss_ev;
uvm_event send_ack_ev;
uvm_event send_slv_enum_ev;
uvm_event rd_st_ev;
uvm_event send_slv_rd_ack_ev;

function new(string name = "icas_slv_sm");


super.new(name);
start_ev = new("start_ev");
stop_ev = new("stop_ev");
arb_loss_ev = new("arb_loss_ev");
send_slv_enum_ev = new("send_slv_enum_ev");
send_ack_ev = new("send_ack_ev");
rd_st_ev = new("rd_st_ev");
send_slv_rd_ack_ev =new("send_slv_rd_ack_ev");
endfunction : new

//External tasks
extern task run_slv_sm();
extern task receive_byte(output bit[7:0] rcv_byte);
extern task chk_ack(output bit chk_ack_n);
extern task chk_local_ack(output bit local_ack_n);
extern task receive_tbit(output bit rcv_tbit);
extern function void set_cfg(icas_configuration cfg_in);
extern task slv_wr();
extern task slv_st_sp_det();

endclass :icas_slv_sm
`protect

task icas_slv_sm::run_slv_sm();

//Signals
//bit [$clog2(`NUM_SLV_SM_STATES)-1:0]icas_intf.state; //Present and
next state
//bit [31:0]state;
bit prog = 1'b1;

//Parameters

parameter IDLE_ST = 0;
parameter ADDR1_ST = 1;
parameter RCV_ICMD_ST = 2;
parameter RX_PVT_XFER_ST = 3;
parameter STOP_DET_ST = 4;
parameter BRW_ST = 5;
parameter U_PVT_RD_ST = 6;
parameter U_PVT_WR_ST = 7;
parameter B_PVT_ADDR_ST = 8;
parameter B_PVT_RD_ST = 9;
parameter B_PVT_WR_ST = 10;
parameter STATIC_ADDR_ST = 11;
parameter SET_ICMD_ST = 12;
parameter GET_ICMD_ST = 13;
parameter NO_DATA_ICMD_ST = 14;
parameter DDR_ST = 15;
parameter SEND_ENUM_REGS_ST = 16;
parameter RCV_ENUM_ST = 17;
parameter RCV_DYN_ADDR_ST = 18;
parameter STATIC_ADDR_NAK_ST = 19;
parameter SEND_STAT_ADDR_ST = 20;

icas_intf.state=IDLE_ST;
forever begin
case(icas_intf.state)

IDLE_ST : begin
`uvm_info("run_slv_sm","IDLE_ST STATE ENTRY",UVM_DEBUG);
start_ev.wait_trigger();
`uvm_info("run_slv_sm","start_event detected ",UVM_LOW);
icas_intf.state = ADDR1_ST;
end
/*
ADDR1_ST : begin
`uvm_info("run_slv_sm","ADDR1_ST State Entry",UVM_LOW);
receive_byte(rcv_byte);
//one byte // Broadcast_Addr+Wr
addr = rcv_byte[7:1];
rnw = rcv_byte[0];

send_ack_ev.trigger();
chk_ack(chk_ack_n);

if(!chk_ack_n) begin
if({addr,rnw} == `BR_WR)
//Br_addr state
icas_intf.state = BRW_ST;
else if(addr == cfg.current_addr) begin
icas_intf.state = (rnw) ? U_PVT_RD_ST : U_PVT_WR_ST;
//Uni_cast private read/write state
end
else begin
icas_intf.state = IDLE_ST;
`uvm_error("run_slv_sm","Received illegal ACK in ADDR state, address was not
matching");
end
end
else
icas_intf.state = IDLE_ST;
//Nack
end//ADDR_ST
*/
ADDR1_ST : begin

`uvm_info("run_slv_sm","ADDR1_ST State Entry",UVM_LOW);


receive_byte(rcv_byte);
//one byte // Broadcast_Addr+Wr
addr = rcv_byte[7:1];
rnw = rcv_byte[0];
if({addr,rnw} == `BR_WR)begin
//Br_addr state
send_ack_ev.trigger();
chk_ack(chk_ack_n);
if(!chk_ack_n)
icas_intf.state = BRW_ST;
else begin
icas_intf.state = IDLE_ST;
`uvm_error("run_slv_sm","Received illegal ACK in ADDR state, address was
not matching");
end
end
else if(addr == cfg.current_addr[6:0]) begin
//U_PVT ADDR ST
`uvm_info("run_slv_sm",$sformatf(" cfg.current_addr[6:0] = %h,addr = %h,rnw =
%b",cfg.current_addr[6:0],addr,rnw), UVM_LOW);
if(!rnw)
send_ack_ev.trigger();
//Writes
else
send_slv_rd_ack_ev.trigger();
//Reads

chk_local_ack(local_ack_n);
if(!local_ack_n)
icas_intf.state = (rnw) ? U_PVT_RD_ST : U_PVT_WR_ST;
//Uni_cast private read/write state
else begin
icas_intf.state = IDLE_ST;
`uvm_error("run_slv_sm","Received Br_addr and dyn_addr was not matching");
end
end
else begin
`uvm_info("run_slv_sm",$sformatf(" cfg.current_addr[6:0] = %h,addr =
%h,rnw = %b",cfg.current_addr[6:0],addr,rnw), UVM_LOW);
`uvm_error("run_slv_sm","Both BR_ADDR and DYN_ADDR was not matching");
icas_intf.state = IDLE_ST;
end

end//ADDR1_ST

BRW_ST : begin
`uvm_info("run_slv_sm: ", "BRW_ST ",UVM_LOW);
fork
begin
start_ev.wait_ptrigger();
//after 7e if start(sr) goto br_cast private read/write state
icas_intf.state = B_PVT_ADDR_ST;
end

begin
stop_ev.wait_ptrigger();
icas_intf.state = IDLE_ST;
//after 7e if stop goto idle
end

begin
receive_byte(icmd);
receive_tbit(rcv_tbit);
icas_intf.state = RCV_ICMD_ST;
//ICMD state
end
join_any
//any => anyOne should finish to go forward.
disable fork;
//join => all shud finish;

//join_none => start move fwd, no wait for end


end//BRW_ST

B_PVT_ADDR_ST : begin
//enter if we got SR after Br_addr
`uvm_info("run_slv_sm", "B_PVT_ADDR_ST State Entry!",UVM_LOW);

receive_byte(rcv_byte);
//to receive the {Dyn_addr,rnw}
{addr,rnw} = rcv_byte[7:0];
`uvm_info(get_type_name(),$sformatf(" cfg.current_addr[6:0] = %h,addr = %h,rnw =
%b",cfg.current_addr[6:0],addr,rnw), UVM_LOW);
if({addr,rnw} == `BR_WR)
//after SR if Br_addr goto BRW_ST
icas_intf.state = BRW_ST;
else if(cfg.current_addr[6:0] == addr) begin
`uvm_info("run_slv_sm", "B_PVT_ADDR_ST Dyn_addr matched !",UVM_LOW);
if(!rnw) begin
send_ack_ev.trigger();
chk_local_ack(local_ack_n);
`uvm_info("run_slv_sm",$sformatf(" local_ack_n = %b,cfg.current_addr[6:0] =
%h,addr = %h,rnw = %b",local_ack_n,cfg.current_addr[6:0],addr,rnw), UVM_LOW);
if(!local_ack_n)
icas_intf.state = B_PVT_WR_ST;
// writes
else begin
icas_intf.state = IDLE_ST;
`uvm_error("run_slv_sm","ACK not driven properly from slave");
end
end
else begin
send_slv_rd_ack_ev.trigger();
chk_local_ack(local_ack_n);
`uvm_info(get_type_name(),$sformatf( " local_ack_n =
%b,cfg.current_addr[6:0] = %h,addr = %h,rnw =
%b",local_ack_n,cfg.current_addr[6:0],addr,rnw), UVM_LOW);
if(!local_ack_n)
icas_intf.state = B_PVT_RD_ST;
// reads
else begin
icas_intf.state = IDLE_ST;
`uvm_error("run_slv_sm","ACK not driven properly from slave");
end
end
end
else begin
`uvm_error("run_slv_sm","Both BR_ADDR and DYN_ADDR was not matching");
icas_intf.state = IDLE_ST;
end
end

B_PVT_RD_ST : begin
`uvm_info("run_slv_sm", "B_PVT_RD State Entry!",UVM_LOW);
// rd_data_state = 1;
// `uvm_info("run_slv_sm",$sformatf("rd_data_state =
%d",rd_data_state),UVM_LOW);
rd_st_ev.trigger();
fork
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
//after read if ew got stop goto idle
end
begin
start_ev.wait_trigger();
icas_intf.state = ADDR1_ST;
//after read if got SR goto addr1 state
end
join_any
disable fork;
end

B_PVT_WR_ST : begin
`uvm_info("run_slv_sm", "B_PVT_WR State Entry!",UVM_LOW);
wr_data_state = 1;
fork
//TODO need to have event for write task?
begin
// receive_byte(rcv_byte);
// receive_tbit(rcv_tbit);
// `uvm_info(get_type_name(),$sformatf( " rcv_byte = %h,rcv_tbit =
%b",rcv_byte,rcv_tbit), UVM_LOW);
slv_wr();
end
begin
stop_ev.wait_trigger();
//@stop_event
icas_intf.state = IDLE_ST;
//after write if ew got stop goto idle
end
begin
start_ev.wait_trigger();
//@start_event
icas_intf.state = ADDR1_ST;
//after write if got SR goto addr1 state
end
join_any
disable fork;
wr_data_state = 0;
end

// Reaches to this state if ICMD is received


// decode icmd and move into one of the following 6 states
// 1. ENUM, 2. STATIC_ADDR 3. SET_ICMD 4. GET_ICMD 5. NO_DATA_CMD 6. DDR

RCV_ICMD_ST : begin
// ICMD CMD for Broadcast Transfer
`uvm_info(get_full_name(), "RCV_ICMD State Entry!",UVM_LOW);
`uvm_info(get_type_name(),$sformatf( " icmd = %b",icmd), UVM_LOW);
`uvm_info(get_type_name(),$sformatf( " dyn_addr_valid = %b",cfg.dyn_addr_valid),
UVM_LOW);
case(icmd)
`SET_ENUM : icas_intf.state = RCV_ENUM_ST;
//ICMD is ENUM

`SET_STATIC : icas_intf.state = STATIC_ADDR_ST;


//ICMD is STATIC

`SET_FEAT,`DSET_FEAT,`CLR_FEAT,`DCLR_FEAT,`SET_MRL,`SET_MWL :
icas_intf.state = SET_ICMD_ST;

`DGET_MRL,`DGET_MWL,`SENDSLVINFO :
//TODO GET_MRL & GET_MWL is uni_cast we have to cmp and go or we can go directly to
next state
icas_intf.state = GET_ICMD_ST;

`CLR_ADDR,`GOU0,`GOU1,`GOU2,`GOU3,`DCLR_ADDR,`DGOU0,`DGOU1,`DGOU2,`DGOU3:
icas_intf.state = NO_DATA_ICMD_ST;

`GODDR1,`GODDR2,`GODDR3 :
icas_intf.state = DDR_ST;
endcase

end //RCV_ICMD_ST

RCV_ENUM_ST : begin
`uvm_info(get_full_name(), "RCV_ENUM State Entry!",UVM_DEBUG);
fork
begin
start_ev.wait_trigger();
//SR
receive_byte(rcv_byte);
//recieve addr 2 (BR_RD)

if(!cfg.dyn_addr_valid)
send_slv_rd_ack_ev.trigger();
//send_ack_ev.trigger();
chk_ack(chk_ack_n);

`uvm_info(get_type_name(),$sformatf( " chk_ack_n = %b, cfg.dyn_addr_valid =


%b",chk_ack_n,cfg.dyn_addr_valid), UVM_LOW);
if(!chk_ack_n)
icas_intf.state = SEND_ENUM_REGS_ST;

//stay in same state util stop comes


end
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
end
join_any
disable fork;
end // RCV_ENUM_ST

SEND_ENUM_REGS_ST : begin
`uvm_info(get_full_name(), "SEND_ENUM_REG_ST State Entry!",UVM_DEBUG);
check_arb = 1;
fork
begin
//arb loss back to prev state
arb_loss_ev.wait_trigger();
//TODO Does we need to check for an arb_loss while reading ?
icas_intf.state = RCV_ENUM_ST;
end
begin
//send 64 clocks, and then goto receive dynamic address
if( !cfg.dyn_addr_valid)
send_slv_enum_ev.trigger();

repeat(64) @(posedge icas_intf.scl_in);


icas_intf.state = RCV_DYN_ADDR_ST;
end
join_any
disable fork;
check_arb = 0;
end//SEND_REGS_ST

RCV_DYN_ADDR_ST : begin
`uvm_info("run_slv_sm", "RCV_DYN_ADDR State Entry!",UVM_LOW);
receive_byte(rcv_byte);
cfg.current_addr = rcv_byte[7:1];
//rcv_byte={dyn_addr,1'b0}
if(icmd == `SET_STATIC)
//rcv_tbit if icmd is static
receive_tbit(rcv_tbit);

if(icmd == `SET_STATIC)begin
//after recieving dyn_addr if cmd is static then goto static_addr_st for SR
`uvm_info("run_slv_sm",$sformatf("STATIC_ADDR_ST :: Dynamic address has
been assigned : %2h",rcv_byte[7:1]),UVM_LOW);
cfg.dyn_addr_valid = 1'b1;
icas_intf.state = STATIC_ADDR_ST;
end
else begin
//after rec_dyn_addr if cmd is ENUM then send ack
send_ack_ev.trigger();
chk_local_ack(local_ack_n);

if(!local_ack_n) begin
cfg.dyn_addr_valid = 1'b1;
icas_intf.state = RCV_ENUM_ST;
`uvm_info("run_slv_sm",$sformatf("ENUM_ST :: Dynamic address has been
assigned : %2h",rcv_byte[7:1]),UVM_DEBUG);
end
else begin
icas_intf.state = (icmd == `SET_ENUM) ? RCV_ENUM_ST : STATIC_ADDR_ST;
`uvm_error("run_slv_sm",$sformatf("Dynamic address has corrupted parity,
received value %2h",rcv_byte[7:1]));
end
end
end//RCV_DYN_ADDR_ST

STATIC_ADDR_ST: begin
`uvm_info("run_slv_sm", "STATIC_ADDR State Entry!",UVM_LOW);
fork
begin
start_ev.wait_trigger();
//SR
receive_byte(rcv_byte);
//to recieve {static address,WR}
`uvm_info(get_full_name(),$sformatf("run_slv_sm::static_addr =
%h,rcv_byte[7:1] = %h,dyn_addr_valid =
%b",cfg.static_addr,rcv_byte[7:1],cfg.dyn_addr_valid), UVM_LOW);

if(!cfg.dyn_addr_valid && (cfg.static_addr[6:0] == rcv_byte[7:1]))


// If dyn_addr_valid is low then send ack
send_ack_ev.trigger();

chk_local_ack(local_ack_n);
`uvm_info(get_full_name(),$sformatf( "run_slv_sm:: local_ack_n =
%b",local_ack_n), UVM_LOW);
icas_intf.state = (local_ack_n) ? STATIC_ADDR_NAK_ST : RCV_DYN_ADDR_ST;
end
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
end

join_any
disable fork;
end//STATIC_ADDR_ST

STATIC_ADDR_NAK_ST : begin
icas_intf.state = STATIC_ADDR_ST;
end//STATIC_ADDR_NAK

SET_ICMD_ST: begin
`uvm_info("run_slv_sm","SET_ICMD State Entry!",UVM_DEBUG);
if(icmd[7] == `BR_CMD) begin
`uvm_info("run_slv_sm","Broadcast ICMD",UVM_DEBUG);
fork
begin
receive_byte(rcv_byte);
receive_tbit(rcv_tbit);
`uvm_info("run_slv_sm",$sformatf("slv rcv_byte = %h,rcv_tbit =
%b",rcv_byte,rcv_tbit), UVM_LOW);
end
begin
start_ev.wait_trigger();
icas_intf.state = ADDR1_ST;
end
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
end
join_any
disable fork;
end

else begin
`uvm_info("run_slv_sm","Unicast ICMD",UVM_DEBUG);
fork
forever begin
// @(start_ev);
start_ev.wait_trigger();
receive_byte(rcv_byte);
//receive slave address
send_ack_ev.trigger();
chk_ack(chk_ack_n);
if(!chk_ack_n)begin
receive_byte(rcv_byte);
//receive byte data
receive_tbit(rcv_tbit);
//receive t_bit
end
end
begin
//@(stop_ev);
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
end
join_any
disable fork;
end

end//SET_ICMD_ST

GET_ICMD_ST: begin
`uvm_info("run_slv_sm","GET_ICMD State Entry!",UVM_DEBUG);

end//GET_ICMD_ST

NO_DATA_ICMD_ST: begin
`uvm_info("run_slv_sm","NO_DATA_ICMD State Entry!",UVM_DEBUG);
//Enter after receving cmd
if(icmd[7] == `BR_CMD)begin
//Broadcast cmd(gou0-gou3)and (clr_addr)
case(icmd)
`CLR_ADDR : begin
`uvm_info("run_slv_sm","rcv_cmd is CLR_ADDR",UVM_LOW);
cfg.dyn_addr_valid = 1'b0;
cfg.current_addr = 0;
end
`GOU0 : begin
`uvm_info("run_slv_sm","rcv_cmd is GOU0",UVM_LOW);
end
`GOU1 : begin
`uvm_info("run_slv_sm","rcv_cmd is GOU1",UVM_LOW);
end
`GOU2 : begin
`uvm_info("run_slv_sm","rcv_cmd is GOU2",UVM_LOW);
end
`GOU3 : begin
`uvm_info("run_slv_sm","rcv_cmd is GOU3",UVM_LOW);
end
endcase

fork
begin
start_ev.wait_trigger();
icas_intf.state = ADDR1_ST;
end
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
end
join_any
disable fork;
end

else begin
fork
while(prog == 1)begin
//Unicast cmd(Dgou0-Dgou3)and (Dclr_addr)
//@(start_ev);
start_ev.wait_trigger();
receive_byte(rcv_byte);
//TODO check for wr/rd and send ack

send_ack_ev.trigger();
chk_ack(chk_ack_n);
if(!chk_ack_n)
prog = 1;
end
begin
//@stop_ev;
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
end
join_any
disable fork;
end

end//NO_DATA_ICMD_ST

DDR_ST: begin
`uvm_info("run_slv_sm","DDR_ST State Entry!",UVM_DEBUG);
end//DDR_ST

U_PVT_RD_ST : begin
`uvm_info("run_slv_sm","U_PVT_RD State Entry!",UVM_LOW);
//TODO need to have event for read task?
//receive_byte(rcv_byte);
rd_st_ev.trigger();
fork
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
//after read if we got stop goto idle
end
begin
start_ev.wait_trigger();
icas_intf.state = ADDR1_ST;
//after read if got SR goto addr1 state
end
join_any
disable fork;
end//U_PVT_RD_ST

U_PVT_WR_ST: begin
`uvm_info("run_slv_sm","U_PVT_WR State Entry!",UVM_DEBUG);
wr_data_state = 1;
fork
begin
slv_wr();
end
begin
stop_ev.wait_trigger();
icas_intf.state = IDLE_ST;
//after write if ew got stop goto idle
end
begin
start_ev.wait_trigger();
icas_intf.state = ADDR1_ST;
//after write if got SR goto addr1 state
end
join_any
disable fork;
wr_data_state = 0;
end//U_PVT_WR_ST
endcase
end //forever
endtask : run_slv_sm

task icas_slv_sm::receive_byte(output bit[7:0] rcv_byte);

`uvm_info("receive_byte","Start",UVM_LOW);
repeat(8)
begin
@(posedge icas_intf.scl_in)
rcv_byte[7:0] = {rcv_byte[6:0],icas_intf.sda_in};
end
`uvm_info("receive_byte","Ends",UVM_LOW);
endtask : receive_byte
task icas_slv_sm::receive_tbit(output bit rcv_tbit);
`uvm_info("chk_ack","Start",UVM_DEBUG);
@(posedge icas_intf.scl_in)
rcv_tbit = icas_intf.sda_in;
`uvm_info("chk_ack","Ends",UVM_DEBUG);
endtask :receive_tbit

//checking wand ack//


task icas_slv_sm::chk_ack(output bit chk_ack_n);
`uvm_info("chk_ack","Start",UVM_DEBUG);
@(posedge icas_intf.scl_in)
if(icas_intf.sda_in == 0)
chk_ack_n = 0;
else
chk_ack_n = 1;

`uvm_info("chk_ack","Ends",UVM_DEBUG);
endtask : chk_ack

//checking individual ack

task icas_slv_sm::chk_local_ack(output bit local_ack_n);


`uvm_info("chk_local_ack","Start",UVM_DEBUG);
@(posedge icas_intf.scl_in)
if(icas_intf.sda_en_n == 0)
local_ack_n = 0;
else
local_ack_n = 1;

`uvm_info("chk_local_ack","Ends",UVM_DEBUG);
endtask : chk_local_ack

// receives write transactions from master


// triggered when state machine goes into write data state
// exits when state machine exits

task icas_slv_sm::slv_wr();
// TODO pass this data array to monitor
bit parity_exp,m_bit9;
bit [7:0] m_data;
bit data_array[];
bit err;
bit parity_err;
int parity_err_index;
`uvm_info("slv_wr","Starts forever",UVM_LOW)
forever
begin
data_array.delete();
err = 0;
parity_err = 0;
parity_err_index = 0;
wait(wr_data_state == 1);
`uvm_info("slv_wr","Receiving data Starts",UVM_LOW);
while(wr_data_state) begin
receive_byte(m_data);
data_array = new[data_array.size() + 1](data_array);
//storing data by creating new mem for each byte
data_array[data_array.size() - 1] = m_data;
receive_tbit(m_bit9);
`uvm_info(get_type_name(),$sformatf( " slv_rcv_byte = %h,slv_rcv_tbit =
%b",m_data,m_bit9), UVM_LOW);
parity_exp = ~(^m_data);
if(m_bit9 != parity_exp)begin
err = 1;
parity_err = 1;
parity_err_index = data_array.size-1;
`uvm_error("slv_wr",$sformatf("Parity error occured at index =
%d",parity_err_index));
end
end
`uvm_info("slv_wr","Receiving data Ends",UVM_LOW);
end
endtask:slv_wr

function void icas_slv_sm::set_cfg(icas_configuration cfg_in);


cfg = cfg_in;
endfunction : set_cfg

task icas_slv_sm::slv_st_sp_det();
parameter t_su = 1;
`uvm_info("slv_st_sp","Start",UVM_LOW);
fork
begin
forever begin
@(negedge icas_intf.sda_in)
if(icas_intf.scl_in)begin
start_ev.trigger();
`uvm_info("START_BIT","triggered",UVM_LOW);
end
end
end

begin
forever begin
@(posedge icas_intf.sda_in)
#t_su if(icas_intf.scl_in)begin
stop_ev.trigger();
`uvm_info("STOP_BIT","triggered",UVM_LOW);
end
end
end

forever begin
@(posedge icas_intf.scl_in)
if(check_arb & icas_intf.sda_en_n & !icas_intf.sda_in ) begin
arb_loss_ev.trigger();
arb_lost = 1;
`uvm_info("slv_st_sp","arbitration loss detected",UVM_LOW);
fork
start_ev.wait_trigger();
stop_ev.wait_trigger();
join_any
disable fork;
arb_lost = 0;
`uvm_info("slv_st_sp","end of arbitration loss",UVM_LOW);
end
end
join
`uvm_info("slv_st_sp","Ends",UVM_LOW);
endtask :slv_st_sp_det

`endprotect
`endif

Das könnte Ihnen auch gefallen