レコード型の入出力を想定したFIFOを想定すると、fifoラッパーの入出力のレコード型と実際のFIFOのstd_logic_vectorの間のマッピングを処理する簡単な方法がありますか?VHDL/FPGAのFIFOとの間でレコードを簡単に読み書きする方法はありますか?
0
A
答えて
0
私がこれまでに出てくることができました最も簡単な方法です、次のように:まず
一定の範囲宣言整理する機能パッケージ:
library ieee;
use ieee.std_logic_1164.all;
package Fun_pck is
function fLenAtTopOf(a : natural; b: std_logic_vector) return natural;
function fTopOf(b : std_logic_vector) return natural;
end package Fun_pck;
package body Fun_pck is
function fLenAtTopOf(a : natural; b: std_logic_vector) return natural is
begin
return a+b'left;
end function fLenAtTopOf;
function fTopOf(b: std_logic_vector) return natural is
begin
return b'left+1;
end function fTopOf;
end package body Fun_pck;
次に、2つのパッケージが含まれヘルパーFIFOの定義:
library ieee;
use ieee.std_logic_1164.all;
use work.Fun_pck.all;
package ExampleFifo_pck_private is
-- This package is 'private', i.e. only meant to be seen by the package and
-- entity in this file. This is so that the elements will not have a name
-- clash. As they are top-level constants that would be a likely problem.
-- Fifo element constants.
type width_array is array (integer range <>) of integer;
constant cElementWidths : width_array(0 to 2) := (4, 8, 1);
constant cFifoElement0 : std_logic_vector(cElementWidths(0)-1 downto 0) := (others => '0');
constant cFifoElement1 : std_logic_vector(
fLenAtTopOf(cElementWidths(1), cFifoElement0) downto
fTopOf(cFifoElement0)) := (others => '0');
constant cFifoElement2 : std_logic_vector(
fLenAtTopOf(cElementWidths(2), cFifoElement1) downto
fTopOf(cFifoElement1)) := (others => '0');
-- General Form:
--constant cFifoElementN : std_logic_vector(
-- fLenAtTopOf(cElementWidths(N), cFifoElement[N-1]) downto
-- fTopOf(cFifoElement[N-1])) := (others => '0');
end package ExampleFifo_pck_private;
library ieee;
use ieee.std_logic_1164.all;
use work.Fun_pck.all;
use work.ExampleFifo_pck_private.all;
-- Fifo item type
type tExampleFifoData is record
A : std_logic_vector(cFifoElement0'length-1 downto 0);
B : std_logic_vector(cFifoElement1'length-1 downto 0);
C : std_logic_vector(cFifoElement2'length-1 downto 0);
end record tExampleFifoData;
-- Reset constant
constant cResetExampleFifoData : tExampleFifoData := (
A => cFifoElement0,
B => cFifoElement1,
C => cFifoElement2
);
-- Length Constant
constant cExampleFifoWidth : integer := fTopOf(cFifoElement2);
-- Data array type
type tExampleFifoData_Array is array (natural range<>) of tExampleFifoData;
end package ExampleFifo_pck;
およびFIFOモジュールをラップ最終的エンティティ/アーキテクチャのペア、この場合のザイリンクスXPM:
library ieee;
use ieee.std_logic_1164.all;
use work.ExampleFifo_pck.all;
use work.ExampleFifo_pck_private.all;
library xpm;
use xpm.vcomponents.all;
entity ExampleFifo is
port (
iWrClk : in std_logic;
iRst : in std_logic;
iWrEn : in std_logic;
iWrData : in tExampleFifoData;
oWrFull : out std_logic;
oWrProgFull : out std_logic;
iRdClk : in std_logic;
iRdEn : in std_logic;
oRdData : out tExampleFifoData;
oRdEmpty : out std_logic
);
end entity ExampleFifo;
architecture RTL of ExampleFifo is
-- Internal vector signals
signal sWrData : std_logic_vector(cExampleFifoWidth-1 downto 0) := (others => '0');
signal sRdData : std_logic_vector(cExampleFifoWidth-1 downto 0) := (others => '0');
begin
sWrData(cFifoElement0'range) <= iWrData.A;
sWrData(cFifoElement1'range) <= iWrData.B;
sWrData(cFifoElement2'range) <= iWrData.C;
oRdData.A <= sRdData(cFifoElement0'range);
oRdData.B <= sRdData(cFifoElement1'range);
oRdData.C <= sRdData(cFifoElement2'range);
x_fifo : xpm_fifo_async
generic map (
-- check:
FIFO_MEMORY_TYPE => "distributed", --string; "auto", "block", or "distributed";
ECC_MODE => "no_ecc", --string; "no_ecc" or "en_ecc";
-- check:
RELATED_CLOCKS => 0, --positive integer; 0 or 1
-- check:
FIFO_WRITE_DEPTH => 32, --positive integer
-- modify:
WRITE_DATA_WIDTH => cExampleFifoWidth, --positive integer
WR_DATA_COUNT_WIDTH => 1, --positive integer
-- check:
PROG_FULL_THRESH => 27, --positive integer
FULL_RESET_VALUE => 0, --positive integer; 0 or 1;
read_mode => "fwft", --string; "std" or "fwft";
FIFO_READ_LATENCY => 0, --positive integer;
-- modify:
READ_DATA_WIDTH => cExampleFifoWidth, --positive integer
RD_DATA_COUNT_WIDTH => 1, --positive integer
PROG_EMPTY_THRESH => 10, --positive integer
DOUT_RESET_VALUE => "0", --string
CDC_SYNC_STAGES => 2, --positive integer
WAKEUP_TIME => 0 --positive integer; 0 or 2;
)
port map (
sleep => '0',
rst => iRst,
wr_clk => iWrClk,
wr_en => iWrEn,
din => sWrData,
full => oWrFull,
overflow => open,
wr_rst_busy => open,
rd_clk => iRdClk,
rd_en => iRdEn,
dout => sRdData,
empty => oRdEmpty,
underflow => open,
rd_rst_busy => open,
prog_full => oWrProgFull,
wr_data_count => open,
prog_empty => open,
rd_data_count => open,
injectsbiterr => '0',
injectdbiterr => '0',
sbiterr => open,
dbiterr => open
);
end architecture RTL;
これは少し問題ですが、fifoを宣言するのはかなり管理しやすいです。それぞれのfifoは依然としてパッケージとエンティティの独自のバージョンを必要とします。当然のことながら、それらは単一のファイルに存在することができます。
は、このトラブルの後、FIFOの実際の使用は非常に簡単です:
簡潔にすることlibrary ieee;
use ieee.std_logic_1164.all;
use work.ExampleFifo_pck.all;
entity tb is
end entity tb;
architecture sim of tb is
signal iWrClk : std_logic := '1';
signal iRst : std_logic := '0';
signal sWrEn : std_logic := '0';
signal sWrData : tExampleFifoData;
signal sWrFull : std_logic;
signal sWrProgFull : std_logic;
signal iRdClk : std_logic := '1';
signal sRdEn : std_logic := '0';
signal sRdData : tExampleFifoData;
signal sRdEmpty : std_logic;
signal sTestIn : tExampleFifoData := cResetExampleFifoData;
signal sTestOut : tExampleFifoData;
constant tests : tExampleFifoData_Array(0 to 1) :=
(0 => (x"E", x"A7", "1"), 1 => (x"7", x"AC", "0"));
begin
iWrClk <= not iWrClk after 5 ns;
iRdClk <= not iRdClk after 7.2 ns;
ExFifo : entity work.ExampleFifo
port map (
iWrClk => iWrClk,
iRst => iRst,
iWrEn => sWrEn,
iWrData => sTestIn,
oWrFull => sWrFull,
oWrProgFull => sWrProgFull,
iRdClk => iRdClk,
iRdEn => sRdEn,
oRdData => sTestOut,
oRdEmpty => sRdEmpty
);
wr : process is
begin
iRst <= '1';
for i in 0 to 5 loop
wait until rising_edge(iWrClk);
end loop;
iRst <= '0';
wait for 150 ns;
for i in 0 to 1 loop
wait for 15 ns;
wait until rising_edge(iWrClk);
sTestIn <= tests(i);
sWrEn <= '1';
wait until rising_edge(iWrClk);
sWrEn <= '0';
wait until rising_edge(iWrClk);
end loop;
wait;
end process wr;
rd : process is
begin
wait until rising_edge(iRdClk);
sRdEn <= '0';
if(sRdEmpty = '0' ans sRdEn <= '0') then
sRdEn <= '1';
end if;
end process rd;
end architecture sim;
0
...
-- items within fifo
constant c_items : integer := 8;
constant c_width : integer :=
(-- ADD NEW ITEMS HERE
c_CWidth +
c_BWidth +
c_AWidth
);
type t_intVector is array (natural range <>) of integer;
constant c_start : t_intVector(c_items downto 0) :=
(-- INSERT/MODIFY FOR NEW ITEMS
0+c_AWidth+c_BWidth+c_CWidth, -- end
0+c_AWidth+c_BWidth, -- C
0+c_AWidth, -- B
0 -- A
);
-- MODIFY FOR ADDITIONAL ITEMS
procedure f_writeToFifo(
signal o_f : out std_logic_vector;
i_A : unsigned;
i_B : unsigned;
i_C : unsigned) is
begin
o_f <= i_C &
i_B &
i_A;
end procedure f_writeToFifo;
type t_data is record
A : unsigned(c_AWidth-1 downto 0);
B : unsigned(c_BWidth-1 downto 0);
C : unsigned(c_CWidth-1 downto 0);
end record;
function f_readA(i_f : std_logic_vector) return unsigned is begin return unsigned(i_f(c_start(3)-1 downto c_start(2))); end function f_readA;
function f_readB(i_f : std_logic_vector) return unsigned is begin return unsigned(i_f(c_start(2)-1 downto c_start(1))); end function f_readB;
function f_readC(i_f : std_logic_vector) return unsigned is begin return unsigned(i_f(c_start(1)-1 downto c_start(0))); end function f_readC;
function f_read (i_f : std_logic_vector) return t_data is begin
return (C => f_readC(i_f),
B => f_readB(i_f),
A => f_readA(i_f));
end function f_read;
リスト/位置/アイテムの作成を無視します。プロシージャ/レコード/関数は、私が強調しようとしているものです。
1
提示されているように、パッケージ内の会話を非表示にすることができます。したがって、FIFOインターフェイスとレコード間の2つの機能があります。
Rob Gaddi(IEEE WG for VHDLの副議長)は、一度レコードタイプとの間でstd_logic_vectorsを素早くパッキングしアンパックするための一連のヘルパープロシージャを提示しました。 彼のproposed pack and unpack subprogramsを参照してください。
ワーキンググループは、このような問題の解決方法について長い議論を重ねてきました。 3つの可能性があります。
- VHDLはエンティティ宣言のジェネリック型をサポートしています。したがって、VHDL-2008に準拠した合成ツールは、任意のタイプ*)をFIFO要素として受け入れる汎用FIFOを作成することができます。
- VHDL-2017は、少なくともレコードからの会話を
std_logic_vector
に解決することができるreflection APIを追加します。私は逆の道を実装する方法を考えています。 - レコード要素を反復する直接的解決策は未だ見出されておらず、次のリビジョン(VHDL-2020)
*)任意の合成スカラ、アレイまたはレコードタイプに遅延されます。
関連する問題
- 1. スタイルシートをインラインスタイルで上書きする簡単な方法はありますか?
- 2. CとPython間のFifoファイルの読み込みと書き込み
- 3. fifo上のデータの書き込み/読み取りの正しい方法
- 4. 簡単で読みやすい方法でフィルタ辞書
- 5. BCPを使用してSPROCから読み書きする簡単な方法
- 6. 複数のプロセス読み取り/書き込みfifo
- 7. 名前付きFIFOパイプはディスクの書き込みと読み取りを使用しますか?
- 8. pthread読み書きロックはFIFOですか?
- 9. キー&辞書で簡単に簡単に解読できますか?
- 10. このコードを簡単に書く方法はありますか?
- 11. これをPythonで簡単に書く方法はありますか?
- 12. Visual StudioでUTF-8オクテットを簡単に書く方法はありますか?
- 13. マクロでトランザクションを簡単に書く方法はありますか?
- 14. rubyで簡単に読み書きできるjson文字列
- 15. Markdownを簡単なHTML文書に変換する簡単な方法はありますか?
- 16. CObListを簡単にソートする方法はありますか?
- 17. ファイルディスクリプタを簡単にフォークする方法はありますか?
- 18. QProgressBarを簡単にカスタマイズする方法はありますか?
- 19. comlexプロジェクトのビルドスクリプトを書くのは簡単で人間的な方法はありますか?
- 20. WebSphereに簡単にデプロイする方法はありますか?
- 21. Androidを使ってデータを読み書きする簡単な方法
- 22. UnicodeDecodeError読み辞書の単語は簡単なPythonスクリプトでファイルとき
- 23. XCodeでファイルを簡単に置き換える方法はありますか?
- 24. 簡単な方法で個々のレコードを取得し、自動的に書き込みます
- 25. 簡単な方法でデータベースから1つのデータのみを取得する方法はありますか?
- 26. このhtml/razorコードを書く簡単な方法はありますか?
- 27. Readlineに代わる簡単な方法はありますか?
- 28. Unity3dのテキストファイルにいくつかのTransformを書き込んで読み込む簡単な方法はありますか?
- 29. Kafkaキューへの書き込みと読み取りの間に遅延があるのはなぜですか?
- 30. 辞書に格納されたAnyObjectを簡単に読み取る方法は?
これを正しく理解しているとすれば、入力/出力用のレコードをFIFOに使用することに決めました。レコードを入力として受け取り、std_logic_vectorを返す関数を使用してもかまいません。 –
仮定は正しいです。これらの関数が簡略化されていて、サンプルの答えに書かれているものよりもエラーが起こりにくい例がありますか? – FritzDC
例を追加しますが、そのエラーが発生しにくいということについてはわかりません。あなたがそれをより良く判断できると思います。 –