2016-08-22 5 views
-1

을 VHDL로 작성하십시오. 모든 코드 라인은 컴퓨터이므로 병렬 방식으로 실행됩니다. RAM 블록에서 출력으로 특정 레지스터를 읽는이 RAM을 만들고 '이후'만 동일한 레지스터에 입력을 쓰고 싶습니다. 내 코드는 다음과 같이 진행됩니다읽기, RAM VHDL

architecture Behavioral of RAM is 

type ram_t is array (0 to numOfRegs-1) of std_logic_vector (rLength-1 downto 0); 
signal ram_s: ram_t; 
signal loc : integer; 

begin 

process(clk) 
begin 
    if(rising_edge(clk)) then 
     if(we='1') then 
      dataout <= ram_s(loc); -- reads the 'old' data to the output 
      ram_s(loc) <= datain; -- writes the 'new' data to the RAM 
      loc <= conv_integer(addr); 
     end if; 
    end if; 
end process;     
end Behavioral; 

here되게 유사한 경우가 있습니다.

내 코드가 잘 작동하는지 또는 반 클록주기의 지연을 넣는 것과 같이 조정할 필요가 있는지 묻고 싶습니다. 그렇다면 구현 방법은 무엇입니까? 귀하의 인내와 도움에 감사 드리며 VHDL에 매우 익숙합니다.

아래 테스트 벤치 시뮬레이션을 추가하십시오. 볼 수 있듯이 데이터 출력은 전혀 작동하지 않습니다.

testbench i've simulated

+0

시뮬레이션에서 원하는대로 할 수 있습니까? –

+1

쓰기가 가능할 때만 데이터를 읽으려고합니까? –

답변

1

귀하의 질문은 결과를 복제 할 수있는 능력을 결여하는 Minimal, Verifiable and Complete example 존재하지 않습니다.

결과 중 하나는 표시되지 않은 코드 부분에 문제의 원인이 하나 이상있는 경우 대답이 모호 할 수 있다는 것입니다.

우리가 유효하지 않을 때 데이터를 읽지 않는다는 브라이언의 의견은 신랄하며, 웨이브에서 노란색 마커 왼쪽의 시계 사이클에 대한 책임이 있습니다.

loc 신호와 관련하여 문제가 있습니다. 신호는 업데이트 예정이며 현재 시뮬레이션주기에서 다시 시작하도록 예약 된 프로세스가 재개되지 않고 일시 중단되지 않은 상태에서 업데이트가 발생하지 않습니다.

이것은 주소의 정수 버전이 지연되어 다음 상승 에지까지 처리되지 않음을 의미합니다. 파이프 라이닝 datain에 대한 대안으로 그것을 변수를 만들고 당신의 RAM 과정을 다음과 같이 변경으로 수행하는 dataout 할당을 이동하여 loc 고정

는 :

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; -- standard package 

entity ram is 
    generic (
     ADDRLENGTH: natural := 8; 
     RLENGTH: natural := 16; 
     NUMOFREGS: natural := 256 
    ); 
    port (
     clk:  in std_logic; 
     we:   in std_logic; 
     addr:  in std_logic_vector (ADDRLENGTH - 1 downto 0); 
     datain:  in std_logic_vector (RLENGTH - 1 downto 0); 
     dataout: out std_logic_vector (RLENGTH - 1 downto 0) 
    ); 

end entity; 

architecture behavioral of ram is 

    type ram_t is array (0 to NUMOFREGS - 1) of 
      std_logic_vector (RLENGTH - 1 downto 0); 
    signal ram_s: ram_t; 

    -- signal loc: integer; -- USE VARIABLE in process instead 

begin 

    process(clk) 
    variable loc: integer; -- MAKE loc variable so it's immediately available 
    begin 
     if rising_edge(clk) then 
      loc := to_integer(unsigned(addr)); -- MOVED so READ works 
      if we = '1' then 
       -- dataout <= ram_s(loc); -- reads the 'old' data to the output 
       ram_s(loc) <= datain; -- writes the 'new' data to the ram 
       -- loc <= conv_integer(addr); 
      end if; 
      dataout <= ram_s(loc); -- MOVED reads the 'old' data to the output 
     end if; 
    end process;     
end architecture behavioral; 

또한 엔티티 선언에서 작성의 자유있다 Synopsys의 std_logic_arith 패키지를 사용하여 conv_integer에서 IEEE numeric_std 패키지의 to_integer으로 변환합니다. -2008 호환 도구 체인을 사용하면 대신 IEEE의 패키지 numeric_std_unsigned를 사용하여 형식 변환을 사용하지 않고 부호없는 상태로 만들 수 있습니다.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity ram_tb is 
end entity; 

architecture foo of ram_tb is 
    constant ADDRLENGTH: natural := 8; 
    constant RLENGTH: natural := 16; 
    constant NUMOFREGS: natural := 256; 
    signal clk:  std_logic := '0'; 
    signal we:   std_logic := '1'; 
    signal addr:  std_logic_vector (ADDRLENGTH - 1 downto 0); 
    signal datain:  std_logic_vector (RLENGTH - 1 downto 0); 
    signal dataout: std_logic_vector (RLENGTH - 1 downto 0); 

begin 
DUT: 
    entity work.ram 
     generic map (
      ADDRLENGTH => ADDRLENGTH, 
      RLENGTH => RLENGTH, 
      NUMOFREGS => NUMOFREGS 
     ) 
     port map (
      clk => clk, 
      we => we, 
      addr => addr, 
      datain => datain, 
      dataout => dataout 
     ); 

CLOCK: 
    process 
    begin 
     if now = 500 ps then 
      wait for 200 ps; 
     else 
      wait for 100 ps; 
     end if; 
     clk <= not clk; 
     if now >= 1100 ps then 
      wait; 
     end if; 
    end process; 

STIMULI: 
    process 
    begin 
     for i in 0 to 2 loop 
      addr <= std_logic_vector(to_unsigned (i, ADDRLENGTH)); 
      case i is 
       when 0 => 
        datain <= x"00FF"; 
       when 1 => 
        datain <= x"FF00"; 
       when 2 => 
        datain <= x"FFFF"; 
      end case; 
      wait until falling_edge(clk); 
      if i = 1 then 
       we <= '0'; 
      end if; 
     end loop; 
     for i in 1 to 2 loop 
      addr <= std_logic_vector(to_unsigned (i, ADDRLENGTH)); 
      case i is 
       when 1 => 
        datain <= x"FF00"; 
       when 2 => 
        datain <= x"FFFF"; 
      end case; 
      wait until falling_edge(clk); 
     end loop;   
     wait; 
    end process; 

end architecture; 

그리고 이것은 생산 :

ram_tb_match.png

를 하나 개 기록 된 주소입니다 경우 테스트 벤치가 파형 디스플레이 이미지를 복제하기 위해 작성되었다 ram_test 테스트 벤치도 공급되지 않았기 때문에

이후에 올바른 데이터가 표시됩니다.

사용 된 시뮬레이터는 파형 덤프에 비 신호를 표시하지 않으며 (선언의 경계는 정적이어야합니다) 제공된 설계 사양 부분에 rst이 없습니다.

앞서 지적한 것처럼 설계 사양 또는 테스트 벤치의 일부가 귀하의 질문에 제공되지 않은 다른 문제가 있다는 보장은 없습니다.

표시된 테스트 벤치는 결코 포괄적 인 것은 아닙니다.