2013-10-26 1 views
1

VHDL의 배열에서 2 개의 다른 주소에서 2 개의 값을 할당하려고하지만 어떻게 든 항상 잘못된 값 (대부분의 시간 0)을 반환합니다. 나는 그것을 단지 1 개의 주소와 1 개의 데이터 출력으로 테스트하여 정확한 값을 반환했다.VHDL에서 동일한 배열의 두 요소에 액세스

architecture Behavioral of registerFile is 
    type reg_type is array (31 downto 0) of std_logic_vector (31 downto 0); 
    signal REG : reg_type := (x"00000031", x"00000030", x"00000029", x"00000028", x"00000027", x"00000026", x"00000025", x"00000024", x"00000023", x"00000022", x"00000021", x"00000020",x"00000019",x"00000018", x"00000017", x"00000016", x"00000015", x"00000014", x"00000013", x"00000012", x"00000011", x"00000010", x"00000009", x"00000008", x"00000007",x"00000006", x"00000005", x"00000004", x"00000003", x"00000004", x"00000001", x"00000000"); 
begin 
process(clk) 
begin 
    if clk'event and clk='1' then 
     if ENABLE = '1' then 
      if readReg = '1' then -- read from register 
       DATAone <= REG(conv_integer(ADDRone)); 
       DATAtwo <= REG(conv_integer(ADDRtwo)); 
      else 
       REG(conv_integer(ADDRone)) <= DATAone; 
       REG(conv_integer(ADDRtwo)) <= DATAtwo; 
      end if; 
     end if; 
    end if; 
end process; 
end Behavioral; 

Google 검색을 시도했지만 모든 것이 다차원 배열이거나 한 번에 1 개 요소 만 액세스합니다.

감사합니다.

+0

1) 엔티티 선언을 게시 할 수 있습니까? 2) 모듈 입력을 어떻게 유도합니까? 3) 시뮬레이터에서 정확히 무엇이 일어나고 있습니까? – godel9

+0

DATAone과 DATAtwo는 읽기와 쓰기 모두에 사용되므로 읽기 값도 다시 쓰여진 값입니다 ... 이것은 이상하게 보입니다. 나는 레지스터 파일이 읽기와 쓰기를위한 별도의 데이터 포트를 가질 것으로 기대한다. OK일지도 모르지만 요구 사항에 대한 배경을 좀 더 알려주고 엔티티 선언을 게시하여 전체 그림을 얻는 것이 더 쉽습니다. –

+0

감사합니다. 그것은 시뮬레이션 작업 중이지만 FPGA에서는 작동하지 않습니다. 그러나 이것을 변경 한 후에 작동합니다. 나는 이것을 놓쳤다 고 생각한다. – charpi

답변

0

저는 이것이 대부분의 구조에서 합성 가능하다는 것을 확신하지 못합니다. 당신은 각각에 reg 배열과 인덱스의 두 복사본을 생성 할 수 있습니다.

0

쿼드 포트 메모리를 구현하려는 것 같습니다. 어쨌든, 레지스터 파일이 정확히 4 포트 메모리가 아니더라도, 아마 하나 주위에 구현 될 수 있습니다.

알테라의 메모리 예는 Advanced Synthesis Cookbook입니다. 알테라의 예제 파일을 사용하는 경우는 알테라의 기본 요소를 인스턴스화 및 저장을위한 FPGA 블록 RAM을 사용합니다

Altera Simple Quad Port RAM Example

: 사진은 아래의 관련 부분을 보여줍니다. 이식성에 관심이 있거나 원하는 것을 수행하는 VHDL 코드를보고 싶다면 아래 예제를 확인하십시오. 그림과 같이 대략 동일한 회로를 구현하며 FPGA에서 분산 메모리로 합성 될 가능성이 큽니다.

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

-- Quad-port RAM with 2 read ports 2 write ports. The design uses 2 memory blocks 
-- (MAIN_MEMORY and SHADOW_MEMORY) to allow for simultaneous writes. Port A writes to 
-- main memory, Port B writes to shadow memory. On a read from either port, data is 
-- read from the memory block that was most recently written at the given position. 
entity quad_port_ram is 
    generic (
     ADDRESS_WIDTH: natural := 5; 
     DATA_WIDTH: natural := 32 
    ); 
    port (
     clock: in std_logic; 

     read_addr_a: in natural range 0 to 2**ADDRESS_WIDTH-1; 
     read_data_a: out std_logic_vector(DATA_WIDTH-1 downto 0); 
     write_addr_a: in natural range 0 to 2**ADDRESS_WIDTH-1; 
     write_data_a: in std_logic_vector(DATA_WIDTH-1 downto 0); 
     write_enable_a: in std_logic; 

     read_addr_b: in natural range 0 to 2**ADDRESS_WIDTH-1; 
     read_data_b: out std_logic_vector(DATA_WIDTH-1 downto 0); 
     write_addr_b: in natural range 0 to 2**ADDRESS_WIDTH-1; 
     write_data_b: in std_logic_vector(DATA_WIDTH-1 downto 0); 
     write_enable_b: in std_logic 
    ); 
end; 

architecture rtl of quad_port_ram is 

    type memory_type is (MAIN_MEMORY, SHADOW_MEMORY); 
    type memory_type_array is array (natural range <>) of memory_type; 

    -- Keep track of which memory has the most recently written data for each address 
    signal most_recent_port_for_address: memory_type_array(0 to 2**ADDRESS_WIDTH-1); 

    type memory_array is array (0 to 2**ADDRESS_WIDTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0); 
    type dual_memory_array is array (memory_type) of memory_array; 

    -- Store the actual memory bits. Access like this: 
    -- memory_data(memory_type)(address)(bit_position) 
    signal memory_data: dual_memory_array; 

    -- Auxiliary signals to decide where to read the data from (main or shadow) 
    signal most_recent_port_for_addr_a, most_recent_port_for_addr_b: memory_type; 
begin 

    process (clock) begin 
     if rising_edge(clock) then 

      if write_enable_a then 
       memory_data(MAIN_MEMORY)(write_addr_a) <= write_data_a; 
       most_recent_port_for_address(write_addr_a) <= MAIN_MEMORY; 
      end if; 

      if write_enable_b then 
       if (write_enable_a = '0') or (write_addr_a /= write_addr_b) then 
        memory_data(SHADOW_MEMORY)(write_addr_b) <= write_data_b; 
        most_recent_port_for_address(write_addr_b) <= SHADOW_MEMORY; 
       end if; 
      end if; 
     end if; 

    end process; 

    most_recent_port_for_addr_a <= most_recent_port_for_address(read_addr_a); 
    most_recent_port_for_addr_b <= most_recent_port_for_address(read_addr_b); 

    read_data_a <= memory_data(most_recent_port_for_addr_a)(read_addr_a); 
    read_data_b <= memory_data(most_recent_port_for_addr_b)(read_addr_b); 

end; 
관련 문제