可配置奇偶分频Verilog实现

可配置奇偶分频 及testbench

module odd_even_div (
//input
input wire clk,
input wire rst_n,
input wire rst_n_clkn,
input wire [7:0] div_cfg,
// output
output wire done,
output wire clk_o
);
/// counter
// reg [7:0] div_cfg;
reg div_clk_r;
reg div_clk_f;


reg [7:0] cnt;

wire [7:0] signal_chg_1st;
wire [7:0] signal_chg_2nd;

wire [7:0] signal_shift_r;
wire clko_pre;

wire even_or_odd;


// control div_cfg changes
reg  [7:0]  div_cfg_r;
reg [2:0]  div_cfg_chg;

always @(posedge clk  or negedge rst_n) begin
if (~rst_n) begin
div_cfg_r <= 8'h02;
div_cfg_chg<=3'b000;
end else if (div_cfg!=div_cfg_r && |div_cfg && ~div_clk_r&& ~div_clk_f) begin
div_cfg_chg<=3'b111;
div_cfg_r <= div_cfg;
end else
div_cfg_chg<={div_cfg_chg[1:0],1'b0};
end

// 
assign done = ~div_cfg_chg[2];


assign even_or_odd = ^div_cfg_r;

//wire clko;
assign signal_shift_r = div_cfg_r >>1;
assign signal_chg_1st = even_or_odd ? div_cfg_r>> 1: (div_cfg_r-{{7{1'b0}},1'b1})>>1;

assign signal_chg_2nd = div_cfg_r;


always @(posedge clk or negedge rst_n) begin
if (~rst_n)
cnt <= 8'h00;
else if (div_cfg_chg[2]) //synchronous reset counter and stay 3 cycles after div_cfg changes
cnt <= 8'h00;
else if (cnt==div_cfg_r)
cnt <= 8'h01;
else
cnt <= cnt +1;
end


always @(posedge clk or negedge rst_n) begin
if (~rst_n)
div_clk_r <= 1'b0;
else if (div_cfg_chg[2])
div_clk_r <= 1'b0;
else if (cnt==8'h00)
div_clk_r <= 1'b1;
else if (cnt== signal_chg_1st || cnt== signal_chg_2nd)
div_clk_r <= ~div_clk_r;
end

always @(negedge clk or negedge rst_n_clkn) begin
if (~rst_n_clkn)
div_clk_f <= 1'b0;
else if (div_cfg_chg[2])
div_clk_f <= 1'b0;
else if (cnt==8'h01)
div_clk_f <= 1'b1;
else if (cnt== signal_chg_1st +'b1 )
div_clk_f <= ~div_clk_f;
end
assign clko_pre = even_or_odd? div_clk_r : div_clk_f || div_clk_r;
assign clk_o = clko_pre &(~div_cfg_chg[2]);
endmodule



 

`timescale 1ns/1ps
module tb ();

reg clk;
reg rst_n;
reg rst_n_clkn;
reg [7:0] div_cfg;
wire clk_o;
wire clk_o_new;
wire clk_o_oe;
initial begin
  clk = 0;
  rst_n = 1'b0;
  rst_n_clkn = 1'b0;
  div_cfg = 8'h02;
  #2
  @(posedge clk)
  rst_n = 1'b1;
  @(negedge clk)
  rst_n_clkn = 1'b1;
  repeat (20) @(posedge clk);
  @(posedge clk)
  #0.1 div_cfg = 8'h03;
  repeat (20) @(posedge clk);
  @(posedge clk)
  #0.1 div_cfg = 8'h04;
  repeat (20) @(posedge clk);
  @(posedge clk)
  #0.1 div_cfg = 8'h05;
  repeat (20) @(posedge clk);
  @(posedge clk)
  #0.1 div_cfg = 8'h0b;
  repeat (50) @(posedge clk);
  #50
  $finish;
end 

//initial begin
  
//end
always #0.5 clk = ~clk;  


odd_even_div inst_odd_even_div (
//input
.clk(clk),
.rst_n(rst_n),
.rst_n_clkn(rst_n_clkn),
.div_cfg(div_cfg),
// output
.done(),
.clk_o(clk_o_oe) 
);

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值