Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Xilinx Spartan 6 - Use PLL to create 1 MHz clock

Status
Not open for further replies.

pigtwo

Member level 4
Joined
Jul 16, 2015
Messages
70
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
2,771
Hello all,

I'm working on a project where I have a 50 MHz clock and one module would like to run at 1 MHz. I've done this conversion with Altera FPGAs before by using a PLL. So I attempted this with ISE's CORE Generator but I'm running into a problem. I found 'clocking wizard' in the catalog but no direct PLL. So I attempted to use the clocking wizard to create the desired frequency but it appears that it cannot create a frequency less than 4.687 MHz. I did a little research and found the PLL could multiple and divide by integers 1 to 128. So I don't see where the limitation is as my M could be 1 and my D could be 50 which does not exceed the PLL specs. It seems weird that the minimum frequency of a PLL is as high as 4.687 MHz but I'm not very experienced so maybe I just don't know about these things.

I feel like I'm missing something or I am looking in the wrong place. I looked around the CORE Generator and I didn't not find a stand alone PLL so I assumed that I had to use the clocking wizard but maybe I'm wrong here. Does anyone know what I'm missing? Maybe I should call the primitive directly?

Thank you,
Dylan
 

Hi,

The VCO of the PLL has a limited frequency range. I don't know it's specifications now, but it's possible, that it can't generate 1MHz directely.

It's usual to generate higher frequency clocks with the PLL.

But the solution is simple:
Just use the higher frequency clock.
If it is 50MHz then use a counter 0...24 and with every synchronous counter_reset toggle your clock signal.

Klaus
 

It seems weird that the minimum frequency of a PLL is as high as 4.687 MHz but I'm not very experienced so maybe I just don't know about these things.
That's correct, as I also see it!

But the other option is also easy, as KlausST has mentioned above.
But the solution is simple:
Just use the higher frequency clock.
If it is 50MHz then use a counter 0...24 and with every synchronous counter_reset toggle your clock signal.

If I were you, I would use a counter to generate a clock enable signal, keep the 50MHz as the system clock and feed these two signals to the logic.
 

That makes sense and I've used counters in this way before but I've been told that you shouldn't use logic to drive clocks(at least not directly). I'm guessing there's some primitive that can take a signal and make it a global clock. My first thought would be send the generated 1 MHz signal through a DCM(by using the clocking wizard) and not change the frequency/phase/etc and this should handle routing the 1 MHz signal to the appropriate clocking fabric(name?).
 

There is a well documented restriction on the VCO frequency range and the input clock has to first be multiplied up to the VCO's frequency range first before being divided down with counters to the lower frequency.

So in the case of your 50 MHz input being divided down to 3.125 you first have a feedback multiplication of 8 (M/D = 8/1) followed by a counter divide down of 128. i.e 50M * 8/128 = 3.125M. (see page 99 of ug382 and page 56 of ds162) The PLL minimum VCO frequency is 400 MHz and the maximum depends on speed grade is between 1080 MHz and 1000 MHz.

- - - Updated - - -

That makes sense and I've used counters in this way before but I've been told that you shouldn't use logic to drive clocks(at least not directly). I'm guessing there's some primitive that can take a signal and make it a global clock. My first thought would be send the generated 1 MHz signal through a DCM(by using the clocking wizard) and not change the frequency/phase/etc and this should handle routing the 1 MHz signal to the appropriate clocking fabric(name?).

You don't use the counter as a clock you use the counter to generate an enable the logic still gets clocked with the 50 MHz it only gets enabled at 1 MHz.

Also the DCM has even worse frequency restrictions and can only give you very rudimentary frequency ratios like 2x, 1x, and very limited divide ratios. I checked and it can only get down to 5 MHz no matter what you put in as a clock.

- - - Updated - - -

Also the PLL_ADV can be directly selected (not recommended) in the GUI by disabling the Auto Selection Mode on the first panel and instead selecting Manual Selection. You then get the option of selecting the specific clock management component. Which is the PLL that gives you the 50 MHz to 3.125 MHz you already saw.
 
  • Like
Reactions: pigtwo

    pigtwo

    Points: 2
    Helpful Answer Positive Rating
Ah ok, I guess this is the first time I've run into these limitations. So in general with PLLs the lowest output frequency I can get is the minimum VCO frequency(in this case 400 MHz) divided the largest division possible(in this case 128, thus leading to the 3.125 MHz). For some reason I was getting 4.687 MHz as the lowest frequency but I'm guessing the input clock was multiplied to 600 MHz for some reason.

