Skip to content
Snippets Groups Projects

Resolve HPR-87

Merged Reinier van der Walle requested to merge HPR-87 into master
5 unresolved threads
3 files
+ 321
0
Compare changes
  • Side-by-side
  • Inline

Files

+ 219
0
 
-- --------------------------------------------------------------------------
 
-- Copyright 2023
 
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
 
--
 
-- Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
 
--
 
-- Unless required by applicable law or agreed to in writing, software
 
-- distributed under the 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.
 
-- --------------------------------------------------------------------------
 
 
-- Author:
 
-- . Reinier van der Walle
 
-- Purpose:
 
-- . Bridge between AXI4 lite and MM interfaces.
 
-- Description:
 
-- . This core consists of:
 
-- . Combinatorial translation of one interface to the other.
 
-- . Ready latency adapters as AXI4-Lite has RL = 0 and MM has RL = 1.
 
-- . Details:
 
-- . g_active_low_rst should be set to TRUE when in_rst is active low. This is useful as an
 
-- AXI4 interface often comes with an active-low reset while DP comes with an active-high
 
-- reset.
 
 
LIBRARY IEEE, common_lib, dp_lib, technology_lib, mm_lib;
 
USE IEEE.STD_LOGIC_1164.ALL;
 
USE common_lib.common_pkg.ALL;
 
USE common_lib.common_mem_pkg.ALL;
 
USE dp_lib.dp_stream_pkg.ALL;
 
USE work.axi4_stream_pkg.ALL;
 
USE work.axi4_lite_pkg.ALL;
 
 
ENTITY axi4_lite_mm_bridge IS
 
GENERIC (
 
g_active_low_rst : BOOLEAN := FALSE -- When True, in_rst is interpreted as active-low.
 
);
 
PORT (
 
in_clk : IN STD_LOGIC := '0';
 
in_rst : IN STD_LOGIC := is_true(g_active_low_rst); -- Default state is "not in reset".
 
 
aresetn : OUT STD_LOGIC := '1'; -- AXI4 active-low reset
 
mm_rst : OUT STD_LOGIC := '0'; -- MM active-high reset
 
 
-- Translate AXI4 lite to MM
 
axi4_in_copi : IN t_axi4_lite_copi := c_axi4_lite_copi_rst;
    • Liever volgorde bijvoorbeeld zo en met comment, dus zodanig dat ports volgorde meer de functionaliteit volgt:

          -- Translate AXI4 lite to MM
          axi4_in_copi  : IN  t_axi4_lite_copi := c_axi4_lite_copi_rst;
          axi4_in_cipo  : OUT t_axi4_lite_cipo := c_axi4_lite_cipo_rst;
      
          mm_out_copi   : OUT t_mem_copi   := c_mem_copi_rst;
          mm_out_cipo   : IN  t_mem_cipo   := c_mem_cipo_rst;
      
          -- Translate MM to AXI4 lite
          mm_in_copi    : IN  t_mem_copi   := c_mem_copi_rst;
          mm_in_cipo    : OUT t_mem_cipo   := c_mem_cipo_rst;
      
          axi4_out_copi : OUT t_axi4_lite_copi := c_axi4_lite_copi_rst;
          axi4_out_cipo : IN  t_axi4_lite_cipo := c_axi4_lite_cipo_rst;
      
      Edited by Eric Kooistra
Please register or sign in to reply
 
axi4_in_cipo : OUT t_axi4_lite_cipo := c_axi4_lite_cipo_rst;
 
 
mm_out_copi : OUT t_mem_copi := c_mem_copi_rst;
 
mm_out_cipo : IN t_mem_cipo := c_mem_cipo_rst;
 
 
-- Translate MM to AXI4 lite
 
mm_in_copi : IN t_mem_copi := c_mem_copi_rst;
 
mm_in_cipo : OUT t_mem_cipo := c_mem_cipo_rst;
 
 
axi4_out_copi : OUT t_axi4_lite_copi := c_axi4_lite_copi_rst;
 
axi4_out_cipo : IN t_axi4_lite_cipo := c_axi4_lite_cipo_rst
 
);
 
END axi4_lite_mm_bridge;
 
 
ARCHITECTURE str OF axi4_lite_mm_bridge IS
 
-- Sum of all t_mem_copi fields widths (synthesis will optimize away unused address and data bits)
 
