Sequencer和Driver

一、概述

在这里插入图片描述driversequencer之间的TLM通信采取了get模式,即由driver发起请求,从sequencer一端获得item,再由sequencer将其传递至driver。作为driver,永远停不下来,只要它可以从sequencer获取item,它就一直工作。sequenceritem只应该在合适的时间点产生需要的数据,而至于怎么处理数据,则会由driver来实现。

为了便于item传输,UVM专门定义了匹配的TLM端口供sequencerdriver使用:

uvm_seq_item_pull_port #(type REQ=int, type RSP=REQ)
uvm_seq_item_pull_export #(type REQ=int, type RSP=REQ)
uvm_seq_item_pull_imp #(type REQ=int, type RSP=REQ, type imp=int)

由于driver是请求发起端,所以driver一侧例化了下面两种端口:

uvm_seq_item_pull_port #(REQ, RSP) seq_item_port;
uvm_analysis_port #(RSP) rsp_port;

sequencer一侧则为请求的响应端,在sequencer一侧例化了对应的两种端口:

uvm_seq_item_pull_imp #(REQ, RSP, this_type) seq_item_export
uvm_analysis_export #(RSP) rsp_export

二、端口和方法

通常情况下,可以通过匹配的第一对TLM端口完成item的完整传送,即driver::seq_item_portsequencer::seq_item_export。这一对端口在连接时同其它端口连接方式一样,即通过driver::seq_item_port.connect(sequencer::seq_item_export)完成。这一类端口功能主要用来实现driversequencerrequest获取和response返回。

这一种类型的TLM端口支持如下方法:

//采取blocking的方式等待从sequence获取下一个item
task get_next_item(output REQ req_arg)
//采取blocking的方式等待从sequence获取下一个item,如果立即返回的结果req_arg为null,则表示sequence还没有准备好
task try_next_item(output REQ req_arg)
//用来通知sequence当前的sequence item已经消化完毕,可以选择性地传递RSP参数,返回状态值。
function void item_done(input RSP rsp_arg=null)
//等待当前的sequence直到产生下一个有效的item
task wait_for_sequences()
//如果当前的sequence准备好而且可以获取下一个有效item,则返回1,否则返回0
function bit has_do_available()
//采取nonblocking方式发送response,如果成功返回1,否则返回0
function void put_response(input RSP rsp_arg)
//采用get方式获取item
task get(output REQ req_arg)
//采用peek方式获取item
task peek(output REQ req_arg)
//采取blocking方式将response发送回sequence
task put(input RSP rsp_arg)

关于REQRSP类型的一致性,由于uvm_sequenceruvm_driver实际上都是参数化的类:

uvm_sequencer #(type REQ=uvm_sequence_item, RSP=REQ)

//这有一个潜在的类型转换要求,即driver得到REQ对象在进行下一步处理时,
//需要进行动态的类型转换,将REQ转换为uvm_sequence_item的子类型才可以从中获取有效的成员数据。
uvm_driver #(type REQ=uvm_sequence_item, RSP=REQ)

通常情况下RSP类型与REQ类型保持一致,这么做的好处是为了便于统一处理,方便item对象的拷贝、修改等操作。driver消化完当前的request后,可以通过item_done(input RSP rsp_arg=null)方法来告知sequence此次传输已经结束,参数中的RSP可以选择填入,返回相应的状态值。driver也可以通过put_response()或者put()方法来单独发送response。此外发送response还可以通过成对的uvm_driver::rsp_portuvm_driver::rsp_export端口来完成,方法为uvm_driver::rsp_port::write(RSP)

三、事务传输示例

class bus_trans extends uvm_sequence_item;
	rand int data;
	`uvm_object_utils_begin(bus_trans)
		`uvm_field_int(data, UVM_ALL_ON)
	`uvm_object_utils_end
	...
endclass

class flat_seq extends uvm_sequence;
	`uvm_object_utils(flat_seq)
	...
	
	task body();
		uvm_sequence_item tmp;
		bus_trans req, rsp;
		tmp = create_item(bus_trans::get_type(), m_sequencer, "req");
		void'($cast(req, tmp));
		start_item(req);
		req.randomize with {data == 10;};
		`uvm_info("SEQ", $sformatf("sent a item \n %s", req.sprint()), UVM_LOW)
		finish_item(req);
		get_response(tmp);
		void'($cast(rsp, tmp));
		`uvm_info("SEQ", $sformatf("got a item \n %s", rsp.sprint()), UVM_LOW)
	endtask
