循环运算符 "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”索引范围声明数组类型。这是位向量的常见做法,因为从右到左索引它们也很常见,但是对于 m1MetricABrMet 数组,您也可以将它们索引为更多“自然”方式:

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 值。