);
end component;
+ signal stretch_reg : std_logic_vector(3 downto 0) := x"8";
+ signal invert : std_logic_vector(31 downto 0) := x"00000000";
+ signal enable : std_logic_vector(31 downto 0) := x"00000000";
- signal invert : std_logic_vector(31 downto 0) := x"00000000";
- signal enable : std_logic_vector(31 downto 0) := x"00000003";
- signal stretch : std_logic_vector(3 downto 0) := x"8";
signal del_val : integer range 0 to 15;
- signal sig_i : std_logic_vector(11 downto 0);
- signal cre : std_logic_vector(11 downto 0);
+ signal sig_i : std_logic_vector(11 downto 0);
+ signal sig_or : std_logic;
+ signal cre : std_logic;
+ signal reset_cff : std_logic;
- type cff_fsm_state_t is array(0 to 11) of integer range 0 to 15;
- signal cff_fsm_state : cff_fsm_state_t := (others => 0);
+ type fsm_state is (IDLE, STRETCH, RESET);
+ signal state : fsm_state := IDLE;
- type ctr_array is array(0 to 11) of integer range 0 to 31;
- signal del_ctr : ctr_array := (others => 20);
-
- signal reset_creff : std_logic_vector(11 downto 0);
+ signal delay : integer range 0 to 15 := 8;
+ signal delay_ctr : integer range 0 to 15 := 0;
-------------------------------------------------------------------------------
-- Input signal enable/disable and invert logic
sig_i <= (SIG_IN xor invert(11 downto 0)) and enable(11 downto 0);
- -- Generate output signals (OR of captured signals)
- g_OR_OUT : for i in 0 to 7 generate
- SIG_OUT(i) <= or_all(cre);
+ -- Or of all enabled input signals
+ sig_or <= or_all(sig_i);
+
+ -- Generate output signals
+ -- Stretched OR signal (output on all 4 pairs of J11)
+ g_OR_OUT_J11 : for i in 0 to 3 generate
+ SIG_OUT(i) <= sig_or when del_val = 0 else cre;
+ end generate;
+ -- Raw OR signal (output on all 4 pairs of J12)
+ g_OR_OUT_J12 : for i in 4 to 7 generate
+ SIG_OUT(i) <= sig_or;
end generate;
-- Set length of stretched pulses (set via TRBnet)
- del_val <= to_integer(unsigned(stretch));
-
- -- Generate capture stages
- g_CAPTURE_STAGES : for i in 0 to 11 generate
-
- -- Input signal rising edge capture flip-flop
- -- Signal needs to be positive logic
- CREFF : FD1S3DX
- port map (CK => sig_i(i),
- CD => reset_creff(i),
- D => '1',
- Q => cre(i));
-
- CAPTURE_FSM : process(CLK)
- begin
- if rising_edge(CLK) then
- case cff_fsm_state(i) is
- -- Wait for rising edge of input signal
- when 0 =>
- reset_creff(i) <= '0';
- del_ctr(i) <= del_val;
- if cre(i) = '1' then
- cff_fsm_state(i) <= cff_fsm_state(i) + 1;
- else
- cff_fsm_state(i) <= cff_fsm_state(i);
- end if;
- -- Synchronous delay after rising edge (defines pulse width)
- when 1 =>
- reset_creff(i) <= '0';
- if del_ctr(i) > 0 then
- del_ctr(i) <= del_ctr(i) - 1;
- cff_fsm_state(i) <= cff_fsm_state(i);
+ del_val <= to_integer(unsigned(stretch_reg));
+
+ -- Edge-capture flip-flop for edge-to-pulse
+ CREFF : FD1S3DX
+ port map (CK => sig_or,
+ CD => reset_cff,
+ D => '1',
+ Q => cre);
+
+ -- Capture flip-flop reset state machine
+ CAPTURE_FSM : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ case state is
+ -- Synchronous delay after rising edge (defines output pulse width)
+ when STRETCH =>
+ reset_cff <= '0';
+ if cre = '1' then
+ if delay_ctr < del_val then
+ delay_ctr <= delay_ctr + 1;
+ state <= STRETCH;
else
- cff_fsm_state(i) <= cff_fsm_state(i) + 1;
+ delay_ctr <= delay_ctr;
+ state <= RESET;
end if;
- -- Reset capture flip-flop
- when 2 =>
- reset_creff(i) <= '1';
- del_ctr(i) <= del_ctr(i);
- cff_fsm_state(i) <= 0;
- -- Catch erronous states
- when others =>
- reset_creff(i) <= '1';
- del_ctr(i) <= del_val;
- cff_fsm_state(i) <= 0;
- end case;
- end if;
- end process;
+ else
+ delay_ctr <= delay_ctr;
+ state <= STRETCH;
+ end if;
+ -- Reset capture flip-flop
+ when RESET =>
+ reset_cff <= '1';
+ delay_ctr <= 0;
+ state <= STRETCH;
+ -- Catch erronous states
+ when others =>
+ reset_cff <= '1';
+ delay_ctr <= 0;
+ state <= STRETCH;
+ end case;
+ end if;
+ end process;
- end generate;
+ -- -- Capture flip-flop reset state machine
+ -- CAPTURE_FSM : process(CLK)
+ -- begin
+ -- if rising_edge(CLK) then
+ -- case state is
+ -- -- Wait for detection of rising edge
+ -- when IDLE =>
+ -- reset_cff <= '0';
+ -- delay <= del_val;
+ -- if cre = '1' then
+ -- if delay > 1 then
+ -- state <= STRETCH;
+ -- else
+ -- state <= RESET;
+ -- end if;
+ -- else
+ -- state <= IDLE;
+ -- end if;
+ -- -- Synchronous delay after rising edge (defines output pulse width)
+ -- when STRETCH =>
+ -- reset_cff <= '0';
+ -- delay <= delay - 1;
+ -- if delay > 0 then
+ -- state <= STRETCH;
+ -- else
+ -- state <= RESET;
+ -- end if;
+ -- -- Reset capture flip-flop
+ -- when RESET =>
+ -- reset_cff <= '1';
+ -- delay <= delay;
+ -- state <= IDLE;
+ -- -- Catch erronous states
+ -- when others =>
+ -- reset_cff <= '1';
+ -- delay <= del_val;
+ -- state <= IDLE;
+ -- end case;
+ -- end if;
+ -- end process;
-- TRBnet
BUS_TX.ack <= '1';
case BUS_RX.addr(1 downto 0) is
when "00" =>
- stretch <= BUS_RX.data(3 downto 0);
+ stretch_reg <= BUS_RX.data(3 downto 0);
when "01" =>
invert <= BUS_RX.data;
when "10" =>
BUS_TX.ack <= '0';
BUS_TX.unknown <= '1';
end case;
+
elsif BUS_RX.read = '1' then
BUS_TX.ack <= '1';
case BUS_RX.addr(1 downto 0) is
- when "00" => BUS_TX.data(3 downto 0) <= stretch;
+ when "00" => BUS_TX.data(3 downto 0) <= stretch_reg;
when "01" => BUS_TX.data <= invert;