1: // clock divider
2: `timescale 1ns/1ps
3: module clgen
4: #(parameter DIVIDER_LEN = 8)
5: (
6: input wire clk_in,
7: input wire rst,
8: input wire enable,
9: input wire [DIVIDER_LEN-1:0] divider,
10: output wire clk_out
11: );
12:
13: wire odd_or_even;
14: wire [DIVIDER_LEN-1:0] cnt_zero;
15: wire [DIVIDER_LEN-1:0] cnt_one;
16: reg [DIVIDER_LEN-1:0] cnt_pos;
17: reg [DIVIDER_LEN-1:0] cnt_neg;
18: reg flag_pos;
19: reg flag_neg;
20:
21: assign odd_or_even = divider[0];
22: assign cnt_zero = odd_or_even ? (divider-1)>>1:divider[DIVIDER_LEN-1:1]-1 ;
23: assign cnt_one = (divider-1);
24:
25: always @(posedge clk_in or posedge rst)
26: if(rst)
27: cnt_pos <= {DIVIDER_LEN{1'b0}};
28: else begin
29: if(cnt_pos >= cnt_one)
30: cnt_pos <= {DIVIDER_LEN{1'b0}};
31: else if(enable)
32: cnt_pos <= cnt_pos + 1;
33: end
34:
35: always @(negedge clk_in or posedge rst)
36: if(rst)
37: cnt_neg <= {DIVIDER_LEN{1'b0}};
38: else begin
39: if(cnt_neg >= cnt_one)
40: cnt_neg <= {DIVIDER_LEN{1'b0}};
41: else if(enable)
42: cnt_neg <= cnt_neg + 1;
43:
44: end
45:
46: always @(posedge clk_in or posedge rst)
47: if(rst)
48: flag_pos <= 1'b0;
49: else begin
50: if(cnt_pos == cnt_zero)
51: flag_pos <= 1'b0;
52: else
53: if(cnt_pos == cnt_one)
54: flag_pos <= 1'b1;
55: end
56:
57: always @(negedge clk_in or posedge rst)
58: if(rst)
59: flag_neg <= 1'b0;
60: else begin
61: if(cnt_neg == cnt_zero)
62: flag_neg <= 1'b0;
63: else
64: if(cnt_neg == cnt_one)
65: flag_neg <= 1'b1;
66: end
67:
68: assign clk_out = odd_or_even ?( flag_pos & flag_neg) : flag_pos;
69:
70:
91: endmodule
92: