在模拟中,这很完美。这是检查可综合代码的零的最佳方法吗?会产生什么资源?
signal vector_slv : std_logic_vector(2048 downto 0);
...
if (vector_slv = (vector_slv'range => '0')) then
-- do something...
考虑到硬件映射(具有最佳资源利用率),是否有任何其他最佳方式来实施此解决方案。
我会对了解所使用的资源更感兴趣。
在模拟中,这很完美。这是检查可综合代码的零的最佳方法吗?会产生什么资源?
signal vector_slv : std_logic_vector(2048 downto 0);
...
if (vector_slv = (vector_slv'range => '0')) then
-- do something...
考虑到硬件映射(具有最佳资源利用率),是否有任何其他最佳方式来实施此解决方案。
我会对了解所使用的资源更感兴趣。
没有办法对合成或多或少有意义。编写最能表达您意图的代码。
如果您要比较一个全零的向量,则以下结果都应该产生相同的结果,或者您应该针对该工具提交一个严重的错误!
signal vector_slv : std_logic_vector(2048 downto 0);
constant zeros : std_logic_vector(vector_slv'range) := (others => '0');
...
if vector_slv = (vector_slv'range => '0') then
-- do something...
if vector_slv = zeros then
-- do something...
if unsigned(vector_slv) = to_unsigned(0, vector_slv'length) then
-- do something...
实际上对于适合整数的较短向量:
if intvar = 0 then
将与任何 32 位向量比较完全相同。
(顺便说一句,请注意条件周围不需要括号if
- VHDL 不是 C :)
如果范围可用,如您的示例代码中所示,那么建议解决方案看起来不错,我希望合成工具可以处理这样的结构。
如果范围不可用,则可以与零进行比较,如下所示:
library ieee;
use ieee.numeric_std.all;
...
if unsigned( {std_logic_vector expression of any length} ) = 0 then
-- do something...
我希望综合工具可以处理这个问题,就像比较(vector_slv'range => '0')
.
就综合而言,是的,这种简单的构造通常由该工具很好地优化。确切的硬件布局当然取决于您的目标是什么(FPGA、ASIC,...)。
我的建议是查看综合结果(例如 Altera FPGA 的 Technology Map Viewer)。如果综合破坏了它,您可以手动将其转换为与零比较的二叉树,同时考虑到您可用的技术原语。不过,这可能比听起来要棘手得多,尤其是对于 FPGA(那里不仅有 LUT 可以玩),而且对于一个像样的工具来说,这不是必需的。
您可以使用一元运算符,例如:
signal vector_slv: std_logic_vector(2048 downto 0);
...
if and vector_slv then
-- Do something for all 1...
elsif nand vector_slv then
-- Do something for at least one 0...
elsif or vector_slv then
-- Do something for at least one 1...
elsif nor vector_slv then
-- Do something for all 0...
end if;
或者您可以使用std_logic_1164中定义的函数,例如:
function "and" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
function "nand" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
function "or" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
function "nor" (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
use ieee.std_logic_1164.all;
...
signal vector_slv: std_logic_vector(2048 downto 0);
...
if and(vector_slv) then
-- Do something for all 1...
elsif nand(vector_slv) then
-- Do something for at least one 0...
elsif or(vector_slv) then
-- Do something for at least one 1...
elsif nor(vector_slv) then
-- Do something for all 0...
end if;
您还可以通过这样做来分离谓词和赋值:
signal is_zero : boolean;
signal vector_slv : std_logic_vector(2048 downto 0);
...
process(clk)
begin
if rising_edge(clk) then
is_zero <= vector_slv = (vector_slv'range => '0');
if is_zero then
...
end if;
end if;
end process;
这应该会极大地改善您的计时。考虑到谓词“is_zero”现在是原始比较的延迟版本!