Newer
Older
--------------------------------------------------------------------------------

Dimitris Lampridis
committed
-- CERN BE-CO-HT
-- GN4124 core for PCIe FMC carrier
-- http://www.ohwr.org/projects/gn4124-core
--------------------------------------------------------------------------------
--

Dimitris Lampridis
committed
-- unit name: gn4124_core

Dimitris Lampridis
committed
-- description: GN4124 core top level. Version for spartan6 FPGAs.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

Dimitris Lampridis
committed
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gencores_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
--==============================================================================
-- Entity declaration for GN4124 core (gn4124_core)
--==============================================================================
entity gn4124_core is
-- If TRUE, enable the DMA interface
g_WITH_DMA : boolean := TRUE;
-- Tunable size and threshold for all async FIFOs.
-- If not sure, leave the defaults.
g_WBM_TO_WB_FIFO_SIZE : positive := 128;
g_WBM_TO_WB_FIFO_FULL_THRES : positive := 110;
g_WBM_FROM_WB_FIFO_SIZE : positive := 128;
g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110;
g_P2L_FIFO_SIZE : positive := 64;
g_L2P_FIFO_SIZE : positive := 256;
g_L2P_FIFO_FULL_THRES : positive := 64;
-- Wishbone ACK timeout (in wishbone clock cycles)
g_ACK_TIMEOUT : positive := 100);
port (
---------------------------------------------------------
-- Control and status
rst_n_a_i : in std_logic; -- Asynchronous reset from GN4124
status_o : out std_logic_vector(31 downto 0); -- Core status output
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
-- P2L Control
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
-- L2P Control
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
---------------------------------------------------------
-- Interrupt interface
dma_irq_o : out std_logic; -- Interrupt source to IRQ manager
irq_p_i : in std_logic; -- Interrupt request pulse from IRQ manager
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
---------------------------------------------------------
-- DMA registers wishbone interface (slave classic)
dma_reg_rst_n_i : in std_logic;
dma_reg_clk_i : in std_logic;
dma_reg_adr_i : in std_logic_vector(31 downto 0);
dma_reg_dat_i : in std_logic_vector(31 downto 0);
dma_reg_sel_i : in std_logic_vector(3 downto 0);
dma_reg_stb_i : in std_logic;
dma_reg_we_i : in std_logic;
dma_reg_cyc_i : in std_logic;
dma_reg_dat_o : out std_logic_vector(31 downto 0);
dma_reg_ack_o : out std_logic;
dma_reg_stall_o : out std_logic;
---------------------------------------------------------
-- CSR wishbone interface (master pipelined)
csr_rst_n_i : in std_logic;
csr_clk_i : in std_logic;
csr_adr_o : out std_logic_vector(31 downto 0);
csr_dat_o : out std_logic_vector(31 downto 0);
csr_sel_o : out std_logic_vector(3 downto 0);
csr_stb_o : out std_logic;
csr_we_o : out std_logic;
csr_cyc_o : out std_logic;
csr_dat_i : in std_logic_vector(31 downto 0);
csr_ack_i : in std_logic;
csr_stall_i : in std_logic;
csr_err_i : in std_logic := '0';
csr_rty_i : in std_logic := '0'; -- not used internally
---------------------------------------------------------
-- DMA wishbone interface (master pipelined)
dma_rst_n_i : in std_logic;
dma_clk_i : in std_logic;
dma_adr_o : out std_logic_vector(31 downto 0);
dma_dat_o : out std_logic_vector(31 downto 0);
dma_sel_o : out std_logic_vector(3 downto 0);
dma_stb_o : out std_logic;
dma_we_o : out std_logic;
dma_cyc_o : out std_logic;
dma_dat_i : in std_logic_vector(31 downto 0);
dma_ack_i : in std_logic;
dma_stall_i : in std_logic;
dma_err_i : in std_logic := '0'; -- not used internally
dma_rty_i : in std_logic := '0' -- not used internally
);
end gn4124_core;
--==============================================================================
-- Architecture declaration for GN4124 core (gn4124_core)
--==============================================================================
architecture rtl of gn4124_core is
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
-- Clock
signal sys_clk : std_logic;
signal io_clk : std_logic;
signal serdes_strobe : std_logic;
signal p2l_pll_locked : std_logic;
signal arst_logic_in : std_logic;

