diff --git a/libraries/base/mm/hdllib.cfg b/libraries/base/mm/hdllib.cfg index f5f5ef576e1cb78b63da26c6d421bff39c578294..31ded13808503f47ff519fb6e23db28ee83a193e 100644 --- a/libraries/base/mm/hdllib.cfg +++ b/libraries/base/mm/hdllib.cfg @@ -13,6 +13,7 @@ synth_files = src/verilog/wbs_arbiter.v src/vhdl/mm_arbiter.vhd + src/vhdl/mm_slave_enable.vhd src/vhdl/mm_latency_adapter.vhd src/vhdl/mm_bus.vhd src/vhdl/mm_master_mux.vhd diff --git a/libraries/base/mm/src/vhdl/mm_slave_enable.vhd b/libraries/base/mm/src/vhdl/mm_slave_enable.vhd new file mode 100644 index 0000000000000000000000000000000000000000..29ce6fa4301bbb7a02810738c9bbb53fe903356b --- /dev/null +++ b/libraries/base/mm/src/vhdl/mm_slave_enable.vhd @@ -0,0 +1,121 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2020 +-- 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: E. Kooistra +-- Purpose: Connect an MM slave to the MM bus or represent an not connected +-- slave. +-- Description: +-- * g_enable +-- When FALSE then the in_miso output tot the master is forced to +-- c_mem_miso_rst to represent a not connected MM slave. When TRUE then +-- the out_miso signal from the slave is passed on to the master. +-- * g_waitrequest +-- When FALSE then the in_miso.waitrequest is forced to '0' to indicate +-- that the MM slave does not need mosi flow control. When FALSE then +-- the miso.waitrequest from the connected slave is passed on to the +-- master. +-- * g_rd_latency +-- Used to derive in_miso.rdval from in_mosi.rd and out_miso.waitrequest, +-- to provide rdval for MM slaves that do not drive rdval. Typically any +-- MM slave that needs miso.waitrequest flow control, also should support +-- rdval themselves. +-- +-- Todo: +-- * Add miso.response field as defined in Avalon bus, to inform master about +-- rd status (00 = okay, 01 = rsvd, 10 = slaveerror, 11 = decodeerror). +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + +ENTITY mm_slave_enable IS + GENERIC ( + g_enable : BOOLEAN; + g_waitrequest : BOOLEAN; + g_rd_latency : NATURAL + ); + PORT ( + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + -- MM input RL = 1 + in_mosi : IN t_mem_mosi; + in_miso : OUT t_mem_miso; + -- MM output RL = 0 + out_mosi : OUT t_mem_mosi; + out_miso : IN t_mem_miso + ); +END mm_slave_enable; + + +ARCHITECTURE rtl OF mm_slave_enable IS + + SIGNAL rd : STD_LOGIC; + SIGNAL rdval : STD_LOGIC; + SIGNAL waitrequest : STD_LOGIC; + +BEGIN + + -- Use mosi.rd to create miso.rdval for unconnected slave or for slaves that do not support rdval + u_rdval : ENTITY common_lib.common_pipeline_sl + GENERIC MAP ( + g_pipeline => g_rd_latency + ) + PORT MAP ( + rst => mm_rst, + clk => mm_clk, + in_dat => rd, + out_dat => rdval + ); + + + no_slave : IF g_enable = FALSE GENERATE + out_mosi <= c_mem_mosi_rst; + + rd <= in_mosi.rd; + + p_in_miso : PROCESS(rdval) + BEGIN + in_miso <= c_mem_miso_rst; -- force all miso to 0, so rddata = 0 and no waitrequest + in_miso.rdval <= rdval; -- support rdval to avoid hanging master that waits for rdval + END PROCESS; + END GENERATE; + + gen_slave : IF g_enable = TRUE GENERATE + out_mosi <= in_mosi; + + -- Use waitrequest from slave, or force waitrequest = '0' if slave does not need mosi flow control + waitrequest <= out_miso.waitrequest WHEN g_waitrequest = TRUE ELSE '0'; + + rd <= in_mosi.rd AND NOT waitrequest; + + p_in_miso : PROCESS(out_miso, rdval, waitrequest) + BEGIN + in_miso <= out_miso; + in_miso.rdval <= rdval; + in_miso.waitrequest <= waitrequest; + END PROCESS; + END GENERATE; + +END rtl;