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

В одном процессе я принимаю команды

 when X"01" =>  --continious data read
         cont_ram_addr := to_integer(unsigned(addr_bus));
       ram_command <= RAM_CONT_WRITE;
     when X"02" =>  --continious data write
         cont_ram_addr := to_integer(unsigned(addr_bus));
       ram_command <= RAM_CONT_READ;
     when X"03" => --read data command 
         ram_command <= RAM_BYTE_WRITE;
     when X"04" => --write data command 
         ram_command <= RAM_BYTE_READ;

В другом я проверяю команду и в соответсвии команде делаю какое то действие.

case RamState is
        when ST_IDLE =>
        if(ram_command > "000") then  
          case ram_command is
           when RAM_CONT_WRITE => RamState <= ST_CONT_WR_RAM;
           when RAM_CONT_READ  => RamState <= ST_CONT_RD_RAM;
           when RAM_BYTE_WRITE => RamState <= ST_WR_RAM;
           when RAM_BYTE_READ  => RamState <= ST_RD_RAM;
           when others => RamState <= ST_IDLE;
       end case;
      end if;
      
    when ST_WR_RAM =>   - 
        --do something
      RamState <= ST_IDLE;
      
      when ST_RD_RAM =>   
        --do something
        RamState <= ST_IDLE;

    when ST_CONT_WR_RAM =>        
        -do something
      RamState <= ST_IDLE;

    when ST_CONT_RD_RAM =>
     -- do something 
        RamState <= ST_IDLE;

Но когда мне обнулить ram_command?

Иначе я вернусь в ST_IDLE и снова case ram_command и так буду крутиться в бесконечном цикле.

Логично было бы обнулить ram_command во втором процессе но тогда я получу

Error (10028): Can't resolve multiple constant drivers for net

Получается нет синхронизации между процессами.

 

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


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

Логично было бы обнулить ram_command во втором процессе но тогда я получу
Опять те же грабли? Запомните раз и навсегда первое: вы не программу пишете, а "рисуете" схему словами. Запомните раз и навсегда второе: сигнал в схеме -- это не переменная в программе, вы не можете изменять один сигнал из двух независимых источников. Это всё равно что физически соединить выходы двух устройств.

Получается нет синхронизации между процессами.
Вы разработчик, вы и сделайте так, чтобы она была.

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


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

Опять те же грабли? Запомните раз и навсегда первое: вы не программу пишете, а "рисуете" схему словами. Запомните раз и навсегда второе: сигнал в схеме -- это не переменная в программе, вы не можете изменять один сигнал из двух независимых источников. Это всё равно что физически соединить выходы двух устройств.

это я таки понял.

 

Вы разработчик, вы и сделайте так, чтобы она была.

опыта в VHDL не хватает. иначе спрашивал я бы на форуме?

 

 

Изменено пользователем Jenya7

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


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

А что мешает обнулять ram_command в первом процессе?

 

И что мешает принимать ram_command и совершать действия по ней в одном процессе?

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


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

Ну, вы можете:

- автоматически обнулить ram_command после одного или нескольких тактов;

- сделать так, чтобы вторая часть выдавала сигнал завершения по-которому ram_command будет сбрасываться;

- в конце концов, объединить обе части в один процесс.

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


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

опыта в VHDL не хватает.
А чо сразу VHDL? Это лишь средство реализации алгоритма. У вас до конца не продуман именно алгоритм работы. Вы не кидайтесь сразу код писать, а распишите детально алгоритм. На листочке, что ли. Диаграммы сигналов нарисуйте потактово. Вот когда всё сойдётся, тогда и код будет проще писать.

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


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

А что мешает обнулять ram_command в первом процессе?

 

И что мешает принимать ram_command и совершать действия по ней в одном процессе?

 

 

Ну, вы можете:

- автоматически обнулить ram_command после одного или нескольких тактов;