You don't use the counter as a clock you use the counter to generate an enable the logic still gets clocked with the 50 MHz it only gets enabled at 1 MHz.
I see that I misunderstood dpaul and KlausST. I'm a little confused about this works. Is the below code the basic idea?

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module test(
        input CLOCK_50
        );
    
    reg[4:0] counter;
    wire tick_1MHz;
    reg data, data_next;
    
    assign tick_1MHz = (counter == 24);
    
    always @(posedge CLOCK_50)
    begin
        counter <= (counter == 24) ? 0 : counter + 1;
        if(tick_1MHz)
        begin
            data <= data_next;
        end
    end
    
endmodule



Thank you!
 

yes, like that, but you might want to decode for a count of 49 to divide down to 1 MHz instead of 24 which results in 2 MHz (you aren't trying to produce a toggling clock at the 1 MHz rate you want pulses that are at 1 MHz rate.

I would also consider using a FF and decode a count of 48 so it will occur on a clock edge giving you maximum setup time (this might not be necessary if you don't have much logic using the enable.
 

I must have had 24 stuck in my head for some reason. That makes sense. So the final basic example would look like this:

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module test(
        input CLOCK_50
        );
    
    reg[5:0] counter;
    reg tick_1MHz;
    reg data, data_next;
    
    always @(posedge CLOCK_50)
    begin
        tick_1MHz <= (counter == 48);
        counter <= (counter == 49) ? 0 : counter + 1;
        if(tick_1MHz)
        begin
            data <= data_next;
        end
    end
    
endmodule



Thanks for all the help!
 

Hi,

What's your goal?

If you really want to create a 1MHz (clock) signal, then you need to count 0...24.

If you want a function to be processed 1 million times per second, then count 0..49.

Klaus
 

So how this came about this is I wrote a simple module that reads data from an ADC over SPI. The SPI interface max frequency is about 1 MHz but the only available clock in the system is 50 MHz. I decided to make the whole module run at 1 MHz for simplicity and to practice making a cross clock domain solution.

I understand what you suggest (counting to 24 then toggling) but I don't know how to turn this signal into a real clock(IE one routed to the global clock network). So I started going down the path that dpaul and ads-ee recommend as it seems to avoid this problem. The only problem with this is that I do eventually need a real clock for the SPI interface but imagine it should be simple enough. Something like this maybe:

Code Verilog - [expand]
1
assign clock_1 = (counter > 24);


And since this only drives one pin I would guess it should be fine.

I'm really only doing this to learn so I am interested in the way you describe. How do I turn a signal into a clock? I was reading through the primitives available but nothing stuck out to me. Maybe I just configure it some where in ISE?

Thank you!
 

Hi,

There is no problem in generating a clock signal for external periferals.
For SPI you need two internal enable signals (one at rising SPI_clock edge and one at falling SPI clock edge)
AND you need the 1MHz external square wave SPI_clock signal.
--> Then you need to count 0..49..
* compare with "0" and generate an internal "SPI_cr" enable signal. SET SPI_clock.
* compare with "25" and generate an internal "SPI_cf" enable signal. CLEAR SPI_clock.
(Cr = clock rising, cf = clock falling)
...
Why two internal enable signals?
Because with SPI you output data at one SPI_clock edge (= update MOSI)
And you input data at the opposite SPI_clock edge ( = read MISO)

There is no need to route SPI_clock to global network. Global clock network is used to spread a clock signal to the complete FPGA area so it is available anywhere on the chip with high timing precision.
But again: You don't need this 1MHz square wave inside your FPGA.
Just treat it (internally) as a standard data signal. To avoid glitches .. it should be the output of a flipflop, not the output of combinatorial logic.
If you need some "combinatorial" then do this at the FF input.

Klaus
 

I decided to make the whole module run at 1 MHz for simplicity and to practice making a cross clock domain solution.

Possible, but not reasonable. If you want to practice domain crossing logic, you should do it for an application where it's actually required. Consider e.g. a SPI slave module clocked by an external 20 or 50 MHz SCK.

The other point is that the logic generated 1 MHz clock isn't actually asynchronous and don't necessary need domain crossing techniques.
 

I understand what you suggest (counting to 24 then toggling) but I don't know how to turn this signal into a real clock(IE one routed to the global clock network). So I started going down the path that dpaul and ads-ee recommend as it seems to avoid this problem.
As mentioned in #2 and #5 you keep the 50MHz as the only clock, and let the counter generate the signal that will act as the clock enable signal.

This why FvM mentions in #12
The other point is that the logic generated 1 MHz clock isn't actually asynchronous and don't necessary need domain crossing techniques.
You counter will be clocked by the 50MHz clock, so the counter o/p signal (i.e. the clock enable signal) will be sync to the 50MHz clk.

I'm really only doing this to learn so I am interested in the way you describe. How do I turn a signal into a clock? I was reading through the primitives available but nothing stuck out to me. Maybe I just configure it some where in ISE?
You are doing it wrong in #10. A clock will ALWAYS be supplied from an external input port. During simu you will generate a toggling signal in your test-bench that will be connected to your clock input port of your actual design (commonly called DesignUnderTest).

Code:
initial begin
   clk = 0; 
end  

always  
  #5  clk =  ! clk;
 
Last edited:

@KlausST I think that makes sense. I did not know about the two enables and I'm sure that would have tripped me up. The current module I'm working only has MISO so I only have to read from the SPI which makes it easier. I have one more module I need to write for this board and it is an interface to a SPI memory chip so we'll see if I really understand it then.

In this case I understand that the SPI clock doesn't need to be routed to the global clock network because it is only going to the SPI chip. My confusion came from trying to use this clock to clock the entire module which turned out to not be necessary. Just for curiosities sake is there a way to route a signal to the global clock network or does this clock always have to come from outside the chip(into one of the gclk pins)?

@FvM So this wouldn't need cross clock domain techniques because the signal is not asynchronous? Basically because they're in phase the faster side would be able to know exactly when data was coming in? Until now I thought crossing clock domains happened anytime data was transferred across domains with different frequency clocks(even if generated from the same clock).

@dpaul That makes more sense.
A clock will ALWAYS be supplied from an external input port.
When you say from an external input port, is that external to the module or to the FPGA itself?

Thank you everyone for the replies, I understand at least a little better and I was able to get the module to work. Just for reference below is what I came up with. It does work but I'm sure I'm doing stuff kind of weird as it's the first time I've used clock enables.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
module ADC_SPI(
        // Basic signals
        input CLOCK_50,
        input RESET,
        
        // ADC signals
        input ADC_SDO,    // Serial data from ADC
        output SCLK_ADC,
        output CS_ADC,
        
        // Output signals
        output[7:0] LEDOUT
    );
 
    // Create 1MHz clock
    reg clock_1;
 
    // Define internal registers
    reg cs, cs_next, tick_1MHZ;
    reg[3:0] state, state_next, bit_count, bit_count_next;
    reg[7:0] ledout_temp, ledout_temp_next, ledout_hold, ledout_hold_next;
    reg[5:0] clock_counter;
 
    // Define external connections
    assign SCLK_ADC = clock_1;
    assign CS_ADC = cs;
    assign LEDOUT = ledout_hold;
    
    // Define states
    localparam[3:0]
        Start = 0,
        Idle = 1,
        GetData = 2;    
    
    // Define combinational logic
    always @(posedge CLOCK_50)
    begin
        clock_counter <= ((clock_counter == 49) | (RESET)) ? 0 : clock_counter + 1;
        tick_1MHZ <= (clock_counter == 48);
        clock_1 <= (clock_counter > 24);
        if(tick_1MHZ)
        begin
            if(RESET)
            begin
                cs <= 1'b1;
                state <= Start;
                ledout_temp <= 0;
                ledout_hold <= 0;
                bit_count <= 0;
            end
            else
            begin
                cs <= cs_next;
                state <= state_next;
                ledout_temp <= ledout_temp_next;
                ledout_hold <= ledout_hold_next;
                bit_count <= bit_count_next;
            end
        end
    end
    
    // Define sequential logic
    always @*
    begin
        // Define default transitions
        cs_next = cs;
        state_next = state;
        ledout_temp_next = ledout_temp;
        ledout_hold_next = ledout_hold;
        bit_count_next = bit_count;
        case(state)
            Start:
            begin
                cs_next = 1'b1;
                ledout_temp_next = 0;
                ledout_hold_next = 0;
                bit_count_next = 0;
                state_next = Idle;
            end
            
            Idle:
            begin
                cs_next = 1'b1;
                ledout_hold_next = ledout_temp;
                bit_count_next = 1'b0;
                state_next = GetData;
            end
            
            GetData:
            begin
                cs_next = 1'b0;
                if(bit_count == 12)
                begin
                    state_next = Idle;
                end
                else
                begin
                    bit_count_next = bit_count + 1;
                    ledout_temp_next = {ledout_temp[6:0], ADC_SDO};
                    state_next = GetData;
                end
            end
            
            default: state_next = Start;
        endcase
    end
    
 
endmodule

 

Just for curiosities sake is there a way to route a signal to the global clock network or does this clock always have to come from outside the chip(into one of the gclk pins)?
internal signals can be routed to the global clock resources xBUFx type primitives. The problem is if you use internal logic to generate a clock that you then distribute over the clock buffers you end up with a clock that automatically has to be treated as asynchronous. You will also have to create generated clocks in your constraints file to account for this clock as the tools typically won't add this clock in automatically (i.e. like for a PLL).

pigtwo said:
@FvM So this wouldn't need cross clock domain techniques because the signal is not asynchronous? Basically because they're in phase the faster side would be able to know exactly when data was coming in? Until now I thought crossing clock domains happened anytime data was transferred across domains with different frequency clocks(even if generated from the same clock).
The enable is not asynchronous the launch clock is the same as the destination clocks. The enable is treat like any other D input to a D-FF.
You can have either synchronous or asynchronous transfers from clocks produced by the same input clock depending on the output frequency of the clocks. Output clocks of a single PLL can be considered synchronous if they are an integer multiple of each other. e.g. 50 MHz input clock with 25 MHz and 100 MHz output clocks 1:4 ratio of output clocks.
If the clocks are not in integer multiple of each other then the clocks should be considered asynchronous as they will have many possible rising edge to rising edge relationships.
Capture.PNG

When you say from an external input port, is that external to the module or to the FPGA itself?
I'm sure they meant from an input pin of the FPGA.

Look for ads-ee: comments embedded in the code...
Uh, the first line says combinational logic and you have synchronous logic described below it...if you aren't going to have comments that are correct it is better to have NO comments IMO.

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Define combinational logic
    always @(posedge CLOCK_50)
    begin
        clock_counter <= ((clock_counter == 49) | (RESET)) ? 0 : clock_counter + 1;  // ads-ee: this might not allow the use of the reset pin of a FF and force the reset into a LUT.
        tick_1MHZ <= (clock_counter == 48);
        clock_1 <= (clock_counter > 24);
        if(tick_1MHZ) // ads-ee: The enable should NOT supersede the reset, this is a really bad design decision.
        begin
            if(RESET)
            begin
// bunch of assignments cut out
            end
            else
            begin
// bunch more assignments cut out
            end
        end
    end
    
        // ads-ee: I'm beginning to wonder if you know the difference between a sequential and combinational logic
        // THIS is the combinational logic.
    // Define sequential logic
    always @*
    begin
        // Define default transitions
        cs_next = cs;
                // ......bunch of code cut out.....
            default: state_next = Start;
        endcase
    end
    
 
endmodule



Your enable logic should look like this:

Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
always @ (posedge clk) begin
  if (reset) begin
    // always allow reset regardless of the enable
    // better yet use an asynchronous reset with a synchronous deassertion... adding the posedge reset to the list
  end else if (enable) begin
    // this is the code you are enabling
    if (do_this) begin
      // do someting
    end else if (or_this) begin
      // do someting
    end else if (maybe_this) begin
      // do someting
    end else begin
      // do someting
    end
  end
end



I would also avoid combining the reset with other logic that sets the outputs to 0, like you did for clock_counter. If the reset is coded so it is embedded in with conditions that set the outputs to the reset value the tools are unlikely to have a synthesis template that corresponds to that coding style and therefore the reset will end up being implemented in the LUT instead of utilizing the already existing reset pin of the D-FF primitive.

- - - Updated - - -

Also this is technically incorrect as this is supposed to be a logical expression before the ?.
Code:
((clock_counter == 49) | (RESET)) ? ...
| is the bitwise OR
|| is the logical OR
& is the bitwise AND
&& is the logical AND
~ is the bitwise NOT
! is the logical NOT

I've seen many people use these incorrectly on single bit values. The results for single bit wide values is the same regardless of which you use but is not the same when using multi-bit values. So it is better to use the correct one in the appropriate context, logical for logical expressions and bitwise for boolean operations.

I noticed earlier that dpaul used the wrong one for their example clock code:
dpaul said:
Code:
always  
  #5  clk =  ! clk;
at the time I didn't bother pointing it out, but now that you are doing the same thing, I felt it should be brought up.
 
  • Like
Reactions: pigtwo

    pigtwo

    Points: 2
    Helpful Answer Positive Rating
The only reason to use a PLL here would be to "clean" a
jittery clock source.

Why not just use a /50 divider made from logic blocks?
 

internal signals can be routed to the global clock resources xBUFx type primitives. The problem is if you use internal logic to generate a clock that you then distribute over the clock buffers you end up with a clock that automatically has to be treated as asynchronous. You will also have to create generated clocks in your constraints file to account for this clock as the tools typically won't add this clock in automatically (i.e. like for a PLL).
Ah ok, I've seen those xBUFx primitives a lot but was searching for something with clock in the name. Is the reason the clock that is routed as a global clock asynchronous because the buffering causes some skew and so the relationship between the two clocks is no longer known(IE their edges would no longer line up)? Even though they could be integer multiples?

I'm guessing that the preferred way to clock a module with a slower clock is with a clock enable opposed to routing an internal signal to the clock buffers.

Look for ads-ee: comments embedded in the code...
Uh, the first line says combinational logic and you have synchronous logic described below it...if you aren't going to have comments that are correct it is better to have NO comments IMO.
That was dumb of me, I swear I do know the difference. I must have been in autopilot while writing the comments. Thank you for the comments, I was a little confused about how to reset properly but now that I see the solution it seems obvious. Also, I'm still working on having a clean, consistent coding style and I really like stacking the single word keywords like 'end else begin' opposed to placing each one on its own separate line. I'll have to go through my previous projects and fix it.

Also this is technically incorrect as this is supposed to be a logical expression before the ?.
Code:
((clock_counter == 49) | (RESET)) ? ...
| is the bitwise OR
|| is the logical OR
& is the bitwise AND
&& is the logical AND
~ is the bitwise NOT
! is the logical NOT

I've seen many people use these incorrectly on single bit values. The results for single bit wide values is the same regardless of which you use but is not the same when using multi-bit values. So it is better to use the correct one in the appropriate context, logical for logical expressions and bitwise for boolean operations.

I noticed earlier that dpaul used the wrong one for their example clock code:

at the time I didn't bother pointing it out, but now that you are doing the same thing, I felt it should be brought up.

I am glad to be corrected on things like this. My end goal to try to make my code as professional as possible so mistakes like this bother me.
 

Is the reason the clock that is routed as a global clock asynchronous because the buffering causes some skew and so the relationship between the two clocks is no longer known(IE their edges would no longer line up)? Even though they could be integer multiples?

I'm guessing that the preferred way to clock a module with a slower clock is with a clock enable opposed to routing an internal signal to the clock buffers.

Take a look at the following timing diagram with a synchronous divide by 3 logic generated clock. The skew is a bit exaggerated for say a 50 MHz clock, but that wouldn't be the case at 300 MHz.
Capture.PNG
As you can see the hold time is negative for the slow to fast clock transfer due to both the clock to out delay on the logic generated clock C2_Q1 and the BUFG that it has to go through. This makes it more difficult to meet timing, though the tools can compensate for this if the correct C2_Q1 generated clock constraint is applied, which is not easily done as you need to add constraints for minimum and maximum delay for the Q1 output clock. In the generated clock to the main clock the extra delay means that hold time is the critical timing to meet and unless an excessive amount of delay is added to the data path you may still end up with problems.

Besides the transfer C1 to C2 transfers, the C2 to C1 transfers suffers from a severe reduction in the setup time available due to the delayed C2 clock (combined clock to Q delay and the clock buffer delay).

If the C1 clock is a high speed clock, e.g. 400 MHz (2.5 ns) the clock tree alone may add nearly 2 ns of delay before reaching the FFs in the C2 domain. Add those 2ns with the Tco of the C2_Q1 clock output and you may have hardly any setup time left for a Q2 to C1 transfer to make timing.

Because of these kinds of timing problems it's better to NOT use logic generated clocks, unless you are working with really slow stuff and can afford to do transfers with opposite edge clocking. It's usually much better to use enables instead as they are simple clock to q and the normal setup calculation without having the added complexity of a entirely new clock tree being introduce delaying the destination clock.

pigtwo said:
I am glad to be corrected on things like this. My end goal to try to make my code as professional as possible so mistakes like this bother me.
:) a commendable attitude, that I wish more members would exhibit. Too many are fine with: "It works, so what."

- - - Updated - - -

Also, I'm still working on having a clean, consistent coding style and I really like stacking the single word keywords like 'end else begin' opposed to placing each one on its own separate line.
You might find that quite a few people really dislike that format, though many of them after looking at my code tend to decide that maybe it's not so bad after all. ;-)

I know that some authorities on Verilog insist that having all the extra begin-end pairs everywhere is a bad coding style, but I've come to conclude it removes ambiguity and also avoids the problem with people mixing the two styles and formatting their code so poorly that you can't tell where the blocks of code are. I almost always have to reformat and add all the missing begin-ends in to make the code readable. Besides that if you a developing code then having the begin-end pairs already there if you decide to add another signal into the always block that doesn't have begin-ends then you'll have to add them after the fact (you're source control now shows a bunch more changes, even though all you did was add another signal, ugh! and if you add them on different lines like you were...).
 
  • Like
Reactions: pigtwo

    pigtwo

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top