SV的接口应用——interface

本文介绍了SystemVerilog中的接口interface在硬件验证中的重要作用,它简化了Testbench与DUT的连接方式,提供了智能的信号集和同步时钟域管理。文中通过一个简单的仲裁器例子,展示了如何定义接口、modport以及如何在测试环境中使用接口进行激励生成。示例代码详细解释了接口在实际设计中的应用,包括接口文件、激励文件和顶层文件的编写,强调了clocking模块在同步时钟域中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、接口interface介绍

1.1.interface产生背景

传统的Verilog连接验证平台Testbench与DUT的方式名字映射、位置映射
在这里插入图片描述
下面给出实例:
在这里插入图片描述
SystemVerilog则对Verilog的连接方式进行了改进补充,引入了接口interface。

1.2.接口的使用方式

  • 可以直接通过接口的例化名字来实现连接;
  • 可以通过接口中定义的信号来实现连接;

在这里插入图片描述

  SV中接口为块之间的通信建模,接口可以看成是一捆智能的连线。接口包含了连接,同步,甚至是两个块或者更多块之间的通信功能。它们连接了设计和测试平台。具有以下特点:

  • interface中包含了 一组信号
  • interface可以是 一个独立的文件,将多个模块通用的信号集中放在一个文件中;
  • interface中集合了多个Verilog类型信号,是一个独立的端口类型;
  • interface中可以包含多个modport 定义interface的不同视图view(DUT、Test program)
  • interface中可以使用clocking模块 显式指明同步时钟域
  • interface中的clocking只用于验证平台,其中可包含多个clocking模块,clocking中的信号方向与Testbench相关

二、示例代码

以下为一个简易的仲裁器RTL(DUT)代码arb.v:

module arb(                  //简单的仲裁器
           input    reset_n,
           input    clk,
           input    request,
           output reg  grant);

always @(posedge clk or negedge reset_n) begin
if(reset_n 1’b0)begin
grant <= 1’b0;
end
else if(request 1’b1)begin
grant <= 1’b1;
end
else if(request == 1’b0)begin
grant <= 1’b0;
end
end

endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

接口interface文件arb_if.sv:

interface arb_if(input bit clk);   //通常在接口的端口列表中声明时钟信号
       logic      grant;
       logic      request;
       logic      reset_n;
clocking cb@<span class="token punctuation">(</span>posedge clk<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment">//用于同步时钟域,相当于寄存器,将信号寄存一拍</span>
   input      grant<span class="token punctuation">;</span>            <span class="token comment">//clocking模块主要服务于TB</span>
   output     request<span class="token punctuation">;</span>
endclocking

modport TB(                    <span class="token comment">//定义TB视图view</span>
    clocking   cb<span class="token punctuation">,</span>
    output     reset_n)<span class="token punctuation">;</span>

modport <span class="token function">dut</span><span class="token punctuation">(</span>                    <span class="token comment">//定义dut视图view</span>
    input      request<span class="token punctuation">,</span>
    input      reset_n<span class="token punctuation">,</span>
    output     grant<span class="token punctuation">)</span><span class="token punctuation">;</span>

endinterface

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

激励文件test.sv: 通常使用program块编写,可以隐式执行$finish;系统函数结束代码块

program test(arb_if.TB arbif);     //例化接口中的TB视图

initial begin
//Asynch drive reset_n
arbif.cb.request <= 1’b0; //通过时钟clk上沿将request发出给DUT
arbif.reset_n <= 1’b1; //TB中的reset_n与request是异步关系,不需要cb
#15 arbif.reset_n <= 1’b0; //复位,稳定电路
#35 arbif.reset_n <= 1’b1; //撤离复位
#5;
//Synch drive request
//repeat(5)begin
arbif.cb.request <= 1’b1; //TB通过clk上沿将cb.request发送至DUT,DUT会输出一个dut.grant,并传递回给TB(cb.grant)
wait(arbif.cb.grant <= 1’b1;); //TB对接收自DUT(dut.grant)的cb.grant进行判断,完成一次信息交互
arbif.cb.request <= 1’b0;
@arbif.cb; //@(posedge clk);
@arbif.cb;
@arbif.cb;
//end
end

endprogram //program模块不需要$finish函数来结束激励

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

顶层文件arb_tb.sv:包裹接口文件、激励文件和DUT文件

module ARB_TB();
    bit      clk;        
    arb_if   arbif(.*);    //隐式例化接口(clk信号名一样),等价arb_if arbif(.clk(clk));
    test     u_test(.*);   //隐私例化激励文件
    arb      u_arb(        //通过接口连接TB与DUT
                  .reset_n(arbif.reset_n),
                  .clk    (clk),
                  .request(arbif.request),
                  .grant  (arbif.grant) 
               );
     initial begin
        clk = 0;
        forever #10 clk = ~clk;
     end

endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

对于波形图, 要注意时钟沿数数据变化边沿出现重合的情况,此时,由于数据延迟,时钟沿通常采集的是数据变化边沿之前的状态数据。如下图DUT中所示:
在这里插入图片描述
同时要注意clocking对于信号的同步时钟域作用
在这里插入图片描述

SV小项目-异步FIFO是一个简单的项目,旨在让学生理解FIFO缓存的原理和实现方式。 FIFO缓存是一种常用的数据存储方式,可以用于解决数据传输时的不匹配问题。在异步FIFO中,数据的写入和读取是异步的,意味着数据可以在任何时候写入或读取。这种异步的方式可以增加FIFO的灵活性,并且允许数据的写入和读取在不同的时钟域上应用。 这个小项目的主要目标是实现一个基于Verilog的异步FIFO模块,包括以下功能: 1. 内部缓存的储存和检索 2. 空和满指示器的生成 3. 数据的写入和读取 对于写入操作,当FIFO未满时,它将数据存储在内部缓存中,并更新其指针以指向下一个空位置。当缓存已满时,写入操作将被忽略,并且FIFO满指示器将被设置为高电平。同样,读取操作从内部缓存中检索数据,并将其指针更新以指向下一个位置。当缓存为空时,读操作将被忽略,并且FIFO空指示器将被设置为高电平。 在设计过程中,需要考虑解决的问题包括时序和异步信号的同步。时序问题可以通过FIFO指针和状态机解决,而异步信号可以通过信号同步器进行同步。此外,还需要考虑FIFO的读写顺序和存储器的尺寸,并确保FIFO模块的有效性和可靠性。 总之,通过实现SV异步FIFO项目,学生可以加深对FIFO缓存的理解,并学习基于Verilog的设计和实现。此外,学生还可以通过在项目中遇到的挑战来提高他们的编程和设计技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值