Jump to content
  • 0

Basys 3. Clock that works alone to build a counter.


Jess

Question

Hello, i am trying to make a 4 bit counter that works with flipflops in VHDL. Now i have an issue related to how to make the code for the clock. I know It has to do with the oscillator in the basys and a frequency divider but i don't know how to unite thé code with the board. So, I really need help. 

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

@D@n 

2 minutes ago, D@n said:

@Jess,

You don't need to create the "code for the clock" in hardware.  It's an external clock.  It already exists coming into your design.  You just need to bring it into your design and use it.

Dan

 Thank you so much for answering

Okay, but, how do I use it ? I make the frequency divider and then how do I tell the basys that I need the external clock? Could you give me an example? I seriously need it.

Link to comment
Share on other sites

@Jess,

Here's my example for how to make a frequency divider.  Yeah, I know its Verilog.  The same principles apply for VHDL, although the syntax will be different.  Remember: Nothing other than a bonafide clock should be in the rising_edge section of a process.

In my design, I have inputs to the design from the external world.  i_clk is always one such input.  The XDC has a clk input that I rename i_clk.  These two files (my design and the XDC) then match, and so I get the clock at the rate it comes into the board.

Be careful not to adjust the frequency yourself.  Use a PLL, MMCM, or other.  Making your own clock is a class/common beginner mistake--so common that I have to wonder if the text books aren't teaching things wrong.  Another classic mistake is to try to "create a clock" from scratch using syntax that can't be implemented.  That doesn't work either.  The clock coming into your design must have the same name as the one in your XDC file.  I'd also recommend integer clock division with a clock-enable signal, but that's what the link above describes.

Dan

Link to comment
Share on other sites

@D@n

Thank you for that, but, the thing is, I don't really know how to write a code in VHDL. It is a school proyect and we are not really taught VHDL properly. This is what i've got so far. 

this for the clock divider

image.png.896ba8f39108da811c91190be9029278.png

this for the flip flop

image.png.d54df330ae79b9cb72119a4ede0c8a2d.png

and I am stuck with the counter 

image.png.4578cc9155ad0da457037c316464a9c4.png

image.png.b0feba35449d014eaa3bd4d8e9f5e3a6.png

I want to call the flip flop, but i dont know what is wrong

I want them all to share the clock divider, but i dont know how

I don't even know if the flip flop actually needs the clock.

If you could help me correct this i would be extremely grateful.

image.png

Link to comment
Share on other sites

@Jess,

While I've done VHDL before, it's really not my strong suit so I'd love to see some VHDL designers step in at this point.

That said, you should never need to instantiate a flip-flop (FF) on your own.  The tools should "just do it" for you.  In particular, your code snippet (below) does exactly this:

divisor : process(elclock)
  variable div_cont : integer := 0;
begin
  if (rising_edge(elclock)) then
    if (div_cont = max) then
      temporal <= not temporal;
      div_cont := 0;
    else
      div_cont := div_cont + 1;
    end if;
  end if;
end process divisor;

Both div_cont and temporal will be implemented with FF's.

That said, I'm not familiar enough with VHDL to catch the subtleties here.  For example, I've never seen something set *after* the end of the if (rising_edge(clock)) block but still within the process.  This might be a bad thing, or might not, I'm not sure.

The other thing to be aware of is that in spite of its name s_clock *IS* *NOT* *A* *CLOCK* *SIGNAL*!  Sorry for yelling so loud, but I feel like a broken record when discussing this--it seems like every new HDL designer tries to use something like this to make a clock.  Do not use s_clock like a c,lock.  It is not a clock.  It is a logic generated signal.  Most FPGAs have dedicated clock logic, both PLLs and MMCMs as well as special clock buffers and routing networks, used to handle clocks.  Logic generated "clocks", like this one, don't get access to this special purpose hardware.  As a result, you are often queuing up for yourself a disaster when your code actually meets real hardware.

The problem specifically comes to play when you try to do something like:

broken: process (s_clock)
begin
  if (rising_edge(s_clock)) then
    // Your design is now broken
  end if
end process

The correct way to do this is to use some form of clock enable signal, such as,

divisor : process(elclock)
  variable div_cont : integer := 0; // This should probably also be limited in width
begin
  if (rising_edge(elclock))
    if (div_cont = max-1) then
      ce := 1;
      div_cont := 0;
    else
      ce := 0;
      div_cont := div_cont + 1;
    end if;
  end if;
end process;

process (elclock)
begin
  if (rising_edge(elclock)) then
    if (ce) then
      // Now you can put your rate limited logic here
      // ... without worrying (as much) about simulation
      // vs synthesis bugs, or the synthesis tool doing
      // something unexpected
    end if;
  end if;
end process;

That said, nothing prevents you from calling s_clock a clock or outputting it on an output pin to examine with a scope.  It's just that, using it's rising edge within your design will cause problems.

Also, my apologies to all of the real VHDL designer out there for bugs I might be missing, but this is the basic concept of what you need to do.

Finally, don't forget to make sure the name elclock matches the name of the incoming clock within your XDC file.  It should be on the same pin that a hardware-clock comes in on.

Dan

Link to comment
Share on other sites

Archived

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

×
×
  • Create New...