systemverilog接口
发布时间:2020-12-14 03:20:50 所属栏目:大数据 来源:网络整理
导读:在verilog中每当遇到复杂的模块时,我们都不得不书写一长串端口声明, 稍有不慎就会写错,并且难以检查。但在systemverilog中,接口interface 则是避免了这个问题。 下面的代码是对一个一位加法器的验证,使用了接口。 `timescale?1ns?/?1psinterface?if_por
在verilog中每当遇到复杂的模块时,我们都不得不书写一长串端口声明,
稍有不慎就会写错,并且难以检查。但在systemverilog中,接口interface 则是避免了这个问题。 下面的代码是对一个一位加法器的验证,使用了接口。 `timescale?1ns?/?1ps interface?if_port(?input?bit?clk?);?????//???声明接口 ??logic?a?,?b?,?cin?,?sum?,cout?;??????//???声明所有的连接线 ?? ??clocking?[email?protected](posedge?clk);???????????//????声明在同一个时钟变化下,连接线的方向。?? ????output?a?,?b,?cin?; ??endclocking ?? ??clocking?[email?protected](posedge?clk); ????input?a?,cout; ??endclocking ?? ??modport?simulus(clocking?cp);??????//???声明端口的输入与输出 ??modport?adder(?input?a?,?output?sum?,cout?); ??modport?monitor(clocking?cn); endinterface module?simulus(if_port.simulus?port);???//????使用接口的激励模块 ?? ??[email?protected](port.cp)?begin ????port.cp.a?<=?$radnom()%2?; ????port.cp.b?<=?$random()%2?; ????port.cp.cin?<=?$random()%2?; ??end endmodule:simulus module?adder(if_port.adder?port);???????//?????一位加法器 ??assign?{?port.cout?,?port.sum?}?=?port.a?+?port.b?+?port.cin?; endmodule:adder module?monitor(if_port.monitor?mon);????//???????监测模块,在时钟的下降沿打印结果 ??[email?protected](?mon.cn?)begin ????$display("?%d?%d?%d?%d??%d?",mon.cn.a?,?mon.cn.b?,?mon.cn.cin?,?mon.cn.cout?,?mon.cn.sum?); ??end endmodule module?top; ??timeunit?1ns?; ??timeprecision?1ps?;??????//????模块内部的时钟情况 ??bit?clk?; ?? ??if_port?port(clk);???????????//????实例化所有模块,并且连接接口 ??simulus?sim(port.simulus); ??adder?add(port.adder); ??monitor?mon(port.monitor); ?? ??initial?begin ????clk?<=?0?;??????????????????//???时钟的生成 ????while(1)?#10?clk?=?~clk?; ??end ?? endmodule 相信由这个例子,大家可以看出接口的使用方法。尽管在这个例子中接口的使用比较繁琐, 但在一个较大型的模块中时,使用接口绝对是最佳的方式。 在接口中还有一种叫做虚接口,虚接口是接口的一个句柄,可以同过虚接口来操作接口成员的值。 下面就看看IEEE sv标准中的例子。 interface??SBus;????//?A?Simple?bus?interface???? ????logic??req,?grant;???? ????logic?[7:0]?addr,?data; endinterface class????SBusTransctor;???//?SBus?transactor?class???? ????virtual?SBus?bus;????//?virtual?interface?of?type?Sbus?? ?????? ????function?new(?virtual?SBus?s?);???????????????? ????????bus?=?s;????//?initialize?the?virtual?interface???? ????endfunction ???? ???task?request();??//?request?the?bus???????????????? ???????bus.req?<=?1'b1;???? ???endtask ??? ???task?wait_for_bus();?//?wait?for?the?bus?to?be?granted???????????????? ???????@(posedge?bus.grant);???? ???endtask endclass module??devA(?Sbus?s?)?...? endmodule????//?devices?that?use?SBus module??devB(?Sbus?s?)?...? endmodule module??top;???? ???????SBus?s[1:4]?();??//?instantiate?4?interfaces ????devA?a1(?s[1]?);??//?instantiate?4?devices???? ????devB?b1(?s[2]?);???? ????devA?a2(?s[3]?);???? ????devB?b2(?s[4]?);???? ???? ????initial?begin???????????? ????????SbusTransactor?t[1:4];??//?create?4?bus-transactors?and?bind???????????? ????????t[1]?=?new(?s[1]?);???????????? ????????t[2]?=?new(?s[2]?);???????????? ????????t[3]?=?new(?s[3]?);???????????? ????????t[4]?=?new(?s[4]?);???????????? ????????//?test?t[1:4]???????? endendmodule 可以看出接口与模块还是以实例化的方式相互连接,但在激励上使用了类与虚接口来进行实现。 这样在书写激励时可以动态的修改激励,并且在一定程度上增进了代码的复用程度。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |