2016-06-13 14 views
0

私は、std_logic_vectorの特定の位置にビットを設定するリソース効率的な方法を探しています。標準パターンをstd_logic_vectorで生成する

私は、signal a := std_logic_vector(LEN-1 downto 0) := (others => '0'), のようなstd_logic_vectorを持っているとしましょう。ここでLENは一般的なものです。 定期的なインターバル、例えば、第5、第10、...の位置でそれを1に設定したいと考えています。インターバルは、あらかじめ定義された数字の小さなセット( )から来るかもしれません。例えば、(5,10,20,25,30,40,50)です。 これを達成するための最も省資源的な方法は何ですか?

明らかに、これは、forループとmod機能を使用して達成できます。 しかし、このメソッドを合成に使用したいので、mod関数が高価になる可能性があります。もう一つの可能​​性は、ループを展開することです。しかし、LENは一般的なので、私はステップの数を知らない。さらに、不可解な組み合わせ、例えばLEN = 20を除外したい場合は、インバージョン> 20を除外する必要があります。

+1

。両方とも一定です。最も高価な部分は、あなたがそれを熱くしないと入力選択を解読する可能性が高いです。 –

+0

1つ以上の定数宣言の値を生成する関数を書くことができます。値を消費するために使用するメカニズム以外のコストを必要としない、洗練されたデザインを合成するからです。 – user1155120

答えて

1

ヤンの答えには、VHDLの構文に精通していない人には答えを出すためにここで取り上げたいいくつかの問題があります。これはYannが選択した実装の批判ではなく、構文の問題を明確にするためのものです。

まず、上記の例は完全ではありません。 componentステートメントが記述されていますが、対応するentityはありません。 componentの使用は宣言的な領域にのみあり、packageまたはarchitectureの外部には単独で存在することはできません。書かれているように、それはコンパイルされません。むしろ、それが変更されるべきである:

entity columns is 
... 
end entity columns; 

第二に、一つは、対応するタイプ宣言せずに配列を宣言することができません。つまり、ヤンのポストの例:

values : array (0 to choices-1) of integer 

は実行できません。タイプは、使用する前に宣言する必要があります。そして、そのタイプをコンポーネント/エンティティに見えるようにするには、componentまたはentityの前に定義する必要があります。 entityの場合は、パッケージで定義する必要があります。例えば:

package columns_pkg is 
    type values_array is array(natural range <>) of integer; 
end package columns_pkg; 

そしてcolumns_pkgentityで参照することができます。など:

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

entity columns is 
    generic (
    LEN  : integer;     -- bits of output 
    choices : integer;     -- number of column combinations 
     -- distances at which bits may be 1 
    values : values_array(0 to choices-1) 
); 
    ... 

今、これはまだかなり正しくありません。 VHDL-2008でのみ、ジェネリックは互いに依存することができます。つまり、valuesの範囲はVHDL-2008のchoicesにのみ依存することができます。それ以前の言語バージョンでは、VHDL-2002以前のバージョンでは、上記のvaluesの宣言が失敗することになります。

しかし、choicesも必要ないことが判明しました。 valuesが拘束されないことを

library ieee; 
use ieee.std_logic_1164.all; 

package columns_pkg is 
    type values_array is array(natural range <>) of integer; 
end package columns_pkg; 

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

entity columns is 
    generic 
    (
    LEN  : integer;     -- bits of output 
    values : values_array 
); 
    port 
    (
    -- one hot encoded distance choice 
    distance : in std_logic_vector(values'length-1 downto 0); 
    -- data which is 1 at selected distance 
    bits  : out std_logic_vector(LEN-1 downto 0) 
); 
end entity columns; 

architecture behavioural of columns is  
begin -- architecture behavioural 

    bitgen: for i in bits'range generate 
    begin 
    -- purpose: calculate one individual bit 
    -- type : combinational 
    -- inputs : distance 
    -- outputs: bits(i) 
    bitcalc: process (distance) is 
     variable j : integer; 
    begin -- process bitcalc 
     bits(i) <= '0'; 
     for j in values'range loop 
     if i mod values(j) = 0 and distance(j) = '1' then 
      bits(i) <= '1'; 
     end if; 
     end loop; -- j 
    end process bitcalc; 
    end generate; 

end architecture behavioural; 

注:むしろ、1本(それをすべて一緒に持って来ると、タイプミスのカップルをクリーンアップ)を行うことができます。長さは精緻化時に決定されます。また、属性を使用して長さと範囲を決定することもできます。

また、LENと範囲valuesの間に関係がある場合は、LENジェネリックも削除される可能性があります。

そして最後に、columnsを利用するために、一つはありません:あなたは、事前に定義された数の制限されたセットとビット位置との間のmodをやっている

entity top is 
end entity top; 

use work.columns_pkg.all; 

architecture behavioural of top is 
    constant columns_values : values_array(0 to 5) := (0, 5, 10, 15); 

    -- one hot encoded distance choice 
    signal distance : std_logic_vector(columns_values'length-1 downto 0); 

    -- data which is 1 at selected distance 
    signal bits  : out std_logic_vector(31 downto 0); 
begin 
    columns_inst : entity work.columns 
    generic map 
    (
    LEN => bits'length, 
    values => columns_values 
) 
    port map 
    (
    distance => distance, 
    bits => bits 
); 

end architecture behavioural; 
+0

ありがとう、私は提案されたソリューションを使用します! – Apoptose

0

数字があらかじめ定義されているとすれば、一定のビット位置と1つの(一握りの)定数の間でモジュロを行うだけです。これは、ビットごとに単純かつ/またはツリーを生成する2つのループのセットで行うことができます。シンセサイザーはいくつかの一般的なロジックを排除することができます。私はおそらくステップの距離を1つのホットとして、あるいはおそらく5がn * 5をも意味するような木のフォームとしてエンコードします。私はコードが類似していると思います:

component columns is 
    generic (
    LEN  : integer;     -- bits of output 
    choices : integer;     -- number of column combinations 
     -- distances at which bits may be 1 
    values : array (0 to choices-1) of integer); 
    port (
     -- one hot encoded distance choice 
    distance : in std_logic_vector(choices-1 downto 0); 
     -- data which is 1 at selected distance 
    bits  : out std_logic_vector(LEN-1 downto 0)); 
end component columns; 

architecture behavioural of columns is 

begin -- architecture behavioural 

    bitgen: for i in 0 to choices-1 generate 
    begin 
    -- purpose: calculate one individual bit 
    -- type : combinational 
    -- inputs : distance 
    -- outputs: bits(i) 
    bitcalc: process (distance) is 
     variable j : integer; 
    begin -- process bitcalc 
     bits(i) <= '0'; 
     for j in 0 to chocies-1 loop 
     if i mod values(j) = 0 and distance(j) then 
      bits(i) <= '1'; 
     end if; 
     end loop; -- j 
    end process bitcalc; 
    end generate; 

end architecture behavioural; 

これは、幅や幅が一握りのものに過ぎません。

+0

ありがとう、私はこれを試してみましょう! – Apoptose

関連する問題