【前端验证】通用型顺序比对的uvm scoreboard组件编写

前言

最近在研究uvm环境的仿真结束机制,准备在现有的objection机制基础上补充看门狗操作。而看门狗操作中,scoreboard喂狗是重要的一环,因此这次先实现一下通用型顺序比对的scoreboard组件编写。

scoreboard

在之前的 【python脚本】用于生成简单握手接口与自测环境的gen_uvm_agent脚本 工程中,我针对每一个agent都生成了对应的scb,这实际是没有必要的,绝大多数的transaction都可以共用一套scb,只需要把对应的数据类型传入即可,暂且将其中的顺序比对公用scb命名为prj_scoreboard。

class prj_scoreboard #(type REQ=uvm_sequence_item) extends uvm_scoreboard;
	REQ expect_q[$];
	REQ actual_q[$];
	uvm_blocking_get_port #(REQ)  exp_port;
	uvm_blocking_get_port #(REQ)  act_port;
	static event feed_watchdog;
	
	extern function new(string name, uvm_component parent = null);
    extern virtual function void build_phase(uvm_phase phase);
    extern virtual task run_phase(uvm_phase phase);
	
	`uvm_component_param_utils(prj_scoreboard#(REQ))
endclass: prj_scoreboard

prj_scoreboard必然是继承自uvm_scoreboard,不过要做公用的那必然要将内部比对的数据类型作为参数传入,因此使用REQ作为传参类型,内部的queue声明和port声明都以REQ作为数据类型。feed_watchdog是全局可见的event,后续所有例化的prj_scoreboard均触发这一个event就可以了,没有必要在环境中@每一个scb的比对事件,因为所有的scb比对事件均要触发喂狗,因此大家喂一个就可以了。

`uvm_component_param_utils(prj_scoreboard#(REQ))这一行卡了时间(毕竟我自学成才o(╥﹏╥)o),虽然能够确定要使用param型的注册,但是应该如何注册呢,我先后试用了

`uvm_component_utils(prj_scoreboard)
`uvm_component_param_utils(prj_scoreboard#(type REQ=uvm_sequence_item))
`uvm_component_param_utils(prj_scoreboard#(uvm_sequence_item))

然后发现要么编译不过,要么后面create时有问题。然后问了大神应该怎么写,大神一语点醒梦中人:参数型的class传了不同的参数就是完全不同的class,因此注册时要明确当前的参数,而在内部注册时,参数就是REQ,后面声明时REQ传参指向谁那么注册的类就是谁。所以这里的factory注册方式直接就是:

`uvm_component_param_utils(prj_scoreboard#(REQ))

内部的方法,new和build_phase都没有什么多说的,比对行为放在了run_phase中,因为scb是被动型的组件,不需要raise objection,一直工作就可以了。

function prj_scoreboard::new(string name, uvm_component parent = null);
   super.new(name, parent);
endfunction: new

function void prj_scoreboard::build_phase(uvm_phase phase);
   super.build_phase(phase);
   exp_port = new("exp_port", this);
   act_port = new("act_port", this);
endfunction: build_phase

task prj_scoreboard::run_phase(uvm_phase phase);
    super.run_phase(phase);
    fork 
        while(1)begin
		    REQ get_expect;
            exp_port.get(get_expect);
            expect_q.push_back(get_expect);
        end
        while(1)begin
			REQ get_actual;
            act_port.get(get_actual);
			actual_q.push_back(get_actual);
		end
		while(1)begin
			REQ get_expect;
			REQ get_actual;
			bit result;
			if(actual_q.size() > 0)begin
				get_actual = actual_q.pop_front();
				-> feed_watchdog;
				if(expect_q.size() > 0) begin
					get_expect = expect_q.pop_front();
					result = get_actual.compare(get_expect);
					if(result) begin 
						`uvm_info("prj_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);
					end
					else begin
						`uvm_error("prj_scoreboard", "Compare FAILED");
						$display("RM:");
						get_expect.print();
						$display("RTL:");
						get_actual.print();
					end
				end
				else begin
					`uvm_error("prj_scoreboard", "Received from DUT, while Expect Queue is empty");
					get_actual.print();
				end
            end
            else begin
                #1;
            end
        end
    join_none
endtask: run_phase

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的UVM评分板(Scoreboard)的示例,用于检查接收到的事务与期望的结果是否匹配: ```verilog class my_scoreboard extends uvm_scoreboard; `uvm_component_utils(my_scoreboard) // Declare analysis port for receiving transactions uvm_analysis_port #(my_transaction) analysis_port; // Override the build_phase to connect the analysis port virtual function void build_phase(uvm_phase phase); super.build_phase(phase); // Connect the analysis port to the scoreboard's analysis_export analysis_port = new("analysis_port", this); endfunction // Override the write method to check received transactions virtual function void write(my_transaction txn); super.write(txn); // Check the received transaction against expected results if (txn.result == txn.expected_result) `uvm_info("SCOREBOARD", $sformatf("Transaction %0d passed", txn.transaction_id), UVM_MEDIUM) else `uvm_error("SCOREBOARD", $sformatf("Transaction %0d failed", txn.transaction_id)) endfunction endclass ``` 在上面的示例中,`my_scoreboard`是一个UVM评分板,它用于检查接收到的`my_transaction`类型的事务与期望的结果是否匹配。在`build_phase`中,评分板创建了一个分析端口(`analysis_port`)并将其连接到评分板的`analysis_export`。 评分板的`write`方法被重写以检查接收到的事务。在该方法中,评分板比较事务的`result`字段与`expected_result`字段,如果它们匹配,则打印一条通过的信息;否则,打印一条失败的信息。 以上是一个简单的UVM评分板示例,它展示了如何在UVM中创建和使用评分板来检查接收到的事务与期望的结果是否匹配。具体实现中,你需要根据你的需求进行适当的修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼德兰的喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值