我正在使用 VHDL 构建一个 MP3 解码器,我想让它可合成,因为我知道对于可变大小的循环并从可变位置选择可变大小std_logic_vector
也是不可合成的
那么如何使循环可合成以及如何从可std_logic_vector
合成中选择可变大小
for j in 0 to switch_point_1-1 loop
bits:= data(ptr+current+scale_lengths(j)-1 downto ptr+current);
scalefac(j)(0) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
scalefac(j)(1) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
scalefac(j)(2) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
current := current+ scale_lengths(j);
end loop;
还有一个
for j in switch_point_s-1 to cb_max loop
for k in 0 to 2 loop
-- window
bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
scalefac(j)(k) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
current := current+ scale_lengths(j);
end loop;
end loop;
这是我拥有的循环之一,其中有一个选择bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
也是不可合成的,我怎样才能使它们可合成?
完整代码:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.txt_util.all;
--use txt_util.all;
entity extract_main is
port(
data:in std_logic_vector(4095 downto 0);
en: in std_logic;
gr,clk:in std_logic;
enabled:in std_logic;
scsfi:in std_logic_vector(20 downto 0);
ptr: in integer;
windows_switching: in std_logic;
block_type: in std_logic_vector(1 downto 0);
mixed_block_flag: in std_logic;
part2_3_length: in std_logic_vector(11 downto 0);
slen1,slen2: in integer;
saved_scalefac_in: in integer;
saved_scalefac_out: out integer;
ptr_out: out integer;
enablenext:out std_logic
);
end extract_main;
architecture a of extract_main is
type intarr is array(20 downto 0) of integer;
type scalef is array(20 downto 0) of intarr;
begin
process(clk)
variable scalefac : scalef;
variable scale_lengths : intarr;
variable mainInfoBegin,mainInfoSize : integer;
variable blockType : integer;
variable part2_length :integer;
variable switch_point_1: integer;
variable switch_point_s: integer;
variable cb_max : integer;
variable current: integer:=0; -- iterator on data
variable it: integer;
variable bits: std_logic_vector(3 downto 0):="0000";
variable ptrout: integer;
begin
if enabled ='1' then
--size of main data
if falling_edge(clk) then
if en = '1' then
mainInfoSize := to_integer(UNSIGNED(part2_3_length));
if windows_switching = '0' then
blockType := 0;
else
blockType := to_integer(UNSIGNED(block_type));
end if;
if blockType = 2 and mixed_block_flag = '1' then
part2_length := 17 * slen1 + 18 * slen2;
scale_lengths(16) :=slen2;
scale_lengths(15) :=slen2;
scale_lengths(14) :=slen2;
scale_lengths(13) :=slen2;
scale_lengths(12) :=slen2;
scale_lengths(11) :=slen2;
scale_lengths(10) :=slen1;
scale_lengths(9) :=slen1;
scale_lengths(8) :=slen1;
scale_lengths(7) :=slen1;
scale_lengths(6) :=slen1;
scale_lengths(5) :=slen1;
scale_lengths(4) :=slen1;
scale_lengths(3) :=slen1;
scale_lengths(2) :=slen1;
scale_lengths(1) :=slen1;
scale_lengths(0) :=slen1;
cb_max := 16;
switch_point_1 := 8;
switch_point_s := 9;
elsif blockType = 2 and mixed_block_flag = '0' then
part2_length := 18 * slen1 + 18 * slen2;
scale_lengths(11) :=slen2;
scale_lengths(10) :=slen2;
scale_lengths(9) :=slen2;
scale_lengths(8) :=slen2;
scale_lengths(7) :=slen2;
scale_lengths(6) :=slen2;
scale_lengths(5) :=slen1;
scale_lengths(4) :=slen1;
scale_lengths(3) :=slen1;
scale_lengths(2) :=slen1;
scale_lengths(1) :=slen1;
scale_lengths(0) :=slen1;
switch_point_1 := 0;
switch_point_s := 1;
cb_max := 11;
else
part2_length := 11 * slen1 + 10 * slen2;
--scalefactor_bands(20 downto 11) <= slen2;
--scalefactor_bands(10 downto 0)<= slen1;
scale_lengths(20) :=slen2;
scale_lengths(19) :=slen2;
scale_lengths(18) :=slen2;
scale_lengths(17) :=slen2;
scale_lengths(16) :=slen2;
scale_lengths(15) :=slen2;
scale_lengths(14) :=slen2;
scale_lengths(13) :=slen2;
scale_lengths(12) :=slen2;
scale_lengths(11) :=slen2;
scale_lengths(10) :=slen1;
scale_lengths(9) :=slen1;
scale_lengths(8) :=slen1;
scale_lengths(7) :=slen1;
scale_lengths(6) :=slen1;
scale_lengths(5) :=slen1;
scale_lengths(4) :=slen1;
scale_lengths(3) :=slen1;
scale_lengths(2) :=slen1;
scale_lengths(1) :=slen1;
scale_lengths(0) :=slen1;
cb_max := 20;
end if;
if blockType = 2 and windows_switching = '1' then
for j in 0 to switch_point_1-1 loop
-- it:=0;
--for e in ptr+current to ptr+current+scale_lengths(j)-1 loop
-- bits(it) := ram(e)(0);
--it := it+1;
--end loop;
bits:= data(ptr+current+scale_lengths(j)-1 downto ptr+current);
scalefac(j)(0) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
scalefac(j)(1) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
scalefac(j)(2) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
current := current+ scale_lengths(j);
end loop;
for j in switch_point_s-1 to cb_max loop
for k in 0 to 2 loop
-- window
-- it:=0;
-- for e in ptr+current to ptr+current+scale_lengths(j)-1 loop
-- bits(it) := ram(e)(0);
-- it := it+1;
--end loop;
bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
scalefac(j)(k) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
current := current+ scale_lengths(j);
end loop;
end loop;
else
for j in 0 to 20 loop
if gr ='0' or scsfi(j) ='0' then
-- it:=0;
-- for e in ptr+current to ptr+current+scale_lengths(j)-1 loop
-- bits(it) := ram(e)(0);
-- it := it+1;
--end loop;
bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
scalefac(j)(0):= to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
current := current+ scale_lengths(j);
else
scalefac(j)(0):= saved_scalefac_in;
end if;
end loop;
if gr ='1' then
if scsfi(0) /= '0' or scsfi(6) /='0' or scsfi(11)/='0' or scsfi(16)/='0' then
saved_scalefac_out<=scalefac(0)(0);
end if;
end if;
end if;
ptrout:=ptr+current;
ptr_out<=ptrout;
enablenext<='1';
end if;
end if;
else enablenext<='0';
end if;
end process;
end;