硬件设计及建模—第.pptx
10.1 接口的概念接口反映的是模块与模块之间的互连,对Verilog来说,主要通过模块的端口表现。第1页/共42页10.1 接口的概念module top(input wire clock,resetn,teset_mode);wire 15:0 data,address,program_addr,jump_addr;wire 7:0 instr,next_instr;wire 3:0 slave_instr;wire slave_req,slave_rdy;wire bus_req,bus_grant;wire mem_read,mem_write;write data_rdy;processor proc1(/main_bus ports .data(data),.address(address),.slave_instr(slave_instr),.slave_req(slave_req),.bus_grant(bus_grant),.mem_read(mem_read),.mem_write(mem_write),.bus_req(bus_req),.slave_rdy(slave_rdy),/other ports .jump_addr(jump_addr),.instr(instr),.clock(clock),.resetn(resetn),.test_mode(test_mode);第2页/共42页10.1 接口的概念 slave slave1(/main_bus ports .data(data),.address(address),.bus_req(bus_req),.slave_ready(slave_ready),.mem_read(mem_read),.mem_write(mem_write),.slave_instr(slave_instr),.slave_req(slave_req),.bus_grant(bus_grant),.data_rdy(data_rdy),/other ports .clock(clock),.resetn(resetn);dual_port_ram ram(/main_bus ports .data(data),.data_rdy(data_rdy),.address(address),.mem_read(mem_read),.mem_write(mem_write),/other ports .program_addr(program_addr),.data_b(next_instr);第3页/共42页10.1 接口的概念 test_generator test_gen(/main_bus ports .data(data),.address(address),.mem_read(mem_read),.mem_write(mem_write),/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第4页/共42页10.1 接口的概念module processor(/main_bus ports inout wire 15:0 data,output reg 15:0 address,output reg 3:0 slave_instr,output reg slave_req,output reg bus_grant,output wire mem_read,output wire mem_write,input wire bus_req,input wire slave_rdy,/other ports output reg 15:0 jump_addr,input wire 7:0 instr,input wire clock,input wire resetn,input wire test_mode);./module functionality codeendmodulemodule slave(/main_bus ports inout wire 15:0 data,inout wire 15:0 address,output reg bus_req,output reg slave_rdy,output wire mem_read,output wire mem_write,input wire 3:0 slave_instr,input wire slave_req,input wire bus_grant,input wire data_rdy,/other ports input wire clock,input wire resetn);./module functionality codeendmodule第5页/共42页10.1 接口的概念module dual_port_ram(/main_bus ports inout wire 15:0 data,output wire data_rdy,input wire 15:0 address,input tri0 mem_read,input tri0 mem_write,/other ports input wire 15:0 program_addr,output reg 7:0 data_b);./module functionality codeendmodulemodule test_generator(/main_bus ports output wire 15:0 data,output reg 15:0 address,output reg mem_read,output reg mem_write,/other ports input wire clock,input wire resetn,input wire test_mode);./module functionality codeendmodule第6页/共42页10.1 接口的概念module instruction_reg(output reg 15:0 program_addr,output reg 7:0 instr,input wire 15:0 jump_addr,input wire 7:0 next_instr,input wire clock,input wire resetn);./module functionality codeendmodule第7页/共42页10.1.1 Verilog模块端口的缺点Verilog模块的端口提供了一种描述设计中模块之间连接关系的方式,这种方式直观明了,但在大型复杂设计中,有很多缺点:在多个模块中必须重复声明端口在不同模块中有声明不匹配的风险设计规范中的一个改动需要修改多个模块在多个模块中通信协议也必须重复 例如有三个模块对一个共享存储器进行读写操作,那么在这三个模块中,读写操作的控制逻辑必须重复描述限制了抽象的自顶向下的设计 用模块端口连接时,设计的具体互连必须在设计周期的早期确定,而不能在一个不需要考虑设计细节的抽象层面上描述。第8页/共42页10.1.2 SystemVerilog接口优势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第9页/共42页10.1.2 SystemVerilog接口优势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);第10页/共42页10.1.2 SystemVerilog接口优势 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);第11页/共42页10.1.2 SystemVerilog接口优势 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第12页/共42页10.1.2 SystemVerilog接口优势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 codeendmodulemodule slave(/main_bus interface port main_bus bus,/interface port/other ports input logic clock,input logic resetn);./module functionality codeendmodulemodule 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 codeendmodulemodule 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 codeendmodule第13页/共42页10.1.3 接口内容接口不仅仅是一组连接线,它也可以封装模块间通信的所有细节。使用接口可以:(1)在一个地方接口中定义通信所需的各个信号和端口;(2)在接口中定义通信协议;(3)在接口中直接建立协议校验和其它验证程序。接口可以包含类型声明、任务、函数、过程块、程序块和断言。接口与模块之间有三个不同点:(1)接口不可以包含设计层次,接口不可以包含模块或原语的实例;(2)接口可以用作模块端口,表示模块间的通信通道,而在端口中使用模块则是非法的(3)接口可以包含“modport”,这使得每个连接到接口上的模块以不同的方式访问接口。第14页/共42页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第15页/共42页10.2 接口声明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 .clock(clock),.resetn(resetn),.test_mode(test_mode);processor proc1(/main_bus ports .bus(bus),/interface connection/other ports .jump_addr(jump_addr),.instr(instr);./remainder of netlist and module definitions are not listed第16页/共42页10.2 接口声明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/remainder of module definitions are not listed接口实例也可以使用简化的端口连接.name和.*第17页/共42页10.2 接口声明接口名称引用:(1)在模块端口中;(2)在接口实例化中。当接口作为模块的端口时,接口就象模块一样,可以在其定义之前使用,因此不需要考虑源代码的编译顺序。接口可以象模块一样单独定义,接口名称可以在设计的任何层次、任何模块中当作端口使用。接口也可以在嵌套的模块中定义,使用接口只能在这个模块的局部范围内使用。第18页/共42页10.3 将接口用作模块端口显式命名的接口端口:在模块端口可以显式的声明为特定接口类型,显式命名的接口端口只可以连接到同一名称的接口上。interface chip_bus;endinterfacemodule cache(chip_bus pins,input clock);endmodule通用接口端口:通用接口端口用关键字interface定义端口类型,而不是使用特定接口类型,模块实例化时,任何接口都可以连接到通用接口端口上。module ram(interface pins,input clock);endmodule第19页/共42页10.4 接口实例化和连接接口实例化的方式与模块相同,如果接口定义有商品,那么信号可以像模块实例化一样通过端口次序连接方式或端口名称连接方式连接到接口实例上。接口类型的端口必须连接,不能悬空!在模块实例中,声明为接口类型的端口必须连接到一个接口实例或连接到上层的其它接口端口上。SystemVerilog的.name和.*连接方式也适用于接口实例。接口的端口也可以定义为一个接口,从而使接口可以连接到另一个接口上。如AMBA总线可以描述为一个总接口、一个主接口和一个从接口,主、从接口可以表示为总接口的一个端口。第20页/共42页10.5 接口内部信号的引用在有接口类型端口的模块中,接口内部信号必须用端口名进行访问:.。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.data=bus.slave_rdy?slave_data:z;enum logic 4:0 RESET=5b00001,START=5b00010,REQ_DATA=5b00100,EXECUTE=5b01000,DONE=5b10000 State,NextState;always_ff(posedge bus.clock,negedge bus.resetn)begin:FSM if(!bus.resetn)State=START;else State=NextState;end第21页/共42页10.5 接口内部信号的引用 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_decodeendmodule不要忘记把接口类型端口的名称取短些!第22页/共42页10.6 接口的modportSystemVerilog定义接口时,可以定义接口信号的不同接入方式,以处理不同模块连接到接口端口的方向问题。modport的定义从模块角度描述了接口表示的端口的接入方式,接口中可以有任意数量的modport定义,每个定义描述了各个模块访问接口中的信号。modport定义中不包含向量位数和类型,这些信息在接口的信号类型声明中定义。事实上modport声明只是使相互连接的模块将信号看成是input、output、inout还是ref。第23页/共42页10.6 接口的modportinterface 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第24页/共42页10.6.1 指定使用哪种modport方式SystemVerilog提供两种方法指定模块接口端口使用modport的方式:(1)在模块实例化时的接口连接中说明;(2)在模块定义的端口声明时说明。module primary(interface pins);/generic interface port.endmodulemodule secondary(chip_bus pins);/specific interface port.endmodulemodule chip(input logic clock,resetn);chip_bus bus(clock,resetn);/instance of an interfaceprimary i1(bus.master);/use the master modport viewsecondary i2(bus.slave);/use the slave modport viewendmodule第25页/共42页10.6.1 指定使用哪种modport方式module primary(chip_bus.master pins);/generic interface port.endmodulemodule secondary(chip_bus.slave pins);/specific interface port.endmodulemodule chip(input logic clock,resetn);chip_bus bus(clock,resetn);/instance of an interfaceprimary i1(bus);/use the master modport viewsecondary i2(bus);/use the slave modport viewendmodulemodport既可在模块实例化时指定,又可以在模块定义中指定,但不能同时选择这两种方式!第26页/共42页10.6.2 使用modport定义不同的连接在复杂设计的接口中,不是每个模块需要访问相同的接口信号,modport为每个模块创建自己的接口。通过modport使得模块只可以直接访问在modport定义中列出的信号,达到接口中的某些信号对某些模块隐藏的目的。接口中可以定义对任何modport都不可见的内部信号,这些信号只能由接口中的协议检查器或其它功能模块使用。如果连接到接口的模块没有指定modport,模块则可以访问接口中定义的所有信号modport不禁止通过完整层次化的路径访问接口中的任何对象,但完整层次路径不可综合!第27页/共42页10.6.2 使用modport定义不同的连接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;modport master(inout data,output address,output slave_instr,output slave_req,output bus_grant,output mem_read,output mem_write,input bus_req,input slave_rdy,input data_rdy,input clock,input resetn,input test_mode);第28页/共42页10.6.2 使用modport定义不同的连接 modport slave(inout data,inout address,output mem_read,output mem_write,output bus_req,output slave_rdy,input slave_instr,input slave_req,input bus_grant,input data_rdy,input resetn);modport mem(inout data,output data_ready,input address,input mem_read,input mem_write);endinterface第29页/共42页10.6.2 使用modport定义不同的连接/*Top-level Netlist*/module top(input logic clock,resetn,test_mode);logic 15:0 program_addr,jump_addr;logic 7:0 instr,next_instr,data_b;main_bus bus(.*);/instance of an interface processor proc1(.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_instr);endmodule第30页/共42页10.7 在接口中使用任务和函数SystemVerilog可以在接口中声明任务和函数,这些任务和函数可以作为接口方法来引用。对大型设计建模时,使用接口方法,模块间的通信细节可以在接口中描述,与模块间通信相关的代码就不需要在每个模块重复编写,因此,接口不仅可以用来封装连接模块的数据,还可以用来封装模块间通信协议。接口中定义的任务或函数,语法与模块中定义任务和函数相同,使用的语句相同。接口方法可以对接口中的任意信号进行操作,并可以通过输入参数从接口外部读入数值,也可将返回值从接口方法写回。第31页/共42页10.7.2 接口方法的导入modport可以导入接口方法,接口方法导入用关键字import,import定义是在接口中指定为modport定义的一部分,在modport中的import声明表示要导入任务或函数。导入声明有以下两种方式:(1)使用任务和函数名称导入(2)使用任务和函数的完整原型导入 modport(import );modport(import task ();或 modport(import function ();modport imass(import task read(input 63:0 data,output 31:0 addr),import function parity_gen(input 63:0 data),input clock,resetn);第32页/共42页10.7.2 接口方法的导入导入接口方法的调用:.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);./do handshaking to fetch a and b values endtask task FloatingPointRead(output real a_real,b_real);./do handshaking to fetch a and b values endtask modport int_io(import IntegerRead,input clock,resetN,output result_int);modport fp_io(import FloatingPointRead,input clock,resetN,output result_real);endinterface第33页/共42页10.7.2 接口方法的导入/Module Definitions module integer_math_unit(interface io);int a_reg,b_reg;always(posedge io.clock)begin io.IntegerRead(a_reg,b_reg);./process math operation endendmodulemodule floating_point_unit(interface io);real a_reg,b_reg;always(posedge io.clock)begin io.FloatingPointRead(a_reg,b_reg);./process math operation endendmodule第34页/共42页10.7.2 接口方法的导入/Top-level Netlist module dual_mu(input logic clock,resetN);math_bus bus_a(clock,resetN);math_bus bus_b(clock,resetN);integer_math_unit i1(bus_a.int_io);/connect to interface using integer types floating_point_unit i2(bus_b.fp_io);/connect to interface using real typesendmodule使用从接口中导入的任务或函数的模块是可综合的,综合将导入的任务或函数作为模块的一个局部副本。但任务或函数必须是自动的!第35页/共42页10.7.4 导出任务和函数SystemVerilog接口和modport提供一种机制:一个模块中定义的任务或函数可以通过接口导出到其它模块。接口modport中的导出声明不要求说明任务或函数参数的完整原型,只需在modport声明中列出任务或函数名。如果导出的任务或函数有默认值形参或调用任务或函数使用参数名称传递而不是位置传递,则导入声明需要给出完整原型。导出任务或函数使用关键字:export导出任务或函数是不可综合的!第36页/共42页10.7.4 导出任务和函数interface chip_bus(input logic clock,resetN);logic request,grant,ready;logic 63:0 address,data;modport master(output request,.export check);modport slave(input request,.import check);Endinterfacemodule CPU(chip_bus.master io);function check(input parity,input 63:0 data);.endfunction .endmodule第37页/共42页10.7.4 导出任务和函数interface chip_bus(input logic clock,resetN);logic request,grant,ready;logic 63:0 address,data;extern function check(input logic parity,input logic 63:0 data);modport master(output request,.);modport slave(input request,.import function check(input logic parity,input logic 63:0 data);endinterfacemodule CPU(chip_bus.master io);function check(input logic parity,input logic 63:0 data);.endfunction .endmodule模块通过将接口中任务或函数声明为extern把任务或函数导出到整个接口!第38页/共42页10.7.4 导出任务和函数导出任务和函数限制:(1)从不同模块或同一模块的两个实例导出相同的函数名到同一个接口是非法的;(2)从不同模块或同一模块的两个实例导出相同的任务名到同一个接口是非法的(用extern fork join除外);fork .task(q,r).task(q,r)join第39页/共42页10.8 接口中的过程块除任务和函数外,接口还可以包含always、always_comb、always_latch、always_ff、initial、final过程块和assign持续赋值语句,接口中过程块的一个用途就是设计验证,如在接口中建立一个协议检查器。接口也可以象模块一样使用参数重定义和generate语句,便于接口实例化时进行重构。接口的使用改变了验证过程,通信通道可以开发为接口,独立于其它模块的开发,并且由于接口可以包含实现通信协议的方法,所以接口的测试与验证可以独立进行。第40页/共42页10.8 接口中的过程块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);endinterfacemodule top(input logic clock,resetN);math_bus bus_a(clock);/use int data math_bus(#.DTYPE(real)bus_b(clock);/use real data integer_math_unit i1(bus_a.int_io);floating_point_unit i2(bus_b.fp_io);endmodule/end of module top第41页/共42页感谢您的观看!第42页/共42页