I have tried to design a Booth multiplier and it runs well in all compilers including:
我尝试设计一个摊位乘数,它在所有编译器中运行良好,包括:
Modelsim,Verilogger Extreame,Aldec Active Hdl & Xilinx's Isim......
Modelsim,Verilogger,Aldec Active Hdl & Xilinx的Isim……。
I know Simulation and Synthesis are two Different Process and only few Verilog constructs with various restrictions are there for synthesis. But I don't know what happen While loop
in my program not work in Synopsys Synplify 9.6 as well as in Xilinx ise 14.2.
我知道模拟和合成是两个不同的过程,只有很少的Verilog构造有各种各样的限制来进行合成。但是我不知道在我的程序中循环发生了什么,在Synopsys Synplify 9.6和xilinxise 14.2中都不工作。
When I try to synthesize Synopsys says "loop iteration limit 2000 exceeded"
while Xilinx' XST says " This Xilinx application has run out of memory or has encountered a memory conflict"
当我尝试合成Synopsys时,它说“循环迭代极限2000超过”,而Xilinx' XST说“这个Xilinx应用程序已经耗尽内存,或者遇到了内存冲突”
I have attached my code below. I Also write this <-------"Error Generated Here due to this while loop" where Synthesizer generates error due to while loop......
我已经在下面附上了我的代码。我也写了这个<------- -“这里产生的错误,因为这个while循环”合成器产生错误,因为while循环……
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////Author/Coder-Shrikant Vaishnav///////////////////////////////////////////////
/////////////////////////////////////////Design-Booth Algorithm Demonstration////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
module booth_synt(input wire [4:0]a,input wire [4:0]b,output reg signed[9:0] g);
reg signed[10:0]c;// One extra bit for sign bit.....I mean 11th bit.
//We used Signed Reg bcoz ASR fill vacant bit with MSB and then shift other for unsigned reg they fill it with zeros and then shift..
reg[4:0]d;
reg [4:0]e;
reg [2:0]count1;
reg [2:0]count2;
reg [2:0]count3;
reg [2:0]count4;
//Always start whenever any changes happens
always@(a,b)
begin :close
//If's for sign bit check...
//Then 2's Complement...
count1=3'b000; //Initialize Counter
count2=3'b000;
count3=3'b000;
count4=3'b000;
//For negative
if(a[4]==1'b1) //Internal checking
begin
if(a==5'b10000)
begin
g[9:0]=10'b0000000000;
end
else
begin
d=~{1'b0,a[3],a[2],a[1],a[0]}; //we place 1'b0 because its inversion is 1
d=d+5'b00001; //2's Complement we use additional register d for data holding.....bcoz wire not hold data
if(d[4]==1'b0)//This "if" is used bcoz if due to calculation if accidently d[5]==1'b0 then this changs sign bit and thus ans
begin
d[4]=1'b1;
end
c[5:1]=d;
end
end
if(b[4]==1'b1)
begin
if(b==5'b10000)
begin
g[9:0]=10'b0000000000;
disable close;
end
else
begin
e=~{1'b0,b[3],b[2],b[1],b[0]}; //we place 1'b0 because its inversion is 1
e=e+5'b00001;
if(e[4]==1'b0)//This "if" is used bcoz if due to calculation if accidently e[4]==1'b0 then this changs sign bit and thus ans
begin
e[4]=1'b1;
end
end
end
//For positive
if(b[4]==1'b0)
begin
e[4:0]=b[4:0];
end
if(a[4]==1'b0)
begin
c[1]=a[0];
c[2]=a[1]; //"a" is multiplier while "b" is multiplicand...
c[3]=a[2];
c[4]=a[3];
c[5]=a[4];
end
//Initialization of Output ........
c[0]=1'b0;
//All MSB's are Initially set to Zeros
c[6]=1'b0;
c[7]=1'b0;
c[8]=1'b0;
c[9]=1'b0;
c[10]=1'b0;
//Four Different Conditions Checking......
case({c[1],c[0]})
2'b00:begin //Case 1
while(count1<3'b101) **<-------"Error Generated Here due to this while loop"**
begin
if({c[1],c[0]}==2'b10) //cond1 for 10
begin
c[10:6]=(c[10:6]-e[4:0]);
c=c>>>1;
count1=count1+1'b1;
if(count1==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end //end if==4
end
if(({c[1],c[0]}==2'b00) || ({c[1],c[0]}==2'b11)) //cond 2 in it we describe both 00 and11.........Arithemetic Right Shift operation
begin
c=c>>>1;
count1=count1+1'b1;
if(count1==3'b101) // Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if({c[1],c[0]}==2'b01) //cond3 for 01
begin
c[10:6]=(c[10:6]+e[4:0]);
c=c>>>1;
count1=count1+1'b1;
if(count1==3'b101) // Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
end
end//while's end
//Case2
2'b11:begin
while(count2<3'b101) **<-------"Error Generated Here due to this while loop"**
begin
if({c[1],c[0]}==2'b10) //cond1 for 10
begin
c[10:6]=(c[10:6]-e[4:0]);
c=c>>>1;
count2=count2+1'b1;
if(count2==3'b101) // Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if(({c[1],c[0]}==2'b00)||({c[1],c[0]}==2'b11))//cond 2 in it we describe both 00 and11.........Arithemetic Right Shift operation
begin
c=c>>>1;
count2=count2+1'b1;
if(count2==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if({c[1],c[0]}==2'b01) //cond3 for 01
begin
c[10:6]=(c[10:6]+e[4:0]);
c=c>>>1;
count2=count2+1'b1;
if(count2==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
end
end //while's end
//Case 3
2'b10:begin
while(count3<3'b101) **<-------"Error Generated Here due to this while loop"**
begin
if({c[1],c[0]}==2'b10) //Cond1 for 10
begin
c[10:6]=(c[10:6]-e[4:0]);
c=c>>>1;
count3=count3+1'b1;
if(count3==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if(({c[1],c[0]}==2'b00)||({c[1],c[0]}==2'b11))//cond 2 in it we describe both 00 and11.........Arithemetic Right Shift operation
begin
c=c>>>1;
count3=count3+1'b1;
if(count3==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if({c[1],c[0]}==2'b01) //cond3 for 01
begin
c[10:6]=(c[10:6]+e[4:0]);
c=c>>>1;
count3=count3+1'd1;
if(count3==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
end
end //while's end
//Case 4
2'b01:begin
while(count4<3'b101) **<-------"Error Generated Here due to this while loop"**
begin
if({c[1],c[0]}==2'b10) //cond1 for 10
begin
c[10:6]=(c[10:6]-e[4:0]);
c=c>>>1;
count4=count4+1'b1;
if(count4==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if(({c[1],c[0]}==2'b00)||({c[1],c[0]}==2'b11))//cond 2 in it we describe both 00 and11.........Arithemetic Right Shift operation
begin
c=c>>>1;
count4=count4+1'b1;
if(count4==3'b101)// Counter value check
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
if({c[1],c[0]}==2'b01) //cond3 for 01
begin
c[10:6]=(c[10:6]+e[4:0]);
c=c>>>1;
count4<=count4+1'b1;
if(count4==3'b101)
begin
if(c[10]==1)
begin
c=~{1'b0,c[9],c[8],c[7],c[6],c[5],c[4],c[3],c[2],c[1],c[0]};//we place 1'b0 because its inversion is 1
c=c+10'b0000000010;
c[10]=1'b1; //Again giving 1 for surity
g[9:0]=c[10:1];
end
if(c[10]==0)
begin
c[10]=1'b0;
g[9:0]=c[10:1];
end
end
end
end //while's end
end//01's end
endcase //case end
end //always end
endmodule
3 个解决方案
#1
1
This is poorly written code.You have written it like a computer program. Verilog is a Hardware Description Language - not a programming language. In your case, synthesizer is trying to replicate logic inside the while loop in the case statement.
这是写得不好的代码。你把它写成了电脑程序。Verilog是一种硬件描述语言,而不是一种编程语言。在您的例子中,合成器试图在case语句的while循环中复制逻辑。
- Design the hardware on a piece of paper before translating it to HDL
- 在将其转换为HDL之前,在一张纸上设计硬件。
- Identify the combinational and sequential logic in the design before coding.
- 在编码之前确定设计中的组合和顺序逻辑。
- Think what logic will synthesizer use to realize the logic you have written.
- 想想用什么逻辑合成器来实现你所写的逻辑。
#2
0
Here are some tips:
这里有一些建议:
- Remove the latches:
-
c[5:1]
is a latch because it is not initialized in theif(a==5'b10000)
branch. - c[5:1]是一个门闩,因为它在if(a==5'b10000)分支中没有初始化。
-
d
is not defined inif(a==5'b10000)
and could be a potential latch depending on the synthesizer optimization capabilities. - 如果(a==5'b10000),则d没有定义,并且根据合成器的优化能力,它可能是一个潜在的锁存器。
-
e
is not defined inif(b==5'b10000)
and could be a potential latch liked
. - e不是在if(b==5'b10000)中定义的,也可能是像d那样的潜在锁存。
- At the beginning of the always block, make sure all the combination logic have initial values.
- 在总是块的开头,确保所有组合逻辑都有初始值。
-
- 删除门闩:c[5:1]是一个锁存器,因为它在if(a==5'b10000)分支中没有初始化。如果(a==5'b10000),则d没有定义,并且根据合成器的优化能力,它可能是一个潜在的锁存器。e不是在if(b==5'b10000)中定义的,并且可能是像d那样的潜在的锁存。在总是块的开头,确保所有组合逻辑都有初始值。
- Try to avoid using
disable
for code to be synthesized. Use if-else statements instead.- Note: This is a guideline not a rule.
- 注意:这是一个指导原则,而不是规则。
- 尽量避免使用禁用的代码来合成。使用if - else语句。注意:这是一个指导原则,而不是规则。
- There is lot of redundant and poorly organized code:
- All branches with in the case statement are the same. Should be cleaned up in consolidated.
- 在case语句中所有的分支都是相同的。应该在合并中清理。
- There is code inside the while loop that is better suited outside the loop (e.g. the
if(count*==3'b101)
block) - 在while循环中有代码更适合于外部循环(例如if(count*==3'b101))
- 有很多冗余和组织混乱的代码:在case语句中所有的分支都是相同的。应该在合并中清理。在while循环中有代码更适合于外部循环(例如if(count*==3'b101))
- If the
while
loop is having problems, try afor
loop. - 如果while循环出现问题,请尝试for循环。
#3
0
While
loops tend to imply something dynamic, like checking a condition. This is not a good use of verilog intended for synthesis. For
loops which can be statically unrolled are more commonly used to shorten the written code.
While循环往往意味着一些动态的东西,比如检查一个条件。这不是用于合成的verilog的良好使用。对于可以静态展开的循环,更常用的方法是缩短编写的代码。
If you need some thing more dynamic a dedicated state machine should be written.
如果您需要一些更动态的东西,就应该编写一个专用的状态机。
To answer some of the questions raised in the comments:
来回答一些在评论中提出的问题:
Combinatorial logic uses assign
or is contained in always @*
this is continuously evaluated and all runs in parallel think AND, OR, NOR gates.
组合逻辑使用分配或包含在总是@*这是连续的评估,所有的运行在并行思考和,或,或盖茨。
Sequential logic will be contained in an always @( posedge clk )
this is executed on every positive edge of the clock. The registers or memory elements used inside of this typically represent Flip-Flops.
顺序逻辑将被包含在一个总是@(posedge clk)中,这是在时钟的每一个正边缘上执行的。在此中使用的寄存器或内存元素通常代表触发器。
#1
1
This is poorly written code.You have written it like a computer program. Verilog is a Hardware Description Language - not a programming language. In your case, synthesizer is trying to replicate logic inside the while loop in the case statement.
这是写得不好的代码。你把它写成了电脑程序。Verilog是一种硬件描述语言,而不是一种编程语言。在您的例子中,合成器试图在case语句的while循环中复制逻辑。
- Design the hardware on a piece of paper before translating it to HDL
- 在将其转换为HDL之前,在一张纸上设计硬件。
- Identify the combinational and sequential logic in the design before coding.
- 在编码之前确定设计中的组合和顺序逻辑。
- Think what logic will synthesizer use to realize the logic you have written.
- 想想用什么逻辑合成器来实现你所写的逻辑。
#2
0
Here are some tips:
这里有一些建议:
- Remove the latches:
-
c[5:1]
is a latch because it is not initialized in theif(a==5'b10000)
branch. - c[5:1]是一个门闩,因为它在if(a==5'b10000)分支中没有初始化。
-
d
is not defined inif(a==5'b10000)
and could be a potential latch depending on the synthesizer optimization capabilities. - 如果(a==5'b10000),则d没有定义,并且根据合成器的优化能力,它可能是一个潜在的锁存器。
-
e
is not defined inif(b==5'b10000)
and could be a potential latch liked
. - e不是在if(b==5'b10000)中定义的,也可能是像d那样的潜在锁存。
- At the beginning of the always block, make sure all the combination logic have initial values.
- 在总是块的开头,确保所有组合逻辑都有初始值。
-
- 删除门闩:c[5:1]是一个锁存器,因为它在if(a==5'b10000)分支中没有初始化。如果(a==5'b10000),则d没有定义,并且根据合成器的优化能力,它可能是一个潜在的锁存器。e不是在if(b==5'b10000)中定义的,并且可能是像d那样的潜在的锁存。在总是块的开头,确保所有组合逻辑都有初始值。
- Try to avoid using
disable
for code to be synthesized. Use if-else statements instead.- Note: This is a guideline not a rule.
- 注意:这是一个指导原则,而不是规则。
- 尽量避免使用禁用的代码来合成。使用if - else语句。注意:这是一个指导原则,而不是规则。
- There is lot of redundant and poorly organized code:
- All branches with in the case statement are the same. Should be cleaned up in consolidated.
- 在case语句中所有的分支都是相同的。应该在合并中清理。
- There is code inside the while loop that is better suited outside the loop (e.g. the
if(count*==3'b101)
block) - 在while循环中有代码更适合于外部循环(例如if(count*==3'b101))
- 有很多冗余和组织混乱的代码:在case语句中所有的分支都是相同的。应该在合并中清理。在while循环中有代码更适合于外部循环(例如if(count*==3'b101))
- If the
while
loop is having problems, try afor
loop. - 如果while循环出现问题,请尝试for循环。
#3
0
While
loops tend to imply something dynamic, like checking a condition. This is not a good use of verilog intended for synthesis. For
loops which can be statically unrolled are more commonly used to shorten the written code.
While循环往往意味着一些动态的东西,比如检查一个条件。这不是用于合成的verilog的良好使用。对于可以静态展开的循环,更常用的方法是缩短编写的代码。
If you need some thing more dynamic a dedicated state machine should be written.
如果您需要一些更动态的东西,就应该编写一个专用的状态机。
To answer some of the questions raised in the comments:
来回答一些在评论中提出的问题:
Combinatorial logic uses assign
or is contained in always @*
this is continuously evaluated and all runs in parallel think AND, OR, NOR gates.
组合逻辑使用分配或包含在总是@*这是连续的评估,所有的运行在并行思考和,或,或盖茨。
Sequential logic will be contained in an always @( posedge clk )
this is executed on every positive edge of the clock. The registers or memory elements used inside of this typically represent Flip-Flops.
顺序逻辑将被包含在一个总是@(posedge clk)中,这是在时钟的每一个正边缘上执行的。在此中使用的寄存器或内存元素通常代表触发器。