endclass

class sequencer extends uvm_sequencer;
	`uvm_component_utils(sequencer)
	...
endclass

class driver extends uvm_driver;
	`uvm_component_utils(driver)
	...
	
	task run_phase(uvm_phase phase);
		REQ tmp;
		bus_trans req, rsp;
		seq_item_port.get_next_item(tmp);
		void'($cast(req, tmp));
		`uvm_info("DRV", $sformatf("got a item \n %s", rsp.sprint()), UVM_LOW)
		void'($cast(rsp, req.clone()));
		rsp.set_sequence_id(req.get_sequence_id());
		rsp.data += 100;
		seq_item_port_done(rsp);
		`uvm_info("DRV", $sformatf("sent a item \n %s", rsp.sprint()), UVM_LOW)
	endtask
endclass

class env extends uvm_env;
	sequencer sqr;
	driver drv;
	`uvm_component_utils(env)
	...
	function void build_phase(uvm_phase phase);
		sqr = sequencer::type_id::create("sqr", this);
		drv = driver::type_id::create("drv", this);
	endfunction
	function void connect_phase(uvm_phase phase);
		drv.seq_item_port.connect(sqr.seq_item_export);
	endfunction
endclass

class test1 extends uvm_test;
	env e;
	`uvm_component_utils(test1)
	...
	function void build_phase(uvm_phase phase);
		e = env::type_id::create("e", this);
	endfunction
	task run_phase(uvm_phase phase);	
		flat_seq seq;
		phase.raise_objection(phase);
		seq = new();
		seq.start(e.sqr);
		phase.drop_objection(phase);
	endtask
endclass

输出结果:
在这里插入图片描述

四、事务传输过程分析

在定义sequencer时,默认了REQ类型为uvm_sequence_item类型,这与定义driver时采取默认REQ类型保持一致。

flat_seq作为动态创建的数据生成载体,它的主任务flat_seq::body()做了下面几件事情:

  • 通过方法create_item()创建request item对象。
  • 调用start_item()准备发送item
  • 在完成发送item之前对item进行随机处理。
  • 调用finish_item()完成item发送。
  • 有必要的情况下可以从driver获取response item

在定义driver时,它的主任务driver::run_phase()也应通常做出如下处理:

  • 通过seq_item_port.get_next_item(REQ)sequencer获取有效的request item
  • request item中获取数据,进而产生数据激励。
  • request item进行克隆生成新的对象response item
  • 修改response item中的数据成员,最终通过seq_item_port.item_done(RSP)response item对象返回给sequence

对于uvm_sequence::get_response(RSP)uvm_driver::item_done(RSP)这种成对得到操作,是可选的而不是必须的,即可以选择uvm_driver不返回response item,同时sequence也无需获取response item

在高层环境中,应该在connect_phase中完成driversequencer的TLM端口连接,比如在env::connect_phase()中通过drv.seq_item_port.connect(sqr.seq_item_export)完成了driversequencer的连接。

在完成了flat_seqsequencerdriverenv的定义后,到了test1层,除了需要考虑挂起objection防止提前退出,便可以利用uvm_sequence类的方法uvm_sequence::start(SEQUENCER)来实现sequencesequencer的挂载。

五、通信时序

