Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Vivado RTL Development
- :
- Design Entry
- :
- Re: verilog

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted
##

sum@

Contributor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

05-22-2019 04:15 AM

593 Views

Registered:
02-06-2019

verilog

tten the following code but i get an error as 2000 iterrations not allowed. The code is shown below

`timescale 1ns / 1ps

module top (clk, rst, sig_in, pwm_out);

input clk, rst, sig_in;

output pwm_out;

reg pwm_out;

reg enable, start;

reg [6:0] count, cx1, cx2, cx3, cy1, cy2, cy3, c1, c2, c3;

always @ (posedge clk)

begin

if(rst)

enable <= 1'b0;

else

enable <= 1'b1;

end

always @ (posedge sig_in)

begin

if(rst)

start <= 1'b0;

else if(enable)

begin

if(count == 5'b00000)

begin

while(sig_in == 1'b1)

begin

cx1 <= cx1 + 1'b1;

end

while(sig_in == 1'b0)

begin

cy1 <= cy1 + 1'b1;

end

count <= count + 1'b1;

end

else if(count == 5'b00001)

begin

while(sig_in == 1'b1)

begin

cx2 <= cx2 + 1'b1;

end

while(sig_in == 1'b0)

begin

cy2 <= cy2 + 1'b1;

end

count <= count + 1'b1;

end

else if(count == 5'b00010)

begin

while(sig_in == 1'b1)

begin

cx3 <= cx3 + 1'b1;

end

while(sig_in == 1'b0)

begin

cy3 <= cy3 + 1'b1;

end

if(cx1 > cx2 & cx1 > cx3)

begin

cx1 <= 5'b00000;

cy1 <= 5'b00000;

cx2 <= 5'b00000;

cy2 <= 5'b00000;

cx3 <= 5'b00000;

cy3 <= 5'b00000;

start <= 1'b1;

count <= 5'b00000;

end

else

count <= count + 1'b1;

end

else if(count == 5'b00011)

begin

if(cx2 > cx1 & cx2 > cx3)

begin

/* while(dummy <= (cx1 + cy1))

begin

dummy <= dummy + 1'b1;

end*/

cx1 <= 5'b00000;

cy1 <= 5'b00000;

cx2 <= 5'b00000;

cy2 <= 5'b00000;

cx3 <= 5'b00000;

cy3 <= 5'b00000;

start <= 1'b1;

count <= 5'b00000;

end

else

count <= count + 1'b1;

end

else

begin

/* while(dummy <= (cx1 + cy1 + cx2 + cy2))

begin

dummy <= dummy + 1'b1;

end*/

cx1 <= 5'b00000;

cy1 <= 5'b00000;

cx2 <= 5'b00000;

cy2 <= 5'b00000;

cx3 <= 5'b00000;

cy3 <= 5'b00000;

start <= 1'b1;

count <= 5'b00000;

end

end

end

always @ (posedge sig_in)

begin

if(rst)

pwm_out <= 1'b0;

else if(start == 1'b1)

begin

if(c1 == 5'b00000)

begin

while(sig_in == 1'b1)

begin

c1 <= c1 + 1'b1;

pwm_out <= 1'b1;

end

while(sig_in == 1'b0)

begin

c1 <= c1 + 1'b1;

pwm_out <= 1'b1;

end

end

else if(c2 == 5'b00000)

begin

while(c2 <= (c1/2))

begin

c2 <= c2 + 1'b1;

pwm_out <= 1'b1;

end

while(c2 <= c1)

begin

c2 <= c2 + 1'b1;

pwm_out <= 1'b0;

end

end

else if(c3 == 5'b00000)

begin

while(c3 <= c1)

begin

c3 <= c3 + 1'b1;

pwm_out <= 1'b0;

end

c1 <= 5'b00000;

c2 <= 5'b00000;

c3 <= 5'b00000;

end

end

end

endmodule

testbench

`timescale 1ns / 1ps

module tb_top();

reg clk, rst, sig_in;

reg [6:0] ct1, ct2, ct3;

wire pwm_out;

top dut(clk, rst, sig_in, pwm_out);

initial clk = 1'b1;

always #10 clk = ~clk;

initial

begin

rst = 1'b1;

#1000 rst = 1'b0;

end

initial sig_in = 1'b0;

always #10

begin

if(ct1 != 5'b10000)

begin

if(ct1 < 5'b01000)

sig_in <= 1'b1;

else

sig_in <= 1'b0;

ct1 <= ct1+1;

end

else if(ct1 == 5'b10000 & ct2 != 5'b10000)

begin

if(ct2 < 5'b00100)

sig_in <= 1'b1;

else

sig_in <= 1'b0;

ct2 <= ct2+1;

end

else if(ct1 == 5'b10000 & ct2 == 5'b10000 & ct3 != 5'b10000)

begin

if(ct3 < 5'b00010)

sig_in <= 1'b1;

else

sig_in <= 1'b0;

ct3 <= ct3 + 1'b1;

/* if(ct3 == 5'b10000)

begin

ct1<=5'b00000;

ct2<=5'b00000;

ct3<=5'b00000;

end*/

end

else begin

ct1<=5'b00000;

ct2<=5'b00000;

ct3<=5'b00000;

end

end

endmodule

2 Replies

Highlighted
##

betontalpfa

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

05-22-2019 05:56 AM

570 Views

Registered:
10-12-2018

Hi sum@

First of all please write better questions, be as minimal as possible, format your code. It is hard to find the root of the problem. Read this guide.

Use only **synchronous processes**, and use **only synthetisable construct** in your design. (Non synthetisable construct wont be compiled to HW :).

**Concrete:**

**Dont use: sig_in as clock**:

//... always @ (posedge sig_in) begin if(rst) //...

Use edge detector instead.

**Dont use while loop inside an always block**

(this is what cause the hanging of the simulation)

//...

always @ (posedge sig_in) begin if(rst) start <= 1'b0; else if(enable) begin if(count == 5'b00000) beginwhile(sig_in == 1'b1) begin cx1 <= cx1 + 1'b1; endwhile(sig_in == 1'b0) begin cy1 <= cy1 + 1'b1; end count <= count + 1'b1; end

//...

The problem is that the simulator cannot leave that while loop, because sig_in will never go to '0'.

Highlighted
##

u4223374

Advisor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

05-22-2019 06:38 AM

560 Views

Registered:
04-26-2015

I fully agree with @betontalpfa on all points.

The key thing to understand is that everything inside a block happens in effectively zero time. This is not a microcontroller where you can use "while" as a delay loop. When using blocking assignment, Vivado will try to act as if the operations happen sequentially - but really they're all being computed simultaneously. As a result, if sig_in == 1 when this block triggers (which it will be, because the block is triggered on the rising edge of sig_in) then that 'while" loop is going to run once, taking zero time. sig_in is still 1 (because zero time has passed), so the loop runs again. And again. And again. And again. And it would go on for infinite times, except that the simulator stops it.

Related to that, the second "while" loop can never trigger. Everything in this block runs in zero time. sig_in == 1 when the block starts, and so sig_in will always be 1 when the block is running. It can never be zero inside this block.

As a general rule, "while" loops are a bad idea in HDL. Vivado/ISE will fully unroll every loop they find, because that's the only way to make all the logic run simultaneously. With a "for" loop, this normally isn't a problem - the loop has a fixed number of iterations, and Vivado builds that many instances of the loop hardware. With a "while" loop, how many instances should it build? One? Ten? Ten Million?