.Проектирование устройств и систем с высокоскоростными соединениями
.pdfwait_idle – обнаружен второй символ конечного маркера кадра или второй символ маркера ожидания кадра;
wait_idle_next – обнаружен первый символ маркера ожидания кадра;
lock_up – состояние блокировки приема кадра из-за искажения его структуры.
Рис. 6.14. Управляющий автомат разбора кадра узлом deframer
Ниже приведена синтезируемая программа на VHDL узла deframer.
VHDL программа-спецификация узла deframer проекта #2
library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity deframer is
port(
reset_n : in STD_LOGIC;
data_in : in STD_LOGIC_VECTOR(9 downto 0); rx_coreclock : in STD_LOGIC;
op_code : out STD_LOGIC_VECTOR(1 downto 0); data_out : out STD_LOGIC_VECTOR(9 downto 0)
); end deframer;
141
architecture deframer of deframer is
-- Управляющие символы кода 8b/10b
constant K28_5_RDm : STD_LOGIC_VECTOR(9 downto 0) := "0101111100"; constant K28_0_RDm : STD_LOGIC_VECTOR(9 downto 0) := "0010111100";
constant K29_7_RDm : STD_LOGIC_VECTOR(9 downto 0) := "0001011101";
-- Функция поиска разделителя в последних 20 битах принятой последовательности
function comma_detector(x: std_logic_vector(19 downto 0)) return unsigned is variable TEMP: unsigned(3 downto 0);
begin TEMP:="0000"; for I in 0 to 9 loop
if (x(I+9 downto i)=K28_5_RDm) or (x(I+9 downto i)=not K28_5_RDm) then
return TEMP+I; end if;
end loop; return x"a";
end;
-- Функция перестановки бит для кода 8b/10b (6 бит)
function Cross_6 (x: STD_LOGIC_VECTOR(5 downto 0)) return STD_LOGIC_VECTOR is
variable y:std_logic_vector(5 downto 0); begin
for I in 0 to 5 loop y(I):=x(5-I);
end loop; return y;
end;
-- Функция перестановки бит для кода 8b/10b (4 бита)
function Cross_4 (x: STD_LOGIC_VECTOR(3 downto 0)) return STD_LOGIC_VECTOR is
variable y:std_logic_vector(3 downto 0); begin
for I in 0 to 3 loop y(I):=x(3-I);
end loop; return y;
end;
signal preg10: std_logic_vector(9 downto 0); signal align: std_logic_vector(3 downto 0);
type TYPE_STATE is (wait_comma1,wait_comma2,data_0,data_1,data_2, data_3,wait _end, wait_idle,wait_idle_next, lock_up);
signal state: TYPE_STATE;
142
begin |
--Кодированиеэтаповсборкиданныхпользователя |
||
with state select |
|||
op_code <= "01" when data_1, -- для узла decoder_8b10b |
|
||
"10" when data_2, |
|
|
|
"11" when data_3, |
|
|
|
"00" when others; |
-- Процесс поиска разделителей запускается |
||
DETECTOR_COMMA: |
|
||
по каждому |
|
-- положительному фронту тактовой син- |
|
process(reset_n, rx_coreclock) |
|||
хронизации |
|
|
|
variable v_align: STD_LOGIC_VECTOR(3 downto 0); |
|
||
variable v_data10: STD_LOGIC_VECTOR(9 downto 0); |
|
||
begin |
|
|
|
if reset_n='0' then |
|
|
|
preg10<=(others=>'0'); |
|
|
|
align<="1010"; |
|
|
|
data_out<=(others=>'0'); |
|
|
|
state<= wait_comma1; |
|
|
|
elsif rising_edge( rx_coreclock) then |
|
||
preg10<= data_in; |
|
|
|
v_align:=std_logic_vector(comma_detector(data_in&preg10)); |
-- |
||
Определение |
|
--положения «запятой» |
|
if v_align /= "1010" then |
|
||
align<= v_align; |
|
|
|
else |
|
|
|
v_align:= |
align; |
|
|
end if;
case v_align is --Формированиеуказателяположенияграницы символа
when "0000" => |
|
v_data10:= |
preg10; |
when "0001" => |
|
v_data10:= |
data_in(0)&preg10(9 downto 1); |
when "0010" => |
|
v_data10:= |
data_in(1 downto 0)&preg10(9 downto 2); |
when "0011" => |
|
v_data10:= |
data_in(2 downto 0)&preg10(9 downto 3); |
when "0100" => |
|
v_data10:= |
data_in(3 downto 0)&preg10(9 downto 4); |
when "0101" => |
|
v_data10:= |
data_in(4 downto 0)&preg10(9 downto 5); |
when "0110" => |
|
v_data10:= |
data_in(5 downto 0)&preg10(9 downto 6); |
when "0111" => |
|
v_data10:= |
data_in(6 downto 0)&preg10(9 downto 7); |
|
143 |
when "1000" => |
|
v_data10:= |
data_in(7 downto 0)&preg10(9 downto 8); |
when "1001" => |
|
v_data10:= |
data_in(8 downto 0)&preg10(9 ); |
when others => |
|
v_data10:= |
preg10; |
end case;
STATE_MACHINE: case state is --Автомат управления разбором кадра when wait_comma1=>
if v_data10=K28_5_RDm or v_data10=not K28_5_RDm then state<=wait_comma2;
end if;
when wait_comma2=>
if v_data10=K28_5_RDm or v_data10=not K28_5_RDm then state<=data_0;
else
state<=lock_up; end if;
when data_0=> state<=data_1;
when data_1=> state<=data_2;
when data_2=> state<=data_3;
when data_3=>
if v_data10=K28_0_RDm or v_data10=not K28_0_RDm then state<=wait_end;
else state<=data_1;
end if;
when wait_end=>
if (v_data10(5 downto 0)=Cross_6 ("100111") and v_data10(9 downto 6)=Cross_4 ("1011")) or
(v_data10(5 downto 0)=Cross_6 ("100111") and v_data10(9 downto 6)=Cross_4 (not"1011")) or
(v_data10(5 downto 0)=Cross_6 (not "100111") and v_data10(9 downto 6)=Cross_4 ("1011")) or
(v_data10(5 downto 0)=Cross_6 (not "100111") and v_data10(9 downto 6)=Cross_4 (not"1011")) then
state<=wait_idle;
else
state<=lock_up; end if;
when wait_idle=>
144
if v_data10=K29_7_RDm or v_data10=not K29_7_RDm then state<=wait_idle_next;
elsif v_data10=K28_5_RDm or v_data10=not K28_5_RDm then state<=wait_comma2;
else
state<=lock_up;
end if;
when wait_idle_next=>
if v_data10=K28_5_RDm or v_data10=not K28_5_RDm then state<=wait_idle; --wait_comma2;
else
state<=lock_up;
end if;
when others => null;
end case; data_out<=v_data10;
end if; end process;
end deframer;
Следующий текст на VHDL представляет синтезируемую программу узла decoder_8b10b, моделирующую процесс преобразования 10-разрядных символов кода 8b/10b в 8-разрядные данные и сборку из них 12-разрядных данных для потребителя. Формируется также сигнал wr, инициирующий запись дан-
ных в fifo.
VHDL программа-спецификация узла decoder_8b10b проекта #2
library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity decoder_8b10b is
port(
reset_n : in STD_LOGIC; en : in STD_LOGIC;
data_in : in STD_LOGIC_VECTOR(9 downto 0); op_code : in STD_LOGIC_VECTOR(1 downto 0); wr: out STD_LOGIC;
data_out : out STD_LOGIC_VECTOR(11 downto 0)
);
145
end decoder_8b10b
architecture decoder_8b10b of decoder_8b10b is
function cross_6 (x: std_logic_vector(5 downto 0)) return std_logic_vector is variable y: std_logic_vector(5 downto 0);
begin
for I in 0 to 5 loop y(I):=x(5-I); end loop; return y;
end;
function cross_4 (x: std_logic_vector(3 downto 0)) return std_logic_vector is variable y: std_logic_vector(3 downto 0);
begin
for I in 0 to 3 loop y(I):=x(3-I); end loop; return y;
end;
constant K28_5_RDm : STD_LOGIC_VECTOR(9 downto 0) := "0101111100"; constant K28_0_RDm : STD_LOGIC_VECTOR(9 downto 0) := "0010111100"; constant K29_7_RDm : STD_LOGIC_VECTOR(9 downto 0) := "0001011101";
type Code5b6b_type is array (0 to 31) of STD_LOGIC_VECTOR(5 downto 0); constant Code5b6b_ROM_RDm : Code5b6b_type := ( -- Таблицакодированиякода
"100111", "011101", "101101", "110001", |
-- 8b/10d для 5 младших бит |
|||
"110101", "101001", "011001", "111000", |
-- RD= –1 |
|||
"111001", |
"100101", |
"010101", "110100", |
|
|
"001101", |
"101100", |
"011100", "010111", |
|
|
"011011", |
"100011", "010011", |
"110010", |
|
|
"001011", |
"101010", |
"011010", "111010", |
|
"110011", "100110", "010110","110110",
"001110", "101110", "011110", "101011" );
constant Code5b6b_ROM_RDp : Code5b6b_type := ( -- Таблица кодирования
кода |
|
|
|
-- 8b/10d для 5 старших бит |
|
0=> |
not Code5b6b_ROM_RDm(0), |
|
|||
1=> |
not Code5b6b_ROM_RDm(1), |
|
-- RD= +1 |
|
|
2=> |
not Code5b6b_ROM_RDm(2), |
|
|
|
|
3=> |
"110001", |
|
|
|
|
4=> |
not Code5b6b_ROM_RDm(4), |
|
|
|
|
5=> |
"101001", 6=> |
"011001", |
|
|
|
7=> |
not Code5b6b_ROM_RDm(7), |
|
|
|
|
8=> |
not Code5b6b_ROM_RDm(8), |
|
|
|
|
9=> |
"100101", 10=> |
"010101", |
11=> |
"110100", 12=> |
"001101", |
13=> |
"101100", 14=> |
"011100", |
|
|
|
15=> |
not Code5b6b_ROM_RDm(15), |
|
|
||
16=> |
not Code5b6b_ROM_RDm(16), |
|
|
||
17=> |
"100011",18=> |
"010011", |
19=> |
"110010",20=> |
"001011", |
21=> |
"101010",22=> |
"011010", |
|
|
|
23=> |
not Code5b6b_ROM_RDm(23), |
|
|
||
146 |
|
|
|
|
|
24=> |
not Code5b6b_ROM_RDm(24), |
25=> |
"100110",26=> "010110", |
27=> |
not Code5b6b_ROM_RDm(27), |
28=> |
"001110", |
29=> |
not Code5b6b_ROM_RDm(29), |
30=> |
not Code5b6b_ROM_RDm(30), |
31=> |
not Code5b6b_ROM_RDm(31) ); |
type Code3b4b_type is array (0 to 7) of STD_LOGIC_VECTOR(3 downto 0); constant Code3b4b_ROM_RDm : Code3b4b_type := ( -- Таблицакодированиякода 0=> "1011",1=> "1001", 2=> "0101",3=> "1100", -- 8b/10d для3 старшихбит
4=> "1101",5=> "1010", 6=> "0110",7=> "1110"); -- RD= –1
constant Code3b4b_ROM_RDp : Code3b4b_type := ( -- Таблицакодированиякода
0=> |
not Code3b4b_ROM_RDm(0), |
-- 8b/10d для 3 старших бит |
1=> |
"1001", |
-- RD= +1 |
2=> |
"0101", |
|
3=> |
not Code3b4b_ROM_RDm(3), |
|
4=> |
not Code3b4b_ROM_RDm(4), |
|
5=> |
"1010", 6=> "0110", |
|
7=> |
not Code3b4b_ROM_RDm(7) ); |
|
signal buff:std_logic_vector(7 downto 0); |
|
|
signal wr_r1,wr_f1,wr_r2,wr_f2:std_logic; |
|
|
begin |
|
wr_f2);--Генерация сигнала записи |
wr<= |
(wr_r1 and wr_f1) or (wr_r2 and |
для fifo
process(reset_n, en) --Формирование вспомогательных сигналовзаписи wr_r для variable v_code8: STD_LOGIC_VECTOR(7 downto 0); -- генерации сигнала wr
begin
if reset_n='0' then wr_r1<='0'; wr_r2<='0';
elsif rising_edge(en) then
if op_code="01" then wr_r1<='1';
else
wr_r1<='0'; end if;
if op_code="10" then wr_r2<='1';
else
wr_r2<='0'; end if;
end if; end process;
DATA_ASSEMBLER:
147
process(reset_n, en)
variable v_code8: STD_LOGIC_VECTOR(7 downto 0); begin
if reset_n='0' then data_out<=(others=>'0'); wr_f1<='0';
wr_f2<='0';
elsif falling_edge(en) then
if op_code="10" then --Формирование вспомогательных сигналов wr_f1<='1'; -- wr_ f для генерации сигнала wr
else
wr_f1<='0'; end if;
if op_code="11" then wr_f2<='1';
else
wr_f2<='0';
end if;
for I in 0 to 31 loop -- Декодирование младших бит кода 8b/10b if (data_in(5 downto0)=Cross_6(Code5b6b_ROM_RDm(i))) or (data_in(5 downto0)=Cross_6(Code5b6b_ROM_RDp(i))) then v_code8(4 downto 0):=std_logic_vector(to_unsigned(i,5));
end if;
end loop;
for I in 0 to 7 loop -- Декодирование старших бит кода 8b/10b if (data_in(9 downto 6)=Cross_4(Code3b4b_ROM_RDm(i))) or
(data_in(9 downto 6)=Cross_4(Code3b4b_ROM_RDp(i))) then v_code8(7 downto 5):=std_logic_vector(to_unsigned(i,3));
end if; end loop;
buff<=v_code8;
if op_code="10" then -- Сборка данных пользователя
data_out(7 downto |
0)<= buff; |
data_out(11 downto 8)<= v_code8(3 downto 0); |
|
elsif op_code="11" then |
|
data_out(3 downto |
0)<= buff(7 downto 4); |
data_out(11 downto 4)<= v_code8; end if;
end if; end process;
end decoder_8b10b;
148
Рис. 6.15. Временная диаграмма генерации сигнала wr с помощью группы сигналов wr_f и wr_r
Временная диаграмма на рис 6.15 иллюстрирует генерации сигнала wr узлом decoder_8b10b.
6.3. XILINX 7 SERIES
Xilinx 7 series [10] включает три унифицированные семейства. Семейство Artix™-7 оптимизировано под наименьшие затраты для использования в массовом производстве, Virtex®-7 оптимизировано под наивысшую производительность и емкость, а Kintex™-7 является инновационным классом, оптимизированным по критерию наилучшая цена – производительность. GTX трансиверы той серии поддерживают скорость передачи от 500 Мбит/с
до 12,5 Гбит/с, а GTH – от 500 Мбит/с до 13,1 Гбит/с. GTX/GTH
разработаны для поддержки таких интерфейсов, как:
•PCI Express, версии 1.1/2.0/3.0;
•10GBASE-R – спецификация последовательного кодирования 64B/66B для кадра Ethernet на скорости около 10,3 Гбит/с (10,000 Гбит/с на MAC уровне · 66/64 = 10,312 Гбит/с);
•Interlaken – безвозмездный протокол взаимодействия по
множеству высокоскоростных каналов (кодирование 64B/66B)
между микросхемами от Cisco Systems и Cortina Systems;
• Стандарты взаимодействия MAC и физических подуров-
ней Ethernet: XAUI (10 Gb Attachment Unit Interface), RXAUI (Reduced Pin eXtended Attachment Unit Interface), CAUI (100 Gb Attachment Unit Interface), XLAUI (40 Gb Attachment Unit Interface);
149
• CPRI/ OBSAI (Common Packet Radio/InterfaceOpen Base Station Architecture Initiative) – стандарт, определяющий интер-
фейс между функциональными блоками базовой станции сотовой связи;
•OC-48/192 (STM-16/ STM-64) – транспортные структуры синхронных систем передачи SONET/ SDH (2,5 –40 Гбит/с);
•OTU-1, OTU-2, OTU-3, OTU-4 – спецификации оптических транспортных сетей (Optical Transport Network – OTN);
•последовательный RapidIO (SRIO);
•SATA/SAS (Serial Advanced Technology Attachment/Serial Attached SCSI) – последовательный интерфейс обмена данными с
накопителями информации;
• SDI (Serial Digital Interface) – цифровой видеоинтерфейс.
Все трансиверы GTX/GTH (в дальнейшем будем называть MGT) объединены в MGT-четверки, как на рис. 6.16, где CPLL – канальные ФАПЧ, а QPLL – общая ФАПЧ MGT-четверки.
Рис. 6.16. Структура MGT-четверка
150