打印

自己写的分频程序,贴出来!

[复制链接]
1871|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jlgcumt|  楼主 | 2012-11-26 09:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
任意整数分频,50%占空比!
module PWMDIV(clk_in,clk_out,clk_div,clk_dutycycle,rst);

input  clk_in;    //  输入时钟频率
output clk_out;        //  分频后的时钟输出
input [15:0] clk_div;
input [15:0] clk_dutycycle;
input  rst;        //  异步复位信号

reg [23:0] cnt_p;  // 上升沿脉冲计数
reg clk_p;
reg [23:0] cnt_n;  // 下降沿脉冲计数
reg [23:0] cnt;
reg clk_n;
reg clk_even;
wire clk_odd;

reg [15:0] clk_div_r;
reg [15:0] clk_dutycycle_r;
reg [15:0] pulse_num_r;
reg [15:0] cnt_pulse;

always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                cnt_p <= 0;       
        else if((clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
                cnt_p <= 0;
        else if(cnt_p == clk_div[15:0] -1)
           cnt_p <= 0;
        else
                cnt_p <= cnt_p+1;
end


always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                clk_p <= 0;
        else if( (clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
                clk_p <= 0;
        else if(cnt_p < (clk_div[15:0]-1)/2)
                clk_p <= 0;
        else if(cnt_p == (clk_div[15:0]-1)/2)
                clk_p <= ~clk_p;
        else if(cnt_p == clk_div[15:0] -1)               
                        clk_p <= ~clk_p;                       
end


always @(negedge clk_in or negedge rst)
begin
        if(!rst)
                cnt_n <= 0;
        else if((clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
                cnt_n <= 0;
        else if(cnt_n == clk_div[15:0] -1)
                cnt_n <= 0;
        else
                cnt_n <= cnt_n+1;
end

always @(negedge clk_in or negedge rst)
begin
        if( !rst )
                clk_n <= 0;
        else if( (clk_div[15:0]%2 == 0)|| (clk_div[15:0] == 0) )
                clk_n <= 0;
        else if(cnt_n < (clk_div[15:0]-1)/2)
                clk_n <= 0;
        else if(cnt_n == (clk_div[15:0]-1)/2)           
                clk_n <= ~clk_n;
        else if(cnt_n == clk_div[15:0]-1)
                clk_n <= ~clk_n;
end

// 偶数分频
always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                cnt <= 0;
        else if( (clk_div[15:0]%2 == 1) || (clk_div[15:0] == 0)  )
                cnt <= 0;
        else if(cnt == clk_div[15:0] -1)
           cnt <= 0;
        else
                cnt <= cnt+1;
end

always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                clk_even <= 0;       
        else if( (clk_div[15:0]%2 == 1) || (clk_div[15:0] == 0)  )
                clk_even <= 0;
        else if(cnt < clk_div[15:0]/2-1)
                clk_even <= 0;
        else if( cnt == clk_div[15:0]/2-1 )
                clk_even <= ~clk_even;
               
        else if(cnt == clk_div[15:0] -1)
                clk_even <= ~clk_even;
end


assign clk_odd = clk_p | clk_n;                                                                        //分频系数为奇数时的脉冲输出信号
assign clk_out = (clk_div[15:0]%2) ? clk_odd : clk_even;        // 当分频系数为偶数时,输出clk_even,否则输出clk_odd

endmodule

相关帖子

沙发
jlgcumt|  楼主 | 2012-11-26 09:42 | 只看该作者
任意整数n分频,占空比为任意1/n的分频程序!

module PWMDIV_ANY(clk_in,clk_out,clk_div,clk_dutycycle,rst);

input  clk_in;                                            //  输入系统时钟频率
output clk_out;                                                //  分频后的时钟输出
input  [23:0] clk_div;                                 // 9200写入的分频系数
input  [23:0] clk_dutycycle;                // 9200写入的占空比
input  rst;                                               //  异步复位信号

reg [23:0] cnt_p;                                          // 上升沿脉冲计数
reg clk_p;
reg [23:0] cnt_n;                                          // 下降沿脉冲计数
reg [23:0] cnt;
reg clk_n;
reg clk_even;
wire clk_odd;

// 奇数分频电路
always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                cnt_p <= 0;
        else if( (clk_div[23:0]%2 == 0) || (clk_div[15:0] == 0) )
                cnt_p <= 0;
        else if(cnt_p == clk_div[23:0] -1)
           cnt_p <= 0;
        else
                cnt_p <= cnt_p+1;
end

always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                clk_p <= 0;
        else if((clk_div[23:0]%2 == 0) || (clk_div[23:0] == 0) )
                clk_p <= 0;
        else if(cnt_p < clk_dutycycle[23:0]-1)
                clk_p <= 0;
        else if(cnt_p == clk_dutycycle[23:0]-1)
                clk_p <= ~clk_p;
        else if(cnt_p == clk_div[23:0] -1)
                clk_p <= ~clk_p;
end


always @(negedge clk_in or negedge rst)
begin
        if(!rst)
                cnt_n <= 0;
        else if((clk_div[23:0]%2 == 0) || (clk_div[23:0] == 0)  )
                cnt_n <= 0;
        else if(cnt_n == clk_div[23:0] -1)
                cnt_n <= 0;
        else
                cnt_n <= cnt_n+1;
end

always @(negedge clk_in or negedge rst)
begin
        if( !rst )
                clk_n <= 0;
        else if( (clk_div[23:0]%2 == 0) || (clk_div[23:0] == 0)  )
                clk_n <= 0;
        else if(cnt_n < clk_dutycycle[23:0]-1)
                clk_n <= 0;
//////////////////////////////////////////////////////////////////////////////////////////////
//        else if(cnt_n == clk_dutycycle[15:0]-1)  // 此处删掉,因为会多出半个时钟,只限在50%占空比里面使用!
//                clk_n <= ~clk_n;
//////////////////////////////////////////////////////////////////////////////////////////////
        else if(cnt_n == clk_div[23:0]-1)
                clk_n <= ~clk_n;
end


// 偶数分频电路
always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                cnt <= 0;
        else if( (clk_div[23:0]%2 == 1) || (clk_div[23:0] == 0)  )
                cnt <= 0;
        else if(cnt == clk_div[23:0] -1)
           cnt <= 0;
        else
                cnt <= cnt+1;
end

always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                clk_even <= 0;       
        else if( (clk_div[23:0]%2 == 1) || (clk_div[23:0] == 0)  )
                clk_even <= 0;
        else if(cnt < clk_dutycycle[23:0]-1 )
                clk_even <= 0;
        else if( cnt == clk_dutycycle[23:0]-1 )
                clk_even <= ~clk_even;
               
        else if(cnt == clk_div[23:0] -1)
                clk_even <= ~clk_even;
end

assign clk_odd = clk_p | clk_n;                          //分频系数为奇数时的脉冲输出信号
assign clk_out = (clk_div[23:0]%2) ? clk_odd : clk_even; // 当分频系数为偶数时,输出clk_even,否则输出clk_odd

endmodule

使用特权

评论回复
板凳
jlgcumt|  楼主 | 2012-11-26 09:43 | 只看该作者
输出规定脉冲个数,50%占空比的程序!

// 输出脉冲计数模块///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
module PusleCnt(clk_in,clr_cmd,pulse_num,out_flag,rst);
input clk_in;
input clr_cmd;
input [15:0] pulse_num;
output out_flag;
input rst;

reg [15:0] pulse_num_cnt;
reg out_flag_r;

always @(negedge clk_in or negedge rst)
begin
        if(!rst)
                begin
                        pulse_num_cnt[15:0] <= 0;
                        out_flag_r <= 0;
                end
        else if( clr_cmd == 1'b1)
                begin
                        pulse_num_cnt[15:0] <= 0;
                        out_flag_r <= 0;
                end
        else
                begin
                        if( pulse_num_cnt[15:0] < pulse_num[15:0] )
                                begin
                                        pulse_num_cnt[15:0] <= pulse_num_cnt[15:0] + 1;       
                                        out_flag_r <= 1;
                                end
                        else if( pulse_num_cnt[15:0] == pulse_num[15:0])
                                begin
                                        out_flag_r <= 0;
                                end
                end
       
end

        assign out_flag = out_flag_r;
       
endmodule

///////////////////////////////////////////////////////////////////////////
//固定个数脉冲输出模块///////////////////////////////////////////////////////
//实现方法:利用计数脉冲的完成来关掉时钟输出////////////////////////////////////
//程序存在问题:响应时间会随着分频系数的变大而变大//////////////////////////////
//////////////////////////////////////////////////////////////////////////
module PulseCtl(clk_in,clk_out,clk_div,clk_dutycycle,pulse_num,clr_cmd,rst);

input  clk_in;    //  输入时钟频率
output clk_out;        //  分频后的时钟输出
input [15:0] clk_div;   
input [15:0] clk_dutycycle;
input [15:0] pulse_num;
input clr_cmd;
input  rst;        //  异步复位信号

reg [23:0] cnt_p;  // 上升沿脉冲计数
reg clk_p;
reg [23:0] cnt_n;  // 下降沿脉冲计数
reg [23:0] cnt;
reg clk_n;
reg clk_even;
wire clk_odd;

wire pulse_en_flag;
wire clk_out_tmp;

reg [15:0] clk_div_r;
reg [15:0] clk_dutycycle_r;
reg [15:0] pulse_num_r;
reg [15:0] cnt_pulse;

always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                cnt_p <= 0;       
        else if((clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
                cnt_p <= 0;
        else if(cnt_p == clk_div[15:0] -1)
           cnt_p <= 0;
        else
                cnt_p <= cnt_p+1;
end


always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                clk_p <= 0;
        else if( (clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
                clk_p <= 0;
        else if(cnt_p < (clk_div[15:0]-1)/2)
                clk_p <= 0;
        else if(cnt_p == (clk_div[15:0]-1)/2)
                clk_p <= ~clk_p;
        else if(cnt_p == clk_div[15:0] -1)               
                        clk_p <= ~clk_p;                       
end


always @(negedge clk_in or negedge rst)
begin
        if(!rst)
                cnt_n <= 0;
        else if((clk_div[15:0]%2 == 0) || (clk_div[15:0] == 0))
                cnt_n <= 0;
        else if(cnt_n == clk_div[15:0] -1)
                cnt_n <= 0;
        else
                cnt_n <= cnt_n+1;
end

always @(negedge clk_in or negedge rst)
begin
        if( !rst )
                clk_n <= 0;
        else if( (clk_div[15:0]%2 == 0)|| (clk_div[15:0] == 0) )
                clk_n <= 0;
        else if(cnt_n < (clk_div[15:0]-1)/2)
                clk_n <= 0;
        else if(cnt_n == (clk_div[15:0]-1)/2)           
                clk_n <= ~clk_n;
        else if(cnt_n == clk_div[15:0]-1)
                clk_n <= ~clk_n;
end

// 偶数分频
always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                cnt <= 0;
        else if( (clk_div[15:0]%2 == 1) || (clk_div[15:0] == 0)  )
                cnt <= 0;
        else if(cnt == clk_div[15:0] -1)
           cnt <= 0;
        else
                cnt <= cnt+1;
end

always @(posedge clk_in or negedge rst)
begin
        if(!rst)
                clk_even <= 0;       
        else if( (clk_div[15:0]%2 == 1) || (clk_div[15:0] == 0)  )
                clk_even <= 0;
        else if(cnt < clk_div[15:0]/2-1)
                clk_even <= 0;
        else if( cnt == clk_div[15:0]/2-1 )
                clk_even <= ~clk_even;               
        else if(cnt == clk_div[15:0] -1)
                clk_even <= ~clk_even;
end


assign clk_odd = clk_p | clk_n;
assign clk_out = (pulse_en_flag) ? ((clk_div[15:0]%2) ? clk_odd : clk_even) : 0;
assign clk_out_tmp = (clk_div[15:0]%2) ? clk_odd : clk_even;

PusleCnt PusCnt(.clk_in(clk_out_tmp),.clr_cmd(clr_cmd),.pulse_num(pulse_num),.out_flag(pulse_en_flag),.rst(rst));

endmodule

使用特权

评论回复
地板
jlgcumt|  楼主 | 2012-11-26 11:46 | 只看该作者
问一下上面写的程序消耗资源都比较大,怎么优化?

使用特权

评论回复
5
GoldSunMonkey| | 2012-11-26 20:16 | 只看该作者
什么资源耗费的大?

使用特权

评论回复
6
Backkom80| | 2012-11-27 08:10 | 只看该作者
取作余%,除 /,这些操作占资源了
虽然新的综合器对%,/,这些都支持其综合了,但综合出来占的资源及性能不是很理想。
改变设计思路,尽量避开这些

使用特权

评论回复
7
jlgcumt|  楼主 | 2012-11-27 09:47 | 只看该作者
5# GoldSunMonkey 逻辑宏消耗的比较多,在CPLD里面写的!

使用特权

评论回复
8
jlgcumt|  楼主 | 2012-11-27 09:48 | 只看该作者
6# Backkom80 我试试看,谢谢!

使用特权

评论回复
9
GoldSunMonkey| | 2012-11-27 18:05 | 只看该作者
5# GoldSunMonkey  逻辑宏消耗的比较多,在CPLD里面写的!
jlgcumt 发表于 2012-11-27 09:47
贝壳说的供参考。乘除是比较占资源的。

使用特权

评论回复
10
GoldSunMonkey| | 2012-11-28 21:12 | 只看该作者
是呀。要修改啊。

使用特权

评论回复
11
Tianya283| | 2012-11-29 19:56 | 只看该作者
学习了。

使用特权

评论回复
12
GoldSunMonkey| | 2012-11-29 20:23 | 只看该作者
解决了么?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:善攻者,动于九天之上,善守者,藏于九地之下!

183

主题

733

帖子

4

粉丝