确定矩阵中列的长度

Determine Lengths of Columns in Matrix

我要确定 4x4 矩阵中每一列的长度。每列的长度从每列的底部向上计算,并且仅从访问的初始“1”开始计算。

1110   
0111
0110
0001

列 1=1,列 2=3,列 3=3,列 4=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;

你描述的是优先级编码器,从它的外观来看,你暗示它在一个时钟内运行,这可以 运行 进入基于目标设备的某个时钟速率限制(假设你会综合)。

优先级编码可以是 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,因为我使用的工具不会生成增量循环波形,而且变量没有时间概念。 temp_col 已成为一个变量,以允许在分配后立即使用它的值(更新的信号值在当前模拟周期中不可用)。

您还可以看到我根据您的问题为 M 提供了一个默认值。