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нс.

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

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

Просмотров:   2672

Комментарии

Добавить комментарий

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.
CAPTCHA
Введи эти символы. Ато роботы одолели!