2.3 为验证平平台加入各种组件
uvm白皮书练习_ch2_ch231_加入transaction
代码部分
top_tb.sv
python
`timescale 1ns / 1ps
`include "uvm_macros.svh"
import uvm_pkg::*;
/*只能现在*/
`include "my_if.sv"
`include "my_transaction.sv"
`include "my_driver.sv"
module top_tb();
/*time set*/
initial begin
$display("start sim");
#1.5ms;
$finish;
end
/*fsdb*/
initial begin
$display("fsdbDumpfilrs is start at %d",$time);
$fsdbDumpfile("verilog.fsdb");
$fsdbDumpvars(0);
end
reg clk;
reg rst_n;
reg [7:0] rxd;
reg rx_dv;
wire [7:0] txd;
wire tx_en;
my_if input_if (clk,rst_n);
my_if output_if (clk,rst_n);
initial begin
clk = 0;
forever begin
#100ns clk = ~ clk;
end
end
initial begin
rst_n =1'b0 ;
#1us;
rst_n =1'b1 ;
end
dut my_dut(.clk (clk ),
.rst_n (rst_n ),
.rxd (input_if.data ),
.rx_dv (input_if.valid ),
.txd (output_if.data ),
.tx_en (output_if.valid ) );
// initial begin
// my_driver drv;
// drv=new("drv",null);
// drv.main_phase(null);
// $finish;
// end
initial begin
run_test("my_driver");
end
initial begin
uvm_config_db#(virtual my_if)::set(null, "uvm_test_top", "vif", input_if);
end
endmodule
my_if.sv
python
`ifndef MY_IF__SV
`define MY_IF__SV
interface my_if(input clk,input rst_n);
logic [7:0] data;
logic valid;
endinterface //my_if
`endif
my_transaction.sv
python
`ifndef MY_TRANSACTION__SV
`define MY_TRANSACTION__SV
class my_transaction extends uvm_sequence_item;
rand bit[47:0] dmac;
rand bit[47:0] smac;
rand bit[15:0] ether_type;
rand byte pload[];
rand bit[31:0] crc;
constraint pload_cons{
pload.size >= 46;
pload.size <= 1500;
}
function bit[31:0] calc_crc();
return 32'h0;
endfunction
function void post_randomize();
crc = calc_crc;
endfunction
`uvm_object_utils(my_transaction)
function new(string name = "my_transaction");
super.new();
endfunction
endclass
`endif
my_driver.sv
python
// `ifndef MY_DRIVER__SV
// `define MY_DRIVER__SV
// class my_driver extends uvm_driver;
// virtual my_if vif;
// `uvm_component_utils(my_driver) //没有后缀
// function new(string name="my_driver",uvm_component parent = null);
// super.new(name,parent);
// `uvm_info("my_driver", "new is called", UVM_LOW)
// endfunction //new()
// virtual function void build_phase(uvm_phase phase);
// super.build_phase(phase);
// `uvm_info("my_driver", "build phase is caslled", UVM_LOW)
// if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
// `uvm_fatal("my_driver", "virtual interface must be set for vif!!!") //没有后缀
// endfunction
// extern task main_phase(uvm_phase phase);
// extern task drive_one_pkt(my_transaction tr);
// endclass //my_driver extends uvm_driver
`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV
class my_driver extends uvm_driver;
virtual my_if vif;
`uvm_component_utils(my_driver)
function new(string name = "my_driver", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
`uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
endfunction
extern task main_phase(uvm_phase phase);
extern task drive_one_pkt(my_transaction tr);
endclass
task my_driver::main_phase (uvm_phase phase);
my_transaction tr ; /*先声明数组*/
phase.raise_objection(this); //有后缀,项目真起始点
vif.data <= 8'b0;
vif.valid <= 1'b0;//先来一个初始化
while(!vif.rst_n)
@(posedge vif.clk);
for(int i = 0; i < 2; i++)begin //发两轮数据包
tr = new("tr");
// assert (tr.randomize() with {pload.size ==20;});//源码200,这里减到20,进行随机初始化
assert (tr.randomize() with {pload.size ==50;});//源码200,这里减到20,进行随机初始化
// else error_process //本来此处还有断言,源码处暂时没有
drive_one_pkt(tr);
end
repeat(5) @(posedge vif.clk);//等待5个时钟
// vif.valid <= 1'b0;
phase.drop_objection(this);//运行结束
endtask //my_driver::main_phase
task my_driver::drive_one_pkt(my_transaction tr);
bit [47:0] tmp_data;
bit [7:0] data_q[$];
//push dmac to data_q
tmp_data = tr.dmac;
for(int i = 0; i < 6; i++) begin
data_q.push_back(tmp_data[7:0]);
tmp_data = (tmp_data >> 8);
end
//push smac to data_q
tmp_data = tr.smac;
for(int i = 0; i < 6; i++) begin
data_q.push_back(tmp_data[7:0]);
tmp_data = (tmp_data >> 8);
end
//push ether_type to data_q
tmp_data = tr.ether_type;
for(int i = 0; i < 2; i++) begin
data_q.push_back(tmp_data[7:0]);
tmp_data = (tmp_data >> 8);
end
//push payload to data_q
for(int i = 0; i < tr.pload.size; i++) begin
data_q.push_back(tr.pload[i]);
end
//push crc to data_q
tmp_data = tr.crc;
for(int i = 0; i < 4; i++) begin
data_q.push_back(tmp_data[7:0]);
tmp_data = (tmp_data >> 8);
end
`uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
repeat(3) @(posedge vif.clk);
while(data_q.size() > 0) begin
@(posedge vif.clk);
vif.valid <= 1'b1;
vif.data <= data_q.pop_front();
end
@(posedge vif.clk);
vif.valid <= 1'b0;
`uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask
`endif
// /*
// 注册
// main phase
// driver one pkt
// */
仿真结果
python
UVM_INFO @ 0: reporter [RNTST] Running test my_driver...
UVM_INFO my_driver.sv(100) @ 1100000: uvm_test_top [my_driver] begin to drive one pkt
UVM_INFO my_driver.sv(111) @ 15500000: uvm_test_top [my_driver] end drive one pkt
UVM_INFO my_driver.sv(100) @ 15500000: uvm_test_top [my_driver] begin to drive one pkt
UVM_INFO my_driver.sv(111) @ 29900000: uvm_test_top [my_driver] end drive one pkt
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 5
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[RNTST] 1
[my_driver] 4
小结
python
Error-[CNST-CIF] Constraints inconsistency failure
my_driver.sv, 57
Constraints are inconsistent and cannot be solved.
Please check the inconsistent constraints being printed above and rewrite
them.
约束超出预设范围,会导致失败
解决方法,使用范围内的数据值进行随机化