- сделать так, чтобы вторая часть выдавала сигнал завершения по-которому ram_command будет сбрасываться;

- в конце концов, объединить обе части в один процесс.

 

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

вот я и подумал выделить отдельные процессы – для RAM для с мср25625 и так далее -

так разные таски могут работать параллельно. если я засуну все в один процесс -пришла следующая команда а я еще обрабатываю предыдущую. а так - пришла команда для RAM - выставил ram_command, пришла команда для mcp25625 – выставил mcp25625_command и оба таска выполняют свои задачи паралельно.

 

автоматически обнулить ram_command после одного или нескольких тактов

spi_slave_interface : process(REG_CLK, REG_RSTn, SPI_DATA_LATCH)
begin 
     
    if(REG_RSTn = '0') then
         --REG_DATA_OUT <= (others => '0');
          --State <= ST_IDLE;
          --command <= "000";
          --MSPI_CS <= '1';
     elsif (rising_edge(REG_CLK) and SPI_DATA_LATCH = '1') then  --REG_DATA_LATCH to be sure command, address, data was received from spi slave
     
         if (REG_COM_IN(7 downto 5) = REG_CHAN) then  --select spi channel
             
              case REG_COM_IN(4 downto 0) is --command from mcu spi 
              
                    when "00001" =>  --continious data read
                        cont_ram_addr := to_integer(unsigned(addr_bus));
                         ram_command <= RAM_CONT_WRITE;
                         
                    when "00010" =>  --continious data write
                        cont_ram_addr := to_integer(unsigned(addr_bus));
                         ram_command <= RAM_CONT_READ;
                         
                    when "00011" => --read data command 
                        ram_command <= RAM_BYTE_WRITE;
                        
                    when "00100" =>    --write data command    
                        ram_command <= RAM_BYTE_READ;
                                            
             end case;

             ram_command <= "000";

         end if;
         
    end if;
end process spi_slave_interface;

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

Изменено пользователем Jenya7

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


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

вам надо бы разобраться с типовыми "кусками", применяемыми в ПЛИС для решения тех или иных задач. когда применять очереди (FIFO), арбитры, планировщики (scheduler),

рекомендую к прочтению:

10_lec08.pdf

 

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

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


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

Так а почему нельзя написать так:

 

when "00011" => --read data command

ram_command <= RAM_BYTE_WRITE;

 

when "00100" => --write data command

ram_command <= RAM_BYTE_READ;

WHEN OTHERS => ram_command <= NOPE;

 

end case;

Где NOPE это и есть "000".

Весь процесс я бы вот так написал

 

SPI_SLAVE_INTERFACE : PROCESS
(
    REG_CLK
)
BEGIN 
    IF (RISING_EDGE(REG_CLK)) THEN
        IF (SPI_DATA_LATCH = '1') THEN  --REG_DATA_LATCH TO BE SURE COMMAND, ADDRESS, DATA WAS RECEIVED FROM SPI SLAVE
            IF (REG_COM_IN(7 DOWNTO 5) = REG_CHAN) THEN  --SELECT SPI CHANNEL
                CASE REG_COM_IN(4 DOWNTO 0) IS --COMMAND FROM MCU SPI 
                    WHEN "00001" =>  --CONTINIOUS DATA READ
                                    CONT_RAM_ADDR <= TO_INTEGER(UNSIGNED(ADDR_BUS));
                                    RAM_COMMAND <= RAM_CONT_WRITE;
                         
                    WHEN "00010" =>  --CONTINIOUS DATA WRITE
                                    CONT_RAM_ADDR <= TO_INTEGER(UNSIGNED(ADDR_BUS));
                                    RAM_COMMAND <= RAM_CONT_READ;
                         
                    WHEN "00011" => --READ DATA COMMAND 
                                    RAM_COMMAND <= RAM_BYTE_WRITE;
                        
                    WHEN "00100" =>    --WRITE DATA COMMAND    
                                    RAM_COMMAND <= RAM_BYTE_READ;
                    WHEN OTHERS =>  RAM_COMMAND <= NOPE;
                END CASE;
            END IF;
        END IF;
        IF (REG_RSTN = '0') THEN
            REG_DATA_OUT <= (OTHERS => '0');
            STATE <= ST_IDLE;
            COMMAND <= NOPE;
            MSPI_CS <= '1';
        END IF;
    END IF;