Dimitris Lampridis
committed
attribute keep : string;
attribute keep of sys_clk : signal is "TRUE";
attribute keep of io_clk : signal is "TRUE";
signal arst_pll : std_logic;
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
-------------------------------------------------------------
-- P2L DataPath (from deserializer to packet decoder)
-------------------------------------------------------------
signal des_pd_valid : std_logic;
signal des_pd_dframe : std_logic;
signal des_pd_data : std_logic_vector(31 downto 0);
-- Local bus control
signal p2l_rdy_wbm : std_logic;
signal p2l_rdy_pdm : std_logic;
-------------------------------------------------------------
-- P2L DataPath (from packet decoder to Wishbone master and P2L DMA master)
-------------------------------------------------------------
signal p2l_hdr_start : std_logic;
signal p2l_hdr_length : std_logic_vector(9 downto 0);
signal p2l_hdr_cid : std_logic_vector(1 downto 0);
signal p2l_hdr_last : std_logic;
signal p2l_hdr_stat : std_logic_vector(1 downto 0);
signal p2l_target_mrd : std_logic;
signal p2l_target_mwr : std_logic;
signal p2l_master_cpld : std_logic;
signal p2l_master_cpln : std_logic;
signal p2l_d_valid : std_logic;
signal p2l_d_last : std_logic;
signal p2l_d : std_logic_vector(31 downto 0);
signal p2l_be : std_logic_vector(3 downto 0);
signal p2l_addr : std_logic_vector(31 downto 0);
signal p2l_addr_start : std_logic;
-------------------------------------------------------------
-- L2P DataPath (from arbiter to serializer)
-------------------------------------------------------------
signal arb_ser_valid : std_logic;
signal arb_ser_dframe : std_logic;
signal arb_ser_data : std_logic_vector(31 downto 0);
-- Local bus control
signal l_wr_rdy_t : std_logic;
signal l_wr_rdy : std_logic;
signal p_rd_d_rdy_t : std_logic;
signal p_rd_d_rdy : std_logic;
signal l2p_rdy : std_logic;
signal l2p_edb : std_logic;
signal l2p_edb_d1 : std_logic;
signal l2p_edb_d2 : std_logic;
signal tx_error : std_logic;
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
-------------------------------------------------------------
-- CSR wishbone master to arbiter
-------------------------------------------------------------
signal wbm_arb_valid : std_logic;
signal wbm_arb_dframe : std_logic;
signal wbm_arb_data : std_logic_vector(31 downto 0);
signal wbm_arb_req : std_logic;
signal arb_wbm_gnt : std_logic;
-------------------------------------------------------------
-- L2P DMA master to arbiter
-------------------------------------------------------------
signal ldm_arb_req : std_logic;
signal arb_ldm_gnt : std_logic;
signal ldm_arb_valid : std_logic;
signal ldm_arb_dframe : std_logic;
signal ldm_arb_data : std_logic_vector(31 downto 0);
-------------------------------------------------------------
-- P2L DMA master to arbiter
-------------------------------------------------------------
signal pdm_arb_valid : std_logic;
signal pdm_arb_dframe : std_logic;
signal pdm_arb_data : std_logic_vector(31 downto 0);
signal pdm_arb_req : std_logic;
signal arb_pdm_gnt : std_logic;
-------------------------------------------------------------
-- DMA controller
-------------------------------------------------------------
signal dma_ctrl_carrier_addr : std_logic_vector(31 downto 0);
signal dma_ctrl_host_addr_h : std_logic_vector(31 downto 0);
signal dma_ctrl_host_addr_l : std_logic_vector(31 downto 0);
signal dma_ctrl_len : std_logic_vector(31 downto 0);
signal dma_ctrl_start_l2p : std_logic;
signal dma_ctrl_start_p2l : std_logic;
signal dma_ctrl_start_next : std_logic;
signal dma_ctrl_direction : std_logic;
signal dma_ctrl_direction_d : std_logic;
signal dma_ctrl_done : std_logic;
signal dma_ctrl_error : std_logic;
signal dma_ctrl_l2p_done : std_logic;
signal dma_ctrl_l2p_error : std_logic;
signal dma_ctrl_p2l_done : std_logic;
signal dma_ctrl_p2l_error : std_logic;
signal dma_ctrl_byte_swap : std_logic_vector(1 downto 0);
signal dma_ctrl_abort : std_logic;
signal next_item_carrier_addr : std_logic_vector(31 downto 0);
signal next_item_host_addr_h : std_logic_vector(31 downto 0);
signal next_item_host_addr_l : std_logic_vector(31 downto 0);
signal next_item_len : std_logic_vector(31 downto 0);
signal next_item_next_l : std_logic_vector(31 downto 0);
signal next_item_next_h : std_logic_vector(31 downto 0);
signal next_item_attrib : std_logic_vector(31 downto 0);
signal next_item_valid : std_logic;
signal dma_irq : std_logic;
------------------------------------------------------------------------------
-- CSR wishbone bus
------------------------------------------------------------------------------
signal csr_adr : std_logic_vector(30 downto 0);
------------------------------------------------------------------------------
-- DMA wishbone bus
------------------------------------------------------------------------------
signal l2p_dma_in : t_wishbone_master_in;
signal l2p_dma_out : t_wishbone_master_out;
signal p2l_dma_in : t_wishbone_master_in;
signal p2l_dma_out : t_wishbone_master_out;
--==============================================================================
-- Architecture begin (gn4124_core)
--==============================================================================
begin
------------------------------------------------------------------------------
-- Status output assignment
------------------------------------------------------------------------------
status_o(0) <= p2l_pll_locked;
status_o(31 downto 1) <= (others => '0');
------------------------------------------------------------------------------
-- Clock Input. Generate ioclocks and system clock via BUFPLL
------------------------------------------------------------------------------
cmp_clk_in : entity work.serdes_1_to_n_clk_pll_s2_diff
generic map(
CLKIN_PERIOD => 5.000,
PLLD => 1,
PLLX => 2,
S => 2,
BS => false)
port map (
clkin_p => p2l_clk_p_i,
clkin_n => p2l_clk_n_i,
rxioclk => io_clk,
pattern1 => "10",
pattern2 => "10",
rx_serdesstrobe => serdes_strobe,
rx_bufg_pll_x1 => sys_clk,
bitslip => open,
reset => arst_pll,
rx_bufpll_lckd => p2l_pll_locked);
------------------------------------------------------------------------------
-- Reset aligned to core clock
------------------------------------------------------------------------------
arst_logic_in <= not p2l_pll_locked;
cmp_core_rst_sync : gc_reset_multi_aasd
generic map (
g_CLOCKS => 1,
g_RST_LEN => 16)
arst_i => arst_logic_in,
clks_i(0) => sys_clk,
rst_n_o(0) => sys_rst_n);
-- Always active high reset for PLL and SERDES
arst_pll <= not(rst_n_a_i);
------------------------------------------------------------------------------
-- IRQ pulse forward to GN4124 GPIO
------------------------------------------------------------------------------
irq_p_o <= irq_p_i;
--============================================================================
-- P2L DataPath
--============================================================================
-----------------------------------------------------------------------------
-- p2l_des: Deserialize the P2L DDR inputs
-----------------------------------------------------------------------------
cmp_p2l_des : entity work.p2l_des
port map
(
---------------------------------------------------------
-- Clocks and reset
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
sys_clk_i => sys_clk,
io_clk_i => io_clk,
serdes_strobe_i => serdes_strobe,
---------------------------------------------------------
-- P2L DDR inputs
p2l_valid_i => p2l_valid_i,
p2l_dframe_i => p2l_dframe_i,
p2l_data_i => p2l_data_i,
---------------------------------------------------------
-- P2L SDR outputs
p2l_valid_o => des_pd_valid,
p2l_dframe_o => des_pd_dframe,
p2l_data_o => des_pd_data
);
------------------------------------------------------------------------------
-- P2L local bus control signals
------------------------------------------------------------------------------
-- de-asserted to pause transfer from GN4124
p2l_rdy_o <= p2l_rdy_wbm and p2l_rdy_pdm;
-----------------------------------------------------------------------------
-- p2l_decode32: Decode the output of the p2l_des
-----------------------------------------------------------------------------
cmp_p2l_decode32 : entity work.p2l_decode32
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => sys_clk,
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
---------------------------------------------------------
-- Input from the Deserializer
--
des_p2l_valid_i => des_pd_valid,
des_p2l_dframe_i => des_pd_dframe,
des_p2l_data_i => des_pd_data,
---------------------------------------------------------
-- Decoder Outputs
--
-- Header
p2l_hdr_start_o => p2l_hdr_start,
p2l_hdr_length_o => p2l_hdr_length,
p2l_hdr_cid_o => p2l_hdr_cid,
p2l_hdr_last_o => p2l_hdr_last,
p2l_hdr_stat_o => p2l_hdr_stat,
p2l_target_mrd_o => p2l_target_mrd,
p2l_target_mwr_o => p2l_target_mwr,
p2l_master_cpld_o => p2l_master_cpld,
p2l_master_cpln_o => p2l_master_cpln,
--
-- Address
p2l_addr_start_o => p2l_addr_start,
p2l_addr_o => p2l_addr,
--
-- Data
p2l_d_valid_o => p2l_d_valid,
p2l_d_last_o => p2l_d_last,
p2l_d_o => p2l_d,
p2l_be_o => p2l_be
);
--===========================================================================
-- Core Logic Blocks
--===========================================================================
-----------------------------------------------------------------------------
-- Wishbone master
-----------------------------------------------------------------------------
cmp_wbmaster32 : entity work.wbmaster32
generic map (
g_TO_WB_FIFO_SIZE => g_WBM_TO_WB_FIFO_SIZE,
g_TO_WB_FIFO_FULL_THRES => g_WBM_TO_WB_FIFO_FULL_THRES,
g_FROM_WB_FIFO_SIZE => g_WBM_FROM_WB_FIFO_SIZE,
g_FROM_WB_FIFO_FULL_THRES => g_WBM_FROM_WB_FIFO_FULL_THRES,
g_ACK_TIMEOUT => g_ACK_TIMEOUT)
port map (
---------------------------------------------------------
-- Clock/Reset
clk_i => sys_clk,
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
---------------------------------------------------------
-- From P2L Decoder
--
-- Header
pd_wbm_hdr_start_i => p2l_hdr_start,
pd_wbm_hdr_length_i => p2l_hdr_length,
pd_wbm_hdr_cid_i => p2l_hdr_cid,
pd_wbm_target_mrd_i => p2l_target_mrd,
pd_wbm_target_mwr_i => p2l_target_mwr,
--
-- Address
pd_wbm_addr_start_i => p2l_addr_start,
pd_wbm_addr_i => p2l_addr,
--
-- Data
pd_wbm_data_valid_i => p2l_d_valid,
pd_wbm_data_last_i => p2l_d_last,
pd_wbm_data_i => p2l_d,
pd_wbm_be_i => p2l_be,
---------------------------------------------------------
-- P2L Control
p_wr_rdy_o => p_wr_rdy_o,
p2l_rdy_o => p2l_rdy_wbm,
p_rd_d_rdy_i => p_rd_d_rdy,
---------------------------------------------------------
-- To the L2P Interface
wbm_arb_valid_o => wbm_arb_valid,
wbm_arb_dframe_o => wbm_arb_dframe,
wbm_arb_data_o => wbm_arb_data,
wbm_arb_req_o => wbm_arb_req,
arb_wbm_gnt_i => arb_wbm_gnt,
---------------------------------------------------------
-- Wishbone Interface
wb_rst_n_i => csr_rst_n_i,
wb_clk_i => csr_clk_i,
wb_adr_o => csr_adr,
wb_dat_i => csr_dat_i,
wb_dat_o => csr_dat_o,
wb_sel_o => csr_sel_o,
wb_cyc_o => csr_cyc_o,
wb_stb_o => csr_stb_o,
wb_we_o => csr_we_o,
wb_ack_i => csr_ack_i,
wb_stall_i => csr_stall_i,
wb_err_i => csr_err_i,
wb_rty_i => csr_rty_i
-- Adapt address bus width for top level
csr_adr_o <= '0' & csr_adr;
gen_with_dma: if g_WITH_DMA generate
-----------------------------------------------------------------------------
-- DMA controller
-----------------------------------------------------------------------------
cmp_dma_controller : entity work.dma_controller
port map
(
clk_i => sys_clk,
rst_n_i => sys_rst_n,
dma_ctrl_irq_o => dma_irq,
dma_ctrl_direction_o => dma_ctrl_direction,
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
dma_ctrl_carrier_addr_o => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_o => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_o => dma_ctrl_host_addr_l,
dma_ctrl_len_o => dma_ctrl_len,
dma_ctrl_start_l2p_o => dma_ctrl_start_l2p,
dma_ctrl_start_p2l_o => dma_ctrl_start_p2l,
dma_ctrl_start_next_o => dma_ctrl_start_next,
dma_ctrl_done_i => dma_ctrl_done,
dma_ctrl_error_i => dma_ctrl_error,
dma_ctrl_byte_swap_o => dma_ctrl_byte_swap,
dma_ctrl_abort_o => dma_ctrl_abort,
next_item_carrier_addr_i => next_item_carrier_addr,
next_item_host_addr_h_i => next_item_host_addr_h,
next_item_host_addr_l_i => next_item_host_addr_l,
next_item_len_i => next_item_len,
next_item_next_l_i => next_item_next_l,
next_item_next_h_i => next_item_next_h,
next_item_attrib_i => next_item_attrib,
next_item_valid_i => next_item_valid,
wb_rst_n_i => dma_reg_rst_n_i,
wb_clk_i => dma_reg_clk_i,
wb_adr_i => dma_reg_adr_i(3 downto 0),
wb_dat_o => dma_reg_dat_o,
wb_dat_i => dma_reg_dat_i,
wb_sel_i => dma_reg_sel_i,
wb_cyc_i => dma_reg_cyc_i,
wb_stb_i => dma_reg_stb_i,
wb_we_i => dma_reg_we_i,
wb_ack_o => dma_reg_ack_o
-- DMA registers is a classic wishbone slave supporting single pipelined cycles
dma_reg_stall_o <= '0';
-- Status signals from DMA masters
dma_ctrl_done <= dma_ctrl_l2p_done or dma_ctrl_p2l_done;
dma_ctrl_error <= dma_ctrl_l2p_error or dma_ctrl_p2l_error;
-- Synchronise DMA IRQ to csr_clk_i clock domain
cmp_dma_irq_sync : entity work.gc_sync_ffs
port map(
clk_i => csr_clk_i,
rst_n_i => csr_rst_n_i,
data_i => dma_irq,
synced_o => dma_irq_o
);
-----------------------------------------------------------------------------
-- L2P DMA master (for board to host transfers)
-----------------------------------------------------------------------------
cmp_l2p_dma_master : entity work.l2p_dma_master
generic map (
g_FIFO_FULL_THRES => g_L2P_FIFO_FULL_THRES,
g_FIFO_SIZE => g_L2P_FIFO_SIZE,
g_BYTE_SWAP => TRUE)
port map (
clk_i => sys_clk,
rst_n_i => sys_rst_n,
dma_ctrl_target_addr_i => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_i => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_i => dma_ctrl_host_addr_l,
dma_ctrl_len_i => dma_ctrl_len,
dma_ctrl_start_l2p_i => dma_ctrl_start_l2p,
dma_ctrl_done_o => dma_ctrl_l2p_done,
dma_ctrl_error_o => dma_ctrl_l2p_error,
dma_ctrl_byte_swap_i => dma_ctrl_byte_swap,
dma_ctrl_abort_i => dma_ctrl_abort,
ldm_arb_valid_o => ldm_arb_valid,
ldm_arb_dframe_o => ldm_arb_dframe,
ldm_arb_data_o => ldm_arb_data,
ldm_arb_req_o => ldm_arb_req,
l2p_edb_o => l2p_edb,
l_wr_rdy_i => l_wr_rdy,
l2p_rdy_i => l2p_rdy,
tx_error_i => tx_error,
wb_dma_rst_n_i => dma_rst_n_i,
wb_dma_clk_i => dma_clk_i,
wb_dma_i => l2p_dma_in,
wb_dma_o => l2p_dma_out);
l2p_dma_in.dat <= dma_dat_i;
l2p_dma_in.err <= dma_err_i;
l2p_dma_in.rty <= dma_rty_i;
-----------------------------------------------------------------------------
-- P2L DMA master (for host to board transfers)
-----------------------------------------------------------------------------
cmp_p2l_dma_master : entity work.p2l_dma_master
generic map (
g_FIFO_SIZE => g_P2L_FIFO_SIZE,
g_BYTE_SWAP => TRUE)
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
port map (
clk_i => sys_clk,
rst_n_i => sys_rst_n,
dma_ctrl_carrier_addr_i => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_i => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_i => dma_ctrl_host_addr_l,
dma_ctrl_len_i => dma_ctrl_len,
dma_ctrl_start_p2l_i => dma_ctrl_start_p2l,
dma_ctrl_start_next_i => dma_ctrl_start_next,
dma_ctrl_done_o => dma_ctrl_p2l_done,
dma_ctrl_error_o => dma_ctrl_p2l_error,
dma_ctrl_byte_swap_i => dma_ctrl_byte_swap,
dma_ctrl_abort_i => dma_ctrl_abort,
pd_pdm_hdr_start_i => p2l_hdr_start,
pd_pdm_hdr_length_i => p2l_hdr_length,
pd_pdm_hdr_cid_i => p2l_hdr_cid,
pd_pdm_master_cpld_i => p2l_master_cpld,
pd_pdm_master_cpln_i => p2l_master_cpln,
pd_pdm_data_valid_i => p2l_d_valid,
pd_pdm_data_last_i => p2l_d_last,
pd_pdm_data_i => p2l_d,
pd_pdm_be_i => p2l_be,
p2l_rdy_o => p2l_rdy_pdm,
rx_error_o => rx_error_o,
pdm_arb_valid_o => pdm_arb_valid,
pdm_arb_dframe_o => pdm_arb_dframe,
pdm_arb_data_o => pdm_arb_data,
pdm_arb_req_o => pdm_arb_req,
arb_pdm_gnt_i => arb_pdm_gnt,
wb_dma_rst_n_i => dma_rst_n_i,
wb_dma_clk_i => dma_clk_i,
wb_dma_i => p2l_dma_in,
wb_dma_o => p2l_dma_out,
next_item_carrier_addr_o => next_item_carrier_addr,
next_item_host_addr_h_o => next_item_host_addr_h,
next_item_host_addr_l_o => next_item_host_addr_l,
next_item_len_o => next_item_len,
next_item_next_l_o => next_item_next_l,
next_item_next_h_o => next_item_next_h,
next_item_attrib_o => next_item_attrib,
next_item_valid_o => next_item_valid
);
p2l_dma_in.dat <= dma_dat_i;
p2l_dma_in.err <= dma_err_i;
p2l_dma_in.rty <= dma_rty_i;
-- NOTE: dma_ctrl_direction crosses clock domains.
process (dma_clk_i)
begin
if rising_edge(dma_clk_i) then
dma_ctrl_direction_d <= dma_ctrl_direction;
end if;
end process;
p_dma_wb_mux : process (dma_ack_i, dma_ctrl_direction_d, dma_stall_i,
if dma_ctrl_direction_d = '0' then
dma_adr_o <= l2p_dma_out.adr;
dma_dat_o <= l2p_dma_out.dat;
dma_sel_o <= l2p_dma_out.sel;
dma_cyc_o <= l2p_dma_out.cyc;
dma_stb_o <= l2p_dma_out.stb;
dma_we_o <= l2p_dma_out.we;
l2p_dma_in.ack <= dma_ack_i;
l2p_dma_in.stall <= dma_stall_i;
p2l_dma_in.ack <= '0';
p2l_dma_in.stall <= '0';
dma_adr_o <= p2l_dma_out.adr;
dma_dat_o <= p2l_dma_out.dat;
dma_sel_o <= p2l_dma_out.sel;
dma_cyc_o <= p2l_dma_out.cyc;
dma_stb_o <= p2l_dma_out.stb;
dma_we_o <= p2l_dma_out.we;
p2l_dma_in.ack <= dma_ack_i;
p2l_dma_in.stall <= dma_stall_i;
l2p_dma_in.ack <= '0';
l2p_dma_in.stall <= '0';
end if;
end process p_dma_wb_mux;
end generate gen_with_dma;
gen_without_dma : if not g_WITH_DMA generate
rx_error_o <= '0';
dma_irq_o <= '0';
dma_reg_dat_o <= (others => '0');
dma_adr_o <= (others => '0');
dma_dat_o <= (others => '0');
dma_sel_o <= (others => '0');
ldm_arb_data <= (others => '0');
pdm_arb_data <= (others => '0');
dma_reg_ack_o <= '0';
dma_reg_stall_o <= '0';
dma_stb_o <= '0';
dma_we_o <= '0';
dma_cyc_o <= '0';
p2l_rdy_pdm <= '1';
l2p_edb <= '0';
ldm_arb_req <= '0';
ldm_arb_valid <= '0';
ldm_arb_dframe <= '0';
pdm_arb_req <= '0';
pdm_arb_valid <= '0';
pdm_arb_dframe <= '0';
end generate gen_without_dma;
--===========================================================================
-- L2P DataPath
--===========================================================================
-----------------------------------------------------------------------------
-- Resync GN412x L2P status signals
-----------------------------------------------------------------------------
-- must be checked before l2p_dma_master issues a master write.
-- l2p_dma_master only checks if the signal equals "11", so it is safe to
-- use an AND gate and resync a single bit.
l_wr_rdy_t <= l_wr_rdy_i(1) and l_wr_rdy_i(0);
cmp_sync_l_wr_rdy : gc_sync_ffs
port map (
clk_i => sys_clk,
data_i => l_wr_rdy_t,
synced_o => l_wr_rdy);
-- must be checked before wbmaster32 sends read completion with data
-- wbmaster32 only checks if the signal equals "11", so it is safe to
-- use an AND gate and resync a single bit.
p_rd_d_rdy_t <= p_rd_d_rdy_i(1) and p_rd_d_rdy_i(0);
cmp_sync_p_rd_d_rdy : gc_sync_ffs
port map (
clk_i => sys_clk,
data_i => p_rd_d_rdy_t,
synced_o => p_rd_d_rdy);
-- when de-asserted, l2p_dma_master must stop sending data
-- (de-assert l2p_valid) within 3 (or 7 ?) clock cycles
cmp_sync_l2p_rdy : gc_sync_ffs
port map (
clk_i => sys_clk,
data_i => l2p_rdy_i,
synced_o => l2p_rdy);
-- when asserted, stop dma transfer. Should never be asserted
-- under normal operation conditions!
cmp_sync_tx_error : gc_sync_ffs
port map (
clk_i => sys_clk,
data_i => tx_error_i,
synced_o => tx_error);
-- assert when packet badly ends (e.g. dma abort)
-- delay output by 3 cycles
-- NOTE: this was here before the rehauling of resets and synchronizers.
-- l2p_edb is driven by sys_clk, no need to resync. I left it in order
-- to preserve the sequencing of the outputs. Not sure if it is needed.
p_l2p_edb_d3 : process (sys_clk) is
if rising_edge(sys_clk) then
l2p_edb_d1 <= '0';
l2p_edb_d2 <= '0';
else
l2p_edb_d1 <= l2p_edb;
l2p_edb_d2 <= l2p_edb_d1;
l2p_edb_o <= l2p_edb_d2;
end if;
end process p_l2p_edb_d3;
-----------------------------------------------------------------------------
-- L2P arbiter, arbitrates access to GN4124
-----------------------------------------------------------------------------
cmp_l2p_arbiter : entity work.l2p_arbiter
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => sys_clk,
---------------------------------------------------------
-- From Wishbone master (wbm) to arbiter (arb)
wbm_arb_valid_i => wbm_arb_valid,
wbm_arb_dframe_i => wbm_arb_dframe,
wbm_arb_data_i => wbm_arb_data,
wbm_arb_req_i => wbm_arb_req,
arb_wbm_gnt_o => arb_wbm_gnt,
---------------------------------------------------------
-- From P2L DMA master (pdm) to arbiter (arb)
pdm_arb_valid_i => pdm_arb_valid,
pdm_arb_dframe_i => pdm_arb_dframe,
pdm_arb_data_i => pdm_arb_data,
pdm_arb_req_i => pdm_arb_req,
arb_pdm_gnt_o => arb_pdm_gnt,
---------------------------------------------------------
-- From L2P DMA master (ldm) to arbiter (arb)
ldm_arb_valid_i => ldm_arb_valid,
ldm_arb_dframe_i => ldm_arb_dframe,
ldm_arb_data_i => ldm_arb_data,
ldm_arb_req_i => ldm_arb_req,
arb_ldm_gnt_o => arb_ldm_gnt,
---------------------------------------------------------
-- From arbiter (arb) to serializer (ser)
arb_ser_valid_o => arb_ser_valid,
arb_ser_dframe_o => arb_ser_dframe,
arb_ser_data_o => arb_ser_data
);
-----------------------------------------------------------------------------
-- L2P_SER: Generate the L2P DDR Outputs
-----------------------------------------------------------------------------
cmp_l2p_ser : entity work.l2p_ser
port map
(
---------------------------------------------------------
-- Clocks and reset
sys_clk_i => sys_clk,
io_clk_i => io_clk,
serdes_strobe_i => serdes_strobe,
---------------------------------------------------------
-- L2P SDR inputs
l2p_valid_i => arb_ser_valid,
l2p_dframe_i => arb_ser_dframe,
l2p_data_i => arb_ser_data,
---------------------------------------------------------
-- L2P DDR outputs
l2p_clk_p_o => l2p_clk_p_o,
l2p_clk_n_o => l2p_clk_n_o,
l2p_valid_o => l2p_valid_o,
l2p_dframe_o => l2p_dframe_o,
l2p_data_o => l2p_data_o
);
end rtl;
--==============================================================================
-- Architecture end (gn4124_core)
--==============================================================================