【验证小白】只有SV+modelsim学验证(5)——先将嗷嗷待验的DUT加入环境,至此就只遗留环境的灵魂RM了

mac2024-01-27  37

今天我们继续向前大步迈进,把待验证的DUT加入到环境中来!为此我写了一个非常复杂的模块~~主要的功能把输入的数据打两拍然后送出去。。。。当然这只是level1.0版本,后续在添加reference module时,我一定会补充更加复杂的场景代码的!其实急着把DUT放进来主要是为了下一个博客——验证环境module与program中的time slot做准备。

闲话不多说了,先来看看我的待验证DUT模块。目前功能实在是太简单了,我就不多说啥了,最后的三个fb接口是为之后预留的,可以先不管他们。那么从代码上要连接这个dut只需要两组接口,数据输入interface和数据输出interface。

`ifndef FLOW_PROC_V `define FLOW_PROC_V module flow_proc #( parameter DATA_WIDTH = 8 )( input clk , input rst_n , input data_in_vld , input sop_in_vld , input eop_in_vld , input [DATA_WIDTH-1:0] data_in , output reg data_out_vld , output reg sop_out_vld , output reg eop_out_vld , output reg [DATA_WIDTH-1:0] data_out , output fb_vld , output fb_eop , output fb_cnt ); reg data_out_vld_ff1 ; reg sop_out_vld_ff1 ; reg eop_out_vld_ff1 ; reg [DATA_WIDTH-1:0] data_out_ff1 ; always @(posedge clk) begin if(rst_n == 1'b0)begin data_out_vld_ff1 <= 1'b0; sop_out_vld_ff1 <= 1'b0; eop_out_vld_ff1 <= 1'b0; data_out_ff1 <= {DATA_WIDTH{1'b0}}; end else begin data_out_vld_ff1 <= data_in_vld; sop_out_vld_ff1 <= sop_in_vld; eop_out_vld_ff1 <= eop_in_vld; data_out_ff1 <= data_in; end end always @(posedge clk) begin if(rst_n == 1'b0)begin data_out_vld <= 1'b0; sop_out_vld <= 1'b0; eop_out_vld <= 1'b0; data_out <= {DATA_WIDTH{1'b0}}; end else begin data_out_vld <= data_out_vld_ff1; sop_out_vld <= sop_out_vld_ff1; eop_out_vld <= eop_out_vld_ff1; data_out <= data_out_ff1; end end endmodule `endif

?那我们来改造下验证环境,把DUT加入验证环境中。

改造1.用interface pkt_in_bus和pkt_out_bus分别连接DUT的入口和出口;

改造2.用in_mon采集pkt_in_bus上的信号,out_mon采集pkt_out_bus上的信号,转化为pkt格式traction;

改造3.chk不再与gen相连接,改为与in_mon和out_mon通过channnel连接;

改造4.in_mon的pkt包作为预期,out_mon的包为实际处理结果,由于DUT没有做逻辑处理因此暂时不需要RM;

改造后的验证环境如下图所示。

根据我们设计的验证环境,我们开始轰轰烈烈的改造工程。

首先来组织一下interface,可以预见到我们的模块后面的接口肯定会越来越多,那么我们不能每次加一个接口就从顶层一直加到env里面去,这种方式实在是太费力了,因此我将已有的pkt_if又封装了一层代码如下:

`include "pkt_if.sv" `ifndef PKT_INTERFACE_SV `define PKT_INTERFACE_SV interface pkt_if_pack( input logic clk, input logic rst_n ); pkt_if pkt_in_bus (clk, rst_n); pkt_if pkt_out_bus (clk, rst_n); endinterface : pkt_if_pack //class pkt_interface; // virtual pkt_if pkt_in_bus = pkt_if_pack.pkt_in_bus; // virtual pkt_if pkt_out_bus = pkt_if_pack.pkt_out_bus; //endclass : pkt_interface `endif

(注释掉的class部分可以暂时不用关注,本来是一种通过virtual来更简洁的做法但是不知道为啥modelsim编译可以过仿真时候会报错,看来我还是要早点把虚拟机里的VCS用起来才是正道。)

把两个pkt_in_bus和pkt_out_out封装在这里,之后进行例化和传递时会简单很多。

封装好interface后我们就可以把DUT例化到环境中了,直接将DUT例化在top顶层即可,这里还想吐槽下modelsim,为啥我想include rtl_link文件也要报错呢,是我不会用么?不多说了,下面是在top中的例化代码,完整代码附在最后面。

