如何填充和显示矩阵? [VHDL]
How can i fill and display a matrix ? [VHDL]
我有一个作为 std_logic_vector 的数据输入,我想用数据输入的位填充一个矩阵,然后显示它。
如何填充和显示矩阵?
这是我的代码:
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;
谢谢,
首先,我们根据您的代码片段构造一个 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')。
所以这是内部循环的原因。使用数据输入,您将矩阵 mat1(i,j) 的每个元素分配 N 次,其中 N 是数据输入的长度(j2 的范围)。使用 dataout,您可以将 dataout (i4) 的每个索引元素分配给 mat(i2,i3) 的每个矩阵元素。
那么是否可以让三个循环执行这些分配?
嗯,没有。
在INITIALIZE_MATRIX过程中,mat1的每个(i,j)位置都被datain的所有索引值覆盖。只有最后一个起作用了。这用全“0”填充了矩阵。
在 MATRIX_TO_DATAOUT 过程中,所有数据输出索引都 'scheduled' 具有每个 i3 循环迭代的最后一个 mat1(i2,i3) 值,确定 i2 的最后一个循环迭代值和i3,一个'0'。
我们可以修改这两组循环,将j2或i4作为变量直接递减(datain和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
我们在哪里找到 dataout 匹配 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 相同的答案,并具有更正的过程语句。
我有一个作为 std_logic_vector 的数据输入,我想用数据输入的位填充一个矩阵,然后显示它。
如何填充和显示矩阵?
这是我的代码:
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;
谢谢,
首先,我们根据您的代码片段构造一个 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')。
所以这是内部循环的原因。使用数据输入,您将矩阵 mat1(i,j) 的每个元素分配 N 次,其中 N 是数据输入的长度(j2 的范围)。使用 dataout,您可以将 dataout (i4) 的每个索引元素分配给 mat(i2,i3) 的每个矩阵元素。
那么是否可以让三个循环执行这些分配?
嗯,没有。
在INITIALIZE_MATRIX过程中,mat1的每个(i,j)位置都被datain的所有索引值覆盖。只有最后一个起作用了。这用全“0”填充了矩阵。
在 MATRIX_TO_DATAOUT 过程中,所有数据输出索引都 'scheduled' 具有每个 i3 循环迭代的最后一个 mat1(i2,i3) 值,确定 i2 的最后一个循环迭代值和i3,一个'0'。
我们可以修改这两组循环,将j2或i4作为变量直接递减(datain和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
我们在哪里找到 dataout 匹配 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 相同的答案,并具有更正的过程语句。