UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Participant sum@
Participant
213 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

Capturesasa.JPG
0 Kudos
2 Replies
Explorer
Explorer
190 Views
Registered: ‎10-12-2018

Re: verilog

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) 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
//...

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

Scholar u4223374
Scholar
180 Views
Registered: ‎04-26-2015

Re: verilog

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?