vhdl 中寄存器的算术平均值
Arithmetic mean of a register in vhdl
对于我目前正在进行的项目,我正在尝试获取一些输入,将它们存储在寄存器中,然后找到寄存器的算术平均值。我所有的输入都是 24 位长。我的寄存器有 4 个输入长,因此我简单地删除最低有效位的最后 3 位,同时将它们除以 4 以计算算术平均值,然后简单地将它们相加。
mean 是我的 register(95 downto 0)
(4 x 24 = 96),mean_medium
是类型 unsigned
.
当我编写以下行时
signal mean_medium : unsigned (23 downto 0) := (others => '0');
mean_medium <= unsigned(medium (95 downto 75)) +
unsigned(medium (71 downto 51)) +
unsigned(medium (47 downto 27)) +
unsigned(medium (23 downto 3)) ;
我接受了以下警告:
Width mismatch. mean_medium has a width of 24 bits but assigned expression is 21-bit wide.
你有什么解决这个问题的建议吗?
我假设您使用的是 numeric_std
包。
在numeric_std
包中,+
运算符要求和的宽度与最宽的操作数的宽度相同。你的操作数是 21 位宽,你的总和是 24 位宽。因此,您也需要将操作数设置为 24 位宽。您可以使用 numeric_std
中的 resize
函数来执行此操作。事实上,这应该足够了:
mean_medium <= resize(unsigned(medium (95 downto 75)),24) +
unsigned(medium (71 downto 51)) +
unsigned(medium (47 downto 27)) +
unsigned(medium (23 downto 3)) ;
但如果您认为它更整洁,您也可以这样做:
mean_medium <= resize(unsigned(medium (95 downto 75)),24) +
resize(unsigned(medium (71 downto 51)),24) +
resize(unsigned(medium (47 downto 27)),24) +
resize(unsigned(medium (23 downto 3)) ,24) ;
或者对此进行一些改进:
mean_medium <= resize(unsigned(medium (95 downto 75)),mean_medium'length) +
unsigned(medium (71 downto 51)) +
unsigned(medium (47 downto 27)) +
unsigned(medium (23 downto 3)) ;
等式两边应该有相同的大小,你可以使用调整大小函数或者你可以使用 24 位临时信号并这样做:
signal temp : std_logic_vector(23 downto 0);
temp(23 downto 21) <= "000";
temp(20 downto 0) <= medium (95 downto 75);
mean_medium <= temp + ....
一个错误是你通过移动 3 位来除以四。您只需要移动 2 位。
但对于 correct/precise 算术,您应该 而不是 预移动该表达式的运算符,因为您会因截断而失去精度。首先将所有 4 个完整的 24 位值添加到一个 26 位输出。然后对输出进行移位和舍入。例子
signal mean_medium : unsigned (23 downto 0); -- redundant := (others => '0');
signal mean_temp : unsigned(25 downto 0);
mean_temp <=
resize(unsigned(medium (95 downto 72)), mean_Temp'length) +
resize(unsigned(medium (71 downto 48)), mean_Temp'length) +
resize(unsigned(medium (47 downto 24)), mean_Temp'length) +
resize(unsigned(medium (23 downto 0)), mean_Temp'length) +
2; -- round factor
mean_medium <= shift_right(mean_temp, 2); --divide by 4
p.s。您也可以将其组合成一行,从而消除 mean_temp
.
的必要性
对于我目前正在进行的项目,我正在尝试获取一些输入,将它们存储在寄存器中,然后找到寄存器的算术平均值。我所有的输入都是 24 位长。我的寄存器有 4 个输入长,因此我简单地删除最低有效位的最后 3 位,同时将它们除以 4 以计算算术平均值,然后简单地将它们相加。
mean 是我的 register(95 downto 0)
(4 x 24 = 96),mean_medium
是类型 unsigned
.
当我编写以下行时
signal mean_medium : unsigned (23 downto 0) := (others => '0');
mean_medium <= unsigned(medium (95 downto 75)) +
unsigned(medium (71 downto 51)) +
unsigned(medium (47 downto 27)) +
unsigned(medium (23 downto 3)) ;
我接受了以下警告:
Width mismatch. mean_medium has a width of 24 bits but assigned expression is 21-bit wide.
你有什么解决这个问题的建议吗?
我假设您使用的是 numeric_std
包。
在numeric_std
包中,+
运算符要求和的宽度与最宽的操作数的宽度相同。你的操作数是 21 位宽,你的总和是 24 位宽。因此,您也需要将操作数设置为 24 位宽。您可以使用 numeric_std
中的 resize
函数来执行此操作。事实上,这应该足够了:
mean_medium <= resize(unsigned(medium (95 downto 75)),24) +
unsigned(medium (71 downto 51)) +
unsigned(medium (47 downto 27)) +
unsigned(medium (23 downto 3)) ;
但如果您认为它更整洁,您也可以这样做:
mean_medium <= resize(unsigned(medium (95 downto 75)),24) +
resize(unsigned(medium (71 downto 51)),24) +
resize(unsigned(medium (47 downto 27)),24) +
resize(unsigned(medium (23 downto 3)) ,24) ;
或者对此进行一些改进:
mean_medium <= resize(unsigned(medium (95 downto 75)),mean_medium'length) +
unsigned(medium (71 downto 51)) +
unsigned(medium (47 downto 27)) +
unsigned(medium (23 downto 3)) ;
等式两边应该有相同的大小,你可以使用调整大小函数或者你可以使用 24 位临时信号并这样做:
signal temp : std_logic_vector(23 downto 0);
temp(23 downto 21) <= "000";
temp(20 downto 0) <= medium (95 downto 75);
mean_medium <= temp + ....
一个错误是你通过移动 3 位来除以四。您只需要移动 2 位。
但对于 correct/precise 算术,您应该 而不是 预移动该表达式的运算符,因为您会因截断而失去精度。首先将所有 4 个完整的 24 位值添加到一个 26 位输出。然后对输出进行移位和舍入。例子
signal mean_medium : unsigned (23 downto 0); -- redundant := (others => '0');
signal mean_temp : unsigned(25 downto 0);
mean_temp <=
resize(unsigned(medium (95 downto 72)), mean_Temp'length) +
resize(unsigned(medium (71 downto 48)), mean_Temp'length) +
resize(unsigned(medium (47 downto 24)), mean_Temp'length) +
resize(unsigned(medium (23 downto 0)), mean_Temp'length) +
2; -- round factor
mean_medium <= shift_right(mean_temp, 2); --divide by 4
p.s。您也可以将其组合成一行,从而消除 mean_temp
.