热度 1| |
module div2(fi, div, rst_, fo); // Programmable frequency divider
parameter size = 2; //divider counter bit length, division ratio from 1 to 8
input fi; //input signal with frequency fi to be divided
input[size-1:0] div; //division ratio from 1 to 7, div=0 corresponds to divide by 8
input rst_; //active-low reset
output fo; //output signal with frequency fo = fi/div
reg[size-1:0] p; //p=1+integer(div/2) determines the falling edge of fo
reg[size-1:0] counter; //counter value;
reg p0, fout; //output buffer
wire ctr;
// Down counter: counter = counter - 1:
always @(posedge fi or negedge rst_)
if (!rst_) //reset to div = 1
begin
counter[size-1:0] <= {{(size-1){1'b0}},1'b1};
//The above line can be simplified as counter <= {{(size-1){1b0}},1b1}.
//But, its a good practice to specify clearly the every word range
p[size-1:0] <= {{(size-1){1'b0}},1'b1};
p0 <= 1'b1;
end
else if ( counter[size-1:0] == {{(size-1){1'b0}},1'b1} )
begin //load new division ratio when counter=1
counter[size-1:0] <= div[size-1:0]; //load new division ratio
p0 <= ( div[size-1:0] == {{(size-1){1'b0}},1'b1} ); //p0=1, if div=1
if(div[size-1:0] == {size{1'b0}})
p <= {1'b1,{(size-2){1'b0}},{1'b1}}; //div=0 is used to divide by 8
else
p <= {1'b0,div[size-1:1]} + {{(size-1){1'b0}},1'b1}; //p=1+integer(div/2)
end
else //otherwise counter-1
counter[size-1:0] <= counter[size-1:0] - {{(size-1){1'b0}},1'b1};
// Output pulse generator:
always @(posedge fi or negedge rst_)
if (!rst_) fout <= 1'b0;
else if(counter[size-1:0] == {{(size-1){1'b0}},1'b1}) fout <= 1'b1;
else if(counter[size-1:0] == p) fout <= 1'b0;
assign fo = p0 ? fi : fout; //if div=1, pass fi to fo
endmodule