//`include “rtl_link” //part1 wire data_in_vld ; wire sop_in_vld ; wire eop_in_vld ; wire [8 -1:0] data_in ; wire data_out_vld ; wire sop_out_vld ; wire eop_out_vld ; wire [8 -1:0] data_out ; wire fb_vld ; wire fb_eop ; wire fb_cnt ; //part2 pkt_if_pack pkt_bus(clk, rst_n); //part3 flow_proc #(.DATA_WIDTH(8)) U_flow_proc( .clk (clk) , .rst_n (rst_n) , .data_in_vld (data_in_vld) , .sop_in_vld (sop_in_vld) , .eop_in_vld (eop_in_vld) , .data_in (data_in) , .data_out_vld (data_out_vld) , .sop_out_vld (sop_out_vld) , .eop_out_vld (eop_out_vld) , .data_out (data_out) , .fb_vld (fb_vld) , .fb_eop (fb_eop) , .fb_cnt (fb_cnt) ); //part4 assign data_in_vld = pkt_bus.pkt_in_bus.vld ; assign sop_in_vld = pkt_bus.pkt_in_bus.sop ; assign eop_in_vld = pkt_bus.pkt_in_bus.eop ; assign data_in = pkt_bus.pkt_in_bus.data ; assign pkt_bus.pkt_out_bus.vld = data_out_vld ; assign pkt_bus.pkt_out_bus.sop = sop_out_vld ; assign pkt_bus.pkt_out_bus.eop = eop_out_vld ; assign pkt_bus.pkt_out_bus.data = data_out ; //part5 test u_test(pkt_bus);

例化分为四个部分,part1定义wire信号,part2例化interface(与例化module方式一致),part3例化DUT,part4将interface与module相连接,part5将interface作为接口传参传入test,实现验证环境与DUT的互连。

当然每个人有自己的代码风格,这里我写的比较繁琐,主要是这样用惯了。

继续进行,接下来是最大的改动点env(test new()也有改动,看最后的代码好啦)。

改动1.if例化改为例化一份pkt_if_pack bus(之后所有的接口增减都到pkt_if_pack里面去做),例化两份mom,channel也对应的修改下;

virtual pkt_if_pack bus; pkt_gen gen; pkt_drv drv; pkt_mon in_mon; pkt_mon out_mon; pkt_chk chk; env_cfg cfg; mailbox gen2drv_chan; mailbox in_mon2chk_chan; mailbox out_mon2chk_chan;

改动2.new函数微调下;

function environment::new(input virtual pkt_if_pack bus); $display("At %0t, [ENV NOTE]: environment::new() start!", $time); this.bus = bus; this.cfg = new(); gen2drv_chan = new(1); in_mon2chk_chan = new(1); out_mon2chk_chan = new(1); endfunction

改动3.bulid()中改变组件的连接方式,gen减少一个gen2chk channel传参,最终连接与图示一致;

task environment::build(); $display("At %0t, [ENV NOTE]: environment::build() start!", $time); gen = new(cfg, gen2drv_chan); drv = new(cfg, this.bus.pkt_in_bus, gen2drv_chan); in_mon = new(cfg, this.bus.pkt_in_bus, this.in_mon2chk_chan); out_mon = new(cfg, this.bus.pkt_out_bus, this.out_mon2chk_chan); chk = new(cfg, in_mon2chk_chan, out_mon2chk_chan); endtask

再对照一下这个图;

改动4.微调run(),主要涉及in_mon和out_mon;

好的至此主要改动基本完成,不过别忘记调整pkt_gen内部代码,毕竟少了一个通道嘛。

最终的编译文件和编译顺序如下图:

编译完成后,run个100000ns啥的发100个包

看看波形和打印log:

太完美了!附上截至目前为止的代码,睡觉~~~

 

附目前为止所有文件

`include "pkt_dec.sv" module top(); logic clk; logic rst_n; initial begin #0ns clk = 0; forever #5ns clk = ~clk; end initial begin #0ns rst_n = 0; #225ns rst_n = 1; end //`include “rtl_link” wire data_in_vld ; wire sop_in_vld ; wire eop_in_vld ; wire [8 -1:0] data_in ; wire data_out_vld ; wire sop_out_vld ; wire eop_out_vld ; wire [8 -1:0] data_out ; wire fb_vld ; wire fb_eop ; wire fb_cnt ; pkt_if_pack pkt_bus(clk, rst_n); flow_proc #(.DATA_WIDTH(8)) U_flow_proc( .clk (clk) , .rst_n (rst_n) , .data_in_vld (data_in_vld) , .sop_in_vld (sop_in_vld) , .eop_in_vld (eop_in_vld) , .data_in (data_in) , .data_out_vld (data_out_vld) , .sop_out_vld (sop_out_vld) , .eop_out_vld (eop_out_vld) , .data_out (data_out) , .fb_vld (fb_vld) , .fb_eop (fb_eop) , .fb_cnt (fb_cnt) ); assign data_in_vld = pkt_bus.pkt_in_bus.vld ; assign sop_in_vld = pkt_bus.pkt_in_bus.sop ; assign eop_in_vld = pkt_bus.pkt_in_bus.eop ; assign data_in = pkt_bus.pkt_in_bus.data ; assign pkt_bus.pkt_out_bus.vld = data_out_vld ; assign pkt_bus.pkt_out_bus.sop = sop_out_vld ; assign pkt_bus.pkt_out_bus.eop = eop_out_vld ; assign pkt_bus.pkt_out_bus.data = data_out ; test u_test(pkt_bus); endmodule `ifndef PKT_DATA_SV `define PKT_DATA_SV class pkt_data; rand bit [7:0] payload_q[$]; rand int interval; rand int pkt_len; bit send_over; bit [10:0] data[$]; constraint data_size_cons{ payload_q.size() == pkt_len; }; constraint pkt_len_cons{ pkt_len inside {[1:50]}; //pkt_len == 5; }; constraint interval_cons{ interval inside {[3:6]}; }; extern function new(); extern virtual function string psprintf(string preset = ""); extern virtual function bit compare(pkt_data to); extern virtual function void pack(); extern virtual function void unpack(); extern virtual function pkt_data copy(pkt_data to=null); endclass function pkt_data::new(); endfunction function bit pkt_data::compare(pkt_data to); bit match = 1; if(this.pkt_len != to.pkt_len) match = 0; foreach(payload_q[i]) if(this.payload_q[i] != to.payload_q[i]) match = 0; return match; endfunction:compare function void pkt_data::pack(); foreach (this.payload_q[i]) begin if (i==0 & i==pkt_len-1) //modify!!!!! this.data.push_back({1'b1, 1'b1, 1'b1, payload_q[i]}); else if (i==0) this.data.push_back({1'b1, 1'b1, 1'b0, payload_q[i]}); else if (i==pkt_len-1) this.data.push_back({1'b1, 1'b0, 1'b1, payload_q[i]}); else this.data.push_back({1'b1, 1'b0, 1'b0, payload_q[i]}); end for(int i=0; i<interval; i++)begin this.data.push_front({'0}); end endfunction function string pkt_data::psprintf(string preset = ""); psprintf = {preset, $psprintf("pkt_len = %0d", pkt_len)}; foreach(payload_q[i]) psprintf = {psprintf, ",", $psprintf("payload[%0d] = 'h%0h", i, payload_q[i])}; endfunction function pkt_data pkt_data::copy(pkt_data to=null); pkt_data tmp; if (to == null) tmp = new(); else $cast(tmp, to); tmp.interval = this.interval; tmp.pkt_len = this.pkt_len; tmp.send_over= this.send_over; foreach(this.payload_q[i])begin tmp.payload_q.push_back(this.payload_q[i]); end return tmp; endfunction function void pkt_data::unpack(); this.pkt_len = payload_q.size(); endfunction `endif `ifndef ENV_CFG_SV `define ENV_CFG_SV class env_cfg; bit chk_idle; bit gen_idle; bit drv_idle; bit mon_idle; int env_wait_pkt_time = 10000; int mon_wait_pkt_time = 1000; int drv_wait_pkt_time = 1000; int chk_wait_pkt_time = 1000; endclass:env_cfg `endif `include "pkt_if.sv" `include "environment.sv" program automatic test(pkt_if_pack bus); environment env; initial begin env = new(bus); env.build(); env.gen.send_num = 100; env.run(); $display("At %0t, [TESt NOTE]: simulation finish~~~~~~~~~~~~~~~~~~", $time); $finish; end endprogram `ifndef ENV_SV `define ENV_SV `include "pkt_gen.sv" `include "pkt_drv.sv" `include "pkt_mon.sv" `include "pkt_chk.sv" `include "pkt_if.sv" `include "env_cfg.sv" `include "pkt_if_pack.sv" class environment; virtual pkt_if_pack bus; pkt_gen gen; pkt_drv drv; pkt_mon in_mon; pkt_mon out_mon; pkt_chk chk; env_cfg cfg; mailbox gen2drv_chan; mailbox in_mon2chk_chan; mailbox out_mon2chk_chan; int send_pkt_num; //for finish fimu int wait_time; extern function new(input virtual pkt_if_pack bus); extern virtual task build(); extern virtual task run(); extern virtual task report(); endclass function environment::new(input virtual pkt_if_pack bus); $display("At %0t, [ENV NOTE]: environment::new() start!", $time); this.bus = bus; this.cfg = new(); gen2drv_chan = new(1); in_mon2chk_chan = new(1); out_mon2chk_chan = new(1); endfunction task environment::build(); $display("At %0t, [ENV NOTE]: environment::build() start!", $time); gen = new(cfg, gen2drv_chan); drv = new(cfg, this.bus.pkt_in_bus, gen2drv_chan); in_mon = new(cfg, this.bus.pkt_in_bus, this.in_mon2chk_chan); out_mon = new(cfg, this.bus.pkt_out_bus, this.out_mon2chk_chan); chk = new(cfg, in_mon2chk_chan, out_mon2chk_chan); endtask task environment::run(); fork drv.run(); gen.run(); in_mon.run(); out_mon.run(); chk.run(); join_none #100; fork //$display("At %0t, [ENV NOTE]: wait for end............", $time); begin wait(cfg.gen_idle); wait(cfg.drv_idle); wait(cfg.mon_idle); wait(cfg.chk_idle); $display("At %0t, [ENV NOTE]: normal finish", $time); end begin while(1)begin @(negedge top.clk); if(this.bus.pkt_in_bus.vld) wait_time = 0; else wait_time++; if(wait_time > this.cfg.env_wait_pkt_time) break; end $display("At %0t, [ENV ERROR]: time out!!!!!", $time); end join_any #1000; report(); endtask task environment::report(); $display("At %0t, [ENV NOTE]: report start", $time); repeat(100) @top.clk; chk.report(); $display("At %0t, [ENV NOTE]: report over", $time); endtask `endif `ifndef PKT_GEN_SV `define PKT_GEN_SV `include "pkt_data.sv" `include "env_cfg.sv" class pkt_gen; env_cfg cfg; mailbox gen2drv_chan; pkt_data pkt; int send_num; extern function new(env_cfg cfg, mailbox gen2drv_chan); extern virtual task run(); endclass function pkt_gen::new(env_cfg cfg, mailbox gen2drv_chan); this.cfg = cfg; this.gen2drv_chan = gen2drv_chan; this.pkt = new(); endfunction task pkt_gen::run(); pkt_data send_pkt; pkt_data chk_pkt; $display("At %0t, [GEN NOTE]: send_num = %0d", $time, send_num); repeat(send_num) begin assert(pkt.randomize()); $cast(send_pkt, pkt.copy()); $cast(chk_pkt, pkt.copy()); gen2drv_chan.put(send_pkt); end this.cfg.gen_idle = 1; //$display("At %0t, [GEN NOTE]: gen over pkt", $time); endtask `endif `ifndef PKT_DRV_SV `define PKT_DRV_SV `include "pkt_data.sv" `include "pkt_if.sv" `include "env_cfg.sv" class pkt_drv; env_cfg cfg; mailbox gen2drv_chan; vdrv dif; //for finish simu int idle_cnt; int get_num; extern function new(env_cfg cfg, vdrv dif, mailbox gen2drv_chan ); extern virtual task run(); extern virtual task my_run(); extern virtual task rst_sig(); extern virtual task pkt_send(input pkt_data pkt); extern virtual task set_idle(); endclass function pkt_drv::new(env_cfg cfg, vdrv dif, mailbox gen2drv_chan ); this.cfg = cfg; this.dif = dif; this.gen2drv_chan = gen2drv_chan; this.get_num = 0; endfunction task pkt_drv::run(); fork my_run(); set_idle(); join_none endtask task pkt_drv::my_run(); pkt_data send_pkt; //$display("At %0t, [DRV NOTE]: pkt_drv run start!", $time); rst_sig(); //$display("At %0t, [DRV NOTE]: after rst_n", $time); while(1) begin gen2drv_chan.peek(send_pkt); //$display("At %0t, [DRV NOTE]: get no.%0d pkt from gen", $time, this.get_num++); send_pkt.pack(); pkt_send(send_pkt); gen2drv_chan.get(send_pkt); rst_sig(); end endtask:my_run task pkt_drv::rst_sig(); wait(top.rst_n == 1'b1); @(posedge top.clk); this.dif.vld <= '0; this.dif.sop <= '0; this.dif.eop <= '0; this.dif.data<= '0; endtask task pkt_drv::pkt_send(input pkt_data pkt); foreach(pkt.data[i]) begin @(posedge top.clk); this.dif.vld <= pkt.data[i][10]; this.dif.sop <= pkt.data[i][9]; this.dif.eop <= pkt.data[i][8]; this.dif.data<= pkt.data[i][7:0]; end endtask task pkt_drv::set_idle(); while(1)begin @(negedge top.clk); if(this.dif.vld == 1) idle_cnt = 0; else idle_cnt++; if(idle_cnt > this.cfg.drv_wait_pkt_time) this.cfg.drv_idle = 1; else this.cfg.drv_idle = 0; end endtask:set_idle `endif `ifndef PKT_MON_SV `define PKT_MON_SV `include "pkt_data.sv" `include "pkt_if.sv" `include "env_cfg.sv" class pkt_mon; env_cfg cfg; vmon mif; mailbox mon2chk_chan; bit rec_status;//0:wait sop, 1:wait eop int wait_pkt_time = 1000; extern function new(env_cfg cfg, vmon mif, mailbox mon2chk_chan); extern virtual task run(); extern virtual task send_chk(pkt_data pkt); endclass function pkt_mon::new(env_cfg cfg, vmon mif, mailbox mon2chk_chan ); this.cfg = cfg; this.mif = mif; this.mon2chk_chan = mon2chk_chan; this.wait_pkt_time = cfg.mon_wait_pkt_time; this.rec_status = 0; endfunction : new task pkt_mon::run(); pkt_data rec_pkt; int wait_time; int i = 0; //$display("At %0t, [MON NOTE]: run start!", $time); while(1) begin while(1) begin @(posedge top.clk); if(mif.vld == 1)begin wait_time = 0; if(rec_status == 0) begin//wait sop rec_pkt = new(); if(mif.sop == 0) begin $display("At %0t, [MON ERROR]: ERROR! The first pkt cycle is not sop!", $time); break; end else begin rec_pkt.payload_q.push_back(mif.data); if(mif.eop == 1) begin rec_status = 0; //$display("At %0t, [MON NOTE]: get no.%0d pkt!", $time, i++); send_chk(rec_pkt); end else rec_status = 1; end end else if(rec_status == 1) begin//wait eop if(mif.sop == 1) begin $display("At %0t, [MON ERROR]: ERROR! SOP????", $time); break; end else begin rec_pkt.payload_q.push_back(mif.data); if(mif.eop == 1) begin rec_status = 0; //$display("At %0t, [MON NOTE]: get no.%0d pkt!", $time, i++); send_chk(rec_pkt); end else rec_status = 1; end end end else begin wait_time++; if(wait_time <= wait_pkt_time) begin wait_time++; end else break; end end this.cfg.mon_idle = 1; //$display("At %0t, [MON NOTE]: mon run over!", $time); break; end endtask : run task pkt_mon::send_chk(pkt_data pkt); pkt.unpack(); mon2chk_chan.put(pkt); endtask : send_chk `endif `ifndef PKT_CHK_SV `define PKT_CHK_SV `include "pkt_data.sv" `include "env_cfg.sv" class pkt_chk; env_cfg cfg; pkt_data expect_q[$]; int in_expect, in_actual; int match, not_match; mailbox gen2chk_chan; mailbox mon2chk_chan; //for finish simu int idle_cnt; extern function new(env_cfg cfg, mailbox gen2chk_chan, mailbox mon2chk_chan); extern virtual task run(); extern virtual task expect_gain(); extern virtual task actual_gain(); extern virtual task set_idle(); extern virtual function report(); endclass:pkt_chk function pkt_chk::new(env_cfg cfg, mailbox gen2chk_chan, mailbox mon2chk_chan); this.cfg = cfg; this.gen2chk_chan = gen2chk_chan; this.mon2chk_chan = mon2chk_chan; endfunction:new task pkt_chk::run(); fork expect_gain(); actual_gain(); set_idle(); join_none endtask:run task pkt_chk::expect_gain(); pkt_data expect_data; while(1) begin gen2chk_chan.get(expect_data); this.expect_q.push_back(expect_data); in_expect++; idle_cnt = 0; //$display("At %0t, [CHK NOTE]: get a expect pkt", $time); end endtask:expect_gain task pkt_chk::actual_gain(); pkt_data expect_data; pkt_data actual_data; while(1) begin mon2chk_chan.get(actual_data); in_actual++; idle_cnt = 0; if(this.expect_q.size == 0) $display("At %0t, [CHK ERROR]: expect_q==0???", $time); else begin expect_data = expect_q[0]; if(!expect_data.compare(actual_data)) begin $display("At %0t, [CHK ERROR]: no match, \nexpect data:%s \nactual data:%s ", $time, expect_data.psprintf(), actual_data.psprintf()); expect_q.pop_front(); not_match++; end else begin expect_q.pop_front(); //$display("At %0t, [CHK NOTE]: match, \nexpect data:%s \nactual data:%s ", $time, expect_data.psprintf(), actual_data.psprintf()); match++; end end end endtask:actual_gain task pkt_chk::set_idle(); while(1)begin @(negedge top.clk); idle_cnt++; if(idle_cnt > this.cfg.chk_wait_pkt_time) this.cfg.chk_idle = 1; else this.cfg.chk_idle = 0; end endtask:set_idle function pkt_chk::report(); $display("----------------------------------------------------------------------------------------------------"); $display("[CHECKER REPORT]expect pkt_num=%0d, actual pkt_num=%0d, match pkt_num=%0d, not match pkt_num=%0d", in_expect, in_actual, match, not_match); $display("----------------------------------------------------------------------------------------------------"); endfunction:report `endif `ifndef PKT_IF_SV `define PKT_IF_SV interface pkt_if(input clk, rst_n); logic [7:0] data; logic sop; logic eop; logic vld; clocking drv @(posedge clk); output data; output sop, eop, vld; endclocking : drv modport pkt_drv (clocking drv); clocking mon @(posedge clk); input data; input sop, eop, vld; endclocking : mon modport pkt_mon (clocking mon); endinterface typedef virtual pkt_if.drv vdrv; typedef virtual pkt_if.mon vmon; `endif `ifndef FLOW_PROC_V `define FLOW_PROC_V module flow_proc #( parameter DATA_WIDTH = 8 )( input clk , input rst_n , input data_in_vld , input sop_in_vld , input eop_in_vld , input [DATA_WIDTH-1:0] data_in , output reg data_out_vld , output reg sop_out_vld , output reg eop_out_vld , output reg [DATA_WIDTH-1:0] data_out , output fb_vld , output fb_eop , output fb_cnt ); reg data_out_vld_ff1 ; reg sop_out_vld_ff1 ; reg eop_out_vld_ff1 ; reg [DATA_WIDTH-1:0] data_out_ff1 ; always @(posedge clk) begin if(rst_n == 1'b0)begin data_out_vld_ff1 <= 1'b0; sop_out_vld_ff1 <= 1'b0; eop_out_vld_ff1 <= 1'b0; data_out_ff1 <= {DATA_WIDTH{1'b0}}; end else begin data_out_vld_ff1 <= data_in_vld; sop_out_vld_ff1 <= sop_in_vld; eop_out_vld_ff1 <= eop_in_vld; data_out_ff1 <= data_in; end end always @(posedge clk) begin if(rst_n == 1'b0)begin data_out_vld <= 1'b0; sop_out_vld <= 1'b0; eop_out_vld <= 1'b0; data_out <= {DATA_WIDTH{1'b0}}; end else begin data_out_vld <= data_out_vld_ff1; sop_out_vld <= sop_out_vld_ff1; eop_out_vld <= eop_out_vld_ff1; data_out <= data_out_ff1; end end endmodule `endif

 

`include "pkt_if.sv" `ifndef PKT_INTERFACE_SV `define PKT_INTERFACE_SV interface pkt_if_pack( input logic clk , input logic rst_n ); pkt_if pkt_in_bus (clk, rst_n); pkt_if pkt_out_bus (clk, rst_n); endinterface : pkt_if_pack //class pkt_interface; // virtual pkt_if pkt_in_bus = pkt_if_pack.pkt_in_bus; // virtual pkt_if pkt_out_bus = pkt_if_pack.pkt_out_bus; //endclass : pkt_interface `endif

 

最新回复(0)