接口不仅仅是一组连接线,它也可以封装模块间通信的所有细节。使用接口可以:(1)在一个地方—接口中定义通信所需的各个信号和端口;(2)在接口中定义通信协议;(3)在接口中直接建立协议校验和其它验证程序。 接口可以包含类型声明、任务、函数、过程块、程序块和断言。 接口与模块之间有三个不同点:(1)接口不可以包含设计层次,接口不可以包含模块或原语的实例;(2) 接口可以用作模块端口,表示模块间的通信通道,而在端口中使用模块则是非法的(3)接口可以包含“modport”,这使得每个连接到接口上的模块以不同的方式访问接口。 SystemVerilog增加了新的端口类型—接口,接口允许许多信号合成一组由一个端口表示,只需在一个地方对组成接口的信号进行声明,使用这些信号的模块只需一个接口类型的端口。 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 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)); //---------------------------------------------------------------------------------------------- test_generator test_gen( // main_bus ports .bus(bus), // interface connection // other ports .clock(clock), .resetn(resetn), .test_mode(test_mode)); instruction_reg ir ( .program_addr (program_addr), .instr(instr), .jump_addr(jump_addr), .next_instr(next_instr), .clock(clock), .resetn(resetn)); endmodule //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ module processor ( // main_bus interface port main_bus bus,// interface port // other ports output logic [15:0] jump_addr, input logic [ 7:0] instr, input logic clock, input logic resetn, input logic test_mode); ... // module functionality code endmodule module slave ( // main_bus interface port main_bus bus,// interface port // other ports input logic clock, input logic resetn); ... // module functionality code endmodule //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ module dual_port_ram ( // main_bus interface port main_bus bus,// interface port // other ports input logic [15:0] program_addr, output logic [ 7:0] data_b); ... // module functionality code endmodule module test_generator ( // main_bus interface port main_bus bus,// interface port // other ports input logic clock, input logic resetn, input logic test_mode); ... // module functionality code endmodule 10.2 接口声明 接口定义语法与模块相似,接口也可以拥有端口,这些端口将成为接口所描述一组信号的一部分,接口可以包含Verilog和SystemVerilog中任何类型的声明。 interface main_bus (input logic clock,resetn, test_mode); 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 接口实例也可以使用简化的端口连接.name和.* module top (input logic clock, resetn,test_mode); logic [15:0] program_addr, jump_addr; logic [ 7:0] instr, next_instr; main_bus bus (.*); processor proc1 (.*); slave slave1(.*); instruction_reg ir(.*); test_generator test_gen(.*); dual_port_ram ram(.*, .data_b(next_instr)); endmodule 10.6 接口的modport SystemVerilog定义接口时,可以定义接口信号的不同接入方式,以处理不同模块连接到接口端口的方向问题。 modport的定义从模块角度描述了接口表示的端口的接入方式,接口中可以有任意数量的modport定义,每个定义描述了各个模块访问接口中的信号。 modport定义中不包含向量位数和类型,这些信息在接口的信号类型声明中定义。事实上modport声明只是使相互连接的模块将信号看成是input、output、inout还是ref。 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 6.3 对任务和函数的改进 形式参数的缺省方向和类型:Verilog中函数的每个形式参数必须显式声明为input,而任务的每个形式参数必须显式声明为input、output或inout,方向声明后面可以跟着逗号分隔的参数列表;SystemVerilog简化了任务和函数声明语法,形式参数的缺省方向为input,缺省类型为logic。 缺省的形式参数值:SystemVerilog允许任务与函数为每个形式参数设置一个可选的缺省值,设定缺省值的语法与设置变量初始值的语法类似,设定缺省值的任务或函数调用时,可以对形式参数全部指定、部分指定或不指定值,如果不指定值,则使用缺省的值。 如果对没有缺省形式参数值的任务或函数调用时不传递值给形式参数,系统会报告一个错误。 SystemVerilog允许任务或函数的实际参数数目小于形式参数数目! 用引用取代复制来传递参数值:任务或函数调用时,通常是将输入复制后传递给任务或函数;Verilog通过使用外部名称方式隐含传递参数给任务或函数; SystemVerilog可以显式地通过引用的方法传递参数给任务或函数,在形式参数说明中, 用ref代替input、output和inout方向关键词。 注意:只有自动函数或任务才可以具有ref参数! 只读引用参数:通过将形式参数说明为const ref类型,只允许对引用对象进行读操作,而禁止任务或函数改动对象内容。 function automatic void fill_packet( const ref logic [7 : 0] data_in [7 : 0], refpacket_t data_out); … endfunction 对使用ref参数的函数调用限制:与带有输出形参函数调用限制相同,不能被以下几种情况调用: 事件表达式 使用过程持续赋值的表达式 不在过程语句内的表达式 任务ref参数对变化敏感:任务ref参数的一个重要特点是任务中的逻辑会对信号在调用程序内发生的变化敏感,由于函数必须零延时执行,所有函数ref参数不能包含对变化敏感的时间控制。 1. ref参数可以读取当前值 2. ref参数可以立即传播变化而不是等到任务结束时才反映 |
|