Jump to content

    
Sign in to follow this  
Мур

Головоломка конвейеризации в комбинационной логике.

Recommended Posts

Мотивация проста, в архитектуре DSP блоки конечны и приходится ловчить...

Получил(заимствовано из интернета) в лоб архитектуру на 12 разрядов, которая изначальное, чисто комбинационно, достаточно симпатична в RTL просмотре, но как следствие,- медленная.

Вставить регистр на половине структуры в имеющейся парадигме  проблемно.  Как бы это сделать  изящнее?

--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--  FILE: SQRN.VHD
--  PROJECT: Square Unit
--  AUTHOR:  Anatoli Sergiyenko
--  Email:   aser@comsys.kpi.ua
--  FUNCTION: - calculating the square function       https://kanyevsky.kpi.ua/ru/статьи/вычисление-квадрата/
--  	from the STD_LOGIC_VECTOR,
--   which represent the natural integer data.
--  CONSTRAINTS: the input data bit number is equal to
--	bit_num, where bit_num >4 is a generic value,
-- 	the output data bit number is equal to 2*bit_num,
--   respectivelYYPUT. 
--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
entity SQRN is generic(bit_num: integer:=12);
	port(CLK:  in STD_LOGIC;
	RST: in STD_LOGIC;
	XXPUT:in STD_LOGIC_VECTOR(bit_num-1 downto 0);
	YYPUT:out STD_LOGIC_VECTOR(bit_num*2-1 downto 0));
end entity SQRN;

architecture STR of SQRN is
signal XXPUTR:STD_LOGIC_VECTOR(bit_num-1 downto 0);
signal XXPUT0:STD_LOGIC_VECTOR(3 downto 0);
signal YYPUT0:STD_LOGIC_VECTOR(7 downto 0);		   
signal XXPUT2:STD_LOGIC_VECTOR(2*bit_num-1 downto 0);

begin	
	XXPUT_REGISTER: process(CLK,RST,XXPUT)
         begin
      if RST='1' then
         XXPUTR<=(others=>'0');
       elsif CLK='1' and CLK'event then
             XXPUTR<=XXPUT;
      end if;
end process;

--initial square function
	XXPUT0<=XXPUTR(3 downto 0);
	SQR4:process(XXPUT0)
		begin
		case XXPUT0 is
       when "0000"=> YYPUT0<="00000000";
       when "0001"=> YYPUT0<="00000001";
       when "0010"=> YYPUT0<="00000100";
       when "0011"=> YYPUT0<="00001001";
       when "0100"=> YYPUT0<="00010000";
       when "0101"=> YYPUT0<="00011001";
       when "0110"=> YYPUT0<="00100100";
       when "0111"=> YYPUT0<="00110001";
       when "1000"=> YYPUT0<="01000000";
       when "1001"=> YYPUT0<="01010001";
       when "1010"=> YYPUT0<="01100100";
       when "1011"=> YYPUT0<="01111001";
       when "1100"=> YYPUT0<="10010000";
       when "1101"=> YYPUT0<="10101001";
       when "1110"=> YYPUT0<="11000100";
       when "1111"=> YYPUT0<="11100001";
       when others => null;
       end case;
    end process;

