下载

2下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 夏宇文老师vlogRef4

夏宇文老师vlogRef4.doc

夏宇文老师vlogRef4

lsy512
2018-09-10 0人阅读 举报 0 0 暂无简介

简介:本文档为《夏宇文老师vlogRef4doc》,可适用于工程科技领域

Strength强度除了逻辑值外Net类型的变量还可以定义强度因而可以更精确地建模。Net的强度来自于动态Net驱动器的强度。在开关级仿真时当Net由多个驱动器驱动且其值互相矛盾时常用强度(Strength)的概念来描述这种逻辑行为。语法:{either}(Strength,Strength)(Strength,Strength)(Strength){pulldownprimitivesonly}(Strength){pullupprimitivesonly}(ChargeStrength){triregnetsonly}Strength={either}supplystrongpullweakhighzStrength={either}supplystrongpullweakhighzChargeStrength={either}largemediumsmall在程序中位于何处:请参照:Net、Instantiation、ContinuousAssignment的说明。规则:·关键词Strength和Strength用于定义Net的驱动器强度。其中Strength表示强度与紧跟着的和连起来分别表示输出逻辑值为和时的强度。·在强度声明中可选择不同的强度关键字来代替strength但(highz,highz)和(highz,highz)这两种强度定义是不允许的在pullup(上拉)和pulldown(下拉)门的强度声明中highz和highz是不允许的。·默认的强度定义为(strong,strong)但下述情况除外:)对于pullupandpulldown门默认强度分别为(pull)和(pull)。)对于trireg的Net默认强度为medium)强度定义为supply和supply的Net总是能提供强度。·在仿真期间Net的强度来自于Net上的主驱动强度(即具有最大强度值的实例或连续赋值语句)。如果Net未被驱动它会呈现高阻值但以下情况除外:)tri和tri类型的net分别具有逻辑值和并为pull强度。)trireg类型的net保持它们最后的驱动值。)强度为supply和supply的nets分别具有逻辑值和并能提供驱动能力。·强度值有强弱顺序可从supply(最强的)依次减弱排列到highz(最弱的)当需要确定Net的确实逻辑值和强度时或者当Net由多个驱动器驱动而且驱动相互间出现冲突时出现冲突的两个强度值在强弱顺序表中的相对位置就会对该Net的真实逻辑值起作用。SupplyStrongPullLargeWeakMediumSmallHighz可综合性问题:不可综合提示:可以在$display和$monitor等中用特定的格式控制符V显示其强度值。举例说明:assign(weak,weak)f=abtrireg(large)c,cand(strong,weak)u(x,y,z)请参阅:ContinousAssignment、Instantiation、Net、$display的说明String字符串字符串能够用在系统任务(诸如$display和$monitor等)中作为变量字符串的值可以像数字一样储存在寄存器中也可以像对数字一样对字符串进行赋值、比较和拼接。语法见“string”说明。在程序中位于何处:请参见Expression说明。规则·一条字符串不能占原代码的多行。·字符串可以包含下列扩展字符。·n·换行·t·Tab符··反斜杠字符·”·双引号字符”·nnn·八进制的ASCII字符··百分号·诸如$display和$monitor等的系统任务中的打印字符串可以包含特殊的格式控制符(如b)(参见$display的说明)。·当字符串存储于寄存器中每个字符要占位字符以ASCII代码形式存储。VerilogHDL语言的字符串的定义和C语言的不一样。在C语言中需要用而在VerilogHDL语言中不需要用ASCII代码的字符来表示字符串的结束。注意!在表达式中使用字符串时请注意填加物。对字符串的处理跟对数字的处理方式一样当字符所占的位数少于寄存器的数目时则在字符串的左边的寄存器中填加。举例说明:reg:MonthName:initialbeginMonthName="Jan"MonthName="Feb"MonthName="Mar"MonthName="Apr"MonthName="May"MonthName="Jun"MonthName="Jul"MonthName="Aug"MonthName="Sep"MonthName="Oct"MonthName="Nov"MonthName="Dec"end请参阅:NUMBER,$display的说明。Task任务任务常用于把模块代码分割成由若干声明语句构成的较大的块便于模块代码的理解和维护也可以从模块代码的不同位置执行这样一个常见的顺序声明语句块。语法:taskTaskNameDeclarationsStatementendtaskDeclaration={either}inputRangeName,outputRangeName,inoutRangeName,RegisterParameterEventRange=ConstantExpression:ConstantExpression规则:·若用于任务中的命名变量或参数没有在任务块中声明则指的是在模块中声明的命名变量或参数。·任务中的input、output和inout的个数不受限制(也可以为零个)。·任务中的变量(包括输入和双向端口(inout))可以声明为寄存器型。如果没有明确地声明则默认为寄存器型且其位宽与相应的变量匹配。·当启动任务时相应于任务的输入和双向端口(inout)的变量表达式的值被存入相应的变量寄存器中。当任务结束时输入和双向端口(inout)的变量寄存器中的值又被代入启动任务的语句中相应的表达式。注意!·和模块的端口定义不一样任务的变量不能在任务名后的括号中定义。·任务中若包括一句以上的语句必须要用begin–end或forkjoin将其包含成块。·任务的输入、双向端口(inout)、输出和局部寄存器的值都是静态储存的也就是说即使多次启动任务也只有一份这些寄存器的拷贝。若第一次启动的任务还未完成便第二次启动该任务其输入、双向端口(inout)、输出和局部寄存器的值便会被覆盖。·当被启动的任务运行结束时输出和双向端口(inout)的值被代入任务中相应的寄存器表达式。如果任务中的输出和双向端口(inout)在赋值后有时间的控制则相应的寄存器只能在定时控制延迟后才被更新。·同样对输出和双向端口(inout)寄存器变量的非阻塞赋值语句也不会起作用因为当任务返回时赋值语句可能还未生效。可综合性问题:包含定时控制语句的任务是不可综合的。启动的任务往往被综合成组合逻辑。提示:·复杂RTL模块通常需要用多个always块来构造。建议最好不要采用一个always块运行多个任务的方案。·在测试块中可用任务来产生重复的激励序列。例如对存储器的数据读写(见例)序列。·某任务如果被多个模块引用可以把它定义为一个独立的模块(只包括该任务)并可用层次命名来引用它。举例说明:这个例子表示一个简单的可以综合的RTL任务taskCounterinout:CountinputResetif(Reset)同步复位Count=对RTL必须用非阻塞方式赋值elseCount=CountEndtask下面这个例子说明如何在测试模块中运用任务。moduleTestRAMparameterAddrWidth=parameterDataWidth=parameterMaxAddr=<<AddrBitsregDataWidth:AddrregAddrWidth:DatawireDataWidth:DataBus=DataregCe,Read,WriteRamxUut(Ce(Ce),Rd(Read),Wr(Write),Data(DataBus),Addr(Addr))initialbegin:stimulusintegerNErrorsintegeri错误开始记数NErrors=为每个地址写上地址值for(i=i<=MaxAddri=i)WriteRam(i,i)读且比较for(i=i<=MaxAddri=i)beginReadRam(i,Data)if(Data!==i)RamError(i,i,Data)end小结错误个数$display(Completedwithderrors,NErrors)endtaskWriteRaminputAddrWidth:AddressinputDataWidth:RamDatabeginCe=Addr=AddressData=RamData#Write=#Write=Ce=endendtasktaskReadRaminputAddrWidth:AddressoutputDataWidth:RamDatabeginCe=Addr=AddressData=RamDataRead=#RamData=DataBusRead=Ce=endendtasktaskRamErrorinputAddrWidth:AddressinputDataWidth:ExpectedinputDataWidth:Actualif(Expected!==Actual)begin$display("Errorreadingaddressh",Address)$display("Actualb,Expectedb",Actual,Expected)NErrors=NErrorsendendtaskendmodule请参阅:TaskEnableFunction的说明。TaskEnable任务的启动在模块代码中只需用任务名便可启动任务。当任务启动时输入值通过任务的端口变量(输入和inout变量)传递到任务中。当任务结束时返回值通过任务的端口寄存器变量(输出和inout变量)传出。语法TaskName(Expression,)规则·任务可以从initial或always块或其它任务中启动。任务可以多次调用。但任务不能被函数调用。·调用任务的语句中端口表达式的顺序和任务端口变量声明的顺序必须一致。端口的个数必须与任务声明的端口变量的个数一致。·若任务的端口变量是输入时则对应的端口变量可以是任何一种表达式若端口变量为输出和inout时对应的端口变量必须位于进程赋值语句的左边而且必须是有效的。·当任务启动时输入和inout表达式复制到相应的变量寄存器中。当任务结束时输出和inout寄存器的值会复制到启动任务相应的端口寄存器中。·可以在任务内部或任务外部把任务禁止(disable)。注意!任务中变量寄存器默认为静态的所以当一个任务正在执行时又启动该任务时输入和inout寄存器的值会被覆盖。可综合性问题:若任务不包含定时控制是有可能被综合的。调用的任务往往被综合成组合逻辑。举例说明:taskCounterinout:CountinputResetendtaskalways(posedgeClock)Counter(Count,Reset)请参阅:Disable、Task、FunctionCall的说明。Timingcontrol定时控制用于延迟语句的执行或按排语句的执行顺序。定时控制可以放在语句的前面或者在程序的进程赋值语句表达式中的赋值操作符(即=或<=)之间。前一种延迟语句的执行后一种延迟声明的语句生效。语法:{Timingcontrolsbeforestatements}{either}DelayControlEventControlWaitControl{IntraassignmentTimingcontrols}{either}DelayControlEventControlrepeat(Expression)EventControlDelayControl={either}#UnsignedNumber#ParameterName#ConstantMinTypMaxExpression#(MinTypMaxExpression)EventControl={either}Name{ofRegister,NetorEvent}(EventExpression)EventExpression={either}ExpressionName{ofRegister,NetorEvent}posedgeExpression{,X,Z,XorZ}negedgeExpression{,X,Z,ZorX}EventExpressionorEventExpressionWaitControl=wait(Expression)在程序中位于何处:请参阅:statement、proceduralassignment(forintraassignmenttimingcontrol)的说明。规则:·在某声明语句前面插入的事件或延迟控制使原本立刻要执行的该条语句延迟执行。·当执行到wait时如果其表达式为假(或X)wait控制只延迟wait语句后的下一条语句当表达式为真(非)时下一条语句才执行。当执行到wait时如果表达式为真下一句不延迟马上执行。·执行进程赋值语句时要检查赋值语句右边的表达式如果没有内部赋值延迟若用的是阻塞赋值则左边的寄存器类型变量立即更新若用的是非阻塞赋值则在下一个仿真周期更新。如果有内部赋值延迟左边的寄存器类型变量只有在发生内部赋值延迟后才更新。·内部赋值延迟必须是常数的但语句前的延迟可以是常数或变量(即Net或reg型变量)。·or列表中的任何一个信号(事件)变化(发生)时即触发事件控制。·对于posedge(上升沿)和negedge(下降沿)事件触发控制只测试表达式的最低位。要不然的话表达式的任何变化都会触发事件。注意!对于阻塞赋值语句而言指定内部赋值延迟为零(#)与不指定是不一样的也与没有赋值延迟的非阻塞赋值语句不同。对于阻塞赋值语句而言指定#意味着该语句在所有待定事件完成以后而在非阻塞赋值完成以前进行。(不指定内部赋值延迟和指定内部赋值延迟为零(#)的赋值语句是一样的。)可综合性问题:·综合时延迟被忽略。·综合工具不支持wait语句和内部赋值延迟以及repeat(重复)语句。·事件控制用于控制always块的执行从而能确定综合出的逻辑是组合的还是时序的。一般情况下always后紧跟着的就是事件控制这有时也称为敏感列表。提示:在用RTL(寄存器传输级HDL语言)描述电路时可用内部赋值延迟可来描述在给表示触发器的寄存器变量赋值时的时钟偏移现象。举例说明:##(Period)#(::)Trigger(aorborc)(posedgeclockornegedgereset)wait(!Reset)非阻塞赋值时使用延迟来克服时钟的偏移:always(posedgeClock)Count<=#Count在周期时钟的第五个下降沿复位:initialbeginReset=repeat()(negedgeClock)Reset=(negedgeclock)End请参阅:ProceduralAssignment、Always、Repeat语句的说明UserDefinedPrimitive用户自定义原语用户自定义原语(UDPS)可以为小型元件建立模型这也是模块的另一种表示方法。可以用引用由门构建的实例同样的方式来实例引用用户自定义原语(UDPS)。语法:primitiveUDPName(OutputName,InputName,)UDPPortDeclarationsUDPBodyendprimitiveUDPPortDeclaration={either}outputOutputNameinputInputName,regOutputName{SequentialUDP}UDPBody={either}CombinationalBodySequentialBodyCombinationalBody=tableCombinationalEntryendtableSequentialBody=initialOutputName=InitialValuetableSequentialEntryendtableInitialValue={either}'b'b'bx{notcasesensitive}CombinationalEntry=LevelInputList:OutputSymbolSequentialEntry=SequentialInputList:CurrentOutput:NextOutputSequentialInputList={either}LevelInputListEdgeInputListLevelInputList=LevelSymbolEdgeInputList=LevelSymbolEdgeIndicatorLevelSymbolCurrentOutput=LevelSymbolNextOutput={either}OutputSymbolEdgeIndicator={either}(LevelSymbolLevelSymbol)EdgeSymbolOutputSymbol={either}x{notcasesensitive}LevelSymbol={either}xb{notcasesensitive}EdgeSymbol={either}rfpn*{notcasesensitive}规则:·UDP只允许有一个输出端至少允许有一个输入端。具体实施时对输入端的个数是有限制的但必须至少允许个输入端口。·如果某UDP的输出端定义为reg型(寄存器类型)变量则该UDP是时序逻辑的UDP,否则为组合逻辑的UDP。·如果已对时序逻辑的UDP的输出进行了初始化则只有待到在仿真开始时初始值才开始从引用的原语实例的输出传出。·描述时序逻辑的UDPS可以是电平敏感的或边沿敏感的。若在真值表中有边沿敏感的指示(至少一个)则该描述时序逻辑的UDP为边沿敏感的。·UDP的行为在表中定义。表的行定义为不同输入条件下的输出。对于描述组合逻辑的UDP每一行定义为一个或多个输入的组合逻辑的输出。对于描述时序逻辑的UDP每一行都要考虑reg类型变量的当前输出值。一行最多只能有一个边沿变化入口。行定义了在指定的边沿发生变化时由输入值和当前输出值所产生的输出值。·UDP表中所用的特殊的电平和边沿符号含义如下:?或xborB或输出不变(vw)由v变为wrorR()fofF()porP()(x)或(x)norN()(x)或(x)*()·若组合逻辑的输入值和触发边沿没有明确指定将会导致输出的不确定。·不支持Z值。输入时Z看成是X输出值不允许设为X。注意?符号的特殊含义它和在数字中的?符号意思不一样在数字的表示中符号?和z含义相同。注意!在描述时序逻辑的UDP中若在表中任何地方出现边沿触发的条件则输入信号所有可能的边沿都要认真考虑并列出因为默认的只是一种边沿的触发的条件这将导致输出的不确定性。可综合性问题:任何一种工具都不能综合UDP它只被用来建立基本的门级逻辑器件的逻辑仿真模型。提示:·和行为模块相比较用UDP来做仿真非常有效。为ASIC单元库的元件建立模型时应该使用UDP。·输出端口在一个以上的元件应该对每个输出建立独立的UDP。·在表的第一行加上注释指明每一列的含义。举例说明:primitiveMuxto(f,a,b,sel)组合UDPoutputfinputa,b,seltableabsel:f::::::endtableendprimitiveprimitiveLatch(Q,D,Ena)outputQinputD,EnaregQLevelsensitiveUDPtableDEna:oldQ:Q::::::保持原先值::::endtableendprimitiveprimitiveDFF(Q,Clk,D)outputQinputClk,DregQEdgesensitiveUDPinitialQ=tableClkD:oldQ:Qr::Clock''r::Clock''()::PossibleClock()::""()::""()::""()::Ignorefallingclock()::"""*::IgnorechangesonDendtableendprimitive请参阅:Module、Gate、Instantiation的语法说明。While条件循环语句只要控制表达式为真(即不为零)循环语句就重复进行。语法wile{Expression}Statement可综合性问题:只有当循环块有事件控制(即(posedgeClock))才可综合。举例说明:reg:Wordwhile(Word)beginif(Word)CountOnes=CountOnesWord=Word>>End请参阅:For、Forever、Repeat语句的说明。CompilerDirectives编译器指示编译器指示是在源代码中对Verilog编译器所发出的指令。在编译指示需要用反引号(`)做前导。编译器指示从它在源代码出现的地方开始生效并一直继续生效到随后运行的所有的文件直到编译器指示结束的地方或一直运行的最后的文件。下面有Verilog编译指示的摘要。摘要后面详细介绍了一些比较重要的编译指示。注意!编译器指示的生效依赖于编译时源代码中所包含文件的执行顺序。StandardCompilerDirectives标准的编译器指示在VerilogLRM中定义了以下编译器指示:)`celldefine和`endcelldefine可用来作为分别加在模块的前面和后面的标记以表示该模块是一个库单元(cell)。单元可被PLI子程序调用来做某种应用比如延迟的计算。例子:`celldefinemoduleNand{…}endmodule)`endcelldefine)`defaultnettype改变Net类型的默认类型。如果没有该声明默认的Net类型是wire型。)例子:`defaultnettypetril)`define和`undef`define定义一个文本宏`undef取消已定义的文本宏定义。在编译的第一阶段期间,宏(macro)被它所定义的文本字符串取代。宏也可以用来控制条件编译(请参阅`ifdef)。想要知道关于`define应用的更多细节见下面说明。)`ifdef,`else和`endif)根据是否定义了特殊的宏来指示编译器是否要编译这一段Verilog源代码。详细细节见下面。)`include指示编译器读入包含文件的内容并在`include所在的地方编译该文件。)例子:`include“definitionsv”)`resetall把现行的已启动的所有编译器指示复位到原默认值。该编译指示可以写在每个Verilog源文件的第一行以防止前面别的源文件的编译指示在该源文件编译时产生不需要的结果。例子:`resetall)`timescale定义仿真的时间单位和精度。细节请见下面说明。)`unconnecteddrive和`nounconnecteddrive`unconnecteddrive编译指示把模块没连接的输入端口设置为上拉pullup(pull即逻辑)或为下拉pulldown(pull,即逻辑)。`nounconnecteddrive编译指示把模块没连接输入端口的设置恢复到默认值即把没连接的输入端口值设置为高阻浮动(Z)。例子:`unconnecteddrivepull或pull(即逻辑值为)NonStandardCompilerDirectives非标准编译器指示下面的编译指示并不属于VerilogHDL语言的IEEE标准。但在CADENCE公司的VerilogLRM中提及。并不是所有的Verilog工具都支持以下这些编译指示。)`defaultdecaytime若未明确给定衰减时间则由该编译指示将其设置为默认的三态寄存器(trireg)类型的线路连接(Net)的衰减时间。例子:`defaultdecaytime`defaultdecaytimeinfinite表示无衰减时间)`defaulttriregstrength把三态寄存器(trireg)类型的线路连接(Net)的默认强度设置为整数。用整数来表示强度并不符合IEEE规定的Verilog语言标准但仍属于Verilog语言非标准扩展部分。例子:`defaulttriregstrength)`delaymodedistribute、`delaymodepath、`delaymodeunit和`delaymodezero这些编译指示都会影响延迟的仿真方式。分布式延迟是在原语实例中的延迟、赋值延迟和线路连接延迟。路径延迟是在Specify(指定)块中定义的延迟。若用单位和零延迟代替分布式延迟和路径延迟将加快仿真的过程但会丢失真实的延迟信息。在默认情况下仿真器会自动选择最长的延迟仿真方式即分布式延迟和路径延迟仿真方式。)`define`define定义一个文本宏。宏在编译的第一阶段被由它定义的文本所代替。在用参数和函数表达不适合或不允许的情况下用宏可以提高Verilog源代码的可读性和可维护性。语法:{declaration}`defineName(Argument,…)Text{usage}`Name(Expression,…)在程序中位于何处:宏可以在模块内或模块外定义。规则:·像所有的编译指示一样宏定义在整个文件中生效除非被后面的`define、`undef和`resetall编译指示改写或清除。宏定义没有范围的限制。·若定义的宏内有参数即在宏文本中用到参数则当宏调用时宏的参数被实际的参数表达式所代替。`defineadd(a,b)abf=`add(,)f=·宏定义可以用反斜杠()跨越几行。新的一行是宏文本中的一部分。·宏文本不允许分下列语言记号:注释数字字符串名称保留名称操作符。·不能把编译器指示名用作宏名。注意!·所有的具体电路实现工具都不支持带参数的宏。·若定义了宏则必须把撇号(`)写在宏名的紧前面才能调用该宏。没有撇号(`)打头的名即使名称与宏名一致则为独立的标识符与宏定义无关。·要区别撇号(`)和表示数制的前引号(‘)的不同。·不要用分号来结束宏定义除非真要在用宏代替分号。否则会引起语法错误。提示:·通常更喜欢用参数而不是用宏给无含义的字符起一个有含义的名字。·仿真时用带参数的宏要比用同样功能的函数效率高。举例说明:本例子说明在分层设计中如何用文本宏来选择不同的模块实现。这在综合时很有用特别是当必须用RTL源代码模块和已综合成门级电路的模块做混合仿真时。`defineSUBBLOCKsubblockrt`defineSUBBLOCKsubblockrt`defineSUBBLOCKsubblockgatesmoduleTopLevel…`SUBBLOCKsubinst(…)`SUBBLOCKsubinst(…)`SUBBLOCKsubinst(…)…endmodule下面的例子说明带参数的文本宏的定义和调用:`definenand(delay)nand#(delay)nand()(f,a,b)nand()(g,f,c)请参阅:‘ifdef的说明。)`ifdef根据是否定义了特定的宏来决定是否编译这部分Verilog源代码。语法:`ifdefMacroNameVerilogCode…`elseVerilogCode…`endif规则:·如果宏名已经用`define定义只编译Verilog编码的第一块。·如果宏名没有定义和`else指示出现只编译第二块。·这些编译指示是可以嵌套的。·没被编译的代码仍然必须是有效的Verilog代码。提示:这些编译指示可以用来调试模块。例如可以在同一个模块的两种形式之间切换(如布线前仿真模块和带布线延迟的门级仿真模块之间)或有选择地开启诊断信息的打印输出。例子`defineprimitiveModelmoduleTest…`ifdefprimitiveModelMydesignprimitivesUUT(…)`elseMydesignRTLUUT(…)`endifendmodule请参阅:`define的说明。)`timescale定义时间单位和仿真精度语法:`timescaleTimeUnitPrecisionUnitTimeUnit=TimeUnitPrecisionUnit=TimeUnitTime={either}Unit={either}smsusnspsfs规则:·像所有的编译指示一样`timescale影响在该指示后的所有模块无论位于同一个文件的还是位于独立编译的多个文件中的模块直到碰到下一个`timescale或`resetall指示将其改写或复位到默认为止。·精度单位必须小于或等于时间单位。·仿真器运行的精度就是在`timescale指示中所定义的最小精度单位。所有的延迟时间都以精度单位为准取整。提示:在每个模块文件的第一句应写上`timescale指示即使在模块中没有延迟也是如此因为有的仿真器必需要有`timescale指示才能正常工作。举例说明:`timescalensps请参阅:$timeformat的说明。

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/19

夏宇文老师vlogRef4

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利