VHDL/FPGA-dagi fifos-dan/yoki yozuvlarni yozishning oddiy usullari bormi?

Ro'yxatga olish turi va tashqarisiga ega bo'lgan beshlikni nazarda tutadigan bo'lsak, fifo-wrapper va std_logic_vector-ning haqiqiy beshlikdagi kirish va chiqishi bilan ro'yxatga olish turi o'rtasidagi xaritalashni osonlashtiradigan usul bormi?

0
Buni to'g'ri tushungan bo'lsam-da, FIFO-ga kirish/chiqishingiz uchun yozuvni ishlatishga qaror qilgandirsiz - nima uchun siz yozuvni yozib olgan va std_logic_vector va aksincha, funksiyani ishlatmaysiz.
qo'shib qo'ydi muallif fpga_magik, manba
Misol keltiraman, uning qobiliyatini kamroq xatolarga moyil bo'lishiga ishonchim komil emas - deb o'ylayman.
qo'shib qo'ydi muallif fpga_magik, manba
Misol keltiraman, uning qobiliyatini kamroq xatolarga moyil bo'lishiga ishonchim komil emas - deb o'ylayman.
qo'shib qo'ydi muallif fpga_magik, manba
Misol keltiraman, uning qobiliyatini kamroq xatolarga moyil bo'lishiga ishonchim komil emas - deb o'ylayman.
qo'shib qo'ydi muallif fpga_magik, manba
Qaysi FIFO elementlari haqida qayg'urasiz? Ehtimol, bu erda kichik bir misol bor? Nomlar to'qnashuviga yo'l qo'ymaslik uchun turli xil paketlardan foydalanishingiz mumkin - bu erda men juda ko'p tafsilotlarni izohlash qiyin deb hisoblayman.
qo'shib qo'ydi muallif fpga_magik, manba
Qaysi FIFO elementlari haqida qayg'urasiz? Ehtimol, bu erda kichik bir misol bor? Nomlar to'qnashuviga yo'l qo'ymaslik uchun turli xil paketlardan foydalanishingiz mumkin - bu erda men juda ko'p tafsilotlarni izohlash qiyin deb hisoblayman.
qo'shib qo'ydi muallif fpga_magik, manba
Qaysi FIFO elementlari haqida qayg'urasiz? Ehtimol, bu erda kichik bir misol bor? Nomlar to'qnashuviga yo'l qo'ymaslik uchun turli xil paketlardan foydalanishingiz mumkin - bu erda men juda ko'p tafsilotlarni izohlash qiyin deb hisoblayman.
qo'shib qo'ydi muallif fpga_magik, manba
Bashorat to'g'ri. Misol tariqasida bu funktsiyalar soddalashtirilsa yoki kamroq xato bo'lsa, unda namunadagi javobdan ko'ra yoza olasizmi?
qo'shib qo'ydi muallif FritzDC, manba
Bashorat to'g'ri. Misol tariqasida bu funktsiyalar soddalashtirilsa yoki kamroq xato bo'lsa, unda namunadagi javobdan ko'ra yoza olasizmi?
qo'shib qo'ydi muallif FritzDC, manba
Bashorat to'g'ri. Misol tariqasida bu funktsiyalar soddalashtirilsa yoki kamroq xato bo'lsa, unda namunadagi javobdan ko'ra yoza olasizmi?
qo'shib qo'ydi muallif FritzDC, manba
Siz uchun rahmat. Siz haqsiz - tasdiqlash, ta'mga soladigan narsa bo'ladi. Umuman olganda, mening maqsadim, qopqog'i ostidagi iflos ishlarni iloji boricha yashirish edi, shuning uchun fifo'dan foydalanish bu qanday sodir bo'lishini bilishga hojat yo'q. Men funktsiyalarga bir xil erishish mumkinligiga roziman. Muammo bir nechta fifos bilan va beshor elementlarni nom-ziddiyatdan qanday qilib saqlab qolish mumkin bo'ladi.
qo'shib qo'ydi muallif FritzDC, manba
Siz uchun rahmat. Siz haqsiz - tasdiqlash, ta'mga soladigan narsa bo'ladi. Umuman olganda, mening maqsadim, qopqog'i ostidagi iflos ishlarni iloji boricha yashirish edi, shuning uchun fifo'dan foydalanish bu qanday sodir bo'lishini bilishga hojat yo'q. Men funktsiyalarga bir xil erishish mumkinligiga roziman. Muammo bir nechta fifos bilan va beshor elementlarni nom-ziddiyatdan qanday qilib saqlab qolish mumkin bo'ladi.
qo'shib qo'ydi muallif FritzDC, manba
Siz uchun rahmat. Siz haqsiz - tasdiqlash, ta'mga soladigan narsa bo'ladi. Umuman olganda, mening maqsadim, qopqog'i ostidagi iflos ishlarni iloji boricha yashirish edi, shuning uchun fifo'dan foydalanish bu qanday sodir bo'lishini bilishga hojat yo'q. Men funktsiyalarga bir xil erishish mumkinligiga roziman. Muammo bir nechta fifos bilan va beshor elementlarni nom-ziddiyatdan qanday qilib saqlab qolish mumkin bo'ladi.
qo'shib qo'ydi muallif FritzDC, manba

9 javoblar

Taqdim etilganidek, suhbatni paketda yashirishingiz mumkin. Shunday qilib, siz FIFO interfeysidan va yozuvdan 2 funktsiyaga ega bo'lasiz.

Rob Gaddi (VHDL uchun IEEE WG ning vitse-spikeri) bir marta tezroq mahsulotni yig'ish va ro'yxatga olish turlaridan std_logic_vectorsni ochish uchun yordamchi vositalarni taqdim etdi. taklif etilgan paket va ochish subprograms ga qarang.

Ishchi guruhning o'zi bunday masalani qanday hal qilish borasida uzoq vaqt davomida munozaralar o'tkazdi. 3 ta imkoniyat mavjud:

  • VHDL supports generic types on entity declarations. So a VHDL-2008 compliant synthesis tool could create a generic FIFO accepting any type *) as a FIFO element.
  • VHDL-2017 adds a reflection API that can at least solve the conversation from record to std_logic_vector. I'm working on a idea how to implement the reverse path.
  • A direct solution to iterate record elements was not found yet and is delayed to the next revision (VHDL-2020)

*) Har qanday synthesizable skalar, qator yoki yozuv turi.

1
qo'shib qo'ydi

Taqdim etilganidek, suhbatni paketda yashirishingiz mumkin. Shunday qilib, siz FIFO interfeysidan va yozuvdan 2 funktsiyaga ega bo'lasiz.

Rob Gaddi (VHDL uchun IEEE WG ning vitse-spikeri) bir marta tezroq mahsulotni yig'ish va ro'yxatga olish turlaridan std_logic_vectorsni ochish uchun yordamchi vositalarni taqdim etdi. taklif etilgan paket va ochish subprograms ga qarang.

Ishchi guruhning o'zi bunday masalani qanday hal qilish borasida uzoq vaqt davomida munozaralar o'tkazdi. 3 ta imkoniyat mavjud:

  • VHDL supports generic types on entity declarations. So a VHDL-2008 compliant synthesis tool could create a generic FIFO accepting any type *) as a FIFO element.
  • VHDL-2017 adds a reflection API that can at least solve the conversation from record to std_logic_vector. I'm working on a idea how to implement the reverse path.
  • A direct solution to iterate record elements was not found yet and is delayed to the next revision (VHDL-2020)

*) Har qanday synthesizable skalar, qator yoki yozuv turi.

1
qo'shib qo'ydi

Taqdim etilganidek, suhbatni paketda yashirishingiz mumkin. Shunday qilib, siz FIFO interfeysidan va yozuvdan 2 funktsiyaga ega bo'lasiz.

Rob Gaddi (VHDL uchun IEEE WG ning vitse-spikeri) bir marta tezroq mahsulotni yig'ish va ro'yxatga olish turlaridan std_logic_vectorsni ochish uchun yordamchi vositalarni taqdim etdi. taklif etilgan paket va ochish subprograms ga qarang.

