LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY feq_sel IS
PORT(clk : INSTD_LOGIC;
ena : INSTD_LOGIC;
reset : INSTD_LOGIC;
clkout : out std_logic
);
END feq_sel;
ARCHITECTURE a OF feq_sel IS
SIGNAL c2 : STD_LOGIc;
begin
process(reset,ena)
begin
if reset='1' then
clkout<='0';
elsif ena='1' then
clkout<=c2;
end if;
end process;
process(clk)
variable count : std_logic_vector(7 downto 0);
variable cnt : std_logic_vector(7 downto 0);
begin
IF rising_edge(clk) THEN
count:=count+1;
if count="00000001" then
c2<=NOT c2;
elsif count="00000010" then
cnt:=cnt+1;
elsif count="00000011" then
count:="00000000";
end if;
end if;
IF falling_edge(clk) then
if cnt="00000001" then--下降沿的且cnt等于1时候才使c2变化
c2<=not c2;
cnt:="00000000";
end if;
end if;
END PROCESS;
end a;
以上是本人抽取的程序,可能还有一些没有改的地方
大体的思路是:(1)、让count记到1 的时候改边一次c2
(2)、让count记到2的时候,cnt为1,之后当时钟的下降沿来的时候再把c2改变一次
从而实现三分;
实际中遇到问题:编译通过,仿真的时候上述(2)的c2在count为2时的时钟的上升沿改变了 值而非在时钟的下降沿改变
不知道是为什么?
请高手赐教,本人通宵一夜也没有想出,菜鸟水平,不好意思麻烦大家了!
下面这个程序是以前从这儿看到的:
-- 占空比1:1的通用分频模块 -- by superdsp, 709th Research Institute. -- Dec-7-2004 -- superdsp@21cn.com
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;
entity ClockDiv is generic (div_size: integer := 24); port( clk : in std_logic; rst : in std_logic; clkout : out std_logic); end ClockDiv;
architecture behavioral of ClockDiv is signal c1 : integer range 0 to div_size - 1; signal c2 : integer range 0 to div_size - 1; signal div_even : std_logic; signal div_odd : std_logic; begin
process(rst, clk) begin if (rst = '0') then c1 <= 0; elsif rising_edge(clk) then if (c1 = div_size - 1) then c1 <= 0; else c1 <= c1 + 1; end if; end if; end process;
process(rst, clk) begin if (rst = '0') then c2 <= 0; elsif falling_edge(clk) then if (c2 = div_size - 1) then c2 <= 0; else c2 <= c2 + 1; end if; end if; end process;
div_even <= '1' when (c2 >= (div_size + 1) / 2) else '0'; div_odd <= '1' when ((c2 >= (div_size + 1) / 2) or (c1 >= (div_size + 1) / 2)) else '0';
clkout <= clk when (div_size = 1) else div_even when (div_size / 2 * 2 = div_size) else div_odd;
end behavioral; |
|
仅在modelsim功能仿真,欢迎仁者见仁,智者见智啊:) module dclk(a,b,c,clk,reset,i,j); input clk,reset; output[1:0] i,j; output a,b,c; reg [1:0] i,j; reg a,b,c; //2:1 posedge clk always @(posedge clk or negedge reset) begin if (!reset) begin i<=0; a<=0; end else begin i=i+1; case(i) 1 : a=1; 2 : a=1; 3 : a=0; default: begin a=1; i=1; end endcase end end
//2:1 negedge clk always @(negedge clk or negedge reset) begin if (!reset) begin j<=0; b<=0; end else begin j=j+1; case(j) 1 : b=1; 2 : b=1; 3 : b=0; default: begin b=1; j=1; end endcase end end always @(a or b or c) begin if(!reset) c=0; else c=a&b; end
endmodule |
|
|
测试文件如下: module test_dclk; wire a,b,c; wire [1:0] i,j; reg clk; reg reset; dclk dut(.a(a),.b(b),.c(c),.clk(clk),.reset(reset),.i(i),.j(j)); always #10 clk=~clk; initial begin clk=0; reset=1; #5 reset=0; #10 reset=1; end
endmodule
|
|
always @(posedge clk) begin if(reset==1'b0) out <= 0 ; cnt <= 0 ; else if(cnt==2) cnt <= 0 ; out<= ~out ; else cnt <= cnt+1; end |
搂主的想法是做一个占空比为1:1的3分频器
4楼的是3分频,搂主的不是,不要忘了i=0的情况
module s1 ( // {{ALTERA_ARGS_BEGIN}} DO NOT REMOVE THIS LINE! clkin, clkout, s1, s2 // {{ALTERA_ARGS_END}} DO NOT REMOVE THIS LINE! ); // Port Declaration
// {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE! input clkin; output clkout, s1, s2; // {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE! wire s1,s2; reg [1:0] step1, step2; always @(posedge clkin) begin case (step1) 2'b00: step1<=2'b01; 2'b01: step1<=2'b10; 2'b10: step1<=2'b00; default :step1<=2'b00; endcase end
always @(negedge clkin) begin case (step2) 2'b00: step2<=2'b01; 2'b01: step2<=2'b10; 2'b10: step2<=2'b00; default :step2<=2'b00; endcase end
assign clkout=step1[1]|step2[1]; assign s1=step1[1]; assign s2=step2[1];
endmodule
testbench: `timescale 1ns/1ns module s1_tb; reg clk_in; wire clk_out,s1, s2; always #50 clk_in=~clk_in; initial begin
clk_in=0; #1000 $stop; end s1 s10(.clkin(clk_in), .clkout(clk_out), .s1(s1), .s2(s2)); endmodule
|
楼上这个才是三分频吧!
老师让我们做的占空比为1:1的三分频
module frus3(clk,qout);
output qout;
input clk;
reg qout,q1,q2,d,qout1,qout2;
always @(negedge clk)
begin
q1<=~d;
q2<=~q1;
d<=q1&q2;
qout1=q2;
end
always @(posedge clk)
begin
qout2=qout1;
end
always @(qout1 or qout2)
begin
qout=qout1|qout2;
end
endmodule
module ddd;
//-----------------------------------------
//testbench
reg CLOCK;
reg RESET;
initial
begin
RESET = 1'b0;
CLOCK = 1'b0;
#100 RESET = 1'b1;
#230 RESET = 1'b0;
end
always #50 CLOCK = !CLOCK;
//--------------------------------------------
//main module
reg CLK_even;
reg CLK_odd_n;
wire CLK;
reg[4:0] CNT;
reg[4:0] RATE = 5'd4;//RATE是分频系数,要几分频就将RATE设为几
always @(posedge CLOCK)
begin
if(RESET)
CNT <= 5'b0;
else
begin
if(CNT==RATE-1'b1)
CNT <= 5'b0;
else
CNT <= CNT + 1'b1;
end
end
//--------------------------
always @(posedge CLOCK)
begin
if(RESET)CLK_even <= 1'b0;
else
begin:even_freq //偶分频
if(CNT==((RATE>>>1)-1'b1))
CLK_even <= 1'b0;
else if(CNT==RATE-1'b1)
CLK_even <= 1'b1;
end
end
//--------------------------
//generate odd_freq clock
always @(negedge CLOCK)
begin
if(RESET)
CLK_odd_n <= 1'b0;
else
CLK_odd_n <= CLK_even;
end
//-------------------------
assign CLK = (RATE[0]==1'b1)?(CLK_even|CLK_odd_n):CLK_even;
endmodule
我总结的,不是原创,其中三分频是herewangying的功劳
******************************************************************
分频技术几点
******************************************************************
10.1分频
9次10分频和1次11分频
因为
(9×10+1×11)/(9+1)=10.1
******************************************************************
实例:用于实现N-0.5分频
******************************************************************
begin
-------异或门
clk <= inclk xor divide2; --------inclk(输入时钟)
-------模N减法计数器
process(clk)
if (clk'event and clk='1') then
if (count="0000") then
count <= present-1; --------outclk(输出时钟) ,present 预置分频值,即N值
outclk <= '1';
else
count <= count-1;
outclk <= '0';
end if;
end if ;
end process;
------2分频器
process(outclk)
begin
if (outclk'event and outclk='1') then
divide2 <= not divide2;
end if;
end process;
******************************************************************
3分频实例:
******************************************************************
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY div3 IS
PORT ( clk_in :in std_logic;
clk_out :out std_logic);
END div3;
ARCHITECTURE behav OF div3 IS
SIGNAL clk1,clk2:std_logic_vector(1 DOWNTO 0);
BEGIN
PROCESS1:PROCESS(clk_in)
BEGIN
IF clk_in'event AND clk_in='1' THEN
CASE clk1 is
WHEN "00" => clk1 <= "01";
WHEN "01" => clk1 <= "11";
WHEN "11" => clk1 <= "00";
WHEN OTHERS => clk1 <= "00";
END CASE;
END IF;
END PROCESS PROCESS1;
PROCESS2:PROCESS(clk_in)
BEGIN
IF clk_in'event AND clk_in='0' THEN
CASE clk2 IS
WHEN "00" => clk2 <= "01";
WHEN "01" => clk2 <= "11";
WHEN "11" => clk2 <= "00";
WHEN OTHERS => clk2 <= "00";
END CASE;
END IF;
END PROCESS PROCESS2;
clk_out <= '1' WHEN(clk1 AND clk2)=0
ELSE '0';
END behav;
我在网上看到一个3分频器,它的思路如下
1写一个根据上升沿触发的1:2的三分频器(低1高2)
2写一个根据下降沿触发的1:2的三分频器(低1高2)
3两个结果与一下就行了,得到占空比1:1的三分频器
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.std_logic_unsigned.all;
entity div_three is
port(
clk : in STD_LOGIC;
clr : in STD_LOGIC;
count11:out std_logic;
count00:out std_logic;
div3_clk : out STD_LOGIC
);
end div_three;
architecture rtl of div_three is
signal count3:std_logic_vector(1 downto 0);
signal count2:std_logic_vector(1 downto 0);
signal count1:std_logic;
signal count0:std_logic;
begin
cnt3:process(clk,clr)
begin
if clr='0' then
count3<="00";
elsif clk'event and clk='1' then
if count3="10"then
count3<="00";
else
count3<=count3+'1';
end if;
end if;
end process cnt3;
count0<='1' when count3<="01"else
'0';
cnt2:process(clk,clr)
begin
if clr='0' then
count2<="00";
elsif clk'event and clk='0' then
if count2="10"then
count2<="00";
else
count2<=count2+'1';
end if;
end if;
end process cnt2;
count1<='1' when count2<="01"else
'0';
div3_clk<=count1 and count0;
count11<=count1;
count00<=count0;
-- enter your statements here --
end rtl;
我不理解这两条语句
count0<='1' when count3<="01"else '0';
count1<='1' when count2<="01"else '0';
从仿真波形看,当count3="10"时count0='0';count3="00"和count3="01"时count0='1'
当count2="10"时count1='0';count2="00"和count2="01"时count1='1'
这是为什么呢?
这两条语句
count0<='1' when count3<="01"else '0';
count1<='1' when count2<="01"else '0';
究竟是什么意思呢?
count0<='1' when count3<="01"else '0';
当count3小于等于“01”时count0=1,否则为0,所以你从仿真波形上看就会有当count3="10"时count0='0';count3="00"和count3="01"时count0='1'
|
加count11,count00两个输出是为了看count0 和count1的波形 |
|
|
任意整数的分频器 module divide(clkin,out,clkout1,clkout2); input clkin; output out,clkout1,clkout2; reg clkout1,clkout2; reg [2:0] value1,value2;
always @(posedge clkin) begin if(value1==3'b001) begin value1=0; clkout1=~clkout1; end else value1=value1+1; end always @(negedge clkin) begin if(value2==3'b001) begin value2=0; clkout2=~clkout2; end else value2=value2+1; end assign out=clkout1^clkout2;
endmodule |
|
下面这个程序是我看到的一个分频器的程序,可是我看了半天不懂它的原理,请高手帮忙啊!源程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity p_cnt is
port(clk:in std_logic;
rst:in std_logic;
num_set:in std_logic;--分频比预置使能端
div_num:in std_logic_vector(3 downto 0);--分频比预置端分频比为2-15
div_out:out std_logic
);
end p_cnt;
architecture beha of p_cnt is
signal num_reg:std_logic_vector(3 downto 0);
signal counter:std_logic_vector(3 downto 0);
signal rising_cp:std_logic;
signal falling_cp:std_logic;
signal pre_out:std_logic;
begin
process(clk)
begin
if(rising_edge(clk))then
if(num_set='1')then
if((div_num(3)or div_num(2)or div_num(1))='0')then
num_reg<="0001";
else
num_reg<=div_num+"1111";
end if;
end if;
end if;
end process;
process(clk)
begin
if(rising_edge(clk))then
if(rst='1'or counter=num_reg)then
counter<="0000";
rising_cp<='0';
elsif(counter='0'&num_reg(3 downto 1))then
rising_cp<='1';
counter<=counter+'1';
else
counter<=counter+'1';
end if;
end if;
end process;
process(clk)
begin
if(falling_edge(clk))then
if(rising_cp='1')then
falling_cp<='1';
else
falling_cp<='0';
end if;
end if;
end process;
pre_out<=(not num_reg(0))and falling_cp;
div_out<=pre_out or rising_cp;
end beha;