IEEE Standard for SystemVerilog—Chapter25.5 Modports

news/2024/5/19 19:13:51 标签: systemverilog

 25.5 Modports

        为了限制模块内的接口访问,有一些modport列表,其中包含在接口内声明的方向。关键字modport表示方向是在模块内部声明的。

interface i2;
    wire a, b, c, d;
    modport master (input a, b, output c, d);
    modport slave (output a, b, input c, d);
endinterface

        在本例中,可以在模块头部中指定modport列表名称(master or slave),其中接口名称选择接口,modport名称为模块头部中访问的接口信号选择适当的方向信息。

module m (i2.master i);
    ...
endmodule

module s (i2.slave i);
    ...
endmodule

module top;
    i2 i();
    m u1(.i(i));
    s u2(.i(i));
endmodule

        interface_name.modport_name reference_name的语法为层次引用提供了一个本地名称。通过编写interface.modport_name reference_name,可以将此技术推广到具有给定modport名称的任何接口。modport列表名称(master or slave)也可以在与模块实例的端口连接中指定,其中modport名称是从接口实例分层的。

module m (i2 i);
    ...
endmodule

module s (i2 i);
    ...
endmodule

module top;
    i2 i();
    m u1(.i(i.master));
    s u2(.i(i.slave));
endmodule

        如果端口连接在模块实例和模块头部声明中都指定了modport列表名称,则这两个modport列表名应相同。modport声明中使用的所有名称应由与modport本身相同的接口声明。特别是,使用的名称不应是由另一个封闭接口声明的名称,modport声明也不应隐式声明新端口。
以下接口声明是非法的:

interface i;
    wire x, y;

        interface illegal_i;
            wire a, b, c, d;
            // x, y not declared by this interface
        modport master(input a, b, x, output c, d, y);

        modport slave(output a, b, x, input c, d, y);
    endinterface : illegal_i
endinterface : i

interface illegal_i;
    // a, b, c, d not declared by this interface
    modport master(input a, b, output c, d);
    modport slave(output a, b, input c, d);
endinterface : illegal_i

        向接口添加modports不需要在使用接口时使用任何modports如果在模块头部或端口连接中没有指定modport,那么接口中的所有网络和变量都可以通过方向inout或ref访问,如前面的示例所示。

25.5.1 Example of named port bundle

        这个接口示例展示了如何使用modports来控制端口声明中的信号方向。它在模块定义中使用modport名称。



interface simple_bus (input logic clk); // Define the interface
	logic req, gnt;
	logic [7:0] addr, data;
	logic [1:0] mode;
	logic start, rdy;
	
modport slave (input req, addr, mode, start, clk,
	output gnt, rdy,
	ref data);
	
	
modport master(input gnt, rdy, clk,
	output req, addr, mode, start,
	ref data);
endinterface: simple_bus


module memMod (simple_bus.slave a); // interface name and modport name
	logic avail;
always @(posedge a.clk) // the clk signal from the interface
	a.gnt <= a.req & avail; // the gnt and req signal in the interface
endmodule

module cpuMod (simple_bus.master b);
	
	always @(posedge b.clk)
		b.start<=1;
	
	
endmodule


module top;
	logic clk = 0;
	simple_bus sb_intf(clk); // Instantiate the interface
	initial repeat(10) #10 clk++;
		memMod mem(.a(sb_intf)); // Connect the interface to the module instance
		cpuMod cpu(.b(sb_intf));
endmodule

25.5.2 Example of connecting port bundle

        这个接口示例展示了如何使用modports来限制接口信号访问并控制其方向。它在模块实例化中使用modport名称。

interface simple_bus (input logic clk); // Define the interface
	logic req, gnt;
	logic [7:0] addr, data;
	logic [1:0] mode;
	logic start, rdy;
	
modport slave (input req, addr, mode, start, clk,
	output gnt, rdy,
	ref data);
	
modport master(input gnt, rdy, clk,
	output req, addr, mode, start,
	ref data);
endinterface: simple_bus

module memMod(simple_bus a); // Uses just the interface name
	logic avail;
always @(posedge a.clk) // the clk signal from the interface
	a.gnt <= a.req & avail; // the gnt and req signal in the interface
endmodule


module cpuMod(simple_bus b);
	...
endmodule

module top;
	logic clk = 0;
	simple_bus sb_intf(clk); // Instantiate the interface
	initial repeat(10) #10 clk++;
		memMod mem(sb_intf.slave); // Connect the modport to the module instance
		cpuMod cpu(sb_intf.master);
endmodule

