VHDL:为2D Array的特定元素分配新值

时间:2017-08-31 06:29:42

标签: vhdl

我想将Average Variable值复制到2d Array的特定位置。对于此代码,它是array_new_signal11(3,2)

任何人都可以指导我如何做到这一点?这段代码在模拟时给出了错误。

architecture Behavioral of Correction is

type array_new is array (0 to 4, 0 to 4) of integer;
signal array_new_signal: array_new;

begin

array_new_signal11 <=  ((1,2,3,4,5),
                        (4,5,6,7,8),
                        (7,8,9,0,1),
                        (1,3,6,5,9),
                        (2,3,5,4,5)); 

  Process(kelvin)
    variable Sum1: integer:= 0;
    Variable Sum2: integer:= 0;
    Variable Total_Sum: integer:= 0;
    Variable Average: integer:= 0;

    begin

        for Row in 0 to 4 loop
          for Column in 0 to 4 loop 

            if(Row = 1 and Column = 1) then
                for Column in 1 to 3 loop
                    sum1 := array_new_signal11(Row, Column) + Sum1;
                end loop;
            end if;

            if(Row = 2 and Column = 1) then
                for Column in 1 to 3 loop
                    sum2 := array_new_signal11(Row, Column) + Sum2;
                end loop;
            end if;   
         end loop;
        end loop;
      Total_Sum := Sum1 + Sum2;
      Average := Total_Sum / 8;
      **array_new_signal11(3,2) <= Average;**
     end Process;
    end Behavioral;

2 个答案:

答案 0 :(得分:3)

从问题构建一个最小,完整和可验证的例子:

entity correction is 
end correction;

architecture behavioral of correction is
    type array_new is array (0 to 4, 0 to 4) of integer;
    signal array_new_signal11: array_new := ((1,2,3,4,5),
                                             (4,5,6,7,8),
                                             (7,8,9,0,1),
                                             (1,3,6,5,9),
                                             (2,3,5,4,5));
    signal kelvin: boolean;
begin

    -- array_new_signal11 <=  ((1,2,3,4,5),
    --                         (4,5,6,7,8),
    --                         (7,8,9,0,1),
    --                         (1,3,6,5,9),
    --                         (2,3,5,4,5));

    process (kelvin)
        variable sum1: integer:= 0;
        variable sum2: integer:= 0;
        variable total_sum: integer:= 0;
        variable average: integer:= 0;
    begin
        for row in 0 to 4 loop
            for column in 0 to 4 loop 
                if row = 1 and column = 1 then
                    for column in 1 to 3 loop
                        sum1 := array_new_signal11(row, column) + sum1;
                    end loop;
                end if;
                if row = 2 and column = 1 then
                    for column in 1 to 3 loop
                        sum2 := array_new_signal11(row, column) + sum2;
                    end loop;
                end if;   
            end loop;
        end loop;
      total_sum := sum1 + sum2;
      average := total_sum / 8;
      report "sum1 = " & integer'image(sum1) & ", " &
             "sum2 = " & integer'image(sum2) & ", " &
             "average = " & integer'image(average);
      array_new_signal11(3,2) <= average;
    end process;
MONITOR_PROCESS:
    process
    begin
        wait on array_new_signal11;
        for row in 0 to 4 loop
            report "row" & integer'image(row) & " = " &
                    integer'image(array_new_signal11(row,0)) & ", " &
                    integer'image(array_new_signal11(row,1)) & ", " &
                    integer'image(array_new_signal11(row,2)) & ", " &
                    integer'image(array_new_signal11(row,3)) & ", " &
                    integer'image(array_new_signal11(row,4));
        end loop;
    end process;
end behavioral;

我们看到报告语句告诉我们平均值并报告新的数组值。

我们看到第3行第2列初始化为6,现在为4:

