Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

.Проектирование устройств и систем с высокоскоростными соединениями

.pdf
Скачиваний:
41
Добавлен:
15.11.2022
Размер:
21.68 Mб
Скачать

data_11_4<=data_in12(11 downto 4); when "10"=>

data8<=data_11_4; when others=>

null; end case;

end if; end process;

end conv_2_12_to_3_8;

Реализуем следующий узел с интерфейсом Serializer (рис. 3.9), используя модель программно-управляемого автомата (модель программно-управляемого автомата подробно рассмотрена в главе 7).

 

 

Serializer

 

 

 

 

hs_clock

 

Rdr

 

 

data_in10(1111…0 )

rd_mode(1…0)

 

 

_

…0 )

rd mode(1…0)

 

 

idle

 

op

…0)

 

 

 

op codecode(2…0)

 

 

 

 

 

en

 

 

 

 

 

en

 

 

 

 

 

rd fifo

 

 

 

 

 

Рис. 3.9. Интерфейс узла

Serializer

На вход hs_clock

подается тактовый

сигнал частотой

2,5 ГГц, под действием которого параллельные 10-битные символы, поступающие на вход данных data_in10 от «Кодер 8b/10b», преобразуются в выходной последовательный поток tx. Остальные выходные сигналы необходимы для работы узлов «FIFO передачи», «Преобразование 12/8 бит» и «Кодер 8b/10b».

Представим процесс формирования кадра в виде синхронного автомата (рис. 3.10), в котором состояния интерпретируются следующим образом:

SF1 – формирование первого символа стартового маркера кадра;

SF2 – формирование второго символа стартового маркера кадра;

DATA0 – 8b/10b кодирование данных этап 0; DATA1 – 8b/10b кодирование данных этап 1; DATA2 – 8b/10b кодирование данных этап 2;

EF1 – формирование первого символа конечного маркера кадра;

61

EF2 – формирование второго символа конечного маркера кадра;

IDLE1 – формирование первого символа маркера ожидания кадра;

IDLE2 – формирование второго символа маркера ожидания кадра.

Рис. 3.10. Автомат формирования кадра

На вход symbol_counter поступает число переданных пар символов, а вход idle удерживается в 1 для передачи необходимого количества символов ожидания.

Ниже приведена программа-спецификация на VHDL узла

Serializer, содержащая два процесса – COUNTER_0_TO_9 и STATE_MACINE.

VHDL программа-спецификация узла Serializer

library IEEE;

use IEEE.STD_LOGIC_1164.all;

use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.NUMERIC_STD.all;

entity Serializer is port(

reset_n : in STD_LOGIC; hs_clock : in STD_LOGIC;

data_in10 : in STD_LOGIC_VECTOR(9 downto 0); idle : in STD_LOGIC;

62

op_code : out STD_LOGIC_VECTOR(2 downto 0); en : out STD_LOGIC;

rd : out STD_LOGIC; rd_fifo : out STD_LOGIC;

rd_mode : out STD_LOGIC_VECTOR(1 downto 0); tx : out STD_LOGIC

);

end Serializer;

architecture Serializer of Serializer is

type TYPE_STATE is (SF1, SF2,DATA0,DATA1, DATA2,EF1,EF2, IDLE1,IDLE2); signal state:TYPE_STATE;

signal bit_counter: unsigned (3 downto 0);

 

signal symbol_counter: STD_LOGIC_VECTOR (3 downto 0);

 

signal symbol,sreg: STD_LOGIC_VECTOR (9 downto 0);

 

begin

 

 

 

 

op_code<="000" when state=SF1 or state=SF2 else

-- K28.5

"001" when

state=DATA0

or

state=DATA1 or state=DATA2 else -- дан-

ные

 

 

 

 

"010" when

state=EF1

else

 

-- K28.0

"011" when

state=EF2

else

 

-- D0.0

"100" when

state=IDLE1 else

 

-- K29.7

"000";

 

 

 

 

rd_mode<="00" when state=DATA0 else

 

"01" when

state=DATA1 else

 

 

"10" when

state=DATA2 else

 

 

"11";

 

 

 

 

Tx<=sreg(0);

 

 

 

 

COUNTER_0_TO_9: process(reset_n,hs_clock)

 

begin

 

 

 

 

if reset_n='0' then

 

 

 

bit_counter<=(others=>'0');

 

rd<='0';

 

 

 

rd_fifo<='0';

 

 

 

en<='0';

 

 

 

symbol<=(others=>'0');

 

 

sreg<= (others=>'0');

 

 

elsif rising_edge(hs_clock)

then

 

if

bit_counter=9 then

 

 

bit_counter<=(others=>'0');

 

 

sreg<= symbol;

-- параллельная загрузка

else

sreg(8 downto 0)<=sreg(9 downto 1); -- сериализация bit_counter<=bit_counter+1;

case to_integer(bit_counter) is when 0 =>

63

if state=data0 or state=data1 or state=data2 then rd<='1';

end if;

