可合成代码的verilog编码风格

可合成代码的verilog编码风格,verilog,system-verilog,Verilog,System Verilog,我编写了如下代码: always @(state or i1 or i2 or i3 or i4) begin next = 5'bx; err = 0; n_o1 = 1; o2 = 0; o3 = 0; o4 = 0; case (state) // synopsys full_case parallel_case IDLE: begin if (!i1) next = IDLE; else if ( i2) next = S1; else if ( i3) next = S2; else

我编写了如下代码:

always @(state or i1 or i2 or i3 or i4) begin
next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
case (state) // synopsys full_case parallel_case
IDLE: begin
if (!i1) next = IDLE;
else if ( i2) next = S1;
else if ( i3) next = S2;
else next = ERROR;
end
S1: begin
if (!i2) next = S1;
else if ( i3) next = S2;
else if ( i4) next = S3;
else next = ERROR;**strong text**
...
我的经理,当然我不想在我有激烈的争论之前和他争论,但他审查了我的代码并说要写

next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
在组合逻辑中,如果没有将右边放在灵敏度列表中,将导致合成中出现问题。由于没有这3行,我需要在每个单独的案例中显式地写下else部分,他说是的

我想知道这种编码风格有什么问题吗?通过在组合逻辑中初始化这些值,它会导致合成问题或任何类型的问题(可能某些版本或旧的合成工具不会合成?)?他所说的对我来说是有意义的,我实际上从来没有想过,因为他说这是软件逻辑,每根导线都从它之前的逻辑中得到它的初始值,并带有初始条件。我告诉他学校教了我们这些,他就像学校不太关心任何合成,但工业关心


谢谢你的帮助!我想,即使我有答案,我也没有试图说服他任何东西,因为团队需要坚持一种风格,但我被他弄糊涂了,因为我一直看到其他人这样做,他也是一个有着丰富经验的人,所以…困惑

首先,你应该始终使用
@(*)
来自Verilog-2001,或者更好的
始终\u comb
来自SystemVerilog,因此灵敏度列表会自动为您构建


代码的问题在于使用了中所述的
完整大小写
合成杂注。只要您确定为
始终
块中的所有可能的流指定了
块中的每个变量,那么您的编码风格就不需要完整的大小写

我认为你的老板所说的“软件逻辑”是指你的编码风格要求设计师按顺序思考。换句话说,当我阅读您的
始终
块时,我首先被迫考虑将所有值初始化为它们的默认值,然后我必须评估案例逻辑。实际上,逻辑将合成为一个相当于
默认值的情况。这导致了代表RTL的逻辑和我如何评估你在我脑海中的表达的逻辑之间的差异。如果你知道自己在做什么,那么大多数时候这应该是好的。但您是为一家公司工作,所以您的代码应该考虑到从事项目的其他工程师。设计流程中的每个不同团队将通过一个可能不同的视角来看待相同的逻辑(例如,物理设计团队不关心Verilog,而是综合RTL)。如果我们编写Verilog来反映最终的RTL(即“硬件逻辑”),那么每个人都在以类似的方式分析逻辑。如果我观察一个电路中的输出,知道给定时间步长下输入的所有值,那么我可以直观地跟踪电路中的输出并确定其值,而不考虑其他逻辑。您的Verilog代码应该以相同的方式编写

总之,您的初始化语句不过是RTL中选择mux的另一种情况。所以,你应该这样写。使用
默认值
大小写,并在每种情况下显式分配块的每个输出。这通常被认为是最佳做法。它可能不是编写Verilog最聪明、最优雅的方式,但它是可读性最强的方式,并且产生的错误要少得多(在业界,人们更关心设计验证以降低成本,而不是Verilog的聪明)

此外,正如@dave_59所提到的,如果您使用
full_case
Synopsis指令,那么它将为您创建默认输出驱动程序,其中输出设置为“不在乎”。这不是任何人想要的结果,验证团队将标记它。要解决这个问题,您需要确保每个输出都已分配,方法是将它们添加到您老板提到的所有案例中。如果您被迫这样做,那么
full\u case
是多余的,因为您已经显式地将case语句设置为full。至于较旧的合成工具,我不认为这是这个特定主题的一个大问题,但这是工业界经常考虑的问题。更重要的问题是,如果您的公司配置了下游工具,以强制使用较旧的构造,从而降低验证成本


相信你的经理在这个问题上的经验。行业中的编码风格很大程度上受与其他工程师的协作、成本和遗产的影响,而不是受技术细节的影响。这就是你的经理经验的价值所在。

谢谢你,戴夫。我知道应该使用always(*)。因此,您的答案是,在case语句的顶部初始化变量是可以的,这不会导致任何问题?顺便说一句,这种编码风格完全是从你刚才提到的那个人那里复制过来的,但与他有一篇不同的论文“用于合成的状态机编码风格”。我阅读了他的论文(包括你提到的那篇)作为参考。当我的老板说敏感度列表不完整时,我告诉他使用(*),但他似乎在初始化变量方面有问题。她看到了这一点,说“我不喜欢这种风格,因为这就像软件逻辑”我喜欢。。。这是我的学校教给我的…他希望每个if后面都有一个else,这样就不会有旧的合成工具的闩锁。这种风格很好,并且被广泛使用。但有一件事是不受欢迎的:
next=5'bx最好在此处指定一个已知值,否则您可能会遇到验证/合成问题。感谢您的回答。后续操作:我的初始化将在开始时将变量分配给0,即使选择了非默认情况,并且没有触发该情况下的if语句。所以如果我有一个默认的case,如果我输入一次case,if执行varia