Jump to content

    
Sign in to follow this  
acvarif

Перевод VHDL на Verilog

Recommended Posts

Имеется модуль сумматор-умножитель для КИХ фильтра

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multadd is

Generic (
	-- разрядность входных данных
	multadd_in_lenght 	: integer := 12;
	-- разрядность ПЗУ коэффициентов
	rom_lenght 					: integer := 16;
	-- разрядность выходных данных
	multadd_out_lenght	: integer := 16
	);
Port (
	-- задающая частота 
	clk_multadd 	: in std_logic; 
	-- общий сброс 
	clr_multadd 	: in std_logic; 
	-- обнуление результата 
	zero_multadd 	: in std_logic; 
	-- вкл(выкл)умножителя
	multadd_onoff : in std_logic; 

	-- входные данные 
	multadd_in 	: in std_logic_vector(multadd_in_lenght - 1 downto 0); 
	-- входной коэффициент 
	romfir_in 	: in std_logic_vector(rom_lenght - 1 downto 0); 

	-- выходные данные
	multadd_out 		: out std_logic_vector(multadd_out_lenght - 1 downto 0) 
	);

end multadd;

architecture behavioural of multadd is
attribute multstyle : string;
-- на базе логики
--attribute multstyle of behavioural : architecture is "logic";
-- на базе встроенных умножителей
attribute multstyle of behavioural : architecture is "dsp";

constant multadd_lenght_temp : integer	:= 28;  
-- сигналы синхронизации
signal multadd_sum_tmp : std_logic_vector(multadd_lenght_temp - 1 downto 0);

begin

process(clk_multadd,clr_multadd,multadd_in,romfir_in,multadd_sum_tmp, zero_multadd)
begin
	if clr_multadd = '0' then 
		multadd_out <= (others => '0');
	elsif zero_multadd = '0' then
		multadd_sum_tmp <= (others => '0');
	elsif clk_multadd'event and clk_multadd = '0' then
		-- умножитель включен
		if multadd_onoff = '1' then
			multadd_sum_tmp <= multadd_sum_tmp + (signed(multadd_in)* signed(romfir_in));
		else	
		-- входные данные на выход 
			multadd_sum_tmp(27 downto 12) <= conv_std_logic_vector(signed(multadd_in), 16);
		end if;	
	end if;	

multadd_out(15 downto 0) <= multadd_sum_tmp(27 downto 12);

end process;

end behavioural;

 

Попытка перевести это на Verilog закончилась неудачей

(* multstyle = "dsp" *)
module multadd_v 

#(
//разрядность входных данных
parameter multadd_in_lenght = 12,
// разрядность коэффициентов
parameter rom_lenght = 16,
// разрядность выходных данных
parameter multadd_out_lenght = 16
)
(
	// задающая частота 
	input clk_multadd,	
	// общий сброс 
	input clr_multadd,	
	// обнуление результата 
	input zero_multadd, 
	// вкл(выкл)сумматора-умножителя
	input multadd_onoff, 
	// входные данные 
	input signed multadd_in [(multadd_in_lenght - 1):0], 
	// входной коэффициент 
	input signed romfir_in [(rom_lenght - 1):0], 
	// выходные данные
	output multadd_out [(multadd_out_lenght - 1):0] 
);


parameter multadd_lenght_temp = 28;  
// промежуточный результат
reg multadd_sum_tmp [(multadd_lenght_temp - 1):0];


always @ (posedge clk_multadd or negedge clr_multadd)
begin
	// общий сброс
	if (!clr_multadd)
		multadd_out <= 0;
	// текущее онуление 
	else if (!zero_multadd)
		multadd_sum_tmp <= 0;
		// умножитель включен
	else if (multadd_onoff) begin 
			multadd_sum_tmp <= multadd_sum_tmp + (multadd_in * romfir_in);
		else	
			// входные данные на выход 
			multadd_sum_tmp[27:12] <= multadd_in;
		end 	
	end	
//end	

assign multadd_out[15:0] = multadd_sum_tmp[27:12];

