Перейти к содержанию
    

Помогите разобраться с портом типа INOUT в VHDL

Написал описание однопортового синхронного ОЗУс проверкой синдрома четности. Порт data объявлен как inout, но при моделировании testbench запись в ОЗУ происходит нормально, а вот с чтением проблемы. Когда "дебагил" увидел что при выполнении инструкции "data <= xRAM(conv_integer(addr))(word_size-1 downto 0);" data не меняет своего значения, т.е. в него не записывается значение полученное из xRAM, а сохраняет старое.

Тот же код исправил на 2 порта, один in и один out, все прекрасно работает, но надо написать с использованием inout.

Помогите, плиз, может кто знает в чем проблема???

 

library IEEE;

use IEEE.STD_LOGIC_1164.all;

use IEEE.STD_LOGIC_UNSIGNED.all;

use work.mylib.all;

 

 

entity RAM is

generic (

bw : integer := 3; --разрядность шины адреса

word_size : integer := 4; --разрядность шины данных

ram_size : integer := 8 --ёмкость ОЗУ в словах

);

port (

addr : in std_logic_vector(bw-1 downto 0);

ce, wr, oe, clk : in std_logic;

data : inout std_logic_vector(word_size-1 downto 0)

);

end RAM;

 

architecture Beh of RAM is

 

subtype ram_word is std_logic_vector(word_size downto 0);

type ram_table is array(0 to ram_size-1) of ram_word;

signal xRAM : ram_table;

 

begin

 

write : process(clk, addr, data, ce, wr)

variable bch : std_logic :='1';

begin

if clk'event and clk='1' then

if ce = '1' then

if wr = '0' then

bch:=bitchet(data);

xRAM(conv_integer(addr))(word_size) <= bch;

xRAM(conv_integer(addr))(word_size-1 downto 0) <= data;

 

end if;

end if;

end if;

end process;

read : process(clk, addr, ce, oe, wr)

variable bch : std_logic :='1';

begin

if clk'event and clk='1' then

if ce = '1' then

if wr = '1' then

if oe = '1' then

 

data <= xRAM(conv_integer(addr))(word_size-1 downto 0);

bch:=bitchet(data);

if xRAM(conv_integer(addr))(word_size) /= bch then

 

data<= (others => 'X');

end if;

else

data <= (others => 'Z');

end if;

end if;

end if;

end if;

end process;

end Beh;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте так:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all; 
use work.mylib.all;


entity RAM is
    generic ( 
        bw        : integer := 3; --разрядность шины адреса
        word_size : integer := 4; --разрядность шины данных
        ram_size  : integer := 8  --ёмкость ОЗУ в словах 
    ); 
    port (
        clk  : in std_logic;
        ce   : in std_logic;
        wr   : in std_logic;
        oe   : in std_logic;
        addr : in std_logic_vector(bw-1 downto 0);
        data : inout std_logic_vector(word_size-1 downto 0)
    );
end RAM;

architecture Beh of RAM is

subtype ram_word is std_logic_vector(word_size downto 0);
type ram_table is array(0 to ram_size-1) of ram_word;
signal xRAM : ram_table;

signal r_data : std_logic_vector( word_size - 1 downto 0 );
signal r_data_valid : std_logic;

begin

data <= r_data when ( ( oe = '0' ) and ( r_data_valid = '1' ) ) else (others => 'Z');

write : process(clk)
variable bch : std_logic :='1';
begin 
    if clk'event and clk='1' then
        if ce = '1' then
            if wr = '0' then 
                bch:=bitchet(data);
                xRAM(conv_integer(addr))(word_size) <= bch;
                xRAM(conv_integer(addr))(word_size-1 downto 0) <= data;
            end if;
        end if; 
    end if;
end process;

read : process(clk) 
variable bch : std_logic :='1';
begin 
    if clk'event and clk='1' then
    
        if ( ( ce = '1' ) and ( wr = '1' ) ) then

            r_data <= xRAM(conv_integer(addr))(word_size-1 downto 0);
            bch:=bitchet(data);
            if xRAM(conv_integer(addr))(word_size) /= bch then
                r_data <= (others => 'X');
            end if; 

        end if; 

        if ( ce = '1' ) then
            r_data_valid <= wr;
        end if;

    end if;
end process;

end Beh;

В вашем коде data назначается под clk, то есть является регистром, а регистры с Z не работают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

write : process(clk, addr, data, ce, wr)

Проблема в том что код написан НЕ ПРАВИЛЬНО. Здеесь такие же шедевры уже были. Поищите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