--calculating the recursion
	RECURSION:process(XXPUTR,YYPUT0)is
	variable XXPUT2I: STD_LOGIC_VECTOR(2*bit_num-1 downto 0);
	variable Varble:STD_LOGIC_VECTOR(bit_num-1 downto 0);
	variable SM1:STD_LOGIC_VECTOR(bit_num-1 downto 0);
	variable aaa:STD_LOGIC;
	variable iii: integer;
		begin
	XXPUT2I:=(others=>'0');
	XXPUT2I(7 downto 0):=YYPUT0;
   for iii in 1 to bit_num-4 loop
       Varble(iii+2 downto 0):= XXPUTR(iii+2 downto 0);
       aaa:=XXPUTR(iii+3);
			if aaa='0' then
			  SM1(iii+3 downto 0):= "00"&XXPUT2I(2*iii+5 downto iii+4);
			else
			  SM1(iii+3 downto 0):=  UNSIGNED('0'& aaa & XXPUT2I(2*iii+5 downto iii+4)) + UNSIGNED(Varble(iii+2 downto 0));
			end if;

     if iii /= 5  then			--вставка  попытка
			PUN_REG: XXPUT2I(2*iii+7 downto iii+4):=SM1(iii+3 downto 0);
		else
			PUT_REG: process(CLK)
					  begin
					  if CLK='1' and CLK'event then
						  XXPUT2I(2*iii+7 downto iii+4):=SM1(iii+3 downto 0);
					  end if;
					 end process PUT_REG;

	--		XXPUT2I(2*iii+7 downto iii+4):=SM1(iii+3 downto 0);   --было вначале
		end if;
	  
  end loop;

  XXPUT2<=XXPUT2I;
end process;

YYPUT_REGISTER: process(CLK,RST,XXPUT2)
  begin
  if RST='1' then
     YYPUT<=(others=> '0');
  elsif CLK='1' and CLK'event then
     YYPUT<=XXPUT2;
  end if;
 end process;
end architecture STR;

Что я только не пробовал!  ...или туплю?     Спасибо!!!

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

image.thumb.png.89b3dccd952dc5b792268a7591e5c71b.png

Share this post


Link to post
Share on other sites

Тут может с форматированием что не то, но кажется, что один процесс вставлен вовнутрь другого. Как-то это нетрадиционно.

Может для начала поставить регистров по выходу и натравить ретайминг, в т.ч. специальными констрейнами (зависит от архитектуры).

Share this post


Link to post
Share on other sites
3 minutes ago, alexadmin said:

Тут может с форматированием что не то, но кажется, что один процесс вставлен вовнутрь другого. Как-то это нетрадиционно.

Может для начала поставить регистров по выходу и натравить ретайминг, в т.ч. специальными констрейнами (зависит от архитектуры).

Я понимаю.  Я это тут втулил для демонстрации замысла! Оно и не работает потому..

  Скорее надо разорвать процесс пополам...   Спасибо!

Share this post


Link to post
Share on other sites

Переписать на два комбинаторных процесса. Один с циклом 1 to (bit_num-4)/2, второй (bit_num-4)/2+1 to bit_num-4. После первого защелкнуть в регистр, дальше работать с данными из этого регистра

Share this post


Link to post
Share on other sites
Just now, alexadmin said:

Переписать на два комбинаторных процесса. Один с циклом 1 to (bit_num-4)/2, второй (bit_num-4)/2+1 to bit_num-4. После первого защелкнуть в регистр, дальше работать с данными из этого регистра

Я как раз так и пытаюсь сделать...     Была надежда, что есть что-то более изящнее.

Спасибо!

Share this post


Link to post
Share on other sites
3 hours ago, andrew_b said:

Добавить регистр 

Вот это другое дело...

--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--  FILE: SQRN.VHD
--  PROJECT: Square Unit
--  AUTHOR:  Anatoli Sergiyenko
--  Email:   aser@comsys.kpi.ua
--  FUNCTION: - calculating the square function       https://kanyevsky.kpi.ua/ru/статьи/вычисление-квадрата/
--  	from the STD_LOGIC_VECTOR,
--   which represent the natural integer data.
--  CONSTRAINTS: the input data bit number is equal to
--	bit_num, where bit_num >4 is a generic value,
-- 	the output data bit number is equal to 2*bit_num,
--   respectivelYYPUT. 
--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
entity SQRN is generic(bit_num: integer:=12);
	port(CLK:  in STD_LOGIC;
	RST: in STD_LOGIC;
	XXPUT:in STD_LOGIC_VECTOR(bit_num-1 downto 0);
	YYPUT:out STD_LOGIC_VECTOR(bit_num*2-1 downto 0));