endmodule

Прочитав бегло пару букварей Verilog не обнаружил там ничего про конструкции bein end. Где они расставляются и вобще зачем нужны. И смутное пояснение применения else if. Поэтому полностью запутался. Кому не лень поясните пожалуйста в чем хитрость применительно к данному примеру.

 

Share this post


Link to post
Share on other sites

Добрый день. Самое простое представить, что вы пишите на си, а фигурные скобки в случае верилог - это Бегин энд. А вообще "букварь" должен помочь, в вашем случае вы Бегин энд ставите на иф целиком как в vhdl, а следует мыслить как в Си и ставить только на инструкции между иф элзе.

И в случае, как у вас, вообще, можно обойтись без Бегин энд, то есть просто их не ставить здесь

Edited by 7777777alex

Share this post


Link to post
Share on other sites
Прочитав бегло пару букварей Verilog не обнаружил там ничего про конструкции bein end. Где они расставляются и вобще зачем нужны. И смутное пояснение применения else if. Поэтому полностью запутался. Кому не лень поясните пожалуйста в чем хитрость применительно к данному примеру.

У меня на сайте - Краткий Курс.

Вопросы - можно по скайпу..

Удачи!

 

Share this post


Link to post
Share on other sites
Вам бы для начала с VHDL разобраться. Написана полная ерунда.

Это врядли, как сказал-бы товарищ Сухов.

Разбираюсь уже достаточно времени. Все работает как задумано.

Самое простое представить, что вы пишите на си, а фигурные скобки в случае верилог - это Бегин энд.

Насчет скобок в С стало понятнее. Спасибо.

Касательно данного примера - где от них можно избавться вообще?.. (в смысле begin end)

Получается, что любое if нужно заключать в скобки?

В VHDL есть конструкция elsif которая не требует end if; В Verilog такое есть?

Вроде как нет. Как поступить в этом случае?

У меня на сайте - Краткий Курс.

Ссылка не работает. Переходит на рекламу.

А.. Хитрая реклама от Яндекса?. После зарытия заработало.

 

Edited by Acvarif

Share this post


Link to post
Share on other sites
Это врядли, как сказал-бы товарищ Сухов.

Разбираюсь уже достаточно времени. Все работает как задумано.

Да не-не, точно говорю ерунда. Оно, может и работает но так писать нельзя! Вы и себя запутаете, и результат может оказаться непредсказуем. Почитайте про списки чувствительности в процессах. Почитайте про синхронный и асинхронный сброс в синхронных схемах. Вы ж Ваш модуль, надеюсь, пишете не для того чтоб на его работу в симуляторе смотреть, Вы ж наверняка, хотите, чтоб он синтезировался в ПЛИС. Почитайте ветку

Share this post


Link to post
Share on other sites
Да не-не, точно говорю ерунда. Оно, может и работает но так писать нельзя! Вы и себя запутаете, и результат может оказаться непредсказуем. Почитайте про списки чувствительности в процессах. Почитайте про синхронный и асинхронный сброс в синхронных схемах. Вы ж Ваш модуль, надеюсь, пишете не для того чтоб на его работу в симуляторе смотреть, Вы ж наверняка, хотите, чтоб он синтезировался в ПЛИС. Почитайте ветку

На списки чувствительности я никогда не обращаю внимание. Может и не по правилам. В симуляторе смотрю только временную симуляцию где списки чувствительности до... Какраз временная симуляция это то, что реально работает в железе. Так оно и есть. Все остальное лишнее...

Вроде так получается:

(* multstyle = "dsp" *)
module multadd_v 

#(
//разрядность входных данных
parameter multadd_in_lenght = 12,
// разрядность коэффициентов
parameter rom_lenght = 16,
// разрядность выходных данных
parameter multadd_out_lenght = 16
)
(
	// задающая частота 
	input clk_multadd,	
	// общий сброс 
	input clr_multadd,	
	// обнуление результата 
	input zero_multadd, 
	// вкл(выкл)сумматора-умножителя
	input multadd_onoff, 
	// входные данные 
	input signed multadd_in [(multadd_in_lenght - 1):0], 
	// входной коэффициент 
	input signed romfir_in [(rom_lenght - 1):0], 
	// выходные данные
	output multadd_out [(multadd_out_lenght - 1):0] 
);


