• 0

Frequency divider in SystemVerilog


Go to solution Solved by [email protected],

Question

Hello, there

I have written a frequency divider.sv with SystemVerilog. But I have a problem about it.

I use the following code to instantiate a two-level divider:
 

    divider CLK_DIV_1 (
        .clk    (clk),
        .rst    (rst),
        .n      (32'd100000000),
        .clkout (clk_0)
    );    

    divider CLK_DIV_2 (
        .clk    (clk_0),
        .rst    (rst),
        .n      (32'd4),
        .clkout (clk_1)
    );

The clk is 100MHZ, its period is 10ns. So the clk_0's period is 1s, and the clk_0's period is 4s. Then I connected clk_0 and clk_1 to two led lights to observe the result. Clk_0 is correct, but clk_1 is wrong.

However, I simply modified the code to look like this:

`timescale 1ns / 1ps

module divider (
    input logic rst,
    input logic clk,
    input logic [31:0] n,
    output logic clkout
    );

    logic[31:0] q;
    
    always_ff @(posedge clk, posedge rst) begin
        if (rst)
            q <= 0;
        else if (q >= n - 1)
            q <= 0;
        else
            q <= q + 1'b1;
        clkout <= (q < (n>>1));
    end
    
//    assign clkout = (q < (n>>1));

endmodule

The problem disappears. The difference between the two codes is whether the clkout signal uses combinatorial logic or sequential logic. I don't know what effect this will have. Can someone tell me?

PS: I am using Vivado 2018.2 and Nexys4DDR.

Thanks.

Edited by Shaw
Link to post
Share on other sites

8 answers to this question

Recommended Posts

  • 0
  • Solution

@Shaw,

A common beginner mistake is to attempt to create a clock within logic, and then to transition on edges of that clock.  You've just discovered one of the reasons why that's bad.

  1. If A is created from combinatorial logic, then it may glitch before it settles.  If something depends upon the edge of signal A, some things will transition, others won't, and the design will not be reliable.
  2. Suppose you create B from sequential logic, you still have troubles.  A) Vivado can't tell it's frequency, so it can't tell if the logic dependent upon it is still valid, B ) There will be a delay between the original clock signal and the new one, limiting the ability of signals to cross from the first clock domain to the second, C) The new signal won't be using any of the dedicated circuitry within the FPGA.

If you need to slow something down, this is not the way to do it.  Let me offer two better approaches, a fractional approach and an integer divider approach.  Here's the fractional divider,

module fractionaldivider(i_clk, i_step, o_stb);
	input wire i_clk;
	input wire [31:0] i_step;
	output	reg	o_stb;

	reg	[31:0]	counter;
	always @(posedge i_clk)
		{ o_stb, counter } <= counter + i_step;

endmodule

And the integer divider,

module integer_divider(i_clk, i_div, o_stb);
	input	wire	i_clk;
	input	wire	[31:0]	i_div;
	output	reg		o_stb;

	reg	[31:0]	counter;
	always @(posedge i_clk)
	if (counter == 0)
		counter <= i_div;
	else
		counter <= counter - 1;

	always @(posedge i_clk)
   		o_stb <= (counter == 1);
        
endmodule
        

Note that neither example produces a clock signal.  Instead they produce a strobe signal.  You can use this to control your timing as part of a "clock-enable" structure--basically a big if statement that controls all of your logic, such as ...

	always @(posedge clk)
	if (stb)
	begin
		// Your slow logic would go here
	end

You can read more about these techniques here, some rules to help you avoid this type of mistake here, and more about pipeline signaling here.

Dan

Link to post
Share on other sites
  • 0
1 hour ago, [email protected] said:

A common beginner mistake is to attempt to create a clock within logic, and then to transition on edges of that clock.  You've just discovered one of the reasons why that's bad.

Well you've just discovered a few of the reasons why this is a bad idea. Aside from the ones that Dan mentioned there are plenty more.

Having said that, there is a case for creating signals that are used as edge-triggered clocks by external devices on IO pins. For low speed interfaces like I2C, SPI, etc this is fine. You do have to make sure that the positioning of the clock edge used by the external device ( rising or falling )  has a large enough window on either side of the imaginary edge transition where the data is not allowed to change states to account for all manner of slop which includes, among other things, place and route timing delays (which you should expect to vary from build to build), varying delays due to the logic that creates your data, etc. In this case Vivado is totally unaware that your 'clock' signal is a clock. Dan is correct that Vivado and the FPGA devices that it works with assume that clock signals are special and not the same as other signals in a design. All of the timing analysis and steps in synthesis and place and route depend on this assumption. As you should suspect doing this only works well for SDR data interfaces and clock periods that are much much longer than the total of all delays that could be encountered in creating the signals ( the actual analysis is a bit more complicated than that...). Some external devices might be sensitive to jitter and even at low clock rates render this technique unusable. Also, if this isn't clear from what I've said so far, you can't used these signals internally to the FPGA.

For high speed interfaces you need to play according to the rules and make sure that all clocks are sourced by an external high quality clock module, or derived from one using one of the available clock modules that all FPGA devices now have. This is because there just isn't enough control over delays to account for the worst case variations in when signals transition relative to each other for even simple logic implementations.

I'm assuming that you've made a bigger and more common beginners' mistake by not reading the Xilinx literature and understanding FPGA architecture and resources or how the tools work. Assumptions are deadly in FPGA design and development. Vivado will not fix your mistakes in either conception or logic so you need to have a good understanding of all of that before writing your first module.

I'm curious, why did you decided on SystemVerilog as your HDL rather than one of the 'older' standbys like Verilog?

Edited by zygot
Link to post
Share on other sites
  • 0

Yes, see above...

in one line: don't mess with clock signals, use one single clock for your design (for a start). Divide and debug information signals, not clock signals.

Unfortunately, a lot of textbooks and online material are misleading for FPGA. Same for hacker forums that make "complex things simple" 🙂

Link to post
Share on other sites
  • 0

Hi,

you can find one possible answer from your course book on page 88 ("Glitches"), as seen on Google books preview.

"So far we have discussed the case where a single input transition causes a single output transition. However, it is possible that a single input transition can cause multiple output transitions"... the short path... the critical path.

This is the problematic combinational expression in the first example

assign clkout = (q < (n>>1));

and registering it using <= avoids the issue, since the downstream signal is free of combinational logic (consider this digital forensics, not design advice, there's more to it in reality e.g. see Vivado's DONT_TOUCH attribute).

 

Link to post
Share on other sites
  • 0
14 hours ago, Shaw said:

we are using the book Digital Design and Computer Architecture

So @Shaw, forgive me if the following commentary seems like a lecture; it's just some hastily collected random thoughts that seem to be relevant. Since I have no idea what the goals for your course are these thoughts are not particularly directed to your situation.... more so for any beginners, not taking a formal course, who happen to read them. 

I understand how difficult it is to construct a stand-alone course and present material that is relevant to current technology and has a depth that is useful. More decades than I care to admit I took an undergrad course in digital design that was mostly just the basics of logic design concepts and reducing complicated logic expressions to minimal form. Nothing wrong with that as an introduction to the material. There was no mention of actual LSI or MSI logic devices that existed at the time, or even a hint about analysing real physical phenomena  in the coursework. Again nothing wrong with that, except for anyone finding themselves doing this as a profession. In those days companies had a commitment for training young engineer hires and provided mentors to help guide them for the real education. This is how I learned digital design, from doing, from example, from critical reviews of my work and from expectations that I provide proper analysis of why I thought that my work was worth integrating into a project. I suspect that those days are long gone for most engineering graduates. Again, I understand that introductory coursework can't replace actual training for creating marketable skill in most technical fields. These days almost no one uses those LSI and MSI components to do logic design; we have much more flexible options in the form of programmable logic devices. Most of the concepts that I learned in my digital design course were not needed, to a large extent, in my education on designing real circuits with real components on real materials for real environmental conditions. Even more so since FPGA devices became normative. Still, that one course in logic design might have been a bit more realistic in terms of doing actual digital design. This bring me to what I'm trying to say. I suspect that most readers of this user forum are trying to learn this stuff for themselves, with or without a few text books for guidance. I suspect that very few even consider getting a text on digital design because FPGA is generally presented as a software development enterprise. I learned quite a lot from poring over the few good application notes and texts offered by logic vendors, particularly emitter coupled logic, but if you don't have the old paper versions these tomes are long gone ( along with the devices ) or at least very hard to come by in a different form. Since the FPGA has become the de facto platform for digital logic design the distance between those basic logic concepts in the course I took to what's needed to be competent has widened significantly. Now, in spite of the fact that all those physical boolean logic devices have been replaced by look-up tables I have a significant advantage in being able to use those FPGAs than someone starting from the same position that I was when I got my first job because of years of training, from sources that no longer exist for the most part.

The FPGA newbie ( including anyone taking an introductory course in logic design ? ) has a few obstacles to overcome:

  • The perception that FPGA design involves learning a "digital design language" like VHDL or Verilog and that using them is just like using a software language like C or Rust.. or worse that it can be done using a GUI and cans of IP.
  • The perception that FPGA design doesn't require the same kinds of analysis and understanding of digital design basics and real device physics that I had to learn on the job.
  • The perception that digital design with FPGAs is independent from the actual architecture, resources, and development tools that vendors provide in order to implement a design.

Fortunately, Xilinx does offer a lot of information that can help with using the devices, tool, design source flows such as HDLs. For those taking introductory courses I hope that they are at least introduced to the complexities of devices and tools beyond simply writing "code" modules illustrating a few basic concepts. It's easy to get a badly simplistic view of digital design without some knowledge of the details. For anyone trying to learn this for themselves, without a supporting group, your workload is heavy. The beginning starts with the material offered in the Xilinx Document Navigator in the form of user's manuals, reference manuals, application notes, and more. Without a good foundation in designing logic for devices and technology used in the '80s grasping, even finding, the necessary basic concepts will be hard work.

I realize that there is a broad spectrum of people who want to use FPGA devices, from those who need to have a good understanding of everything to those who simply want to treat the FPGA as a black box; so I can't offer guidance to suit everyone. I do feel comfortable suggesting that if you are like most people intending to do substantial FPGA development that you can't afford to ignore any of the components. Learn basic logic design and timing analysis. Learn how to understand the AC and DC data sheet specifications. Learn an HDL in the context of digital design. Learn the vendors tool flows. Learn the device architectures and limitation. There is no deadline. There is no finish line. There's just training and retraining. To borrow from a quote I recently ran across attributed to Mark Twain; "Don't let schooling get in the way of your education".

Edited by zygot
Link to post
Share on other sites
  • 0

As my previous post was getting a bit long-winded... I hastily cut it short forgetting the most important part of any introductory course in modern digital design or for that matter any self-guided journey into the subject. That would be verification, and at the least include some exploration of simulation and writing effective testbench code. Verification is really part of the design process but is complex enough to deserve it's own special discussion. 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now