使用FPGA时的奇怪综合

如今,有两种最常见的硬件描述语言:Verilog / SystemVerilog和VHDL。 硬件描述语言本身是相当通用的手段,但是总是这样吗? 硬件描述语言的“非通用性”又可以依靠什么呢?

撰写本文的想法是在不同开发环境中的一个项目的综合过程中产生的,因此获得了不同的结果。 由于源模块非常庞大,因此编写了一个较小容量的测试模块来演示结果,但是其综合导致了相同的警告/错误。 使用具有异步复位的4位寄存器作为测试模块,并选择Libero SoC 18.1,Quartus Prime 17.1,Vivado 2017.4.1作为开发环境。

首先,提供了一种以Verilog语言描述这种模块的变体,所选开发环境可以正确识别其文本:

module test1 ( input clk, input arst, input [3:0] data, output reg [3:0] q ); always @( posedge clk or negedge arst ) begin if ( ~ arst ) begin q <= 4'h0 ; end else begin q <= data ; end end endmodule 

综合此模块的结果,获得了以下方案:

  1. Libero SoC v11.8

    test1 Libero SoC

  2. Quartus Prime 17.1

    test1 quartus素数

  3. Vivado 2017.4.1

    test1 vivado


在所有用于test1的合成电路中,D触发器与反向复位输入(Quartus Prime)一起使用,或者与反相器一起使用(对于Libero SoC是VERIFIC_INV,对于Vivado是LUT1)。

如果更改异步复位的状态检查,合成电路会有所不同吗? 为此,将test1模块的文本更改为test2模块的描述:

 module test2 ( input clk, input arst, input [3:0] data, output reg [3:0] q ); always @(posedge clk or negedge arst) begin if (arst) begin q<=data; end else begin q<=4'h0; end end endmodule 

可以假定test2模块的综合不应与test1模块的综合相同,因为这两个模块的描述逻辑并不相互矛盾。 但是,test2模块的综合导致以下结果:

  1. Libero SoC v11.8
    电路已合成,但是以下警告消息“边沿和条件不匹配(CG136)”出现在消息中。 该警告表示灵敏度列表和重置条件验证不匹配。 但是,合成电路与test1模块没有什么不同。

    test2 Libero SoC

  2. Quartus Prime 17.1

    电路综合失败,并显示以下错误:

    “错误(10200):test2.v处的Verilog HDL条件语句错误(10):无法将条件中的操作数与Always结构的封闭事件控件中的相应边相匹配。” 错误文本类似于Libero SoC发出的警告。
  3. Vivado 2017.4.1

    进行电路综合并显示以下警告:

    “ [Synth 8-5788]模块测试中的寄存器q_reg具有相同的设置和复位优先级。 这可能会导致模拟不匹配。 考虑重写代码[“ /home/vlasovdv0111/project_1/project_1.srcs/sources_1/new/test2.v":10]。” 与Libero SoC和Quartus Prime相似,发出了类似的警告。 此外,警告还提到了建模结果与硬件工作之间可能存在差异,因此建议重写模块代码。

    test2 vivado


在描述模块test1和test2之后,提出了检查如果我们合成以下代码会发生什么的想法:

 module test3 ( input clk, input arst, input [3:0] data, output reg [3:0] q ); always @(posedge clk or negedge arst) begin if (arst) begin q<=4'h0; end else begin q<=data; end end endmodule 

这种寄存器的描述是不合逻辑的,因为在这种情况下,触发器的复位是在复位线处于非活动状态时发生的。

合成结果如下:

  1. Libero SoC v11.8

    电路综合未执行,但出现错误:“ q [3:0]的逻辑与标准触发器(CL123)不匹配”,因此以没有综合所需的触发类型为由,拒绝合成电路。
  2. Quartus Prime 17.1

    电路未合成,并出现以下错误:“错误(10200):test3.v(9)上的Verilog HDL条件语句错误:无法将条件中的操作数与Always结构的封闭事件控件中的相应边匹配” 。 该错误的文本与test2模块的错误文本没有不同。
  3. Vivado 2017.4.1

    该方案综合无误:

    test3 vivado


但是,如果我们描述的模块中的灵敏度列表与复位条件的检查不矛盾,但是当复位线处于非活动状态时,触发器将被复位(如test3模块描述的情况),将会发生什么。 这样的test4模块的描述如下:

 module test4 ( input clk, input arst, input [3:0] data, output reg [3:0] q ); always @( posedge clk or negedge arst ) begin if ( ~ arst ) begin q <= data ; end else begin q <= 4'h0 ; end end endmodule 

在合成过程中,获得了以下结果:

  1. Libero SoC v11.8

    进行电路综合并显示以下警告:

    “找到的信号被标识为系统时钟,它控制4个连续元素,包括q_1 [3]。 使用没有指定时序约束的时钟会对设计性能产生不利影响。 (MT532)。”

    test4 Libero SoC

  2. Quartus Prime 17.1

    综合电路的结果,收到了警告:

    «Warning (13004): Presettable and clearable registers converted to equivalent circuits with latches. Registers power-up to an undefined state, and DEVCLRn places the registers in an undefined state.
    Warning (13310): Register "q[0]~reg0" is converted into an equivalent circuit using register "q[0]~reg0_emulated" and latch "q[0]~1"
    Warning (13310): Register "q[1]~reg0" is converted into an equivalent circuit using register "q[1]~reg0_emulated" and latch "q[1]~1"
    Warning (13310): Register "q[2]~reg0" is converted into an equivalent circuit using register "q[2]~reg0_emulated" and latch "q[2]~1"
    Warning (13310): Register "q[3]~reg0" is converted into an equivalent circuit using register "q[3]~reg0_emulated" and latch "q[3]~1"»

    上述所有警告均与使用闩锁代替触发器的事实相对应。

    test4 quartus质数

  3. Vivado 2017.4.1

    该电路综合了一个警告:

    “ [Synth 8-5788]模块测试中的寄存器q_reg具有相同的设置和复位优先级。 这可能会导致模拟不匹配。 考虑重写代码[“ /home/vlasovdv0111/project_1/project_1.srcs/sources_1/new/test.v":11]。” 该错误的文本重复了test2模块的错误文本。

    test4 vivado


从所有描述的实验中,可以得出以下结论:

  1. Verilog语言是一种通用的硬件描述语言,其局限性在于开发环境本身的功能;
  2. 为了对设备进行正确的描述,必须了解语言的语法,并分析在项目构建的每个阶段发生的警告和错误列表。

Source: https://habr.com/ru/post/zh-CN413007/


All Articles