Commit 076d89de authored by Dimitris Lampridis's avatar Dimitris Lampridis

Merge remote-tracking branch 'origin/ML-Btrain-review-feedback' into proposed_master

parents 2782bc8c b49f40e3
......@@ -21,5 +21,7 @@ files = [ "matrix_pkg.vhd",
"gc_big_adder.vhd",
"gc_fsm_watchdog.vhd",
"gc_bicolor_led_ctrl.vhd",
"gc_sync_register.vhd"
"gc_sync_register.vhd",
"gc_single_reset_gen.vhd",
"gc_async_signals_input_stage.vhd"
];
-------------------------------------------------------------------------------
-- Title : Generic input stage for asynchronous input signals
-------------------------------------------------------------------------------
-- File : gc_async_signals_input_stage.vhd
-- Author : Maciej Lipinski
-- Company : CERN
-- Platform : FPGA-generics
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
--
-- A generic input stage for digital asynchronous input signals.
-- It implements a number of stages that might be generally useful/needed
-- before using such signals in a synchronous FPGA-base applications.
--
-- It includes the following input stages:
-- 1. synchronisation with clock domain with taking care for metastability
-- 2. choice of HIGH/LOW active
-- 3. degliching with a filter width set through generic
-- 4. single-clock pulse generation on edge detection
-- * rising edge if HIGH active set
-- * falling edge if LOW actvie set
-- 5. extension of pulse with width set through generic
--
-- The output provides three outputs, any of them can be used at will
-- signals_o : synchronised and deglichted signal active LOW or HIGH,
-- depending on conifg
-- signals_p_o : single-clock pulse on rising/faling edge of the synchronised
-- and degliched signal
-- signals_pN_o : the single-clock pulse extended
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2016 CERN/TE-MS-MM
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2016-08-25 1.0 mlipinsk created
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.gencores_pkg.all;
entity gc_async_signals_input_stage is
generic (
-- number of input signals to be synchronised
g_signal_num : integer := 2;
-- number of clock cycles (N) for the extended output pulse signal
g_extended_pulse_width : integer := 0;
-- number of cycles that filter out glitches
g_dglitch_filter_len : integer := 2
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- input asynchronous signals
signals_a_i : in std_logic_vector(g_signal_num-1 downto 0);
--- Configuration of each input signal
--- '0': active LOW: deglitcher works for '0s' and pulses are produced on falling edge
--- '1': active HIGH: deglitcher works for '1s' and pulses are produced on rising edge
config_active_i : in std_logic_vector(g_signal_num-1 downto 0);
-- synchronised and deglitched signal
signals_o : out std_logic_vector(g_signal_num-1 downto 0);
-- single-clock pulse on rising or falling edge of the input signal (depends on the config)
signals_p1_o : out std_logic_vector(g_signal_num-1 downto 0);
-- N-cycle pulse on rising or falling edge of the input signal (depends on the config)
-- N=g_extended_pulse_width
signals_pN_o : out std_logic_vector(g_signal_num-1 downto 0)
);
end entity gc_async_signals_input_stage;
architecture behav of gc_async_signals_input_stage is
signal signals_synched : std_logic_vector(g_signal_num-1 downto 0);
signal signals_high_or_low : std_logic_vector(g_signal_num-1 downto 0);
signal signals_deglitched : std_logic_vector(g_signal_num-1 downto 0);
signal signals_deglitched_d1 : std_logic_vector(g_signal_num-1 downto 0);
signal signals_pulse_p1 : std_logic_vector(g_signal_num-1 downto 0);
signal signals_pulse_pN : std_logic_vector(g_signal_num-1 downto 0);
begin
gen_synced_signals: for i in 0 to g_signal_num-1 generate
-----------------------------------------------------------------------------------------
-- 1 stage: synchronzie with clock domain
-----------------------------------------------------------------------------------------
cmp_sync_with_clk : gc_sync_ffs
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => signals_a_i(i),
synced_o => signals_synched(i));
-----------------------------------------------------------------------------------------
-- 2 stage: configure active low or high
-----------------------------------------------------------------------------------------
signals_high_or_low(i) <= not signals_synched(i) when config_active_i(i) = '0' else
signals_synched(i);
-----------------------------------------------------------------------------------------
-- 3 stage: deglitch signals where the active is HIGH
-----------------------------------------------------------------------------------------
cmp_deglitch : gc_glitch_filt
generic map (
g_len => g_dglitch_filter_len)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
dat_i => signals_high_or_low(i),
dat_o => signals_deglitched(i));
-----------------------------------------------------------------------------------------
-- 4 stage: produce pulse on rising edge
-----------------------------------------------------------------------------------------
p_pulse_gen : process (clk_i)
begin
if rising_edge (clk_i) then
if rst_n_i = '0' then
signals_deglitched_d1(i) <= '0';
signals_pulse_p1(i) <= '0';
else
if(signals_deglitched(i) = '1' and signals_deglitched_d1(i) = '0') then
signals_pulse_p1(i) <= '1';
else
signals_pulse_p1(i) <= '0';
end if;
signals_deglitched_d1(i) <= signals_deglitched(i);
end if;
end if;
end process;
-----------------------------------------------------------------------------------------
-- 5 stage: extended the pulse (if configured to do so)
-----------------------------------------------------------------------------------------
gen_no_pulse_extender: if(g_extended_pulse_width = 0) generate
signals_pulse_pN(i) <= signals_pulse_p1(i);
end generate gen_no_pulse_extender;
gen_pulse_extender: if(g_extended_pulse_width > 0) generate
cmp_extend_pulse: gc_extend_pulse
generic map (
g_width => g_extended_pulse_width)
port map(
clk_i => clk_i,
rst_n_i => rst_n_i,
pulse_i => signals_pulse_p1(i),
extended_o => signals_pulse_pN(i));
end generate gen_pulse_extender;
end generate gen_synced_signals;
-------------------------------------------------------------------------------------------
-- outputs:
-------------------------------------------------------------------------------------------
signals_o <= signals_deglitched;
signals_p1_o <= signals_pulse_p1;
signals_pN_o <= signals_pulse_pN;
end architecture behav;
\ No newline at end of file
-------------------------------------------------------------------------------
-- Title : Generic generation of synchronous reset for one clock domain
-------------------------------------------------------------------------------
-- File : gc_single_reset_gen.vhd
-- Author : Tomasz Wlostowski, Maciej Lipinski
-- Company : CERN
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description:
--
-- This module generates a synchronous negative pulse reset from a vector of
-- asynchronous inputs (e.g. the PCIe bus powerup reset and SPEC button reset).
--
-- It was importent from wr-cores/top/spec_1_1/wr_core_demo/spec_reset_gen.vhd
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2016 CERN/BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.gencores_pkg.all;
entity gc_single_reset_gen is
generic(
-- number of flip-flops before the final signals' output
g_out_reg_depth : natural :=2;
-- number of input asynchronous reset signals
g_rst_in_num : natural :=2);
port (
-- clock with which the output reset signal is synchronised
clk_i : in std_logic;
-- input asynch reset signals
rst_signals_n_a_i : in std_logic_vector(g_rst_in_num-1 downto 0);
-- synchronous output reset signal
rst_n_o : out std_logic
);
end gc_single_reset_gen;
architecture behavioral of gc_single_reset_gen is
signal powerup_cnt : unsigned(7 downto 0) := x"00";
signal rst_signals_synced_n : std_logic_vector(g_rst_in_num-1 downto 0) := (others => '0');
signal ones : std_logic_vector(g_rst_in_num-1 downto 0) := (others => '1');
signal rst_powerup_n : std_logic := '0';
signal rst_n : std_logic;
signal rst_n_shifter : std_logic_vector(g_out_reg_depth-1 downto 0):= (others => '0');
begin -- behavioral
-- we all love VHDL...
ones <= (others=>'1');
-------------------------------------------------------------------------------------------
-- synchronise input reset signals with the system clock domain
-------------------------------------------------------------------------------------------
gen_synch_inputs: for i in 0 to g_rst_in_num-1 generate
U_EdgeDet_PCIe : gc_sync_ffs port map (
clk_i => clk_i,
rst_n_i => '1',
data_i => rst_signals_n_a_i(i),
synced_o => rst_signals_synced_n(i));
end generate gen_synch_inputs;
-------------------------------------------------------------------------------------------
-- produce a powerup reset
-------------------------------------------------------------------------------------------
p_powerup_reset : process(clk_i)
begin
if rising_edge(clk_i) then
if(powerup_cnt /= x"ff") then
powerup_cnt <= powerup_cnt + 1;
rst_powerup_n <= '0';
else
rst_powerup_n <= '1';
end if;
end if;
end process;
-------------------------------------------------------------------------------------------
-- final reset signal
-------------------------------------------------------------------------------------------
rst_n <= '1' when (rst_powerup_n = '1' and rst_signals_synced_n = ones) else '0';
-------------------------------------------------------------------------------------------
-- Pass through few flip-flops before it goes into an FPGA-wide fun-out
-- (a configurable number of register)
-------------------------------------------------------------------------------------------
p_out_rst_shift_reg: process(clk_i)
begin
if rising_edge(clk_i) then
rst_n_shifter <= rst_n & rst_n_shifter(g_out_reg_depth-1 downto 1);
end if;
end process;
-------------------------------------------------------------------------------------------
-- final output negative active reset
-------------------------------------------------------------------------------------------
rst_n_o<=rst_n_shifter(0);
end behavioral;
......@@ -254,6 +254,21 @@ package gencores_pkg is
rstn_o : out std_logic_vector(g_clocks-1 downto 0));
end component;
------------------------------------------------------------------------------
-- Power-On reset generator of synchronous single reset from multiple
-- asynchronous input reset signals
------------------------------------------------------------------------------
component gc_single_reset_gen is
generic(
g_out_reg_depth : natural :=2;
g_rst_in_num : natural :=2);
port (
clk_i : in std_logic;
rst_signals_n_a_i : in std_logic_vector(g_rst_in_num-1 downto 0);
rst_n_o : out std_logic
);
end component;
------------------------------------------------------------------------------
-- Round robin arbiter
------------------------------------------------------------------------------
......@@ -480,6 +495,21 @@ package gencores_pkg is
q_o : out std_logic_vector(g_width-1 downto 0));
end component gc_sync_register;
component gc_async_signals_input_stage is
generic (
g_signal_num : integer;
g_extended_pulse_width : integer;
g_dglitch_filter_len : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
signals_a_i : in std_logic_vector(g_signal_num-1 downto 0);
config_active_i : in std_logic_vector(g_signal_num-1 downto 0);
signals_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_p1_o : out std_logic_vector(g_signal_num-1 downto 0);
signals_pN_o : out std_logic_vector(g_signal_num-1 downto 0));
end component;
--============================================================================
-- Procedures and functions
--============================================================================
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment