如果 crc_n_par 被实例化,也需要长度:
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
你可以独立计算两个地方的长度:
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;
但你可以看到这是不必要的重复,需要-2008来分析和阐述:
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 在计算polynom 长度时与您的问题标题匹配:
VHDL 2008 计算不带前导零的向量长度
这就是使用将数组值转换为整数并确定它的 log2 上限并减一的目的。