END PROCESS;

Изменено пользователем Flip-fl0p

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


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

вам надо бы разобраться с типовыми "кусками", применяемыми в ПЛИС для решения тех или иных задач. когда применять очереди (FIFO), арбитры, планировщики (scheduler),

рекомендую к прочтению:

10_lec08.pdf

 

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

почитал. там все на уровне блок-диаграм.

а FIFO мне нужно несколько я так понимаю? для каждой комманды FIFO? я привел кусок процесса. а там кроме ram_command есть и другие команды.

 

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


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

почитал. там все на уровне блок-диаграм.

а FIFO мне нужно несколько я так понимаю? для каждой комманды FIFO? я привел кусок процесса. а там кроме ram_command есть и другие команды.

Смотря что Вам нужно. Двупортовое FIFO я обычно применяю для пересечения клоковых доменов. Однопортовое FIFO я использую когда каике-то команды\запросы идут с одной периодичностью, к примеру раз в 3 такта. А блок, который эти запросы обрабатывает тратит 10 тактов. Но обычно требуется механизм защиты от переполнения FIFO. Тут уже всё упирается в Вашу фантазию.

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


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

Где NOPE это и есть "000".

Весь процесс я бы вот так написал

 

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

 

WHEN OTHERS => RAM_COMMAND <= NOPE;

 

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

я этот момент не очень понял. WHEN OTHERS сработает по условию прихода команды - SPI_DATA_LATCH = '1'. а если команда не пришла? RAM_COMMAND останется на предыдущем кейсе.

 

 

а если так?

IF (SPI_DATA_LATCH = '1') THEN  
-----------------------------------
----------------------------------
ELSE

    RAM_COMMAND <= NOPE;

END IF;

Изменено пользователем Jenya7

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


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

я этот момент не очень понял. WHEN OTHERS сработает по условию прихода команды - SPI_DATA_LATCH = '1'. а если команда не пришла? RAM_COMMAND останется на предыдущем кейсе.

Ошибся я что-то :crying:

Я вижу 2 путя:

Первый:

IF (RISING_EDGE(REG_CLK)) THEN
    RAM_COMMAND <= NOPE;

А второй - это использовать сигнал (SPI_DATA_LATCH = '1'), как сигнал разрешения работы с память. Т.е пока он равен нулю, памяти без разницы состояние регистра RAM_COMMAND.

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


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

Ошибся я что-то :crying:

Я вижу 2 путя:

Первый:

IF (RISING_EDGE(REG_CLK)) THEN
    RAM_COMMAND <= NOPE;

А второй - это использовать сигнал (SPI_DATA_LATCH = '1'), как сигнал разрешения работы с память. Т.е пока он равен нулю, памяти без разницы состояние регистра RAM_COMMAND.

первый опасный. у второго процесса будет только один клок захватить ram_command.

а второй это идея. SPI_DATA_LATCH защелкнет мне и состояние ram_command . да. это идея.... следущая тема будет - где поднять и где опустить SPI_DATA_LATCH. :)

Изменено пользователем Jenya7

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


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

Зря вы отвергли предлагаемые вам пути решения проблемы (предлагали в других темах)

 

У вас "программистическое" мышление, ну так и надо делать программисткие описания.

Будет не супер оптимально, зато результат будет без боли и гораздо быстрее.

У меня для вас даже есть рецепт успеха, всего то надо на верилог переехать, программистам там удобнее.

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


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

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

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

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

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

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

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

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

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

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