|
@@
-17,112
+17,112
|
|
17
|
-- Additional Comments:
|
|
17
|
-- Additional Comments:
|
|
18
|
--
|
|
18
|
--
|
|
19
|
----------------------------------------------------------------------------------
|
|
19
|
----------------------------------------------------------------------------------
|
|
20
|
library IEEE;
|
|
20
|
LIBRARY IEEE;
|
|
21
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
21
|
USE IEEE.STD_LOGIC_1164.ALL;
|
|
22
|
use IEEE.NUMERIC_STD.ALL;
|
|
22
|
USE IEEE.NUMERIC_STD.ALL;
|
|
23
|
library lpp;
|
|
23
|
LIBRARY lpp;
|
|
24
|
use lpp.general_purpose.Clk_divider;
|
|
24
|
USE lpp.general_purpose.Clk_divider;
|
|
25
|
|
|
25
|
|
|
26
|
entity lfr_time_management is
|
|
26
|
ENTITY lfr_time_management IS
|
|
27
|
generic (
|
|
27
|
GENERIC (
|
|
28
|
masterclk : integer := 25000000; -- master clock in Hz
|
|
28
|
masterclk : INTEGER := 25000000; -- master clock in Hz
|
|
29
|
timeclk : integer := 49152000; -- 2nd clock in Hz
|
|
29
|
timeclk : INTEGER := 49152000; -- 2nd clock in Hz
|
|
30
|
finetimeclk : integer := 65536; -- divided clock used for the fine time counter
|
|
30
|
finetimeclk : INTEGER := 65536; -- divided clock used for the fine time counter
|
|
31
|
nb_clk_div_ticks : integer := 1 -- nb ticks before commutation to AUTO state
|
|
31
|
nb_clk_div_ticks : INTEGER := 1 -- nb ticks before commutation to AUTO state
|
|
32
|
);
|
|
32
|
);
|
|
33
|
Port (
|
|
33
|
PORT (
|
|
34
|
master_clock : in std_logic; --! Clock
|
|
34
|
master_clock : IN STD_LOGIC; --! Clock
|
|
35
|
time_clock : in std_logic; --! 2nd Clock
|
|
35
|
time_clock : IN STD_LOGIC; --! 2nd Clock
|
|
36
|
resetn : in std_logic; --! Reset
|
|
36
|
resetn : IN STD_LOGIC; --! Reset
|
|
37
|
grspw_tick : in std_logic;
|
|
37
|
grspw_tick : IN STD_LOGIC;
|
|
38
|
soft_tick : in std_logic; --! soft tick, load the coarse_time value
|
|
38
|
soft_tick : IN STD_LOGIC; --! soft tick, load the coarse_time value
|
|
39
|
coarse_time_load : in std_logic_vector(31 downto 0);
|
|
39
|
coarse_time_load : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
40
|
coarse_time : out std_logic_vector(31 downto 0);
|
|
40
|
coarse_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
41
|
fine_time : out std_logic_vector(31 downto 0);
|
|
41
|
fine_time : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
42
|
next_commutation : in std_logic_vector(31 downto 0);
|
|
42
|
next_commutation : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
43
|
reset_next_commutation: out std_logic;
|
|
43
|
reset_next_commutation : OUT STD_LOGIC;
|
|
44
|
irq1 : out std_logic;
|
|
44
|
irq1 : OUT STD_LOGIC;
|
|
45
|
irq2 : out std_logic
|
|
45
|
irq2 : OUT STD_LOGIC
|
|
46
|
);
|
|
46
|
);
|
|
47
|
end lfr_time_management;
|
|
47
|
END lfr_time_management;
|
|
48
|
|
|
48
|
|
|
49
|
architecture Behavioral of lfr_time_management is
|
|
49
|
ARCHITECTURE Behavioral OF lfr_time_management IS
|
|
50
|
|
|
50
|
|
|
51
|
signal resetn_clk_div : std_logic;
|
|
51
|
SIGNAL resetn_clk_div : STD_LOGIC;
|
|
52
|
signal clk_div : std_logic;
|
|
52
|
SIGNAL clk_div : STD_LOGIC;
|
|
53
|
--
|
|
53
|
--
|
|
54
|
signal flag : std_logic;
|
|
54
|
SIGNAL flag : STD_LOGIC;
|
|
55
|
signal s_coarse_time : std_logic_vector(31 downto 0);
|
|
55
|
SIGNAL s_coarse_time : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
56
|
signal previous_coarse_time_load : std_logic_vector(31 downto 0);
|
|
56
|
SIGNAL previous_coarse_time_load : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
57
|
signal cpt : integer range 0 to 100000;
|
|
57
|
SIGNAL cpt : INTEGER RANGE 0 TO 100000;
|
|
58
|
signal secondary_cpt : integer range 0 to 72000;
|
|
58
|
SIGNAL secondary_cpt : INTEGER RANGE 0 TO 72000;
|
|
59
|
--
|
|
59
|
--
|
|
60
|
signal sirq1 : std_logic;
|
|
60
|
SIGNAL sirq1 : STD_LOGIC;
|
|
61
|
signal sirq2 : std_logic;
|
|
61
|
SIGNAL sirq2 : STD_LOGIC;
|
|
62
|
signal cpt_next_commutation : integer range 0 to 100000;
|
|
62
|
SIGNAL cpt_next_commutation : INTEGER RANGE 0 TO 100000;
|
|
63
|
signal p_next_commutation : std_logic_vector(31 downto 0);
|
|
63
|
SIGNAL p_next_commutation : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
64
|
signal latched_next_commutation : std_logic_vector(31 downto 0);
|
|
64
|
SIGNAL latched_next_commutation : STD_LOGIC_VECTOR(31 DOWNTO 0);
|
|
65
|
signal p_clk_div : std_logic;
|
|
65
|
SIGNAL p_clk_div : STD_LOGIC;
|
|
66
|
--
|
|
66
|
--
|
|
67
|
type state_type is (auto, slave);
|
|
67
|
TYPE state_type IS (auto, slave);
|
|
68
|
signal state : state_type;
|
|
68
|
SIGNAL state : state_type;
|
|
69
|
type timer_type is (idle, engaged);
|
|
69
|
TYPE timer_type IS (idle, engaged);
|
|
70
|
signal commutation_timer : timer_type;
|
|
70
|
SIGNAL commutation_timer : timer_type;
|
|
71
|
|
|
71
|
|
|
72
|
begin
|
|
72
|
BEGIN
|
|
73
|
|
|
73
|
|
|
74
|
--*******************************************
|
|
74
|
--*******************************************
|
|
75
|
-- COMMUTATION TIMER AND INTERRUPT GENERATION
|
|
75
|
-- COMMUTATION TIMER AND INTERRUPT GENERATION
|
|
76
|
process(master_clock, resetn)
|
|
76
|
PROCESS(master_clock, resetn)
|
|
77
|
begin
|
|
77
|
BEGIN
|
|
78
|
|
|
78
|
|
|
79
|
if resetn = '0' then
|
|
79
|
IF resetn = '0' THEN
|
|
80
|
commutation_timer <= idle;
|
|
80
|
commutation_timer <= idle;
|
|
81
|
cpt_next_commutation <= 0;
|
|
81
|
cpt_next_commutation <= 0;
|
|
82
|
sirq1 <= '0';
|
|
82
|
sirq1 <= '0';
|
|
83
|
sirq2 <= '0';
|
|
83
|
sirq2 <= '0';
|
|
84
|
latched_next_commutation <= x"ffffffff";
|
|
84
|
latched_next_commutation <= x"ffffffff";
|
|
85
|
|
|
85
|
|
|
86
|
elsif master_clock'event and master_clock = '1' then
|
|
86
|
ELSIF master_clock'EVENT AND master_clock = '1' THEN
|
|
87
|
|
|
87
|
|
|
88
|
case commutation_timer is
|
|
88
|
CASE commutation_timer IS
|
|
89
|
|
|
89
|
|
|
90
|
when idle =>
|
|
90
|
WHEN idle =>
|
|
91
|
sirq1 <= '0';
|
|
91
|
sirq1 <= '0';
|
|
92
|
sirq2 <= '0';
|
|
92
|
sirq2 <= '0';
|
|
93
|
if s_coarse_time = latched_next_commutation then
|
|
93
|
IF s_coarse_time = latched_next_commutation THEN
|
|
94
|
commutation_timer <= engaged; -- transition to state "engaged"
|
|
94
|
commutation_timer <= engaged; -- transition to state "engaged"
|
|
95
|
sirq1 <= '1'; -- start the pulse on sirq1
|
|
95
|
sirq1 <= '1'; -- start the pulse on sirq1
|
|
96
|
latched_next_commutation <= x"ffffffff";
|
|
96
|
latched_next_commutation <= x"ffffffff";
|
|
97
|
elsif not(p_next_commutation = next_commutation) then -- next_commutation has changed
|
|
97
|
ELSIF NOT(p_next_commutation = next_commutation) THEN -- next_commutation has changed
|
|
98
|
latched_next_commutation <= next_commutation; -- latch the value
|
|
98
|
latched_next_commutation <= next_commutation; -- latch the value
|
|
99
|
else
|
|
99
|
ELSE
|
|
100
|
commutation_timer <= idle;
|
|
100
|
commutation_timer <= idle;
|
|
101
|
end if;
|
|
101
|
END IF;
|
|
102
|
|
|
102
|
|
|
103
|
when engaged =>
|
|
103
|
WHEN engaged =>
|
|
104
|
sirq1 <= '0'; -- stop the pulse on sirq1
|
|
104
|
sirq1 <= '0'; -- stop the pulse on sirq1
|
|
105
|
if not(p_clk_div = clk_div) and clk_div = '1' then -- detect a clk_div raising edge
|
|
105
|
IF NOT(p_clk_div = clk_div) AND clk_div = '1' THEN -- detect a clk_div raising edge
|
|
106
|
if cpt_next_commutation = 65536 then
|
|
106
|
IF cpt_next_commutation = 65536 THEN
|
|
107
|
cpt_next_commutation <= 0;
|
|
107
|
cpt_next_commutation <= 0;
|
|
108
|
commutation_timer <= idle;
|
|
108
|
commutation_timer <= idle;
|
|
109
|
sirq2 <= '1'; -- start the pulse on sirq2
|
|
109
|
sirq2 <= '1'; -- start the pulse on sirq2
|
|
110
|
else
|
|
110
|
ELSE
|
|
111
|
cpt_next_commutation <= cpt_next_commutation + 1;
|
|
111
|
cpt_next_commutation <= cpt_next_commutation + 1;
|
|
112
|
end if;
|
|
112
|
END IF;
|
|
113
|
end if;
|
|
113
|
END IF;
|
|
114
|
|
|
114
|
|
|
115
|
when others =>
|
|
115
|
WHEN OTHERS =>
|
|
116
|
commutation_timer <= idle;
|
|
116
|
commutation_timer <= idle;
|
|
117
|
|
|
117
|
|
|
118
|
end case;
|
|
118
|
END CASE;
|
|
119
|
|
|
119
|
|
|
120
|
p_next_commutation <= next_commutation;
|
|
120
|
p_next_commutation <= next_commutation;
|
|
121
|
p_clk_div <= clk_div;
|
|
121
|
p_clk_div <= clk_div;
|
|
122
|
|
|
122
|
|
|
123
|
end if;
|
|
123
|
END IF;
|
|
124
|
|
|
124
|
|
|
125
|
end process;
|
|
125
|
END PROCESS;
|
|
126
|
|
|
126
|
|
|
127
|
irq1 <= sirq1;
|
|
127
|
irq1 <= sirq1;
|
|
128
|
irq2 <= sirq2;
|
|
128
|
irq2 <= sirq2;
|
|
@@
-133,25
+133,26
reset_next_commutation <= '0';
|
|
133
|
|
|
133
|
|
|
134
|
--**********************
|
|
134
|
--**********************
|
|
135
|
-- synchronization stage
|
|
135
|
-- synchronization stage
|
|
136
|
process(master_clock, resetn) -- resynchronisation with clk
|
|
136
|
PROCESS(master_clock, resetn) -- resynchronisation with clk
|
|
137
|
begin
|
|
137
|
BEGIN
|
|
138
|
|
|
138
|
|
|
139
|
if resetn = '0' then
|
|
139
|
IF resetn = '0' THEN
|
|
140
|
coarse_time(31 downto 0) <= x"80000000"; -- set the most significant bit of the coarse time to 1 on reset
|
|
140
|
coarse_time(31 DOWNTO 0) <= x"80000000"; -- set the most significant bit of the coarse time to 1 on reset
|
|
141
|
|
|
141
|
|
|
142
|
elsif master_clock'event and master_clock = '1' then
|
|
142
|
ELSIF master_clock'EVENT AND master_clock = '1' THEN
|
|
143
|
coarse_time(31 downto 0) <= s_coarse_time(31 downto 0); -- coarse_time is changed synchronously with clk
|
|
143
|
coarse_time(31 DOWNTO 0) <= s_coarse_time(31 DOWNTO 0); -- coarse_time is changed synchronously with clk
|
|
144
|
end if;
|
|
144
|
END IF;
|
|
145
|
|
|
145
|
|
|
146
|
end process;
|
|
146
|
END PROCESS;
|
|
147
|
--
|
|
147
|
--
|
|
148
|
--**********************
|
|
148
|
--**********************
|
|
149
|
|
|
149
|
|
|
150
|
|
|
150
|
|
|
151
|
process(clk_div, resetn, grspw_tick, soft_tick, flag, coarse_time_load) --
|
|
151
|
-- PROCESS(clk_div, resetn, grspw_tick, soft_tick, flag, coarse_time_load) -- JC
|
|
152
|
begin
|
|
152
|
PROCESS(clk_div, resetn) -- JC
|
|
|
|
|
153
|
BEGIN
|
|
153
|
|
|
154
|
|
|
154
|
if resetn = '0' then
|
|
155
|
IF resetn = '0' THEN
|
|
155
|
flag <= '0';
|
|
156
|
flag <= '0';
|
|
156
|
cpt <= 0;
|
|
157
|
cpt <= 0;
|
|
157
|
secondary_cpt <= 0;
|
|
158
|
secondary_cpt <= 0;
|
|
@@
-159,70
+160,95
begin
|
|
159
|
previous_coarse_time_load <= x"80000000";
|
|
160
|
previous_coarse_time_load <= x"80000000";
|
|
160
|
state <= auto;
|
|
161
|
state <= auto;
|
|
161
|
|
|
162
|
|
|
162
|
elsif grspw_tick = '1' or soft_tick = '1' then
|
|
163
|
--ELSIF grspw_tick = '1' OR soft_tick = '1' THEN
|
|
163
|
if flag = '1' then -- coarse_time_load shall change at least 1/65536 s before the timecode
|
|
164
|
-- --IF flag = '1' THEN -- coarse_time_load shall change at least 1/65536 s before the timecode
|
|
|
|
|
165
|
-- -- s_coarse_time <= coarse_time_load;
|
|
|
|
|
166
|
-- -- flag <= '0';
|
|
|
|
|
167
|
-- --ELSE -- if coarse_time_load has not changed, increment the value autonomously
|
|
|
|
|
168
|
-- -- s_coarse_time <= STD_LOGIC_VECTOR(UNSIGNED(s_coarse_time) + 1);
|
|
|
|
|
169
|
-- --END IF;
|
|
|
|
|
170
|
|
|
|
|
|
171
|
-- cpt <= 0;
|
|
|
|
|
172
|
-- secondary_cpt <= 0;
|
|
|
|
|
173
|
-- state <= slave;
|
|
|
|
|
174
|
|
|
|
|
|
175
|
ELSIF clk_div'EVENT AND clk_div = '1' THEN
|
|
|
|
|
176
|
|
|
|
|
|
177
|
CASE state IS
|
|
|
|
|
178
|
|
|
|
|
|
179
|
WHEN auto =>
|
|
|
|
|
180
|
IF grspw_tick = '1' OR soft_tick = '1' THEN
|
|
|
|
|
181
|
IF flag = '1' THEN -- coarse_time_load shall change at least 1/65536 s before the timecode
|
|
164
|
s_coarse_time <= coarse_time_load;
|
|
182
|
s_coarse_time <= coarse_time_load;
|
|
|
|
|
183
|
ELSE -- if coarse_time_load has not changed, increment the value autonomously
|
|
|
|
|
184
|
s_coarse_time <= STD_LOGIC_VECTOR(UNSIGNED(s_coarse_time) + 1);
|
|
|
|
|
185
|
END IF;
|
|
165
|
flag <= '0';
|
|
186
|
flag <= '0';
|
|
166
|
else -- if coarse_time_load has not changed, increment the value autonomously
|
|
|
|
|
167
|
s_coarse_time <= std_logic_vector(unsigned(s_coarse_time) + 1);
|
|
|
|
|
168
|
end if;
|
|
|
|
|
169
|
cpt <= 0;
|
|
187
|
cpt <= 0;
|
|
170
|
secondary_cpt <= 0;
|
|
188
|
secondary_cpt <= 0;
|
|
171
|
state <= slave;
|
|
189
|
state <= slave;
|
|
172
|
|
|
190
|
ELSE
|
|
173
|
elsif clk_div'event and clk_div = '1' then
|
|
191
|
IF cpt = 65535 THEN
|
|
174
|
|
|
192
|
IF flag = '1' THEN
|
|
175
|
case state is
|
|
|
|
|
176
|
|
|
|
|
|
177
|
when auto =>
|
|
|
|
|
178
|
if cpt = 65535 then
|
|
|
|
|
179
|
if flag = '1' then
|
|
|
|
|
180
|
s_coarse_time <= coarse_time_load;
|
|
193
|
s_coarse_time <= coarse_time_load;
|
|
181
|
flag <= '0';
|
|
194
|
flag <= '0';
|
|
182
|
else
|
|
195
|
ELSE
|
|
183
|
s_coarse_time <= std_logic_vector(unsigned(s_coarse_time) + 1);
|
|
196
|
s_coarse_time <= STD_LOGIC_VECTOR(UNSIGNED(s_coarse_time) + 1);
|
|
184
|
end if;
|
|
197
|
END IF;
|
|
185
|
cpt <= 0;
|
|
198
|
cpt <= 0;
|
|
186
|
secondary_cpt <= secondary_cpt + 1;
|
|
199
|
secondary_cpt <= secondary_cpt + 1;
|
|
187
|
else
|
|
200
|
ELSE
|
|
188
|
cpt <= cpt + 1 ;
|
|
201
|
cpt <= cpt + 1;
|
|
189
|
end if;
|
|
202
|
END IF;
|
|
|
|
|
203
|
END IF;
|
|
190
|
|
|
204
|
|
|
191
|
when slave =>
|
|
205
|
WHEN slave =>
|
|
192
|
if cpt = 65536 + nb_clk_div_ticks then -- 1 / 65536 = 15.259 us
|
|
206
|
IF grspw_tick = '1' OR soft_tick = '1' THEN
|
|
|
|
|
207
|
IF flag = '1' THEN -- coarse_time_load shall change at least 1/65536 s before the timecode
|
|
|
|
|
208
|
s_coarse_time <= coarse_time_load;
|
|
|
|
|
209
|
ELSE -- if coarse_time_load has not changed, increment the value autonomously
|
|
|
|
|
210
|
s_coarse_time <= STD_LOGIC_VECTOR(UNSIGNED(s_coarse_time) + 1);
|
|
|
|
|
211
|
END IF;
|
|
|
|
|
212
|
flag <= '0';
|
|
|
|
|
213
|
cpt <= 0;
|
|
|
|
|
214
|
secondary_cpt <= 0;
|
|
|
|
|
215
|
state <= slave;
|
|
|
|
|
216
|
ELSE
|
|
|
|
|
217
|
IF cpt = 65536 + nb_clk_div_ticks THEN -- 1 / 65536 = 15.259 us
|
|
193
|
state <= auto; -- commutation to AUTO state
|
|
218
|
state <= auto; -- commutation to AUTO state
|
|
194
|
if flag = '1' then
|
|
219
|
IF flag = '1' THEN
|
|
195
|
s_coarse_time <= coarse_time_load;
|
|
220
|
s_coarse_time <= coarse_time_load;
|
|
196
|
flag <= '0';
|
|
221
|
flag <= '0';
|
|
197
|
else
|
|
222
|
ELSE
|
|
198
|
s_coarse_time <= std_logic_vector(unsigned(s_coarse_time) + 1);
|
|
223
|
s_coarse_time <= STD_LOGIC_VECTOR(UNSIGNED(s_coarse_time) + 1);
|
|
199
|
end if;
|
|
224
|
END IF;
|
|
200
|
cpt <= nb_clk_div_ticks; -- reset cpt at nb_clk_div_ticks
|
|
225
|
cpt <= nb_clk_div_ticks; -- reset cpt at nb_clk_div_ticks
|
|
201
|
secondary_cpt <= secondary_cpt + 1;
|
|
226
|
secondary_cpt <= secondary_cpt + 1;
|
|
202
|
else
|
|
227
|
ELSE
|
|
203
|
cpt <= cpt + 1;
|
|
228
|
cpt <= cpt + 1;
|
|
204
|
end if;
|
|
229
|
END IF;
|
|
|
|
|
230
|
END IF;
|
|
205
|
|
|
231
|
|
|
206
|
when others =>
|
|
232
|
WHEN OTHERS =>
|
|
207
|
state <= auto;
|
|
233
|
state <= auto;
|
|
208
|
|
|
234
|
|
|
209
|
end case;
|
|
235
|
END CASE;
|
|
210
|
|
|
236
|
|
|
211
|
if secondary_cpt > 60 then
|
|
237
|
IF secondary_cpt > 60 THEN
|
|
212
|
s_coarse_time(31) <= '1';
|
|
238
|
s_coarse_time(31) <= '1';
|
|
213
|
end if;
|
|
239
|
END IF;
|
|
214
|
|
|
240
|
|
|
215
|
if not(previous_coarse_time_load = coarse_time_load) then
|
|
241
|
IF NOT(previous_coarse_time_load = coarse_time_load) THEN
|
|
216
|
flag <= '1';
|
|
242
|
flag <= '1';
|
|
217
|
end if;
|
|
243
|
END IF;
|
|
218
|
|
|
244
|
|
|
219
|
previous_coarse_time_load <= coarse_time_load;
|
|
245
|
previous_coarse_time_load <= coarse_time_load;
|
|
220
|
|
|
246
|
|
|
221
|
end if;
|
|
247
|
END IF;
|
|
222
|
|
|
248
|
|
|
223
|
end process;
|
|
249
|
END PROCESS;
|
|
224
|
|
|
250
|
|
|
225
|
fine_time <= std_logic_vector(to_unsigned(cpt, 32));
|
|
251
|
fine_time <= STD_LOGIC_VECTOR(to_unsigned(cpt, 32));
|
|
226
|
|
|
252
|
|
|
227
|
-- resetn grspw_tick soft_tick resetn_clk_div
|
|
253
|
-- resetn grspw_tick soft_tick resetn_clk_div
|
|
228
|
-- 0 0 0 0
|
|
254
|
-- 0 0 0 0
|
|
@@
-233,8
+259,8
fine_time <= std_logic_vector(to_unsigne
|
|
233
|
-- 1 0 1 0
|
|
259
|
-- 1 0 1 0
|
|
234
|
-- 1 1 0 0
|
|
260
|
-- 1 1 0 0
|
|
235
|
-- 1 1 1 0
|
|
261
|
-- 1 1 1 0
|
|
236
|
resetn_clk_div <= '1' when ( (resetn='1') and (grspw_tick='0') and (soft_tick='0') ) else '0';
|
|
262
|
resetn_clk_div <= '1' WHEN ((resetn = '1') AND (grspw_tick = '0') AND (soft_tick = '0')) ELSE '0';
|
|
237
|
Clk_divider0 : Clk_divider -- the target frequency is 65536 Hz
|
|
263
|
Clk_divider0 : Clk_divider -- the target frequency is 65536 Hz
|
|
238
|
generic map (timeclk,finetimeclk) port map ( time_clock, resetn_clk_div, clk_div);
|
|
264
|
GENERIC MAP (timeclk, finetimeclk) PORT MAP (time_clock, resetn_clk_div, clk_div);
|
|
239
|
|
|
265
|
|
|
240
|
end Behavioral;
No newline at end of file
|
|
266
|
END Behavioral;
|