SystemVerilog接口(九)

  1. Verilog模块的端口提供了一种描述设计中模块之间连接关系的方式,但是在大型复杂的设计中,Verilog模块的端口有许多缺点。这些缺点包括:
  • 在多个模块中必须重复声明端口
  • 在多个模块中通信协议中也必须重复
  • 在不同模块中有声明不匹配的风险
  • 设计规范中的一个改动需要修改多个模块
  1. SystemVerilog相比Verilog增加了一种新的功能强大的端口类型:接口。
// 定义接口
interface main_bus;
	wire	[15:0]	data;
	wire	[15:0]	address;
	logic	[7:0]	slave_instruction;
	...
endinterface

// 模块中例化接口,然后把接口实例传递到模块内例化的其他模块端口
module tpo(input logic clock,resetN,test_mode);
	logic	[15:0]	program_address,jump_address;
	logic	[7:0]	instruction,next_instruction;
	
	main_bus bus();
	
	processor procl(
		.bus(bus),
		.jump_address(jump_address),
		.instruction(instruction)
	);
endmodule

// 子模块
module processo(
	main_bus bus,	// 接口类型的端口
	output	logic	[15:0]	jump_address,
	input	logic	[7:0]	instruction
);

endmodule
  1. 模块端口可以声明为两种类型,显示命名的接口端口和通用接口端口。显示命名的接口端口只可以连接到同一名称的接口上,其他不同定义的接口连接到这个端口就会报错。如果端口声明是通用接口类型,那么这个端口可以连接到任何类型的接口实例上。接口的端口也可以定义为一个接口,这使得接口可以连接到另一个接口上。
interface chip_bus;
	...
endinterface

// 显示命名的接口端口
module CACHE(
	chip_bus pins,	// 接口端口
	input clock
);
	...
endmodule

// 通用接口端口
module RAM(
	interface pins,
	input clock
);
	...
endmodule
  1. SystemVerilog接口定义时,可以定义接口信号的不同接入方式,在接口内部使用关键字modport来定义。如果连接到接口的模块没有指定modport,那么模块可以访问接口中定义的所有信号
interface chip_bus(input logic clock, resetN);
	logic	interrupt_request,grant,ready;
	logic	[31:0]	address;
	wire	[63:0]	data;

	modport master(
		input	interrupt_request,
		input	address,
		output	grant,ready,
		inout	data,
		input	clock,resetN
	);
	
	modport slave(
		output	interrupt_request,
		output	address,
		input	grant,ready,
		inout	data,
		input	clock,resetN
	);
endinterface
  1. SystemVerilog提供两种方式,指定模块接口端口使用哪种modport方式。modport既可以在模块实例中指定,又可以在模块定义中指定,但不能同时选择这两种方式。如果没有在接口连接中指定modport,那么接口中所有的线网信号将默认为是双向inout信号,而所有的变量将默认为ref类型
// 在模块实例中选择modport
chip_bus	bus();		// 例化接口
primary i1(.bus(bus.master));	// 使用master modport

module primary(
	chip_bus	bus
);
	...
endmodule
// 在模块端口声明中选择modport
chip_bus	bus();		// 例化接口
primary i1(.bus(bus));		// 会使用master modport

module primary(chip_bus.master	bus);
	...
endmodule
module top(input logic clock,resetN,test_mode);
	logic	[15:0]	program_address,jump_address;
	logic	[7:0]	instruction,next_instruction,data_b;
	
	main_bus		bus(.*);
	processor		procl(.bus(bus.master),.*);
	slave			slave1(.bus(bus.slave),.*);
	instruction_reg	ir(.*);
	test_generator	test_gen(.bus(bus),.*);
	dual_port_ram	ram(.bus(bus.mem),.*,.data_b(next_instruction));
endmodule
  1. SystemVerilog可以在接口中声明任务和函数,这些任务和函数可以作为接口方法来引用。接口的方法可以对接口中的任意信号进行操作,并可以通过输入参数从接口外部读入值,还可以通过输出参数或函数返回值将数值从接口方法写出。对于大型设计的建模,使用接口的方法有许多优势。使用接口方法,模块之间通信的细节可以转移到接口内描述。从而,与模块间通信的细节可以转移到接口内描述。如果模块通过modport连接到接口上,那么接口方法必须用关键字import指定。导入(import)定义是在接口中指定为modport定义的一部分。
// 使用函数和任务的名称导入
modport in(
	import	Read,		// Read是函数名或任务名
	import	parity_gen,	// parity_gen是函数名或任务名
	input	clock,resetN
);

// 使用函数和任务的完整原型导入
modport in(
	// 定义了任务的原型
	import	task	Read(
		input	[63:0]	data,
		output	[31:0]	address
	),
	// 定义了函数的原型
	import	function	parity(
		input	[63:0]	data
	),
	input	clock,resetN
);
interface math_bus(input logic clock,resetN);
	int 	a_int,b_int,result_int;
	real	a_real,b_real,result_real;

	task IntegerRead(output int a_int,b_int);
		// 进行握手来提取a和b的值
	endtask

	task FloatingPointRead(output real a_real,b_real);
		// 进行握手来提取a和b的值
	endtask

	modport int_io(
		import	IntegerRead,
		input	clock,resetN,
		output	result_int
	);
	
	modport fp_io(
		import	FloatingPointRead,
		input	clock,resetN,
		output	result_real
	);
endinterface

module dual_mu(input logic clock,resetN);
	math_bus bus_a;
	math_bus bus_b;

	integer_math_unit i1(.io(bus_a.int_io));

	floatint_point_unit i2(.io(bus_b.fp_io));
endmodule

module integer_math_unit(interface io);
	int	a_reg,b_reg;
	
	always@(posedge io.clk)
	begin
		io.IntegerRead(a_reg,b_reg);
		...
	end
endmodule

module floatint_point_unit(interface io);
	int	a_reg,b_reg;
	
	always@(posedge io.clk)
	begin
		io.FloatingPointRead(a_reg,b_reg);
		...
	end
endmodule
  1. 接口可以使用参数进行向量位数和其他声明,使用Verilog的参数重定义结构对其重构,也可以使用SystemVerilog的数据类型参数化。
interface math_bus #(
	parameter type DTYPE=int
) (
	input	logic	clock
);

	DTYPE a,b,result;

	task Read(output DTYPE a,b);
		...
	endtask
	
	modport int_io(
		import	Read,
		input	clock,
		output	result
	);
	
	modport fp_io(
		import	Read,
		input	clock,
		output	result
	);
endinterface

module top(input logic clock,resetN);
	math_bus				bus_a(clock);
	math_bus#(.DTYPE(real)) bus_b(clock);

	integer_math_unit i1(.io(bus_a.int_io));
	floating_point_unit i2(.io(bus_b.fp_io));
endmodule
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值