循环运算符 "For" 以填充 VHDL 中的数组
Loop operator "For" to fill an array in VHDL
我想理解和改进我得到的一个 VHDL 代码。
在VHDL实现中有以下部分:
m1(000) <= MetricA(000) + BrMet(3);
m1(001) <= MetricA(001) + BrMet(1);
m1(002) <= MetricA(002) + BrMet(0);
m1(003) <= MetricA(003) + BrMet(2);
m1(004) <= MetricA(004) + BrMet(0);
m1(005) <= MetricA(005) + BrMet(2);
m1(006) <= MetricA(006) + BrMet(3);
m1(007) <= MetricA(007) + BrMet(1);
m1(008) <= MetricA(008) + BrMet(2);
m1(009) <= MetricA(009) + BrMet(0);
m1(010) <= MetricA(010) + BrMet(1);
m1(011) <= MetricA(011) + BrMet(3);
m1(012) <= MetricA(012) + BrMet(1);
m1(013) <= MetricA(013) + BrMet(3);
m1(014) <= MetricA(014) + BrMet(2);
m1(015) <= MetricA(015) + BrMet(0);
哪里
type BRANCH_METRIC is array (3 downto 0) of STD_LOGIC_VECTOR (7 downto 0);
signal BrMet: RANCH_METRIC := (OTHERS =>(OTHERS => '0'));
type PATH_METRIC is array (15downto 0) of STD_LOGIC_VECTOR (7 downto 0);
signal MetricA: PATH_METRIC := (OTHERS =>(OTHERS => '0'));
我的问题:
1.m1(001), .... m1(015)
,MetricA(001), .... MetricA(015)
表示一个位置的值:
m1(001)
表示第一个单元格上的值,m1(015)
表示第 15 个单元格上的值。
BrMet(0)
可以表示别的意思吗?
2. 我的任务是使用 for
循环重写上面的代码。
我可以写:
for i in 1 to 15 loop
m1(i) <= MetricA(i) + BrMet(?);
如何在此循环中添加 BrMet
?
我想创建一个 table 作为:
Tab = {3,1,0,2,0,2...}
{3,1,0,2,0,2...} 表示 BrMet(3), BrMet(1), BrMet(0) 等等
我会把循环写成
for i in 1 to 15 loop
m1(i) <= MetricA(i) + Tab(i);
但不幸的是,我没有找到任何关于如何在 VHDL 中创建 table 的信息。有LUT table , bit 不合格
"m1(001)
表示第一个单元格上的值,m1(015)
在第15个单元格上"
如果“第一个单元格”是指具有最小索引的单元格,那么不,m1(1)
不是“第一个”单元格,它是“第二个” “(并且 m1(15)
是“第 16 个”),因为您将数组类型声明为 0 作为“第一个”索引,而不是 1。请注意,根据这些数组定义,您的循环可能是错误的:它们应该从索引开始0,不是 1。
"BrMet(0)
可以表示别的意思吗?"
还有什么? BrMet(0)
是数组 BrMet
中具有最小索引的单元格。
"如何在此循环中添加 BrMet
?"
您显然知道如何声明数组类型并使用它们。这也不例外。只需声明一个数组类型和一个该类型的常量:
type BrMetIdx_t is array(0 to 15) of integer;
constant BrMetIdx: BrMetIdx_t := (3, 1, 0, 2, 0, 2, 3, 1, 2, 0, 1, 3, 1, 3, 2, 0);
...
for i in 0 to 15 loop
m1(i) <= MetricA(i) + BrMet(BrMetIdx(i));
end loop;
...
注意:将 BrMetIdx_t
数组的元素类型限制为 0 到 3 范围内的整数可能会更安全:
type BrMetIdx_t is array(0 to 15) of integer range 0 to 3;
这样,如果在您的常量声明中出现打字错误,例如值 4,您将从编译器收到一条明确的错误消息。
注意:您不必使用“downto”索引范围声明数组类型。这是位向量的常见做法,因为从右到左索引它们也很常见,但是对于 m1
、MetricA
和 BrMet
数组,您也可以将它们索引为更多“自然”方式:
type BRANCH_METRIC is array (0 to 3) of STD_LOGIC_VECTOR (7 downto 0);
type PATH_METRIC is array (0 to 15) of STD_LOGIC_VECTOR (7 downto 0);
这可能有助于全球理解。
注意:我怀疑您是否会为您的(Viterbi?)解码器的路径和分支指标使用多个驱动器。因此,使用 std_ulogic_vector
之类的未解析类型而不是 std_logic_vector
会更安全。这样,如果您不小心创建了一个多驱动器情况,您将从编译器收到一条明确的错误消息,而不是花费数小时试图理解为什么您在模拟期间会看到所有这些 X
值。
我想理解和改进我得到的一个 VHDL 代码。
在VHDL实现中有以下部分:
m1(000) <= MetricA(000) + BrMet(3);
m1(001) <= MetricA(001) + BrMet(1);
m1(002) <= MetricA(002) + BrMet(0);
m1(003) <= MetricA(003) + BrMet(2);
m1(004) <= MetricA(004) + BrMet(0);
m1(005) <= MetricA(005) + BrMet(2);
m1(006) <= MetricA(006) + BrMet(3);
m1(007) <= MetricA(007) + BrMet(1);
m1(008) <= MetricA(008) + BrMet(2);
m1(009) <= MetricA(009) + BrMet(0);
m1(010) <= MetricA(010) + BrMet(1);
m1(011) <= MetricA(011) + BrMet(3);
m1(012) <= MetricA(012) + BrMet(1);
m1(013) <= MetricA(013) + BrMet(3);
m1(014) <= MetricA(014) + BrMet(2);
m1(015) <= MetricA(015) + BrMet(0);
哪里
type BRANCH_METRIC is array (3 downto 0) of STD_LOGIC_VECTOR (7 downto 0);
signal BrMet: RANCH_METRIC := (OTHERS =>(OTHERS => '0'));
type PATH_METRIC is array (15downto 0) of STD_LOGIC_VECTOR (7 downto 0);
signal MetricA: PATH_METRIC := (OTHERS =>(OTHERS => '0'));
我的问题:
1.m1(001), .... m1(015)
,MetricA(001), .... MetricA(015)
表示一个位置的值:
m1(001)
表示第一个单元格上的值,m1(015)
表示第 15 个单元格上的值。
BrMet(0)
可以表示别的意思吗?
2. 我的任务是使用 for
循环重写上面的代码。
我可以写:
for i in 1 to 15 loop
m1(i) <= MetricA(i) + BrMet(?);
如何在此循环中添加 BrMet
?
我想创建一个 table 作为:
Tab = {3,1,0,2,0,2...}
{3,1,0,2,0,2...} 表示 BrMet(3), BrMet(1), BrMet(0) 等等
我会把循环写成
for i in 1 to 15 loop
m1(i) <= MetricA(i) + Tab(i);
但不幸的是,我没有找到任何关于如何在 VHDL 中创建 table 的信息。有LUT table , bit 不合格
"m1(001)
表示第一个单元格上的值,m1(015)
在第15个单元格上"
如果“第一个单元格”是指具有最小索引的单元格,那么不,m1(1)
不是“第一个”单元格,它是“第二个” “(并且 m1(15)
是“第 16 个”),因为您将数组类型声明为 0 作为“第一个”索引,而不是 1。请注意,根据这些数组定义,您的循环可能是错误的:它们应该从索引开始0,不是 1。
"BrMet(0)
可以表示别的意思吗?"
还有什么? BrMet(0)
是数组 BrMet
中具有最小索引的单元格。
"如何在此循环中添加 BrMet
?"
您显然知道如何声明数组类型并使用它们。这也不例外。只需声明一个数组类型和一个该类型的常量:
type BrMetIdx_t is array(0 to 15) of integer;
constant BrMetIdx: BrMetIdx_t := (3, 1, 0, 2, 0, 2, 3, 1, 2, 0, 1, 3, 1, 3, 2, 0);
...
for i in 0 to 15 loop
m1(i) <= MetricA(i) + BrMet(BrMetIdx(i));
end loop;
...
注意:将 BrMetIdx_t
数组的元素类型限制为 0 到 3 范围内的整数可能会更安全:
type BrMetIdx_t is array(0 to 15) of integer range 0 to 3;
这样,如果在您的常量声明中出现打字错误,例如值 4,您将从编译器收到一条明确的错误消息。
注意:您不必使用“downto”索引范围声明数组类型。这是位向量的常见做法,因为从右到左索引它们也很常见,但是对于 m1
、MetricA
和 BrMet
数组,您也可以将它们索引为更多“自然”方式:
type BRANCH_METRIC is array (0 to 3) of STD_LOGIC_VECTOR (7 downto 0);
type PATH_METRIC is array (0 to 15) of STD_LOGIC_VECTOR (7 downto 0);
这可能有助于全球理解。
注意:我怀疑您是否会为您的(Viterbi?)解码器的路径和分支指标使用多个驱动器。因此,使用 std_ulogic_vector
之类的未解析类型而不是 std_logic_vector
会更安全。这样,如果您不小心创建了一个多驱动器情况,您将从编译器收到一条明确的错误消息,而不是花费数小时试图理解为什么您在模拟期间会看到所有这些 X
值。