Jump to content

    

"Схемотехнические трюки для ПЛИСоводов"

не нашел куда написать, а новой темы.......

.На AHDL можно написать:

ff[3..0]: dffe;
ff.(d, ena, clk, q) = (Din[3..0], ena, clk_GN, iDin[3..0]);

На SV никак в одну строчку не укоротить?

DFFE ff_all[3:0] (.d(Din), .ena(ena), .clk(clk_GN), .q(iDin));

ключевыe слова поиска - verilog array of instance

первое что нашёл

http://dropzone.tamu.edu/~lwang/ee468/slides/lec03.pdf

Share this post


Link to post
Share on other sites

У меня такая проблемка возникла.

Есть 32х.р. счетчик, который никогда не останавливается:

 

always_ff@(posedge adc_mclk_mux or negedge rst_i) begin 27,648 MHz
    if (!rst_i) counter<='0;
    else if (!TRIG3_stb && TRIG3_rg_n)   counter<=32'd0; //start condition
    else counter<=counter+1'b1;
end

На другой стороне процессор с 16р шиной (clk~49 MHz ), который должен прочитать "грамотно" за два обращения текущее значение данного счетчика.

Понятное дело если его просто так читать, то получается полная каша. Ставлю защелку:

always_ff@(negedge adc_mclk_mux or negedge rst_i) begin
    if (!rst_i) cnt_rg_HADC<='0;
        else if (!ff_hold) cnt_rg_HADC<=counter;
end

 

И, собственно, управление защелкой(LRD стоит 2 такта clk_i). Вначале читается старшее, потом младшее слово:

always_ff@(posedge clk_i or negedge rst_i) begin
    if (!rst_i) fHold_value<='0;
        else if (!IOMS && !LRD) begin
                  if         (LA==pIOMS_ADC_CTRL_CNTR_L)    fHold_value<='0; //LSB       
                  else if    (LA==pIOMS_PXI_MUX_CNTR_H)      fHold_value<='1; //MSB        
        end                                          
end


always_ff@(negedge adc_mclk_mux or negedge rst_i) begin//posedge
if (!rst_i)  ff_hold<='0; 
else if ( fHold_value && IOMS)  ff_hold<='1;
else if (!fHold_value && IOMS)  ff_hold<='0; 

end

 

при таком раскладе получается, что холдится только младшее слово. Итог:

post-52939-1323233244_thumb.jpg

В принципе устраивает. Но может как то грамотней можно сделать?

Share this post


Link to post
Share on other sites
DFFE ff_all[3:0] (.d(Din), .ena(ena), .clk(clk_GN), .q(iDin));

 

У меня выдает

Error (10253): Verilog HDL Module Instantiation error at tx_8b_10b.sv(82): cannot elaborate array of instances because the declaration for the instantiated module has not been analyzed

не пойму, он дополнительно объявление требует или что?

Share this post


Link to post
Share on other sites
не пойму, он дополнительно объявление требует или что?

 

При переходе с AHDL на verilog без схемотехнических трюков не обойтись.

reg [3:0] dffe_rg = 4'h0;

always @(posedge clk_GN)
begin
if (ena)        dffe_rg  <= Din
end

Share this post


Link to post
Share on other sites
У меня выдает

Error (10253): Verilog HDL Module Instantiation error at tx_8b_10b.sv(82): cannot elaborate array of instances because the declaration for the instantiated module has not been analyzed

не пойму, он дополнительно объявление требует или что?

Нужно сделать свой модуль - обёртку для DFFE, и его уже можно будет вставить сразу массивом.

Например для LCELL:

module lc(input in, output out);
  LCELL l (.in(in), .out(out));
endmodule

и потом

wire [7:0] p, q;
lc lcq[7:0] (p, q);

Для DFFE нужно аналогично

Share this post


Link to post
Share on other sites

2 sazh & maksimp такие методы я понимаю. но это о5 многа букав. хотел в одну строку. как в http://electronix.ru/redirect.php?http://d...lides/lec03.pdf

хотя код ниже приемлим =)

always_ff @ (posedge clk)
    if (ena) iDin <= Din;

Edited by stu

Share this post


Link to post
Share on other sites
хотел в одну строку

 

Так ведь никто не поймет, что Вы наваяли.

Share this post


Link to post
Share on other sites

Здравствуйте, уважаемые ПЛИСоводы.

Раз уж тут обсуждаются трюки на плис, Решил написать свою задачу

 

