2016-03-10 6 views
-1

Я смущен тем, почему мой проект VHDL не работает. Я должен создать файл top.vhd, который будет программировать плату FPGA для отображения адресов с 0 по 15 и соответствующих значений для каждого адреса. Когда я имитирую свой дизайн, все часы и сбрасывания работают. Проблема, с которой я столкнулась, - это процессы FSM и процесс адреса. Я знаю, что здесь происходит много, поэтому, если вам нужно разъяснение, я могу ответить на ваши вопросы.Modelsim Altera VHDL MEMORY ROM

library IEEE; 
use IEEE.std_logic_1164.ALL; 
use IEEE.numeric_std.all; 

entity top is 

    port(Clock : in std_logic; 
      Reset : in std_logic; 
      SW : in std_logic_vector (1 downto 0); 
      HEX2, HEX4: out std_logic_vector (6 downto 0); 
      KEY0: in std_logic); 

end entity; 

architecture top_arch of top is 

    component char_decoder is 
     port(BIN_IN : in std_logic_vector (3 downto 0); 
      HEX_OUT : out std_logic_vector (6 downto 0)); 
    end component; 

    component rom_16x4_sync is 
     port (clock: in std_logic; 
      address: in std_logic_vector (3 downto 0); 
      rom_en: in std_logic; 
      data_out: out std_logic_vector(3 downto 0)); 
    end component; 

    type state_type is (start, read_rom, clear_addr, done); 
    signal current_state, next_state : state_type; 
    signal Rom_en, addr_count_clr, addr_count_en : std_logic; 
    signal address_counter : integer range 0 to 15; 
    signal address_uns : unsigned (3 downto 0); 
    signal clock_slow : std_logic; 
    signal rom_out : std_logic_vector (3 downto 0); 

    begin 

    char : char_decoder port map (BIN_IN => rom_out, HEX_OUT => HEX2); 
    char1 : char_decoder port map (BIN_IN => std_logic_vector(address_uns), HEX_OUT => HEX4); 
    clock_slow <= Clock; 
    rom : rom_16x4_sync port map (clock => clock_slow, address => std_logic_vector(address_uns), rom_en => Rom_en, data_out => rom_out); 



     State_Memory : process (clock_slow, Reset) 
      begin 
       if (Reset = '0') then 
        current_state <= start; 
       elsif (clock_slow'event and clock_slow = '1') then 
          current_state <= next_state; 
       end if; 
      end process; 

     NEXT_STATE_LOGIC : process (current_state) 
       begin 
        case (current_state) is 
         when start => if (KEY0 = '0') then 
              next_state <= read_rom; 
             else next_state <= start; 
                       end if; 
               when read_rom => if (address_counter = 15) then 
               next_state <= clear_addr; 
               else 
                address_counter <= address_counter + 1; 
               end if; 
         when clear_addr => next_state <= done; 
               address_counter <= 0; 
         when done => next_state <= done; 
         end case; 
       end process; 

     OUTPUT_LOGIC : process (current_state) 
      begin 
       case (current_state) is 
        when start => Rom_en <= '0'; 
              addr_count_en <= '0'; 
              addr_count_clr <= '0'; 
        when read_rom => Rom_en <= '1'; 
              addr_count_en <= '1'; 
              addr_count_clr <= '0'; 
        when clear_addr => Rom_en <= '0'; 
              addr_count_en <= '1'; 
              addr_count_clr <= '1'; 
        when done => Rom_en <= '0'; 
              addr_count_en <= '0'; 
              addr_count_clr <= '0'; 
        end case; 
      end process; 



      Address_Count : process (addr_count_en, addr_count_clr, clock_slow) 
       begin 
       if (clock_slow'event and clock_slow = '1') then 
        if (addr_count_en = '1') then 
         if (addr_count_clr = '1') then 
          address_uns <= "0000"; 
         else 
          address_uns <= address_uns + 1; 
         end if; 
        end if; 
       end if; 
      end process; 
       address_uns <= to_unsigned(address_counter,4); 



end architecture; 
+1

Пожалуйста, также разместите свой тестовый стенд. Какова конкретная проблема, с которой вы сталкиваетесь? Я подозреваю, что ваши часы слишком быстры, чтобы отличить шестнадцатеричный вывод. –

+1

Создайте [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve), так как это поможет сделать полезный ответ, и вы в этом процессе даже можете найти ответ сам. –

+1

[Некоторые вопросы по-прежнему не относятся к теме ...] (http://stackoverflow.com/help/on-topic) 1. Вопросы, требующие отладки («почему этот код не работает?») Должны включать поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения в самом вопросе. Вопросы без четкого описания проблемы не полезны другим читателям. См. [Как создать минимальный, завершенный и проверяемый пример] (http://stackoverflow.com/help/mcve). – user1155120

ответ

0

Я прокомментировал то, что я мог видеть, не так с вашим кодом:

address_counter не разгонял и является излишним. Удалите назначения и измените сравнение на address_uns (которое также должно войти в список чувствительности) в процессе NEXT_STATE_LOGIC. Удалите назначение параллельного сигнала address_uns после процесса Address_Counter. Если процессы Address_Count и OUTPUT_LOGIC верны, а также rom_16x4_sync, у вас должно быть что-то, что работает.

Ну я имел большинство биты и куски, сидящие вокруг других вопросов, ген полный MCVE вместе с небольшим усилием в основном путем копирования и вставки, и что дал:

top_tb.png

Как вы можете видеть, что Бесполезный работа, и причина в том, что address_uns необходимо сбросить (это значение по умолчанию - все «U»).

Добавление сброса дает:

top_tb_address_us_reset

Так суть в том, что ваше состояние машины было почти правильно, он отсутствовал счетчик адреса в его списке чувствительности и два адреса счетчиков. Ограничивая это до одного и сбросив его, чтобы вы не добавляли 1 ко всем «U», показывает, что ваш конечный автомат работает.

И код со всеми исправлениями:

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

entity char_decoder is 
    port (
     bin_in: in std_logic_vector (3 downto 0); 
     hex_out: out std_logic_vector (6 downto 0) 
    ); 
end entity; 

architecture dummy of char_decoder is 
    -- seven segment display 
    -- 
    --  a 
    --  f  b 
    --  g 
    --  e  c 
    --  d 
    -- 
    -- SEGMENT is defined (g downto a) 
    -- 
    type segment7 is array (integer range 0 to 15) of 
           std_logic_vector (6 downto 0); 

    constant hex_to_segment: segment7 := (
       "1000000", -- 0 
       "1111001", -- 1 
       "0100100", -- 2 
       "0110000", -- 3 
       "0011001", -- 4 
       "0010010", -- 5 
       "0000010", -- 6 
       "1111000", -- 7 
       "0000000", -- 8 
       "0011000", -- 9 
       "0001000", -- A 
       "0000011", -- b 
       "0111001", -- C 
       "0100001", -- d 
       "0000110", -- E 
       "0001110" -- F 
      ); 
begin 
    process (bin_in) 
     variable seg7_val: integer range 0 to 15; 
    begin 
     seg7_val := to_integer(unsigned(bin_in)); 

     hex_out <= hex_to_segment(seg7_val); 
    end process; 
end architecture; 

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

entity rom_16x4_sync is 
    port (
     clock: in std_logic; 
     address: in std_logic_vector (3 downto 0); 
     rom_en: in std_logic; 
     data_out: out std_logic_vector(3 downto 0) 
    ); 
end entity; 

architecture dummy of rom_16x4_sync is 
    type rom_array is array (0 to 15) of std_logic_vector(3 downto 0); 

    function fill_rom return rom_array is 
     variable ret_val: rom_array; 
    begin 
     for i in rom_array'reverse_range loop -- backward to i 
      ret_val(i) := std_logic_vector(to_unsigned(i,4)); 
     end loop; 
     return ret_val; 
    end function; 
    constant rom: rom_array := fill_rom; 
begin 
    process (clock) 
    begin 
     if rising_edge(clock) and rom_en = '1' then -- NO RESET 
      data_out <= rom(to_integer(unsigned(address))); 
     end if; 
    end process; 
end architecture; 

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

entity top is 
    port (
     clock:  in std_logic; 
     reset:  in std_logic; 
     sw:   in std_logic_vector (1 downto 0); -- not used? 
     hex2, hex4: out std_logic_vector (6 downto 0); 
     key0:  in std_logic 
    ); 
end entity; 

architecture top_arch of top is 

    component char_decoder is 
     port (
      bin_in: in std_logic_vector (3 downto 0); 
      hex_out: out std_logic_vector (6 downto 0) 
     ); 
    end component; 

    component rom_16x4_sync is 
     port (
      clock: in std_logic; 
      address: in std_logic_vector (3 downto 0); 
      rom_en: in std_logic; 
      data_out: out std_logic_vector(3 downto 0) 
     ); 
    end component; 

    type state_type is (start, read_rom, clear_addr, done); 
    signal current_state, 
      next_state:   state_type; 
    signal rom_en, 
      addr_count_clr, 
      addr_count_en:  std_logic; 
    -- signal address_counter:  integer range 0 to 15; 
    signal address_uns:   unsigned (3 downto 0); 
    signal clock_slow:   std_logic; 
    signal rom_out:    std_logic_vector (3 downto 0); 

    begin 

char: 
    char_decoder 
     port map (
      bin_in => rom_out, 
      hex_out => hex2 
     ); 
char1: 
    char_decoder 
     port map (
      bin_in => std_logic_vector(address_uns), 
      hex_out => hex4 
     ); 

    clock_slow <= clock; 

rom: 
    rom_16x4_sync 
     port map (
      clock => clock_slow, 
      address => std_logic_vector(address_uns), 
      rom_en => rom_en, data_out => rom_out 
     ); 

state_memory: 
    process (clock_slow, reset) 
    begin 
     if reset = '0' then 
      current_state <= start; 
     elsif clock_slow'event and clock_slow = '1' then 
      current_state <= next_state; 
     end if; 
    end process; 

next_state_logic: 
    -- process (current_state) 
    process (current_state, address_uns) 
    begin 
     case (current_state) is 
      when start => 
       if key0 = '0' then 
        next_state <= read_rom; 
       else 
        next_state <= start; 
       end if; 
      when read_rom => 
       if address_uns = 15 then 
        next_state <= clear_addr; 
       -- else 
       -- address_counter <= address_counter + 1; 
       end if; 
      when clear_addr => -- not a defined sequential logic inference 
       next_state <= done; 
       -- address_counter <= 0; 
      when done => 
       next_state <= done; 
     end case; 
    end process; 

output_logic: 
    process (current_state) 
     begin 
      case (current_state) is 
       when start => 
        rom_en <= '0'; 
        addr_count_en <= '0'; 
        addr_count_clr <= '0'; 
       when read_rom => 
        rom_en <= '1'; 
        addr_count_en <= '1'; 
        addr_count_clr <= '0'; 
       when clear_addr => 
        rom_en <= '0'; 
        addr_count_en <= '1'; 
        addr_count_clr <= '1'; 
       when done => 
        rom_en <= '0'; 
        addr_count_en <= '0'; 
        addr_count_clr <= '0'; 
       end case; 
     end process; 

address_count: 
    process (addr_count_en, addr_count_clr, clock_slow) 
    begin 
     if reset = '0' then     -- added reset 
      address_uns <= (others =>'0'); 
     elsif clock_slow'event and clock_slow = '1' then 
      if addr_count_en = '1' then 
       if addr_count_clr = '1' then 
        address_uns <= "0000"; 
       else 
        address_uns <= address_uns + 1; 
       end if; 
      end if; 
     end if; 
    end process; 

    -- address_uns <= to_unsigned(address_counter, 4); 

end architecture; 

library ieee; 
use ieee.std_logic_1164.all; 

entity top_tb is 
end entity; 

architecture foo of top_tb is 
    signal clock:  std_logic := '0'; 
    signal reset:  std_logic := '1'; 
    signal sw:   std_logic_vector (1 downto 0) := "00"; 
    signal hex2, hex4: std_logic_vector (6 downto 0); 
    signal key0:  std_logic := '0'; 
begin 
DUT: 
    entity work.top 
     port map (
      clock => clock, 
      reset => reset, 
      sw => sw, 
      hex2 => hex2, 
      hex4 => hex4, 
      key0 => key0 
     ); 
CLK: 
    process 
    begin 
     wait for 5 ns;  
     clock <= not clock; 
     if now > 200 ns then 
      wait; 
     end if;  
    end process; 

STIMULIS: 
    process 
    begin 
     wait for 1 ns; 
     reset <= '0'; 
     wait for 10 ns; 
     reset <= '1'; 
     wait for 10 ns; 
     wait; 
    end process; 
end architecture; 

char_decoder я должен быть полностью функциональным. Содержимое ПЗУ просто замаскировано.

Смежные вопросы