if state=data0 or state=data1 then rd_fifo<='1';

end if; when 2 =>

rd<='0'; rd_fifo<='0';

when 4 => en<='1';

when 6 => en<='0';

symbol<=data_in10; when others =>

null; end case;

end if; end if;

end process;

STATE_MACHINE: process(reset_n,hs_clock) begin

if reset_n='0' then state<=SF1;

symbol_counter<= (others=>'0');

elsif rising_edge(hs_clock)

then

if bit_counter=9 then

 

case state is

 

when SF1 =>

 

state<=SF2;

 

when SF2 =>

 

state<=DATA0;

 

when DATA0 =>

 

state<=DATA1;

 

when DATA1 =>

 

state<=DATA2;

 

when DATA2 =>

if symbol_counter=7 then state<=EF1;

else

state<=DATA0; symbol_counter<=symbol_counter+1;

end if; when EF1 =>

state<=EF2;

64

symbol_counter<= (others=>'0'); when EF2 =>

state<=IDLE1; when IDLE1 =>

state<=IDLE2; when IDLE2 =>

if idle='1' then state<=IDLE1;

else

state<=SF1; end if;

when others => null;

end case; end if;

end if; end process; end Serializer;

Процесс STATE_MACINE реализует граф переходов автомата путем изменения значений сигнала state, кодирующего состояние автомата. Процесс COUNTER_0_TO_9 выполняет деление на 10-тактовой частоте hs_clock. 10 тактов – это время передачи символа кода 8b/10b на частоте hs_clock. В 9-м такте (счет идет от 0 до 9) каждого цикла делителя (сигнал bit_ counter) инициируется переход в автомате. В процессе формируются такие выходные сигналы, как rd и en. На рис. 3.11 приведена временная диаграмма формирования этих сигналов. В STATE_MACINE также выполняется операция сериализации: параллельная загрузка в 9-м такте и сдвиг в сторону младших разрядов сигнала sreg в остальных тактах. Младший разряд sreg(0) подключен к выходу Tx.

Рис. 3.11. Временная диаграмма формирования сигналов rd, rd_mode, en и op_code

65

Из диаграммы видны моменты времени переключения сигналов для трехэтапного преобразования в узле «Преобразование 12/8 бит». 12-разрядные данные считываются по сигналу rd, если значение сигнала rd_mode равно 0 или 1.

Сигнал op_code, сопровождаемый сигналом en, сообщает узлу «Кодер 8b/10b» тип формируемых символов (управляющие или данные). Значения сигналов op_code и rd_mode определяются только состояниями автомата (STATE_MACINE является автоматом Мура) и формируются условными параллельными операторами присвоения.

На рис. 3.12 приведен интерфейс coder_8b10b узла «Кодер 8b/10b», а ниже – программа-спецификация узла на VHDL.

coder_8b10b

op_code (2…0 )

data_out10 (9…0)

en

 

data_in8 (7…0 )

 

Рис. 3.12. Интерфейс узла «Кодер 8b/10»

VHDL программа-спецификация узла «Кодер 8b/10b»

library IEEE;

use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; entity coder_8b10b is

port(

reset_n : in STD_LOGIC; en : in STD_LOGIC;

op_code : in STD_LOGIC_VECTOR(2 downto 0); data_in8 : in STD_LOGIC_VECTOR(7 downto 0); data_out10 : out STD_LOGIC_VECTOR(9 downto 0)

);

end coder_8b10b;

architecture coder_8b10b of coder_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

66

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",

 

 

"110101", "101001",

"011001", "111000",

 

 

"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 := (

 

0=>

not Code5b6b_ROM_RDm(0),

 

 

 

1=>

not Code5b6b_ROM_RDm(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),

 

 

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 D_of_Code5b6b_type is array (0 to 31) of STD_LOGIC; constant D_of_Code5b6b : D_of_Code5b6b_type := (

'1','1','1','0','1','0','0','1','1','0','0','0','0','0','0',‘1', '1','0', '0','0','0','0', '0','1','1', '0','0', '1','0', '1','1', '1');

67

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",

4=>

"1101",5=>

"1010", 6=>

"0110",7=>

"1110");

constant Code3b4b_ROM_RDp : Code3b4b_type := (

0=>

not Code3b4b_ROM_RDm(0),

 

1=>

"1001", 2=>

"0101",

 

 

3=>

not Code3b4b_ROM_RDm(3),

 

4=>

not Code3b4b_ROM_RDm(4),

 

5=>

"1010", 6=>

"0110",

 

 

7=>

not Code3b4b_ROM_RDm(7) );

 

type D_of_Code3b4b_type is array (0 to 7) of STD_LOGIC; constant D_of_Code3b4b : D_of_Code3b4b_type := (

0=>

'1',1=>

'0',2=>

'0',

3=>

'1',

4=>

'1',5=>

'0',6=>

'0',

7=>

'1');

signal RD:std_logic; begin

CODER_8B_10B: process(reset_n, en) variable v_RD: std_logic;

