When HDL is used to realize the frequency divider, it is mainly realized by writing the rising / falling edge of counter counting clock. Even frequency division is very easy to be realized here. Odd frequency division needs to generate two waveforms by counter and then perform exclusive or operation to realize odd frequency division.
The Verilog HDL program code of 5-fold frequency division and 10-fold frequency division, and testbench test simulation program are given below.
Verilog program:
module frequence_divider ( input clk_50MHz, input rst, output clk_10MHz, output clk_5MHz ); reg [3:0] cnt; reg clk_5MHz_temp; reg clk_10MHz_temp1; reg clk_10MHz_temp2; assign clk_5MHz=clk_5MHz_temp; assign clk_10MHz=(clk_10MHz_temp1^clk_10MHz_temp2);//Superposition of two signals to produce odd multiple frequency division signal always@(posedge clk_50MHz or negedge rst) begin if(rst==1'b0)begin cnt<=4'd0; end else begin if(cnt==4'd4)begin cnt<=4'd0; end else begin cnt<=cnt+1'd1; end end end always@(posedge clk_50MHz or negedge rst) begin if(rst==1'b0)begin clk_5MHz_temp<=1'b1; end else begin if(cnt==4'd0)begin clk_5MHz_temp<= ~clk_5MHz_temp; end else begin clk_5MHz_temp<=clk_5MHz_temp; end end end always@(posedge clk_50MHz or negedge rst) begin if(rst==1'b0)begin clk_10MHz_temp1<=1'b1; end else begin if(cnt==3'd0)begin clk_10MHz_temp1<= ~clk_10MHz_temp1; end else begin clk_10MHz_temp1<=clk_10MHz_temp1; end end end always@(negedge clk_50MHz or negedge rst) //Note that this is the clock falling edge operation begin if(rst==1'b0)begin clk_10MHz_temp2<=1'b1; end else begin if(cnt==3'd3)begin clk_10MHz_temp2<= ~clk_10MHz_temp2; end else begin clk_10MHz_temp2<=clk_10MHz_temp2; end end end endmodule
testbench code is as follows:
`timescale 1ps/1ps `define clock_period 20 module frequence_divider_tb; reg rst; reg clk; wire clk_10MHz; wire clk_5MHz; frequence_divider my_frequence_divider( .clk_50MHz(clk), .rst(rst), .clk_10MHz(clk_10MHz), .clk_5MHz(clk_5MHz) ); initial begin clk=1'b1; end always #(`clock_period/2) clk=~clk; initial begin rst=1'b0; #(`clock_period*10) rst=1'b1; #(`clock_period*200) $stop; end endmodule
The simulation results are as follows:
It can be seen that 5 times and 10 times frequency division are realized.
VHDL frequency divider Code: the program achieves 25 times frequency division and 50 times frequency division respectively
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_ARITH.ALL; entity frequency_divider_2 is port ( clk : in std_logic; rst : in std_logic; clk_out3 : out std_logic; clk_out2 : out std_logic ); end entity frequency_divider_2; architecture behav of frequency_divider_2 is signal cnt2 : integer; signal cnt3 : integer; signal clk_out_temp2_1 : std_logic; signal clk_out_temp2_2 : std_logic; signal clk_out_temp3 : std_logic; begin clk_out2<= clk_out_temp2_1 xor clk_out_temp2_2; clk_out3<=clk_out_temp3; process(clk,rst) begin if(rst='0')then cnt3<=0; elsif(clk'event and clk='1')then if cnt3=24 then cnt3<=0; else cnt3<=cnt3+1; end if; end if; end process; process(clk,rst) begin if(rst='0')then clk_out_temp3<='0'; elsif(clk'event and clk='1')then if cnt3 = 0 then clk_out_temp3 <= not clk_out_temp3; end if; end if; end process; --Odd multiple frequency division process(clk, rst) begin if(rst = '0') then cnt2<=0; clk_out_temp2_1<='1'; clk_out_temp2_2<='1'; elsif (clk'event and clk = '1') then if (cnt2=0) then cnt2<=24; clk_out_temp2_1<= not clk_out_temp2_1; else cnt2 <=cnt2-1; clk_out_temp2_1<=clk_out_temp2_1; end if; elsif (clk'event and clk = '0') then if (cnt2=12) then clk_out_temp2_2 <= not clk_out_temp2_2; else clk_out_temp2_2 <= clk_out_temp2_2; end if; end if; end process; end behav;