标签:总结 req sequence mem Sequence item uvm sequencer UVM
一个sequence生成一系列的sequence_item,并通过sequencer发送给驱动程序,Sequence是通过扩展uvm_sequence来编写的。
uvm_sequence 派生自 uvm_sequence_item
sequence用 sequence_item 的类型参数化,这定义了和 driver 之间 发送/接收的 sequence_item 的类型。
sequence base class
virtual class uvm_sequence #( type REQ = uvm_sequence_item, type RSP = REQ ) extends uvm_sequence_base
example:
class write_sequence extends uvm_sequence #(mem_seq_item);
....
....
endclass
该writ_sequence具有 mem_seq_item 的句柄 req 和 rsp。
request/req:
提供信息来启动特定操作的事务。
response/rsp:
提供有关特定操作的完成信息或状态信息的事务。
Sequence执行
sequence最重要的属性是:
- body method
- m_sequencer handle
body Method:
body 方法定义了这个sequence做什么事情。
m_sequencer Handle:
m_sequencer 句柄包含对运行 sequence 的 sequencer 的引用。
该 sequence 将在从 test 中调用 sequence 的 start 时开始执行。
sequence_name.start(sequencer_name);
sequencer_name 指定 sequence 必须在哪个 sequencer 上运行。
有与 uvm_sequence 相关的 Methods, macros and pre-defined callbacks(方法、宏和预定义的回调)。
用户可以将方法(任务或函数)定义为预定义的回调。这些方法将在调用序列 start 时自动执行。
这些方法不应由用户直接调用。
下面的框图显示了调用sequence start时调用方法的顺序。
注意:* mid_do 和 post_do 是函数,其他都是任务
Starting The Sequence:
生成和发送 sequence_item 的逻辑将写入sequence的 body() 方法中。
发送 sequence_item 的sequence、sequencer和driver之间的握手如下所示。
sequence和driver之间的通信涉及以下步骤,
1.create_item() / create req.
2.wait_for_grant().
3.randomize the req.
4.send the req.
5.wait for item done.
6.get response.
* 步骤 5 和 6 是可选的。
Method Call | Description |
---|---|
create_item() req = **_seq_item::type_id::create(“req”); |
创建和初始化*一个 sequence_item 或sequence *initialize - 初始化以与指定的sequencer通信 |
wait_for_grant() |
这个方法调用是阻塞的,执行会一直阻塞,直到方法返回。 1.此方法向当前 sequencer 发出请求 2.sequencer 授予从 driver 获取的 get_next_item() request |
req.randomize() | 这个方法是随机化sequence_item |
send_request(req,re-randomize) re-randomize = 0 or re-randomize = 1; |
将request item 发送到sequencer,sequencer会将其转发给driver。如果设置了重新随机化位,则item将在发送给driver之前被随机化。 |
wait_for_item_done() | 此调用是可选的。此任务将阻塞,直到 driver 调用 item_done 或 put。 |
get_current_item() | 返回当前由 sequencer 执行的请求项。 如果sequencer当前未执行项目,则此方法将返回 null。 |
get_response(rsp) | 收到 driver 的回复。 |
编写 UVM sequence
class mem_sequence extends uvm_sequence#(mem_seq_item);
`uvm_object_utils(mem_sequence)
//Constructor
function new(string name = "mem_sequence");
super.new(name);
endfunction
virtual task body();
req = mem_seq_item::type_id::create("req"); //create the req (seq item)
wait_for_grant(); //wait for grant
assert(req.randomize()); //randomize the req
send_request(req); //send req to driver
wait_for_item_done(); //wait for item done from driver
get_response(rsp); //get response from driver
endtask
endclass
UVM Sequence 宏
这些宏用于在默认sequencer,m_sequencer 上start sequence和sequence item。
Macro | Description |
---|---|
`uvm_do(Item/Seq) | 此宏将 seq_item 或sequence作为参数。 在调用 `uvm_do() 时,将执行上面定义的 6 个步骤。 |
`uvm_create(Item/Seq) | 此宏创建 item or sequence. |
`uvm_send(Item/Seq) | create() 和 randomize() 被跳过,其余所有步骤都被执行。 |
`uvm_rand_send(Item/Seq) | 只有 create() 被跳过,其余所有步骤都被执行。 |
`uvm_do_with(Item/Seq,Constraints) | 该宏执行上述 6 个步骤以及第二个参数中定义的约束。 |
`uvm_rand_send_with(Item/Seq,Constraints) | create() 被跳过,其余所有步骤与第二个参数中定义的约束一起执行。 |
`uvm_do_pri(Item/Seq,Priority ) | 以提到的优先级执行`uvm_do()。 |
`uvm_do_pri_with(Item/Seq,Constraints,Priority) | 执行 `uvm_do() 以及定义的约束和提到的优先级。 |
`uvm_send_pri(Item/Seq,Priority) | create() 和 randomize() 被跳过,其余所有其他步骤都以提到的优先级执行。 |
`uvm_rand_send_pri(Item/Seq,Priority) | 只有 create() 被跳过,其余所有其他步骤都以提到的优先级执行。 |
`uvm_rand_send_pri_with(Item/Seq,Priority, Constraints) | 只有 create() 被跳过,其余所有其他步骤与 create() 一起被跳过,其余所有其他步骤与定义的优先级约束一起执行。 |
`uvm_declare_p_sequencer(SEQUENCER) | 该宏用于声明一个变量 p_sequencer,其类型由 SEQUENCER 指定。通过使用 p_sequencer 句柄,可以访问 sequencer 的属性。 |
使用宏编写sequence
`UVM_DO()
class mem_sequence extends uvm_sequence#(mem_seq_item);
`uvm_object_utils(mem_sequence)
//Constructor
function new(string name = "mem_sequence");
super.new(name);
endfunction
virtual task body();
`uvm_do(req)
endtask
endclass
`UVM_CREATE() AND `UVM_SEND()
class mem_sequence extends uvm_sequence#(mem_seq_item);
`uvm_object_utils(mem_sequence)
//Constructor
function new(string name = "mem_sequence");
super.new(name);
endfunction
virtual task body();
`uvm_create(req)
assert(req.randomize());
`uvm_send(req);
endtask
endclass
`UVM_RAND_SEND()
class mem_sequence extends uvm_sequence#(mem_seq_item);
`uvm_object_utils(mem_sequence)
//Constructor
function new(string name = "mem_sequence");
super.new(name);
endfunction
virtual task body();
`uvm_create(req)
`uvm_rand_send(req)
endtask
endclass
`UVM_DO_WITH()
class write_sequence extends uvm_sequence#(mem_seq_item);
`uvm_object_utils(write_sequence)
//Constructor
function new(string name = "write_sequence");
super.new(name);
endfunction
virtual task body();
`uvm_do_with(req,{req.wr_en == 1;})
endtask
endclass
`UVM_RAND_SEND_WITH()
class read_sequence extends uvm_sequence#(mem_seq_item);
`uvm_object_utils(read_sequence)
//Constructor
function new(string name = "read_sequence");
super.new(name);
endfunction
virtual task body();
`uvm_create(req)
`uvm_rand_send_with(req,{req.rd_en == 1;})
endtask
CALLING SEQUENCE’S INSIDE THE SEQUENCE
class wr_rd_seq extends uvm_sequence#(mem_seq_item);
write_sequence wr_seq;
read_sequence rd_seq;
`uvm_object_utils(wr_rd_seq)
//Constructor
function new(string name = "wr_rd_seq");
super.new(name);
endfunction
virtual task body();
`uvm_do(wr_seq)
`uvm_do(rd_seq)
endtask
endclass
m_sequencer 和 p_sequencer 的区别:
m_sequencer,
m_sequencer 句柄包含对运行sequence 的sequencer(默认sequencer)的引用。
这是由,
start 方法中提供的sequencer句柄
parent sequence 使用的sequencer
使用 set_sequencer 方法设置的sequencer
p_sequencer,
p_sequencer 是一个变量,用作访问 sequencer 属性的句柄。
p_sequencer 是使用宏定义的 : `uvm_declare_p_sequencer(SEQUENCER_NAME)
标签:总结,req,sequence,mem,Sequence,item,uvm,sequencer,UVM 来源: https://www.cnblogs.com/fuqiangblog/p/16683750.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。