第二,如果循环在verilog中不工作,并且生成了锁存。如何修复这些问题?
我是Verilog的新手。我尝试了下面的代码,将“任务”调用到if循环中。。语法正确。但是,当我以choice作为010执行行为模拟时,循环不起作用。输出显示为全零,合成报告显示已生成锁存。如何修复这两个问题第二,如果循环在verilog中不工作,并且生成了锁存。如何修复这些问题?,verilog,Verilog,我是Verilog的新手。我尝试了下面的代码,将“任务”调用到if循环中。。语法正确。但是,当我以choice作为010执行行为模拟时,循环不起作用。输出显示为全零,合成报告显示已生成锁存。如何修复这两个问题 module a(choice,data1,data2,result); input[2:0]choice; input[6:0]data1; input[8:0]data2; output[8:0]result; reg[8:0]reg_result; wir
module a(choice,data1,data2,result);
input[2:0]choice;
input[6:0]data1;
input[8:0]data2;
output[8:0]result;
reg[8:0]reg_result;
wire[3:0]choice;
wire[6:0]data1;
wire[8:0]data2;
wire[8:0]result;
initial///initailllllllllllllllllllllllllll
begin
reg_result=0; //declaring output register to 0 initially
end
always @(data1 or data2 or choice )
begin
if(choice==001)////if loop 1
begin
taskoperation(data1,reg_result);///load result from task
end
if(choice==010)//when choice is given as 010 the simulated output gives me all
begin//zeroes in result(output reg)
taskoperation(data2,reg_result);
end
end
//task operation
task taskoperation(
input [8:0]datainput;
output [8:0]dataoutput
);
dataoutput[8:0]=~(datainput[8:0]);//taskoperation
endtask
assign result=reg_result;
endmodule
闩锁
闩锁可能是由于使用2个if语句作为选择器而生成的。这些应该是声明
case (choice)
3'b001 :
begin
taskoperation(data1,reg_result);
end
3'b010 :
begin
taskoperation(data2,reg_result);
end
default : $display("Error in choice"); //Know when there are other issues!
endcase
为什么010不起作用
请参见我的案例陈述中如何使用3'b001和3'b010来表示案例?通过包含大小前缀3,我指示需要该总线的位数。通过包含b,我表示我希望我的数字被解释为二进制值。所以3'b001等于十进制值1。同样,3'b010被解释为2。如果我只写010而没有任何前缀,编译器会认为我说的是十进制值,并将其解释为十进制的10。这就是你可能出错的地方。010案件根本就没有联系到。这个故事的寓意是,当用文字编码时,总是要写前缀
注释
请注意,如果您确实认为if语句是作业的正确工具,请确保始终包含else块,以避免闩锁生成
文字:
另一个案例参考:
最后是关于锁存发生原因的初学者参考:010被推断为十进制,使其值为10。用布尔基文本定义它;3'b010。您还应该将001改为3'b001
SystemVerilog遵循相同的规则。这是§5.7.1整型文字常量的定义
整数文字常量可以以十进制、十六进制、八进制或二进制格式指定。
有两种形式可以表示整型文字常量。第一种形式是简单的十进制数,应指定为0到9的数字序列,可以选择以加号或减号一元运算符开头。第二种形式指定了一个基于文字的常量,该常量最多由三个标记组成:可选大小常量、撇号字符'、ASCII 0x27,后跟一个基本格式字符,以及表示数字值的数字。替换这三种代币是合法的
导致闩锁的原因有两个:
choice==010意味着{29'b0,choice}==32'd10,这永远不会是真的,并且将在sunthesis期间进行优化。
当选项不是1或2时,没有其他条件。这意味着reg_结果将保持其值。由于这是在组合逻辑中,所以可以推断出锁存器。
将ifchoice==010转到else ifchoice==2'b010,然后添加一个else条件,为reg_结果赋值
修复语法错误:input[8:0]datainput;需要输入[8:0]数据输入,分号到逗号
其他建议:
除非您需要遵守严格的Verilog95标准,否则请始终使用@*而不是@data1或data2或choice。当灵敏度列表较长时,使用@*有助于防止推断锁存。提到
在打算合成时,尽可能使用函数而不是任务。任务允许不可合成的时间阻塞。
使用ANSI样式的端口声明。仅Verilog95需要非ANSI样式。例子:
module a(
input [2:0] choice,
input [6:0] data1,
input [8:0] data2,
output reg [8:0] result );
Verilog-2001支持ANSI样式。每当您有非顺序块时,都会生成锁存。任何始终块在灵敏度列表中都没有@posedge或@negedge,并且RTL中有一个可能的代码路径,导致信号保留其旧值 例如:
if (foo)
bar = 1;
// no else
在这种情况下,将推断闩锁,因为如果foo==0,则bar将在有状态时保留其值。要解决此问题,请使用else:
if (foo)
bar = 1;
else
bar = ~fred;
或者,如果决策树很复杂,请指定一个默认值,并在以后覆盖它:
bar = ~fred;
if (foo)
bar = 1;
后者经常与状态机一起使用,在状态机中很难确保每个信号都有完整的case/if/else树