2017-03-03 8 views
2

私の要件は、入力ファイルからデータビットを読み込み、データをvhdlのメモリ配列(出力)に書き込むことです。 私は入力ファイルのデータ量を認識していないため、未知のサイズの配列を宣言し、後の段階でデータをメモリに割り当てる必要があります。VHDL配列 - 未知のサイズの配列を宣言して使用するには

私のコードは以下の通りです:

宣言:私は私の正確なrequiremnetに実際のコードを最小限に抑えている

PACKAGE io IS 
    type memory is array (natural range<>) of std_logic_vector(3 downto 0); 
END; 

entity File_io is 
port (
    clk:    in std_logic; 
    Data_memory:  out memory 
); 
end entity; 

architecture behav of File_io is 
signal mem: memory; 
begin 
process(clk) 
    begin 
    for i in 0 to 15 loop -- Took just 16 values for explaination purpose. 
          -- i may need more values to be written which is unknown. 
     mem(i) <= std_logic_vector(to_unsigned(i, 4)); 
    end loop; 
    Data_memory <= mem; 
    end process; 
end architecture behav; 

。構文エラーがあれば無視してください。

問題は、制約されていない、つまり未定義のサイズの配列に値を割り当てることができないという問題です。 どうすればいいですか?どのような提案や選択肢?ガイドme

+0

ちょうどあなたがいくつかの検索エンジンを試しましたか?私はVHDLの教祖ではない。しかし、そのトピックに関する様々な議論があるようです... – GhostCat

+1

私はさまざまなリンクで議論を行ってきましたが、私が得たものは、ある値でサイズを宣言する必要があります(可能な限り最大値かもしれません)。 –

+0

私は不思議に思っています:最終的にVHDLは "ハードウェア"を構築することではありませんか?では、実際のハードウェアでは「未知のサイズの」配列は何をしていますか? – GhostCat

答えて

2

あなたの他の質問を見てみると - How to Eliminate whitespaces while Reading a file in VHDL提供メモリ初期化ファイルの例とそれを読む際の問題です。

この修正を組み込み、メソッドメソッドJ.Hを使用します。ボナリウスは、Minimal, Complete and Verifiable exampleをもたらすと示唆している:

library ieee; 
use ieee.std_logic_1164.all; 

PACKAGE io IS 
    type memory is array (natural range<>) of std_logic_vector(3 downto 0); 
    function iswhitespace (inpstr: in string) return boolean; 
END; 

package body io is 
    function iswhitespace (inpstr: in string) return boolean is 
     constant NBSP: character := character'val(128); 
    begin 
     for i in inpstr'range loop 
      if inpstr(i) /= ' ' and inpstr(i) /= NBSP and inpstr(i) /= HT then 
       exit; 
      elsif i = inpstr'RIGHT then 
       return TRUE; 
      end if; 
     end loop; 
     return FALSE; 
    end function; 
end package body; 

library ieee; 
use ieee.std_logic_1164.all; 
use work.io.all; 

entity File_io is 
    generic (
     constant MEMORY_SIZE: natural := 42; 
     constant filename: string := "C:\Users\ChowdaryS\Downloads\topo.bin" 
    ); 
    port (
     clk:    in std_logic; 
     Data_memory:  out memory (0 to MEMORY_SIZE - 1) 
    ); 
end entity; 

architecture foo of File_io is 
    signal mem: memory (0 to MEMORY_SIZE - 1); -- ADDED subtype indication 
    use ieee.numeric_std.all;     -- MISSING cntext item 
    use std.textio.all; 
    signal mem_inited:  boolean := FALSE; -- ADDED 
begin 
    process(clk) 
     file f:  text open read_mode is filename; 
     variable L: line; 
     variable i: integer:= 0; 
     variable b: bit_vector(3 downto 0); 
    begin 
     if not mem_inited then 
      i := 0; 
      while not endfile(f) loop 
       readline(f, L); 
       while L.all'length >= b'length and not iswhitespace(L.all) loop 
        read(L, b); 
        mem(i) <= to_stdlogicvector(b); 
        i := i + 1; 
       end loop; 
      end loop; 
      report "mem values loaded = " & integer'image(i); 
      mem_inited <= TRUE; 
     end if; 
    end process; 
    Data_memory <= mem; 
end architecture foo; 

変更があります。関数iswhitespaceがパッケージioに追加されました。トレードオフとそれが必要かどうかについて、上記の質問を見ることができます。

出力ポートへの割り当てがプロセス外に移動されました。このプロセスには、memへの何らかの書き込みがあると仮定しています。

file_ioをインスタンス化してメモリ配列のサイズを決定し、それを汎用として渡すテストベンチもあります。

library ieee; 
use ieee.std_logic_1164.all; 
use work.io.all; 

entity file_io_tb is 
end entity; 

architecture foo of file_io_tb is 

    constant MEMSIZ: natural := 16; 
    constant filename: string := "topo.bin"; -- found locally. 
    signal clk:   std_logic := '0'; 
    signal Data_memory: memory (0 to MEMSIZ - 1); 
    use std.textio.all; 

    impure function getarraysize return natural is 
     variable L:  Line; 
     variable i:  natural; 
     variable b:  bit_vector (3 downto 0); 
     file f:   text open read_mode is filename; 
    begin 
     i := 0; 
     while not endfile(f) loop 
      readline(f, L); 
      while L.all'length >= b'length and not iswhitespace(L.all) loop 
       read(L, b); 
       i := i + 1; 
      end loop; 
     end loop; 
     report " memory size = " & integer'image(i); 
     return i; 
    end function; 
begin 
DUT: 
    entity work.file_io 
     generic map (MEMORY_SIZE => getarraysize, filename => filename) 
     port map (
      clk => clk, 
      Data_memory => Data_memory 
     ); 

CLOCK: 
    process 
    begin 
     wait for 10 ns; 
     clk <= not clk; 
     if now > 50 ns then 
      wait; 
     end if; 
    end process; 

end architecture; 

この関数は、エラボレーション時にファイルを読み取り、ジェネリックを設定します。

は、そして、私たちは、これがMEMを初期化参照:トポの

file_io_tb.png

コピーを。binには最初の行に4つの末尾スペースがあります。

10101100 11010100 10101100 11010100 

11111110 10111001 11111110 10111001 

上記の2つの値は、topo.binと一致しています。

(これはすべて、他の質問の空白で問題を見つけるために書かれています)。

2

ファイルを2回読み、最初に行の量を決定します。たとえば、

編集:最終的にvhdlシミュレータにアクセスできました。コードを修正しました。 私はVHDL、C++、C#、matlab、そしてPythonの間で、最近、構文を混ぜ合わせています。

library IEEE; 
use IEEE.std_logic_1164.all; 
use std.textio.all; 

entity file_io is 
    generic (
     data_width : positive := 4; 
     file_name : string 
    ); 
    port (
     clk   : in std_logic; 
     file_output : out std_logic_vector(data_width-1 downto 0) := (others => '0') 
    ); 
end entity file_io; 

architecture behaviour of file_io is 
    impure function get_line_count return positive is 
     file file_pointer : text; 
     variable line_data : line; 
     variable lineCount : natural := 0; 
    begin 
     file_open(file_pointer, file_name, read_mode); 
     while not endfile(file_pointer) loop 
      readline(file_pointer, line_data); 
      lineCount := lineCount + 1; 
     end loop; 
     file_close(file_pointer); 
     return lineCount; 
    end function get_line_count; 

    constant memory_size : positive := get_line_count; 

    subtype data_type is std_logic_vector(data_width-1 downto 0); 
    type memory_type is array (0 to memory_size-1) of data_type; 

    impure function get_data return memory_type is 
     file file_pointer : text; 
     variable line_data : line; 
     variable line_value : bit_vector(data_width-1 downto 0); 
     variable memory : memory_type; 
     variable index : natural := 0; 
    begin 
     file_open(file_pointer, file_name, read_mode); 
     while not endfile(file_pointer) loop 
      readline(file_pointer, line_data); 
      read(line_data, line_value); 
      memory(index) := to_stdlogicvector(line_value); 
      index := index + 1; 
     end loop; 
     file_close(file_pointer); 
     return memory; 
    end function get_data; 

    constant memory : memory_type := get_data; 
    signal index : natural := 0; 
begin 
    process(clk) 
    begin 
     if rising_edge(clk) then 
      file_output <= memory(index); 
      if (index < memory_size-1) then 
       index <= index + 1; 
      else 
       index <= 0; 
      end if; 
     end if; 
    end process; 
end architecture behaviour; 

とテストベンチ:

library IEEE; 
use IEEE.std_logic_1164.all; 

entity file_io_tb is 
end entity file_io_tb; 

architecture behaviour of file_io_tb is 
    signal clk : std_logic := '0'; 
    constant data_width : positive := 4; 
    signal data : std_logic_vector(data_width-1 downto 0); 
begin 
    file_io_inst : entity work.file_io 
     generic map(
      data_width => 4, 
      file_name => "data_file.txt" 
      ) 
     port map(
      clk => clk, 
      file_output => data 
      ); 

    clk_prc : process 
    begin 
     loop 
      clk <= '0', '1' after 1 ns; 
      wait for 2 ns; 
     end loop; 
    end process; 
end architecture behaviour; 

data_file.txtはちょうどこれが私のために正常に動作します

0101 
1010 
1100 
0011 
... 

が含まれています...

+0

マストのパラメータインターフェイスリストには、少なくとも1つのinterface_elementがあります。 IEEE Std 1076-2009 6.5.6.1、interface_list :: = interface_element {interface_element}。仮パラメータのリストは、副プログラムの宣言ではオプションです。 4.2.1 function_specification :: = [**純粋な** | ** [** paramete ** r](formal_parameter_list)] ** return ** type_mark。 1.2.1角括弧[]は、プロダクションの右側にオプションの項目を囲みます。 – user1155120

+0

修正済み...構文が混乱しています... – JHBonarius

関連する問題