ghdl -a correction.vhdl
ghdl -e correction
ghdl -r correction
correction.vhdl:42:7:@0ms:(report note): sum1 = 18, sum2 = 17, average = 4
correction.vhdl:52:13:@0ms:(report note): row0 = 1, 2, 3, 4, 5
correction.vhdl:52:13:@0ms:(report note): row1 = 4, 5, 6, 7, 8
correction.vhdl:52:13:@0ms:(report note): row2 = 7, 8, 9, 0, 1
correction.vhdl:52:13:@0ms:(report note): row3 = 1, 3, 4, 5, 9
correction.vhdl:52:13:@0ms:(report note): row4 = 2, 3, 5, 4, 5

由平均值指定。

正如Renaud Pacalet所说,你有两个不同的进程驱动array_new_signal11,这在VHDL中是不合法的,因为它的元素类型整数不是已解析的数据类型。

解决方案是在这种情况下初始化数组,并声明它。

否则,对数组信号元素的每个赋值都必须在同一个进程中。您所拥有的并发信号分配将被详细说明为等效的过程语句,并在详细说明时生成错误:

ghdl -r correction
for signal: .correction(behavioral).array_new_signal11(3,2)
./correction:error: several sources for unresolved signal
./correction:error: error during elaboration

(对于ghdl模拟器部分的精化(包括链接和加载)是在调用模拟时完成的(-r命令,加载部分,创建设计网络的地方)。)

Renaud Pacalet建议在过程中分配数组值,但如果没有介入的等待语句,则这些值不可用于后续在同一模拟周期中使用。新信号值在分配的相同模拟周期中不可用。

每个信号分配都会安排波形更新,并且只有特定模拟时间的一个条目可用。在这种情况下,它将保证数组(3,2)将是八个整数值的平均值(这将是不正确的,你应该得到错误导致模拟在未标记的第3循环语句中积累sum1期间结束第一次循环迭代)。

这告诉我们在读取之前需要初始化数组。

上述示例成功的唯一原因是,在一起添加时没有数组元素不会违反您指定值的整数类型的值范围。

你可以通过使用二进制数组等价的整数并注意所需的准确性来解决这类问题。

这个故事有几个道德。首先,VHDL不是一种编程语言,其次是强类型,第三信号分配值在模拟周期中永远不可见。

请注意,开尔文已被添加为布尔信号,以便在不更改过程的情况下触发执行一次。

答案 1 :(得分:1)

您正试图从两个不同的进程中驱动array_new_signal11信号。是的,您的第一个并发信号分配:

array_new_signal11 <=  ((1,2,3,4,5),
                        (4,5,6,7,8),
                        (7,8,9,0,1),
                        (1,3,6,5,9),
                        (2,3,5,4,5));

是流程的简写。它模拟了一个硬件驱动程序,它不断地将这些值强加给你的数组信号(最后只是一堆电线)。

您的第二个进程还会尝试将值强加给数组的一个单元格(单元格array_new_signal11(3,2))。在电气工程中,这种情况被称为短路:当两位车手不同意时,您会期待什么?这也是你的模拟器拒绝这个的原因:它不知道如何处理这个信号。

解决方案:从一个过程中驱动此信号:

process(kelvin)
    ...
begin
    array_new_signal11 <= (
        (1,2,3,4,5),
        (4,5,6,7,8),
        ...
    for Row in 0 to 4 loop
        ...
end process;

注意:

  1. Average是一个变量,你应该有另一个错误:

    Average <= Total_Sum / 8;
    

    应该是:

    Average := Total_Sum / 8;
    
  2. 您在两个嵌套循环中使用相同的循环索引(Column)。不确定你要做什么,但这不是很安全。

  3. 即使我建议修复您的错误,您也会遇到另一个问题:array_new_signal11既是输入的输入(您读取它),也是输出(您指定它)的过程。因此,它也应列在敏感性列表中。在电气工程中,这被称为组合环,并且通常是非常不受欢迎的,除非您想要创建振荡器或一种随机发生器。

  4. 您的过程对信号Kelvin很敏感,但不会使用它。奇怪的情况。您是否清楚自己想要建模的硬件?

  5. 您可能认为每次流程恢复时(即每次Kelvin更改),您的流程变量都会重新初始化为0。情况并非如此:它们保留了分配的最后一个值。可能不是你想要的。您应该在流程体的开头初始化它们。