Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/gn4124-core
1 result
Show changes
Commits on Source (87)
Showing
with 1985 additions and 2343 deletions
---
# SPDX-FileCopyrightText: 2024 CERN (home.cern)
#
# SPDX-License-Identifier: BSD-3-Clause
version: '1.0.0'
name: 'Gennum GN4124 core'
description: 'https://ohwr.org/project/gn4124-core/wikis/home'
website: 'https://ohwr.org/project/gn4124-core'
images:
- 'https://ohwr.org/project/gn4124-core/uploads/e1ac973d81801d37c00cb46c666addd3/GN4124core_arch.png'
documentation: 'https://ohwr.org/project/gn4124-core/wikis'
issues: 'https://ohwr.org/project/gn4124-core/issues'
newsfeed: 'https://ohwr.org/project/gn4124-core/wikis/news'
licenses:
- 'CC0-1.0'
forum: 'https://forums.ohwr.org/c/gn4124-core'
..
SPDX-License-Identifier: CC0-1.0
SPDX-FileCopyrightText: 2019-2020 CERN
==========
Change Log
==========
- Format inspired by: `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_
- Versioning scheme follows: `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_
3.1.2 - 2023-11-20
==================
https://www.ohwr.org/project/gn4124-core/tree/v3.1.2
Changed
-------
- hdl: pipeline l2p arbiter outputs to relax timing (#3)
- hdl: simplify l2p_dma_master FIFO reset logic (#4)
3.1.1 - 2022-11-03
==================
https://www.ohwr.org/project/gn4124-core/tree/v3.1.1
Fixed
-----
- hdl: adjust component
3.1.0 - 2020-11-09
==================
https://www.ohwr.org/project/gn4124-core/tree/v3.1.0
Fixed
-----
- hdl: L2P DMA cross page issue
- hdl: L2P incorrect handling of stall signal
- hdl: P2L allow transfer longer than 4KB
3.0.1 - 2020-09-29
==================
https://www.ohwr.org/project/gn4124-core/tree/v3.0.1
Fixed
-----
- hdl: L2P DMA issues reported with slower hosts
3.0.0 - 2020-07-27
==================
https://www.ohwr.org/project/gn4124-core/tree/v3.0.0
Added
-----
- hdl: SystemVerilog BFM and testbench.
- hdl: Add wrapper with wishbone records and slave adapters.
- hdl: Add generics to tune the depths of the various async FIFOs.
Changed
-------
- hdl: Major rewrite of DMA engine, in particular the L2P DMA Master.
- hdl: Major cleanup of resets and cross-clock domain synchronisation.
- hdl: Stop using coregen FIFOs, switch to FIFOs from general-cores.
- hdl: Make DMA optional (g_WITH_DMA generic).
- hdl: Use cheby to describe registers, only one interrupt (level).
- hdl: Test, verify and enable byte swap feature.
- hdl: Extend SV BFM with tasks to read/write from simulated host memory.
Fixed
-----
- hdl: Fixed incorrect 64-bit DMA transaction generation bug.
- hdl: Allow larger DMA reads (up to the full 32 bits of the "length" register) for L2P DMA master.
- hdl: Add flow control to the write buffer of the BFM to prevent overflows during 'wr' commands.
- hdl: Fix swapped bits in attributes.
- hdl: Handle host 32-bit address overflow in L2P DMA master.
- hdl: Fix bug in BFM not respecting P2L_RDY during DMA writes.
- hdl: Fix bug in BFM not accepting 4096B writes.
2.0.0 - 2014-04-03
==================
https://www.ohwr.org/project/gn4124-core/tree/v2.0.0
Added
-----
- Second release of gn4124-core
1.0.0 - 2013-03-01
==================
https://www.ohwr.org/project/gn4124-core/tree/v1.0.0
Added
-----
- First release of gn4124-core
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
# Solderpad Hardware Licence Version 2.0
This licence (the “Licence”) operates as a wraparound licence to the Apache License Version 2.0 (the
“Apache License”) and grants to You the rights, and imposes the obligations, set out in the Apache
License (which can be found here: http://apache.org/licenses/LICENSE-2.0), with the following
extensions. It must be read in conjunction with the Apache License. Section 1 below modifies
definitions in the Apache License, and section 2 below replaces sections 2 of the Apache
License. You may, at your option, choose to treat any Work released under this License as released
under the Apache License (thus ignoring all sections written below entirely). Words in *italics*
indicate changes rom the Apache License, but are indicative and not to be taken into account in
interpretation.
1. The definitions set out in the Apache License are modified as follows:
**Copyright** any reference to ‘copyright’ (whether capitalised or not) includes ‘Rights’ (as
defined below).
**Contribution** also includes any *design*, as well as any work of authorship.
**Derivative Works** shall not include works that remain *reversibly* separable from, or merely link
(or bind by name) or *physically connect* to or *interoperate with* the interfaces of the Work and
Derivative Works thereof.
**Object** form shall mean any form resulting from mechanical transformation or translation of a
Source form or the application of a Source form to physical material, including but not limited to
compiled object code, generated documentation, the *instantiation* of a hardware design or physical
object* and conversions to other media types, *including intermediate forms such as bytecodes, FPGA
bitstreams, moulds, artwork and semiconductor topographies (mask works)*.
**Rights** means copyright and any similar right including design right (whether registered or
unregistered), semiconductor topography (mask) rights and database rights (but excluding Patents and
Trademarks).
**Source** form shall mean the preferred form for making modifications, including but not limited to
source code, *net lists, board layouts, CAD files*, documentation source, and configuration files.
**Work** also includes a *design* or work of authorship, whether in Source form or *other* Object
form.
2. Grant of Licence
2.1 Subject to the terms and conditions of this License, each Contributor hereby grants to You a
perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable license *under the Rights*
to reproduce, prepare Derivative Works of, *make, adapt, repair,* publicly display, publicly perform,
sublicense, and distribute the Work and such Derivative Works in Source or Object form *and do
anything in relation to the Work as if the Rights did not exist*.
if target=="xilinx": if target=="xilinx":
modules = { modules = {
"local" : [ "local" : [
"hdl/gn4124core/rtl", "hdl/rtl",
], ],
} }
if action == "simulation": if action == "simulation":
modules['local'].append("hdl/gn4124core/sim/gn4124_bfm") modules['local'].append("hdl/sim/gn4124_bfm")
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- GN4124 core for PCIe FMC carrier
-- http://www.ohwr.org/projects/gn4124-core
--------------------------------------------------------------------------------
--
-- unit name: dma_controller
--
-- description: Manages the DMA transfers.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2010-2018
--------------------------------------------------------------------------------
-- 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.gn4124_core_pkg.all;
entity dma_controller is
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Interrupt request
dma_ctrl_irq_o : out std_logic_vector(1 downto 0);
---------------------------------------------------------
-- To the L2P DMA master and P2L DMA master
dma_ctrl_carrier_addr_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_o : out std_logic_vector(31 downto 0);
dma_ctrl_len_o : out std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_o : out std_logic; -- To the L2P DMA master
dma_ctrl_start_p2l_o : out std_logic; -- To the P2L DMA master
dma_ctrl_start_next_o : out std_logic; -- To the P2L DMA master
dma_ctrl_byte_swap_o : out std_logic_vector(1 downto 0);
dma_ctrl_abort_o : out std_logic;
dma_ctrl_done_i : in std_logic;
dma_ctrl_error_i : in std_logic;
---------------------------------------------------------
-- From P2L DMA master
next_item_carrier_addr_i : in std_logic_vector(31 downto 0);
next_item_host_addr_h_i : in std_logic_vector(31 downto 0);
next_item_host_addr_l_i : in std_logic_vector(31 downto 0);
next_item_len_i : in std_logic_vector(31 downto 0);
next_item_next_l_i : in std_logic_vector(31 downto 0);
next_item_next_h_i : in std_logic_vector(31 downto 0);
next_item_attrib_i : in std_logic_vector(31 downto 0);
next_item_valid_i : in std_logic;
---------------------------------------------------------
-- Wishbone slave interface
wb_rst_n_i : in std_logic;
wb_clk_i : in std_logic; -- Bus clock
wb_adr_i : in std_logic_vector(3 downto 0); -- Adress
wb_dat_o : out std_logic_vector(31 downto 0); -- Data in
wb_dat_i : in std_logic_vector(31 downto 0); -- Data out
wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wb_cyc_i : in std_logic; -- Read or write cycle
wb_stb_i : in std_logic; -- Read or write strobe
wb_we_i : in std_logic; -- Write
wb_ack_o : out std_logic -- Acknowledge
);
end dma_controller;
architecture behaviour of dma_controller is
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
constant c_IDLE : std_logic_vector(2 downto 0) := "000";
constant c_DONE : std_logic_vector(2 downto 0) := "001";
constant c_BUSY : std_logic_vector(2 downto 0) := "010";
constant c_ERROR : std_logic_vector(2 downto 0) := "011";
constant c_ABORT : std_logic_vector(2 downto 0) := "100";
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
signal dma_ctrl_carrier_addr : std_logic_vector(31 downto 0) := (others => '0');
signal dma_ctrl_host_addr_h : std_logic_vector(31 downto 0) := (others => '0');
signal dma_ctrl_host_addr_l : std_logic_vector(31 downto 0) := (others => '0');
signal dma_ctrl_len : std_logic_vector(31 downto 0) := (others => '0');
-- DMA controller registers
signal dma_ctrl : std_logic_vector(31 downto 0);
signal dma_stat : std_logic_vector(31 downto 0);
signal dma_cstart : std_logic_vector(31 downto 0);
signal dma_hstartl : std_logic_vector(31 downto 0);
signal dma_hstarth : std_logic_vector(31 downto 0);
signal dma_len : std_logic_vector(31 downto 0);
signal dma_nextl : std_logic_vector(31 downto 0);
signal dma_nexth : std_logic_vector(31 downto 0);
signal dma_attrib : std_logic_vector(31 downto 0);
signal dma_ctrl_load : std_logic;
signal dma_stat_load : std_logic;
signal dma_cstart_load : std_logic;
signal dma_hstartl_load : std_logic;
signal dma_hstarth_load : std_logic;
signal dma_len_load : std_logic;
signal dma_nextl_load : std_logic;
signal dma_nexth_load : std_logic;
signal dma_attrib_load : std_logic;
signal dma_ctrl_reg : std_logic_vector(31 downto 0);
signal dma_stat_reg : std_logic_vector(31 downto 0);
signal dma_cstart_reg : std_logic_vector(31 downto 0);
signal dma_hstartl_reg : std_logic_vector(31 downto 0);
signal dma_hstarth_reg : std_logic_vector(31 downto 0);
signal dma_len_reg : std_logic_vector(31 downto 0);
signal dma_nextl_reg : std_logic_vector(31 downto 0);
signal dma_nexth_reg : std_logic_vector(31 downto 0);
signal dma_attrib_reg : std_logic_vector(31 downto 0);
-- DMA controller FSM
type dma_ctrl_state_type is (DMA_IDLE, DMA_START_TRANSFER, DMA_TRANSFER,
DMA_START_CHAIN, DMA_CHAIN,
DMA_ERROR, DMA_ABORT);
signal dma_ctrl_current_state : dma_ctrl_state_type;
-- status signals
signal dma_status : std_logic_vector(2 downto 0);
signal dma_error_irq : std_logic;
signal dma_done_irq : std_logic;
begin
------------------------------------------------------------------------------
-- Wishbone slave instantiation
------------------------------------------------------------------------------
dma_controller_wb_slave_0 : entity work.dma_controller_wb_slave port map (
rst_n_i => wb_rst_n_i,
wb_clk_i => wb_clk_i,
wb_addr_i => wb_adr_i,
wb_data_i => wb_dat_i,
wb_data_o => wb_dat_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
clk_i => clk_i,
dma_ctrl_o => dma_ctrl,
dma_ctrl_i => dma_ctrl_reg,
dma_ctrl_load_o => dma_ctrl_load,
dma_stat_o => open,
dma_stat_i => dma_stat_reg,
dma_stat_load_o => open,
dma_cstart_o => dma_cstart,
dma_cstart_i => dma_cstart_reg,
dma_cstart_load_o => dma_cstart_load,
dma_hstartl_o => dma_hstartl,
dma_hstartl_i => dma_hstartl_reg,
dma_hstartl_load_o => dma_hstartl_load,
dma_hstarth_o => dma_hstarth,
dma_hstarth_i => dma_hstarth_reg,
dma_hstarth_load_o => dma_hstarth_load,
dma_len_o => dma_len,
dma_len_i => dma_len_reg,
dma_len_load_o => dma_len_load,
dma_nextl_o => dma_nextl,
dma_nextl_i => dma_nextl_reg,
dma_nextl_load_o => dma_nextl_load,
dma_nexth_o => dma_nexth,
dma_nexth_i => dma_nexth_reg,
dma_nexth_load_o => dma_nexth_load,
dma_attrib_o => dma_attrib,
dma_attrib_i => dma_attrib_reg,
dma_attrib_load_o => dma_attrib_load
);
------------------------------------------------------------------------------
-- DMA controller registers
------------------------------------------------------------------------------
p_regs : process (clk_i)
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
dma_ctrl_reg <= (others => '0');
dma_stat_reg <= (others => '0');
dma_cstart_reg <= (others => '0');
dma_hstartl_reg <= (others => '0');
dma_hstarth_reg <= (others => '0');
dma_len_reg <= (others => '0');
dma_nextl_reg <= (others => '0');
dma_nexth_reg <= (others => '0');
dma_attrib_reg <= (others => '0');
else
-- Control register
if (dma_ctrl_load = '1') then
dma_ctrl_reg <= dma_ctrl;
end if;
-- Status register
dma_stat_reg(2 downto 0) <= dma_status;
dma_stat_reg(31 downto 3) <= (others => '0');
-- Target start address
if (dma_cstart_load = '1') then
dma_cstart_reg <= dma_cstart;
end if;
-- Host start address lowest 32-bit
if (dma_hstartl_load = '1') then
dma_hstartl_reg <= dma_hstartl;
end if;
-- Host start address highest 32-bit
if (dma_hstarth_load = '1') then
dma_hstarth_reg <= dma_hstarth;
end if;
-- DMA transfer length in byte
if (dma_len_load = '1') then
dma_len_reg <= dma_len;
end if;
-- next item address lowest 32-bit
if (dma_nextl_load = '1') then
dma_nextl_reg <= dma_nextl;
end if;
-- next item address highest 32-bit
if (dma_nexth_load = '1') then
dma_nexth_reg <= dma_nexth;
end if;
-- Chained DMA control
if (dma_attrib_load = '1') then
dma_attrib_reg <= dma_attrib;
end if;
-- next item received => start a new transfer
if (next_item_valid_i = '1') then
dma_ctrl_reg(0) <= '1';
dma_cstart_reg <= next_item_carrier_addr_i;
dma_hstartl_reg <= next_item_host_addr_l_i;
dma_hstarth_reg <= next_item_host_addr_h_i;
dma_len_reg <= next_item_len_i;
dma_nextl_reg <= next_item_next_l_i;
dma_nexth_reg <= next_item_next_h_i;
dma_attrib_reg <= next_item_attrib_i;
end if;
-- Start DMA, 1 tick pulse
if (dma_ctrl_reg(0) = '1') then
dma_ctrl_reg(0) <= '0';
end if;
end if;
end if;
end process p_regs;
dma_ctrl_byte_swap_o <= dma_ctrl_reg(3 downto 2);
------------------------------------------------------------------------------
-- IRQ output assignement
------------------------------------------------------------------------------
dma_ctrl_irq_o <= dma_error_irq & dma_done_irq;
------------------------------------------------------------------------------
-- DMA controller FSM
------------------------------------------------------------------------------
p_fsm : process (clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
dma_ctrl_current_state <= DMA_IDLE;
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
dma_ctrl_start_next_o <= '0';
dma_status <= c_IDLE;
dma_error_irq <= '0';
dma_done_irq <= '0';
dma_ctrl_abort_o <= '0';
else
case dma_ctrl_current_state is
when DMA_IDLE =>
-- Clear done irq to make it 1 tick pulse
dma_done_irq <= '0';
if(dma_ctrl_reg(0) = '1') then
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_START_TRANSFER =>
-- Clear abort signal
dma_ctrl_abort_o <= '0';
if (unsigned(dma_len_reg(31 downto 2)) = 0) then
-- Requesting a DMA of 0 word length gives a error
dma_error_irq <= '1';
dma_ctrl_current_state <= DMA_ERROR;
else
-- Start the DMA if the length is not 0
if (dma_attrib_reg(1) = '0') then
-- L2P transfer (from target to PCIe)
dma_ctrl_start_l2p_o <= '1';
elsif (dma_attrib_reg(1) = '1') then
-- P2L transfer (from PCIe to target)
dma_ctrl_start_p2l_o <= '1';
end if;
dma_ctrl_current_state <= DMA_TRANSFER;
dma_ctrl_carrier_addr <= dma_cstart_reg;
dma_ctrl_host_addr_h <= dma_hstarth_reg;
dma_ctrl_host_addr_l <= dma_hstartl_reg;
dma_ctrl_len <= dma_len_reg;
dma_status <= c_BUSY;
end if;
when DMA_TRANSFER =>
-- Clear start signals, to make them 1 tick pulses
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
if (dma_ctrl_reg(1) = '1') then
-- Transfer aborted
dma_ctrl_current_state <= DMA_ABORT;
elsif(dma_ctrl_error_i = '1') then
-- An error occurs !
dma_error_irq <= '1';
dma_ctrl_current_state <= DMA_ERROR;
elsif(dma_ctrl_done_i = '1') then
-- End of DMA transfer
if(dma_attrib_reg(0) = '1') then
-- More transfer in chained DMA
dma_ctrl_current_state <= DMA_START_CHAIN;
else
-- Was the last transfer
dma_status <= c_DONE;
dma_done_irq <= '1';
dma_ctrl_current_state <= DMA_IDLE;
end if;
end if;
when DMA_START_CHAIN =>
-- Catch the next item in host memory
dma_ctrl_current_state <= DMA_CHAIN;
dma_ctrl_host_addr_h <= dma_nexth_reg;
dma_ctrl_host_addr_l <= dma_nextl_reg;
dma_ctrl_len <= X"0000001C";
dma_ctrl_start_next_o <= '1';
when DMA_CHAIN =>
-- Clear start next signal, to make it 1 tick pulse
dma_ctrl_start_next_o <= '0';
if (dma_ctrl_reg(1) = '1') then
-- Transfer aborted
dma_ctrl_current_state <= DMA_ABORT;
elsif(dma_ctrl_error_i = '1') then
-- An error occurs !
dma_error_irq <= '1';
dma_ctrl_current_state <= DMA_ERROR;
elsif (next_item_valid_i = '1') then
-- next item received
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_ERROR =>
dma_status <= c_ERROR;
-- Clear error irq to make it 1 tick pulse
dma_error_irq <= '0';
if(dma_ctrl_reg(0) = '1') then
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_ABORT =>
dma_status <= c_ABORT;
dma_ctrl_abort_o <= '1';
if(dma_ctrl_reg(0) = '1') then
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when others =>
dma_ctrl_current_state <= DMA_IDLE;
dma_ctrl_carrier_addr <= (others => '0');
dma_ctrl_host_addr_h <= (others => '0');
dma_ctrl_host_addr_l <= (others => '0');
dma_ctrl_len <= (others => '0');
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
dma_ctrl_start_next_o <= '0';
dma_status <= (others => '0');
dma_error_irq <= '0';
dma_done_irq <= '0';
dma_ctrl_abort_o <= '0';
end case;
end if;
end if;
end process p_fsm;
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;
end behaviour;
This diff is collapsed.
This diff is collapsed.
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// GN4124 core for PCIe FMC carrier
// http://www.ohwr.org/projects/gn4124-core
//------------------------------------------------------------------------------
//
// unit name: main
//
// description: This is a simple example testbench, to demonstrate how to use
// the SystemVerilog BFM of the GN4124 to perform simple accesses over wishbone.
//
// The testbench simply connects the wishbone master of the GN4124 to its own
// DMA configuration wishbone slave and attaches a pre-initialised dummy RAM
// with a wishbone interface to the pipelined DMA interface in order to perform
// a DMA read.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// 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.
//------------------------------------------------------------------------------
`timescale 1ns/1ps
`include "gn4124_bfm.svh"
import wishbone_pkg::*;
module main;
reg clk_125m = 0;
logic gn4124_irq;
t_wishbone_master_in wb_in, wb_dma_in, wb_mem_in;
t_wishbone_master_out wb_out, wb_dma_out, wb_mem_out;
always #4ns clk_125m <= ~clk_125m;
logic rst_125m_n;
initial begin
rst_125m_n = 0;
#80ns rst_125m_n = 1;
end
IGN4124PCIMaster i_gn4124 ();
xwb_gn4124_core
DUT (
.rst_n_a_i (i_gn4124.rst_n),
.p2l_clk_p_i (i_gn4124.p2l_clk_p),
.p2l_clk_n_i (i_gn4124.p2l_clk_n),
.p2l_data_i (i_gn4124.p2l_data),
.p2l_dframe_i (i_gn4124.p2l_dframe),
.p2l_valid_i (i_gn4124.p2l_valid),
.p2l_rdy_o (i_gn4124.p2l_rdy),
.p_wr_req_i (i_gn4124.p_wr_req),
.p_wr_rdy_o (i_gn4124.p_wr_rdy),
.rx_error_o (i_gn4124.rx_error),
.vc_rdy_i (i_gn4124.vc_rdy),
.l2p_clk_p_o (i_gn4124.l2p_clk_p),
.l2p_clk_n_o (i_gn4124.l2p_clk_n),
.l2p_data_o (i_gn4124.l2p_data),
.l2p_dframe_o (i_gn4124.l2p_dframe),
.l2p_valid_o (i_gn4124.l2p_valid),
.l2p_edb_o (i_gn4124.l2p_edb),
.l2p_rdy_i (i_gn4124.l2p_rdy),
.l_wr_rdy_i (i_gn4124.l_wr_rdy),
.p_rd_d_rdy_i (i_gn4124.p_rd_d_rdy),
.tx_error_i (i_gn4124.tx_error),
.dma_irq_o (),
.irq_p_i (1'b0),
.irq_p_o (gn4124_irq),
.status_o (),
.wb_master_clk_i (clk_125m),
.wb_master_rst_n_i (rst_125m_n),
.wb_master_i (wb_in),
.wb_master_o (wb_out),
.wb_dma_cfg_clk_i (clk_125m),
.wb_dma_cfg_rst_n_i (rst_125m_n),
.wb_dma_cfg_i (wb_out),
.wb_dma_cfg_o (wb_in),
.wb_dma_dat_clk_i (clk_125m),
.wb_dma_dat_rst_n_i (rst_125m_n),
.wb_dma_dat_i (wb_dma_in),
.wb_dma_dat_o (wb_dma_out)
);
xwb_dpram #
(
.g_size (32),
.g_init_file ("mem_init.bram"),
.g_slave1_interface_mode (1), // 1 = PIPELINED
.g_slave2_interface_mode (1),
.g_slave1_granularity (1), // 1 = WORD
.g_slave2_granularity (1)
)
MEM (
.rst_n_i (1'b1),
.clk_sys_i (clk_125m),
.slave1_i (wb_dma_out),
.slave1_o (wb_dma_in),
.slave2_i (wb_mem_out),
.slave2_o (wb_mem_in)
);
CBusAccessor acc;
task val_check(string name, uint64_t addr, val, expected);
if (val != expected)
begin
$display();
$display("Simulation FAILED");
$fatal(1, "%s error at address 0x%.2x. Expected 0x%.8x, got 0x%.8x",
name, addr, expected, val);
end
$display("%s at address 0x%.2x: 0x%.8x [OK]",
name, addr, val);
endtask // val_check
task reg_check(uint64_t addr, expected);
uint64_t val;
acc.read(addr, val);
val_check("Register read-back", addr, val, expected);
endtask // reg_check
initial begin
uint64_t addr, val, expected;
@(posedge i_gn4124.ready);
acc = i_gn4124.get_accessor();
acc.set_default_xfer_size(4);
@(posedge clk_125m);
// Verify simple read/writes over wishbone
reg_check('h0, 'h0);
acc.write('h10, 'hffacce55);
acc.write('h20, 'h1badcafe);
reg_check('h10, 'hffacce55);
reg_check('h20, 'h1badcafe);
// Reset all DMA config registers
for (addr = 'h00; addr <= 'h20; addr += 4)
begin
acc.write(addr, 'h0);
end
// Perform 32 reads over DMA
acc.write('h14, 'h80);
acc.write('h00, 'h01);
// Check values read from memory
@(posedge i_gn4124.l2p_valid); // skip header
@(posedge i_gn4124.l2p_valid);
for (addr = 'h20; addr > 'h00; addr -= 1)
begin
expected = 64'h80000000 + addr - 1;
val = i_gn4124.l2p_data;
@(posedge i_gn4124.l2p_clk_n);
val |= i_gn4124.l2p_data << 16;
val_check("DMA read-back", 'h20-addr, val, expected);
@(posedge i_gn4124.l2p_clk_p);
end
#1us;
$display();
$display("Simulation PASSED");
$finish;
end
endmodule // main
10000000000000000000000000011111
10000000000000000000000000011110
10000000000000000000000000011101
10000000000000000000000000011100
10000000000000000000000000011011
10000000000000000000000000011010
10000000000000000000000000011001
10000000000000000000000000011000
10000000000000000000000000010111
10000000000000000000000000010110
10000000000000000000000000010101
10000000000000000000000000010100
10000000000000000000000000010011
10000000000000000000000000010010
10000000000000000000000000010001
10000000000000000000000000010000
10000000000000000000000000001111
10000000000000000000000000001110
10000000000000000000000000001101
10000000000000000000000000001100
10000000000000000000000000001011
10000000000000000000000000001010
10000000000000000000000000001001
10000000000000000000000000001000
10000000000000000000000000000111
10000000000000000000000000000110
10000000000000000000000000000101
10000000000000000000000000000100
10000000000000000000000000000011
10000000000000000000000000000010
10000000000000000000000000000001
10000000000000000000000000000000
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- GN4124 core for PCIe FMC carrier
-- http://www.ohwr.org/projects/gn4124-core
--------------------------------------------------------------------------------
--
-- unit name: dma_controller_wb_slave
--
-- description: GN4124 core DMA controller registers block layout (wbgen2)
--
--------------------------------------------------------------------------------
-- Copyright CERN 2010-2018
--------------------------------------------------------------------------------
-- 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.
--------------------------------------------------------------------------------
peripheral {
name = "GN4124 core DMA controller ";
description = "Wishbone slave for the DMA controller of the GN4124 core";
hdl_entity = "dma_controller_wb_slave";
prefix = "dma";
reg {
name = "DMACTRLR";
prefix = "ctrl";
field {
name = "DMA engine control";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMASTATR";
prefix = "stat";
field {
name = "DMA engine status";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMACSTARTR";
prefix = "cstart";
field {
name = "DMA start address in the carrier";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMAHSTARTLR";
prefix = "hstartl";
field {
name = "DMA start address (low) in the host";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMAHSTARTHR";
prefix = "hstarth";
field {
name = "DMA start address (high) in the host";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMALENR";
prefix = "len";
field {
name = "DMA read length in bytes";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMANEXTLR";
prefix = "nextl";
field {
name = "Pointer (low) to next item in list";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMANEXTHR";
prefix = "nexth";
field {
name = "Pointer (high) to next item in list";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
reg {
name = "DMAATTRIBR";
prefix = "attrib";
field {
name = "DMA chain control";
type = SLV;
size = 32;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
clock = "clk_i"
};
};
};
Subproject commit 4e5f7badf0b72f51bdb01c63fcdc6d69afb4b750 Subproject commit 258eb8e00f99f795fe9b98840b01ac4a8b92ec94
files = [ files = [
"dma_controller.vhd", "dma_controller.vhd",
"dma_controller_wb_slave.vhd", "dma_controller_regs.vhd",
"l2p_arbiter.vhd", "l2p_arbiter.vhd",
"l2p_dma_master.vhd", "l2p_dma_master.vhd",
"p2l_decode32.vhd", "p2l_decode32.vhd",
......
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- GN4124 core for PCIe FMC carrier
-- http://www.ohwr.org/projects/gn4124-core
--------------------------------------------------------------------------------
--
-- unit name: dma_controller
--
-- description: Manages the DMA transfers.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2010-2019
--------------------------------------------------------------------------------
-- 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;
entity dma_controller is
port (
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Interrupt request
dma_ctrl_irq_o : out std_logic;
---------------------------------------------------------
-- Used to control the DMA WB mux
dma_ctrl_direction_o : out std_logic;
---------------------------------------------------------
-- To the L2P DMA master and P2L DMA master
dma_ctrl_carrier_addr_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_o : out std_logic_vector(31 downto 0);
dma_ctrl_len_o : out std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_o : out std_logic; -- To the L2P DMA master
dma_ctrl_start_p2l_o : out std_logic; -- To the P2L DMA master
dma_ctrl_start_next_o : out std_logic; -- To the P2L DMA master
dma_ctrl_byte_swap_o : out std_logic_vector(1 downto 0);
dma_ctrl_abort_o : out std_logic;
dma_ctrl_done_i : in std_logic;
dma_ctrl_error_i : in std_logic;
---------------------------------------------------------
-- From P2L DMA master
next_item_carrier_addr_i : in std_logic_vector(31 downto 0);
next_item_host_addr_h_i : in std_logic_vector(31 downto 0);
next_item_host_addr_l_i : in std_logic_vector(31 downto 0);
next_item_len_i : in std_logic_vector(31 downto 0);
next_item_next_l_i : in std_logic_vector(31 downto 0);
next_item_next_h_i : in std_logic_vector(31 downto 0);
next_item_attrib_i : in std_logic_vector(31 downto 0);
next_item_valid_i : in std_logic;
---------------------------------------------------------
-- Wishbone slave interface
wb_rst_n_i : in std_logic;
wb_clk_i : in std_logic; -- Bus clock
wb_adr_i : in std_logic_vector(3 downto 0); -- Adress
wb_dat_o : out std_logic_vector(31 downto 0); -- Data in
wb_dat_i : in std_logic_vector(31 downto 0); -- Data out
wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wb_cyc_i : in std_logic; -- Read or write cycle
wb_stb_i : in std_logic; -- Read or write strobe
wb_we_i : in std_logic; -- Write
wb_ack_o : out std_logic -- Acknowledge
);
end dma_controller;
architecture arch of dma_controller is
-- Values for the STAT register
constant c_DMA_STAT_IDLE : std_logic_vector(1 downto 0) := "00";
constant c_DMA_STAT_BUSY : std_logic_vector(1 downto 0) := "01";
constant c_DMA_STAT_ERROR : std_logic_vector(1 downto 0) := "10";
constant c_DMA_STAT_ABORT : std_logic_vector(1 downto 0) := "11";
-- DMA controller registers
signal dma_ctrl_start_wb : std_logic;
signal dma_ctrl_abort_wb : std_logic;
signal dma_ctrl_wr_wb : std_logic;
signal dma_ctrl_wack_wb : std_logic;
signal dma_ctrl_byte_swap_wb : std_logic_vector(1 downto 0);
signal dma_ctrl_byte_swap : std_logic_vector(1 downto 0);
signal dma_ctrl_start : std_logic;
signal dma_ctrl_abort : std_logic;
signal dma_ctrl_wr : std_logic;
signal dma_async_cstart : std_logic_vector(31 downto 0);
signal dma_async_hstartl : std_logic_vector(31 downto 0);
signal dma_async_hstarth : std_logic_vector(31 downto 0);
signal dma_async_len : std_logic_vector(31 downto 0);
signal dma_async_nextl : std_logic_vector(31 downto 0);
signal dma_async_nexth : std_logic_vector(31 downto 0);
signal dma_async_attrib_chain : std_logic;
signal dma_async_attrib_dir : std_logic;
signal dma_stat_irq_i_wb : std_logic;
signal dma_stat_irq_o_wb : std_logic;
signal dma_stat_status_wb : std_logic_vector(1 downto 0);
signal dma_stat_wr_wb : std_logic;
signal dma_stat_wack_wb : std_logic;
signal dma_stat_rd_wb : std_logic;
signal dma_stat_rack_wb : std_logic;
signal dma_stat_irq_wr_wb : std_logic;
signal dma_stat_irq_wr : std_logic;
signal dma_stat_wr : std_logic;
signal dma_cstart_reg : std_logic_vector(31 downto 0);
signal dma_hstartl_reg : std_logic_vector(31 downto 0);
signal dma_hstarth_reg : std_logic_vector(31 downto 0);
signal dma_len_reg : std_logic_vector(31 downto 0);
signal dma_nextl_reg : std_logic_vector(31 downto 0);
signal dma_nexth_reg : std_logic_vector(31 downto 0);
signal dma_attrib_chain_reg : std_logic;
signal dma_attrib_dir_reg : std_logic;
signal dma_ctrl_byte_swap_reg : std_logic_vector(1 downto 0);
-- DMA controller FSM
type dma_ctrl_state_type is (DMA_IDLE, DMA_START_TRANSFER, DMA_TRANSFER, DMA_CHAIN);
signal dma_ctrl_current_state : dma_ctrl_state_type;
-- status signals
signal dma_stat_reg : std_logic_vector(1 downto 0);
signal dma_irq_reg : std_logic;
-- This signals come from registers clocked by the dma_reg_clk but read by registers clocked
-- by sys_clk. Synchronization is safe because they are read many clocks later (when a DMA
-- is started), assuming the user doesn't modify them...
-- To relax timing constraints, they share a common prefix 'dma_async_'.
attribute keep : string;
attribute keep of dma_async_cstart, dma_async_hstartl, dma_async_hstarth, dma_async_len,
dma_async_nextl, dma_async_nexth, dma_async_attrib_chain, dma_async_attrib_dir : signal is "true";
begin
------------------------------------------------------------------------------
-- Wishbone slave instantiation
------------------------------------------------------------------------------
inst_dma_controller_regs : entity work.dma_controller_regs
port map (
rst_n_i => wb_rst_n_i,
clk_i => wb_clk_i,
wb_adr_i => wb_adr_i,
wb_dat_i => wb_dat_i,
wb_dat_o => wb_dat_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
ctrl_start_o => dma_ctrl_start_wb,
ctrl_start_i => '0',
ctrl_abort_o => dma_ctrl_abort_wb,
ctrl_abort_i => '0',
ctrl_byteswap_o => dma_ctrl_byte_swap_wb,
ctrl_wr_o => dma_ctrl_wr_wb,
ctrl_wack_i => dma_ctrl_wack_wb,
stat_status_o => open,
stat_status_i => dma_stat_status_wb,
stat_irq_i => dma_stat_irq_i_wb,
stat_irq_o => dma_stat_irq_o_wb,
stat_wr_o => dma_stat_wr_wb,
stat_wack_i => dma_stat_wack_wb,
stat_rd_o => dma_stat_rd_wb,
stat_rack_i => dma_stat_rack_wb,
cstart_o => dma_async_cstart,
hstartl_o => dma_async_hstartl,
hstarth_o => dma_async_hstarth,
len_o => dma_async_len,
nextl_o => dma_async_nextl,
nexth_o => dma_async_nexth,
attrib_chain_o => dma_async_attrib_chain,
attrib_dir_o => dma_async_attrib_dir,
cur_cstart_i => dma_cstart_reg,
cur_hstartl_i => dma_hstartl_reg,
cur_hstarth_i => dma_hstarth_reg,
cur_len_i => dma_len_reg);
-- Synchronizers for control.
inst_sync_ctrl : entity work.gc_sync_word_wr
generic map (
g_WIDTH => 4)
port map (
clk_in_i => wb_clk_i,
rst_in_n_i => wb_rst_n_i,
clk_out_i => clk_i,
rst_out_n_i => rst_n_i,
data_i(0) => dma_ctrl_start_wb,
data_i(1) => dma_ctrl_abort_wb,
data_i(3 downto 2) => dma_ctrl_byte_swap_wb,
wr_i => dma_ctrl_wr_wb,
ack_o => dma_ctrl_wack_wb,
data_o(0) => dma_ctrl_start,
data_o(1) => dma_ctrl_abort,
data_o(3 downto 2) => dma_ctrl_byte_swap,
wr_o => dma_ctrl_wr);
dma_stat_irq_wr_wb <= dma_stat_wr_wb and dma_stat_irq_o_wb;
-- Pulse is generated when a '1' is written to the irq bit of the stat reg.
inst_sync_stat_wr : entity work.gc_sync_word_wr
generic map (
g_auto_wr => FALSE,
g_width => 1)
port map (
clk_in_i => wb_clk_i,
rst_in_n_i => wb_rst_n_i,
clk_out_i => clk_i,
rst_out_n_i => rst_n_i,
data_i(0) => dma_stat_irq_wr_wb,
wr_i => dma_stat_wr_wb,
ack_o => dma_stat_wack_wb,
data_o(0) => dma_stat_irq_wr,
wr_o => dma_stat_wr);
-- Sync stat
inst_sync_stat_rd : entity work.gc_sync_word_rd
generic map (
g_WIDTH => 3)
port map (
clk_out_i => wb_clk_i,
rst_out_n_i => wb_rst_n_i,
clk_in_i => clk_i,
rst_in_n_i => rst_n_i,
data_in_i(1 downto 0) => dma_stat_reg,
data_in_i(2) => dma_irq_reg,
rd_out_i => dma_stat_rd_wb,
ack_out_o => dma_stat_rack_wb,
data_out_o(1 downto 0) => dma_stat_status_wb,
data_out_o(2) => dma_stat_irq_i_wb,
rd_in_o => open);
------------------------------------------------------------------------------
-- DMA controller FSM
------------------------------------------------------------------------------
p_fsm : process (clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
dma_ctrl_current_state <= DMA_IDLE;
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
dma_ctrl_start_next_o <= '0';
dma_ctrl_direction_o <= '0';
dma_ctrl_abort_o <= '0';
dma_stat_reg <= c_DMA_STAT_IDLE;
dma_irq_reg <= '0';
dma_cstart_reg <= (others => '0');
dma_hstartl_reg <= (others => '0');
dma_hstarth_reg <= (others => '0');
dma_len_reg <= (others => '0');
dma_nextl_reg <= (others => '0');
dma_nexth_reg <= (others => '0');
dma_ctrl_byte_swap_reg <= "00";
dma_attrib_chain_reg <= '0';
dma_attrib_dir_reg <= '0';
else
-- Clear interrupt when idle status is read.
if dma_stat_irq_wr = '1' and dma_stat_wr = '1' then
dma_irq_reg <= '0';
end if;
case dma_ctrl_current_state is
when DMA_IDLE =>
if (dma_ctrl_wr and dma_ctrl_start) = '1' then
-- Capture parameters
-- All these inputs registers are synchronized on the start pulse.
dma_cstart_reg <= dma_async_cstart;
dma_hstartl_reg <= dma_async_hstartl;
dma_hstarth_reg <= dma_async_hstarth;
dma_len_reg <= dma_async_len;
dma_nextl_reg <= dma_async_nextl;
dma_nexth_reg <= dma_async_nexth;
dma_attrib_chain_reg <= dma_async_attrib_chain;
dma_attrib_dir_reg <= dma_async_attrib_dir;
dma_ctrl_byte_swap_reg <= dma_ctrl_byte_swap;
-- Set it early to ease timing.
dma_ctrl_direction_o <= dma_async_attrib_dir;
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_START_TRANSFER =>
-- Clear abort signal
dma_ctrl_abort_o <= '0';
if unsigned(dma_len_reg(31 downto 2)) = 0 then
-- Requesting a DMA of 0 word length gives a error
dma_irq_reg <= '1';
dma_stat_reg <= c_DMA_STAT_ERROR;
dma_ctrl_current_state <= DMA_IDLE;
else
if dma_attrib_dir_reg = '0' then
-- L2P transfer (from target to PCIe)
dma_ctrl_start_l2p_o <= '1';
dma_ctrl_direction_o <= '0';
else
-- P2L transfer (from PCIe to target)
dma_ctrl_start_p2l_o <= '1';
dma_ctrl_direction_o <= '1';
end if;
dma_stat_reg <= c_DMA_STAT_BUSY;
dma_ctrl_current_state <= DMA_TRANSFER;
end if;
when DMA_TRANSFER =>
-- Clear start signals, to make them 1 tick pulses
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
if (dma_ctrl_abort and dma_ctrl_wr) = '1' then
-- Transfer aborted
dma_ctrl_abort_o <= '1';
dma_stat_reg <= c_DMA_STAT_ABORT;
dma_ctrl_current_state <= DMA_IDLE;
elsif dma_ctrl_error_i = '1' then
-- An error occured
dma_irq_reg <= '1';
dma_stat_reg <= c_DMA_STAT_ERROR;
dma_ctrl_current_state <= DMA_IDLE;
elsif dma_ctrl_done_i = '1' then
-- End of DMA transfer
if dma_attrib_chain_reg = '1' then
-- More transfers in chained DMA
dma_hstarth_reg <= dma_nexth_reg;
dma_hstartl_reg <= dma_nextl_reg;
dma_len_reg <= X"0000001C";
dma_ctrl_start_next_o <= '1';
dma_ctrl_current_state <= DMA_CHAIN;
else
-- Was the last transfer
dma_irq_reg <= '1';
dma_stat_reg <= c_DMA_STAT_IDLE;
dma_ctrl_current_state <= DMA_IDLE;
end if;
end if;
when DMA_CHAIN =>
-- Clear start next signal, to make it 1 tick pulse
dma_ctrl_start_next_o <= '0';
if (dma_ctrl_abort and dma_ctrl_wr) = '1' then
-- Transfer aborted
dma_ctrl_abort_o <= '1';
dma_stat_reg <= c_DMA_STAT_ABORT;
dma_ctrl_current_state <= DMA_IDLE;
elsif dma_ctrl_error_i = '1' then
-- An error occured
dma_irq_reg <= '1';
dma_stat_reg <= c_DMA_STAT_ERROR;
dma_ctrl_current_state <= DMA_IDLE;
elsif next_item_valid_i = '1' then
-- Capture parameters
dma_cstart_reg <= next_item_carrier_addr_i;
dma_hstartl_reg <= next_item_host_addr_l_i;
dma_hstarth_reg <= next_item_host_addr_h_i;
dma_len_reg <= next_item_len_i;
dma_nextl_reg <= next_item_next_l_i;
dma_nexth_reg <= next_item_next_h_i;
dma_attrib_chain_reg <= next_item_attrib_i(1);
dma_attrib_dir_reg <= next_item_attrib_i(0);
-- Next item received
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
end case;
end if;
end if;
end process p_fsm;
dma_ctrl_carrier_addr_o <= dma_cstart_reg;
dma_ctrl_host_addr_h_o <= dma_hstarth_reg;
dma_ctrl_host_addr_l_o <= dma_hstartl_reg;
dma_ctrl_len_o <= dma_len_reg;
dma_ctrl_irq_o <= dma_irq_reg;
dma_ctrl_byte_swap_o <= dma_ctrl_byte_swap_reg;
end architecture arch;
# ------------------------------------------------------------------------------
# CERN BE-CO-HT
# GN4124 core for PCIe FMC carrier
# http://www.ohwr.org/projects/gn4124-core
# ------------------------------------------------------------------------------
#
# unit name: dma_controller_regs
#
# description: GN4124 core DMA controller registers block layout
#
# ------------------------------------------------------------------------------
# Copyright CERN 2010-2019
# ------------------------------------------------------------------------------
# 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.
# ------------------------------------------------------------------------------
memory-map:
bus: wb-32-be
name: dma_controller_regs
description: "GN4124 core DMA controller"
comment: Wishbone slave for the DMA controller of the GN4124 core
children:
- reg:
name: ctrl
address: 0x00000000
width: 32
access: rw
description: DMACTRLR
children:
- field:
name: start
range: 0
comment: Start DMA transfer
description: Write '1' to start a DMA transfer
x-hdl:
type: wire
- field:
name: abort
range: 1
comment: Abort current DMA transfer
description: Write '1' to abort the DMA transfer
x-hdl:
type: wire
- field:
name: byteswap
range: 3-2
description: Control byte-swapping
comment: |
- 00: ABCD -> ABCD
- 01: ABCD -> DCBA
- 10: ABCD -> CDAB
- 11: ABCD -> BADC
x-hdl:
write-strobe: True
write-ack: True
- reg:
name: stat
address: 0x00000004
width: 32
access: rw
description: DMASTATR
children:
- field:
name: status
comment: DMA state
description: |
DMA state:
00: idle
01: busy
10: error
11: abort
range: 1-0
x-hdl:
type: wire
- field:
name: irq
comment: IRQ status, write 1 to clear
range: 2
x-hdl:
type: wire
x-hdl:
write-strobe: True
write-ack: True
read-strobe: True
read-ack: True
- reg:
name: cstart
address: 0x00000008
width: 32
access: rw
comment: DMACSTARTR
description: Carrier start address
- reg:
name: hstartl
address: 0x0000000c
width: 32
access: rw
comment: DMAHSTARTLR
description: DMA start address (low) in the host
- reg:
name: hstarth
address: 0x00000010
width: 32
access: rw
comment: DMAHSTARTHR
description: DMA start address (high) in the host
- reg:
name: len
address: 0x00000014
width: 32
access: rw
comment: DMALENR
description: DMA read length in bytes
- reg:
name: nextl
address: 0x00000018
width: 32
access: rw
comment: DMANEXTLR
description: Pointer (low) to next item in list
- reg:
name: nexth
address: 0x0000001c
width: 32
access: rw
comment: DMANEXTHR
description: Pointer (high) to next item in list
- reg:
name: attrib
address: 0x00000020
width: 32
access: rw
comment: DMAATTRIBR
description: DMA chain control
children:
- field:
name: chain
comment: Transfer chain (if 1)
range: 1
- field:
name: dir
comment: "Transfer direction (0: to host, 1: to carrier)"
range: 0
- reg:
name: cur_cstart
width: 32
access: ro
description: Current carrier start address
- reg:
name: cur_hstartl
width: 32
access: ro
description: Current DMA start address (low) in the host
- reg:
name: cur_hstarth
width: 32
access: ro
description: Current DMA start address (high) in the host
- reg:
name: cur_len
width: 32
access: ro
description: Current DMA read length in bytes
-- Do not edit; this file was generated by Cheby using these options:
-- --gen-hdl=dma_controller_regs.vhd -i dma_controller_regs.cheby
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dma_controller_regs is
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
wb_cyc_i : in std_logic;
wb_stb_i : in std_logic;
wb_adr_i : in std_logic_vector(5 downto 2);
wb_sel_i : in std_logic_vector(3 downto 0);
wb_we_i : in std_logic;
wb_dat_i : in std_logic_vector(31 downto 0);
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
wb_dat_o : out std_logic_vector(31 downto 0);
-- Start DMA transfer
ctrl_start_i : in std_logic;
ctrl_start_o : out std_logic;
-- Abort current DMA transfer
ctrl_abort_i : in std_logic;
ctrl_abort_o : out std_logic;
-- Control byte-swapping
ctrl_byteswap_o : out std_logic_vector(1 downto 0);
ctrl_wr_o : out std_logic;
ctrl_wack_i : in std_logic;
-- DMA state
stat_status_i : in std_logic_vector(1 downto 0);
stat_status_o : out std_logic_vector(1 downto 0);
-- IRQ status, write 1 to clear
stat_irq_i : in std_logic;
stat_irq_o : out std_logic;
stat_wr_o : out std_logic;
stat_rd_o : out std_logic;
stat_wack_i : in std_logic;
stat_rack_i : in std_logic;
-- Carrier start address
cstart_o : out std_logic_vector(31 downto 0);
-- DMA start address (low) in the host
hstartl_o : out std_logic_vector(31 downto 0);
-- DMA start address (high) in the host
hstarth_o : out std_logic_vector(31 downto 0);
-- DMA read length in bytes
len_o : out std_logic_vector(31 downto 0);
-- Pointer (low) to next item in list
nextl_o : out std_logic_vector(31 downto 0);
-- Pointer (high) to next item in list
nexth_o : out std_logic_vector(31 downto 0);
-- Transfer chain (if 1)
attrib_chain_o : out std_logic;
-- Transfer direction (0: to host, 1: to carrier)
attrib_dir_o : out std_logic;
-- Current carrier start address
cur_cstart_i : in std_logic_vector(31 downto 0);
-- Current DMA start address (low) in the host
cur_hstartl_i : in std_logic_vector(31 downto 0);
-- Current DMA start address (high) in the host
cur_hstarth_i : in std_logic_vector(31 downto 0);
-- Current DMA read length in bytes
cur_len_i : in std_logic_vector(31 downto 0)
);
end dma_controller_regs;
architecture syn of dma_controller_regs is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal rd_ack_int : std_logic;
signal wr_ack_int : std_logic;
signal wb_en : std_logic;
signal ack_int : std_logic;
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal ctrl_byteswap_reg : std_logic_vector(1 downto 0);
signal cstart_reg : std_logic_vector(31 downto 0);
signal hstartl_reg : std_logic_vector(31 downto 0);
signal hstarth_reg : std_logic_vector(31 downto 0);
signal len_reg : std_logic_vector(31 downto 0);
signal nextl_reg : std_logic_vector(31 downto 0);
signal nexth_reg : std_logic_vector(31 downto 0);
signal attrib_chain_reg : std_logic;
signal attrib_dir_reg : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
begin
-- WB decode signals
wb_en <= wb_cyc_i and wb_stb_i;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wb_rip <= '0';
else
wb_rip <= (wb_rip or (wb_en and not wb_we_i)) and not rd_ack_int;
end if;
end if;
end process;
rd_int <= (wb_en and not wb_we_i) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wb_wip <= '0';
else
wb_wip <= (wb_wip or (wb_en and wb_we_i)) and not wr_ack_int;
end if;
end if;
end process;
wr_int <= (wb_en and wb_we_i) and not wb_wip;
ack_int <= rd_ack_int or wr_ack_int;
wb_ack_o <= ack_int;
wb_stall_o <= not ack_int and wb_en;
wb_rty_o <= '0';
wb_err_o <= '0';
-- Assign outputs
ctrl_byteswap_o <= ctrl_byteswap_reg;
cstart_o <= cstart_reg;
hstartl_o <= hstartl_reg;
hstarth_o <= hstarth_reg;
len_o <= len_reg;
nextl_o <= nextl_reg;
nexth_o <= nexth_reg;
attrib_chain_o <= attrib_chain_reg;
attrib_dir_o <= attrib_dir_reg;
-- Process for write requests.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
ctrl_wr_o <= '0';
ctrl_byteswap_reg <= "00";
stat_wr_o <= '0';
cstart_reg <= "00000000000000000000000000000000";
hstartl_reg <= "00000000000000000000000000000000";
hstarth_reg <= "00000000000000000000000000000000";
len_reg <= "00000000000000000000000000000000";
nextl_reg <= "00000000000000000000000000000000";
nexth_reg <= "00000000000000000000000000000000";
attrib_chain_reg <= '0';
attrib_dir_reg <= '0';
else
wr_ack_int <= '0';
ctrl_wr_o <= '0';
stat_wr_o <= '0';
case wb_adr_i(5 downto 2) is
when "0000" =>
-- Register ctrl
ctrl_wr_o <= wr_int;
if wr_int = '1' then
ctrl_start_o <= wb_dat_i(0);
ctrl_abort_o <= wb_dat_i(1);
ctrl_byteswap_reg <= wb_dat_i(3 downto 2);
end if;
wr_ack_int <= ctrl_wack_i;
when "0001" =>
-- Register stat
stat_wr_o <= wr_int;
if wr_int = '1' then
stat_status_o <= wb_dat_i(1 downto 0);
stat_irq_o <= wb_dat_i(2);
end if;
wr_ack_int <= stat_wack_i;
when "0010" =>
-- Register cstart
if wr_int = '1' then
cstart_reg <= wb_dat_i;
end if;
wr_ack_int <= wr_int;
when "0011" =>
-- Register hstartl
if wr_int = '1' then
hstartl_reg <= wb_dat_i;
end if;
wr_ack_int <= wr_int;
when "0100" =>
-- Register hstarth
if wr_int = '1' then
hstarth_reg <= wb_dat_i;
end if;
wr_ack_int <= wr_int;
when "0101" =>
-- Register len
if wr_int = '1' then
len_reg <= wb_dat_i;
end if;
wr_ack_int <= wr_int;
when "0110" =>
-- Register nextl
if wr_int = '1' then
nextl_reg <= wb_dat_i;
end if;
wr_ack_int <= wr_int;
when "0111" =>
-- Register nexth
if wr_int = '1' then
nexth_reg <= wb_dat_i;
end if;
wr_ack_int <= wr_int;
when "1000" =>
-- Register attrib
if wr_int = '1' then
attrib_chain_reg <= wb_dat_i(1);
attrib_dir_reg <= wb_dat_i(0);
end if;
wr_ack_int <= wr_int;
when "1001" =>
-- Register cur_cstart
when "1010" =>
-- Register cur_hstartl
when "1011" =>
-- Register cur_hstarth
when "1100" =>
-- Register cur_len
when others =>
wr_ack_int <= wr_int;
end case;
end if;
end if;
end process;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
stat_rd_o <= '0';
else
stat_rd_o <= '0';
reg_rdat_int <= (others => '0');
case wb_adr_i(5 downto 2) is
when "0000" =>
-- ctrl
reg_rdat_int(0) <= ctrl_start_i;
reg_rdat_int(1) <= ctrl_abort_i;
reg_rdat_int(3 downto 2) <= ctrl_byteswap_reg;
rd_ack1_int <= rd_int;
when "0001" =>
-- stat
reg_rdat_int(1 downto 0) <= stat_status_i;
reg_rdat_int(2) <= stat_irq_i;
stat_rd_o <= rd_int;
rd_ack1_int <= stat_rack_i;
when "0010" =>
-- cstart
reg_rdat_int <= cstart_reg;
rd_ack1_int <= rd_int;
when "0011" =>
-- hstartl
reg_rdat_int <= hstartl_reg;
rd_ack1_int <= rd_int;
when "0100" =>
-- hstarth
reg_rdat_int <= hstarth_reg;
rd_ack1_int <= rd_int;
when "0101" =>
-- len
reg_rdat_int <= len_reg;
rd_ack1_int <= rd_int;
when "0110" =>
-- nextl
reg_rdat_int <= nextl_reg;
rd_ack1_int <= rd_int;
when "0111" =>
-- nexth
reg_rdat_int <= nexth_reg;
rd_ack1_int <= rd_int;
when "1000" =>
-- attrib
reg_rdat_int(1) <= attrib_chain_reg;
reg_rdat_int(0) <= attrib_dir_reg;
rd_ack1_int <= rd_int;
when "1001" =>
-- cur_cstart
reg_rdat_int <= cur_cstart_i;
rd_ack1_int <= rd_int;
when "1010" =>
-- cur_hstartl
reg_rdat_int <= cur_hstartl_i;
rd_ack1_int <= rd_int;
when "1011" =>
-- cur_hstarth
reg_rdat_int <= cur_hstarth_i;
rd_ack1_int <= rd_int;
when "1100" =>
-- cur_len
reg_rdat_int <= cur_len_i;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
end process;
-- Process for read requests.
process (wb_adr_i, reg_rdat_int, rd_ack1_int, rd_int) begin
-- By default ack read requests
wb_dat_o <= (others => '0');
case wb_adr_i(5 downto 2) is
when "0000" =>
-- ctrl
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0001" =>
-- stat
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0010" =>
-- cstart
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0011" =>
-- hstartl
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0100" =>
-- hstarth
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0101" =>
-- len
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0110" =>
-- nextl
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0111" =>
-- nexth
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1000" =>
-- attrib
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1001" =>
-- cur_cstart
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1010" =>
-- cur_hstartl
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1011" =>
-- cur_hstarth
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1100" =>
-- cur_len
wb_dat_o <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when others =>
rd_ack_int <= rd_int;
end case;
end process;
end syn;
...@@ -86,6 +86,9 @@ architecture rtl of l2p_arbiter is ...@@ -86,6 +86,9 @@ architecture rtl of l2p_arbiter is
signal arb_ser_valid_t : std_logic; signal arb_ser_valid_t : std_logic;
signal arb_ser_dframe_t : std_logic; signal arb_ser_dframe_t : std_logic;
signal arb_ser_data_t : std_logic_vector(31 downto 0) := (others => '0'); signal arb_ser_data_t : std_logic_vector(31 downto 0) := (others => '0');
signal arb_ser_valid_d : std_logic;
signal arb_ser_dframe_d : std_logic;
signal arb_ser_data_d : std_logic_vector(31 downto 0) := (others => '0');
begin begin
...@@ -174,9 +177,12 @@ begin ...@@ -174,9 +177,12 @@ begin
arb_ser_valid_o <= '0'; arb_ser_valid_o <= '0';
arb_ser_dframe_o <= '0'; arb_ser_dframe_o <= '0';
else else
arb_ser_valid_o <= arb_ser_valid_t; arb_ser_valid_d <= arb_ser_valid_t;
arb_ser_dframe_o <= arb_ser_dframe_t; arb_ser_dframe_d <= arb_ser_dframe_t;
arb_ser_data_o <= arb_ser_data_t; arb_ser_data_d <= arb_ser_data_t;
arb_ser_valid_o <= arb_ser_valid_d;
arb_ser_dframe_o <= arb_ser_dframe_d;
arb_ser_data_o <= arb_ser_data_d;
end if; end if;
end if; end if;
end process; end process;
......
This diff is collapsed.
...@@ -95,7 +95,6 @@ architecture rtl of p2l_decode32 is ...@@ -95,7 +95,6 @@ architecture rtl of p2l_decode32 is
signal des_p2l_dframe_d : std_logic := '0'; signal des_p2l_dframe_d : std_logic := '0';
signal p2l_packet_start : std_logic; signal p2l_packet_start : std_logic;
signal p2l_packet_start_d : std_logic;
signal p2l_packet_end : std_logic; signal p2l_packet_end : std_logic;
signal p2l_addr_cycle : std_logic; signal p2l_addr_cycle : std_logic;
...@@ -113,7 +112,6 @@ architecture rtl of p2l_decode32 is ...@@ -113,7 +112,6 @@ architecture rtl of p2l_decode32 is
signal p2l_addr : unsigned(31 downto 0) := (others => '0'); -- Registered and counting Address signal p2l_addr : unsigned(31 downto 0) := (others => '0'); -- Registered and counting Address
signal p2l_d_valid : std_logic; -- Indicates Address/Data is valid signal p2l_d_valid : std_logic; -- Indicates Address/Data is valid
signal p2l_d_first : std_logic;
signal p2l_d_last : std_logic; -- Indicates end of the packet signal p2l_d_last : std_logic; -- Indicates end of the packet
signal p2l_d : std_logic_vector(31 downto 0) := (others => '0'); -- Address/Data signal p2l_d : std_logic_vector(31 downto 0) := (others => '0'); -- Address/Data
signal p2l_be : std_logic_vector(3 downto 0) := (others => '0'); -- Byte Enable for data signal p2l_be : std_logic_vector(3 downto 0) := (others => '0'); -- Byte Enable for data
......