【问题标题】:Assign values to an array partially in VHDL?部分在VHDL中为数组赋值?
【发布时间】:2016-11-21 15:19:54
【问题描述】:

我有一个形式为 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"

从某种意义上说,这就像一个二维矩阵,我希望只完全初始化一列。 除了一一分配位,还能做什么?

【问题讨论】:

    标签: vhdl


    【解决方案1】:

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

    array(0 to 15)
    

    但是你分配给这个类型使用的实例的信号:

    cache_array(15 downto 0)
    

    您应该为两者选择todownto

    最后一个错误是因为您将仅适用于位向量的(others =&gt; '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; 
    

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

    【讨论】:

    • 我想为数组的所有索引制作那个特定的位'0'。我试过这个comparisons(15 downto 0)(32) &lt;= '0';,但我收到一个错误Cache.vhd:65:28: static constant violates bounds
    • @KalpeshKrishna 好的,我只是想解释为什么您的代码会导致错误。请查看我的编辑。
    • 我不知道这些generate 声明。所有这些确实会产生可综合的代码,对吗?这看起来真的很有用!
    • @KalpeshKrishna 是的,循环和生成语句是可综合的。请注意,这两种循环都是展开的,因此在合成时必须知道循环边界。
    • 另外,这些是否在硬件中并行发生?还是它们以顺序组合的方式工作?
    【解决方案2】:

    在可怕的_jeff 显示的生成循环方法中应谨慎使用。 generate 循环中的并发语句将导致一个单独的进程,每个生成的块中都有一个单独的驱动程序,这意味着您不能在不解析为元值的情况下从另一个进程为 cache_array(i) 分配 (33)。

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

    还有第三种方法使用 AND 掩码,对于那些有编程背景的人来说很熟悉,用于将 cache_array(i)(33) 设置为 '0':

    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;
    

    因为它需要为类型 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
    

    第一个缓存值是初始值,第二个是“and”掩码的结果(注意我最初用'1'填充了cache_array以显示“and”有效)。

    您可以为缓存字添加额外的字段分隔符,使其更易于阅读,并与特定基数使用等内容一起,注意您负责正确计算 retval 字符串长度并管理 retval 指针 (retptr) to_string 函数。您可以添加一个输出标题。您还可以在缓存行的基础上组织输出。 ...

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

    【讨论】:

      猜你喜欢
      • 2020-01-13
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      相关资源
      最近更新 更多