Ishchi guruhning o'zi bunday masalani qanday hal qilish borasida uzoq vaqt davomida munozaralar o'tkazdi. 3 ta imkoniyat mavjud:

  • VHDL supports generic types on entity declarations. So a VHDL-2008 compliant synthesis tool could create a generic FIFO accepting any type *) as a FIFO element.
  • VHDL-2017 adds a reflection API that can at least solve the conversation from record to std_logic_vector. I'm working on a idea how to implement the reverse path.
  • A direct solution to iterate record elements was not found yet and is delayed to the next revision (VHDL-2020)

*) Har qanday synthesizable skalar, qator yoki yozuv turi.

1
qo'shib qo'ydi

Qisqartirish uchun qilingan ...

-- 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;

Ro'yxatni/joylashuvni/maqola yaratishni e'tiborsiz qoldiring. Yordan/ro'yxatga olish/funktsiyalarni ta'kidlashni maqsad qilganman.

0
qo'shib qo'ydi

Qisqartirish uchun qilingan ...

-- 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;

Ro'yxatni/joylashuvni/maqola yaratishni e'tiborsiz qoldiring. Yordan/ro'yxatga olish/funktsiyalarni ta'kidlashni maqsad qilganman.

0
qo'shib qo'ydi

Qisqartirish uchun qilingan ...

-- 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;

Ro'yxatni/joylashuvni/maqola yaratishni e'tiborsiz qoldiring. Yordan/ro'yxatga olish/funktsiyalarni ta'kidlashni maqsad qilganman.

0
qo'shib qo'ydi

Hozirgacha men hozirda paydo bo'lgan eng oddiy usul quyidagilar:

Birinchidan, doimo oralig'i deklaratsiyasini tartibga solish uchun funksiya to'plami:

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;

So'ngra fifo uchun yordamchi ta'riflarni o'z ichiga olgan ikkita paket:

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;

va nihoyat fifo modulni to'ldiruvchi shaxs/me'moriy juftlik, bu holda Xilinx 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;

Bu bir oz muammodir, lekin beshta e'lon qilish uchun juda qulay. Har bir boshqa fifo hali o'z versiyasi paketi va shaxsga kerak. Tabiiyki ular bitta faylda bo'lishi mumkin.

Ushbu muammodan so'ng, fifo'nun haqiqiy foydalanish juda oddiy:

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
qo'shib qo'ydi

Hozirgacha men hozirda paydo bo'lgan eng oddiy usul quyidagilar:

Birinchidan, doimo oralig'i deklaratsiyasini tartibga solish uchun funksiya to'plami:

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;

So'ngra fifo uchun yordamchi ta'riflarni o'z ichiga olgan ikkita paket:

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;

va nihoyat fifo modulni to'ldiruvchi shaxs/me'moriy juftlik, bu holda Xilinx 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;

Bu bir oz muammodir, lekin beshta e'lon qilish uchun juda qulay. Har bir boshqa fifo hali o'z versiyasi paketi va shaxsga kerak. Tabiiyki ular bitta faylda bo'lishi mumkin.

Ushbu muammodan so'ng, fifo'nun haqiqiy foydalanish juda oddiy:

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
qo'shib qo'ydi

Hozirgacha men hozirda paydo bo'lgan eng oddiy usul quyidagilar:

Birinchidan, doimo oralig'i deklaratsiyasini tartibga solish uchun funksiya to'plami:

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;

So'ngra fifo uchun yordamchi ta'riflarni o'z ichiga olgan ikkita paket:

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;

va nihoyat fifo modulni to'ldiruvchi shaxs/me'moriy juftlik, bu holda Xilinx 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;

Bu bir oz muammodir, lekin beshta e'lon qilish uchun juda qulay. Har bir boshqa fifo hali o'z versiyasi paketi va shaxsga kerak. Tabiiyki ular bitta faylda bo'lishi mumkin.

Ushbu muammodan so'ng, fifo'nun haqiqiy foydalanish juda oddiy:

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
qo'shib qo'ydi