end entity SQRN;

architecture STR of SQRN is
signal XXPUTR:STD_LOGIC_VECTOR(bit_num-1 downto 0);
signal XXPUT0:STD_LOGIC_VECTOR(3 downto 0);
signal YYPUT0:STD_LOGIC_VECTOR(7 downto 0);		   
signal XXPUT2:STD_LOGIC_VECTOR(2*bit_num-1 downto 0);
signal FXXPUT2I: STD_LOGIC_VECTOR(2*bit_num-1 downto 0);
signal FVarble:STD_LOGIC_VECTOR(bit_num-1 downto 0);
signal FSM1:STD_LOGIC_VECTOR(bit_num-1 downto 0);
signal DXXPUT2I: STD_LOGIC_VECTOR(2*bit_num-1 downto 0);
signal DVarble	:STD_LOGIC_VECTOR(bit_num-1 downto 0);
signal DSM1		:STD_LOGIC_VECTOR(bit_num-1 downto 0);

begin	
	XXPUT_REGISTER: process(CLK,RST,XXPUT)
         begin
      if RST='1' then
         XXPUTR<=(others=>'0');
       elsif CLK='1' and CLK'event then
             XXPUTR<=XXPUT;
      end if;
end process;

--initial square function
	XXPUT0<=XXPUTR(3 downto 0);
	SQR4:process(XXPUT0)
		begin
		case XXPUT0 is
       when "0000"=> YYPUT0<="00000000";
       when "0001"=> YYPUT0<="00000001";
       when "0010"=> YYPUT0<="00000100";
       when "0011"=> YYPUT0<="00001001";
       when "0100"=> YYPUT0<="00010000";
       when "0101"=> YYPUT0<="00011001";
       when "0110"=> YYPUT0<="00100100";
       when "0111"=> YYPUT0<="00110001";
       when "1000"=> YYPUT0<="01000000";
       when "1001"=> YYPUT0<="01010001";
       when "1010"=> YYPUT0<="01100100";
       when "1011"=> YYPUT0<="01111001";
       when "1100"=> YYPUT0<="10010000";
       when "1101"=> YYPUT0<="10101001";
       when "1110"=> YYPUT0<="11000100";
       when "1111"=> YYPUT0<="11100001";
       when others => null;
       end case;
    end process;


	RECURSION0:process(XXPUTR,YYPUT0)is
	variable XXPUT2I	: STD_LOGIC_VECTOR(2*bit_num-1 downto 0);
	variable Varble	:STD_LOGIC_VECTOR(bit_num-1 downto 0);
	variable SM1		:STD_LOGIC_VECTOR(bit_num-1 downto 0);
	variable aaa		:STD_LOGIC;
	variable iii		: integer;
		begin
	XXPUT2I:=(others=>'0');
	XXPUT2I(7 downto 0):=YYPUT0;
   for iii in 1 to (bit_num-4)/2 loop
       Varble(iii+2 downto 0):= XXPUTR(iii+2 downto 0);
       aaa:=XXPUTR(iii+3);
			if aaa='0' then
			  SM1(iii+3 downto 0):= "00"&XXPUT2I(2*iii+5 downto iii+4);
			else
			  SM1(iii+3 downto 0):=  UNSIGNED('0'& aaa & XXPUT2I(2*iii+5 downto iii+4)) + UNSIGNED(Varble(iii+2 downto 0));
			end if;
		XXPUT2I(2*iii+7 downto iii+4):=SM1(iii+3 downto 0);
		end loop;
  DXXPUT2I		<=  XXPUT2I;
  DVarble		<=  Varble;
  DSM1			<=  SM1;    
end process;

