您的位置:首页 > 其它

【温故而知新】【3】时钟分频-半整数分频N.5

2015-10-06 20:54 381 查看

【温故而知新】【3】时钟分频-半整数分频N.5

本次实现是半整数分频,或者叫做N.5分频。实现的方式是通过移位寄存器。这种方式的思路来源于文献“Clock dividers made easy”, writed by Mohit Arora from ST mircoelectronics, LTD。 Mohit Arora 也写过一本书,叫做“The art of hardware architecture”, 由Springer出版,这本书的第四章的内容跟上述论文的内容一致。

实现步骤和方式(N=1)

定义移位寄存器的初值,将移位初值定义为3’b001;

定义移位寄存器,每个周期将末位的‘1’向左移位1位,移位产生的中间数据跟初值位宽一致,设为tmp。

采用将tmp[1]寄存一拍,注意此处采用的时钟信号边沿与移位寄存器时钟边沿相反。设移位之后的信号分别位tmp_1_

将tmp[0]、tmp_1_进行 或操作

以下是实现1.5分频的Verilog代码

//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 1.5
//===========================================================
module iCLK_div_shift_register_15
(
input   iCLK,
input   iRESET,
output  oCLK
);

wire    [2:0] tmp_shift;

reg tmp_0_;
reg tmp_1_;
reg [2:0] tmp;

assign  tmp_shift = 3'b001;

always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[1:0], tmp[2]};
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_1_<=1'b0;
else
tmp_1_<=tmp[1];
end

assign oCLK = tmp[0]|tmp_1_;

endmodule


1.5分频的仿真波形



实现步骤和方式(N>2):

定义移位寄存器的初值,比如4.5分频时,将移位初值定义为9’b0_0000_0001,3.5分频时,将移位器初值定义为7’b000_0001,以此类推。

定义移位寄存器,每个周期将末位的‘1’向左移位1位,移位产生的中间数据跟初值位宽一致,设为tmp。

采用将tmp[0]、tmp[1]、tmp
和tmp[N+1]寄存一拍,注意此处采用的时钟信号边沿与移位寄存器时钟边沿相反。设移位之后的信号分别位tmp_0_, tmp_1_, tmp_N_, tmp_N+1_

将tmp[0]、tmp[1]、tmp_0_、tmp_N_, tmp_N+1_、tmp[N+1]进行 或操作

以下是实现2.5、3.5、4.5和13.5分频的Verilog代码

//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 2.5
//===========================================================
module iCLK_div_shift_register_25
(
input   iCLK,
input   iRESET,
output  oCLK
);

wire    [4:0] tmp_shift;

reg tmp_0_;
reg tmp_2_;
reg tmp_3_;

reg [4:0] tmp;
assign  tmp_shift = 5'b0_0001;

always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[3:0], tmp[4]};
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_0_<=1'b0;
else
tmp_0_<=tmp[0];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_2_<=1'b0;
else
tmp_2_<=tmp[2];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_3_<=1'b0;
else
tmp_3_<=tmp[3];
end

assign oCLK = tmp[0]|tmp[1]|tmp_0_|tmp_2_|tmp_3_|tmp[3];

endmodule


2.5分频的仿真波形



//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 3.5
//===========================================================
module iCLK_div_shift_register_35
(
input   iCLK,
input   iRESET,
output  oCLK
);

wire    [6:0] tmp_shift;

reg tmp_0_;
reg tmp_3_;
reg tmp_4_;

reg [6:0] tmp;
assign  tmp_shift = 7'b000_0001;

always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[5:0], tmp[6]};
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_0_<=1'b0;
else
tmp_0_<=tmp[0];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_3_<=1'b0;
else
tmp_3_<=tmp[3];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_4_<=1'b0;
else
tmp_4_<=tmp[4];
end

assign oCLK = tmp[0]|tmp[1]|tmp_0_|tmp_4_|tmp_3_|tmp[4];

endmodule


3.5分频的仿真波形



//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 4.5
//===========================================================
module iCLK_div_shift_register_45
(
input   iCLK,
input   iRESET,
output  oCLK
);

wire    [8:0] tmp_shift;

reg tmp_0_;
reg tmp_4_;
reg tmp_5_;

reg [8:0] tmp;
assign  tmp_shift = 9'b0_0000_0001;

always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[7:0], tmp[8]};
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_0_<=1'b0;
else
tmp_0_<=tmp[0];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_4_<=1'b0;
else
tmp_4_<=tmp[4];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_5_<=1'b0;
else
tmp_5_<=tmp[5];
end

