我要确定4x4矩阵中每列的长度。每列的长度从每列的底部开始向上计算,并且仅从访问的初始“1”开始计算。
1110
0111
0110
0001
Column1 = 1,Column2 = 3,Column3 = 3,Column4 = 4等......
有没有人有任何想法我怎么能这样做?到目前为止,我一直试图在函数旁边生成一个矩阵来提取每个列。
type col_mat is array (0 to 3) of std_logic;
type matrix is array (0 to 3, 0 to 3) of std_logic;
signal M: matrix;
signal temp_col : col_mat;
signal count : unsigned (1 downto 0):= "00";
function extract_col(x: matrix; column : integer) return col_mat is
variable ret: col_mat;
begin
for i in col_mat'range loop
ret(i) := x(i,column)
end loop;
return ret;
end function;
begin
if rising_edge(clk) then
temp_col<= extract_col(M, to_integer(count) );
count <= count+1;
end if;
end process;
答案 0 :(得分:0)
您正在描述一个优先级编码器,从它的外观来看,您暗示它在一个时钟内运行,根据目标设备可能会遇到一些时钟速率限制(假设您将合成)。
优先级编码可以是if语句,case语句,带退出的循环语句(如Martin Zabel所评论的),用逻辑运算符或条件信号赋值组合描述。
对于这种特殊用途,循环语句是最紧凑的,并且已经添加到您的过程中。
以下代码源自您的问题,充实为a Minimal, Complete, and Verifiable example。
结果是根据数组类型索引(从0开始)。
我添加了一个用于计数命名列的流水线寄存器以及用于指定找到'1'的信号的寄存器(found_1),并且在(富有想象力的命名行)中找到最高行值'1':
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity column is
end entity;
architecture foo of column is
type col_mat is array (0 to 3) of std_logic;
type matrix is array (0 to 3, 0 to 3) of std_logic; -- (row,column)
-- signal M: matrix;
-- 1110
-- 0111
-- 0110
-- 0001
--
-- Column1=1, Column2=3, Column3=3, Column4=4 etc...
--
-- column0 = 0, column1 = 2 column2 = 2, column3 = 3
-- (matrix is defined so (0,0) is the upper left hand corner)
-- Looking for the highest column index occupied by a '1'
signal M: matrix := ( -- for demo provide matrix default value
('1','1','1','0'), -- row 0
('0','1','1','1'),
('0','1','1','0'),
('0','0','0','1') -- row 3
);
-- signal temp_col: col_mat;
signal count: unsigned (1 downto 0):= "00";
function extract_col(x: matrix; column: integer) return col_mat is
variable ret: col_mat;
begin
for i in col_mat'range loop
ret(i) := x(i,column); -- was missing semicolon
end loop;
return ret;
end function;
-- added signals:
signal clk: std_logic := '1'; -- rising_edge() requires 0 -> 1 trans
signal found_1: std_logic := '0';
signal column: unsigned (1 downto 0);
signal row: integer range 0 to 3;
signal mat_col: col_mat;
begin
UNLABELED:
process (clk)
variable temp_col: col_mat; -- made temp_col a variable, use immediately
begin
if rising_edge(clk) then
temp_col := extract_col(M, to_integer(count)); -- was signal
-- priority encoder: -- added loop
for i in temp_col'RIGHT downto temp_col'LEFT loop -- highest first
if temp_col(i) = '1' then
found_1 <= '1';
column <= count;
row <= i;
exit;
else
found_1 <= '0';
end if;
end loop;
mat_col <= temp_col; -- added
count <= count + 1;
end if;
end process;
CLOCK: -- Added clock process
process
begin
wait for 10 ns;
clk <= not clk;
if now > 90 ns then
wait;
end if;
end process;
end architecture;
当模拟时,这给出了:
我添加了mat_col,因为我使用的工具不做delta循环波形,变量没有时间概念。 temp_col是一个变量,允许在分配后立即使用它的值(当前模拟周期中没有更新的信号值)。
您还可以看到我从您的问题中为M提供了默认值。