- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That is a common problem. Solution is torun on fast clock but each register enabled by slow rate through clkenable signal.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ok, and the clkenable can be generated with plain logic ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yes, using fast clock to run a counter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
clk division and its use looks correct to me (eyeballing)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you !
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page