Systemverilog 接口 interface modport使用说明

news2024/9/27 12:04:45

一、接口的定义
     SystemVerilog在Verilog语言基础上扩展了“接口”(interface)结构,SystemVerilog增加了新的端口类型—接口,接口允许许多信号合成一组由一个端口表示,只需在一个地方对组成接口的信号进行声明,使用这些信号的模块只需一个接口类型的端口。
        接口声明举例:main_bus.sv


interface main_bus;
    wire [15:0] data;
    wire [15:0] address;
    logic [ 7:0] slave_instr;
    logic slave_req;
    logic bus_grant;
    logic bus_req;
    logic slave_rdy;
    logic data_rdy;
    logic mem_read;
    logic mem_write;
endinterface

        在顶层模块中例化接口:top.sv

module top (input logic clock, resetn, test_mode);
    logic [15:0] program_addr, jump_addr;
    logic [ 7:0] instr, next_instr;
    main_bus bus ( );  // instance of an interface
// (instance name is bus)

    processor proc1 (
// main_bus ports
        .bus(bus), // interface connection
// other ports
        .jump_addr (jump_addr),
        .instr (instr),
        .clock(clock),
        .resetn(resetn),
        .test_mode(test_mode));

 slave slave1 (
// main_bus ports
        .bus(bus), // interface connection
// other ports
        .clock(clock),
        .resetn(resetn));

    dual_port_ram ram (
// main_bus ports
        .bus(bus), // interface connection
// other ports
        .program_addr (program_addr),
        .data_b(next_instr));

endmodule

二、接口的内容
        接口不仅仅是一组连接线,它也可以封装模块间通信的所有细节。使用接口可以:(1)在一个地方—接口中定义通信所需的各个信号和端口;(2)在接口中定义通信协议;(3)在接口中直接建立协议校验和其它验证程序。
        接口可以包含类型声明、任务、函数、过程块、程序块和断言

        接口与模块之间有三个不同点:
         (1)接口不可以包含设计层次,接口不可以包含模块或原语的实例
         (2) 接口可以用作模块端口,表示模块间的通信通道,而在端口中使用模块则是非法的
         (3)接口可以包含“modport”,这使得每个连接到接口上的模块以不同的方式访问接口。          (4) 接口内部信号的使用,在有接口类型端口的模块中,接口内部信号必须用端口名进行访问:<端口名称>.<接口内部信号名称>


//接口声明
interface main_bus;
    wire [15:0] data;
    wire [15:0] address;
    logic [ 7:0] slave_instr;
    logic slave_req;
    logic bus_grant;
    logic bus_req;
    logic slave_rdy;
    logic data_rdy;
    logic mem_read;
    logic mem_write;
endinterface

