首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在VHDL/FPGA中有没有简单的方法在fifos中写入/读取记录?

在VHDL/FPGA中有没有简单的方法在fifos中写入/读取记录?
EN

Stack Overflow用户
提问于 2017-03-15 19:48:15
回答 3查看 1K关注 0票数 1

假设一个先进先出具有记录类型输入和输出,有没有一种简单的方法来处理先进先出包装器的输入和输出中的记录类型与实际先进先出中的std_logic_vector之间的映射?

EN

回答 3

Stack Overflow用户

发布于 2017-04-02 09:14:07

如上所述,您可以将对话隐藏在包中。所以你有两个函数去FIFO接口和从FIFO接口到记录。

Rob Gaddi ( IEEE WG for VHDL的副主席)曾经介绍了一组帮助程序,用于更快地将std_logic_vectors打包到记录类型和从记录类型解包。查看他的proposed pack and unpack subprograms

工作组本身已经就如何解决这一问题进行了长时间的讨论。有3种可能性:

  • VHDL支持实体声明的泛型类型。因此,一个符合VHDL2008标准的综合工具可以创建一个通用的先进先出,它可以接受任何类型*)作为一个先进先出,element.
  • VHDL-2017增加了一个至少可以解决从记录到std_logic_vector的对话的reflection API。我正在研究如何实现相反的路径。
  • 还没有找到迭代记录元素的直接解决方案,被推迟到下一个修订版(VHDL2020)

*)任何可合成的标量、数组或记录类型。

票数 1
EN

Stack Overflow用户

发布于 2017-03-15 19:48:15

到目前为止,我能想到的最简单的方法如下:

首先是一个整理常量范围声明的函数包:

代码语言:javascript
复制
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;

然后是包含fifo帮助器定义的两个包:

代码语言:javascript
复制
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模块的实体/体系结构对,在本例中是Xilinx xpm:

代码语言:javascript
复制
    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的实际使用非常简单:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2017-03-20 21:26:36

简而言之..。

代码语言:javascript
复制
-- 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;

忽略列表/位置/项目的创建。过程/记录/函数是我想要强调的内容。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42808880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档