移位溢出错误?超高密度语言
Overflow error in shift? VHDL
我正在尝试将千克转换为 Lib,为此我使用移位器进行转换(由于输出的表示形式不是小数,我会出现一个小错误),我发现正确的函数和值来进行转换,当我这样说时,我的意思是我的移位值是正确的,如果有人想要转换函数,请在下面的评论中告诉我。
我的问题是:当我输入大于 130 KG 的值时,转换出错,小值则 130 KG 工作正常。我正在使用 16 位输入(千克输入)和 16 位输出(LB 输出)。
出现这个错误的时候,我第一时间以为是加法器溢出错误,但是所有加法器都没有进位,所以不可能是加法器溢出。我试图在值(32 位)中使用更大的表示,但错误仍然出现。由于这个原因,我删除了执行输出。
代码下方:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity shift_register is
port (
i_DIN : in unsigned (15 downto 0);
o_DOUT0 : out unsigned (15 downto 0);
o_DOUT1 : out unsigned (15 downto 0);
o_DOUT2 : out unsigned (15 downto 0);
o_DOUT3 : out unsigned (15 downto 0));
end shift_register;
architecture arch_1 of shift_register is
begin
o_DOUT0 <= i_DIN SLL 9;
o_DOUT1 <= i_DIN SLL 5;
o_DOUT2 <= i_DIN SLL 2;
o_DOUT3 <= i_DIN SLL 1;
end arch_1;
在这部分,我对转换工作进行了 4 次必要的转换,在此之后我得到 4 个值输出并求和为 2 个半加器。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity half_adder is
port (
i_DIN0 : in unsigned(15 downto 0); -- data input
i_DIN1 : in unsigned(15 downto 0); -- data input
o_DOUT : out unsigned(16 downto 0)); -- data output
end half_adder;
architecture arch_1 of half_adder is
begin
process(i_DIN0,i_DIN1)
variable soma:unsigned(15 downto 0);
variable c:std_logic;
begin
c :='0';
for i in 0 to 15 loop
soma(i) := i_DIN0(i) xor i_DIN1(i) xor c;
c := (i_DIN0(i) and i_DIN1(i)) or ((i_DIN0(i) xor i_DIN1(i)) and c);
end loop;
o_DOUT(15 downto 0)<= soma(15 downto 0);
o_DOUT(16) <= c;
end process;
end arch_1;
我将有 2 个输出,每个半加器 1 个,这 2 个输出我加到一个全加器中以获得最终的移位值,2 个半加器的进位在每个输出的最后一位连接.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity full_adder is
port (
i_DIN0 : in unsigned(16 downto 0);
i_DIN1 : in unsigned(16 downto 0);
o_DOUT : out unsigned(16 downto 0));
end full_adder;
architecture arch_1 of full_adder is
begin
process(i_DIN0,i_DIN1)
variable soma:unsigned(16 downto 0);
variable c:std_logic;
begin
c := '0';
for i in 0 to 16 loop
soma(i) := i_DIN0(i) xor i_DIN1(i) xor c;
c := (i_DIN0(i) and i_DIN1(i)) or ((i_DIN0(i) xor i_DIN1(i)) and c);
end loop;
o_DOUT <= soma;
end process;
end arch_1;
这里我没有将全加器的进位连接到输出的最后一位,因为我想在总和溢出时显示进位。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity div_register is
port (
i_DIN : in unsigned (16 downto 0);
o_DOUT : out unsigned (16 downto 0));
end div_register;
architecture arch_1 of div_register is
begin
o_DOUT <= i_DIN SRL 8;
end arch_1;
最后我将4个初始移位的总和除以得到转换后的值。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity kg_to_lb is
port (
i_INPUTKG : in unsigned(15 downto 0); -- data input
o_OUTLB : out unsigned(16 downto 0)); -- data output
end kg_to_lb;
architecture arch_1 of kg_to_lb is
component full_adder is
port (
i_DIN0 : in unsigned(16 downto 0);
i_DIN1 : in unsigned(16 downto 0);
o_DOUT : out unsigned(16 downto 0)); -- data output
end component;
component half_adder is
port (
i_DIN0 : in unsigned(15 downto 0); -- data input
i_DIN1 : in unsigned(15 downto 0); -- data input
o_DOUT : out unsigned(16 downto 0)); -- data output
end component;
component shift_register is
port (
i_DIN : in unsigned (15 downto 0);
o_DOUT0 : out unsigned (15 downto 0);
o_DOUT1 : out unsigned (15 downto 0);
o_DOUT2 : out unsigned (15 downto 0);
o_DOUT3 : out unsigned (15 downto 0)); -- data output
end component;
component div_register is
port (
i_DIN : in unsigned (16 downto 0);
o_DOUT : out unsigned (16 downto 0)); -- data output
end component;
signal w_OUT0 : unsigned(15 downto 0);
signal w_OUT1 : unsigned(15 downto 0);
signal w_OUT2 : unsigned(15 downto 0);
signal w_OUT3 : unsigned(15 downto 0);
signal w_OUT4 : unsigned(16 downto 0);
signal w_OUT5 : unsigned(16 downto 0);
signal w_OUT6 : unsigned(16 downto 0);
signal w_OUT7 : unsigned(16 downto 0);
begin
u_0: shift_register port map (
i_DIN => i_INPUTKG,
o_DOUT0 => w_OUT0,
o_DOUT1 => w_OUT1,
o_DOUT2 => w_OUT2,
o_DOUT3 => w_OUT3
);
u_1: half_adder port map (
i_DIN0 => w_OUT0,
i_DIN1 => w_OUT1,
o_DOUT => w_OUT4
);
u_2: half_adder port map (
i_DIN0 => w_OUT2,
i_DIN1 => w_OUT3,
o_DOUT => w_OUT5
);
u_3: full_adder port map (
i_DIN0 => w_OUT4,
i_DIN1 => w_OUT5,
o_DOUT => w_OUT6
);
u_4: div_register port map (
i_DIN => w_OUT6,
o_DOUT => w_OUT7
);
o_OUTLB <= w_OUT7;
end arch_1;
这是我的主文件,我在其中完成了所有这些,基本上我使用的是与下图相同的架构,唯一的区别是偏移,因为我在转换函数中使用了另一个值,但是换个图还是报错
以下正确转换:
就像我之前说的,由于忽略了小数部分,所以会出现错误。当我输入大于 130KG 的值时,转换出错:
注意:在我的模拟中,我没有从全加器中取出进位,因为我已经模拟了这个,并且在模拟中没有出现进位(溢出错误),因此我认为错误是在轮班中。
有人知道这是什么吗?
错误出在内部寄存器宽度上,当我移位逻辑 9 时,对于大于 8 位的值,de 输出保持为 0,因为移位太大,解决方案是使用更大的寄存器(32 位在这种情况)。
我正在尝试将千克转换为 Lib,为此我使用移位器进行转换(由于输出的表示形式不是小数,我会出现一个小错误),我发现正确的函数和值来进行转换,当我这样说时,我的意思是我的移位值是正确的,如果有人想要转换函数,请在下面的评论中告诉我。
我的问题是:当我输入大于 130 KG 的值时,转换出错,小值则 130 KG 工作正常。我正在使用 16 位输入(千克输入)和 16 位输出(LB 输出)。
出现这个错误的时候,我第一时间以为是加法器溢出错误,但是所有加法器都没有进位,所以不可能是加法器溢出。我试图在值(32 位)中使用更大的表示,但错误仍然出现。由于这个原因,我删除了执行输出。
代码下方:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity shift_register is
port (
i_DIN : in unsigned (15 downto 0);
o_DOUT0 : out unsigned (15 downto 0);
o_DOUT1 : out unsigned (15 downto 0);
o_DOUT2 : out unsigned (15 downto 0);
o_DOUT3 : out unsigned (15 downto 0));
end shift_register;
architecture arch_1 of shift_register is
begin
o_DOUT0 <= i_DIN SLL 9;
o_DOUT1 <= i_DIN SLL 5;
o_DOUT2 <= i_DIN SLL 2;
o_DOUT3 <= i_DIN SLL 1;
end arch_1;
在这部分,我对转换工作进行了 4 次必要的转换,在此之后我得到 4 个值输出并求和为 2 个半加器。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity half_adder is
port (
i_DIN0 : in unsigned(15 downto 0); -- data input
i_DIN1 : in unsigned(15 downto 0); -- data input
o_DOUT : out unsigned(16 downto 0)); -- data output
end half_adder;
architecture arch_1 of half_adder is
begin
process(i_DIN0,i_DIN1)
variable soma:unsigned(15 downto 0);
variable c:std_logic;
begin
c :='0';
for i in 0 to 15 loop
soma(i) := i_DIN0(i) xor i_DIN1(i) xor c;
c := (i_DIN0(i) and i_DIN1(i)) or ((i_DIN0(i) xor i_DIN1(i)) and c);
end loop;
o_DOUT(15 downto 0)<= soma(15 downto 0);
o_DOUT(16) <= c;
end process;
end arch_1;
我将有 2 个输出,每个半加器 1 个,这 2 个输出我加到一个全加器中以获得最终的移位值,2 个半加器的进位在每个输出的最后一位连接.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity full_adder is
port (
i_DIN0 : in unsigned(16 downto 0);
i_DIN1 : in unsigned(16 downto 0);
o_DOUT : out unsigned(16 downto 0));
end full_adder;
architecture arch_1 of full_adder is
begin
process(i_DIN0,i_DIN1)
variable soma:unsigned(16 downto 0);
variable c:std_logic;
begin
c := '0';
for i in 0 to 16 loop
soma(i) := i_DIN0(i) xor i_DIN1(i) xor c;
c := (i_DIN0(i) and i_DIN1(i)) or ((i_DIN0(i) xor i_DIN1(i)) and c);
end loop;
o_DOUT <= soma;
end process;
end arch_1;
这里我没有将全加器的进位连接到输出的最后一位,因为我想在总和溢出时显示进位。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity div_register is
port (
i_DIN : in unsigned (16 downto 0);
o_DOUT : out unsigned (16 downto 0));
end div_register;
architecture arch_1 of div_register is
begin
o_DOUT <= i_DIN SRL 8;
end arch_1;
最后我将4个初始移位的总和除以得到转换后的值。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity kg_to_lb is
port (
i_INPUTKG : in unsigned(15 downto 0); -- data input
o_OUTLB : out unsigned(16 downto 0)); -- data output
end kg_to_lb;
architecture arch_1 of kg_to_lb is
component full_adder is
port (
i_DIN0 : in unsigned(16 downto 0);
i_DIN1 : in unsigned(16 downto 0);
o_DOUT : out unsigned(16 downto 0)); -- data output
end component;
component half_adder is
port (
i_DIN0 : in unsigned(15 downto 0); -- data input
i_DIN1 : in unsigned(15 downto 0); -- data input
o_DOUT : out unsigned(16 downto 0)); -- data output
end component;
component shift_register is
port (
i_DIN : in unsigned (15 downto 0);
o_DOUT0 : out unsigned (15 downto 0);
o_DOUT1 : out unsigned (15 downto 0);
o_DOUT2 : out unsigned (15 downto 0);
o_DOUT3 : out unsigned (15 downto 0)); -- data output
end component;
component div_register is
port (
i_DIN : in unsigned (16 downto 0);
o_DOUT : out unsigned (16 downto 0)); -- data output
end component;
signal w_OUT0 : unsigned(15 downto 0);
signal w_OUT1 : unsigned(15 downto 0);
signal w_OUT2 : unsigned(15 downto 0);
signal w_OUT3 : unsigned(15 downto 0);
signal w_OUT4 : unsigned(16 downto 0);
signal w_OUT5 : unsigned(16 downto 0);
signal w_OUT6 : unsigned(16 downto 0);
signal w_OUT7 : unsigned(16 downto 0);
begin
u_0: shift_register port map (
i_DIN => i_INPUTKG,
o_DOUT0 => w_OUT0,
o_DOUT1 => w_OUT1,
o_DOUT2 => w_OUT2,
o_DOUT3 => w_OUT3
);
u_1: half_adder port map (
i_DIN0 => w_OUT0,
i_DIN1 => w_OUT1,
o_DOUT => w_OUT4
);
u_2: half_adder port map (
i_DIN0 => w_OUT2,
i_DIN1 => w_OUT3,
o_DOUT => w_OUT5
);
u_3: full_adder port map (
i_DIN0 => w_OUT4,
i_DIN1 => w_OUT5,
o_DOUT => w_OUT6
);
u_4: div_register port map (
i_DIN => w_OUT6,
o_DOUT => w_OUT7
);
o_OUTLB <= w_OUT7;
end arch_1;
这是我的主文件,我在其中完成了所有这些,基本上我使用的是与下图相同的架构,唯一的区别是偏移,因为我在转换函数中使用了另一个值,但是换个图还是报错
以下正确转换:
就像我之前说的,由于忽略了小数部分,所以会出现错误。当我输入大于 130KG 的值时,转换出错:
注意:在我的模拟中,我没有从全加器中取出进位,因为我已经模拟了这个,并且在模拟中没有出现进位(溢出错误),因此我认为错误是在轮班中。
有人知道这是什么吗?
错误出在内部寄存器宽度上,当我移位逻辑 9 时,对于大于 8 位的值,de 输出保持为 0,因为移位太大,解决方案是使用更大的寄存器(32 位在这种情况)。