cancel
Showing results for
Show  only  | Search instead for
Did you mean:
Highlighted
Visitor
5,455 Views
Registered: ‎06-20-2009

## 30 MHz to 20 MHz

Hi,

I would like to turn my 30 MHz 5V clock signal into a 20 MHz 3.3V clock signal using a xc9536.  I figure that I can use a 3.3V VCIO voltage to drive the 20 MHz signal.  I have tried and failed to several net inspired solutions to divide a clock by 1.5.  If anyone has some thoughts on how to do this in verilog on the xc9500 I would surely appreciate it.

DavidBear

Tags (3)
1 Solution

Accepted Solutions
Highlighted
Professor
6,493 Views
Registered: ‎08-14-2007

First, you should realize that your divided clock will have at best a 1/3 or 2/3 duty cycle.

Second, if the duty cycle of the incoming clock is not 50% your divided clock will also

have significant jitter at 1/2 it's frequency, i.e. the clock period of alternating clock

pulses will be different.

For a device like the 9500 series with no DDR registers, you'll need to use both

clock edges by placing some flip-flops on the rising edge and others on the falling

edge and then use combinatorial logic to generate the output.  A method I have used

can be described with flip-flops and NAND gates.  It takes two D flip-flops with

one rising edge triggered and the other falling-edge triggered.  The two Q outputs

are NANDed together and this signal feeds back to both  D inputs.  It also represents

a divide by 1.5 clock.  The individual Q outputs form two divide-by-3 clocks with

no overlap.  To change the output polarity just change the NAND to a NOR.

In Verilog it would look like:

reg FF1, FF2;

wire div_by_1_5;

always @ (posedge clk)  FF1 <= div_by_1_5;

always @ (negedge clk) FF2 <= div_by_1_5;

assign div_by_1_5 = !(FF1 & FF2);

If you want to simulate this you should also have an initial block to

set the startup condition.  I would suggest simulating with diferent

input clock duty cycles to see what you might be in for.

Regards,

Gabor

-- Gabor
3 Replies
Highlighted
Professor
6,494 Views
Registered: ‎08-14-2007

First, you should realize that your divided clock will have at best a 1/3 or 2/3 duty cycle.

Second, if the duty cycle of the incoming clock is not 50% your divided clock will also

have significant jitter at 1/2 it's frequency, i.e. the clock period of alternating clock

pulses will be different.

For a device like the 9500 series with no DDR registers, you'll need to use both

clock edges by placing some flip-flops on the rising edge and others on the falling

edge and then use combinatorial logic to generate the output.  A method I have used

can be described with flip-flops and NAND gates.  It takes two D flip-flops with

one rising edge triggered and the other falling-edge triggered.  The two Q outputs

are NANDed together and this signal feeds back to both  D inputs.  It also represents

a divide by 1.5 clock.  The individual Q outputs form two divide-by-3 clocks with

no overlap.  To change the output polarity just change the NAND to a NOR.

In Verilog it would look like:

reg FF1, FF2;

wire div_by_1_5;

always @ (posedge clk)  FF1 <= div_by_1_5;

always @ (negedge clk) FF2 <= div_by_1_5;

assign div_by_1_5 = !(FF1 & FF2);

If you want to simulate this you should also have an initial block to

set the startup condition.  I would suggest simulating with diferent

input clock duty cycles to see what you might be in for.

Regards,

Gabor

-- Gabor
Highlighted
Visitor
5,439 Views
Registered: ‎06-20-2009

Thanks!

I seem to not understand the difference between '=' and '<=', I kept getting compiler errors that talked about two or more drivers for one signal.

Yes I realize that the output will be jittery and will not be suitable for a 20 MHz processor, but if I divide by two, I should get a clean 10 MHz, yes?

I hate to continue to be so dense, but no that I have successfully compiled the code and placed it on my chip.  How do I simulate it from ISE?

DavidBear

Highlighted
Professor
5,404 Views
Registered: ‎08-14-2007

I would suggest looking for a good Verilog book.  I read Thomas & Moorby's green book cover

to cover.  It's a great introduction to Verilog even though it is out of date and doesn't cover

Verilog 2001 extensions to the language.

Briefly:

= is a "blocking" assignment.  This means that the assignment takes place before

any subsequent assignments in the same block.

<= is a "non-blocking" assignment.  These are scheduled using the current value

of the right side of the equation when evaluated, but don't take place until the end

of the block is reached or until there is a delay in the block.

For synthesis there is a simple "rule" that blocking assignments are used in

combinatorial blocks and non-blocking assignments in clocked blocks.  This

"rule" is not hard and fast and there are times when you can break it, but it is

a good starting point for beginners.

"multiple drivers" errors in Verlog (and VHDL) come from assigning a value to

the same signal in more than one block.  For example if you have:

reg foo;

always @ (posedge reset)

foo <= 0;

always @ (posedge clock)

foo <= bar;

This code would work fine in simulation, but synthesis tries to build hardware from

each always block and sees both sets of hardware "driving" foo.  There are some

exceptions.  For example it is generally OK to use an initial block and an always block

for the same variable (although some synthesizers don't handle it) like:

initial begin

foo = 0;

end

always @ (posedge clock)

foo <= bar;

This should create the equivalent of an FDC (flip-flop with initialization to zero) like:

FDC foo_ff

(

.Q (foo),

.D (bar),

.C (clk),

.CLR  (1'b0)

);

Note that even though CLR is tied low, this flip-flop will initialize to zero when the part

starts up.  That is what the initial block infers.

I'm not familiar with the ISE simulator, as I have Modelsim PE here, but I imagine that

it should work with the same testbench.  In the ISE GUI (Project Navigator) you can

select Project --> New Source... and select Verilog Text fixture from the list of types.

Give it a name, then associate it with your divide by 1.5 module and click finish.  This

will give you a starting point to write a testbench including declaring the module ports

as signals in the testbench,  initializing the module inputs, and instantiating the module

as "uut" (unit under test).  This test fixture will be added to your ISE project and you

will see it in the sources view for "Behavioral Simulation."  Since your module really

only needs one input (the clock) you should only need to add code like:

always begin

clock = #16.667 1;  // Clock low period (clock goes high after delay)

clock = #16.667 0;  // Clock high period (clock goes low after delay)

end

You can change the delay numbers individually to see what a non-50%

duty cycle will do.

Regards,

Gabor

-- Gabor