Jump to content
  • 0

Displaying a random number on 7 segment display using ZYBO


Aditya Gedela

Question

 

My Code is given in the file below...

Error:

Don't know why just after the implementation all the LEDs are getting HIGH without any delay (i.e) all LEDs on the ZYBO board are getting HIGH at once

According to the code, a random number is generated, so it goes into any of above if conditions and the time gap between the generation of new random number and the previous one is around 3 seconds... So there should be some delay (i.e) all LEDs shouldn't be HIGH at once....

And similar error is observed in 7 segment BCD display too.... (i.e) all the 7 segments of BCD are getting HIGH at once just after implementation....

When I tried my code using online testbench (EDA Playground) it displayed a random number with a delay of 3 seconds around but I don't know why in Vivado its not working..  

 

So can anyone please help me out?

 

Thanks in Advance....

Random generator.rtf

 

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

@Aditya Gedela,

Ok, lots of rookie mistakes there, but let's work through the first file you posted:

  1. Please, don't post in RTF format.  Text is fine.  The original verilog is fine as well.  Posting in text might've helped me figure out whatever the difference was between your two files.  (I couldn't figure it out, so ... I'm only commenting on one of them.)
  2. I'm not sure how this code is related to the code you are actually running on your device.  It doesn't look like it would synthesize, and I'd be surprised if Vivado didn't have problems with it.  Did you really get this code to run?  I'm surprised.
  3. always @(clock or reset) is really not what you want to do.  The first problem is that you want to adjust things on the positive edge of the clock.  (Negative edge is also possible, but mixing the two is usually bad, so most designs by convention just use the positive edge.)  This code would have you adjusting things every time the clock changes, and thus on both ends, and it will lead to timing problems.  (You did check for Vivado warnings, right?)  The second problem with that always block is the reset in the condition list.  While asynchronous resets are possible, they are not recommended.  (Fun video about possible, but not recommended ...)  The most startling example of this for me was when I read in Xilinx's documents that a spurious 1ns noise impulse (such as your cell phone might provide, since the board acts like an antenna at that frequency) might trip such an interrupt.  The fix: use a synchronous reset.  Hence, this line should instead read, always @(posedge clock)
  4. This same goes for your always @(clock).  It should instead read always @(posedge clock)
  5. In your second LFSR always block, you are setting count.  I think you meant to set count_next.  This is probably going to result in a violation of ... something or other.

Let me know how that works for you. ... hopefully it will get you closer.

Dan

Link to comment
Share on other sites

Thanks for your reply Sir @D@n

I actually created 2 files. one has random module and other has LFSR module..... The random number is generated in the LFSR module file and the number is assigned to a wire in the end of LFSR code.This LFSR module is called in the random module file in which displaying the random number on the BCD display is done....

Basically, I require the delay for assigning the random number (reg random_done) to output(wire rnd). I tried in several ways but finally worked in this way in the online test bench (EDA Playground) but it is not working in vivado (i.e) I am not getting the expected output.

Here Basically I am not using any internal clock (so I cannot keep any posedge ). I used clock1 to create the delay for clock as when the clock is HIGH then random_next is assigned to random. I am surprised when I tried this code in online test bench(EDA PLAYGROUND) it worked and I am able to generate random number with delay of nearly 3 seconds and even in Vivado bitstream generation was completed but when I programmed the device all LEDs are glowing together HIGH (i.e) all LEDs are HIGH at once...and all 7 segments in the BCD display are showing HIGH ..

I think that random numbers are generating without any delay so that's why I am not able to show output on BCD display...

And I want to know where the output of $display statement is shown in vivado......

 

So Please help me out...

 

Thanks in Advance...

 

Link to comment
Share on other sites

@Aditya Gedela,

So ... one thing you need to know is that the #<number of clocks> command you like to use is .... not synthesizable.  It only works in simulation, and that depends upon the simulation you are using.  Hence, if you ever try to put such a statement into a design that is supposed to run on hardware, it will either ignore it or give you an error.

If you aren't using a clock, .... then you need to be.  What you want to do will not work without a clock.

Dan

Link to comment
Share on other sites

@Aditya Gedela

$display is another one of those non-synthesizable primitives.  You'll want to figure out another way of communicating your answer back.

Incidentally, $display, and the #<#> primitives both work in simulations--and they are often used to create an output display, and to create pretend/simulated clock.  Often, projects will have files with a _tb.v extension, indicating that those files are for simulation only.  These files then contain those primitives that cannot be synthesized, but they use them to direct a simulation--basically in an attempt to create/support non-existent hardware (such as a clock).  (Why is it non-existent?  Because it's a simulation, and there's no real hardware involved.)

Dan

Link to comment
Share on other sites

@D@n