assign oCLK = tmp[0]|tmp[1]|tmp_0_|tmp_4_|tmp_5_|tmp[5];

endmodule


4.5分频的仿真波形



//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 13.5
//===========================================================
module iCLK_div_shift_register_135
(
input   iCLK,
input   iRESET,
output  oCLK
);

wire    [26:0] tmp_shift;

reg tmp_0_;
reg tmp_13_;
reg tmp_14_;

reg [26:0] tmp;
assign  tmp_shift = 27'b0_0000_0000_0000_0000_0000_0001;

always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[25:0], tmp[26]};
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_0_<=1'b0;
else
tmp_0_<=tmp[0];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_13_<=1'b0;
else
tmp_13_<=tmp[13];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_14_<=1'b0;
else
tmp_14_<=tmp[14];
end

assign oCLK = tmp[0]|tmp[1]|tmp_0_|tmp_13_|tmp_14_|tmp[14];

endmodule


13.5分频的仿真波形



调整分频信号占空比

上述波形显示,13.5分频时钟信号的占空比很小,那么如果想要占空比40%~60%的分频信号呢?应该怎么调整代码?答案是增加或操作中的信号数,依然以13.5分频为例,

assign oCLK = tmp[0]|tmp[1]|tmp[2]|tmp[3]|tmp[4]|tmp[5]|tmp_0_|tmp_1_|tmp_2_| tmp_3_ |tmp_4_ |
tmp_13_|tmp_14_|tmp_15_|tmp_16_|tmp_17_|tmp_18_|tmp[14]|tmp[15]|tmp[16]|tmp[17]|tmp[18];


两行代码分别产生两个周期的分频信号,其中上一行是移位寄存器信号的或操作,而tmp_0_~tmp_4_则是为了消除或操作可能产生的毛刺,下一行是经过相反时钟边沿寄存之后的信号,同样的道理,tmp[14]~tmp[18]是为了消除或操作可能造成的毛刺信号

以下是13.5分频,占空比大于40%的Verilog代码

//===========================================================
// Author: seuchenrui@126.com
//
// Description:
// This is a simple verilog code for clock frequency division
// this code can be used to get
// 1. divided by 13.5,clock duty > 40%
//===========================================================
module iCLK_div_shift_register_135
(
input iCLK,
input iRESET,
output oCLK
);

wire [26:0] tmp_shift;

reg tmp_0_;
reg tmp_1_;
reg tmp_2_;
reg tmp_3_;
reg tmp_4_;
reg tmp_5_;

reg tmp_13_;
reg tmp_14_;
reg tmp_15_;
reg tmp_16_;
reg tmp_17_;
reg tmp_18_;

reg [26:0] tmp;
assign tmp_shift = 27'b0_0000_0000_0000_0000_0000_0001;

always@(posedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp<=tmp_shift;
else
tmp<={tmp[25:0], tmp[26]};
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_0_<=1'b0;
else
tmp_0_<=tmp[0];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_1_<=1'b0;
else
tmp_1_<=tmp[1];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_2_<=1'b0;
else
tmp_2_<=tmp[2];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_3_<=1'b0;
else
tmp_3_<=tmp[3];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_4_<=1'b0;
else
tmp_4_<=tmp[4];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_5_<=1'b0;
else
tmp_5_<=tmp[5];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_13_<=1'b0;
else
tmp_13_<=tmp[13];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_14_<=1'b0;
else
tmp_14_<=tmp[14];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_15_<=1'b0;
else
tmp_15_<=tmp[15];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_16_<=1'b0;
else
tmp_16_<=tmp[16];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_17_<=1'b0;
else
tmp_17_<=tmp[17];
end

always@(negedge iCLK or negedge iRESET)
begin
if(!iRESET)
tmp_18_<=1'b0;
else
tmp_18_<=tmp[18];
end

//assign oCLK = tmp[0]|tmp[1]|tmp_0_|tmp_13_|tmp_14_|tmp[14];

assign oCLK = tmp[0]|tmp[1]|tmp[2]|tmp[3]|tmp[4]|tmp[5]|tmp_0_|tmp_1_|tmp_2_| tmp_3_ |tmp_4_ | tmp_13_|tmp_14_|tmp_15_|tmp_16_|tmp_17_|tmp_18_|tmp[14]|tmp[15]|tmp[16]|tmp[17]|tmp[18];
endmodule


13.5分频,占空比大于40%的仿真波形



后续将继续研究时钟分频
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: