2013-07-23 2 views
0

이 일반적인 FPGA 설계 질문에, 나는 FPGA 설계에 새로운 종류의이야 그냥 멋진 선형 대수 해법을 구축, 내 첫 번째 대규모 프로젝트에 착수했다. 시스템은 꽤 큽니다. 그래서 처음부터 올바르게 시작하는 것이 중요합니다. 성공적인 시뮬레이션 후VHDL 상태 머신의 출력 동기화되지

내가 지금 sythensizing하고 있지만, 악몽 데, 나는 구축하고 시뮬레이션에서와 같이 아무것도 작동하지 않기 때문에 구성 요소 구성 요소를 테스트하는 데! 출력은 예를 들어, 동기화되지 않는 여기서 I는 주로이 내가 사용하는 데이터 로더 상태 기계에 문제가있어 :

기본적
entity TriDiag_Data_Scheduler is 
    generic(W : integer :=16; 
       AW : integer := 10 -- address width 
       ); 
    Port (clk : in STD_LOGIC; 
      rst : in STD_LOGIC; --attatched to data finished 
      d_ready : in STD_LOGIC; 
      din : in STD_LOGIC_VECTOR (W-1 downto 0); 
       wr_en : out STD_LOGIC_VECTOR (3 downto 0); 
       dout_a, dout_b, dout_c, dout_y : out STD_LOGIC_VECTOR (W-1 downto 0); 
       addr_out : out STD_LOGIC_VECTOR (AW-1 downto 0)); 
end TriDiag_Data_Scheduler; 

architecture Behavioral of TriDiag_Data_Scheduler is 

type state is (a,b,c,y); 
signal state_pr, state_next : state := y; 
signal addr_reg, addr_next : std_logic_vector(AW-1 downto 0) :=(others =>'1'); 

signal wr_en_next : std_logic_vector(3 downto 0); 

--data buffer 
signal d_buff, d_buff_a, d_buff_b, d_buff_c, d_buff_y : std_logic_vector (W-1 downto 0) :=(others =>'0'); 
signal d_buff_a_reg, d_buff_b_reg, d_buff_c_reg, d_buff_y_reg : std_logic_vector (W-1 downto 0) :=(others =>'0'); 

begin 