write : process(clk, addr, data, ce, wr)

variable bch : std_logic :='1';

begin

if clk'event and clk='1' then

if ce = '1' then

if wr = '0' then

.....

 

процесс синхронный поэтому все сигналы кроме clk можно убрать из списка чувствительности, но их присутствие не вредит.

 

write : process(clk)

...

read : process(clk)

.....

почитайте доки на любую среду разработки - там примеры есть как память описывать одним процессом.

хотя я лично в этом коде ничего неправильного не вижу.. есть предположение что ошибка в тестбенче и заключается она в том что вы шину данных там не драйвите в Z

 

В вашем коде data назначается под clk, то есть является регистром, а регистры с Z не работают.

с каких это пор зпрещено трехстабильный буфер ставить на выход тригера.. меня както не оповестили

:))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

write : process(clk, addr, data, ce, wr)

variable bch : std_logic :='1';

begin

if clk'event and clk='1' then

if ce = '1' then

if wr = '0' then

.....

 

процесс синхронный поэтому все сигналы кроме clk можно убрать из списка чувствительности, но их присутствие не вредит.

 

write : process(clk)

...

read : process(clk)

.....

почитайте доки на любую среду разработки - там примеры есть как память описывать одним процессом.

хотя я лично в этом коде ничего неправильного не вижу.. есть предположение что ошибка в тестбенче и заключается она в том что вы шину данных там не драйвите в Z

 

В вашем коде data назначается под clk, то есть является регистром, а регистры с Z не работают.

с каких это пор зпрещено трехстабильный буфер ставить на выход тригера.. меня както не оповестили

:))

 

а что значит "заключается она в том что вы шину данных там не драйвите в Z"? как это сделать?

код вроде правильный, так как я уже и говорил, при двух отдельных портах in и out все прекрасно работает....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а что значит "заключается она в том что вы шину данных там не драйвите в Z"? как это сделать?

код вроде правильный, так как я уже и говорил, при двух отдельных портах in и out все прекрасно работает....

дык..

тестбенч в студию..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поясните народу пожалуйста - Вы это синтезировать собираетесь или это просто модель?

 

Четность только при чтении проверяйте, при записи это бессмысленно.

Как Вам уже указали, управление трехстабильным буфером в синхронный процесс не стоило затаскивать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

было

read :
process(clk, addr, ce, oe, wr) 
  variable bch : std_logic :='1';
begin 
  if clk'event and clk='1' then
    if ce = '1' then
      if wr = '1' then
        if oe = '1' then 
          data <= xRAM(conv_integer(addr))(word_size-1 downto 0);
          bch:=bitchet(data);
          if xRAM(conv_integer(addr))(word_size) /= bch then
            data<= (others => 'X');
          end if; 
        else
          data <= (others => 'Z');
        end if;
      end if;
    end if; 
  end if;
end process;

О..

разглядел еще такое:

data - является сигналом, тоесть значение его обнавляется по достижении end process.

bch - переменаая, тоесть меняет свое значение моментально.. но получает на вход неопределенные данные.

думаю нужно так:

          data <= xRAM(conv_integer(addr))(word_size-1 downto 0);
          bch:=bitchet(xRAM(conv_integer(addr))(word_size-1 downto 0));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

data<= (others => 'X');

 

Бесполезно. Используйте другой сигнал.

 

Вообще говоря лучше не используйте std_logic и std_logic_vector как и шины с третьим состоянием. Мало осмыссленно + resolved типы скрывают ошибки. Наверняка Вы в тестах забыли проинициализировать где-нибудь драйвер этого сигнала значением (others => 'Z').

 

О..

разглядел еще такое:

data - является сигналом, тоесть значение его обнавляется по достижении end process.

bch - переменаая, тоесть меняет свое значение моментально.. но получает на вход неопределенные данные.

думаю нужно так:

          data <= xRAM(conv_integer(addr))(word_size-1 downto 0);
          bch:=bitchet(xRAM(conv_integer(addr))(word_size-1 downto 0));

 

Все правильно, похоже, причина именно в этом. В результате всегда xRAM(conv_integer(addr))(word_size) /= bch. Но лучше завести промежуточные переменные, а не повторять код.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а что значит "заключается она в том что вы шину данных там не драйвите в Z"? как это сделать?

код вроде правильный, так как я уже и говорил, при двух отдельных портах in и out все прекрасно работает....

------------------------------------------------

VHDL: Bidirectional Bus:

http://www.altera.com/support/examples/vhdl/v_bidir.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...