VHDL Testbench с выборкой сигналов из файла

Волею судьбы занят сейчас программированием ПЛИС компании Altera семейства Cyclone IV. А тут, как известно, рано или поздно встает вопрос о моделировании.
Вы возможно скажете: «Ну так бери ModelSim и моделируй». Только одна проблема! Я ленивый…

Мне нужно промоделировать блок у которого на вход приходит адрес (16 битное число) и сигнал CS, а на выход он выплевывает кучу разнообразных сигналов управления.
Но в данном контексте это не важно.
Важно то, что мне нужно перебрать кучу значений адреса, что довольно трудозатратно.
Но не беда! Просто сделаем так, чтобы ModelSim брал данные для симуляции из такого файла:

#cs addr 
1 0
0 0
0 1
0 2
0 3
....

Исследуемый блок выглядит так:

entity cs_mux is
        port (  addr : in integer range 0 to 2047;
                                cs : in bit;
                                
                                sys_control : out bit;
                                sync : out bit; 
                                data_collector : out bit; 
                                async_ports : out bit_vector(11 downto 0);
                                recv_buffers : out bit_vector(11 downto 0);
                                transiver_buffers : out bit_vector(11 downto 0) 
                        );
end cs_mux;

Начнем делать наш Testbench.

Объявим пустой entity и библиотеки.

library IEEE;
use IEEE.numeric_std.all;
use STD.TEXTIO.all; --package with routines for reading/writing files

entity TEST_MUX is
end entity;

Приступим к архитектуре. Тут нужно обявить по сигналу для каждого входа/выхода и компонент.

architecture RTL of TEST_MUX is
        signal cs : bit;
        signal addr : integer range 0 to 2047;
        signal sys_control : bit;
        signal sync : bit; 
        signal data_collector : bit;
        signal async_ports : bit_vector(11 downto 0);
        signal recv_buffers : bit_vector(11 downto 0);
        signal transiver_buffers : bit_vector(11 downto 0);

        file infile : text is in "mux_file.txt"; --файл с исходными данными
        
        component cs_mux
                port (  addr : in integer range 0 to 2047;
                                cs : in bit;
                                
                                sys_control : out bit; 
                                sync : out bit; 
                                data_collector : out bit; 
                                async_ports : out bit_vector(11 downto 0); 
                                recv_buffers : out bit_vector(11 downto 0); 
                                transiver_buffers : out bit_vector(11 downto 0) 
                        );
        end component;
        
begin 

Тут главное не пропустить декларацию файла.
Дальше создаем схему.

U1: cs_mux
        port map(
                addr => addr,
                cs => cs,
                sys_control => sys_control,
                sync => sync,
                data_collector => data_collector,
                async_ports => async_ports,
                recv_buffers => recv_buffers,
                transiver_buffers => transiver_buffers
        );

Тут тоже все просто. Соединяем наши сигналы со входами/выходами компонента.
А теперь вся магия.
Процесс загрузки данных из файла.

process
        variable s : line;
        variable gooda, goodc : Boolean;
        variable addrv : integer range 0 to 2047;
        variable csv : bit;
begin
        if endfile(infile) then
                wait;
        end if;
        readline(infile,s);
        if s(s'low) /= '#' then
                read(s, csv, goodc);
                read(s, addrv, gooda);
                if gooda and goodc then
                        addr <= addrv;
                        cs <= csv;

                        wait for 10ns;
                else
                        wait;
                end if;
        end if;
end process;

Тут мы построчно читаем файл. В каждой строке пропускаем все после диеза (это у нас символ комментария такой).
Дальше при помощи функции read читаем сигналы из строки. И если все хорошо (goodc и gooda в значении 1), то присваиваем считанные значения сигналам. После каждой такой процедуры ждем 10нс.

В итоге получается нечто подобное:

А я довольный попиваю кофе 😉

 

Похожий код:

Фото аватара
Алексей Петров

Программист, разработчик с 5 летним опытом работы. Учусь на разработчика игр на Unity и разработчика VR&AR реальности (виртуальной реальности). Основные языки программирования: C#, C++.

Оцените автора
Бла, бла код
Добавить комментарий