verilog中有哪几种方法描述逻辑功能
发布时间:2025-05-20 05:12:19 发布人:远客网络
一、verilog中有哪几种方法描述逻辑功能
1、Verilog HDL有多中描述风格,具体可以分为:结构描述,数据流描述,行为描述,混合描述。
2、结构描述是指通过调用逻辑原件,描述它们之间的连接来建立逻辑电路的verilog HDL模型。这里的逻辑元件包括内置逻辑门、自主研发的已有模块、商业IP模块。所以结构描述也分为门级结构描述和模块级结构描述。通过观察是否有功能模块或原语的实例化可以判断是否有结构描述。
3、数据流描述是指根据信号之间的逻辑关系,采用持续赋值语句描述逻辑电路的方式。通过观察是否使用assign赋值语句可以判断是否有数据流描述。
4、行为描述是指只注重实现的算法,不关心具体的硬件实现细节。这与C语言编程非常类似。通过观察是否使用initial或always语句块可以判断是否有行为描述。
5、混合描述是指以上几种描述方法都存在的一种描述方式。具体在一个工程中,不可能只是用单独哪一种描述方式,一般都是各种描述方式的混合。
6、逻辑电路的结构描述侧重于表示一个电路由哪些基本元件组成,以及这些基本元件的相互连接关系。逻辑电路的数据流描述侧重于逻辑表达式以及Verilog HDL中运算符的灵活运用。逻辑电路的行为描述侧重于电路的输入输出的因果关系(行为特性),即在何种输入条件下,产生何种输出(进行何种操作),并不关心电路的内部结构。EDA综合工具能自动将行为描述转换成电路结构,形成网表文件。当电路规模较大货时序关系较为复杂时,通常采用行为描述方式进行设计。
7、在数字电路设计中,寄存器传输级(RTL)描述在很多情况下时钟能够被逻辑综合工具接受的行为级和数据流级的混合描述。因此RTL级描述的目标就是可综合,而行为级描述的目标就是实现特定的功能而没有可综合的限制。并不是所有的行为级描述都可以被综合。同样是for语句,如果循环条件是常数,就是RTL的,如果是变量,就是行为级的。
二、verilog编程技巧
的设计思想与技巧是一个非常大的话题,由于篇幅所限,本文仅介绍一些常用的设计思想与技巧,包括乒乓球操作、串并转换、流水线操作和数据接口的同步方法。
希望本文能引起工程师们的注意,如果能有意识地利用这些原则指导日后的设计工作,将取得事半功倍的效果!
“乒乓操作”是一个常常应用于数据流控制的处理技巧,典型的乒乓操作方法如图 1所示。
乓操作的处理流程为:输入数据流通过“输入数据选择单元”
将数据流等时分配到两个数据缓冲区,数据缓冲模块可以为任何存储模块,比较常用的存储单元为双口 RAM(DPRAM)、单口 RAM(SPRAM)
、 FIFO等。在第一个缓冲周期,将输入的数据流缓存到“数据缓冲模块 1”;在第 2个缓冲周期,通过“输入数据选择单元”
的切换,将输入的数据流缓存到“数据缓冲模块 2”,同时将“数据缓冲模块 1”缓存的第 1个周期数据通过“输入数据选择单元”
的选择,送到“数据流运算处理模块”进行运算处理;在第 3个缓冲周期通过“输入数据选择单元”的再次切换,将输入的数据流缓存到
“数据缓冲模块 1”,同时将“数据缓冲模块 2”缓存的第 2个周期的数据通过“输入数据选择单元”切换,送到“
数据流运算处理模块”进行运算处理。如此循环。
乒乓操作的最大特点是通过“输入数据选择单元”
和“输出数据选择单元”按节拍、相互配合的切换,将经过缓冲的数据流没有停顿地送到“数据流运算处理模块”
进行运算与处理。把乒乓操作模块当做一个整体,站在这个模块的两端看数据,输入数据流和输出数据流都是连续不断的,没有任何停顿,因此非常适合对数据流进
行流水线式处理。所以乒乓操作常常应用于流水线式算法,完成数据的无缝缓冲与处理。
可以节约缓冲区空间。比如在 WCDMA基带应用中, 1个帧是由 15个时隙组成的,有时需要将 1
整帧的数据延时一个时隙后处理,比较直接的办法是将这帧数据缓存起来,然后延时 1个时隙进行处理。这时缓冲区的长度是 1
整帧数据长,假设数据速率是 3.84Mbps, 1帧长 10ms,则此时需要缓冲区长度是 38400
位。如果采用乒乓操作,只需定义两个能缓冲 1个时隙数据的 RAM(单口 RAM即可)。当向一块 RAM写数据的时候,从另一块
RAM读数据,然后送到处理单元处理,此时每块 RAM的容量仅需 2560位即可, 2块 RAM加起来也只有 5120位的容量。
另外,巧妙运用乒乓操作还可以达到用低速模块处理高速数据流的效果。如图 2所示,数据缓冲模块采用了双口 RAM,并在 DPRAM
后引入了一级数据预处理模块,这个数据预处理可以根据需要的各种数据运算,比如在 WCDMA设计中,对输入数据流的解扩、解扰、去旋转等。假设端口
A的输入数据流的速率为 100Mbps,乒乓操作的缓冲周期是 10ms。以下分析各个节点端口的数据速率。
A端口处输入数据流速率为 100Mbps,在第 1个缓冲周期 10ms内,通过“输入数据选择单元”,从 B1到达 DPRAM1。 B1的数据速率也是 100Mbps, DPRAM1要在 10ms内写入 1Mb数据。同理,在第 2个 10ms,数据流被切换到 DPRAM2,端口 B2的数据速率也是 100Mbps, DPRAM2在第 2个 10ms被写入 1Mb数据。在第 3个 10ms,数据流又切换到 DPRAM1, DPRAM1被写入 1Mb数据。
仔细分析就会发现到第 3个缓冲周期时,留给 DPRAM1读取数据并送到“数据预处理模块 1”的时间一共是 20ms。有的工程师困惑于DPRAM1的读数时间为什么是 20ms,这个时间是这样得来的:首先,在在第 2个缓冲周期向 DPRAM2写数据的 10ms内,
DPRAM1可以进行读操作;另外,在第 1个缓冲周期的第 5ms起(绝对时间为 5ms时刻), DPRAM1就可以一边向500K以后的地址写数据,一边从地址 0读数,到达 10ms时, DPRAM1刚好写完了 1Mb数据,并且读了 500K数据,这个缓冲时间内 DPRAM1读了 5ms;在第 3个缓冲周期的第 5ms起(绝对时间为 35ms时刻),同理可以一边向
500K以后的地址写数据一边从地址 0读数,又读取了 5个 ms,所以截止 DPRAM1第一个周期存入的数据被完全覆盖以前,DPRAM1最多可以读取 20ms时间,而所需读取的数据为 1Mb,所以端口 C1的数据速率为: 1Mb/20ms=50Mbps。因此,“数据预处理模块 1”的最低数据吞吐能力也仅仅要求为 50Mbps。同理,“数据预处理模块 2”的最低数据吞吐能力也仅仅要求为 50Mbps。换言之,通过乒乓操作,“数据预处理模块”
的时序压力减轻了,所要求的数据处理速率仅仅为输入数据速率的 1/2。
通过乒乓操作实现低速模块处理高速数据的实质是:通过 DPRAM这种缓存单元实现了数据流的串并转换,并行用“数据预处理模块 1”和“数据预处理模块 2”处理分流的数据,是面积与速度互换原则的体现!
设计的一个重要技巧,它是数据流处理的常用手段,也是面积与速度互换思想的直接体现。串并转换的实现方法多种多样,根据数据的排序和数量的要求,可以选用
寄存器、 RAM等实现。前面在乒乓操作的图例中,就是通过 DPRAM实现了数据流的串并转换,而且由于使用了 DPRAM,数据的缓冲区可以开得很大,对于数量比较小的设计可以采用寄存器完成串并转换。如无特殊需求,应该用同步时序设计完成串并之间的转换。比如数据从串行到并行,数据排列顺序是高位在前,可以用下面的编码实现:
prl_temp<={prl_temp,srl_in};
其中, prl_temp是并行输出缓存寄存器, srl_in是串行数据输入。对于排列顺序有规定的串并转换,可以用 case语句判断实现。对于复杂的串并转换,还可以用状态机实现。串并转换的方法比较简单,在此不必赘述。
首先需要声明的是,这里所讲述的流水线是指一种处理流程和顺序操作的设计思想,并非 FPGA、 ASIC设计中优化时序所用的“Pipelining”。
流水线处理是高速设计中的一个常用设计手段。如果某个设计的处理流程分为若干步骤,而且整个数据处理是“单流向”的,即没有反馈或者迭代运算,前一个步骤的输出是下一个步骤的输入,则可以考虑采用流水线设计方法来提高系统的工作频率。
流水线设计的结构示意图如图 3所示。其基本结构为:将适当划分的 n个操作步骤单流向串联起来。流水线操作的最大特点和要求是,数据流在各个步骤的处理从时间上看是连续的,如果将每个操作步骤简化假设为通过一个 D触发器(就是用寄存器打一个节拍),那么流水线操作就类似一个移位寄存器组,数据流依次流经 D触发器,完成每个步骤的操作。流水线设计时序如图 4所示。
流水线设计的一个关键在于整个设计时序的合理安排,要求每个操作步骤的划分合理。如果前级操作时间恰好等于后级的操作时间,设计最为简单,前级的输出直接汇入后级的输入即可;如果前级操作时间大于后级的操作时间,则需要对前级的输出数据适当缓存才能汇入到后级输入端;如果前级操作时间恰好小于后级的操作时间,则必须通过复制逻辑,将数据流分流,或者在前级对数据采用存储、后处理方式,否则会造成后级数据溢出。
在 WCDMA设计中经常使用到流水线处理的方法,如 RAKE接收机、搜索器、前导捕获等。流水线处理方式之所以频率较高,是因为复制了处理模块,它是面积换取速度思想的又一种具体体现。
数据接口的同步是 FPGA/CPLD设计的一个常见问题,也是一个重点和难点,很多设计不稳定都是源于数据接口的同步有问题。
在电路图设计阶段,一些工程师手工加入 BUFT或者非门调整数据延迟,从而保证本级模块的时钟对上级模块数据的建立、保持时间要求。还有一些工程师为了有稳定的采样,生成了很多相差 90度的时钟信号,时而用正沿打一下数据,时而用负沿打一下数据,用以调整数据的采样位置。这两种做法都十分不可取,因为一旦芯片更新换代或者移植到其它芯片
组的芯片上,采样实现必须从新设计。而且,这两种做法造成电路实现的余量不够,一旦外界条件变换(比如温度升高),采样时序就有可能完全紊乱,造成电路瘫痪。
下面简单介绍几种不同情况下数据接口的同步方法:
1.输入、输出的延时(芯片间、 PCB布线、一些驱动接口元件的延时等)不可测,或者有可能变动的条件下,如何完成数据同步?
对于数据的延迟不可测或变动,就需要建立同步机制,可以用一个同步使能或同步指示信号。另外,使数据通过 RAM或者 FIFO的存取,也可以达到数据同步目的。
把数据存放在 RAM或 FIFO的方法如下:将上级芯片提供的数据随路时钟作为写信号,将数据写入 RAM或者 FIFO,然后使用本级的采样时钟(一般是数据处理的主时钟)将数据读出来即可。这种做法的关键是数据写入 RAM或者 FIFO要可靠,如果使用同步 RAM或者 FIFO,就要求应该有一个与数据相对延迟关系固定的随路指示信号,这个信号可以是数据的有效指示,也可以是上级模块将数据打出来的时钟。对于慢速数据,也可以采样异步 RAM或者 FIFO,但是不推荐这种做法。
数据是有固定格式安排的,很多重要信息在数据的起始位置,这种情况在通信系统中非常普遍。通讯系统中,很多数据是按照“帧”组织的。而由于整个系统对时钟要求很高,常常专门设计一块时钟板完成高精度时钟的产生与驱动。而数据又是有起始位置的,如何完成数据的同步,并发现数据的“头”呢?
数据的同步方法完全可以采用上面的方法,采用同步指示信号,或者使用 RAM、FIFO缓存一下。找到数据头的方法有两种,第一种很简单,随路传输一个数据起始位置的指示信号即可,对于有些系统,特别是异步系统,则常常在数据中插入一段同步码(比如训练序列),接收端通过状态机检测到同步码后就能发现数据的“头”了,这种做法叫做“盲检测”。
上级数据和本级时钟是异步的,也就是说上级芯片或模块和本级芯片或模块的时钟是异步时钟域的。
前面在输入数据同步化中已经简单介绍了一个原则:如果输入数据的节拍和本级芯片的处理时钟同频,可以直接用本级芯片的主时钟对输入数据寄存器采样,完成输入数据的同步化;如果输入数据和本级芯片的处理时钟是异步的,特别是频率不匹配的时候,则只有用处理时钟对输入数据做两次寄存器采样,才能完成输入数据的同步化。需要说明的是,用寄存器对异步时钟域的数据进行两次采样,其作用是有效防止亚稳态(数据状态不稳定)的传播,使后级电路处理的数据都是有效电平。但是这种做法并不能保证两级寄存器采样后的数据是正确的电平,这种方式处理一般都会产生一定数量的错误电平数据。所以仅仅适用于对少量错误不敏感的功能单元。
为了避免异步时钟域产生错误的采样电平,一般使用 RAM、 FIFO缓存的方法完成异步时钟域的数据转换。最常用的缓存单元是 DPRAM,在输入端口使用上级时钟写数据,在输出端口使用本级时钟读数据,这样就非常方便的完成了异步时钟域之间的数据交换。
2.设计数据接口同步是否需要添加约束?
建议最好添加适当的约束,特别是对于高速设计,一定要对周期、建立、保持时间等添加相应的约束。
a.提高设计的工作频率,满足接口数据同步要求。通过附加周期、建立时间、保持时间等约束可以控制逻辑的综合、映射、布局和布线,以减小逻辑和布线延时,从而提高工作频率,满足接口数据同步要求。
获得正确的时序分析报告。几乎所有的 FPGA设计平台都包含静态时序分析工具,利用这类工具可以获得映射或布局布线后的时序分析报告,从而对设计的性能做出评估。静态时序分析工具以约束作为判断时序是否满足设计要求的标准,因此要求设计者正确输入约束,以便静态时序分析工具输出正确的时序分析报告。
和数据接口相关的常用约束有 Period、 OFFSET_IN_BEFORE、 OFFSET_IN_AFTER、
OFFSET_OUT_BEFORE和 OFFSET_OUT_AFTER等; Altera与数据接口相关的常用约束有 Period、
三、verilog编程的问题
1、你说的两个模块之间的实例化吧,在图形上就是用线连起来,我教你。
2、比如有两个模块定义为:moudle A和moudle B
3、其中A模块有一个输出信号设为:output a1,a2;
4、 B模块有一个输入信号设为:input b1,b2;
5、那么当我们需要将a1,a2连到b1,b2(用debussy看的话也就是一条连线),这个就要实例化A和B这两个模块,具体是这么写的:
6、这段代码放到A模块的最后,endmoudle之前就行。
7、其中B_LianJie是我们自己随便起的实例化的名字,B指的是调用B这个模块进行实例化。
8、如要将这段代码放到B模块里,那么就得调用A模块来实例化:
9、这样就把我们需要连接的两个模块连到一起了,信号多了也是一样的,继续把信号对应填到括号里就行了。
10、如果还有不明白的,可以继续问我。verilog设计我做了2年了,呵呵。