اطلاعیه

Collapse
No announcement yet.

Crossing clock domains

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    Crossing clock domains

    سلام
    ببخشید عنوان رو نخواستم به فارسی بنویسم تا هنگام جستجو پیدا نشه.

    یه پروژه کار میکنم که لازمه یه سیگنال enable یا همون flag رو از یه دامین با فرکانس کم تر به یه دامین با فرکانس بالا بفرستم. نمیدونم چطوری توضیح بدم، اگر منظورم رو نرسوندم، بگید تا بیشتر مشکل رو توضیح بدم.

    یکم انترنت گشتم اینو دیدم.:
    http://www.fpga4fun.com/CrossClockDomain2.html

    راستش من vhdl کار میکنم و از verilog زیاد سر در نمیارم. میخوام همینو خودم با vhdl بنویسم.
    چون چندبار برنامه رو از اول نوشتم ولی همش مشکل داشتند.
    حالا میخوام اینو امتحان کنم.

    کد:
    module Flag_CrossDomain(
      clkA, FlagIn_clkA, 
      clkB, FlagOut_clkB);
    
    // clkA domain signals
    input clkA, FlagIn_clkA;
    
    // clkB domain signals
    input clkB;
    output FlagOut_clkB;
    
    reg FlagToggle_clkA;
    reg [2:0] SyncA_clkB;
    
    // this changes level when a flag is seen
    always @(posedge clkA) if(FlagIn_clkA) FlagToggle_clkA <= ~FlagToggle_clkA;
    
    // which can then be sync-ed to clkB
    always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA};
    
    // and recreate the flag from the level change
    assign FlagOut_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]);
    endmodule
    میشه یکی توضیح بده این برنامه چجوری کار میکنه؟
    یعنی مفهوم کاری که برنامه نویسش کرده چیه؟
    چرا یه آرایه 3 تایی تعریف کرده؟ [2:0]
    در always دوم چه چیزی به SyncA_clkB اختصاص داده میشه؟

    #2
    پاسخ : Crossing clock domains

    کد:
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity CrossDomain is
    port(	clkA, FlagIn_clkA,clkB	: in std_logic;
    		FlagOut_clkB	: out std_logic);
    end entity;
    
    architecture rtl of CrossDomain is
    
    signal SyncA_clkB : std_logic_vector (2 downto 0);
    signal FlagToggle_clkA : std_logic;
    
    begin
    	--this changes level when a flag is seen
    	process(clkA)
    	begin
    		if(rising_edge(clkA))then
    			if(FlagIn_clkA = '1')then
    			FlagToggle_clkA <= not FlagToggle_clkA;
    			end if;
    		end if;
    	end process;
    	
    	-- which can then be sync-ed to clkB
    	process(clkB)
    	begin
    		if(rising_edge(clkB))then
    			SyncA_clkB <= (SyncA_clkB(1 downto 0) & FlagToggle_clkA);
    		end if;
    	end process;
    	
    	FlagOut_clkB <= (SyncA_clkB(2) xor SyncA_clkB(1));
    	
    end rtl;

    دیدگاه

    لطفا صبر کنید...
    X