Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20684 Discussions

how to create low freq clock ?

Altera_Forum
Honored Contributor II
1,240 Views

Hi all, I'm a hobbyist, and I'm a bit puzzled with the following : 

I have a 100 mhz, a 12 mhz and 20 mhz clock at my disposal on a  

cyclone1  

 

I try to sample a signal (<100Khz) for a few millisecs. 

In order to fit this in the memory I need a low sample freq. It seemed  

handy to me to make the clock run slow (at 200Khz) so I get  

a long period sampled with just a few memory cells (200 samples per msec) 

 

now I get the feeling that you need a PLL to generate other clock freq. 

but it seems I can only generate higher frequencies with the ALTPLL. 

is this correct or am I overlooking something ? 

 

I also understand that you should not create a clock from plain logic, 

e.g. the following should not be done : 

always @(posedge fastclk) counter <= counter +1; 

assign slowclock = counter[7]; 

 

how am I supposed/advised to go about creating a low clock freq ? 

 

thanks for any advice you can offer. if there is a link to a beginners guide to clocks, I would be very grateful too.
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
437 Views

That is a common problem. Solution is torun on fast clock but each register enabled by slow rate through clkenable signal.

0 Kudos
Altera_Forum
Honored Contributor II
437 Views

ok, and the clkenable can be generated with plain logic ?

0 Kudos
Altera_Forum
Honored Contributor II
437 Views

yes, using fast clock to run a counter

0 Kudos
Altera_Forum
Honored Contributor II
437 Views

should the code look like this then for a low frequency "clock" ? 

your code review much appreciated ! 

 

I have not yet succeeded in testing it ( a steep learning curve..) nor in writing a test bench. (how does one execute a test bench ?) 

 

module listen(clk, reset, start, data_in, data_out, data_valid, data_count); input clk; input reset; input start; input data_in; // from ADC @ 100 Mhz output data_out; output data_valid; output addr; reg data_out; reg data_valid; reg data_count; /////////////////////////////////////////////////////////////////// // start of listener // ADC runs at 100 mhz // 100 Mhz domain assumed // signal is downsampled :one in every 256 samples is processed // LPF filtering not posible : will not fit chip // todo : make smaller LPF filter // busy goes high as soon as start is received // see data_count for de-asserting busy signal always @(posedge clk) if (~busy) busy <= start; // get and LPF the datastream // sample rate is 100 Mhz, // filter is designed with -3db point at 500 khz // signal is between 10 and 100 khz // decimation by 200 ; next steps need 500 khz clock // beware time-delay !! // // no space on chip for this // //ownfir myLPFfir(.Clk(clk), // .dataIn(data_flash_reg), // .dataOut(data_flash_reg1) // ); // create slow signal for slow sampling reg clockdivider; always @(posedge clk) clockdivider <= clockdivider + 8'd1; // creates a 1-clk pulse every 256 clk pulses reg slowtick always @(posedge clk) slowclk <= (clockdivider == 8'b00000000) ; // divides by 256; should give 390625/sec ticks on 100Mhz clock // decimation // select sample when slowtick is asserted // do this also when not busy to keep feeding the filter reg signed data_flash_reg; always @(posedge clk) if (slowtick) data_flash_reg <= $signed(data_in - 8'd128); // do matched filtering // this answers over the previous 76 slowticks // for 76 taps, that is ownmatch mymatch(.Clk(clk),.slow(slowtick), .dataIn(data_flash_reg), .dataOut(data_flash_reg2) ); // back to unsigned, // report unsigned to the outside world always @(posedge clk) if (slowtick && busy) begin data_out <= $unsigned(data_flash_reg2 + 8'sd127 + 8'sd1); data_valid <= 1'b1; end else data_valid <= 1'b0; // process for address generation // reg data_count; // disregard the first 76 samples !! // todo : manage data_count/ data_valid to compensate for this lag // always @(posedge clk) if (slowtick && busy) data_count <= data_count + 12'd1; else if (~busy) data_count <= 12'd0; // done when address space has been filled always @(posedge clk) if (slowtick && data_count == 12'b111111111111) busy <= 1'd0; endmodule
0 Kudos
Altera_Forum
Honored Contributor II
437 Views

clk division and its use looks correct to me (eyeballing)

0 Kudos
Altera_Forum
Honored Contributor II
437 Views

Thank you !

0 Kudos
Reply