OpenCores
URL https://opencores.org/ocsvn/modular_oscilloscope/modular_oscilloscope/trunk

Subversion Repositories modular_oscilloscope

[/] [modular_oscilloscope/] [trunk/] [hdl/] [ctrl/] [trigger_manager.vhd] - Blame information for rev 55

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 32 budinero
-------------------------------------------------------------------------------------------------100
2
--| Modular Oscilloscope
3
--| UNSL - Argentine
4
--|
5 37 budinero
--| File: ctrl_trigger_manager.vhd
6 32 budinero
--| Version: 0.1
7
--| Tested in: Actel A3PE1500
8
--|-------------------------------------------------------------------------------------------------
9
--| Description:
10
--|   CONTROL - Trigger manager
11
--|   
12
--|   
13
--|-------------------------------------------------------------------------------------------------
14
--| File history:
15
--|   0.1   | jul-2009 | First release
16
----------------------------------------------------------------------------------------------------
17 33 budinero
--| Copyright © 2009, Facundo Aguilera.
18 32 budinero
--|
19
--| This VHDL design file is an open design; you can redistribute it and/or
20
--| modify it and/or implement it after contacting the author.
21
----------------------------------------------------------------------------------------------------
22
 
23
 
24
--==================================================================================================
25
-- TODO
26
-- · (OK) Test offset sum
27
-- · Speed up
28 48 budinero
-- · Compare performance with address_O = actual trigger address - 1
29 32 budinero
--==================================================================================================
30
 
31
library ieee;
32
use ieee.std_logic_1164.all;
33
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
34
use IEEE.NUMERIC_STD.ALL;
35
 
36
 
37 37 budinero
entity ctrl_trigger_manager is
38 32 budinero
  generic (
39
    MEM_ADD_WIDTH:  integer := 14;
40
    DATA_WIDTH:     integer := 10;
41
    CHANNELS_WIDTH: integer := 4
42
  );
43
  port (
44
    data_I:           in  std_logic_vector (DATA_WIDTH - 1 downto 0);
45
    channel_I:        in  std_logic_vector (CHANNELS_WIDTH -1 downto 0);
46
    trig_channel_I:   in  std_logic_vector (CHANNELS_WIDTH -1 downto 0);
47
    address_I:        in  std_logic_vector (MEM_ADD_WIDTH - 1 downto 0);
48
    final_address_I:  in  std_logic_vector (MEM_ADD_WIDTH - 1 downto 0);
49
    -- offset from trigger address (signed). MUST BE: -final_address_I < offset_I < final_address_I
50
    offset_I:         in std_logic_vector (MEM_ADD_WIDTH  downto 0);
51
    -- trigger level (from max to min, not signed)
52
    level_I:          in  std_logic_vector (DATA_WIDTH - 1 downto 0);
53
    -- use falling edge when falling_I = '1', else rising edge
54
    falling_I:        in  std_logic;
55
    clk_I:            in  std_logic;
56
    reset_I:          in  std_logic;
57
    enable_I:         in  std_logic;
58
    -- it is set when trigger condition occurs
59
    trigger_O:        out std_logic;
60
    -- address when trigger plus offset
61
    address_O:        out std_logic_vector (MEM_ADD_WIDTH - 1 downto 0)
62
  );
63
 
64 37 budinero
end entity ctrl_trigger_manager;
65 32 budinero
 
66 37 budinero
architecture arch01_trigger of ctrl_trigger_manager is
67 32 budinero
  -- trigger process signals
68
  signal higher, higher_reg: std_logic;
69
  signal pre_trigger: std_logic;
70
 
71
  -- signals for output address selection
72
  --signal final_address_sign: std_logic_vector (MEM_ADD_WIDTH downto 0);
73
  signal add_plus_off: unsigned (MEM_ADD_WIDTH downto 0);
74
  signal add_plus_off_plus_fa: unsigned (MEM_ADD_WIDTH downto 0);
75
  signal add_plus_off_sign: std_logic;
76
  signal add_plus_off_plus_fa_sign: std_logic;
77
  signal offset_sign: std_logic;
78
  signal truncate: std_logic;
79
  signal selected_address: std_logic_vector(MEM_ADD_WIDTH -1 downto 0);
