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

Сокращение однотипных описаний на VHDL

Возможно ли как-то сократить количество однотипных описаний на языке VHDL.

Например у меня есть кусок кода

PROCESS
        (
        data_ready_0,
        data_ready_1,
        data_ready_2,
        data_ready_3,
        data_ready_4,
        data_ready_5,
        data_ready_6,
        data_ready_7,
        data_ready_8,
        data_ready_9      
        )
    BEGIN
        IF (data_ready_0  = '1' AND data_ready_0'EVENT) THEN
            storage_reg_0 <= shift_reg;
        END IF;
        
        IF (data_ready_1  = '1'AND data_ready_1'EVENT) THEN
            storage_reg_1 <= shift_reg;
        END IF;
        
        IF (data_ready_2  = '1'AND data_ready_2'EVENT) THEN
            storage_reg_2 <= shift_reg;
        END IF;
        
        IF (data_ready_3  = '1'AND data_ready_3'EVENT) THEN
            storage_reg_3 <= shift_reg;
        END IF;
        
        IF (data_ready_4  = '1'AND data_ready_4'EVENT) THEN
            storage_reg_4 <= shift_reg;
        END IF;
        
        IF (data_ready_5  = '1'AND data_ready_5'EVENT) THEN
            storage_reg_5 <= shift_reg;
        END IF;
        
        IF (data_ready_6  = '1'AND data_ready_6'EVENT) THEN
            storage_reg_6 <= shift_reg;
        END IF;
        
        IF (data_ready_7  = '1'AND data_ready_7'EVENT) THEN
            storage_reg_7 <= shift_reg;
        END IF;
        
        IF (data_ready_8  = '1'AND data_ready_8'EVENT) THEN
            storage_reg_8 <= shift_reg;
        END IF;
        
        IF (data_ready_9  = '1'AND data_ready_9'EVENT) THEN
            storage_reg_9 <= shift_reg;
        END IF;
        
    END PROCESS;

Можно ли как-то описать более коротко подобные однотипные языковые конструкции ? А то напрягает работать с портянками на 300-400 строк.

Пробовал через оператор параллельной генерации ( FOR I IN 0 TO 0 GENERATE), но что-то не получилось...

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


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

For... generate. И работайте с массивами. Странно, почему не получилось. Можно еще параметр с помощью generic задавать.

И не используйте кучу разных фронтов. Работайте по одной тактовой.

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


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

Пробовал через оператор параллельной генерации ( FOR I IN 0 TO 0 GENERATE), но что-то не получилось...

Внутри процесса следует использовать FOR LOOP, а не FOR GENERATE, ну и перевести всё на массивы, конечно.

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


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

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD;

ENTITY PHASE_SEARCH_FOR_ONE_CLK IS 
PORT
    (
    bit_clk                         :IN     STD_LOGIC;
    serial_data_in                  :IN     STD_LOGIC;     

    paralel_data_out_0              :OUT    STD_LOGIC_VECTOR(9 DOWNTO 0);
    paralel_data_out_1              :OUT    STD_LOGIC_VECTOR(9 DOWNTO 0)
    );
END PHASE_SEARCH_FOR_ONE_CLK;

ARCHITECTURE PHASE_SEARCH_FOR_ONE_CLK_arc OF PHASE_SEARCH_FOR_ONE_CLK IS
    
    TYPE   storage_reg IS ARRAY (0 TO 1) OF STD_LOGIC_VECTOR (9 DOWNTO 0);
    SIGNAL shift_reg                           :STD_LOGIC_VECTOR (9 DOWNTO 0):= (OTHERS => '0'); 
BEGIN
    PROCESS                                                   
        (
        bit_clk
        )
    VARIABLE counter_bit_clk_0             :STD_LOGIC_VECTOR(3 DOWNTO 0):=(OTHERS => '0');
    BEGIN
    
        IF (bit_clk = '1' AND bit_clk'EVENT) THEN           
            shift_reg(0) <= serial_data_in;                 
            counter_bit_clk_0 := counter_bit_clk_0 + '1';         
            
            FOR i IN 1 TO 9 LOOP
                shift_reg(i) <= shift_reg(i-1);             
            END LOOP;
            
            IF (counter_bit_clk_0 = "1010") THEN            
                counter_bit_clk_0 := (OTHERS => '0');       
                storage_reg(0) <= shift_reg;
            END IF;

            IF (counter_bit_clk_0 = "0001") THEN
                storage_reg(1) <= shift_reg;
            END IF;
      
        ELSE 
            counter_bit_clk_0:= counter_bit_clk_0; 
        END IF;
    END PROCESS;
paralel_data_out_0          <= storage_reg(0);
paralel_data_out_1          <= storage_reg(1);
END PHASE_SEARCH_FOR_ONE_CLK_arc;

 

Попробовал работать с массивами. Столкнулся с проблемой: как с ними работать практически ни в одной книге не сказано. Примеров не нашёл

При компиляции ругается на строчку где я пытаюсь в вектор с нормером 0 записать значение со сдвигового регистра.

Error (10305): VHDL Type Conversion error at phase_search_for_one_clk.vhd(40): cannot convert type " universal_integer" to type "storage_reg"

Подскажите в чем беда ?

 

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD;

ENTITY PHASE_SEARCH_FOR_ONE_CLK IS 

GENERIC
    (
    DATA_WIDTH : INTEGER := 2
    );
PORT
    (
    bit_clk                         :IN     STD_LOGIC;                    
    serial_data_in                  :IN     STD_LOGIC;                    
    paralel_data_out_0              :OUT    STD_LOGIC_VECTOR(9 DOWNTO 0);  
    paralel_data_out_1              :OUT    STD_LOGIC_VECTOR(9 DOWNTO 0)  

    );
END PHASE_SEARCH_FOR_ONE_CLK;
--==========================================================================
ARCHITECTURE PHASE_SEARCH_FOR_ONE_CLK_arc OF PHASE_SEARCH_FOR_ONE_CLK IS
    
    TYPE storage_RAM IS ARRAY (1 DOWNTO 0) OF STD_LOGIC_VECTOR (9 DOWNTO 0);
    SIGNAL shift_reg                     :STD_LOGIC_VECTOR (9 DOWNTO 0):= (OTHERS => '0');    
    SIGNAL RAM:storage_RAM;

BEGIN

    PROCESS                                                   
        (
        bit_clk
        )
    VARIABLE counter_bit_clk_0             :STD_LOGIC_VECTOR(3 DOWNTO 0):=(OTHERS => '0');

    BEGIN
    
        IF (bit_clk = '1' AND bit_clk'EVENT) THEN           
            shift_reg(0) <= serial_data_in;                  
            counter_bit_clk_0 := counter_bit_clk_0 + '1';    
            
            FOR i IN 1 TO 9 LOOP
                shift_reg(i) <= shift_reg(i-1);             
            END LOOP;
            
            IF (counter_bit_clk_0 = "1010") THEN            
                counter_bit_clk_0 := (OTHERS => '0');       
                RAM(0) <= shift_reg;

            END IF;

            IF (counter_bit_clk_0 = "0001") THEN            
            RAM(1) <= shift_reg;

            END IF;
   
        ELSE 
            counter_bit_clk_0:= counter_bit_clk_0; 
        END IF;
    END PROCESS;
paralel_data_out_0          <= RAM(0);
paralel_data_out_1          <= RAM(1);

END PHASE_SEARCH_FOR_ONE_CLK_arc;

 

Кажется разобрался. Оказывается для памяти надо было ещё и сигнал объявлять. Повезло, что нашел готовый модуль памяти и там подсмотрел.

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


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

USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD;

Во-первых, никогда не используйте эти пакеты вместе. Особенно при недостатке опыта в VHDL.

Во-вторых, если нужна математика, используйте только numeric_std. Про std_logic_arith, std_logic_unsigned, std_logic_signed забудьте.

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


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

Во-первых, никогда не используйте эти пакеты вместе. Особенно при недостатке опыта в VHDL.

Во-вторых, если нужна математика, используйте только numeric_std. Про std_logic_arith, std_logic_unsigned, std_logic_signed забудьте.

Это случаем не связано с перегрузкой операторов ?

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


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

Это случаем не связано с перегрузкой операторов ?

 

Это связано с реализацией std_logic_*.

 

google://"numeric_std vs std_logic_arith"

https://groups.google.com/forum/?hl=en#!...Lw/I-g4TlVs7mIJ

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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