ベクトルsignal tmp : std_logic_vector(15 downto 0)
があります
Nビットの左または右にシフトする必要があります。この操作をどのように実現できますか。連結操作を考えましたが、どのように使用するのかわかりませんでした。
ieee.numeric_std
ライブラリと、作業中の数値に適したベクトル型(unsigned
またはsigned
)を使用します。
演算子は、算術シフトの場合はsla
/sra
(右シフトの場合は符号ビットで、左シフトの場合はlsbで埋める)およびsll
/srl
論理シフト(つまり、「0」で埋める)。
演算子にパラメーターを渡し、シフトするビット数を定義します。
A <= B srl 2; -- logical shift right 2 bits
上に何を書いているのかわかりません(指摘してくれたValに感謝します!)
もちろん、signed
およびunsigned
型をシフトする正しい方法は、shift_left
で定義されているshift_right
およびieee.numeric_std
関数を使用することです。
シフトおよび回転演算子sll
、ror
など boolean
、bit
、またはstd_ulogic
のベクトル用 、 興味深いことに予期しない振る舞い を持つことができます。左にシフトしても算術シフトが終了ビットを複製します。
さらに多くの歴史はここで見つけることができます:
http://jdebp.eu./FGA/bit-shifts-in-vhdl.html
しかし、元の質問への答えはまだです
sig <= tmp sll number_of_bits;
これを実現する方法は2つあります。連結、およびシフト/回転機能。
連結は、物事を行う「手動の」方法です。元の信号のどの部分を「維持」するかを指定してから、データを一端または他端に連結します。例:tmp <= tmp(14 downto 0)& '0';
シフト関数(論理、算術):これらは、さまざまな方法でベクトルをシフトまたは回転できる汎用関数です。機能は次のとおりです。sll(左に論理シフト)、srl(右に論理シフト)。論理シフトはゼロを挿入します。算術シフト(sra/sla)は、左端または右端のビットを挿入しますが、論理シフトと同じように機能します。 これらのすべての操作に対して、シフトする対象(tmp)と、シフトを実行する回数(nビット)
回転機能:rol(左回転)、ror(右回転)。回転するだけで、MSBがLSBになり、すべてが左にシフト(rol)するか、逆にrorになります。
便利なリファレンス を見つけました(最初のページを参照)。
個人的には、連結がより良い解決策だと思います。一般的な実装は次のようになります
entity shifter is
generic (
REGSIZE : integer := 8);
port(
clk : in str_logic;
Data_in : in std_logic;
Data_out : out std_logic(REGSIZE-1 downto 0);
end shifter ;
architecture bhv of shifter is
signal shift_reg : std_logic_vector(REGSIZE-1 downto 0) := (others<='0');
begin
process (clk) begin
if rising_Edge(clk) then
shift_reg <= shift_reg(REGSIZE-2 downto 0) & Data_in;
end if;
end process;
end bhv;
Data_out <= shift_reg;
両方ともシフトレジスタとして実装されます。リソースを使用するよりも多くのシフトレジスタが必要な場合(たとえば、1000の数値を4で割る)、値を格納するためにBRAMを使用し、「インデックス」を含む単一のシフトレジスタを使用することを検討してください。すべての数字の正しいシフト。
not std_logic_vectorでsll
またはsrl
を使用することをお勧めします。
シミュレーション中にsll
がこれらのビットに「U」値を与えました。
shift_left()
、shift_right()
関数を使用します。
例えば:
OP1 : in std_logic_vector(7 downto 0); signal accum: std_logic_vector(7 downto 0);
accum <= std_logic_vector(shift_left(unsigned(accum), to_integer(unsigned(OP1)))); accum <= std_logic_vector(shift_right(unsigned(accum), to_integer(unsigned(OP1))));
これは通常、ベクターから適切なビットを選択してから0を追加することにより、手動で行われます。
たとえば、ベクトルを8ビットシフトするには
variable tmp : std_logic_vector(15 downto 0)
...
tmp := x"00" & tmp(15 downto 8);
この単純な答えが誰かに役立つことを願っています
_add_Pbl <= to_stdlogicvector(to_bitvector(dato_cu(25 downto 2)) sll 1);
add_Pbl is a std_logic_vector of 24 bit
dato_cu is a std_logic_vector of 32 bit
_
Sllステートメントは論理1ビットと0ビットで機能するため、最初に_std_logic_vector
_をto_bitvector()
関数で変換する必要があります。