Кто-нибудь пробовал использовать аналоговые свойства плис? Например, как ацп с помощью компаратора портов LVDS, формирование импульсов с точность меньше периода макс. тактовой частоты с помощью линии задержки.

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

 

Кто-то встречался с такими задачами?

 

Спасибо.

 

Share this post


Link to post
Share on other sites
формирование импульсов с точность меньше периода макс. тактовой частоты с помощью линии задержки.

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

Посмотрите здесь

http://www.alteraforum.com/forum/showthrea...2133&page=2

и там по ссылкам.

А вообще искать "delay" на alteraforum.com .

Share this post


Link to post
Share on other sites
Посмотрите здесь

http://www.alteraforum.com/forum/showthrea...2133&page=2

и там по ссылкам.

А вообще искать "delay" на alteraforum.com .

 

Спасибо, изучаю.

 

Думал, может, кто-то из отечественных плисоводов это делал...

Share this post


Link to post
Share on other sites

Вот решил написать свой вариант FIFO-буфера, правда я его в кристалле не тестировал. Прошу покритиковать.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity FIFO is
generic (Addr_Size	: natural := 3;									-- Разрядность адреса (глубина FIFO)
		 Data_Size	: natural := 32);								-- Разрядность данных
port (RST			: in  std_logic;								-- Сброс
	  CLK_WR		: in  std_logic;								-- Тактовый сигнал для записи
	  WE			: in  std_logic;								-- Разрешение записи (Write Enable)
	  Data_WR		: in  std_logic_vector(Data_Size - 1 downto 0); -- Данные, записываемые в буфер
	  CLK_RD		: in  std_logic;								-- Тактовый сигнал для чтения
	  RE			: in  std_logic;								-- Разрешение чтения (Read Enable)
	  Data_RD		: out std_logic_vector(Data_Size - 1 downto 0); -- Данные, читаемые из буфера
	  Full			: out std_logic;								-- Флаг того, что буфер полон
	  Empty			: out std_logic);								-- Флаг того, что буфер пуст
end entity FIFO;


architecture RTL of FIFO is

type FIFO_RAM_Type is array (0 to 2**Addr_Size - 1) of std_logic_vector(Data_Size - 1 downto 0);
signal FIFO_RAM : FIFO_RAM_Type;