//接口信号调用
module slave ( main_bus bus);
// internal signals
  logic [15:0] slave_data, slave_addr;
  logic [15:0] operand_A, operand_B;
  logic mem_select, read, write;
  
  //assign bus.address=mem_select ? slave_addr :'z;
  
  assign bus.address = mem_select? slave_addr: 'z;
  assign bus.data = bus.slave_rdy? slave_data: 'z;
 

 enum logic [4:0] {RESET = 5'b00001, START = 5'b00010,
   REQ_DATA = 5'b00100, EXECUTE = 5'b01000,
   DONE = 5'b10000} State, NextState;
   
   
  always_ff @(posedge bus.clock, negedge bus.resetn)
   begin: FSM
        if (!bus.resetn) State <= START;
        else State <= NextState;
    end
   always_comb begin : FSM_decode
        unique case (State)
            START: if (!bus.slave_req) begin
                bus.bus_req = 0;
                NextState = State;
            end
            else begin
                operand_A = bus.data;
                slave_addr = bus.address;
                bus.bus_req = 1;
                NextState = REQ_DATA;
            end
	// decode other states
        endcase
    end: FSM_decode
endmodule

接口的modport

 SystemVerilog提供两种方法指定模块接口端口使用modport的方式:
 (1)
在模块实例化时的接口连接中说明
 (2)
在模块定义的端口声明时说明;

  在模块实例化时的接口连接中说明


interface chip_bus (input logic clock, resetn);
    logic interrupt_req, grant, ready;
    logic [31:0] address;
    wire [63:0] data;
    modport master (input interrupt_req,
        input address,
        output grant, ready,
        inout data,
        input clock, resetn);
    modport slave (output interrupt_req,
        output address,
        input grant, ready,
        inout data,
        input clock, resetn);
endinterface

//
module primary (interface pins); // generic interface port

endmodule
module secondary (chip_bus pins); // specific interface port

endmodule

module chip (input logic clock, resetn);
chip_bus bus (clock, resetn); // instance of an interface
primary i1 (bus.master);  // use the master modport view
secondary i2 (bus.slave); // use the slave modport view
endmodule

在modport既可在模块实例化时指定,又可以在模块定义中指定,但不能同时选择这两种方式!!
 模块定义的端口声明时说明;

module primary (chip_bus.master pins); // generic interface port
...
endmodule
module secondary (chip_bus.slave pins); // specific interface port
...
endmodule
module chip (input logic clock, resetn);
chip_bus bus (clock, resetn); // instance of an interface
primary i1 (bus); // use the master modport view
secondary i2 (bus); // use the slave modport view
endmodule

三、interface 一主一从结构间的读写操作

 这一部分主要是interface的实际应用,在总线上挂有一主一从结构,主机对从机进行读写操作,使用modport的接口方式,同时博主也对于自己在撰写过程中遇见的错误进行了总结。
在这里插入图片描述

接口部分:

//需要输入的信号 一定要在接口端口声明,否则无法传递数值
interface zuoye_interface(input logic CLK,
          input logic RESETN,
          input [31:0] wdata,         
          input [31:0] waddr,
          input [31:0] raddr);
 
logic [31:0] WDATA;
logic [31:0] RDATA;
logic [31:0] rdata;
logic [31:0] WADDR;
logic [31:0] RADDR;
logic WRITE_REQ;
logic WRITE_ACK;
logic READ_ACK;
logic READ_REQ;
logic WR_DONE;
logic RD_DONE;

//主机master
modport M1(
             input CLK,
             input RESETN,
             input WRITE_ACK,
             input READ_ACK,
             input RD_DONE,
             input wdata,
             input RDATA,
             input waddr,
             input raddr,
             output WDATA,
             output rdata,
             output WRITE_REQ,
             output WADDR,
             output RADDR,
             output READ_REQ,
             output WR_DONE
);

//从机slave
modport S1(
            input WR_DONE,
            input CLK,
            input RESETN,
            input WDATA,
            input WADDR,
            input RADDR,
            input WRITE_REQ,
            input READ_REQ,
            output RDATA,
            output READ_ACK,
            output WRITE_ACK,
            output RD_DONE
);
endinterface

TOP模块部分

module zuoye_top(input CLK,RESETN);
   zuoye_interface u1(.CLK,.RESETN);
   zuoye_M1 i1(u1.M1);
   zuoye_S1 i2(u1.S1);
endmodule

主机Master部分
 

module zuoye_M1(zuoye_interface.M1 M1);
enum logic [2:0] 
{IDLE,WAIT,WRITE_ADDR,WRITE_DATA,
STOP,READ_ADDR,READ_DATA}State,NextState;
logic [1:0] wr_flag;
always_ff @(posedge M1.CLK , negedge M1.RESETN)
begin
  if(!M1.RESETN)
    State <= IDLE;
  else
    State <= NextState;
end
always_comb
begin
 NextState=State;
unique case(State) 
  IDLE: begin
   if(wr_flag==1) 
     NextState=READ_ADDR;
   else
     NextState=WAIT;
   end 
  WAIT: begin
        if(M1.WRITE_ACK==1)
          NextState=WRITE_ADDR;
  end
  
  WRITE_ADDR:begin
    NextState=WRITE_DATA;
  end
  
  WRITE_DATA:begin
   NextState=IDLE;
  end
  
  READ_ADDR:begin
    if(M1.RD_DONE==1)
    NextState=READ_DATA;
  end
  
  READ_DATA:begin
    NextState=STOP;
  end
  
  STOP:begin
    NextState=IDLE;
  end
 endcase
end

always_ff@(posedge M1.CLK , negedge M1.RESETN)
begin
  // wr_flag <=0;
  wr_flag <=0;
  M1.WR_DONE <=0;
 unique case(State)
  IDLE: begin
    if(wr_flag==1) begin
     M1.READ_REQ  <=1;
     M1.WRITE_REQ <=0;
     end
    else begin
     M1.WRITE_REQ <=1;
     M1.READ_REQ  <=0;
     end
    end
  WAIT: begin
     ;
    end
       
  WRITE_ADDR: begin
     M1.WADDR <=M1.waddr;
   end
  WRITE_DATA: begin
    M1.WDATA  <=M1.wdata;
    wr_flag   <=1;
    M1.WR_DONE   <=1;
    end
  
  READ_ADDR: begin
    M1.RADDR <=M1.raddr;
    end
  
  READ_DATA:begin
    M1.rdata <=M1.RDATA;
    end
  
  
  STOP: begin
   ;
  end
 endcase
end

endmodule

从机slave部分

module zuoye_S1(zuoye_interface.S1 S1);
enum logic [2:0] 
{IDLE,WAIT,WRITE,STOP,READ}State,NextState;
logic [1:0] flag; //write finish
logic [7:0] array [0:255];  //memory


always_ff @(posedge S1.CLK , negedge S1.RESETN)
begin
  if(!S1.RESETN)
    State <= IDLE;
  else
    State <= NextState;
end
  
  
always_comb
begin
 NextState=State;       //初始化
unique case(State) 
  IDLE: 
    begin
     if(flag==1)
      NextState=READ;
     else
      NextState=WAIT;
    end
  
  WAIT: begin
        if(S1.WRITE_REQ==1&&S1.WR_DONE==1)
          NextState=WRITE;
        else if(S1.READ_REQ==1)
          NextState=READ;
        else
          NextState=WAIT;
  end
  
  WRITE:begin
        NextState=IDLE;
   end
  
  READ:begin
       NextState=STOP;
  end
  
  STOP:begin
    NextState=IDLE;
  end
 endcase
end
  
always_ff@(posedge S1.CLK , negedge S1.RESETN)
begin
  flag <=0;
  S1.RD_DONE <=0;
 unique case(State)
  IDLE: begin
     ;
    end
  WAIT: begin
     if(S1.WRITE_REQ==1)
         S1.WRITE_ACK <= 1; 
     else if(S1.READ_REQ==1)
         S1.READ_ACK  <= 1;
     end
       
  WRITE: begin
    array[S1.WADDR] <= S1.WDATA;
    flag <=1;
   end
  
  READ: begin
     S1.RDATA <= array[S1.RADDR];
     S1.RD_DONE  <= 1;
    end
  
  
  STOP: begin
   ;
  end
 endcase
end
endmodule

 测试代码

module zuoye_top_tb;
logic CLK,RESETN;
logic [31:0] waddr,raddr;
logic [31:0] wdata;
zuoye_interface bus(.CLK(CLK),.RESETN(RESETN),
.wdata(wdata),.waddr(waddr),.raddr(raddr));
  zuoye_M1 u_M1(bus.M1);
  zuoye_S1 u_S1(bus.S1);
initial
  begin
   CLK=0;
  forever #5 CLK=~CLK;
  end

initial
begin
   RESETN=1;
#10
   RESETN=0;
#10
   RESETN=1;
end

initial
begin
  wdata=32'h8000_0000;
  waddr=32'h8000_0000;
#50;
for(int i=0;i<32;i++)
begin
   waddr=i;
   wdata=i;
 #120;
end

for(int j=0;j<32;j++)
begin
   raddr=j;
 #120;
 end
 $finish;
end
endmodule


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/889273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4G无线网络草坪音箱,4G石头音箱

SV-7042UG 4G无线网络草坪音箱&#xff0c;4G石头音箱 一、描述 SV-7042UG是深圳锐科达电子有限公司的一款壁挂式4G无线网络草坪音箱&#xff0c;通过4G无线卡联网&#xff0c;可将网络音源通过自带的功放和喇叭输出播放&#xff0c;其采用防水设计&#xff0c;功率40W。SV-70…

chatgpt 翻译整本英文电子书,效果非常好

1. 注册chatgpt账号&#xff0c;登录后设置好API token。 https://platform.openai.com/account/api-keys 一定要把生成的token先复制保存好&#xff0c;对话框消失后就无法看到完整token了。 2. 配置免费的cloudflare workers 代理&#xff0c;否则很容易被封号 参考文档 h…

【Windows系统编程】05.内存操作与InlineHook(详解InlineHook实现)

文章目录 内存相关InlineHook完整实现代码&#xff08;dll&#xff09;&#xff1a; InlineHook测试&#xff1a; 内存相关 内存信息 头文件&#xff1a;#include <Psapi.h> //检索有关系统当前使用物理内存和虚拟内存的信息MEMORYSTATUSEX mst;GlobalMemoryStatusEx…

docker 容器满了常用处理方法

docker 容器满了常用处理方法 1、运行 df -h 查看剩余磁盘占用情况 2、进入到docker目录 cd /var/lib/docker 3、运行du -h --max-depth1 &#xff08;检索文件的最大深度1&#xff0c;即只检索汇总计算当前目录下的文件&#xff09; 4、进入占用最大的 /containers文件夹&am…

pg各种条件判断语句

1.基本查询 搜索语句&#xff1a; select (distinct&#xff08;去重&#xff09;) 内容&#xff08;*代表所有&#xff09; as 别名 from 表 注释&#xff1a; -- 快速查询&#xff1a;select 内容 AS 别名 没有表一般当做计算器来用 2.条件查询 null只能用is 或者is…

7.11 Java方法重写

7.11 Java方法重写 这里首先要确定的是重写跟属性没有关系&#xff0c;重写都是方法的重写&#xff0c;与属性无关 带有关键字Static修饰的方法的重写实例 父类实例 package com.baidu.www.oop.demo05;public class B {public static void test(){System.out.println("这…

CLion 创建Qt工程

环境 CLion &#xff1a;2019.3.6 Qt &#xff1a;5.9.6&#xff08;MinGW&#xff09; Clion 配置 编译环境配置 添加Qt MinGW编译环境 添加Qt工具 创建工程 正常创建C工程 CMakeLists cmake_minimum_required(VERSION 3.8) project(QtApp)set(CMAKE_CXX_STANDARD 11)…

APB register脚本

[github repo]根据Excel表格自动生成寄存器RTL/RALF/C header的脚本 - wudayemen - 博客园 (cnblogs.com) 在芯片设计中&#xff0c;常常会使用APB总线配置每个模块的寄存器。这一部分可以使用脚本生成相应RTL代码和对应的验证所需文件比如RALF&#xff0c;和C语言的头文件&am…

【仿写tomcat】三、通过socket读取http请求信息

仿写tomcat 建立Socket连接获取连接信息查看HTTP信息 建立Socket连接 这里我们也是创建一个专门管理socket的类 package com.tomcatServer.socket;import java.io.*; import java.net.ServerSocket;/*** 套接字存储** author ez4sterben* date 2023/08/15*/ public class Soc…

电影《孤注一掷》观后感

上周看了电影《孤注一掷》&#xff0c;看完后&#xff0c;内心久久无法平静,电影影响还是听深远的的。 &#xff08;1&#xff09;情感与金钱的损失 我们每个人&#xff0c;或多或少&#xff0c;都收到过&#xff0c;诈骗类的短信或者电话&#xff0c;只要你使用的智能手机&am…

【MaxKey对接一】对接gitlab的oauth登录

MaxKey的Oauth过程 引导进入 GET http://{{maxKey_host}}/sign/authz/oauth/v20/authorize?client_idYOUR_CLIENT_ID&response_typecode&redirect_uriYOUR_REGISTERED_REDIRECT_URI 登录后回调地址 YOUR_REGISTERED_REDIRECT_URI/?code{{code}} 换取Access Token GET…

探究主成分分析方法数学原理

目录 1、简介 2、实现原理 3、实现步骤 4、公式分析 5、实例分析 6、⭐协方差矩阵补充说明 7、LaTex文本 ⭐创作不易&#xff0c;您的一键三连&#xff0c;就是支持我写作的最大动力&#xff01;&#x1f979; 关于代码如何实现&#xff0c;请看这篇文章&#xff1a;[机器…

C++ string类相关用法实例

前言&#xff1a; 1 string是表示字符串的字符串类 2 string类是basic_string模板类的一个实例&#xff0c;它使用char来实例化basic_string模板类&#xff0c;并用char_traits和allocator作为basic_string的默认参数&#xff0c;所以string在底层实际是&#xff1a;basic_str…

【漏洞修复】OpenSSH-ssh-agent 越权访问CVE-2023-38408

CVE-2023-38408漏洞升级ssh版本 漏洞说明修复步骤RPM包编译 漏洞说明 漏洞名称&#xff1a;OpenSSH-ssh-agent 存在越权访问漏洞影响范围&#xff1a;ssh-agent(-∞, 9.3-p2) openssh(-∞, 9.3p2-1)漏洞描述&#xff1a;SSH-Agent是SSH的一部分&#xff0c;它是一个用于管理私…

设计模式之享元模式(Flyweight)的C++代码实现

1、享元模式提出 面向对象很好地解决了抽象问题&#xff0c;但是创建对象会带来一定的内存开销。绝大部分情况下&#xff0c;创建对象带来的内存开销是可以忽略不计的&#xff1b;在有些情况下是需要谨慎处理的&#xff0c;如类A的sizeof是50个字节&#xff0c;则创建50*1024*…

AIGC:从入门到精通

一、前言 相信一部分的人在看到本活动的主题是关于AIGC的时候&#xff0c;都会存在疑惑--到底什么是AIGC呢&#xff1f;故本文主要介绍关于AIGC的基本内容&#xff0c;全部内容采用自己搭建的ChatGPT模型生成&#xff0c;具体内容如下&#xff1a; 本文章&#xff0c;参与&…

互联网医院|申办互联网医院这些资质不能少

互联网医院作为一种创新的医疗模式&#xff0c;正在以其便捷、智能、人性化的特点改变着人们的生活方式和医疗体验。它以数字化技术和合作共赢的精神&#xff0c;打开了医疗的新纪元。让我们共同期待&#xff0c;互联网医院将为健康事业带来更多机遇和挑战&#xff0c;引领着健…

Spyglass 脚本

Spyglass小白可以使用Gui界面进行debug Spyglass检查(一)作为IC设计人员&#xff0c;熟练掌握数字前端语法检查工具Spyglass的重要性不言而喻&#xff0c;本文讲解景芯SoChttps://mp.weixin.qq.com/s/fp07o-AvaQvLT79Di0Tb7A 熟悉电路和软件之后可以使用脚本完成整个流程 sp…

【分享】使用FileChannel进行文件拷贝

前言: 项目实际编写中&#xff0c;使用到了多种文件拷贝方式&#xff0c;有包括专门使用c写了拷贝工具&#xff0c;供给Java调用&#xff0c;也有使用标准的输入输出流&#xff0c;这里分享的是借助 FileChannel 来读写,nio中传送数据使用channelbuffer&#xff0c;大的数据可以…

第九章 动态规划part09(代码随想录)

198.打家劫舍 题目&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。…