The length is also needed were crc_n_par is instantiated:
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;
This moves the length calculation to a higher point in the design hierarchy allowing the actual used for the port output to be declared with the proper length as well.
When analyzed, elaborated and simulated it produces:
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
You can independently calculate the length two places:
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;
But you can see that's unnecessary duplication and requires -2008 to analyze and elaborate:
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
Note the - 1
in calculating polynom
length matches your question title:
VHDL 2008 calculate length of vector without leading zeros
And this is the purpose of using conversion of the array value to an integer and determining it's log2 ceiling and subtracting one.
polynom
tolen
is still not clear. Could you describe that more specifically? - JHBonarius