--================================================================================
================================================--
--									Функция преобразования из двоичного кода в код Грея: 										  --
--================================================================================
================================================--
function Bin_to_Gray (D: unsigned) return unsigned is
	variable Q	: unsigned(D'range);
begin
	Q := ('0' & D(D'high downto 1)) xor D;
	return Q;
end function Bin_to_Gray;
--================================================================================
================================================--


--================================================================================
================================================--
--										Функция преобразования кода Грея в двоичный код: 										  --
--================================================================================
================================================--
function Gray_to_Bin (D: in unsigned) return unsigned is
	variable Q: unsigned(D'high downto D'low);
begin
	Q(D'high) := D(D'high);
	for i in D'high - 1 downto D'low loop
		Q(i) := D(i) xor Q(i + 1);
	end loop;
	return Q;
end function;
--================================================================================
================================================--

signal Addr_Write_Gray		: unsigned(Addr_Size downto 0);		-- Адрес записи данных в буфер в коде Грея
signal Addr_Write_Gray_Next	: unsigned(Addr_Size downto 0);		-- Следующий адрес записи данных в буфер в коде Грея
signal Addr_Read_Gray		: unsigned(Addr_Size downto 0);		-- Адрес чтения данных из буфера в коде Грея

signal Addr_Write_Bin		: unsigned(Addr_Size downto 0);		-- Адрес записи данных в буфер в двоичном коде
signal Addr_Write_Bin_Next	: unsigned(Addr_Size downto 0);		-- Следующий адрес записи данных в буфер в двоичном коде
signal Addr_Read_Bin		: unsigned(Addr_Size downto 0);		-- Адрес чтения данных из буфера в двоичном коде

signal WE_Allow				: std_logic;						-- Разрешение записи данных в FIFO-буфер
signal RE_Allow				: std_logic;						-- Разрешение чтения данных из FIFO-буфера

signal Full_Match			: std_logic;						-- Сравнение адресов записи и чтения для флага того, что буфер полон
signal Empty_Match			: std_logic;						-- Сравнение адресов записи и чтения для флага того, что буфер пуст
begin

-- Адрес записи данных в буфер в двоичном коде: --
process(RST, CLK_WR)
	begin 
		if (RST = '1') then
			Addr_Write_Bin <= (others => '0');
		elsif (Rising_Edge(CLK_WR)) then
			if(WE_Allow = '1') then
				Addr_Write_Bin <= Addr_Write_Bin + 1;
			end if;
		end if;
end process;

-- Следующий адрес записи данных в буфер в двоичном коде: --
process(RST, CLK_WR)
	begin 
		if (RST = '1') then
			Addr_Write_Bin_Next <= TO_UNSIGNED(1, Addr_Size + 1);
		elsif (Rising_Edge(CLK_WR)) then
			if(WE_Allow = '1') then
				Addr_Write_Bin_Next <= Addr_Write_Bin_Next + 1;
			end if;
		end if;
end process;

-- Адрес записи данных в FIFO-буфер в коде Грея: --
Addr_Write_Gray	<= Bin_to_Gray(Addr_Write_Bin);

-- Следующий адрес записи данных в буфер в коде Грея: --
Addr_Write_Gray_Next	<= Bin_to_Gray(Addr_Write_Bin_Next);

-- Адрес чтения данных из буфера в двоичном коде: --
process(RST, CLK_RD)
	begin 
		if (RST = '1') then
			Addr_Read_Bin <= (others => '0');
		elsif (Rising_Edge(CLK_RD)) then
			if(RE_Allow = '1') then
				Addr_Read_Bin <= Addr_Read_Bin + 1;
			end if;
		end if;
end process;

-- Адрес чтения данных из FIFO-буфера: --
Addr_Read_Gray	<= Bin_to_Gray(Addr_Read_Bin);

-- Запись данных в FIFO-буфер: --
process
	begin 
		wait until (rising_edge(CLK_WR));
			if(WE_Allow = '1') then
				FIFO_RAM(TO_INTEGER(Addr_Write_Gray(Addr_Size - 1 downto 0))) <= Data_WR;
			end if;
end process; 

-- Чтение данных из FIFO-буфера: --
process
	begin 
		wait until (rising_edge(CLK_RD));
			if(RE_Allow = '1') then
				Data_RD <= FIFO_RAM(TO_INTEGER(Addr_Read_Gray(Addr_Size - 1 downto 0)));
			end if;
end process;

-- Разрешение записи данных в FIFO-буфер: --
WE_Allow	<= '1' when (WE = '1' and Full_Match = '0') else '0';

-- Разрешение чтения данных из FIFO-буфера: --
RE_Allow	<= '1' when (RE = '1' and Empty_Match = '0') else '0';			

-- Сравнение адресов записи и чтения для флага того, что буфер полон: --
Full_Match	<= '1' when (Addr_Write_Bin(Addr_Size - 1 downto 0) = Addr_Read_Bin(Addr_Size - 1 downto 0) and Addr_Write_Bin(Addr_Size) /= Addr_Read_Bin(Addr_Size) and (RE = '0' or (RE = '1' and WE = '1'))) else '0';

-- Флаг того, что буфер полон: --	
Full 		<= '1' when (Full_Match = '1' or (Addr_Write_Bin_Next(Addr_Size - 1 downto 0) = Addr_Read_Bin(Addr_Size - 1 downto 0) and Addr_Write_Bin_Next(Addr_Size) /= Addr_Read_Bin(Addr_Size) and (RE = '0' and WE = '1'))) else '0'; 	

-- Сравнение адресов записи и чтения для флага того, что буфер пуст: --
Empty_Match	<= '1' when (Addr_Write_Bin = Addr_Read_Bin  and (WE = '0' or (RE = '1' and WE = '1'))) else '0';

-- Флаг того, что буфер пуст: --	
Empty		<= Empty_Match;
end architecture RTL;

FIFO.rar

Edited by ZED

Share this post


Link to post
Share on other sites

Параметризуемый фильтр КИХ.

Реализация - вторая прямая форма,порядок чётный,ИХ симметричная,латентность - 2 такта не зависимо от порядка.

fir.rar

Share this post


Link to post
Share on other sites

Вот теперь я понимаю почему проекты с опенкорес всегда требуют рихтовки и подгонки :laughing:

Устранил баги и упростил.

FIR.rar

Share this post


Link to post
Share on other sites

Нужна структура быстрого счетчика для FPGA ALTERA ARRIA2GX C5.

Счетчик нужен на разрядность 32, скорость счета до 500МГц, тип счетчика не важен, количество счетных значений 2^32...

Кто поделится мыслями или практикой реализации?

 

Share this post


Link to post
Share on other sites
Кто поделится мыслями или практикой реализации?

Дробить на несколько мелких счетчиков, соединенных последовательно.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now