CONSTANT c_data_w : NATURAL := c_mem_address_w + c_mem_data_w + 2; -- 32 + 72 + 1 (wr) + 1 (rd) = 106
 
 
SIGNAL i_rst : STD_LOGIC := '0';
 
 
SIGNAL axi4_from_mm_copi : t_mem_copi;
 
SIGNAL axi4_from_mm_cipo : t_mem_cipo;
 
SIGNAL mm_from_axi4_copi : t_mem_copi;
 
SIGNAL mm_from_axi4_cipo : t_mem_cipo;
 
 
SIGNAL rl_decr_snk_ready : STD_LOGIC := '0';
 
SIGNAL rl_decr_snk_dat : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
 
SIGNAL rl_decr_snk_val : STD_LOGIC := '0';
 
SIGNAL rl_decr_src_ready : STD_LOGIC := '0';
 
SIGNAL rl_decr_src_dat : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
 
 
SIGNAL rl_incr_snk_ready : STD_LOGIC := '0';
 
SIGNAL rl_incr_snk_dat : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
 
SIGNAL rl_incr_snk_val : STD_LOGIC := '0';
 
SIGNAL rl_incr_src_ready : STD_LOGIC := '0';
 
SIGNAL rl_incr_src_dat : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
 
 
SIGNAL d_bvalid : STD_LOGIC := '0';
 
SIGNAL q_bvalid : STD_LOGIC := '0';
 
 
BEGIN
 
i_rst <= NOT in_rst WHEN g_active_low_rst ELSE in_rst;
 
aresetn <= NOT i_rst;
 
mm_rst <= i_rst;
 
 
-----------------------------------------------
 
-- Translate MM to AXI4 Lite and RL 1 to RL 0
 
-----------------------------------------------
 
-- Decrease ready latency
 
rl_decr_snk_dat <= func_slv_concat(mm_in_copi.address, mm_in_copi.wrdata, slv(mm_in_copi.wr), slv(mm_in_copi.rd));
 
rl_decr_snk_val <= mm_in_copi.wr OR mm_in_copi.rd;
 
 
u_common_rl_decrease : ENTITY common_lib.common_rl_decrease
 
GENERIC MAP (
 
g_dat_w => c_axi4_lite_data_w
 
)
 
PORT MAP (
 
rst => i_rst,
 
clk => in_clk,
 
-- Sink RL = 1
 
snk_out_ready => rl_decr_snk_ready,
 
snk_in_dat => rl_decr_snk_dat,
 
snk_in_val => rl_decr_snk_val,
 
-- Source RL = 0
 
src_in_ready => rl_decr_src_ready,
 
src_out_dat => rl_decr_src_dat,
 
src_out_val => OPEN
 
);
 
 
-- Account for opposite meaning of waitrequest and ready
 
mm_in_cipo.waitrequest <= NOT rl_decr_snk_ready;
 
rl_decr_src_ready <= NOT axi4_from_mm_cipo.waitrequest;
 
 
-- Wire remaining copi/cipo signals
 
mm_from_axi4_cipo.rddata <= mm_out_cipo.rddata;
 
mm_from_axi4_cipo.rdval <= mm_out_cipo.rdval;
 
axi4_from_mm_copi.address <= func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_decr_src_dat, 0);
 
axi4_from_mm_copi.wrdata <= func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_decr_src_dat, 1);
 
axi4_from_mm_copi.wr <= sl(func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_decr_src_dat, 2));
 
axi4_from_mm_copi.rd <= sl(func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_decr_src_dat, 3));
 
 
-- MM to AXI4 Lite
 
axi4_out_copi.awaddr <= axi4_from_mm_copi.address;
 
axi4_out_copi.awprot <= (OTHERS => '0');
 
axi4_out_copi.awvalid <= axi4_from_mm_copi.wr;
 
axi4_out_copi.wdata <= axi4_from_mm_copi.wrdata(c_axi4_lite_data_w-1 DOWNTO 0);
 
axi4_out_copi.wstrb <= (OTHERS => '1'); -- Either ignored or all bytes selected.
 
axi4_out_copi.wvalid <= axi4_from_mm_copi.wr;
 
axi4_out_copi.bready <= '1'; -- Unsupported by MM, assuming always ready.
 
axi4_out_copi.araddr <= axi4_from_mm_copi.address;
 
axi4_out_copi.arprot <= (OTHERS => '0');
 
axi4_out_copi.arvalid <= axi4_from_mm_copi.rd;
 
axi4_out_copi.rready <= '1'; -- Unsupported by MM, assuming always ready.
 
 
axi4_from_mm_cipo.rddata(c_axi4_lite_data_w-1 DOWNTO 0) <= axi4_out_cipo.rdata;
 
axi4_from_mm_cipo.rdval <= axi4_out_cipo.rvalid;
 
axi4_from_mm_cipo.waitrequest <= NOT (axi4_out_cipo.awready AND axi4_out_cipo.wready AND axi4_out_cipo.arready);
 
 
-------------------------------------------
 
-- Translate AXI4 to MM and RL 0 to RL 1
 
-------------------------------------------
 
-- AXI4 Lite to MM
 
mm_from_axi4_copi.address <= axi4_in_copi.awaddr WHEN axi4_in_copi.awvalid = '1' ELSE axi4_in_copi.araddr;
 
mm_from_axi4_copi.wrdata(c_axi4_lite_data_w-1 DOWNTO 0) <= axi4_in_copi.wdata;
 
mm_from_axi4_copi.wr <= axi4_in_copi.awvalid;
 
mm_from_axi4_copi.rd <= axi4_in_copi.arvalid;
 
 
axi4_in_cipo.awready <= NOT mm_from_axi4_cipo.waitrequest;
 
axi4_in_cipo.wready <= NOT mm_from_axi4_cipo.waitrequest;
 
axi4_in_cipo.bresp <= c_axi4_lite_resp_okay;
 
axi4_in_cipo.bvalid <= q_bvalid;
 
axi4_in_cipo.arready <= NOT mm_from_axi4_cipo.waitrequest;
 
axi4_in_cipo.rdata <= mm_from_axi4_cipo.rddata(c_axi4_lite_data_w-1 DOWNTO 0);
 
axi4_in_cipo.rresp <= c_axi4_lite_resp_okay;
 
axi4_in_cipo.rvalid <= mm_from_axi4_cipo.rdval;
 
 
-- Generate bvalid
 
q_bvalid <= d_bvalid WHEN rising_edge(in_clk);
 
 
p_bvalid : PROCESS(i_rst, q_bvalid, mm_from_axi4_cipo, mm_from_axi4_copi, axi4_in_copi)
 
BEGIN
 
d_bvalid <= q_bvalid;
Please register or sign in to reply
 
IF mm_from_axi4_cipo.waitrequest = '0' AND mm_from_axi4_copi.wr = '1' THEN
 
d_bvalid <= '1';
 
ELSIF axi4_in_copi.bready = '1' THEN
 
d_bvalid <= '0';
 
END IF;
 
IF i_rst = '1' THEN
 
d_bvalid <= '0';
 
END IF;
 
END PROCESS;
 
 
-- Increase ready latency
 
rl_incr_snk_dat <= func_slv_concat(mm_from_axi4_copi.address, mm_from_axi4_copi.wrdata, slv(mm_from_axi4_copi.wr), slv(mm_from_axi4_copi.rd));
 
rl_incr_snk_val <= mm_from_axi4_copi.wr OR mm_from_axi4_copi.rd;
 
 
u_common_rl_increase : ENTITY common_lib.common_rl_increase
 
GENERIC MAP (
 
g_dat_w => c_axi4_lite_data_w
 
)
 
PORT MAP (
 
rst => i_rst,
 
clk => in_clk,
 
-- Sink RL = 0
 
snk_out_ready => rl_incr_snk_ready,
 
snk_in_dat => rl_incr_snk_dat,
 
snk_in_val => rl_incr_snk_val,
 
-- Source RL = 1
 
src_in_ready => rl_incr_src_ready,
 
src_out_dat => rl_incr_src_dat,
 
src_out_val => OPEN
 
);
 
 
-- Account for opposite meaning of waitrequest and ready
 
mm_from_axi4_cipo.waitrequest <= NOT rl_incr_snk_ready;
 
rl_incr_src_ready <= NOT mm_out_cipo.waitrequest;
 
 
-- Wire remaining copi/cipo signals
 
mm_from_axi4_cipo.rddata <= mm_out_cipo.rddata;
 
mm_from_axi4_cipo.rdval <= mm_out_cipo.rdval;
 
mm_out_copi.address <= func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_incr_src_dat, 0);
 
mm_out_copi.wrdata <= func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_incr_src_dat, 1);
 
mm_out_copi.wr <= sl(func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_incr_src_dat, 2));
 
mm_out_copi.rd <= sl(func_slv_extract(c_mem_address_w, c_mem_data_w, 1, 1, rl_incr_src_dat, 3));
 
 
END str;
 
Loading