Номера строк предупреждений и ошибок Verilog не могут быть легко обнаружены без идентичного исходного файла, представленного здесь.
В контрольном изображении также отсутствует одно предупреждение (и изображения текста не должны предоставляется в вопросах).
Существует два класса ошибок / предупреждений. Это связано с объявлением функции и присваиванием biti
в блоке always.
function [63:0]bit2bit_sq; // TRANSCRIPTION ERROR WARNING Line (7)
// vector type range wrong SHOULD BE [51:0] NOT [63:0]
input [31:0]x; // TRANSCRIPTION ERROR WARNINGS LINE (8)
// vector type range wrong SHOULD BE [25:0] NOT [31:0]
reg[63:0]y; // TRANSCRIPTION ERROR
begin // TRANSCRIPTION ERROR
for (i =31; i > 0; i=i-1) // TRANSCRIPTION ERROR
// MOVE begin AFTER for loop variable assignment and closing parenthese
// variable i initialization wrong SHOULD be i = 25 NOT i = 30
y [2*i] = x[i];
y [(2*i)+1] = 1'b0;
bit2bit_sq=y; // WARNING Line (14)
end
endfunction
Путаница с размером векторного типа возвращаемого значения и размером векторного типа входных данных x происходит от непонимания семантики VHDL в исходном VHDL:
function bit2bit_sq(x: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
variable y : STD_LOGIC_VECTOR(2*x'left+1 downto 0);
-- Returns x^2 by intercalating zeros in the argument,
-- where x has only one bit different from zero.
begin
for i in x'left downto 0 loop
-- x'right must be zero
y(2*i):=x(i);
y(2*i+1):='0';
end loop;
return y;
end;
Подтип возвращаемого значения определяется выражением (y
), которое возвращается. VHDL строго типизирован, и каждое объявление object определяет подтип , а также базовый тип. Подтип - это тип и ограничение.
Вызов функции для функции может передавать подтип (и здесь необъявленный подтип в объявлении параметра x
происходит из фактического выражения в вызове функции:
for i in 25 downto 0 loop
rt := ('0' & r) - ('0' & (a or bit2bit_sq(biti)));
Есть несколько вещей, которые известны о возвращаемом значении bit2bit_sq
. Из его объявления меткой типа является std_logic_vector. Количество элементов в возвращаемом значении должно быть таким же, как a
:
variable a : STD_LOGIC_VECTOR (51 downto 0);
, поскольку логическому оператору or
требуется соответствующий элемент между его левым и правым операндами.
Известен диапазон индекса переданного параметра biti
:
variable biti : STD_LOGIC_VECTOR (25 downto 0);
Связи между формалами (здесь объявлены параметры) и фактическими данными (переданное выражение, здесь biti
) требуют соответствия элементов, а не идентичных диапазонов индексов.
Это вся информация, необходимая для исправления объявления функции Verilog:
function [63:0]bit2bit_sq; // TRANSCRIPTION ERROR WARNING Line (7)
// vector type range wrong SHOULD BE [51:0] NOT [63:0]
input [31:0]x; // TRANSCRIPTION ERROR WARNINGS LINE (8)
// vector type range wrong SHOULD BE [25:0] NOT [31:0]
reg[63:0]y; // TRANSCRIPTION ERROR
begin // TRANSCRIPTION ERROR
for (i =31; i > 0; i=i-1) // TRANSCRIPTION ERROR
// MOVE begin AFTER for loop variable assignment and closing parenthese
// variable i initialization wrong SHOULD be i = 25 NOT i = 30
y [2*i] = x[i];
y [(2*i)+1] = 1'b0;
end
bit2bit_sq=y; // WARNING Line (14)
// end // MOVED as per
endfunction
Назначение Verilog для biti
имеет недостаточное количество элементов (бит) a Первоначально ssigned:
biti={2'b10,x<=000000};
Источник VHDL назначает все 26 позиций элементов biti
:
biti := "10" & x"000000"; -- 2^(25)
Должен также источник Verilog. Крайний левый элемент a '1', остальные элементы все '0'.
Выводимые защелки не очищаются без номеров строк, но, похоже, происходят из-за несоответствующей длины параметра вызова функции в источнике Verilog.
Остальное предупреждение из-за того, что x_sign
не оценивается (чтение). Его и его назначение можно исключить (также в источнике VHDL).
По определению не должно быть ни предупреждений, ни ошибок при компиляции Verilog, в источнике VHDL их нет.
При моделировании источник VHDL приближается к выходу пакета -2008 IEEE, упакованного float_pkg. Это можно проверить с помощью тестового стенда:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.float_pkg.all;
entity sqrt_tb is
end entity;
architecture fuu of sqrt_tb is
signal x, y: std_logic_vector(31 downto 0);
begin
DUT:
entity work.sqrt
port map (
x => x,
y => y
);
THE_PROCESS:
process
begin
wait for 0 ns; -- ignores default value
for i in 14 to 35 loop
report "x = " & integer'image(i);
x <= to_stdlogicvector(to_float(real(i)));
wait for 0 ns;
report LF & HT & "X = " & to_string(to_float(x));
wait for 1 ns;
report LF & HT & "y = " & to_string(to_float(y)) &
LF & "expected = " & to_string(sqrt(to_float(x))) &
LF & HT & "y = " & real'image(to_real(to_float(y))) &
LF & "expected = " & real'image(to_real(sqrt(to_float(x)))) & LF;
end loop;
wait for 0 ns;
wait;
end process;
end architecture;
Обратите внимание, что квадрат root из 14 и 35 варьируется.
sqrt_tb.vhdl:163:13:@0ms:(report note): x = 14
sqrt_tb.vhdl:166:13:@0ms:(report note):
X = 0:10000010:11000000000000000000000
sqrt_tb.vhdl:168:13:@1ns:(report note):
y = 0:10000000:11011110111011101010001
expected = 0:10000000:11011110111011101010000
y = 3.7416574954986572
expected = 3.741657257080078
sqrt_tb.vhdl:163:13:@21ns:(report note): x = 35
sqrt_tb.vhdl:166:13:@21ns:(report note):
X = 0:10000100:00011000000000000000000
sqrt_tb.vhdl:168:13:@22ns:(report note):
y = 0:10000001:01111010101000010000111
expected = 0:10000001:01111010101000010000110
y = 5.916079998016357
expected = 5.916079521179199
Есть небольшая разница в алгоритмах c. В результате мантисса LSB выглядит иначе, это проблема точности (числа с плавающей запятой являются приблизительными).