25.5.3 Example of connecting port bundle to generic interface

        这个接口示例展示了如何使用modports来控制信号方向。它显示了interface关键字在模块定义中的使用。实际接口和modport在模块实例化中指定。

interface simple_bus (input logic clk); // Define the interface
	logic req, gnt;
	logic [7:0] addr, data;
	logic [1:0] mode;
	logic start, rdy;
	
modport slave (input req, addr, mode, start, clk,
	output gnt, rdy,
	ref data);
	
modport master(input gnt, rdy, clk,
	output req, addr, mode, start,
	ref data);
endinterface: simple_bus

module memMod(interface a); // Uses just the interface
	logic avail;
	always @(posedge a.clk) // the clk signal from the interface
		a.gnt <= a.req & avail; // the gnt and req signal in the interface
endmodule

module cpuMod(interface b);
	...
endmodule

module top;
	logic clk = 0;
	simple_bus sb_intf(clk); // Instantiate the interface
	memMod mem(sb_intf.slave); // Connect the modport to the module instance
	cpuMod cpu(sb_intf.master);
endmodule

25.5.4 Modport expressions

        modport表达式允许数组和结构的元素、元素的级联以及接口中声明的元素的赋值形式表达式包含在modport列表中。此modport表达式使用端口标识符显式命名,仅通过modport连接可见。
        与模块端口声明中显式命名的端口一样,端口标识符存在于每个modport列表各自的名称空间中。当modport项只是一个简单的端口标识符时,该标识符既用作接口项的引用,也用作端口标识符。一旦定义了一个端口标识符,就不会有其他具有相同名称的端口定义
        例如:

interface I;
	logic [7:0] r;
	const int x=1;
	bit R;
	
modport A (output .P(r[3:0]), input .Q(x), R);
modport B (output .P(r[7:4]), input .Q(2), R);
endinterface

module M ( interface i);
	initial i.P = i.Q;
endmodule

module top;
	I i1 ();
	M u1 (i1.A);
	M u2 (i1.B);
	initial #1 $display("%b", i1.r); // displays 00100001
endmodule

        端口表达式的自行确定的类型将变为端口的类型。端口表达式不应被视为类似赋值的上下文。端口表达式应解析为模块端口类型的合法表达式(见23.3.3)。在前面的示例中,Q端口不能是output或inout,因为端口表达式是常量。端口表达式是可选的,因为可以定义不连接到端口内部任何内容的端口。

25.5.5 Clocking blocks and modports

        modport构造还可以用于指定接口内声明的clocking块的方向。与其他modport声明一样,clocking块的方向是从接口成为端口的模块中看到的方向。其语法如语法25-2所示。

modport_declaration ::= modport modport_item { , modport_item } ; // from A.2.9
modport_item ::= modport_identifier ( modport_ports_declaration { , modport_ports_declaration } )
modport_ports_declaration ::=
    { attribute_instance } modport_simple_ports_declaration
    | { attribute_instance } modport_tf_ports_declaration
    | { attribute_instance } modport_clocking_declaration
modport_clocking_declaration ::= clocking clocking_identifier

                Syntax 25-2—Modport clocking declaration syntax (excerpt from Annex A)

        modport声明中使用的所有clocking块应由与modport本身相同的接口声明。与所有modport声明一样,时钟信号的方向是从接口成为端口的模块中看到的方向。以下示例显示如何使用modports来创建同步端口和异步端口。当与虚拟接口结合使用时(见25.9.2),这些构造有助于创建抽象同步模型。


interface A_Bus( input logic clk );
	wire req, gnt;
	wire [7:0] addr, data;
	clocking sb @(posedge clk);
		input gnt;
		output req, addr;
		inout data;
		property p1; req ##[1:3] gnt; endproperty
	endclocking

	modport DUT ( input clk, req, addr, // Device under test modport
		output gnt,
		inout data );

	modport STB ( clocking sb ); // synchronous testbench modport
	
	
	modport TB ( input gnt, // asynchronous testbench modport
		output req, addr,
		inout data );
	
endinterface

然后可以如下实例化前面的接口A_Bus:

module dev1(A_Bus.DUT b); // Some device: Part of the design
	...
endmodule

module dev2(A_Bus.DUT b); // Some device: Part of the design
	...
endmodule

module top;
	logic clk;
	A_Bus b1( clk );
	A_Bus b2( clk );
	dev1 d1( b1 );
	dev2 d2( b2 );
	T tb( b1, b2 );
endmodule

