xytlucil

高精度方波

0
阅读(1042)

该方法参考DDS原理,根据要形成的方波的频率,生成步进参数,当步进参数大时,生成的方波频率就高。

采用100m晶振,步进参数为 k=要生成的频率/(100m/2^32),采用一个32位计数器,每次时钟到来时计数器增加k,当计数器增加到32‘h7ffffff时,输出时钟置高,不到是置低。这样就生成了所需的频率’源代码见附件

//////////////////////////////////////////////////////////////////////////

module top(

input clk,

input rst,

output clk_uart_16,

output clk_uart_16_en



);


precise_devider 

#(.devide_cnt(32'd6597070))

precise_devider

          (.clk(clk),

.rst(rst),

.clk_uart_16(clk_uart_16),

.clk_uart_16_en (clk_uart_16_en)

);


endmodule

//////////////////////////////////////////////////////////////////////////////

module precise_devider

#(parameter devide_cnt=32'd6597070)

(

input clk,

input rst,

output  reg  clk_uart_16,

output clk_uart_16_en

);

//parameter devide_cnt=32'd6597070;

reg [31:0] counter_devide_cnt;


always @(posedge clk or negedge rst)

begin

if(rst==0)

begin

counter_devide_cnt<=0;

end

else

begin

counter_devide_cnt<=counter_devide_cnt+devide_cnt;

end


end


always @(posedge clk or  negedge rst)

begin

if(rst==0)

begin

clk_uart_16<=0;

end

else

begin

if(counter_devide_cnt<=32'h7fffffff)

begin

clk_uart_16<=0;

end

else

begin

clk_uart_16<=1;

end

end

end


reg  clk_uart_16_r;

always@(posedge clk or negedge rst)

begin

if(rst==0)

clk_uart_16_r<=0;

else

clk_uart_16_r<=clk_uart_16;

end


assign clk_uart_16_en=clk_uart_16&(!clk_uart_16_r);


endmodule

/////////////////////////////////////////////////////////////////////

module top_tb;

reg clk;

reg rst;

wire clk_uart_16;

wire clk_uart_16_en;


initial 

begin

#0 rst=0;

#0 clk=0;

#5 clk=0;

#2 rst=1;

#10 rst=0;

#20 rst=1;


end


always #5 clk<=~clk;


top top(

.clk(clk),

.rst(rst),

.clk_uart_16(clk_uart_16),

.clk_uart_16_en(clk_uart_16_en)



);


endmodule 

/////////////////////////////////////////////////////////////////////