确定矩阵中的列长度

时间:2016-04-04 15:45:27

标签: arrays matrix vhdl counter

我要确定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;

1 个答案:

答案 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;

当模拟时,这给出了:

column.png

我添加了mat_col,因为我使用的工具不做delta循环波形,变量没有时间概念。 temp_col是一个变量,允许在分配后立即使用它的值(当前模拟周期中没有更新的信号值)。

您还可以看到我从您的问题中为M提供了默认值。