##// END OF EJS Templates
Fusion avec paul
pellion -
r164:7758f0659e3e merge JC
parent child
Show More
@@ -0,0 +1,174
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 11:17:05 07/02/2012
6 -- Design Name:
7 -- Module Name: apb_lfr_time_management - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.NUMERIC_STD.ALL;
23 library grlib;
24 use grlib.amba.all;
25 use grlib.stdlib.all;
26 use grlib.devices.all;
27 library lpp;
28 use lpp.apb_devices_list.all;
29 use lpp.lpp_lfr_time_management.all;
30
31 entity apb_lfr_time_management is
32
33 generic(
34 pindex : integer := 0; --! APB slave index
35 paddr : integer := 0; --! ADDR field of the APB BAR
36 pmask : integer := 16#fff#; --! MASK field of the APB BAR
37 pirq : integer := 0; --! 2 consecutive IRQ lines are used
38 masterclk : integer := 25000000; --! master clock in Hz
39 otherclk : integer := 49152000; --! other clock in Hz
40 finetimeclk : integer := 65536 --! divided clock used for the fine time counter
41 );
42
43 Port (
44 clk25MHz : in STD_LOGIC; --! Clock
45 clk49_152MHz : in STD_LOGIC; --! secondary clock
46 resetn : in STD_LOGIC; --! Reset
47 grspw_tick : in STD_LOGIC; --! grspw signal asserted when a valid time-code is received
48 apbi : in apb_slv_in_type; --! APB slave input signals
49 apbo : out apb_slv_out_type; --! APB slave output signals
50 coarse_time : out std_logic_vector(31 downto 0); --! coarse time
51 fine_time : out std_logic_vector(31 downto 0) --! fine time
52 );
53
54 end apb_lfr_time_management;
55
56 architecture Behavioral of apb_lfr_time_management is
57
58 constant REVISION : integer := 1;
59
60 --! the following types are defined in the grlib amba package
61 --! subtype amba_config_word is std_logic_vector(31 downto 0);
62 --! type apb_config_type is array (0 to NAPBCFG-1) of amba_config_word;
63 constant pconfig : apb_config_type := (
64 --! 0 => ahb_device_reg (VENDOR_LPP, LPP_ROTARY, 0, REVISION, 0),
65 0 => ahb_device_reg (19, 14, 0, REVISION, pirq),
66 1 => apb_iobar(paddr, pmask));
67
68 type apb_lfr_time_management_Reg is record
69 ctrl : std_logic_vector(31 downto 0);
70 coarse_time_load : std_logic_vector(31 downto 0);
71 coarse_time : std_logic_vector(31 downto 0);
72 fine_time : std_logic_vector(31 downto 0);
73 next_commutation : std_logic_vector(31 downto 0);
74 end record;
75
76 signal r : apb_lfr_time_management_Reg;
77 signal Rdata : std_logic_vector(31 downto 0);
78 signal force_tick : std_logic;
79 signal previous_force_tick : std_logic;
80 signal soft_tick : std_logic;
81 signal reset_next_commutation : std_logic;
82
83 begin
84
85 lfrtimemanagement0: lfr_time_management
86 generic map(masterclk => masterclk, timeclk => otherclk, finetimeclk => finetimeclk)
87 Port map( master_clock => clk25MHz, time_clock => clk49_152MHz, resetn => resetn,
88 grspw_tick => grspw_tick, soft_tick => soft_tick,
89 coarse_time_load => r.coarse_time_load, coarse_time => r.coarse_time, fine_time => r.fine_time,
90 next_commutation => r.next_commutation, reset_next_commutation => reset_next_commutation,
91 irq1 => apbo.pirq(pirq), irq2 => apbo.pirq(pirq+1) );
92
93 process(resetn,clk25MHz, reset_next_commutation)
94 begin
95
96 if resetn = '0' then
97 r.coarse_time_load <= x"80000000";
98 r.ctrl <= x"00000000";
99 r.next_commutation <= x"ffffffff";
100 force_tick <= '0';
101 previous_force_tick <= '0';
102 soft_tick <= '0';
103
104 elsif reset_next_commutation = '1' then
105 r.next_commutation <= x"ffffffff";
106
107 elsif clk25MHz'event and clk25MHz = '1' then
108
109 previous_force_tick <= force_tick;
110 force_tick <= r.ctrl(0);
111 if (previous_force_tick = '0') and (force_tick = '1') then
112 soft_tick <= '1';
113 else
114 soft_tick <= '0';
115 end if;
116
117 --APB Write OP
118 if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
119 case apbi.paddr(7 downto 2) is
120 when "000000" =>
121 r.ctrl <= apbi.pwdata(31 downto 0);
122 when "000001" =>
123 r.coarse_time_load <= apbi.pwdata(31 downto 0);
124 when "000100" =>
125 r.next_commutation <= apbi.pwdata(31 downto 0);
126 when others =>
127 r.coarse_time_load <= x"00000000";
128 end case;
129 elsif r.ctrl(0) = '1' then
130 r.ctrl(0) <= '0';
131 end if;
132
133 --APB READ OP
134 if (apbi.psel(pindex) and (not apbi.pwrite)) = '1' then
135 case apbi.paddr(7 downto 2) is
136 when "000000" =>
137 Rdata(31 downto 24) <= r.ctrl(31 downto 24);
138 Rdata(23 downto 16) <= r.ctrl(23 downto 16);
139 Rdata(15 downto 8) <= r.ctrl(15 downto 8);
140 Rdata(7 downto 0) <= r.ctrl(7 downto 0);
141 when "000001" =>
142 Rdata(31 downto 24) <= r.coarse_time_load(31 downto 24);
143 Rdata(23 downto 16) <= r.coarse_time_load(23 downto 16);
144 Rdata(15 downto 8) <= r.coarse_time_load(15 downto 8);
145 Rdata(7 downto 0) <= r.coarse_time_load(7 downto 0);
146 when "000010" =>
147 Rdata(31 downto 24) <= r.coarse_time(31 downto 24);
148 Rdata(23 downto 16) <= r.coarse_time(23 downto 16);
149 Rdata(15 downto 8) <= r.coarse_time(15 downto 8);
150 Rdata(7 downto 0) <= r.coarse_time(7 downto 0);
151 when "000011" =>
152 Rdata(31 downto 24) <= r.fine_time(31 downto 24);
153 Rdata(23 downto 16) <= r.fine_time(23 downto 16);
154 Rdata(15 downto 8) <= r.fine_time(15 downto 8);
155 Rdata(7 downto 0) <= r.fine_time(7 downto 0);
156 when "000100" =>
157 Rdata(31 downto 24) <= r.next_commutation(31 downto 24);
158 Rdata(23 downto 16) <= r.next_commutation(23 downto 16);
159 Rdata(15 downto 8) <= r.next_commutation(15 downto 8);
160 Rdata(7 downto 0) <= r.next_commutation(7 downto 0);
161 when others =>
162 Rdata(31 downto 0) <= x"00000000";
163 end case;
164 end if;
165
166 end if;
167 apbo.pconfig <= pconfig;
168 end process;
169
170 apbo.prdata <= Rdata when apbi.penable = '1' ;
171 coarse_time <= r.coarse_time;
172 fine_time <= r.fine_time;
173
174 end Behavioral; No newline at end of file
@@ -0,0 +1,240
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 11:14:05 07/02/2012
6 -- Design Name:
7 -- Module Name: lfr_time_management - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.NUMERIC_STD.ALL;
23 library lpp;
24 use lpp.general_purpose.Clk_divider;
25
26 entity lfr_time_management is
27 generic (
28 masterclk : integer := 25000000; -- master clock in Hz
29 timeclk : integer := 49152000; -- 2nd clock in Hz
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
32 );
33 Port (
34 master_clock : in std_logic; --! Clock
35 time_clock : in std_logic; --! 2nd Clock
36 resetn : in std_logic; --! Reset
37 grspw_tick : in std_logic;
38 soft_tick : in std_logic; --! soft tick, load the coarse_time value
39 coarse_time_load : in 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);
42 next_commutation : in std_logic_vector(31 downto 0);
43 reset_next_commutation: out std_logic;
44 irq1 : out std_logic;
45 irq2 : out std_logic
46 );
47 end lfr_time_management;
48
49 architecture Behavioral of lfr_time_management is
50
51 signal resetn_clk_div : std_logic;
52 signal clk_div : std_logic;
53 --
54 signal flag : std_logic;
55 signal s_coarse_time : 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;
58 signal secondary_cpt : integer range 0 to 72000;
59 --
60 signal sirq1 : std_logic;
61 signal sirq2 : std_logic;
62 signal cpt_next_commutation : integer range 0 to 100000;
63 signal p_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;
66 --
67 type state_type is (auto, slave);
68 signal state : state_type;
69 type timer_type is (idle, engaged);
70 signal commutation_timer : timer_type;
71
72 begin
73
74 --*******************************************
75 -- COMMUTATION TIMER AND INTERRUPT GENERATION
76 process(master_clock, resetn)
77 begin
78
79 if resetn = '0' then
80 commutation_timer <= idle;
81 cpt_next_commutation <= 0;
82 sirq1 <= '0';
83 sirq2 <= '0';
84 latched_next_commutation <= x"ffffffff";
85
86 elsif master_clock'event and master_clock = '1' then
87
88 case commutation_timer is
89
90 when idle =>
91 sirq1 <= '0';
92 sirq2 <= '0';
93 if s_coarse_time = latched_next_commutation then
94 commutation_timer <= engaged; -- transition to state "engaged"
95 sirq1 <= '1'; -- start the pulse on sirq1
96 latched_next_commutation <= x"ffffffff";
97 elsif not(p_next_commutation = next_commutation) then -- next_commutation has changed
98 latched_next_commutation <= next_commutation; -- latch the value
99 else
100 commutation_timer <= idle;
101 end if;
102
103 when engaged =>
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
106 if cpt_next_commutation = 65536 then
107 cpt_next_commutation <= 0;
108 commutation_timer <= idle;
109 sirq2 <= '1'; -- start the pulse on sirq2
110 else
111 cpt_next_commutation <= cpt_next_commutation + 1;
112 end if;
113 end if;
114
115 when others =>
116 commutation_timer <= idle;
117
118 end case;
119
120 p_next_commutation <= next_commutation;
121 p_clk_div <= clk_div;
122
123 end if;
124
125 end process;
126
127 irq1 <= sirq1;
128 irq2 <= sirq2;
129 reset_next_commutation <= '0';
130
131 --
132 --*******************************************
133
134 --**********************
135 -- synchronization stage
136 process(master_clock, resetn) -- resynchronisation with clk
137 begin
138
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
141
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
144 end if;
145
146 end process;
147 --
148 --**********************
149
150
151 process(clk_div, resetn, grspw_tick, soft_tick, flag, coarse_time_load) --
152 begin
153
154 if resetn = '0' then
155 flag <= '0';
156 cpt <= 0;
157 secondary_cpt <= 0;
158 s_coarse_time <= x"80000000"; -- set the most significant bit of the coarse time to 1 on reset
159 previous_coarse_time_load <= x"80000000";
160 state <= auto;
161
162 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 s_coarse_time <= coarse_time_load;
165 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;
170 secondary_cpt <= 0;
171 state <= slave;
172
173 elsif clk_div'event and clk_div = '1' then
174
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;
181 flag <= '0';
182 else
183 s_coarse_time <= std_logic_vector(unsigned(s_coarse_time) + 1);
184 end if;
185 cpt <= 0;
186 secondary_cpt <= secondary_cpt + 1;
187 else
188 cpt <= cpt + 1 ;
189 end if;
190
191 when slave =>
192 if cpt = 65536 + nb_clk_div_ticks then -- 1 / 65536 = 15.259 us
193 state <= auto; -- commutation to AUTO state
194 if flag = '1' then
195 s_coarse_time <= coarse_time_load;
196 flag <= '0';
197 else
198 s_coarse_time <= std_logic_vector(unsigned(s_coarse_time) + 1);
199 end if;
200 cpt <= nb_clk_div_ticks; -- reset cpt at nb_clk_div_ticks
201 secondary_cpt <= secondary_cpt + 1;
202 else
203 cpt <= cpt + 1;
204 end if;
205
206 when others =>
207 state <= auto;
208
209 end case;
210
211 if secondary_cpt > 60 then
212 s_coarse_time(31) <= '1';
213 end if;
214
215 if not(previous_coarse_time_load = coarse_time_load) then
216 flag <= '1';
217 end if;
218
219 previous_coarse_time_load <= coarse_time_load;
220
221 end if;
222
223 end process;
224
225 fine_time <= std_logic_vector(to_unsigned(cpt, 32));
226
227 -- resetn grspw_tick soft_tick resetn_clk_div
228 -- 0 0 0 0
229 -- 0 0 1 0
230 -- 0 1 0 0
231 -- 0 1 1 0
232 -- 1 0 0 1
233 -- 1 0 1 0
234 -- 1 1 0 0
235 -- 1 1 1 0
236 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
238 generic map (timeclk,finetimeclk) port map ( time_clock, resetn_clk_div, clk_div);
239
240 end Behavioral; No newline at end of file
@@ -0,0 +1,83
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 13:04:01 07/02/2012
6 -- Design Name:
7 -- Module Name: lpp_lfr_time_management - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.all;
22 library grlib;
23 use grlib.amba.all;
24 use grlib.stdlib.all;
25 use grlib.devices.all;
26
27 package lpp_lfr_time_management is
28
29 --***************************
30 -- APB_LFR_TIME_MANAGEMENT
31
32 component apb_lfr_time_management is
33
34 generic(
35 pindex : integer := 0; --! APB slave index
36 paddr : integer := 0; --! ADDR field of the APB BAR
37 pmask : integer := 16#fff#; --! MASK field of the APB BAR
38 pirq : integer := 0; --! 2 consecutive IRQ lines are used
39 masterclk : integer := 25000000; --! master clock in Hz
40 timeclk : integer := 49152000; --! other clock in Hz
41 finetimeclk : integer := 65536 --! divided clock used for the fine time counter
42 );
43
44 Port (
45 clk25MHz : in STD_LOGIC; --! Clock
46 clk49_152MHz : in STD_LOGIC; --! secondary clock
47 resetn : in STD_LOGIC; --! Reset
48 grspw_tick : in STD_LOGIC; --! grspw signal asserted when a valid time-code is received
49 apbi : in apb_slv_in_type; --! APB slave input signals
50 apbo : out apb_slv_out_type; --! APB slave output signals
51 coarse_time : out std_logic_vector(31 downto 0); --! coarse time
52 fine_time : out std_logic_vector(31 downto 0) --! fine time
53 );
54
55 end component;
56
57 component lfr_time_management is
58
59 generic (
60 masterclk : integer := 25000000; -- master clock in Hz
61 timeclk : integer := 49152000; -- 2nd clock in Hz
62 finetimeclk : integer := 65536; -- divided clock used for the fine time counter
63 nb_clk_div_ticks : integer := 1 -- nb ticks before commutation to AUTO state
64 );
65 Port (
66 master_clock : in std_logic; --! Clock
67 time_clock : in std_logic; --! 2nd Clock
68 resetn : in std_logic; --! Reset
69 grspw_tick : in std_logic;
70 soft_tick : in std_logic; --! soft tick, load the coarse_time value
71 coarse_time_load : in std_logic_vector(31 downto 0);
72 coarse_time : out std_logic_vector(31 downto 0);
73 fine_time : out std_logic_vector(31 downto 0);
74 next_commutation : in std_logic_vector(31 downto 0);
75 reset_next_commutation: out std_logic;
76 irq1 : out std_logic;
77 irq2 : out std_logic
78 );
79
80 end component;
81
82 end lpp_lfr_time_management;
83
@@ -0,0 +1,3
1 apb_lfr_time_management.vhd
2 lfr_time_management.vhd
3 lpp_lfr_time_management.vhd
General Comments 0
You need to be logged in to leave comments. Login now