2016-12-22 76 views
0

我有一个datain作为std_logic_vector,我想用datain的位填充矩阵,然后显示它。如何填充并显示矩阵? [VHDL]

如何填充和显示矩阵?

这里是我的代码:

signal datain : std_logic_vector(39 downto 0) := "1111011101100110011001010110011001100110"; 

    for i1 in 1 to 5 loop 
    for j1 in 1 to 8 loop 
    for j2 in datain'range loop 
    mat1(i1,j1)<=datain(j2); 
     end loop; 
     end loop; 
     end loop; 

     ------- display the matrix 

     for i2 in 1 to 5 loop 
     for i3 in 1 to 8 loop 
      for i4 in dataout'range loop  
      dataout(i4) <= mat1(i2,i3); 
      end loop; 
     end loop; 
     end loop;  

谢谢

回答

2

首先,我们构建从您的代码片段Minimal, Complete and Verifiable example

library ieee; 
use ieee.std_logic_1164.all; 

entity abir is 
end entity; 

architecture foo of abir is 

    type mat_type is array (1 to 5, 1 to 8) of std_logic; 
    signal mat1: mat_type; 
    signal datain : std_logic_vector(39 downto 0) := 
       "1111011101100110011001010110011001100110"; 
    signal dataout: std_logic_vector (39 downto 0); -- MISSING 

    -- this function is predefined in VHDL -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; 
begin 

INITIALIZE_MATRIX: 
    process -- (datain) 
    begin 
     for i1 in 1 to 5 loop 
      for j1 in 1 to 8 loop 
       for j2 in datain'range loop 
        mat1(i1,j1)<=datain(j2); 
       end loop; 
      end loop; 
     end loop; 
     wait; -- Do only once, depends on the initial value of datain 
    end process; -- the wait statement can be removed if you add sensitivity 

    ------- display the matrix 
MATRIX_T0_DATAOUT: 
    process (mat1) 
    begin 
     for i2 in 1 to 5 loop 
      for i3 in 1 to 8 loop 
       for i4 in dataout'range loop 
        dataout(i4) <= mat1(i2,i3); 
       end loop; 
      end loop; 
     end loop; 
    end process; 

DISPLAY_DATAOUT: 
    process -- (dataout) 
    begin    -- wait statements so only disply valid datout 
     wait for 0 ns; -- first delta cycle all 'U's (dataout uninitialized) 
     wait for 0 ns; -- second delta cycle all 'U's (mat1 uninitialized) 
     report LF & 
       HT & "datain = " & to_string(datain) & LF & 
       HT & "dataout = " & to_string(dataout); 
     wait on dataout; 
    end process; 
end architecture; 

功能to_string在VHDL -2008预定义的,这个MCVE应该使用符合VHDL标准早期修订版的工具。

这是具体展示您的代码。它提供了:

ghdl -a abir.vhdl 
ghdl -e abir 
ghdl -r abir 
abir.vhdl:58:9:@0ms:(report note): 
    datain = 1111011101100110011001010110011001100110 
    dataout = 0000000000000000000000000000000000000000 

因此,有一些错误的嵌套循环(你也可以用波形观测,以确定MAT1验证这确实是全0)。

所以这个原因是非常内在的循环。使用datain,可以将矩阵mat1(i,j)的每个元素分配N次,其中N是数据长度(j2的范围)。通过数据输出,可以为mat(i2,i3)的每个矩阵元素分配dataout(i4)的每个索引元素。

那么有可能有三个循环执行这些分配?嗯,不,不。

在INITIALIZE_MATRIX过程中,mat1的每个(i,j)位置都被datain的所有索引值覆盖。只有最后一个影响。这填满了所有'0的矩阵。

在MATRIX_TO_DATAOUT过程中,所有数据输出索引都被调度为具有每个i3循环迭代的最后一个mat1(i2,i3)值,这决定了i2和i3的最后一个循环迭代值'0'。

我们可以通过修改两套循环递减J2或6-14直接变量(数据输入的范围和DATAOUT是按降序排列):

INITIALIZE_MATRIX: 
    process -- (datain) 
     variable j2: natural range datain'range; 
    begin 
     j2 := datain'LEFT; -- so the process can execute again. 
     for i1 in 1 to 5 loop 
      for j1 in 1 to 8 loop 
       -- for j2 in datain'range loop 
        mat1(i1,j1) <= datain(j2); 
        if j2 /= datain'RIGHT then 
         j2 := j2 - 1; -- datain has descending range 
        end if; 
       -- end loop; 
      end loop; 
     end loop; 
     wait; -- Do only once, depends on the initial value of datain 
    end process; -- the wait statement can be removed if you add sensitivity 

    ------- display the matrix 