variable v_data_out: std_logic_vector(9 downto 0); begin

if reset_n='0' then RD<='0';

data_out10<=(others=>'0'); elsif rising_edge(en) then

v_RD:=RD; case op_code is

when "000" => if RD='0' then

data_out10<=K28_5_RDm; else

data_out10<=not K28_5_RDm; end if;

when "001"

if D_of_Code5b6b(TO_INTEGER(unsigned(data_in8(4 downto 0))))='0' then

v_data_out(5 downto ) := cross_6(Code5b6b_ROM_RDm (TO_INTEGER(unsigned(data_in8(4 downto 0)))));

else

if v_RD='0' then

v_data_out(5 downto 0) :=cross_6(Code5b6b_ROM_RDm (TO_INTEGER(unsigned(data_in8(4 downto 0)))));

else

v_data_out(5 downto 0) :=cross_6(Code5b6b_ROM_RDp

68

(TO_INTEGER(unsigned(data_in8(4 downto 0)))));

end if;

if TO_INTEGER(unsigned(data_in8(4 downto 0)))/=7 then vRD:=not vRD;

end if;

end if;

if D_of_Code3b4b(TO_INTEGER(unsigned(data_in8(7 downto 5))))='0' then y(9 downto 6):=Cross_4(Code3b4b_ROM_RDm

(TO_INTEGER(unsigned(data_in8(7 downto 5)))));

else

if TO_INTEGER(unsigned(data_in8(7 downto 5)))/=7 then if vRd='0' then

y(9 downto 6):=Cross_4(Code3b4b_ROM_RDm (TO_INTEGER(unsigned(data_in8(7 downto 5)))));

else

y(9 downto 6):=Cross_4(Code3b4b_ROM_RDp (TO_INTEGER(unsigned(data_in8(7 downto 5)))));

end if;

if TO_INTEGER(unsigned(data_in8(7 downto 5)))/=3 then vRD:=not vRD;

end if;

else

if vRd='0' then

if TO_INTEGER(unsigned(data_in8(4 downto 0)))=17 or TO_INTEGER(unsigned(data_in8(4 downto 0)))=18 or TO_INTEGER(unsigned(data_in8(4 downto 0)))=20 then y(9 downto 6):=Cross_4(Code3b4b_ROM_RDp

(TO_INTEGER(unsigned(data_in8(7 downto 5)))));

else

y(9downto 6):=Cross_4(Code3b4b_ROM_RDm (TO_INTEGER(unsigned(data_in8(7 downto 5)))));

end if; else

if TO_INTEGER(unsigned(data_in8(4 downto 0)))=11 or TO_INTEGER(unsigned(data_in8(4 downto 0)))=13 or TO_INTEGER(unsigned(data_in8(4 downto 0)))=14 then

y(9 downto 6):=Cross_4(Code3b4b_ROM_RDm (TO_INTEGER(unsigned(data_in8(7 downto 5)))));

else

y(9 downto 6):=Cross_4(Code3b4b_ROM_RDp (TO_INTEGER(unsigned(data_in8(7 downot 5)))));

end if; end if;

vRD:=not vRD; end if;

69

end if; RD<=vRD; data_out10<=y;

when "100" => data_out10<=K29_7_RDm;

when others =>

if RD='0' then data_out10<=K28_5_RDm;

else

data_out10<=not K28_5_RDm; end if;

RD:=not RD;

end case; end if;

end process; end coder_8b10b;

В программе определены константы K28_5_RDm, K28_0_ RDm и K29_7_RDm К-символов, массивы констант Code5b6b_

ROM_RDm, Code5b6b_ROM_RDp, Code3b4b_ROM_RDm,

Code3b4b_ROM_RDp D-символов, представляющих таблицы соответствия кода 8b10b. Массивы констант D_of_Code5b6b и D_of_Code3b4b представляют сведения о дисбалансе соответствующих кодовых комбинаций.

Значения кода для данных на входе data_in8 появляются на выходе data_out10 по фронту сигнала en. Значение 0 на входе op_code вызывает формирование К-символа K28.5, значение 1 – D-символов, значение 2 – К-символа K28.0 и значение 3 – D-сим- вола D 0.0. Сигнал RD сохраняет текущее значение дисбаланса. Функции cross_6 и cross_4 выполняют перестановку бит кода для их выдачи в линию связи в правильной последовательности и не требуют аппаратных затрат.

Сиспользованием модели ПУА реализуем узел Deserializer

синтерфейсом на рис. 3.13.

На вход ddr_clock подается тактовый сигнал частотой 1,25 ГГц (ddr – удвоенная скорость), полученный выделителем тактовой частоты из входного сигнала Rx. Под действием ddr_clock последовательные данные Rx выравниваются и преобразуются в параллельные 10-битные символы data_out10. Выходные сигналы en и op_code необходимы для работы узла «Декодер 8b/10b», а выходной сигнал wr – для узла «FIFO приема».

70

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]