process(clk,rst) 
begin 
    if(clk'event and clk ='1') then 
     state_pr <= state_next; 
     d_buff_a <= d_buff_a_reg; 
     d_buff_b <= d_buff_b_reg; 
     d_buff_c <= d_buff_c_reg; 
     d_buff_y <= d_buff_y_reg; 

     addr_reg <= addr_next; 
     wr_en <= wr_en_next; 
    end if; 

end process; 

addr_out <= addr_reg; 
dout_a <= d_buff_a; 
dout_b <= d_buff_b; 
dout_c <= d_buff_c; 
dout_y <= d_buff_y; 


--Data out logic 
process(state_pr, d_buff_a, d_buff_b, d_buff_c, d_buff_y, d_buff) 
begin 

    d_buff_a_reg <= d_buff_a; 
    d_buff_b_reg <= d_buff_b; 
    d_buff_c_reg <= d_buff_c; 
    d_buff_y_reg <= d_buff_y; 

    case state_pr is 
     when a => --move data to a reg 
      d_buff_a_reg <= d_buff; 
     when b => --move data to b reg 
      d_buff_b_reg <= d_buff; 
     when c => --move data to c reg 
      d_buff_c_reg <= d_buff; 
     when y => 
      d_buff_y_reg <= d_buff; 
    end case; 
end process; 

--next state and addr logic 
process(state_pr, d_ready, rst, din) 
begin 

    state_next <= state_pr; 
    addr_next <= addr_reg; 
    wr_en_next <= (others => '0'); 

if(rst = '1') then 
    state_next <= a; 
    addr_next <= (others =>'1'); 
    wr_en_next <= (others => '0'); 
elsif(d_ready = '1') then 
--Read in the data to the buffer 
    d_buff <= din; 
--next state logic 
    case state_pr is 
     when a => --move data to a reg 
      addr_next <= addr_reg + 1; 
     -- d_buff_a_reg <= din; 
      wr_en_next <= "0001"; 
      state_next <= b; 
     when b => --move data to b reg 
      wr_en_next <= "0010"; 
     -- d_buff_b_reg <= din; 
      state_next <= c; 
     when c => --move data to c reg 
      wr_en_next <= "0100"; 
     -- d_buff_c_reg <= din; 
      state_next <= y; 
     when y => 
     -- d_buff_y_reg <= din; 
      wr_en_next <= "1000"; 
      state_next <= a; 
    end case; 
end if; 
end process; 
end Behavioral; 

데이터는 UART 모듈을 통해 수신 될 때의 작업이 다음에로드하는 것 올바른 메모리 (write_en 신호로 제어 됨). 문제는 모든 디자인에서 (이것은 리비전 7입니다) 모든 addr_out, wr_en 및 올바른 데이터가 syn에 있지만, 합성에서 addr 및 wr_en이 데이터와 syn에없고 이전의 절반에서 읽음을 계속 찾습니다. 이전 상태의 절반입니다.

어떤 디자인 사례를 나는 각 구성 요소에 대한 내 모든 이전의 하드 작업을 다시 작성해야 내 VHDL 때문에이 속도 친화적 더 syntheziable이되도록 사용해야합니다! d_ready 신호가 다른 모듈에서 주장 사이에 디자인 작업

많은 감사 샘

+0

내 VHDL 집은 사과 있도록 가르쳐! –

+1

큰 민감도 목록이있는 비 시계 프로세스를 볼 때마다 그 중 일부가 누락되었다고 가정합니다. 나는 세부 사항을 자세히 살펴 보지 못했지만 신디사이저 경고를 확인하여 아무것도 발견되었는지 확인합니다. 개인적으로 나는 이것을 단일 클록 된 프로세스로 다시 작성합니다. –

+0

Martin에게 다시 한번 감사드립니다. 문제는 외부 d_ready 신호에 민감하다는 것입니다. 나는 d_ready 신호에 의해 설정되었지만 clk에 주장 된 동기 틱을 추가하여 문제를 해결했습니다. 나는 d_ready와 clk 사이의 아주 좋은 왜곡으로 고통 받고 있다고 생각하는데, 이것이 왜 모두 동기화되지 않았는가하는 것입니다. 그러나 이제는 동기 틱에 모든 것이 활성화되어 작동하는 것 같습니다. –

답변

0

는, 기존의 디자인은 스큐 앓고 이는 CLK 모듈. 이와 같이 변경 사항이 처음에는 동기화되지 않는 경우가 있습니다. 이 문제를 해결하기 위해 d_tick_next 신호를 사용했지만 모든 올바른 동작을 허용하는 로컬 동기화 신호 d_tick을 어설 션합니다. 한 교훈을 배웠습니다 (내가 틀렸다면 수정하십시오)는 수신 모듈 clk와 동기화되도록 외부에서 클럭 된 신호 (예 : d_ready)에 의존 할 수 없다는 것입니다.

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use ieee.std_logic_unsigned.all; 

-- Uncomment the following library declaration if using 
-- arithmetic functions with Signed or Unsigned values 
--use IEEE.NUMERIC_STD.ALL; 

-- Uncomment the following library declaration if instantiating 
-- any Xilinx primitives in this code. 
--library UNISIM; 
--use UNISIM.VComponents.all; 


-- //////////////////////////////////////////////////////////////////// 
--Takes in the linear stream of data and builds up the memory structure 

--INPUT DATA MUST FOLLOW SEQUENCE [a b c] x = [y] (0 if a or c do not exist) rows 0 and N respectivly 
--////////////////////////////////////////////////////////////////////// 
entity TriDiag_Data_Scheduler is 
    generic(W : integer :=16; 
       AW : integer := 10 -- address width 
       ); 
    Port (clk : in STD_LOGIC; 
      rst : in STD_LOGIC; --attatched to data finished 
      d_ready : in STD_LOGIC; 
      din : in STD_LOGIC_VECTOR (W-1 downto 0); 
       wr_en : out STD_LOGIC_VECTOR (3 downto 0); 
       dout_a, dout_b, dout_c, dout_y : out STD_LOGIC_VECTOR (W-1 downto 0); 
       addr_out : out STD_LOGIC_VECTOR (AW-1 downto 0)); 
end TriDiag_Data_Scheduler; 

architecture Behavioral of TriDiag_Data_Scheduler is 

type state is (a,b,c,y); 
signal state_pr, state_next : state := y; 
signal addr_reg, addr_next : std_logic_vector(AW-1 downto 0) :=(others =>'1'); 

signal wr_en_next : std_logic_vector(3 downto 0); 

signal d_tick, d_tick_next : std_logic; 

--data buffer 
signal d_buff, d_buff_a, d_buff_b, d_buff_c, d_buff_y : std_logic_vector (W-1 downto 0) :=(others =>'0'); 
signal d_buff_a_reg, d_buff_b_reg, d_buff_c_reg, d_buff_y_reg : std_logic_vector (W-1 downto 0) :=(others =>'0'); 

begin 

process(clk,rst) 
begin 
    if(clk'event and clk ='1') then 
     state_pr <= state_next; 

     d_buff_a <= d_buff_a_reg; 
     d_buff_b <= d_buff_b_reg; 
     d_buff_c <= d_buff_c_reg; 
     d_buff_y <= d_buff_y_reg; 

     d_tick <= d_tick_next; 

     addr_reg <= addr_next; 
     wr_en <= wr_en_next; 
    end if; 

end process; 

addr_out <= addr_reg; 
dout_a <= d_buff_a; 
dout_b <= d_buff_b; 
dout_c <= d_buff_c; 
dout_y <= d_buff_y; 


--Data out logic 
process(state_pr,d_tick,rst) 
begin 

    d_buff_a_reg <= d_buff_a; 
    d_buff_b_reg <= d_buff_b; 
    d_buff_c_reg <= d_buff_c; 
    d_buff_y_reg <= d_buff_y; 

    wr_en_next <= (others => '0'); 

if(rst = '1') then 
    addr_next <= (others =>'1'); 
else 
    addr_next <= addr_reg; 
end if; 

if(d_tick = '1') then 
    case state_pr is 
     when a => --move data to a reg 
      d_buff_a_reg <= d_buff; 
      addr_next <= addr_reg + 1; 
      wr_en_next <= "0001"; 
     when b => --move data to b reg 
      d_buff_b_reg <= d_buff; 
      wr_en_next <= "0010"; 
     when c => --move data to c reg 
      d_buff_c_reg <= d_buff; 
      wr_en_next <= "0100"; 
     when y => 
      d_buff_y_reg <= d_buff; 
      wr_en_next <= "1000"; 
    end case; 
end if; 
end process; 

--next state and d_tick 
process(state_pr, d_ready, rst, din) 
begin 

    state_next <= state_pr; 
    d_tick_next <='0'; 

if(rst = '1') then 
    state_next <= y; 
elsif(d_ready = '1') then 
--Read in the data to the buffer 
    d_buff <= din; 
-- set sync tick 
    d_tick_next <= '1'; 
--next state logic 
    case state_pr is 
     when a => 
      state_next <= b; 
     when b => 
      state_next <= c; 
     when c => 
      state_next <= y; 
     when y => 
      state_next <= a; 
    end case; 
end if; 
end process; 

end Behavioral; 이 사람을 기분을 상하게하는 경우

+0

첫 번째 프로세스 (d_buff *, addr_reg 등)의 민감도 목록에 많은 신호가 누락되었습니다. 여전히 d_buff에 대한 래치를 생성 중입니다. 이 두 가지 모두 합성 과정에서 경고로 표시됩니다. 무시하지 마세요. 따라서 시뮬레이션에서는 작동하지만 하드웨어에서는 작동하지 않으면 놀라지 마십시오. 현재 하드웨어에서 작동하는 것으로 보이면 나중에 문제가 발생할 수 있다는 경고를받습니다. – zennehoy

+0

안녕하세요 Zennehoy, 시간 경과에 따른 din 변경으로 래치가 일시적으로 din 상태를 저장해야합니다. 민감도에 관해서는 ISE가 나를 위해 그들을 유추하기에 충분하지만 네, 경고를받습니다! 그러나 내 전자 제품이 오히려 카우보이 인 것처럼 내가 틀렸다면 나를 바로 잡으십시오! –

+0

이 기사는 왜 http://www.doulos.com/knowhow/fpga/latches/인지 설명합니다. 대신 에지 트리거 플립 플롭을 사용하도록 작성하는 것이 좋습니다. 내가 전에 겪었던 문제는 clk와 d_ready가 신호를 받았을 때 d_buff가 불완전하게 채워지는 사이의 왜곡 때문에 가장자리에있을 때였 다. –