module sample (clk4mhz, out44100);
input clk4mhz;
wire clka, clkb, clkc, clkd, locked;
reg [4:0] reset=0;
reg [9:0] count=0;
output out44100;
// synthesize 4 MHz * 21/2 * 21/20 / 1000 = 44100 Hz
DCM dcm1 (.CLKIN(clk4mhz), .RST(1'b0), .CLKFB(), .CLK0(), .CLKDV(), .CLKFX(clka), .LOCKED(locked));
defparam dcm1.CLK_FEEDBACK = "NONE";
defparam dcm1.CLKFX_MULTIPLY = 21;
defparam dcm1.CLKFX_DIVIDE = 2;
defparam dcm1.CLKIN_PERIOD = 250;
defparam dcm1.DFS_FREQUENCY_MODE = "LOW";
BUFG buf1 (.I(clka), .O(clkb));
always @ (posedge clkb)
reset <= {reset,locked};
DCM dcm2 (.CLKIN(clkb), .RST(~reset[4]), .CLKFB(), .CLK0(), .CLKDV(), .CLKFX(clkc), .LOCKED());
defparam dcm2.CLK_FEEDBACK = "NONE";
defparam dcm2.CLKFX_MULTIPLY = 21;
defparam dcm2.CLKFX_DIVIDE = 20;
defparam dcm2.CLKIN_PERIOD = 23.8;
defparam dcm2.DFS_FREQUENCY_MODE = "LOW";
BUFG buf2 (.I(clkc), .O(clkd));
always @ (posedge clkd)
count <= count==1011 ? 12 : count + 1; // divide-by-1000 with square wave in bit 9
assign out44100 = count[9];
endmodule
echo47 said:Oops, yes, I just remembered that too!I'll try to find a way to fix it . . .
<some time passes>
Oh great. I have a solution ready to try, but I can't test it because XST is giving me "FATAL_ERROR" crash messages . . .
<more time passes>
Ok, I solved the FATAL_ERROR messages by replacing my BUFGMUX primitives with BUFG primitives. Go figure!
Here's a new paragraph to replace my earlier paragraph. I tested it by compiling the following Verilog code into my Spartan-3 board, and feeding it a 4 MHz clock. The output reads 44100.0 Hz on my frequency counter.
If you really need 44.1 kHz, and if your FPGA clock is only 4 MHz (that's a really slow clock), then you could feed the 4 MHz clock into a DCM that's configured for 21/2 frequency synthesis, then feed its output into another DCM that's configured for 21/20 synthesis, and then feed its output into a divide-by-1000 counter. The result will be 44.1 kHz, within the accuracy of your crystal oscillator.
4000000 * 21/2 * 21/20 / 1000 = 44100
always @ (posedge clkb)
reset <= {reset,locked};
always @ (posedge clkd)
count <= count==1011 ? 12 : count + 1; // divide-by-1000 with square wave in bit 9
assign out44100 = count[9];
endmodule[/code]
echo47 said:Hi wakaka,
I used two cascaded DCM synthesizers because a single DCM doesn't have enough flexibility in its numerator and denominator to provide the required ratio.
The 4 MHz input clock 'clk4mhz' feeds into dcm1 which is configured as a 21/2 frequency synthesizer, so it's 'clka' output is 42 MHz.
When cascading two Xilinx DCMs, it's necessary to hold the second DCM in reset until the first DCM has stabilized and locked, plus a few additional clock cycles (that's mentioned somewhere in the Xilinx DCM documentation). That's the job of the 'reset' shift register. A shift register needs a good low-skew clock, so I buffered the weak 'clka' signal into global clock 'clkb'.
DCM 'dcm2' is configured as a 21/20 frequency synthesizer. Its 'clkb' input is 41 MHz, so its 'clkc' output is 44.1 MHz.
Signal 'clkc' is also weak, so I buffered it as global clock 'clkd' so it can reliably clock the divide-by-1000 counter. That counter divides the 44.1 MHz 'clkd' into the 44.1 kHz squarewave 'count[9]'. The 10-bit counter endlessly counts from 12 to 1011. I chose that peculiar range so bit 9 would be a perfect square-wave, just in case someone needed 50% duty cycle. If I had counted from 0 to 999, then bit 9 would have been non-square.
Xilinx ISE provides a software tool for generating DCM HDL code, and most people probably use it, but I prefer hand-writing my own code for small things like this.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?