VHDL中的多维数组问题?

发布于 2024-10-19 05:31:13 字数 2960 浏览 0 评论 0原文

我正在尝试在 VHDL 中使用多维数组,但要使其正常工作却遇到了很多麻烦。我的问题是我有一个给定大小的由 17 个向量组成的数组,其中包含 16 个向量。我想要做的是创建 17 个寄存器,它们是 16 * std_logic_vector 32 位的数组(其中 = my b, 512)。所以,我试图在寄存器实例化中传递一些东西来输入和输出,告诉编译器/合成器我想传递一些512位的东西...类似于C,如果我有:(

int var[COLS][ROWS][ELEMENTS];
memcpy(&var[3].. // I'm talking about 3rd COL here, passing in memory that is ROWS*ELEMENTS long

我的实际声明在这里:)

类型partial_pipeline_registers_type是std_logic_vector(iw - 1 downto 0)的数组(0到16,0到15); 信号 h_blk_pipelined_input :partial_pipeline_registers_type;

我尝试简单地使用 h_blk_pipelined_input(0) .. 最多 (16) 但这不起作用。我收到以下错误,这让我看到我需要对数组进行双重索引:

ERROR:HDLParsers:821 - (at the register) Wrong index type for h_blk_pipelined_input.

然后我尝试了下面的内容,然后收到此错误:

ERROR:HDLParsers:164 - (at the register code). parse error, unexpected TO, expecting COMMA or CLOSEPAR


  instantiate_h_pipelined_reg : regn
   generic map ( N=> b, init => bzeros )
   port map ( clk => clk , rst => '0', en => '1',
      input => h_blk_pipelined_input((i - 1), 0 to 15),
      output=> h_blk_pipelined_input((i),     0 to 15));
-- Changing 0 to 15 to (0 to 15) has no effect...

我正在使用 XST,并从他们的文档(http://www .xilinx.com/itp/xilinx6/books/data/docs/xst/xst0067_9.html),上述内容应该有效:

...declaration:

subtype MATRIX15 is array(4 downto 0, 2 downto 0)
   of STD_LOGIC_VECTOR (7 downto 0);

 A multi-dimensional array signal or variable can be completely used:

Just a slice of one row can be specified:

MATRIX15 (4,4 downto 1) <= TAB_B (3 downto 0);

一种替代方案是我可以创建更多小 16 倍的寄存器,而不是尝试执行所有操作一次‘0 到 15’,我只会再做 15 次。然而,我认为这可能会导致合成效率低下,而且我认为这不是正确的解决方案。

编辑:

尝试了Ben所说的,

instantiate_h_m_qa_pipeline_registers: for i in 1 to 16 generate

instantiate_h_pipelined_reg : regn
    generic map ( N=> b, init => bzeros )
    port map ( clk => clk , rst => '0', en => '1',
       input => h_blk_pipelined_input(i - 1),                                            
       output=> h_blk_pipelined_input(i));                                          
end generate instantiate_h_m_qa_pipeline_registers;                                                 

信号现在定义为:

type std_logic_block is array (0 to 15) of std_logic_vector(iw - 1 downto 0) ;
type partial_pipeline_registers_type is array (0 to 16) of std_logic_block;
signal h_blk_pipelined_input : partial_pipeline_registers_type;

我从XST得到的错误是:

ERROR:HDLParsers:800 - ((其中寄存器部分是))的类型输入与 h_blk_pipelined_input 的类型不兼容。

我可以使用 ()() 语法而不是 ( , ) 做我之前能做的所有事情,所以我没有丢失任何东西,但它仍然没有解决我的问题。

编辑:

更进一步,在输入上使用转换函数 =>并输出=>寄存器实例化的参数,使用函数在数组类型和我需要的大小的 std_logic_vector 之间进行转换。它修复了“输入 =>” ' 部分,但是..

与 Formal OUT 模式相关的实际信号“输出”可能不是类型转换或函数调用。 (LRM 4.3.2.2)

I'm trying to use a multidimensional array in VHDL and I'm having a lot of trouble getting it to work properly. My issue is that I've got an array of 17, of 16 vectors, of a given size. What I want to do is create 17 registers that are array of 16 * std_logic_vector of 32 bits (which = my b, 512). So, I'm trying to pass in something to input and output on the register instantiation that tells the compiler/synthesizer that I want to pass in something that is 512 bits worth... Similar to in C if I had:

int var[COLS][ROWS][ELEMENTS];
memcpy(&var[3].. // I'm talking about 3rd COL here, passing in memory that is ROWS*ELEMENTS long

(My actual declaration is here:)

type partial_pipeline_registers_type is array (0 to 16, 0 to 15) of std_logic_vector(iw - 1 downto 0);
signal h_blk_pipelined_input : partial_pipeline_registers_type;

I tried simply using h_blk_pipelined_input(0) .. up to (16) but this doesn't work. I get the following error, which makes me see that I need to double index in to the array:

ERROR:HDLParsers:821 - (at the register) Wrong index type for h_blk_pipelined_input.

So then I tried what's below, and I get this error:

ERROR:HDLParsers:164 - (at the register code). parse error, unexpected TO, expecting COMMA or CLOSEPAR


  instantiate_h_pipelined_reg : regn
   generic map ( N=> b, init => bzeros )
   port map ( clk => clk , rst => '0', en => '1',
      input => h_blk_pipelined_input((i - 1), 0 to 15),
      output=> h_blk_pipelined_input((i),     0 to 15));
-- Changing 0 to 15 to (0 to 15) has no effect...

I'm using XST, and from their documentation (http://www.xilinx.com/itp/xilinx6/books/data/docs/xst/xst0067_9.html), the above should have worked:

...declaration:

subtype MATRIX15 is array(4 downto 0, 2 downto 0)
   of STD_LOGIC_VECTOR (7 downto 0);

 A multi-dimensional array signal or variable can be completely used:

Just a slice of one row can be specified:

MATRIX15 (4,4 downto 1) <= TAB_B (3 downto 0);

One alternative is that I can create more registers that are 16 times smaller, and instead of trying to do all '0 to 15' at once, I would just do that 15 additional times. However, I think this may lead to inefficiency in synthesis and I don't feel like this is the right solution.

EDIT:

Tried what Ben said,

instantiate_h_m_qa_pipeline_registers: for i in 1 to 16 generate

instantiate_h_pipelined_reg : regn
    generic map ( N=> b, init => bzeros )
    port map ( clk => clk , rst => '0', en => '1',
       input => h_blk_pipelined_input(i - 1),                                            
       output=> h_blk_pipelined_input(i));                                          
end generate instantiate_h_m_qa_pipeline_registers;                                                 

The signals are now defined as:

type std_logic_block is array (0 to 15) of std_logic_vector(iw - 1 downto 0) ;
type partial_pipeline_registers_type is array (0 to 16) of std_logic_block;
signal h_blk_pipelined_input : partial_pipeline_registers_type;

And the error I get from XST is:

ERROR:HDLParsers:800 - ((where the register part is)) Type of input is incompatible with type of h_blk_pipelined_input.

I'm able to do everything I was able to do before, using ()() syntax instead of ( , ) so I haven't lost anything going this way, but it still doesn't resolve my problem.

EDIT:

Took it a step further and used a conversion function on the input => and output => arguments for the register instantiation, using a function to convert between the array type and just a std_logic_vector the size that I need. It fixed the 'input => ' part, but..

Actual associated with Formal OUT mode Signal 'output' may not be a type conversion or function call. (LRM 4.3.2.2)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

生生漫 2024-10-26 05:31:13

怎么样:

TYPE reg512_type IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
TYPE partial_pipeline_registers_type IS ARRAY(0 TO 16) OF reg512_type;

Xilinx 网站上的代码显然没有经过测试。由于 ARRAY OF ... 是类型,而不是子类型,因此它们的代码不应编译。

编辑:这些自定义类型无法与现有 IP 组件很好地配合,但没关系,编译器可以轻松推断寄存器。尝试:

instantiate_h_m_qa_pipeline_registers: FOR i IN 1 TO 16 GENERATE

instantiate_h_pipelined_reg : PROCESS (clk)
BEGIN
    IF RISING_EDGE(clk) THEN
        h_blk_pipelined_input(i) <= h_blk_pipelined_input(i - 1);
    END IF;
END GENERATE instantiate_h_m_qa_pipeline_registers;   

How about:

TYPE reg512_type IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
TYPE partial_pipeline_registers_type IS ARRAY(0 TO 16) OF reg512_type;

The code on that Xilinx site obviously isn't tested. Since ARRAY OF ... are types, not subtypes, their code shouldn't compile.

EDIT: These custom types aren't going to play well with existing IP components, but that's ok, the compiler can infer registers easily enough. Try:

instantiate_h_m_qa_pipeline_registers: FOR i IN 1 TO 16 GENERATE

instantiate_h_pipelined_reg : PROCESS (clk)
BEGIN
    IF RISING_EDGE(clk) THEN
        h_blk_pipelined_input(i) <= h_blk_pipelined_input(i - 1);
    END IF;
END GENERATE instantiate_h_m_qa_pipeline_registers;   
稚气少女 2024-10-26 05:31:13

为了让事情正常进行,我必须使用一个函数来展平和取消展平与寄存器实例化交互的数据。

真正的问题归结为我有一个 std_logic_vector() 数组,它产生了一个寄存器实例化需要的大向量..然后寄存器给我返回了向量,我需要将其放入一个数组中向量。

创建一个函数然后执行以下操作效果很好。

      input => blk2vec(h_blk_pipelined_input(i - 1)),                        
      vec2blk(output) => h_blk_pipelined_input(i));

To get things to play right, I had to use a function to flatten and unflatten my data interacting with the register instantiation.

The real issue boiled down to me having an array of std_logic_vector() that resulted in a large vector which the register instantiation needed to have.. and then the register was giving me back the vector, which I needed to put in to an array of vectors.

Creating a function and then doing the following is working great.

      input => blk2vec(h_blk_pipelined_input(i - 1)),                        
      vec2blk(output) => h_blk_pipelined_input(i));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文