澄清: 如果输入向量看起来像" 000100111",则输出向量也应该是(4 downto 0)。这就是我无法使用' length 的原因。
entity CRC_n_par is
generic(
polynom : std_logic_vector
);
port(
clk : in std_logic;
input : in std_logic;
reset : in std_logic;
output : out std_logic_vector(integer(ceil(log2(real(to_integer(unsigned(polynom))))))-2 downto 0) );
end entity;
architecture Behavioral of CRC_n_par is
constant len : integer := integer(ceil(log2(real(to_integer(unsigned(polynom))))))-2;
有没有办法,这样做更优雅。 Here's类似的问题,但我不能在端口声明中使用函数。在端口声明之后,我再次使用常量len。 有没有办法在vhdl中使用类似c的宏? 我正在使用vhdl 2008,这就是转换如此复杂的原因,因为我只能在密切相关的类型之间进行转换。
答案 0 :(得分:1)
crc_n_par实例化时还需要长度:
Foo
这会将长度计算移动到设计层次结构中的更高点,从而允许以适当的长度声明用于端口输出的实际值。
经过分析,精心制作并模拟出来:
library ieee; use ieee.std_logic_1164.all; entity crc_n_par is generic ( len: natural ); port ( clk: in std_logic; input: in std_logic; reset: in std_logic; output: out std_logic_vector (len - 1 downto 0) ); end entity; architecture Behavioral of crc_n_par is begin MONITOR: process begin report "crc_n_par output len = " & integer'image(len); wait; end process; end architecture; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity some_top_level is end entity; architecture foo of some_top_level is -- For -2002 and earlier, present in -2008: function to_string (inp: std_logic_vector) return string is variable image_str: string (1 to inp'length); alias input_str: std_logic_vector (1 to inp'length) is inp; begin for i in input_str'range loop image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i))); end loop; return image_str; end function; constant polynom: std_logic_vector := "000100111"; constant crc_inst_len : natural := integer(ceil(log2(real(to_integer(unsigned(polynom))))))-1; signal clk: std_logic; signal input: std_logic; signal reset: std_logic; signal output: std_logic_vector (crc_inst_len - 1 downto 0); begin MONITOR: process begin report LF & "polynom len = " & integer'image(polynom'length) & " crc_inst_len = " & integer'image(crc_inst_len) & LF & " output length = " & integer'image(output'length) & " polynom = " & to_string(polynom); wait; end process; CRC_INSTANCE: entity work.crc_n_par generic map ( len => crc_inst_len ) port map ( clk => clk, input => input, reset => reset, output => output ); end architecture;
您可以独立计算两个地方的长度:
ghdl -a some_top_level.vhdl
ghdl -e some_top_level
ghdl -r some_top_level
some_top_level.vhdl:20:9:@0ms:(report note): crc_n_par output len = 5
some_top_level.vhdl:55:9:@0ms:(report note):
polynom len = 9 crc_inst_len = 5
output length = 5 polynom = 000100111
但你可以看到这是不必要的重复,需要-2008来分析和阐述:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity crc_n_par is generic ( polynom: std_logic_vector; len: natural := -- requires -2008 to access polynom integer(ceil(log2(real(to_integer(unsigned(polynom)))))) - 1 ); port ( clk: in std_logic; input: in std_logic; reset: in std_logic; output: out std_logic_vector (len - 1 downto 0) ); end entity; architecture Behavioral of crc_n_par is begin MONITOR: process begin report "len = " & integer'image(len); wait; end process; end architecture; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity some_top_level is end entity; architecture foo of some_top_level is constant polynom: std_logic_vector := "000100111"; constant crc_inst_len : natural := integer(ceil(log2(real(to_integer(unsigned(polynom))))))-1; signal clk: std_logic; signal input: std_logic; signal reset: std_logic; signal output: std_logic_vector (crc_inst_len - 1 downto 0); begin MONITOR: process begin report LF & "polynom len = " & integer'image(polynom'length) & " crc_inst_len = " & integer'image(crc_inst_len) & LF & " output length = " & integer'image(output'length) & " polynom = " & to_string(polynom); wait; end process; CRC_INSTANCE: entity work.crc_n_par generic map ( polynom => polynom -- don't pass len ) port map ( clk => clk, input => input, reset => reset, output => output ); end architecture;
请注意,计算ghdl -a --std=08 crc_n_par.vhdl
ghdl -e --std=08 crc_n_par
ghdl -r --std=08 some_top_level
some_top_level.vhdl:20:9:@0ms:(report note): crc_n_par output len = 5
some_top_level.vhdl:55:9:@0ms:(report note):
polynom len = 9 crc_inst_len = 5
output length = 5 polynom = 000100111
长度的- 1
与您的问题标题相匹配:
VHDL 2008计算不带前导零的向量长度
这是使用数组值转换为整数并确定它的log2上限并减去一个的目的。
答案 1 :(得分:0)
首先:您的问题不明确。你说你想确定一个没有前导零的向量的长度。 100111
没有前导零,因此长度为6.并且还不清楚如何从4到5个字节的长度。
嗯,这取决于您的具体实施,这将是一种最佳方法。我会在包中使用一个函数。即。
library ieee;
use ieee.std_logic_1164.all;
package my_functions is
function det_output_len(polynom:std_logic_vector) return positive;
end package;
library ieee;
use ieee.numeric_std.all;
use ieee.math_real.all;
package body my_functions is
function det_output_len(polynom:std_logic_vector) return positive is
begin
return integer(ceil(log2(real(to_integer(unsigned(polynom))))))-1;
end function;
end package body;
然后在你的实体中:
use work.my_functions.all;
entity CRC_n_par is
[...]
port(
[...]
output : out std_logic_vector(det_output_len(polynom)-1 downto 0) );
end entity;
对于常数' len,您不需要重新计算该功能。如果已经为输出向量设置了长度,则可以使用VHDL attributes(旧站点,而不是VHDL-2008上的最新版本)。即。
constant len : positive := output'length;
顺便说一下,这不是VHDL-2008特有的,因为它在VHDL中支持了一段时间。