在这里插入图片描述

  • 无论是sequence还是driver,它们通话的对象都是sequencer。当多个sequence试图挂载到同一个sequencer上时,涉及sequencer的仲裁功能。
  • 对于sequence而言,无论是flat sequence还是hierarchical sequence,进一步切分的话,流向sequencer的都是sequence item,所以就每个item的”成长周期“来看,它起始于create_item(),继而通过start_item()尝试从sequencer获取可以通过的权限。
  • driver一侧将一直处于”吃不饱“的状态,如果没有了item可以使用,将调用get_next_item()来尝试从sequencer一侧获取item
  • sequencer将通过权限交给某一个底层的sequence前,目标sequence中的item应该完成随机化,继而在获取sequencer的通过权限后,执行finish_item()
  • 接下来sequence中的item将穿过sequencer到达driver一侧,这个重要节点标志着sequencer第一次充当通信桥梁的角色已经完成。
  • driver在得到新的item后,会提取有效的数据信息,将其驱动到与DUT连接的接口上面。在完成驱动后,driver通过item_done()告知sequence已经完成数据传送,而sequence在获取该消息后,则表示driversequence双方完成了这一次item的握手传输。在这次传递中,driver可以选择将RSP作为状态返回值传递给sequence,而sequence也可以选择调用get_response(RSP)等待从driver一侧获取返回的数据对象。
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DRV8313是一种三相直流电机驱动器芯片。它采用了高性能的集成晶体管技术,能够为直流电机提供全面的驱动和保护功能。该芯片内置了电流检测、霍尔传感器接口、故障保护和过热保护等特性,能够实现电机的高效运行和安全保护。 DRV8313的主要特点有:首先,它具有三路独立的半桥驱动器,可独立驱动三相直流电机。其次,这款芯片的工作电压范围广泛,适用于多种工作条件。第三,DRV8313具有高功率输出能力,能够满足高功率要求的应用场景。另外,该芯片还支持双向电流测量功能,可实时监测电机的电流情况,以便于故障检测和保护。 在应用方面,DRV8313通常用于电动车辆、工业自动化和机器人等领域。由于其高性能和可靠性,它能够提供稳定、高效的驱动力,满足各种应用对电机控制的需求。此外,DRV8313还具有小尺寸、低功耗和低散热的特点,使得其在紧凑型设备和高密度集成电路板中得到广泛应用。 综上所述,DRV8313是一种功能强大的三相直流电机驱动器芯片,具有高性能、全面的驱动和保护功能,适用于电动车辆、工业自动化和机器人等应用领域。它是电机控制领域中的重要组成部分,为电机系统的稳定运行和保护提供了有效的解决方案。 ### 回答2: DRV8313是德州仪器(Texas Instruments)推出的一款三相无刷直流电机驱动器芯片。该芯片结合了门级驱动器和功率集成器件,提供了高效率、高性能和低成本的解决方案,适用于电动车、机器人、无人机等各种电动驱动应用。 DRV8313集成了三相MOSFET的电源和驱动电路,能够实现三相无刷直流电机的控制。它支持高达10A的电流输出,同时具备过流保护和过温保护功能,确保了系统的安全稳定运行。此外,DRV8313还具有无感应电流测量功能,可以实时监测电机的电流,从而提供更加精确的控制。 DRV8313的控制接口采用了标准的PWM信号输入,支持多种控制器和微控制器。另外,该芯片还提供了丰富的诊断和报警功能,可实时检测电机的运行状态,如过流、欠压等故障,并输出报警信号。这些功能可以提高系统的可靠性和安全性。 DRV8313还具有丰富的保护功能,如过流保护、欠压保护、过温保护等,能够有效保护系统免受异常电流、电压和温度的损害。此外,芯片的小尺寸和低功耗设计使得它能够适应各种紧凑空间和低功耗要求的应用环境。 总之,DRV8313是一款功能强大、性能优越的三相无刷直流电机驱动器芯片,广泛应用于电动驱动领域。它集成了多种功能和保护特性,可提供稳定可靠的电机控制,同时具备较低的成本和功耗,是许多电动驱动应用的理想选择。 ### 回答3: DRV8313是一款高功率三相无感刷电机驱动器,适用于各种工业和汽车应用。它集成了电流检测、过流和过温保护功能,能够确保电机运行的安全和可靠性。 DRV8313具有高性能的控制算法,可以实现高效的电机控制和精确的速度调节。通过SPI接口,用户可以轻松地配置和监控驱动器的参数和状态。 此外,DRV8313具有多种保护特性,例如过流保护、过温保护和短路保护,可以保护驱动器和电机免受损坏。同时,它还具有过电压保护和欠压保护功能,以确保系统的稳定运行。 DRV8313支持PWM控制和脉冲方向控制两种方式,可以满足不同电机控制的需求。它还具有灵活的电源输入电压范围和电流限制功能,可以满足不同应用场景的需求。 总的来说,DRV8313是一款功能强大、性能稳定的电机驱动器,通过其优良的特性和保护机制,可以实现高效、安全的电机控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值