program T (A_Bus.STB b1, A_Bus.STB b2 ); // testbench: 2 synchronous ports
	assert property (b1.sb.p1); // assert property from within program
	initial begin
		b1.sb.req <= 1;
		wait( b1.sb.gnt == 1 );
			...
		b1.sb.req <= 0;
		b2.sb.req <= 1;
		
		wait( b2.sb.gnt == 1 );
			...
		b2.sb.req <= 0;
	end
endprogram

        该示例显示了使用由接口端口b1和b2的时钟modport指定的同步接口的程序块。除了程序驱动和时钟块信号的采样之外,程序断言其接口b1之一的属性p1。

25.6 Interfaces and specify blocks

         specify块用于描述模块上的各种路径,并执行时序检查以验证在模块输入处发生的事件满足由模块描述的设备的时序约束。模块路径是从模块输入端口到输出端口,时序检查是相对于模块输入的。 specify块将这些端口称为terminal描述符。模块输入输出端口可以用作输入或输出端口。当其中一个端口实例是接口时,接口中的每个信号都成为可用的终端,默认方向为接口定义或受modport限制。ref端口不能用作指定块中的终端
        以下显示了将接口与指定块一起使用的示例:

interface itf;
	logic c,q,d;
	modport flop (input c,d, output q);
endinterface

module dtype (itf.flop ch);
	always_ff @(posedge ch.c) ch.q <= ch.d;
	specify
		( posedge ch.c => (ch.q+:ch.d)) = (5,6);
		$setup( ch.d, posedge ch.c, 1 );
	endspecify
endmodule


http://www.niftyadmin.cn/n/5133862.html

相关文章

设计模式--7个原则

单一职责原则&#xff1a;一个类负责一项职责。 里氏替换原则&#xff1a;继承与派生的规则。 依赖倒置原则&#xff1a;高层模块不应该依赖基层模块&#xff0c;二者都应该依赖其抽象&#xff1b;抽象不应该依赖细节&#xff1b;细节应该依赖抽象。即针对接口编程&#xff0…

微信小程序 php java nodejs python课堂学生考勤签到系统zng1p

课堂考勤也是学校的核心&#xff0c;是必不可少的一个部分。在学校的整个教学行业中&#xff0c;学生担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类基于微信小程序也在不断改进。本课题所设计的基于微信小程序的课堂考勤系统&#xff0c;使用微信开发者与…

【Kubernetes】Operator开发之kubebuilder实战(二)

1 解决&#xff08;一&#xff09;中的资源删除问题 在Operator开发之kubebuilder实战&#xff08;一&#xff09;的最后提到了Demo和Pod删除的问题&#xff1a; 由于DemoController只监听了Demo资源的变化&#xff0c;因此&#xff0c;删除Pod时&#xff0c;DemoController不…

ESM蛋白质语言模型系列

模型总览 第一篇《Biological structure and function emerge from scaling unsupervised learning to 250 million protein sequences 》ESM-1b 第二篇《MSA Transformer》在ESM-1b的基础上作出改进&#xff0c;将模型的输入从单一蛋白质序列改为MSA矩阵&#xff0c;并在Tran…

2023mathorcup大数据数学建模竞赛A题坑洼道路识别67页完整高质量原创论文

大家好&#xff0c;从昨天肝到现在&#xff0c;终于完成了本次mathorcup大数据数学建模竞赛A题基于计算机视觉的坑洼道路检测和识别的完整论文了。 给大家看一下目录吧&#xff1a; 摘 要&#xff1a; 10 一、问题重述 12 二&#xff0e;问题分析 13 2.1问题一 13 2.2问题…

<C++> vector模拟实现

目录 前言 一、定义命名空间 二、构造函数 三、拷贝构造 四、赋值运算符重载 五、push_back && reserve 六、深拷贝问题 七、iterator 迭代器 1. 可读可写 2. 只读 八、operator[ ] 1. 可读可写 2. 只读 九、insert 问题&#xff1a;内部迭代器失效 十、erase 十一、re…

chapter 3-6

文章目录 3.检测两个整数是否有相反的符号4.计算整数的绝对值&#xff08;abs&#xff09;而不使用分支5.计算两个整数的最小值或最大值而不使用分支6.确定一个整数是否是2的幂 3.检测两个整数是否有相反的符号 //检测两个整数是否有相反的符号 int x, y; // 要…

C#:枚举是命名的整形常量的集合

在枚举&#xff08;enum&#xff09;中&#xff0c;整形常量指的是一组预定义的整数值&#xff0c;它们代表了枚举类型中的不同取值。这些整数值通常用于表示特定的状态、选项或标识符。 枚举类型是一种自定义的数据类型&#xff0c;它可以用于定义一组相关的命名常量。每个枚…