80
  signal selected_address_reg: std_logic_vector(MEM_ADD_WIDTH -1 downto 0);
81
 
82 55 budinero
  signal full_buffer: std_logic;
83 32 budinero
 
84
begin
85
 
86
  --------------------------------------------------------------------------------------------------
87
  -- Output address selection
88
 
89
  -- Output addess must be between 0 and final_address_I (buffer size), wich may be less than 
90
  -- (others -> '1'). For this reaeson, it must be truncated. 
91
 
92
  add_plus_off <= unsigned(address_I) + unsigned(offset_I);
93
  add_plus_off_sign <= add_plus_off(MEM_ADD_WIDTH);
94
  offset_sign <= offset_I(MEM_ADD_WIDTH);
95
 
96
  add_plus_off_plus_fa <= add_plus_off - unsigned(final_address_I) when offset_sign = '0' else
97
                           add_plus_off + unsigned(final_address_I);
98
 
99
 
100
  add_plus_off_plus_fa_sign <= add_plus_off_plus_fa (MEM_ADD_WIDTH);
101
 
102
  truncate <= (offset_sign and  add_plus_off_sign) or
103
              (not(offset_sign) and not(add_plus_off_plus_fa_sign));
104
 
105
  with truncate select
106
    selected_address <= std_logic_vector(add_plus_off_plus_fa(MEM_ADD_WIDTH - 1 downto 0))
107
                          when '1',
108
                        std_logic_vector(add_plus_off(MEM_ADD_WIDTH - 1 downto 0))
109
                          when others;
110
 
111 55 budinero
  address_O <=  selected_address_reg;
112 32 budinero
 
113
  --------------------------------------------------------------------------------------------------
114
  -- Trigger 
115 55 budinero
  higher <= '1' when data_I >= level_I  else '0';
116 32 budinero
 
117
  P_trigger: process (clk_I, reset_I, enable_I, channel_I, trig_channel_I, higher_reg,
118
  falling_I, higher, address_I, offset_sign, selected_address)
119
  begin
120
    if clk_I'event and clk_I = '1' then
121
      if reset_I = '1' then
122
        pre_trigger <= '0';
123
        higher_reg <= '0';
124
        trigger_O <= '0';
125
        selected_address_reg <= (others => '0');
126
      elsif enable_I = '1' then
127
 
128
        if channel_I = trig_channel_I then
129
          if  (higher_reg = '0' xor falling_I = '1') and
130 55 budinero
              (higher = '1' xor falling_I = '1') and pre_trigger = '0' and full_buffer = '1'
131 32 budinero
              then -- trigger!
132
            pre_trigger <= '1';
133
            selected_address_reg <= selected_address;
134
            if offset_sign = '1' or unsigned(offset_I) = 0 then
135
              trigger_O <= '1';
136
            end if;
137
          end if;
138 55 budinero
          higher_reg <= higher; -- higher_reg will be the previous higher 
139 32 budinero
        end if;
140
 
141
        if pre_trigger = '1' and selected_address_reg = address_I then
142
          -- if offset > 0 then trigger will wait until address_I equals trigger address plus offset
143
            trigger_O <= '1';
144
        end if;
145
 
146
      end if;
147
    end if;
148
  end process;
149
 
150 55 budinero
  -- When using negative offset for buffer, buffer must be filled before set trigger 
151
  P_wait_buffer_full: process (clk_I)
152
  begin
153
    if clk_I'event and clk_I = '1' then
154
      if reset_I = '1' then
155
        full_buffer <= '0';
156
      elsif enable_I = '1' and (offset_sign = '0' or add_plus_off_sign = '0') and
157
      full_buffer <= '0' then
158
        full_buffer <= '1';
159
      end if;
160
    end if;
161
  end process;
162 32 budinero
 
163
  -- t pt f /f xor1 xor2 and
164
  -- 000 1 0 1 
165
  -- 001 0 1 0 
166
  -- 010 1 0 0     
167
  -- 011 0 1 1 1 
168
  -- 100 1 1 1 1 
169
  -- 101 0 0 0  
170
  -- 110 1 1 0  
171
  -- 111 0 0 1  
172
 
173
end architecture;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.