source: firmware/FTM/trigger/drivers/trigger_delayed_pulse/delayed_pulse.vhd@ 18481

Last change on this file since 18481 was 10366, checked in by weitzel, 14 years ago
FTM trigger manager from MCSE added; DCM arrangement changed; changes in FTM ethernet module
File size: 7.7 KB
Line 
1--=======================================================================================
2-- TITLE : Pulse generation with programmable delay
3-- DESCRIPTION : Generate pulse from an input with a programmable delay and width
4-- FILE : time_counter.vhd
5-- COMPANY : Micro-Cameras & Space Exploration SA
6--=======================================================================================
7-- CREATION
8-- DATE AUTHOR PROJECT REVISION
9-- 02/03/2011 JGi FTM 110302a
10--=======================================================================================
11-- MODIFICATION HISTORY
12-- DATE AUTHOR PROJECT REVISION COMMENTS
13-- 02/03/2011 JGi FTM 110302a Description
14--=======================================================================================
15-- Library Definition
16library ieee;
17 use ieee.std_logic_1164.all;
18 use ieee.numeric_std.all;
19
20library unisim;
21 use unisim.vcomponents.all;
22
23-- Entity Definition
24entity delayed_pulse is
25 generic( pulse_width : integer range 0 to 15 := 10);
26 port( --clock
27 clk_250MHz : in std_logic;
28 --control
29 delay : in std_logic_vector(9 downto 0);
30 --I/O
31 input : in std_logic;
32 output : out std_logic);
33end delayed_pulse;
34
35-- Architecture Definition
36architecture RTL of delayed_pulse is
37
38 type t_reg is record
39 -- Internal register declaration
40 delayed_input : std_logic;
41 enable : std_logic_vector(3 downto 0);
42 delay : std_logic_vector(9 downto 0);
43 delay_counter : std_logic_vector(9 downto 0);
44 delay_value_reached : std_logic_vector(2 downto 0);
45 delay_0_done : std_logic_vector(1 downto 0);
46 delay_1_done : std_logic;
47 pulse_shifter : std_logic_vector(pulse_width downto 0);
48 -- Ouput register declaration
49 output : std_logic_vector(1 downto 0);
50 end record;
51
52 signal i_next_reg : t_reg := (delayed_input => '0',
53 enable => (others => '0'),
54 delay => (others => '0'),
55 delay_counter => (others => '0'),
56 delay_value_reached => (others => '0'),
57 delay_0_done => (others => '0'),
58 delay_1_done => '0',
59 pulse_shifter => (others => '0'),
60 output => (others => '0'));
61 signal i_reg : t_reg := (delayed_input => '0',
62 enable => (others => '0'),
63 delay => (others => '0'),
64 delay_counter => (others => '0'),
65 delay_value_reached => (others => '0'),
66 delay_0_done => (others => '0'),
67 delay_1_done => '0',
68 pulse_shifter => (others => '0'),
69 output => (others => '0'));
70
71 signal i_shifted_data : std_logic;
72
73begin
74
75 -- Generate shift register depending on pulse width generic
76 -- defined in ftm_definitions
77 -- Shifter logic
78 gen_shifter_0: if pulse_width = 0 generate
79 process(clk_250MHz)
80 variable shifter : std_logic := '0';
81 begin
82 if rising_edge(clk_250MHz) then
83 shifter := i_reg.output(0) and not(i_reg.output(1));
84 end if;
85 i_shifted_data <= shifter;
86 end process;
87 end generate gen_shifter_0;
88 gen_shifter_1: if pulse_width > 0 generate
89 process(clk_250MHz)
90 variable shifter : std_logic_vector(pulse_width downto 0) := (others => '0');
91 begin
92 if rising_edge(clk_250MHz) then
93 shifter := shifter(pulse_width-1 downto 0) & (i_reg.output(0) and not(i_reg.output(1)));
94 end if;
95 i_shifted_data <= shifter(pulse_width);
96 end process;
97 end generate gen_shifter_1;
98
99 -- Combinatorial logic
100 process(input, delay, i_shifted_data, i_reg)
101 variable v_reg : t_reg := (delayed_input => '0',
102 enable => (others => '0'),
103 delay => (others => '0'),
104 delay_counter => (others => '0'),
105 delay_value_reached => (others => '0'),
106 delay_0_done => (others => '0'),
107 delay_1_done => '0',
108 pulse_shifter => (others => '0'),
109 output => (others => '0'));
110 begin
111 v_reg := i_reg;
112 --===================================================================================
113
114 --===================================================================================
115 -- Delay Counter management
116 --===================================================================================
117 -- Register delay
118 v_reg.delay := delay;
119
120 -- Count delay when input (master trigger) rising edge detected
121 if i_reg.enable(0) = '1' then
122 v_reg.delay_counter(3 downto 0) := std_logic_vector(unsigned(i_reg.delay_counter(3 downto 0))+1);
123 if i_reg.delay_0_done(1) = '1' then
124 v_reg.delay_counter(7 downto 4) := std_logic_vector(unsigned(i_reg.delay_counter(7 downto 4))+1);
125 end if;
126 if i_reg.delay_1_done = '1' then
127 v_reg.delay_counter(9 downto 8) := std_logic_vector(unsigned(i_reg.delay_counter(9 downto 8))+1);
128 end if;
129 else
130 v_reg.delay_counter := (others => '0');
131 end if;
132
133 v_reg.delayed_input := input;
134
135 -- Detect input (master trigger) rising edge to enable counting
136 if input = '1' and i_reg.delayed_input = '0' then
137 v_reg.enable := (others => '1');
138 end if;
139
140 -- Generate partial comparison between counter and setting
141 if i_reg.delay_counter(3 downto 0) = i_reg.delay(3 downto 0) then
142 v_reg.delay_value_reached(0) := i_reg.enable(1);
143 else
144 v_reg.delay_value_reached(0) := '0';
145 end if;
146 if i_reg.delay_counter(7 downto 4) = i_reg.delay(7 downto 4) then
147 v_reg.delay_value_reached(1) := i_reg.enable(1);
148 else
149 v_reg.delay_value_reached(1) := '0';
150 end if;
151 if i_reg.delay_counter(9 downto 8) = i_reg.delay(9 downto 8) then
152 v_reg.delay_value_reached(2) := i_reg.enable(1);
153 else
154 v_reg.delay_value_reached(2) := '0';
155 end if;
156
157 -- Generate partial counter enable
158 if i_reg.delay_counter(3 downto 0) = "1101" then
159 v_reg.delay_0_done(0) := i_reg.enable(2);
160 else
161 v_reg.delay_0_done(0) := '0';
162 end if;
163 v_reg.delay_0_done(1) := i_reg.delay_0_done(0) and i_reg.enable(2);
164
165 if i_reg.delay_counter(7 downto 4) = "1111" then
166 v_reg.delay_1_done := i_reg.delay_0_done(0) and i_reg.enable(2);
167 end if;
168 --===================================================================================
169
170 --===================================================================================
171 -- Pulse Counter management
172 --===================================================================================
173 -- Enable output when delay is reached, and disable it after shift register
174 -- has finished
175 if i_shifted_data = '1' then
176 v_reg.output(0) := '0';
177 elsif i_reg.delay_value_reached = "111" and i_reg.enable(3) = '1' then
178 v_reg.output(0) := '1';
179 v_reg.pulse_shifter(0) := '1';
180 end if;
181
182 -- Once the output falls, reset enable
183 if i_reg.output(1) = '1' and i_reg.output(0) = '0' then
184 v_reg.enable := (others => '0');
185 end if;
186
187 v_reg.output(1) := i_reg.output(0);
188 --===================================================================================
189
190 --===================================================================================
191 -- Drive register input
192 i_next_reg <= v_reg;
193
194 --===================================================================================
195 -- Output assignation
196 output <= i_reg.output(0);
197 --===================================================================================
198 end process;
199
200 -- Sequential logic
201 process(clk_250MHz)
202 begin
203 if rising_edge(clk_250MHz) then
204 i_reg <= i_next_reg;
205 end if;
206 end process;
207
208end RTL;
Note: See TracBrowser for help on using the repository browser.