parameter multadd_lenght_temp = 28;  
// промежуточный результат
reg multadd_sum_tmp [(multadd_lenght_temp - 1):0];


always @ (posedge clk_multadd or negedge clr_multadd)
begin
	// общий сброс
	if (!clr_multadd)
		multadd_out <= 0;
	// текущее онуление 
	else if (!zero_multadd)
		multadd_sum_tmp <= 0;
		// сумматор-умножитель включен
	else if (clk_multadd) begin 
		if(multadd_onoff) begin
			multadd_sum_tmp <= multadd_sum_tmp + (multadd_in * romfir_in); 
		end
		else begin	
			// входные данные на выход 
			multadd_sum_tmp[27:12] <= multadd_in; 
		end
	end 	
end	

assign multadd_out[15:0] = multadd_sum_tmp[27:12];

endmodule

Только теперь полные дрова

Verilog HDL error at multadd_v.v(49): values cannot be 
assigned directly to all or part of array "multadd_out" - 
assignments must be made to individual elements only
Error (10137): Verilog HDL Procedural Assignment error 
at multadd_v.v(49): object "multadd_out" on left-hand 
side of assignment must have a variable data type
Error (10048): Verilog HDL error at multadd_v.v(52):
values cannot be assigned directly to all or part of array 
"multadd_sum_tmp" - assignments must be made 
to individual elements only
Error (10048): Verilog HDL error at multadd_v.v(56): 
values cannot be assigned directly to all or part of array 
"multadd_sum_tmp" - assignments must be made to individual elements only
Error (10686): SystemVerilog error at multadd_v.v(56): 
multadd_sum_tmp has an aggregate value
Error (10686): SystemVerilog error at multadd_v.v(56): 
multadd_in has an aggregate value
Error (10686): SystemVerilog error at multadd_v.v(56): 
romfir_in has an aggregate value
Error (10133): Verilog HDL Expression error at multadd_v.v(59): 
illegal part select of unpacked array "multadd_sum_tmp"
"multadd_sum_tmp"

Edited by Acvarif

Share this post


Link to post
Share on other sites
На списки чувствительности я никогда не обращаю внимание. Может и не по правилам. В симуляторе смотрю только временную симуляцию где списки чувствительности до... Какраз временная симуляция это то, что реально работает в железе. Так оно и есть. Все остальное лишнее...

Дело Ваше. Но список чувствительности не от скуки же придумали. И если Вы не обращаете, то не значит, что синтезатор не обращает. А чтобы понять, что в итоге его работы происходит при таком стиле -- это надо богатое воображение иметь. Разберитесь с ним и избежите массы проблем в будущем.

Share this post


Link to post
Share on other sites
Дело Ваше. Но список чувствительности не от скуки же придумали. И если Вы не обращаете, то не значит, что синтезатор не обращает. А чтобы понять, что в итоге его работы происходит при таком стиле -- это надо богатое воображение иметь. Разберитесь с ним и избежите массы проблем в будущем.

Думаю лишний разговор. Что скажете по поводу конкретного кода Verilog? Чего компилятор так сильно заругался после того как были выровнены все begin end?

Share this post


Link to post
Share on other sites
На списки чувствительности я никогда не обращаю внимание.

Правильно! И даже более того, не надо применять гласные буквы и пробелы...

И черт с ней, с медной лампой, это не наша технология. Щука - это наше все... Родное и понятное. Сказал и готово... Кстати, на выставке Радел, мне знакомый парень из Кейсайта сказал, что у них уже появились осциллографы, которые голос понимают...

 

 

Share this post


Link to post
Share on other sites
Правильно! И даже более того, не надо применять гласные буквы и пробелы...

