URL
https://opencores.org/ocsvn/modular_oscilloscope/modular_oscilloscope/trunk
Subversion Repositories modular_oscilloscope
[/] [modular_oscilloscope/] [trunk/] [hdl/] [ctrl/] [trigger_manager.vhd] - Rev 42
Go to most recent revision | Compare with Previous | Blame | View Log
-------------------------------------------------------------------------------------------------100 --| Modular Oscilloscope --| UNSL - Argentine --| --| File: ctrl_trigger_manager.vhd --| Version: 0.1 --| Tested in: Actel A3PE1500 --|------------------------------------------------------------------------------------------------- --| Description: --| CONTROL - Trigger manager --| --| --|------------------------------------------------------------------------------------------------- --| File history: --| 0.1 | jul-2009 | First release ---------------------------------------------------------------------------------------------------- --| Copyright © 2009, Facundo Aguilera. --| --| This VHDL design file is an open design; you can redistribute it and/or --| modify it and/or implement it after contacting the author. ---------------------------------------------------------------------------------------------------- --================================================================================================== -- TODO -- · (OK) Test offset sum -- · Speed up --================================================================================================== library ieee; use ieee.std_logic_1164.all; --use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.NUMERIC_STD.ALL; entity ctrl_trigger_manager is generic ( MEM_ADD_WIDTH: integer := 14; DATA_WIDTH: integer := 10; CHANNELS_WIDTH: integer := 4 ); port ( data_I: in std_logic_vector (DATA_WIDTH - 1 downto 0); channel_I: in std_logic_vector (CHANNELS_WIDTH -1 downto 0); trig_channel_I: in std_logic_vector (CHANNELS_WIDTH -1 downto 0); address_I: in std_logic_vector (MEM_ADD_WIDTH - 1 downto 0); final_address_I: in std_logic_vector (MEM_ADD_WIDTH - 1 downto 0); -- offset from trigger address (signed). MUST BE: -final_address_I < offset_I < final_address_I offset_I: in std_logic_vector (MEM_ADD_WIDTH downto 0); -- trigger level (from max to min, not signed) level_I: in std_logic_vector (DATA_WIDTH - 1 downto 0); -- use falling edge when falling_I = '1', else rising edge falling_I: in std_logic; clk_I: in std_logic; reset_I: in std_logic; enable_I: in std_logic; -- it is set when trigger condition occurs trigger_O: out std_logic; -- address when trigger plus offset address_O: out std_logic_vector (MEM_ADD_WIDTH - 1 downto 0) ); end entity ctrl_trigger_manager; architecture arch01_trigger of ctrl_trigger_manager is -- trigger process signals signal higher, higher_reg: std_logic; signal pre_trigger: std_logic; -- signals for output address selection --signal final_address_sign: std_logic_vector (MEM_ADD_WIDTH downto 0); signal add_plus_off: unsigned (MEM_ADD_WIDTH downto 0); signal add_plus_off_plus_fa: unsigned (MEM_ADD_WIDTH downto 0); signal add_plus_off_sign: std_logic; signal add_plus_off_plus_fa_sign: std_logic; signal offset_sign: std_logic; signal truncate: std_logic; signal selected_address: std_logic_vector(MEM_ADD_WIDTH -1 downto 0); signal selected_address_reg: std_logic_vector(MEM_ADD_WIDTH -1 downto 0); begin -------------------------------------------------------------------------------------------------- -- Output address selection -- Output addess must be between 0 and final_address_I (buffer size), wich may be less than -- (others -> '1'). For this reaeson, it must be truncated. add_plus_off <= unsigned(address_I) + unsigned(offset_I); add_plus_off_sign <= add_plus_off(MEM_ADD_WIDTH); offset_sign <= offset_I(MEM_ADD_WIDTH); add_plus_off_plus_fa <= add_plus_off - unsigned(final_address_I) when offset_sign = '0' else add_plus_off + unsigned(final_address_I); add_plus_off_plus_fa_sign <= add_plus_off_plus_fa (MEM_ADD_WIDTH); truncate <= (offset_sign and add_plus_off_sign) or (not(offset_sign) and not(add_plus_off_plus_fa_sign)); with truncate select selected_address <= std_logic_vector(add_plus_off_plus_fa(MEM_ADD_WIDTH - 1 downto 0)) when '1', std_logic_vector(add_plus_off(MEM_ADD_WIDTH - 1 downto 0)) when others; address_O <= selected_address_reg; -------------------------------------------------------------------------------------------------- -- Trigger higher <= '1' when data_I >= level_I else '0'; P_trigger: process (clk_I, reset_I, enable_I, channel_I, trig_channel_I, higher_reg, falling_I, higher, address_I, offset_sign, selected_address) begin if clk_I'event and clk_I = '1' then if reset_I = '1' then pre_trigger <= '0'; higher_reg <= '0'; trigger_O <= '0'; selected_address_reg <= (others => '0'); elsif enable_I = '1' then if channel_I = trig_channel_I then if (higher_reg = '0' xor falling_I = '1') and (higher = '1' xor falling_I = '1') and pre_trigger = '0' then -- trigger! pre_trigger <= '1'; selected_address_reg <= selected_address; if offset_sign = '1' or unsigned(offset_I) = 0 then trigger_O <= '1'; end if; end if; higher_reg <= higher; end if; if pre_trigger = '1' and selected_address_reg = address_I then -- if offset > 0 then trigger will wait until address_I equals trigger address plus offset trigger_O <= '1'; end if; end if; end if; end process; -- t pt f /f xor1 xor2 and -- 000 1 0 1 -- 001 0 1 0 -- 010 1 0 0 -- 011 0 1 1 1 -- 100 1 1 1 1 -- 101 0 0 0 -- 110 1 1 0 -- 111 0 0 1 end architecture;
Go to most recent revision | Compare with Previous | Blame | View Log