use ieee.numeric_std.all;
library work;
use work.trb_net_std.all;
+
entity input_signal_stretcher is
port(
INPUT : in std_logic;
OUTPUT : out std_logic;
+
+ INVERT : in std_logic;
+ ENABLE : in std_logic;
STRETCH : in std_logic_vector(3 downto 0) := x"0"
);
end entity;
architecture behaviour of input_signal_stretcher is
- signal or_long : std_logic := '0';
- signal active : std_logic := '1';
- signal cnt : unsigned (3 downto 0) := x"0";
+ signal or_long : std_logic := '0';
+ signal or_long_r : std_logic := '0';
+ signal input_inv : std_logic;
+ signal cnt : unsigned (4 downto 0) := "00000";
+
+ component FD1S3DX
+ generic (gsr : String := "ENABLED");
+ port (
+ d : in std_logic := 'X';
+ ck : in std_logic := 'X';
+ cd : in std_logic := 'X';
+ q : out std_logic := 'X'
+ );
+ end component;
begin
+
+ input_inv <= ((INPUT xor INVERT) and ENABLE);
- or_long <= (or_long or INPUT) and active;
- OUTPUT <= INPUT when STRETCH = x"0" else
+ -- Input signal rising edge capture flip-flop
+ CREFF : FD1S3DX
+ port map (CK => input_inv,
+ CD => cnt(4),
+ D => '1',
+ Q => or_long);
+
+ --or_long <= (or_long or input_inv) and (not cnt(4));
+
+ OUTPUT <= input_inv when STRETCH = x"0" else
or_long;
+
+ or_long_r <= or_long when rising_edge(CLK);
THE_TRIGGER_CONTROL : process
begin
wait until rising_edge(CLK);
if RESET = '1' then
- active <= '1';
- cnt <= x"0";
+ cnt <= "00000";
else
- active <= '1';
-
- if or_long = '1' then -- trigger is high
- cnt <= cnt + 1;
+ if or_long_r = '1' and cnt(4) = '0' then -- trigger is high
+ cnt <= cnt - 1;
+ else
+ cnt <= ('0' & unsigned(STRETCH)) - 1;
end if;
-
-- deactivate high signal of trigger after configured delay
-- 1 stretch bit = 10ns
-- stretch from 10 to 150ns
-- Stretch begins with first clock edge, but signal is async high.
-- So stretch of 10ns could be between 10.00ns to 19.99ns long, etc.
- if std_logic_vector(cnt) >= STRETCH then
- active <= '0';
- cnt <= x"0";
- end if;
end if;
end process;
end entity;
architecture behaviour of stretched_OR_trigger is
- signal input_or : std_logic;
- signal input_inv : std_logic_vector(INPUT_WIDTH-1 downto 0);
- signal invert : std_logic_vector(31 downto 0) := x"00000000";
- signal enable : std_logic_vector(31 downto 0) := x"00000000";
- signal or_long : std_logic := '0';
- signal stretch : std_logic_vector(3 downto 0) := x"0";
- signal or_long_r : std_logic;
- signal cnt : unsigned (4 downto 0) := "00000";
+ signal input_or_stretched : std_logic;
+ signal input_inv : std_logic_vector(INPUT_WIDTH-1 downto 0);
+ signal invert : std_logic_vector(31 downto 0) := x"00000000";
+ signal enable : std_logic_vector(31 downto 0) := x"00000000";
+ signal stretch : std_logic_vector( 3 downto 0) := x"0";
+ signal stretched_input : std_logic_vector(INPUT_WIDTH-1 downto 0) := (others => '0');
begin
- input_inv <= ((INPUT xor invert(INPUT_WIDTH-1 downto 0)) and enable(INPUT_WIDTH-1 downto 0));
- input_or <= or_all( input_inv);
-
- or_long <= (or_long or input_or) and (not cnt(4));
-
- OUTPUT <= input_or when stretch = x"0" else
- or_long;
-
- or_long_r <= or_long when rising_edge(CLK);
-
- THE_TRIGGER_CONTROL : process
- begin
- wait until rising_edge(CLK);
-
- if RESET = '1' then
- cnt <= "00000";
- else
- if or_long_r = '1' and cnt(4) = '0' then -- trigger is high
- cnt <= cnt - 1;
- else
- cnt <= ('0' & unsigned(stretch)) - 1;
- end if;
- -- deactivate high signal of trigger after configured delay
- -- 1 stretch bit = 10ns
- -- stretch from 10 to 150ns
- -- Stretch begins with first clock edge, but signal is async high.
- -- So stretch of 10ns could be between 10.00ns to 19.99ns long, etc.
- end if;
- end process;
+
+ GEN_STRETCH : for i in 0 to (INPUT_WIDTH-1) generate
+ THE_TRIGGER_Stretch : entity work.input_signal_stretcher
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ INPUT => INPUT(i),
+ INVERT => invert(i),
+ ENABLE => enable(i),
+ OUTPUT => stretched_input(i),
+ STRETCH => stretch
+ );
+ end generate GEN_STRETCH;
+
+ input_or_stretched <= or_all( stretched_input );
+
+ OUTPUT <= input_or_stretched;
+
proc_reg : process
+ variable stretch_check : std_logic_vector(3 downto 0) := x"0";
begin
wait until rising_edge(CLK);
BUS_TX.ack <= '0';
case BUS_RX.addr(1 downto 0) is
when "00" =>
stretch <= BUS_RX.data(3 downto 0);
+
when "01" =>
invert <= BUS_RX.data;
when "10" =>