И черт с ней, с медной лампой, это не наша технология. Щука - это наше все... Родное и понятное. Сказал и готово... Кстати, на выставке Радел, мне знакомый парень из Кейсайта сказал, что у них уже появились осциллографы, которые голос понимают...

Просто медная лампа имеет некоторые особенности. Сильно тереть ее не обязательно. Можно дырку протереть. Часто достаточно просто постучать. Эффект будет тотже.

Share this post


Link to post
Share on other sites

Подрехтовав немного код стало намного лучше

(* multstyle = "dsp" *)
module multadd_v 

#(
//разрядность входных данных
parameter multadd_in_lenght = 12,
// разрядность коэффициентов
parameter rom_lenght = 16,
// разрядность выходных данных
parameter multadd_out_lenght = 16
)
(
	// задающая частота 
	input clk_multadd,	
	// общий сброс 
	input clr_multadd,	
	// обнуление результата 
	input zero_multadd, 
	// вкл(выкл)сумматора-умножителя
	input multadd_onoff, 
	// входные данные 
	input signed [(multadd_in_lenght - 1):0] multadd_in, 
	// входной коэффициент 
	input signed [(rom_lenght - 1):0] romfir_in, 
	// выходные данные
	output [(multadd_out_lenght - 1):0] multadd_out 
);


// промежуточный результат
reg [(multadd_out_lenght + multadd_in_lenght - 1):0] multadd_sum_tmp;

always @ (negedge clk_multadd or negedge clr_multadd)
begin
	if (!clr_multadd) 
		//multadd_out <= 0;
		multadd_sum_tmp <= 0;
	else if (!zero_multadd) 
		multadd_sum_tmp <= 0;
	else if (!clk_multadd) begin
		// умножитель включен
		if (multadd_onoff)
			multadd_sum_tmp <= multadd_sum_tmp + (multadd_in * romfir_in);
		// входные данные на выход 
		else 
			multadd_sum_tmp[27:12] <= multadd_in;
	end	
end	

assign multadd_out = multadd_sum_tmp[27:12];

endmodule

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

multadd_sum_tmp(27 downto 12) <= conv_std_logic_vector(signed(multadd_in), 16);

Просто положить 12 разрядов на 16 нельзя. Verilog - пожалуйста

multadd_sum_tmp[27:12] <= multadd_in;

И за это ничего нет...

Я так понимаю, что выражение

else if (!clk_multadd) begin

это отрицательный фронт clk_multadd при наличии clk_multadd в списке чувствительности? А если нужен не фронт, а просто уровень, как тогда?

Edited by Acvarif

Share this post


Link to post
Share on other sites
Подрехтовав немного код стало намного лучше



always @ (negedge clk_multadd or negedge clr_multadd)
begin
	if (!clr_multadd) 

...
	else if (!clk_multadd) begin
....

 

Я так понимаю, что выражение

else if (!clk_multadd) begin

это отрицательный фронт clk_multadd при наличии clk_multadd в списке чувствительности? А если нужен не фронт, а просто уровень, как тогда?

 

Так не делается!

Проект должен быть СИНХРОННЫМ и тактироваться клоком. А этот же клок в "условии" не даст предустановки данных на входе триггера по отношению к его тактовому входу...

Как у Вас соотносятся clk_multadd и основная тактовая в кристалле?

 

Share this post


Link to post
Share on other sites
Так не делается!

Проект должен быть СИНХРОННЫМ и тактироваться клоком. А этот же клок в "условии" не даст предустановки данных на входе триггера по отношению к его тактовому входу...

Как у Вас соотносятся clk_multadd и основная тактовая в кристалле?

clk_multadd - это производная от основной тактовой, а точнее равна ее половине.

Про синхронность мы с Вами уже говорили. Я за. Но при наличии одного и того же клока в проекте он по умолчанию уже синхронен (в смысле проект). А какими фронтами или спадами пользоваться - исходного клока или его производных, пусть даже сильно далеких от основного клока, это уже как считает нужным разработчик. Главное быть внимательным в части задержек. На мой взгляд глобальная синхронность может раздувать проект, что вредно.

 

 

 

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