REGSTERs: process(CLK)			--<<<<<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  begin
  if CLK='1' and CLK'event then
			FXXPUT2I	<=	 DXXPUT2I	;
         FVarble		<=   DVarble	;
         FSM1			<=   DSM1		;
  end if;
 end process;

	RECURSION1:process(XXPUTR,FXXPUT2I, FVarble,FSM1 ) is
	variable XXPUT2I: STD_LOGIC_VECTOR(2*bit_num-1 downto 0);
	variable Varble:STD_LOGIC_VECTOR(bit_num-1 downto 0);
	variable SM1:STD_LOGIC_VECTOR(bit_num-1 downto 0);
	variable aaa:STD_LOGIC;
	variable iii: integer;
		begin
	XXPUT2I	:=    FXXPUT2I;	
	Varble	:=    FVarble	;
	SM1		:=    FSM1	;
   for iii in (bit_num-4)/2+1 to bit_num-4 loop
       Varble(iii+2 downto 0):= XXPUTR(iii+2 downto 0);
       aaa:=XXPUTR(iii+3);
			if aaa='0' then
			  SM1(iii+3 downto 0):= "00"&XXPUT2I(2*iii+5 downto iii+4);
			else
			  SM1(iii+3 downto 0):=  UNSIGNED('0'& aaa & XXPUT2I(2*iii+5 downto iii+4)) + UNSIGNED(Varble(iii+2 downto 0));
			end if;
		XXPUT2I(2*iii+7 downto iii+4):=SM1(iii+3 downto 0);
		end loop;
  XXPUT2<=XXPUT2I;
end process;


YYPUT_REGISTER: process(CLK,RST,XXPUT2)
  begin
  if RST='1' then
     YYPUT<=(others=> '0');
  elsif CLK='1' and CLK'event then
     YYPUT<=XXPUT2;
  end if;
 end process;
end architecture STR;

Вот почему для меня VHDL это все равно что ассемблер!..

Share this post


Link to post
Share on other sites
3 часа назад, des00 сказал:

переписать на верилог дело 10-15 минут ;)

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

Share this post


Link to post
Share on other sites
4 hours ago, des00 said:

переписать на верилог дело 10-15 минут ;)

Вот как раз тот момент, когда можно утереть нос консерваторам от VHDL и показать, упускаемое долбодятлами, изящество Verilog!..

Дескать,- "учись, студент!":clapping:

По мне как VHDL, так и Verilog - ассемблерного типа!

Share this post


Link to post
Share on other sites

хотя не, вот с этим будет проблема, придется обходить

2*iii+5 downto iii+4

подобное задание границ вектора, в верилоге не поддерживается, как и массивы длинны, задаваемой параметром. так что, VHDL еще могет)

Share this post


Link to post
Share on other sites
22 часа назад, Мур сказал:

Вот как раз тот момент, когда можно утереть нос консерваторам от VHDL и показать, упускаемое долбодятлами, изящество Verilog!..

Дескать,- "учись, студент!":clapping:

По мне как VHDL, так и Verilog - ассемблерного типа!

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

Извините за оффтоп.

Share this post


Link to post
Share on other sites
On 9/16/2020 at 7:58 AM, wolfman said:

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

Извините за оффтоп.

Если бы вы были внимательны, то поняли шутку юмора в ответ на вызов по известной религиозной войне

Quote

переписать на верилог дело 10-15 минут ;)

1. Как раз я то и сделал на VHDL!  После того как ожидаемого изящества(а значит и преимущества на Verilog) я не дождался.

2. Долбодятел это Я о себе.

3. Хорошая ссылочка    http://masters.donntu.org/2012/fknt/voloshin/library/html/Translation.htm

Share this post


Link to post
Share on other sites
15 hours ago, wolfman said:

Кстати, а почему инициализацию не засунуть под тактовую?

Можно по-всякому..   В зависимости от архитектуры макроячейки. 

Это не принципиально!  Тема тут иная  и достаточно интересная.  Как поднять быстродействие?  

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this