MATRIX_T0_DATAOUT: 
    process (mat1) 
     variable i4: natural range dataout'range; 
    begin 
     i4 := dataout'LEFT; -- so the process can execute again 
     for i2 in 1 to 5 loop 
      for i3 in 1 to 8 loop 
       -- for i4 in dataout'range loop 
        dataout(i4) <= mat1(i2,i3); 
        if i4 /= dataout'RIGHT then 
         i4 := i4 - 1; -- dataout has descending range 
        end if; 
       -- end loop; 
      end loop; 
     end loop; 
    end process; 

这给了我们:

abir.vhdl:68:9:@0ms:(report note): 
    datain = 1111011101100110011001010110011001100110 
    dataout = 1111011101100110011001010110011001100110 

我们在哪里找到数据输出与datain匹配。 (好东西)

所以问题是每个进程中的三个嵌套循环都是不正确的。我们想单独管理指向输入和输出数组的指针。

我们还管理对变量j2或i4的分配,以防止使用if语句的边界违例,以防止当变量分配超出变量的值范围时j2或i4减少。分配上的边界检查失败会中止仿真。

请注意,信号分配会导致将值写入投影输出波形(队列)。在任何挂起的进程运行并暂停之前,信号更新不会发生。投影输出波形中只有一个值。(包括当前的模拟时间)。

这两种改性工艺可以被用作转换函数的基础:

architecture fum of abir is 

    type mat_type is array (1 to 5, 1 to 8) of std_logic; 
    signal mat1: mat_type; 
    signal datain : std_logic_vector(39 downto 0) := 
       "1111011101100110011001010110011001100110"; 
    signal dataout: std_logic_vector (39 downto 0); -- MISSING 

    -- this function is predefined in VHDL -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; 

    function to_matrix (inp: std_logic_vector) return mat_type is 
     alias input: std_logic_vector(0 to inp'length - 1) is inp; -- ascending 
     variable mat: mat_type; 
     variable inptr: natural range 0 to inp'length; 
    begin 
     assert input'length = mat'length(1) * mat'length(2) 
     report LF & 
      "to_matrix call, input length (" & 
      integer'image(inp'length) & ") " & 
      "/= " & integer'image(mat'length(1) * mat'length(2)) 
     severity FAILURE; 
     for i in mat'range(1) loop  -- first dimension 
      for j in mat'range(2) loop -- second dimension 
       mat(i,j) := input(inptr); 
       inptr := inptr + 1; -- inptr range allows last increment 
      end loop; 
     end loop; 
     return mat; 
    end function; 

    function to_std_logic_vector (mat: mat_type) return std_logic_vector is 
     variable retval: 
      std_logic_vector(0 to mat'length(1) * mat'length(2) - 1); 
     variable outptr: natural range 0 to retval'length; 
    begin 
     for i in mat'range(1) loop  -- first dimension 
      for j in mat'range(2) loop -- second dimension 
       retval(outptr) := mat(i,j); 
       outptr := outptr + 1; -- outptr range allows last increment 
      end loop; 
     end loop; 
     return retval; 
    end function; 
begin 

INITIALIZE_MATRIX: 
    mat1 <= to_matrix(datain); 

MATRIX_T0_DATAOUT: 
    dataout <= to_std_logic_vector(mat1); 

DISPLAY_DATAOUT: 
    process -- (dataout) 
    begin    -- wait statements so only disply valid datout 
     wait for 0 ns; -- first delta cycle all 'U's (dataout uninitialized) 
     wait for 0 ns; -- second delta cycle all 'U's (mat1 uninitialized) 
     report LF & 
       HT & "datain = " & to_string(datain) & LF & 
       HT & "dataout = " & to_string(dataout); 
     wait for 1 ns; 
     wait on dataout; 
    end process; 
end architecture; 

的两个函数是仅依赖于矩阵类型声明。您可以更改mat_type声明,而不必修改声明或函数中发现的任何语句序列。

新架构与to_matrix[std_logic_vector return mat_type]to_std_logic_vector[mat_type return std_logic_vector]函数调用提供了相同的答案与该修正的过程语句MCVE。

+0

非常感谢。 – Abir