1 |
2 |
dsmv |
-------------------------------------------------------------------------------
|
2 |
|
|
--
|
3 |
|
|
-- Title : ctrl_main
|
4 |
|
|
-- Author : Dmitry Smekhov
|
5 |
|
|
-- Company : Instrumental Systems
|
6 |
|
|
-- E-mail : dsmv@insys.ru
|
7 |
|
|
--
|
8 |
|
|
-- Version : 1.3
|
9 |
|
|
--
|
10 |
|
|
-------------------------------------------------------------------------------
|
11 |
|
|
--
|
12 |
|
|
-- Description : Узел формирования команд для управления работой контроллера DMA
|
13 |
|
|
--
|
14 |
|
|
-------------------------------------------------------------------------------
|
15 |
|
|
--
|
16 |
|
|
-- Version 1.3 14.12.2011
|
17 |
|
|
-- Добавлены сигналы dsc_check_start, dsc_check_ready -
|
18 |
|
|
-- для управления подсчётом контрольной суммы после
|
19 |
|
|
-- чтения дескриптора
|
20 |
|
|
--
|
21 |
|
|
-------------------------------------------------------------------------------
|
22 |
|
|
--
|
23 |
|
|
-- Version 1.2 26.01.2011
|
24 |
|
|
-- Добавлена запись 40-битного начального адреса дескриптора
|
25 |
|
|
--
|
26 |
|
|
-------------------------------------------------------------------------------
|
27 |
|
|
--
|
28 |
|
|
-- Version 1.1 02.06.2009
|
29 |
|
|
-- Добавлено чередование приоритетов запуска каналов DMA
|
30 |
|
|
--
|
31 |
|
|
-------------------------------------------------------------------------------
|
32 |
|
|
|
33 |
|
|
library ieee;
|
34 |
|
|
use ieee.std_logic_1164.all;
|
35 |
|
|
|
36 |
|
|
package ctrl_main_pkg is
|
37 |
|
|
|
38 |
|
|
component ctrl_main is
|
39 |
|
|
port(
|
40 |
|
|
---- Global ----
|
41 |
|
|
reset : in std_logic; -- 0 - сброс
|
42 |
|
|
clk : in std_logic; -- тактовая частота
|
43 |
|
|
|
44 |
|
|
---- Регистры управления ----
|
45 |
|
|
dma0_ctrl : in std_logic_vector( 7 downto 0 ); -- Регистр DMA_CTRL, канал 0
|
46 |
|
|
dma1_ctrl : in std_logic_vector( 7 downto 0 ); -- Регистр DMA_CTRL, канал 0
|
47 |
|
|
|
48 |
|
|
---- ctrl_ext_ram ----
|
49 |
|
|
dma0_transfer_rdy : in std_logic; -- 1 - канал 0 готов к обмену
|
50 |
|
|
dma1_transfer_rdy : in std_logic; -- 1 - канал 1 готов к обмену
|
51 |
|
|
|
52 |
|
|
---- Управление DMA ----
|
53 |
|
|
dma_chn : out std_logic; -- номер канала DMA для текущего обмена
|
54 |
|
|
ram_do : out std_logic_vector( 7 downto 0 ); -- данные для записи в регистр STATUS
|
55 |
|
|
ram_adr : out std_logic_vector( 8 downto 0 ); -- адрес для записи в регистр STATUS
|
56 |
|
|
ram_we : out std_logic; -- 1 - запись в память
|
57 |
|
|
dma0_eot_clr : in std_logic; -- 1 - сброс флага DMA0_EOT
|
58 |
|
|
dma1_eot_clr : in std_logic; -- 1 - сброс флага DMA1_EOT
|
59 |
|
|
|
60 |
|
|
reg_dma0_status : out std_logic_vector( 15 downto 0 ); -- регистр STATUS канала 0
|
61 |
|
|
reg_dma1_status : out std_logic_vector( 15 downto 0 ); -- регистр STATUS канала 1
|
62 |
|
|
|
63 |
|
|
---- ctrl_ext_ram ----
|
64 |
|
|
ram_change : out std_logic; -- 1 - изменение блока памяти
|
65 |
|
|
loc_adr_we : out std_logic; -- 1 - запись локального адреса
|
66 |
|
|
|
67 |
|
|
---- ctrl_ext_descriptor ----
|
68 |
|
|
pci_adr_we : out std_logic; -- 1 - запись адреса
|
69 |
|
|
pci_adr_h_we : out std_logic; -- 1 - запись старших разрядов адреса
|
70 |
|
|
dsc_correct : in std_logic; -- 1 - загружен правильный дескриптор
|
71 |
|
|
dsc_cmd : in std_logic_vector( 7 downto 0 ); -- командное слово дескриптора
|
72 |
|
|
dsc_change_adr : out std_logic; -- 1 - смена адреса дескриптора
|
73 |
|
|
dsc_change_mode : out std_logic; -- Режим изменения адреса:
|
74 |
|
|
-- 0: - увеличение
|
75 |
|
|
-- 1: - переход к нулевомй дескриптору
|
76 |
|
|
dsc_load_en : out std_logic; -- 1 - разрешение записи дескриптора
|
77 |
|
|
dsc_check_start : out std_logic; -- 1 - проверка дескриптора
|
78 |
|
|
dsc_check_ready : in std_logic; -- 1 - проверка завершена
|
79 |
|
|
|
80 |
|
|
---- ctrl_dma_ext_cmd ----
|
81 |
|
|
dma_reg0 : out std_logic_vector( 2 downto 0 ); -- регистр упрравления
|
82 |
|
|
dma_change_adr : out std_logic ; -- 1 - изменение адреса и размера
|
83 |
|
|
dma_status : in std_logic_vector( 2 downto 0 ) -- состояние DMA
|
84 |
|
|
-- 0: 1 - завершение обмена
|
85 |
|
|
-- 1: 1 - ошибка при обмене
|
86 |
|
|
-- 2: 1 - размер блока равен 0
|
87 |
|
|
);
|
88 |
|
|
|
89 |
|
|
end component;
|
90 |
|
|
|
91 |
|
|
end package;
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
|
95 |
|
|
library ieee;
|
96 |
|
|
use ieee.std_logic_1164.all;
|
97 |
|
|
use ieee.std_logic_arith.all;
|
98 |
|
|
use ieee.std_logic_unsigned.all;
|
99 |
|
|
|
100 |
|
|
library unisim;
|
101 |
|
|
use unisim.vcomponents.all;
|
102 |
|
|
|
103 |
|
|
|
104 |
|
|
entity ctrl_main is
|
105 |
|
|
port(
|
106 |
|
|
---- Global ----
|
107 |
|
|
reset : in std_logic; -- 0 - сброс
|
108 |
|
|
clk : in std_logic; -- тактовая частота
|
109 |
|
|
|
110 |
|
|
---- Регистры управления ----
|
111 |
|
|
dma0_ctrl : in std_logic_vector( 7 downto 0 ); -- Регистр DMA_CTRL, канал 0
|
112 |
|
|
dma1_ctrl : in std_logic_vector( 7 downto 0 ); -- Регистр DMA_CTRL, канал 0
|
113 |
|
|
|
114 |
|
|
---- ctrl_ext_ram ----
|
115 |
|
|
dma0_transfer_rdy : in std_logic; -- 1 - канал 0 готов к обмену
|
116 |
|
|
dma1_transfer_rdy : in std_logic; -- 1 - канал 1 готов к обмену
|
117 |
|
|
|
118 |
|
|
---- Управление DMA ----
|
119 |
|
|
dma_chn : out std_logic; -- номер канала DMA для текущего обмена
|
120 |
|
|
ram_do : out std_logic_vector( 7 downto 0 ); -- данные для записи в регистр STATUS
|
121 |
|
|
ram_adr : out std_logic_vector( 8 downto 0 ); -- адрес для записи в регистр STATUS
|
122 |
|
|
ram_we : out std_logic; -- 1 - запись в память
|
123 |
|
|
dma0_eot_clr : in std_logic; -- 1 - сброс флага DMA0_EOT
|
124 |
|
|
dma1_eot_clr : in std_logic; -- 1 - сброс флага DMA1_EOT
|
125 |
|
|
|
126 |
|
|
reg_dma0_status : out std_logic_vector( 15 downto 0 ); -- регистр STATUS канала 0
|
127 |
|
|
reg_dma1_status : out std_logic_vector( 15 downto 0 ); -- регистр STATUS канала 1
|
128 |
|
|
|
129 |
|
|
---- ctrl_ext_ram ----
|
130 |
|
|
ram_change : out std_logic; -- 1 - изменение блока памяти
|
131 |
|
|
loc_adr_we : out std_logic; -- 1 - запись локального адреса
|
132 |
|
|
|
133 |
|
|
---- ctrl_ext_descriptor ----
|
134 |
|
|
pci_adr_we : out std_logic; -- 1 - запись адреса
|
135 |
|
|
pci_adr_h_we : out std_logic; -- 1 - запись старших разрядов адреса
|
136 |
|
|
dsc_correct : in std_logic; -- 1 - загружен правильный дескриптор
|
137 |
|
|
dsc_cmd : in std_logic_vector( 7 downto 0 ); -- командное слово дескриптора
|
138 |
|
|
dsc_change_adr : out std_logic; -- 1 - смена адреса дескриптора
|
139 |
|
|
dsc_change_mode : out std_logic; -- Режим изменения адреса:
|
140 |
|
|
-- 0: - увеличение
|
141 |
|
|
-- 1: - переход к нулевомй дескриптору
|
142 |
|
|
dsc_load_en : out std_logic; -- 1 - разрешение записи дескриптора
|
143 |
|
|
dsc_check_start : out std_logic; -- 1 - проверка дескриптора
|
144 |
|
|
dsc_check_ready : in std_logic; -- 1 - проверка завершена
|
145 |
|
|
|
146 |
|
|
---- ctrl_dma_ext_cmd ----
|
147 |
|
|
dma_reg0 : out std_logic_vector( 2 downto 0 ); -- регистр упрравления
|
148 |
|
|
dma_change_adr : out std_logic ; -- 1 - изменение адреса и размера
|
149 |
|
|
dma_status : in std_logic_vector( 2 downto 0 ) -- состояние DMA
|
150 |
|
|
-- 0: 1 - завершение обмена
|
151 |
|
|
-- 1: 1 - ошибка при обмене
|
152 |
|
|
-- 2: 1 - размер блока равен 0
|
153 |
|
|
);
|
154 |
|
|
end ctrl_main;
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
architecture ctrl_main of ctrl_main is
|
158 |
|
|
|
159 |
|
|
signal dma0_eot : std_logic; -- 1 - завершение передачи блока канала 0
|
160 |
|
|
signal dma1_eot : std_logic; -- 1 - завершение передачи блока канала 1
|
161 |
|
|
signal dma0_sg_eot : std_logic; -- 1 - завершение работы канала 0
|
162 |
|
|
signal dma1_sg_eot : std_logic; -- 1 - завершение работы канала 1
|
163 |
|
|
|
164 |
|
|
signal dma_eot_set : std_logic;
|
165 |
|
|
signal dma_sg_eot_set : std_logic;
|
166 |
|
|
|
167 |
|
|
signal ra : std_logic_vector( 7 downto 0 ); -- адрес памяти автомата
|
168 |
|
|
signal dma_chni : std_logic:='0'; -- номер выбранного канала DMA
|
169 |
|
|
|
170 |
|
|
signal ram_a_adr : std_logic_vector( 8 downto 0 );
|
171 |
|
|
signal ram_a_out : std_logic_vector( 31 downto 0 );
|
172 |
|
|
|
173 |
|
|
signal rstp : std_logic;
|
174 |
|
|
signal dma_chn_change_en : std_logic;
|
175 |
|
|
|
176 |
|
|
signal dma0_ctrl_z : std_logic;
|
177 |
|
|
signal dma1_ctrl_z : std_logic;
|
178 |
|
|
|
179 |
|
|
signal dma0_flag_start : std_logic;
|
180 |
|
|
signal dma1_flag_start : std_logic;
|
181 |
|
|
signal dma_flag_start : std_logic;
|
182 |
|
|
signal dma_flag_start_clr : std_logic;
|
183 |
|
|
signal dma_transfer_start : std_logic;
|
184 |
|
|
signal dma_chn_change : std_logic;
|
185 |
|
|
|
186 |
|
|
signal dma0_start : std_logic;
|
187 |
|
|
signal dma1_start : std_logic;
|
188 |
|
|
signal ram_adr_l : std_logic_vector( 2 downto 0 );
|
189 |
|
|
signal dma_start : std_logic;
|
190 |
|
|
|
191 |
|
|
signal dma0_wait_eot : std_logic;
|
192 |
|
|
signal dma1_wait_eot : std_logic;
|
193 |
|
|
|
194 |
|
|
signal dma0_wait_eot2 : std_logic;
|
195 |
|
|
signal dma1_wait_eot2 : std_logic;
|
196 |
|
|
|
197 |
|
|
type st_type is ( s0, s01, s1, s2, s3, s3_01, s4, s4_01, st0, st1, st20, st2, sc0, sc1, sc2, sc3, sc4, sr0, sr1, sr2, sr3, sr4, sr5, sr5_01, sr6 );
|
198 |
|
|
signal stp : st_type;
|
199 |
|
|
|
200 |
|
|
---- Доступ к регистрам ----
|
201 |
|
|
---- 00 - STATUS
|
202 |
|
|
---- 10 - PCI_ADR_L
|
203 |
|
|
---- 11 - LOC_ADR
|
204 |
|
|
signal ram_sel : std_logic_vector( 2 downto 0 );
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
type stw_type is ( s0, s01, s02, s03, s1, s2, s3, s4, s5, s6, s7 );
|
208 |
|
|
signal stw : stw_type;
|
209 |
|
|
|
210 |
|
|
|
211 |
|
|
signal init_compelte : std_logic;
|
212 |
|
|
|
213 |
|
|
signal dma_rotate : std_logic;
|
214 |
|
|
|
215 |
|
|
signal dma0_block : std_logic;
|
216 |
|
|
signal dma1_block : std_logic;
|
217 |
|
|
signal dma0_block_in : std_logic;
|
218 |
|
|
signal dma1_block_in : std_logic;
|
219 |
|
|
signal dma0_block_z : std_logic;
|
220 |
|
|
signal dma1_block_z : std_logic;
|
221 |
|
|
|
222 |
|
|
begin
|
223 |
|
|
|
224 |
|
|
|
225 |
|
|
|
226 |
|
|
rstp <= not reset after 1 ns when rising_edge( clk );
|
227 |
|
|
|
228 |
|
|
dma0_ctrl_z <= dma0_ctrl(0) after 1 ns when rising_edge( clk );
|
229 |
|
|
dma1_ctrl_z <= dma1_ctrl(0) after 1 ns when rising_edge( clk );
|
230 |
|
|
|
231 |
|
|
pr_dma_flag_start: process( clk ) begin
|
232 |
|
|
if( rising_edge( clk ) ) then
|
233 |
|
|
if( dma0_ctrl(0)='0' or (dma_flag_start_clr='1' and dma_chni='0' ) ) then
|
234 |
|
|
dma0_flag_start <= '0' after 1 ns;
|
235 |
|
|
elsif( dma0_ctrl_z='0' ) then
|
236 |
|
|
dma0_flag_start <= '1' after 1 ns;
|
237 |
|
|
end if;
|
238 |
|
|
|
239 |
|
|
if( dma1_ctrl(0)='0' or (dma_flag_start_clr='1' and dma_chni='1' ) ) then
|
240 |
|
|
dma1_flag_start <= '0' after 1 ns;
|
241 |
|
|
elsif( dma1_ctrl_z='0' ) then
|
242 |
|
|
dma1_flag_start <= '1' after 1 ns;
|
243 |
|
|
end if;
|
244 |
|
|
end if;
|
245 |
|
|
end process;
|
246 |
|
|
|
247 |
|
|
|
248 |
|
|
---- Выбор канала для обмена ----
|
249 |
|
|
pr_chn: process( clk ) begin
|
250 |
|
|
if( rising_edge( clk ) ) then
|
251 |
|
|
if( rstp='1' ) then
|
252 |
|
|
dma_chni <= not dma_chni after 1 ns;
|
253 |
|
|
dma_flag_start <= '0' after 1 ns;
|
254 |
|
|
dma_transfer_start <= '0' after 1 ns;
|
255 |
|
|
dma_rotate <= '0' after 1 ns;
|
256 |
|
|
else
|
257 |
|
|
if( dma_chn_change='1' ) then
|
258 |
|
|
|
259 |
|
|
if( dma_transfer_start='0' and dma_flag_start='0' ) then
|
260 |
|
|
if( dma0_flag_start='1' ) then
|
261 |
|
|
dma_chni <= '0' after 1 ns;
|
262 |
|
|
dma_flag_start <= '1' after 1 ns;
|
263 |
|
|
dma_rotate <= '0' after 1 ns;
|
264 |
|
|
elsif( dma1_flag_start='1' ) then
|
265 |
|
|
dma_chni <= '1' after 1 ns;
|
266 |
|
|
dma_flag_start <= '1' after 1 ns;
|
267 |
|
|
dma_rotate <= '1' after 1 ns;
|
268 |
|
|
elsif( dma0_transfer_rdy='1' and dma0_sg_eot='0' and dma0_wait_eot='0' and dma0_block_z='0' and dma_rotate='0' ) then
|
269 |
|
|
dma_chni <= '0' after 1 ns;
|
270 |
|
|
dma_transfer_start <= '1' after 1 ns;
|
271 |
|
|
dma_rotate <= '1' after 1 ns;
|
272 |
|
|
elsif( dma1_transfer_rdy='1' and dma1_sg_eot='0' and dma1_wait_eot='0' and dma1_block_z='0' and dma_rotate='1' ) then
|
273 |
|
|
dma_chni <= '1' after 1 ns;
|
274 |
|
|
dma_transfer_start <= '1' after 1 ns;
|
275 |
|
|
dma_rotate <= '0' after 1 ns;
|
276 |
|
|
else
|
277 |
|
|
dma_rotate <= not dma_rotate after 1 ns;
|
278 |
|
|
end if;
|
279 |
|
|
end if;
|
280 |
|
|
else
|
281 |
|
|
dma_flag_start <= '0' after 1 ns;
|
282 |
|
|
dma_transfer_start <= '0' after 1 ns;
|
283 |
|
|
end if;
|
284 |
|
|
|
285 |
|
|
|
286 |
|
|
|
287 |
|
|
end if;
|
288 |
|
|
end if;
|
289 |
|
|
end process;
|
290 |
|
|
|
291 |
|
|
dma_chn <= dma_chni;
|
292 |
|
|
|
293 |
|
|
---- Инициализация ----
|
294 |
|
|
pr_init: process( clk ) begin
|
295 |
|
|
if( rising_edge( clk ) ) then
|
296 |
|
|
case( stw ) is
|
297 |
|
|
when s0 =>
|
298 |
|
|
ram_sel <= "000" after 1 ns;
|
299 |
|
|
pci_adr_we <= '0' after 1 ns;
|
300 |
|
|
pci_adr_h_we <= '0' after 1 ns;
|
301 |
|
|
loc_adr_we <= '0' after 1 ns;
|
302 |
|
|
init_compelte <= '0' after 1 ns;
|
303 |
|
|
if( stp=s1 ) then
|
304 |
|
|
stw <= s01 after 1 ns;
|
305 |
|
|
end if;
|
306 |
|
|
|
307 |
|
|
when s01 =>
|
308 |
|
|
ram_sel <= "101" after 1 ns;
|
309 |
|
|
stw <= s02 after 1 ns;
|
310 |
|
|
|
311 |
|
|
when s02 =>
|
312 |
|
|
pci_adr_h_we <= '1' after 1 ns;
|
313 |
|
|
stw <= s03 after 1 ns;
|
314 |
|
|
|
315 |
|
|
when s03 =>
|
316 |
|
|
pci_adr_h_we <= '0' after 1 ns;
|
317 |
|
|
stw <= s1 after 1 ns;
|
318 |
|
|
|
319 |
|
|
|
320 |
|
|
when s1 =>
|
321 |
|
|
ram_sel <= "100" after 1 ns;
|
322 |
|
|
stw <= s2 after 1 ns;
|
323 |
|
|
|
324 |
|
|
when s2 =>
|
325 |
|
|
pci_adr_we <= '1' after 1 ns;
|
326 |
|
|
stw <= s3 after 1 ns;
|
327 |
|
|
|
328 |
|
|
when s3 =>
|
329 |
|
|
pci_adr_we <= '0' after 1 ns;
|
330 |
|
|
stw <= s4 after 1 ns;
|
331 |
|
|
|
332 |
|
|
when s4 =>
|
333 |
|
|
ram_sel <= "111" after 1 ns;
|
334 |
|
|
stw <= s5 after 1 ns;
|
335 |
|
|
|
336 |
|
|
when s5 =>
|
337 |
|
|
loc_adr_we <= '1' after 1 ns;
|
338 |
|
|
stw <= s6 after 1 ns;
|
339 |
|
|
|
340 |
|
|
when s6 =>
|
341 |
|
|
loc_adr_we <= '0' after 1 ns;
|
342 |
|
|
stw <= s7 after 1 ns;
|
343 |
|
|
|
344 |
|
|
when s7 =>
|
345 |
|
|
ram_sel <= "000" after 1 ns;
|
346 |
|
|
init_compelte <= '1' after 1 ns;
|
347 |
|
|
|
348 |
|
|
end case;
|
349 |
|
|
|
350 |
|
|
if( stp=s0 or stp=s01 ) then
|
351 |
|
|
stw <= s0 after 1 ns;
|
352 |
|
|
end if;
|
353 |
|
|
end if;
|
354 |
|
|
end process;
|
355 |
|
|
|
356 |
|
|
---- Управление переходами ----
|
357 |
|
|
pr_state: process( clk ) begin
|
358 |
|
|
if( rising_edge( clk ) ) then
|
359 |
|
|
|
360 |
|
|
case( stp ) is
|
361 |
|
|
when s0 =>
|
362 |
|
|
dma_chn_change <= '1' after 1 ns;
|
363 |
|
|
if( dma_flag_start='1' ) then
|
364 |
|
|
stp <= s01 after 1 ns;
|
365 |
|
|
elsif( dma_transfer_start='1' ) then
|
366 |
|
|
stp <= st0 after 1 ns;
|
367 |
|
|
end if;
|
368 |
|
|
dsc_load_en <= '0' after 1 ns;
|
369 |
|
|
dma_reg0 <= "110" after 1 ns;
|
370 |
|
|
dma_flag_start_clr <= '0' after 1 ns;
|
371 |
|
|
dma_change_adr <= '0' after 1 ns;
|
372 |
|
|
dsc_change_adr <= '0' after 1 ns;
|
373 |
|
|
dsc_change_mode <= '0' after 1 ns;
|
374 |
|
|
ram_change <= '0' after 1 ns;
|
375 |
|
|
dma_sg_eot_set <= '0' after 1 ns;
|
376 |
|
|
dma_eot_set <= '0' after 1 ns;
|
377 |
|
|
dsc_check_start <= '0' after 1 ns;
|
378 |
|
|
|
379 |
|
|
when s01 => -- Повтор загрузки первого дескриптора --
|
380 |
|
|
|
381 |
|
|
dsc_load_en <= '0' after 1 ns;
|
382 |
|
|
dma_reg0 <= "110" after 1 ns;
|
383 |
|
|
dma_flag_start_clr <= '0' after 1 ns;
|
384 |
|
|
dma_change_adr <= '0' after 1 ns;
|
385 |
|
|
dsc_change_adr <= '0' after 1 ns;
|
386 |
|
|
dsc_change_mode <= '0' after 1 ns;
|
387 |
|
|
ram_change <= '0' after 1 ns;
|
388 |
|
|
dma_sg_eot_set <= '0' after 1 ns;
|
389 |
|
|
dma_eot_set <= '0' after 1 ns;
|
390 |
|
|
|
391 |
|
|
if( init_compelte='0' ) then
|
392 |
|
|
stp <= s1 after 1 ns;
|
393 |
|
|
end if;
|
394 |
|
|
|
395 |
|
|
when s1 => -- Загрузка первого дескриптора --
|
396 |
|
|
dma_chn_change <= '0' after 1 ns;
|
397 |
|
|
dsc_load_en <= '1' after 1 ns;
|
398 |
|
|
dma_reg0 <= "000" after 1 ns;
|
399 |
|
|
|
400 |
|
|
dsc_change_mode <= '1' after 1 ns;
|
401 |
|
|
dsc_change_adr <= '1' after 1 ns;
|
402 |
|
|
|
403 |
|
|
if( init_compelte='1' ) then
|
404 |
|
|
stp <= s2 after 1 ns;
|
405 |
|
|
end if;
|
406 |
|
|
|
407 |
|
|
|
408 |
|
|
when s2 =>
|
409 |
|
|
dma_change_adr <= '1' after ns;
|
410 |
|
|
dsc_change_adr <= '0' after 1 ns;
|
411 |
|
|
stp <= s3 after 1 ns;
|
412 |
|
|
|
413 |
|
|
when s3 =>
|
414 |
|
|
dma_change_adr <= '0' after ns;
|
415 |
|
|
dma_reg0 <= "001" after 1 ns;
|
416 |
|
|
dsc_load_en <= not dma_status(1) after 1 ns;
|
417 |
|
|
if( dma_status(0)='1' ) then
|
418 |
|
|
if( dma_start='0' ) then
|
419 |
|
|
stp <= s0 after 1 ns;
|
420 |
|
|
else
|
421 |
|
|
stp <= s3_01 after 1 ns;
|
422 |
|
|
|
423 |
|
|
end if;
|
424 |
|
|
end if;
|
425 |
|
|
|
426 |
|
|
when s3_01 => -- проверка дескриптора
|
427 |
|
|
dsc_change_mode <='0' after 1 ns;
|
428 |
|
|
dsc_check_start <= '1' after 1 ns;
|
429 |
|
|
if( dsc_check_ready='1' ) then
|
430 |
|
|
stp <= s4 after 1 ns;
|
431 |
|
|
end if;
|
432 |
|
|
|
433 |
|
|
when s4 =>
|
434 |
|
|
dsc_check_start <= '0' after 1 ns;
|
435 |
|
|
dma_sg_eot_set <= not dsc_correct after 1 ns;
|
436 |
|
|
dma_flag_start_clr <= '1' after 1 ns;
|
437 |
|
|
dsc_change_mode <= '1' after 1 ns;
|
438 |
|
|
dsc_change_adr <= '1' after 1 ns;
|
439 |
|
|
stp <= s4_01 after 1 ns;
|
440 |
|
|
|
441 |
|
|
when s4_01 =>
|
442 |
|
|
dsc_change_mode <= '0' after 1 ns;
|
443 |
|
|
stp <= sc0 after 1 ns;
|
444 |
|
|
|
445 |
|
|
|
446 |
|
|
when st0 =>
|
447 |
|
|
stp <= st1 after 1 ns;
|
448 |
|
|
dma_chn_change <= '0' after 1 ns;
|
449 |
|
|
dsc_change_mode <= dsc_cmd(2) after 1 ns;
|
450 |
|
|
|
451 |
|
|
when st1 => -- Обмен --
|
452 |
|
|
dma_reg0 <= "111" after 1 ns;
|
453 |
|
|
if( dma_status(0)='1' ) then
|
454 |
|
|
if( dma_start='0' ) then
|
455 |
|
|
stp <= s0 after 1 ns;
|
456 |
|
|
else
|
457 |
|
|
if( dma_status(2)='0' ) then
|
458 |
|
|
stp <= sc4 after 1 ns;
|
459 |
|
|
else
|
460 |
|
|
stp <= st20 after 1 ns;
|
461 |
|
|
end if;
|
462 |
|
|
dma_change_adr <= '1' after 1 ns;
|
463 |
|
|
ram_change <= '1' after 1 ns;
|
464 |
|
|
end if;
|
465 |
|
|
end if;
|
466 |
|
|
|
467 |
|
|
when st20 =>
|
468 |
|
|
dma_reg0 <= "010" after 1 ns;
|
469 |
|
|
ram_change <= '0' after 1 ns;
|
470 |
|
|
if( dma_status(0)='0' ) then
|
471 |
|
|
stp <= st2 after 1 ns;
|
472 |
|
|
end if;
|
473 |
|
|
|
474 |
|
|
when st2 => -- Обработка дескриптора --
|
475 |
|
|
dma_change_adr <= '0' after 1 ns;
|
476 |
|
|
ram_change <= '0' after 1 ns;
|
477 |
|
|
dsc_change_adr <= '1' after 1 ns;
|
478 |
|
|
if( dsc_cmd(0)='1' or dsc_cmd(2)='1' ) then -- переход к следующему дескриптору --
|
479 |
|
|
stp <= sc0 after 1 ns; -- запись адреса в ctrl_ext_cmd
|
480 |
|
|
elsif( dsc_cmd(1)='1' ) then
|
481 |
|
|
stp <= sr0 after 1 ns;
|
482 |
|
|
else
|
483 |
|
|
-- завершение работы DMA канала --
|
484 |
|
|
dma_sg_eot_set <= '1' after 1 ns;
|
485 |
|
|
stp <= sc0 after 1 ns;
|
486 |
|
|
end if;
|
487 |
|
|
|
488 |
|
|
dma_eot_set <= dsc_cmd(4) after 1 ns;
|
489 |
|
|
|
490 |
|
|
|
491 |
|
|
when sc0 => -- запись адреса в ctrl_ext_cmd --
|
492 |
|
|
dsc_change_mode <= '0' after 1 ns;
|
493 |
|
|
dsc_change_adr <= '0' after 1 ns;
|
494 |
|
|
dma_eot_set <= '0' after 1 ns;
|
495 |
|
|
stp <= sc1 after 1 ns;
|
496 |
|
|
|
497 |
|
|
when sc1 =>
|
498 |
|
|
stp <= sc2 after 1 ns;
|
499 |
|
|
|
500 |
|
|
when sc2 =>
|
501 |
|
|
stp <= sc3 after 1 ns;
|
502 |
|
|
|
503 |
|
|
when sc3 =>
|
504 |
|
|
dma_change_adr <= '1' after 1 ns;
|
505 |
|
|
stp <= sc4 after 1 ns;
|
506 |
|
|
when sc4 =>
|
507 |
|
|
dma_change_adr <= '0' after 1 ns;
|
508 |
|
|
dma_reg0 <= "110" after 1 ns;
|
509 |
|
|
ram_change <= '0' after 1 ns;
|
510 |
|
|
if( dma_status(0)='0' ) then
|
511 |
|
|
stp <= s0 after 1 ns;
|
512 |
|
|
end if;
|
513 |
|
|
|
514 |
|
|
|
515 |
|
|
when sr0 => -- запись адреса в ctrl_ext_cmd --
|
516 |
|
|
dsc_change_adr <= '0' after 1 ns;
|
517 |
|
|
dma_eot_set <= '0' after 1 ns;
|
518 |
|
|
stp <= sr1 after 1 ns;
|
519 |
|
|
|
520 |
|
|
when sr1 =>
|
521 |
|
|
stp <= sr2 after 1 ns;
|
522 |
|
|
|
523 |
|
|
when sr2 =>
|
524 |
|
|
stp <= sr3 after 1 ns;
|
525 |
|
|
dsc_change_mode <= '1' after 1 ns;
|
526 |
|
|
dsc_change_adr <= '1' after 1 ns;
|
527 |
|
|
|
528 |
|
|
|
529 |
|
|
when sr3 =>
|
530 |
|
|
dma_change_adr <= '1' after 1 ns;
|
531 |
|
|
stp <= sr4 after 1 ns;
|
532 |
|
|
when sr4 =>
|
533 |
|
|
dsc_load_en <= '0' after 1 ns;
|
534 |
|
|
dma_change_adr <= '0' after 1 ns;
|
535 |
|
|
dma_reg0 <= "000" after 1 ns;
|
536 |
|
|
ram_change <= '0' after 1 ns;
|
537 |
|
|
if( dma_status(0)='0' ) then
|
538 |
|
|
stp <= sr5 after 1 ns;
|
539 |
|
|
end if;
|
540 |
|
|
|
541 |
|
|
when sr5 =>
|
542 |
|
|
dsc_load_en <= not dma_status(1) after 1 ns;
|
543 |
|
|
dma_reg0 <= "001" after 1 ns;
|
544 |
|
|
if( dma_status(0)='1' ) then
|
545 |
|
|
stp <= sr5_01 after 1 ns;
|
546 |
|
|
end if;
|
547 |
|
|
|
548 |
|
|
when sr5_01 => -- проверка дескриптора
|
549 |
|
|
dsc_change_mode <='0' after 1 ns;
|
550 |
|
|
dsc_check_start <= '1' after 1 ns;
|
551 |
|
|
if( dsc_check_ready='1' ) then
|
552 |
|
|
stp <= s4 after 1 ns;
|
553 |
|
|
end if;
|
554 |
|
|
|
555 |
|
|
|
556 |
|
|
when sr6 =>
|
557 |
|
|
--dsc_load_en <= '0' after 1 ns;
|
558 |
|
|
dma_sg_eot_set <= not dsc_correct after 1 ns;
|
559 |
|
|
stp <= s4_01 after 1 ns;
|
560 |
|
|
dsc_change_mode <= '1' after 1 ns;
|
561 |
|
|
dsc_change_adr <= '1' after 1 ns;
|
562 |
|
|
|
563 |
|
|
end case;
|
564 |
|
|
|
565 |
|
|
|
566 |
|
|
|
567 |
|
|
if( rstp='1' ) then
|
568 |
|
|
stp <= s0 after 1 ns;
|
569 |
|
|
dma_chn_change <= '0' after 1 ns;
|
570 |
|
|
end if;
|
571 |
|
|
end if;
|
572 |
|
|
end process;
|
573 |
|
|
|
574 |
|
|
dma0_block_in <= '1' when stp=st1 and dma_chni='0' else '0';
|
575 |
|
|
dma1_block_in <= '1' when stp=st1 and dma_chni='1' else '0';
|
576 |
|
|
|
577 |
|
|
xb0: srl16 port map( clk=>clk, d=>dma0_block_in, q=> dma0_block, a0=>'1', a1=>'1', a2=>'0', a3=>'0' );
|
578 |
|
|
xb1: srl16 port map( clk=>clk, d=>dma1_block_in, q=> dma1_block, a0=>'1', a1=>'1', a2=>'0', a3=>'0' );
|
579 |
|
|
|
580 |
|
|
dma0_block_z <= dma0_block after 1 ns when rising_edge( clk );
|
581 |
|
|
dma1_block_z <= dma1_block after 1 ns when rising_edge( clk );
|
582 |
|
|
|
583 |
|
|
--ram_adr_l(2) <= ram_sel(1);
|
584 |
|
|
--ram_adr_l(1 downto 0) <= (others=>ram_sel(0));
|
585 |
|
|
ram_adr_l( 2 downto 0 ) <= ram_sel;
|
586 |
|
|
|
587 |
|
|
ram_adr( 4 downto 0 ) <= "10" & ram_adr_l;
|
588 |
|
|
ram_adr(5) <= dma_chni;
|
589 |
|
|
ram_adr( 8 downto 6 ) <= "000";
|
590 |
|
|
|
591 |
|
|
--ram_do( 0 ) <= (dma0_start and not dma_chni) or (dma1_start and dma_chni); -- 1 - канал DMA работает
|
592 |
|
|
--ram_do( 1 ) <= '0';
|
593 |
|
|
--ram_do( 2 ) <= '0';
|
594 |
|
|
--ram_do( 3 ) <= '0';
|
595 |
|
|
--
|
596 |
|
|
--ram_do( 4 ) <= ((dma0_eot or dma0_wait_eot2) and not dma_chni) or ((dma1_eot or dma1_wait_eot2)and dma_chni); -- 1 - завершение передачи блока данных
|
597 |
|
|
--ram_do( 5 ) <= (dma0_sg_eot and not dma_chni) or (dma1_sg_eot and dma_chni); -- 1 - завершение работы канала DMA
|
598 |
|
|
--ram_do( 6 ) <= (dma0_wait_eot and not dma_chni) or (dma1_wait_eot and dma_chni); -- 1 - ожидание сброса dma_eot
|
599 |
|
|
--ram_do( 7 ) <= dsc_correct;
|
600 |
|
|
|
601 |
|
|
reg_dma0_status( 0 ) <= dma0_start after 1 ns when rising_edge( clk ); -- 1 - канал DMA работает
|
602 |
|
|
reg_dma0_status( 1 ) <= '0';
|
603 |
|
|
reg_dma0_status( 2 ) <= '0';
|
604 |
|
|
reg_dma0_status( 3 ) <= '0';
|
605 |
|
|
|
606 |
|
|
reg_dma0_status( 4 ) <= dma0_eot or dma0_wait_eot2 after 1 ns when rising_edge( clk ); -- 1 - завершение передачи блока данных
|
607 |
|
|
reg_dma0_status( 5 ) <= dma0_sg_eot after 1 ns when rising_edge( clk ); -- 1 - завершение работы канала DMA
|
608 |
|
|
reg_dma0_status( 6 ) <= dma0_wait_eot after 1 ns when rising_edge( clk ); -- 1 - ожидание сброса dma_eot
|
609 |
|
|
reg_dma0_status( 7 ) <= (dma0_eot or dma0_wait_eot2) and dma0_ctrl(5) after 1 ns when rising_edge( clk ); -- 1 - запрос прерывания
|
610 |
|
|
reg_dma0_status( 8 ) <= dsc_correct after 1 ns when rising_edge(clk) and dma_chni='0';
|
611 |
|
|
reg_dma0_status( 15 downto 9 ) <= x"A" & "000";
|
612 |
|
|
|
613 |
|
|
reg_dma1_status( 0 ) <= dma1_start after 1 ns when rising_edge( clk ); -- 1 - канал DMA работает
|
614 |
|
|
reg_dma1_status( 1 ) <= '0';
|
615 |
|
|
reg_dma1_status( 2 ) <= '0';
|
616 |
|
|
reg_dma1_status( 3 ) <= '0';
|
617 |
|
|
|
618 |
|
|
reg_dma1_status( 4 ) <= dma1_eot or dma1_wait_eot2 after 1 ns when rising_edge( clk ); -- 1 - завершение передачи блока данных
|
619 |
|
|
reg_dma1_status( 5 ) <= dma1_sg_eot after 1 ns when rising_edge( clk ); -- 1 - завершение работы канала DMA
|
620 |
|
|
reg_dma1_status( 6 ) <= dma1_wait_eot after 1 ns when rising_edge( clk ); -- 1 - ожидание сброса dma_eot
|
621 |
|
|
reg_dma1_status( 7 ) <= (dma1_eot or dma1_wait_eot2) and dma1_ctrl(5) after 1 ns when rising_edge( clk ); -- 1 - запрос прерывания
|
622 |
|
|
reg_dma1_status( 8 ) <= dsc_correct after 1 ns when rising_edge(clk) and dma_chni='1';
|
623 |
|
|
reg_dma1_status( 15 downto 9 ) <= x"A" & "000";
|
624 |
|
|
|
625 |
|
|
|
626 |
|
|
--ram_we <= not (ram_sel(1) or dma_chn_change);
|
627 |
|
|
ram_do <= (others=>'0');
|
628 |
|
|
ram_we <= '0';
|
629 |
|
|
|
630 |
|
|
pr_dma_eot: process( clk ) begin
|
631 |
|
|
if( rising_edge( clk ) ) then
|
632 |
|
|
if( dma0_ctrl(0)='0' or dma0_eot_clr='1' ) then
|
633 |
|
|
dma0_eot <= '0' after 1 ns;
|
634 |
|
|
elsif( dma_eot_set='1' and dma_chni='0' ) then
|
635 |
|
|
dma0_eot <= '1' after 1 ns;
|
636 |
|
|
end if;
|
637 |
|
|
|
638 |
|
|
if( dma1_ctrl(0)='0' or dma1_eot_clr='1' ) then
|
639 |
|
|
dma1_eot <= '0' after 1 ns;
|
640 |
|
|
elsif( dma_eot_set='1' and dma_chni='1' ) then
|
641 |
|
|
dma1_eot <= '1' after 1 ns;
|
642 |
|
|
end if;
|
643 |
|
|
|
644 |
|
|
if( dma0_ctrl(0)='0' ) then
|
645 |
|
|
dma0_sg_eot <= '0' after 1 ns;
|
646 |
|
|
elsif( dma_sg_eot_set='1' and dma_chni='0' ) then
|
647 |
|
|
dma0_sg_eot <= '1' after 1 ns;
|
648 |
|
|
end if;
|
649 |
|
|
|
650 |
|
|
if( dma1_ctrl(0)='0' ) then
|
651 |
|
|
dma1_sg_eot <= '0' after 1 ns;
|
652 |
|
|
elsif( dma_sg_eot_set='1' and dma_chni='1' ) then
|
653 |
|
|
dma1_sg_eot <= '1' after 1 ns;
|
654 |
|
|
end if;
|
655 |
|
|
|
656 |
|
|
end if;
|
657 |
|
|
end process;
|
658 |
|
|
|
659 |
|
|
pr_dma0_wait_eot: process( clk ) begin
|
660 |
|
|
if( rising_edge( clk ) ) then
|
661 |
|
|
if( dma0_ctrl(0)='0' or (dma0_eot_clr='1' and dma0_wait_eot2='1' ) ) then
|
662 |
|
|
dma0_wait_eot <= '0' after 1 ns;
|
663 |
|
|
elsif( dma_eot_set='1' and dma0_eot='1' and dma_chni='0' ) then
|
664 |
|
|
dma0_wait_eot <= '1' after 1 ns;
|
665 |
|
|
end if;
|
666 |
|
|
|
667 |
|
|
if( dma1_ctrl(0)='0' or (dma1_eot_clr='1' and dma1_wait_eot2='1' ) ) then
|
668 |
|
|
dma1_wait_eot <= '0' after 1 ns;
|
669 |
|
|
elsif( dma_eot_set='1' and dma1_eot='1' and dma_chni='1' ) then
|
670 |
|
|
dma1_wait_eot <= '1' after 1 ns;
|
671 |
|
|
end if;
|
672 |
|
|
|
673 |
|
|
|
674 |
|
|
if( dma0_ctrl(0)='0' ) then
|
675 |
|
|
dma0_wait_eot2 <= '0' after 1 ns;
|
676 |
|
|
elsif( dma0_eot_clr='1' ) then
|
677 |
|
|
dma0_wait_eot2 <= dma0_eot and dma0_wait_eot after 1 ns;
|
678 |
|
|
end if;
|
679 |
|
|
|
680 |
|
|
if( dma1_ctrl(0)='0' ) then
|
681 |
|
|
dma1_wait_eot2 <= '0' after 1 ns;
|
682 |
|
|
elsif( dma1_eot_clr='1' ) then
|
683 |
|
|
dma1_wait_eot2 <= dma1_eot and dma1_wait_eot after 1 ns;
|
684 |
|
|
end if;
|
685 |
|
|
|
686 |
|
|
|
687 |
|
|
|
688 |
|
|
end if;
|
689 |
|
|
end process;
|
690 |
|
|
|
691 |
|
|
pr_dma_start: process( clk ) begin
|
692 |
|
|
if( rising_edge( clk ) ) then
|
693 |
|
|
if( dma0_ctrl(0)='0' ) then
|
694 |
|
|
dma0_start <= '0' after 1 ns;
|
695 |
|
|
elsif( dma_flag_start_clr='1' and dma_chni='0' ) then
|
696 |
|
|
dma0_start <= '1' after 1 ns;
|
697 |
|
|
end if;
|
698 |
|
|
if( dma1_ctrl(0)='0' ) then
|
699 |
|
|
dma1_start <= '0' after 1 ns;
|
700 |
|
|
elsif( dma_flag_start_clr='1' and dma_chni='1' ) then
|
701 |
|
|
dma1_start <= '1' after 1 ns;
|
702 |
|
|
end if;
|
703 |
|
|
end if;
|
704 |
|
|
end process;
|
705 |
|
|
|
706 |
|
|
dma_start <= dma0_ctrl_z when dma_chni='0' else dma1_ctrl_z;
|
707 |
|
|
|
708 |
|
|
------ Сохранение текущего состояния канала DMA ----
|
709 |
|
|
--pr_ra:process( clk ) begin
|
710 |
|
|
-- if( rising_edge( clk ) ) then
|
711 |
|
|
--
|
712 |
|
|
--
|
713 |
|
|
-- if( rstp='1' ) then
|
714 |
|
|
-- ra <= x"00" after 1 ns;
|
715 |
|
|
-- end if;
|
716 |
|
|
--
|
717 |
|
|
-- end if;
|
718 |
|
|
--end process;
|
719 |
|
|
--
|
720 |
|
|
--
|
721 |
|
|
--
|
722 |
|
|
--gen_repack: for ii in 0 to 7 generate
|
723 |
|
|
--
|
724 |
|
|
--ram0: ram16x1d
|
725 |
|
|
-- port map(
|
726 |
|
|
-- we => ra_we,
|
727 |
|
|
-- d => ra(ii),
|
728 |
|
|
-- wclk => clk,
|
729 |
|
|
-- a0 => dma_chni,
|
730 |
|
|
-- a1 => '0',
|
731 |
|
|
-- a2 => '0',
|
732 |
|
|
-- a3 => '0',
|
733 |
|
|
-- spo => ram_a_adr(ii),
|
734 |
|
|
-- dpra0 => '0',
|
735 |
|
|
-- dpra1 => '0',
|
736 |
|
|
-- dpra2 => '0',
|
737 |
|
|
-- dpra3 => '0'
|
738 |
|
|
-- );
|
739 |
|
|
--
|
740 |
|
|
--end generate;
|
741 |
|
|
--
|
742 |
|
|
--
|
743 |
|
|
------ Обработка канала DMA ----
|
744 |
|
|
--
|
745 |
|
|
--ram1: RAMB16_S36_S36
|
746 |
|
|
-- generic map(
|
747 |
|
|
-- SIM_COLLISION_CHECK => "NONE"
|
748 |
|
|
-- )
|
749 |
|
|
--
|
750 |
|
|
-- port map(
|
751 |
|
|
-- DOA => ram_a_out( 31 downto 0 ), --: out std_logic_vector(3 downto 0);
|
752 |
|
|
-- --DOB => ram_b_out( 31 downto 0 ), --: out std_logic_vector(31 downto 0);
|
753 |
|
|
-- --DOPB : out std_logic_vector(3 downto 0);
|
754 |
|
|
--
|
755 |
|
|
-- ADDRA => ram_a_adr( 8 downto 0 ), --: in std_logic_vector(11 downto 0);
|
756 |
|
|
-- ADDRB => (others=>'0'),
|
757 |
|
|
-- CLKA => clk,
|
758 |
|
|
-- CLKB => '0',
|
759 |
|
|
-- DIA => (others=>'0'), --: in std_logic_vector(3 downto 0);
|
760 |
|
|
-- DIB => (others=>'0'),
|
761 |
|
|
-- DIPA => (others=>'0'),
|
762 |
|
|
-- DIPB => (others=>'0'),
|
763 |
|
|
-- ENA => '1',
|
764 |
|
|
-- ENB => '0',
|
765 |
|
|
-- SSRA => '0',
|
766 |
|
|
-- SSRB => '0',
|
767 |
|
|
-- WEA => '1',
|
768 |
|
|
-- WEB => '0'
|
769 |
|
|
-- );
|
770 |
|
|
--
|
771 |
|
|
--
|
772 |
|
|
|
773 |
|
|
|
774 |
|
|
end ctrl_main;
|