vhdl无法切片记录

时间:2018-09-17 08:33:23

标签: vhdl slice record

我可以不分割记录的一部分吗? 我声明一条这样的记录:

signal mt : mytypes(3 downto 0);
signal slv : std_logic_vector (3 downto 0);

这样定义它:

slv(0) <= mt(0).one;
slv(1) <= mt(1).one;

当我这样使用它时,就可以了:

slv(0 to 1) <= mt(0 to 1).one;

但这:

"record type mytypes is used but not declared"

得到错误

function HttpInterceptor() {
    var interceptor = {
        request: function (request) {
            if (request.url === 'request_url1' || request.url === 'request_url2'){
                request.headers['custom_header'] = 'this is conditional header';
            }
            return request;
        },
        response: function (response) {
            console.log(response);
            return response;
        }
    };
    return interceptor;
}

那么是不是只允许记录分割,还是我需要写一些额外的代码来启用它?

我应该说-Quartus II

2 个答案:

答案 0 :(得分:2)

您可以切片记录数组

 Id     Hours
 -----   -----
 1       09:00
 2       09:30
 3       10:00
 4       10:30
 5       11:00
 6       11:30
 7       12:00
 8       12:30
 9       13:00
10       13:30
11       14:00
12       14:30
13       15:00
14       15:30
15       16:00
16       16:30
17       17:00
18       17:30
19       18:00

但是您不能这样做:

signal mt, mt2 : mytype(0 to 3);
mt2(0 to 1) <= mt(0 to 1);

您将必须执行以下操作:

slv(0 to 1) <= mt(0 to 1).one;

顺便说一句:如果使用slv(0) <= mt(0).one; slv(1) <= mt(1).one; 声明数组,则无法使用downto对其进行切片。切片的方向必须与声明的方向匹配。

答案 1 :(得分:1)

VHDL标准最初基于Ada'83 LRM(包括记录类型)。 Ada和VHDL都具有强类型,并且(在VHDL术语中)要求扩展名的后缀是在记录类型声明中声明的元素名称,前缀是适当的(表示记录类型的值)。参见IEEE 1076-2008:

8.3所选名称(第3和第4段)

  

选定的名称可以表示记录的元素,由访问值指定的对象或命名实体,其声明包含在另一个命名实体中,尤其是在库,包或受保护的类型中。此外,选定的名称可以表示其声明包含在库或包中的所有命名实体。

     

对于用于表示记录元素的选定名称,后缀应为简单名称,表示记录对象或值的元素。前缀应适合此对象或值的类型。

那是

slv(0 to 1) <= mt(0 to 1).one;

产生错误(应表示强制性要求,请参见1.3本标准的结构和术语)。

这里的扩展名是mt(0 to 1).one, the suffix is the element name one`和前缀mt(0到1),切片名称是一种数组类型,其元素是记录类型。 (8.5,“切片名称表示由另一维数组的一系列连续元素组成的一维数组。”)

该问题的原始发帖人对一个无法接受的答案进行了评论,该答案是使用生成状态发现有效的解决方案,该生成状态会产生多个并发的赋值语句:

SOME_LABEL:
    for i in 1 downto 0 generate
        slv(i) <= mt(i).one;
    end generate;

其中选定名称mt(i)的后缀将是索引名称(8.4“索引名称表示数组的元素。”)。

您可能会注意到,通过不使用切片名称就可以避免该问题。

切片记录的数组的一种方法是从每个记录中提取元素,方法是使用子程序函数,该表达式返回一个值(4.子程序和包)。该函数将从参数指定的mytypes类型的数组值的元素中返回子元素one

    function mytypes_ones (inp: mytypes) return std_logic_vector is
        variable retv:  std_logic_vector(inp'range);
    begin
        for i in inp'range loop
            retv(i) := inp(i).one;
        end loop;
        return retv;
    end function;

返回值是std_logic_vector值,其长度由类型mytypes的元素数组的长度确定。

使用函数和generate语句之间的区别包括提供一个表达式,该表达式允许一个可以是切片名称的参数,并允许返回值包括来自多个记录元素的子元素。虽然函数需要子程序声明和/或定义,但它的用法是作为可以帮助功能描述流程的表达式。一个函数可以在多个函数调用中使用,而generate语句是特定的。此外,generate语句还将细化为block语句(14.5.3 Generate语句)。一个真正有用的区别是,可以在顺序赋值语句中(例如,在流程语句或子程序中)使用函数调用。

使用问题中的声明创建Minimal, Complete, and Verifiable example

library ieee;
use ieee.std_logic_1164.all;

entity mytypes_slices is
end entity;

architecture fum of mytypes_slices is
    type mytype is record
        one:        std_logic;
        two:        std_logic;
    end record;
    type mytypes is array (natural range <>) of mytype;
    signal mt:      mytypes (3 downto 0) := (
                        (one => '1', two => '0'),   -- mt(3)
                        (one => '1', two => '0'),   -- mt(2)
                        (one => '0', two => '0'),   -- mt(1)
                        (one => '1', two => '0')    -- mt(0)
                    );
    signal slv:     std_logic_vector (3 downto 0);
    signal slv1:    std_logic_vector (3 downto 0);

    function mytypes_ones (inp: mytypes) return std_logic_vector is
        variable retv:  std_logic_vector(inp'range);
    begin
        for i in inp'range loop
            retv(i) := inp(i).one;
        end loop;
        return retv;
    end function;

begin

    slv  (1 downto 0) <= mytypes_ones(mt)(1 downto 0); -- slice return value
    slv1 (1 downto 0) <= mytypes_ones(mt(1 downto 0)); -- slice parameter

MONITOR:
    process
    begin
        wait for 0 ns;  -- skip default values of slv, slv1, delta cycle delay
        report "slv(1 downto 0) = " & 
            character'value(std_ulogic'image(slv(1))) &
            character'value(std_ulogic'image(slv(0)));
        report "slv1(1 downto 0) = " & 
            character'value(std_ulogic'image(slv1(1))) &
            character'value(std_ulogic'image(slv1(0)));
        wait;
    end process;

end architecture;
  

ghdl -r mytypes_slices
  mytypes_slices.vhdl:49:9:@ 0ms :(报告注释):slv(1至0)= 01
  mytypes_slices.vhdl:52:9:@ 0ms :(报告注释):slv1(1降至0)= 01

我们可以看到函数调用也很灵活。对slv的分配使用了一个函数调用,该函数调用的返回值被切片(8.1“某些名称形式(索引名称和选定名称,切片名称和属性名称)包括作为名称或函数调用的前缀”。) )。数组类型参数值也可以切片。这两个表达式提供相同的值。

您还可能注意到切片名称的方向与它们各自数组类型的声明方向匹配。问题OP包含其他错误:

slv(0 to 1) <= mt(0 to 1).one;

如果允许前缀为切片mt(0 to 1),则为空切片(8.5“如果离散范围为空范围,则切片为空切片。这是一个如果离散范围的方向与切片名称的前缀所表示的数组的索引范围的方向不同,则错误,“ 5.2标量类型,5.2.1第3-6段,5.3.2.2索引约束和离散范围)。方向与mt声明中找到的方向不符。