【问题标题】:Determine Lengths of Columns in Matrix确定矩阵中列的长度
【发布时间】:2016-04-04 15:45:27
【问题描述】:

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

【问题讨论】:

  • 一行怎么会有底部和顶部?你的意思是一个专栏?您的示例文本使用从一开始的索引,但 VHDL 代码使用从零开始的索引。请检查您的问题。
  • 我现在已经编辑过了。那时不是要写行
  • 那么,你想找到列向量中的最高设置位位置吗?一般的方法是:1)反转向量; 2) 生成新向量并将二进制数转换为二进制补码; 3) 两个向量的逻辑与 => 给出一个热编码值,其中 1 位于 MSB 的位置。然后你可以使用一个小的LUT来获得结果。另一种选择是,由于 Matrix 相当小,因此只需将每个列向量提供给一个 LUT,该 LUT 对值进行解码。
  • 函数extract_col看起来不错。但是,给定的代码示例没有分析。另一个扫描列的函数怎么样?给你一个指针:你也可以在到达结束之前退出一个 for 循环。
  • 我想找到最高设置位位置,因为我需要找到列的长度。这段代码是更广泛算法的一部分。实际的矩阵会大得多,但这只是作为示例。

标签: arrays matrix vhdl counter


【解决方案1】:

您描述的是优先级编码器,从外观上看,您暗示它在一个时钟内运行,这可能会遇到基于目标设备的某些时钟速率限制(假设您将进行合成)。

优先级编码可以是 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 提供了默认值。

【讨论】:

    猜你喜欢
    • 2019-08-01
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多