在VHDL中部分地为数组赋值?

时间:2016-11-21 15:19:55

标签: vhdl

我有一个表格的VHDL数组,

type CacheArray is array(0 to 15) of std_logic_vector(33 downto 0);
signal cache_array: CacheArray := (others => (others => '0'));

我希望为此数组赋值,以便只初始化每个索引的一位。我怀疑这样的东西会起作用,

cache_array(15 downto 0)(33) <= (others => '0');

但它会出现以下错误: -

Cache.vhd:72:16: direction of the range mismatch
Cache.vhd:72:30: static constant violates bounds
Cache.vhd:72:37: can't match character literal '0' with type array type "std_logic_vector"

在某种意义上,这就像一个2D矩阵,我希望完全初始化一列。 除了逐个分配位之外还能做些什么呢?

2 个答案:

答案 0 :(得分:2)

您收到第一个和第二个错误,因为您的类型已声明:

array(0 to 15)

但您对此类型实例使用的信号的分配:

cache_array(15 downto 0)

您应该为{both}选择todownto

最后一个错误是因为您将(others => '0')(仅适用于位向量)分配给单个位。如果您要创建特定位'0',只需将其分配给'0'

更一般地说,语法cache_array(15 downto 0)(33)没有意义。

如果根据你的评论和更新的问题,你想在每个数组元素中分配一个特定的位,你将不得不使用某种循环:

在流程中:

for i in cache_array'range loop
  cache_array(i)(33) <= '0';
end loop; 

作为并发作业的流程外部:

GenerateLabel : for i in cache_array'range generate
  cache_array(i)(33) <= '0';
end generate; 

另请注意,如果仅实现一位的赋值,则工具不太可能推断使用块内存元素来实现此功能。

答案 1 :(得分:1)

应该在scary_jeff显示的generate循环方法中使用注意事项。生成循环中的并发语句将导致在每个生成的块中具有单独驱动程序的单独进程,这意味着您无法从另一个进程为cache_array(i)分配(33)而不解析为元值。

如果不在单个进程中描述整个缓存操作,则生成循环方法通常不会有用。

还有第三种使用AND掩码的方法,熟悉具有编程背景的人,用于将cache_array(i)(33)设置为&#39; 0&#39;:

library ieee;
use ieee.std_logic_1164.all;

entity cache is
end entity;

architecture foo of cache is
    type CacheArray is array(0 to 15) of std_logic_vector(33 downto 0);
    signal cache_array: CacheArray := (others => (others => '1'));

    constant MASK33:   CacheArray := (others => (33 => '0', others => '1'));

    function "and" (l,r: CacheArray) return CacheArray is
        variable retval: CacheArray;
    begin
        for i in l'range loop
            retval(i) := l(i) and r(i);
        end loop;
        return retval;
    end function;

    function to_string (arg: CacheArray) return string is
        variable retval: string (1 to CacheArray'length * 36);
        variable retptr: natural range 1 to CacheArray'length * 36;
    begin
        retptr := 1;
        for i in arg'range loop
            for j in arg(i)'range loop
                if j = arg(i)'left then
                    retval(retptr) := LF;
                    retptr := retptr + 1;
                    retval(retptr) := HT;
                    retptr := retptr + 1;
                end if;
                retval(retptr) := 
                        character'VALUE(std_ulogic'IMAGE(arg(i)(j)));
                        if retptr < retval'length then
                            retptr := retptr + 1;
                        end if;
            end loop;
        end loop;
        return retval;
    end function;

begin

-- GenerateLabel:
--     for i in cache_array'range generate
--         cache_array(i)(33) <= '0';
--     end generate;
--
-- Clear_33:
--     process (cache_array)
--     begin
--         for i in cache_array'range loop
--           cache_array(i)(33) <= '0';
--         end loop;
--     end process;
MASK:
    process (cache_array)
    begin
        cache_array <= cache_array and MASK33;
    end process;
SHOW:
    process (cache_array)
    begin
        report "cache_array = " & to_string(cache_array);
    end process;
end architecture;

因为它需要定义&#34;和&#34;对于CacheArray类型的运算符,它也导致为CacheArray类型生成一个to_string函数,它可以告诉我们缓存的内容:

ghdl -r cache
cache.vhdl:67:9:@0ms:(report note): cache_array =
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
    1111111111111111111111111111111111
cache.vhdl:67:9:@0ms:(report note): cache_array =
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111
    0111111111111111111111111111111111

第一个缓存值是初始值,第二个是&#34;和&#34;的结果。掩码(注意我最初用&#39; 1&#39; s填充cache_array以显示&#34;和#34;工作)。

您可以为缓存单词添加其他字段分隔符,以便于阅读以及特定基数使用等内容,并指出您负责正确计算退回字符串长度并管理retval指针(retptr)在to_string函数中。你可以去添加一个输出头。您还可以基于缓存行组织输出。 ...

除报告语句外,textio还可用于更精细地控制输出和重定向到文本文件。可以允许您观察缓存状态而无需借助读取波形显示。