As you already mentioned of using the internal clock in the code which I attached in the file...

Earlier Code:

 initial begin
 clock=0;
    clock1 = 0;
    forever
      #80 clock1 = ~clock1;
    end


Instead of this, I wrote:

initial begin
 clock=0;
    clock1 = 0;
   end

always @(posedge clk)
begin 
clock1=~clock1;
end  

 

But again I am getting the same error after generation of btistream....

(i.e) all LEDs and  all the 7 segments of BCD are getting HIGH at once....

 

Please help me out...

Thanks in Advance....

Link to comment
Share on other sites

@Aditya Gedela,

Let's try something.  Can you add a circuit to your design looking like:

reg	[24:0]	evctr;
always @(clk)
	evctr <= evctr+1'b1;
assign evled = evctr[24];

You have more than one LED, right?  Place this onto one of your LED's.  If this LED blinks, it will prove to you that you have a working clock.  (If your simulator is complaining, add the line "initial evctr=0;" just before the always line.)

From this, we can then look at other signals in your design.  For example, if you'd like to know if "S" is ever getting assigned to zero, you might do something like,

reg [24:0]	sctr;
initial sctr = 0;
always @(posedge i_clk)
	if (S==0)
		sctr <= 0;
	else
		sctr <= sctr + 1'b1;
assign sled = sctr[24];

When you are working with logic at this level, this sort of thing allows you to "see" what's going on.  For example, if sled blinks, then you know your variable S is never getting set to zero.

Dan

Link to comment
Share on other sites

Hi @D@n

I tried in the way you mentioned to check whether the internal clock is working.... It is working and the led is blinking...So there is no problem with the internal clock

 

I added a line to my code in always statement:

always(@ clock1)

led[0]=led[0]+1'b1;

 

and  I ended up with this error while generating btistream:

[DRC 23-20] Rule violation (LUTLP-1) Combinatorial Loop - 1 LUT cells form a combinatorial loop. This can create a race condition. Timing analysis may not be accurate. The preferred resolution is to modify the design to remove combinatorial logic loops. To allow bitstream creation for designs with combinatorial logic loops (not recommended), use this command: set_property SEVERITY {Warning} [get_drc_checks LUTLP-1]. NOTE: When using the Vivado Runs infrastructure (e.g. launch_runs Tcl command), add this command to a .tcl file and add that file as a pre-hook for write_bitstream step for the implementation run. led_OBUF[1]_inst_i_1.

 

I don't understand how to come out of this....

Please help me out....
 

Link to comment
Share on other sites

@Aditya Gedela,

The reason why you are getting an error is because you are using the always @(clock) construct.  This is not a clocked construct.  It's intended to be used for combinatorial logic, and in particular combinatorial logic that depends upon your variable named clock--not on the positive or negative edge of the clock which is what you want.  In your case, you have something that isn't dependent upon the wire you call clock (which is a wire, a net, but not a clock--despite what you've named it) changing when your logic clock is changing. 

What's creating the logic loop is the simple fact that led[0] is being set (without a clock to hold it back) to something based upon led[0].  This is by definition a logical loop.  Xilinx is trying to fit all of these led[0] computations between positive clock edges to know whether or not your design meets its timing requirements, and Vivado can't find any edges.  Worse, it finds a loop, since led[0] depends upon led[0].

You should instead write that as,

always @(posedge clk)
	led[0] <= led[0] + 1'b1;

Notice the "posedge clk".  Use that instead of @(clk).  They mean *very* different things.

However, if you are going to transition an LED on every clock, then be prepared to see an LED that is switching faster than your eye can see.  (It'll be half as bright as if you hadn't switched it.)

One way you can slow your whole design down, similar to what you are doing, would be to do something like,

reg	[24:0]	counter;
initial counter  =0;
always @(posedge clk)
	counter <= counter + 1'b1;

reg	zero_clk;
initial zero_clk = 1'b1;
always @(posedge clk)
	zero_clk <= (counter == {(25){1'b1}} ) // Check if it is all ones

// zero_clk will now be true any time the counter is all zeros

(Notice that all of these always blocks change on the positive edge of the clock--that's very important.)  You could then even change your led[0] line to something more reasonable, such as ...

always @(posedge clk)
	if (zero_clk)
		led[0] <= led[0] + 1'b1;

This would blink the LED at a rate that you could watch it.

So, in general, I think I would counsel you away from using always @(whatever) or the similar always @(*), and towards using always @(posedge clk) ... at least until you understand why clocked logic is so important.  Oh, and remember, don't create your clock from logic on anything other than a test-bench.  A synthesized clock generator generates a poor clock.  Use the clock Digilent gives you for your board, or adjust it via a clock management tile if you must.

Dan

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...