1-------------------------------------------------------------------------------
2-- Title      : Wishbone Packet Fabric buffered packet sink
3-- Project    : WR Cores Collection
4-------------------------------------------------------------------------------
5-- File       : xwb_fabric_sink.vhd
6-- Author     : Tomasz Wlostowski
7-- Company    : CERN BE-CO-HT
8-- Created    : 2012-01-16
9-- Last update: 2012-01-22
10-- Platform   :
11-- Standard   : VHDL'93
12-------------------------------------------------------------------------------
13-- Description: A simple WB packet streaming sink with builtin FIFO buffer.
14-- Outputs a trivial interface (start-of-packet, end-of-packet, data-valid)
15-------------------------------------------------------------------------------
16--
17-- Copyright (c) 2011 CERN
18--
19-- This source file is free software; you can redistribute it
20-- and/or modify it under the terms of the GNU Lesser General
21-- Public License as published by the Free Software Foundation;
22-- either version 2.1 of the License, or (at your option) any
23-- later version.
24--
25-- This source is distributed in the hope that it will be
26-- useful, but WITHOUT ANY WARRANTY; without even the implied
27-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
28-- PURPOSE.  See the GNU Lesser General Public License for more
29-- details.
30--
31-- You should have received a copy of the GNU Lesser General
32-- Public License along with this source; if not, download it
33-- from http://www.gnu.org/licenses/lgpl-2.1.html
34--
35-------------------------------------------------------------------------------
36-- Revisions  :
37-- Date        Version  Author          Description
38-- 2011-01-16  1.0      twlostow        Created
39-------------------------------------------------------------------------------
40
41library ieee;
42use ieee.std_logic_1164.all;
43
44use work.genram_pkg.all;
45use work.wr_fabric_pkg.all;
46
47entity xwb_fabric_sink is
48
49  port (
50    clk_i   : in std_logic;
51    rst_n_i : in std_logic;
52
53    -- Wishbone Fabric Interface I/O
54    snk_i : in  t_wrf_sink_in;
55    snk_o : out t_wrf_sink_out;
56
57    -- Decoded & buffered fabric
58    addr_o    : out std_logic_vector(1 downto 0);
59    data_o    : out std_logic_vector(15 downto 0);
60    dvalid_o  : out std_logic;
61    sof_o     : out std_logic;
62    eof_o     : out std_logic;
63    error_o   : out std_logic;
64    bytesel_o : out std_logic;
65    dreq_i    : in  std_logic
66    );
67
68end xwb_fabric_sink;
69
70architecture rtl of xwb_fabric_sink is
71
72  constant c_fifo_width : integer := 16 + 2 + 4;
73
74  signal q_valid, full, we, rd : std_logic;
75  signal fin, fout, fout_reg   : std_logic_vector(c_fifo_width-1 downto 0);
76  signal cyc_d0, rd_d0         : std_logic;
77
78  signal pre_sof, pre_eof, pre_bytesel, pre_dvalid : std_logic;
79  signal post_sof, post_dvalid                     : std_logic;
80  signal post_addr                                 : std_logic_vector(1 downto 0);
81  signal post_data                                 : std_logic_vector(15 downto 0);
82
83  signal snk_out : t_wrf_sink_out;
84
85begin  -- rtl
86
87
88  p_delay_cyc_and_rd : process(clk_i)
89  begin
90    if rising_edge(clk_i) then
91      if rst_n_i = '0' then
92        cyc_d0 <= '0';
93        rd_d0  <= '0';
94      else
95        if(full = '0') then
96          cyc_d0 <= snk_i.cyc;
97        end if;
98
99        rd_d0 <= rd;
100      end if;
101    end if;
102  end process;
103
104
105  pre_sof     <= snk_i.cyc and not cyc_d0;  -- sof
106  pre_eof     <= not snk_i.cyc and cyc_d0;  -- eof
107  pre_bytesel <= not snk_i.sel(0);      -- bytesel
108  pre_dvalid  <= snk_i.stb and snk_i.we and snk_i.cyc and not snk_out.stall;  -- data valid
109
110  fin(15 downto 0)  <= snk_i.dat;
111  fin(17 downto 16) <= snk_i.adr;
112  fin(21 downto 18) <= pre_sof & pre_eof & pre_bytesel & pre_dvalid;
113
114
115  snk_out.stall <= full or (snk_i.cyc and not cyc_d0);
116  snk_out.err   <= '0';
117  snk_out.rty   <= '0';
118
119  p_gen_ack : process(clk_i)
120  begin
121    if rising_edge(clk_i) then
122      if rst_n_i = '0' then
123        snk_out.ack <= '0';
124      else
125        snk_out.ack <= snk_i.cyc and snk_i.stb and snk_i.we and not snk_out.stall;
126      end if;
127    end if;
128  end process;
129
130  snk_o <= snk_out;
131
132  we <= '1' when fin(21 downto 18) /= "0000" and full = '0' else '0';
133  rd <= q_valid and dreq_i and not post_sof;
134
135  U_FIFO : generic_shiftreg_fifo
136    generic map (
137      g_data_width => c_fifo_width,
138      g_size       => 16)
139    port map (
140      rst_n_i       => rst_n_i,
141      clk_i         => clk_i,
142      d_i           => fin,
143      we_i          => we,
144      q_o           => fout,
145      rd_i          => rd,
146      almost_full_o => full,
147      q_valid_o     => q_valid);
148
149  p_fout_reg : process(clk_i)
150  begin
151    if rising_edge(clk_i) then
152      if rst_n_i = '0' then
153        fout_reg <= (others => '0');
154      elsif(rd = '1') then
155        fout_reg <= fout;
156      end if;
157    end if;
158  end process;
159
160
161  post_data <= fout_reg(15 downto 0);
162  post_addr <= fout_reg(17 downto 16);
163  post_sof  <= fout_reg(21) and rd_d0; --and q_valid;
164
165  post_dvalid <= fout_reg(18);
166
167  sof_o     <= post_sof and rd_d0;
168  dvalid_o  <= post_dvalid and rd_d0;
169  error_o   <= '1' when rd_d0 = '1' and (post_addr = c_WRF_STATUS) and (f_unmarshall_wrf_status(post_data).error = '1') else '0';
170  eof_o     <= fout_reg(20) and rd_d0;
171  bytesel_o <= fout_reg(19);
172  data_o    <= post_data;
173  addr_o    <= post_addr;
174
175
176end rtl;
177
178library ieee;
179use ieee.std_logic_1164.all;
180
181use work.genram_pkg.all;
182use work.wr_fabric_pkg.all;
183
184
185entity wb_fabric_sink is
186
187  port (
188    clk_i   : in std_logic;
189    rst_n_i : in std_logic;
190
191    snk_dat_i   : in  std_logic_vector(15 downto 0);
192    snk_adr_i   : in  std_logic_vector(1 downto 0);
193    snk_sel_i   : in  std_logic_vector(1 downto 0);
194    snk_cyc_i   : in  std_logic;
195    snk_stb_i   : in  std_logic;
196    snk_we_i    : in  std_logic;
197    snk_stall_o : out std_logic;
198    snk_ack_o   : out std_logic;
199    snk_err_o   : out std_logic;
200    snk_rty_o   : out std_logic;
201
202    -- Decoded & buffered fabric
203    addr_o    : out std_logic_vector(1 downto 0);
204    data_o    : out std_logic_vector(15 downto 0);
205    dvalid_o  : out std_logic;
206    sof_o     : out std_logic;
207    eof_o     : out std_logic;
208    error_o   : out std_logic;
209    bytesel_o : out std_logic;
210    dreq_i    : in  std_logic
211    );
212
213end wb_fabric_sink;
214
215architecture wrapper of wb_fabric_sink is
216
217  component xwb_fabric_sink
218    port (
219      clk_i     : in  std_logic;
220      rst_n_i   : in  std_logic;
221      snk_i     : in  t_wrf_sink_in;
222      snk_o     : out t_wrf_sink_out;
223      addr_o    : out std_logic_vector(1 downto 0);
224      data_o    : out std_logic_vector(15 downto 0);
225      dvalid_o  : out std_logic;
226      sof_o     : out std_logic;
227      eof_o     : out std_logic;
228      error_o   : out std_logic;
229      bytesel_o : out std_logic;
230      dreq_i    : in  std_logic);
231  end component;
232
233  signal snk_in  : t_wrf_sink_in;
234  signal snk_out : t_wrf_sink_out;
235
236begin  -- wrapper
237
238  U_Wrapped_Sink : xwb_fabric_sink
239    port map (
240      clk_i     => clk_i,
241      rst_n_i   => rst_n_i,
242      snk_i     => snk_in,
243      snk_o     => snk_out,
244      addr_o    => addr_o,
245      data_o    => data_o,
246      dvalid_o  => dvalid_o,
247      sof_o     => sof_o,
248      eof_o     => eof_o,
249      error_o   => error_o,
250      bytesel_o => bytesel_o,
251      dreq_i    => dreq_i);
252
253  snk_in.adr <= snk_adr_i;
254  snk_in.dat <= snk_dat_i;
255  snk_in.stb <= snk_stb_i;
256  snk_in.we  <= snk_we_i;
257  snk_in.cyc <= snk_cyc_i;
258  snk_in.sel <= snk_sel_i;
259
260  snk_stall_o <= snk_out.stall;
261  snk_ack_o   <= snk_out.ack;
262  snk_err_o   <= snk_out.err;
263  snk_rty_o   <= snk_out.rty;
264
265end wrapper;
266