Лекция No7 Основни типове данни и операции при vhdl описания на цифрови устройства. Реализа



Дата28.01.2017
Размер192.79 Kb.
#13746

Проектиране на СГИС Лекция No7

Основни типове данни и операции при VHDL-

описания на цифрови устройства. Реализа -

ция върху ИС.
В следващата Таблица 3.1 са събрани основни типове данни на VHDL, които често се използват при описания на цифрови устройства, проектирани върху ИС. Показаните в таблицата типове могат да имат материални носители в структурата на устройството. Това означава, че с такива типове могат да бъдат данни, които като стойности на сигнали се обменят между устройството и външната за него среда, появяват се на изходите на функционалните му възли и се разпространяват по вътрешните линии и шини на устройството. Съкратено казваме,че сигналите на устройството могат да са от такива типове.

Таблица 3.1

тип на данни, които получават материален носител в проектираното устройство


възможни стойности на данните

boolean

TRUE

FALSE


integer

според развойната среда; типично в обхвата от –(231 – 1) до +(231 – 1)

bit

‘0’

‘1’


bit_vector

вектор (едномерен масив) от

елементи bit



std_logic

‘U’ (Uninitialized)

‘X’ (Forcing Unknown)

‘0' (Forcing 0)

‘1’ (Forcing 1)

‘Z’ (High Impedance)

‘W’ (Weak Unknown)

‘L’ (Weak 0)

‘H’ (Weak 1)

‘-‘ (Don’t care)


std_logic_vector

вектор (едномерен масив) от

елементи std_logic



Класическият тип bit от горната таблица представя стойностите на цифров сигнал по една линия (цифрова ‘0’ и цифрова ‘1’). Типът bit_vector представя едномерен масив от сигнали bit, разпространявани по група линии (например шина). Тези типове, заедно с типовете boolean и integer са дефинирани в пакет STANDARD на библиотека STD и заедно с работната библиотека WORK са достъпни по премълчаване за проект с VHDL – описание в развойните среди (без да се декларира с library… и use…). Типът std_logic е сравнително нов в VHDL и също представя стойностите на цифров сигнал по една линия или на изход на цифрова схема. Тези стойности са 9, за разлика от двете на bit и най-общо се използват за по-прецизно моделиране на проектираното цифрово устройство от развойната среда. Типът std_logic и типът std_logic_vector (представящ едномерен масив от std_logic) са дефинирани в пакета STD_LOGIC_1164, а операции с тях, които са описани в Таблица 3.2 по-долу, са предефинирани в пакета STD_LOGIC_UNSIGNED. Последните два пакета са разположени в библиотеката IEEE и достъпът до тях се декларира.

Представените в горната таблица типове могат да характеризират освен сигнали, също така променливи и константи. Тези елементи на VHDL – описанието се декларират по следния начин:

signal <име на сигнал>: <тип на данни>;

variable <име на променлива>: < тип на данни >;

constant <име на констнанта>: <тип на данни> := <стойност>;

Примери за декларации с използване на описваните тук типове данни:

signal CARRY: std_logic;

signal INPUT_D: std_logic_vector (0 to 15);

signal A_EQ_B: boolean;

signal RESULT: integer range 0 to 31;

signal BYTE_OUT: integer range -256 to 255;

variable OVERFLOW: bit;

variable CONTROL: bit_vector (3 downto 0);

constant COEFF1: std_logic_vector (7 downto 0) := "00100111";

Сигналите са основните VHDL – обекти, използвани за описание на пренасяните данни между цифровите устройства и външната за тях среда и вътре в структурата им. Променливите имат спомагателна функция и се използват главно в така наречените процеси в архитектурите на VHDL–описанията.

Когато във VHDL–процес сигнал приема нова стойност по време на нарастващия фронт на тактовите (синхронизиращи устройството)импулси, за този сигнал се синтезира регистър, съхраняващ стойността му в структурата на проектираното усткройство. Ако стойността се приема от променлива, за нея в структурата не се синтизира регистър.

Ако цифрово устройство за изчисления за “пеперуда” при бързо преобразуване на Фурие има в VHDL–описанието на архитектурата си следващия текст, а не текстът от Фиг.2.5, то в синтезираната му структура няма да ги има регистрите за междинните резултати А и В, тъй като в следващия текст те се декларират чрез променливи, а не чрез сигнали, както е на Фиг.2.5.

architecture Stage_1_3 of Fourier_butterfly is

signal Al1, Al2, Al3, Al4 : std_logic_vector (15 downto 0);

begin


process (CLK )

variable A, B : std_logic_vector (15 downto 0);

begin

if (CLK'event and CLK='1') then



Al1 <= P * R; Al2 <= S * Q;

Al3 <= P * S; Al4 <= R * Q;

A := Al1 - Al2; B := Al3 - Al4;

Mp <= M - A; Pp <= M + A;

Qp <= N + B; Np <= N - B;

end if;


end process;

end Stage_1_3;


При проектиране на цифровото устройство развойната среда разполага декларираните сигнали и променливи върху линии и шини с брой на линииите в шините такъв, че да е съобразен с декларирания брой разряди за данните от тип std_logic_vector или със съображение да представят двоично интервала от стойности, деклариран за типа, в случая за тип integer range….
Следващата Фиг.3.1 показва RTL – схемата, която една развойна среда съставя от горното VHDL – - описание и генерира входове и изходи на устройството с необходимия брой линии за обмен на сигналите, декларирани с типовете, показани по-горе.

Фигура 3.1


Следват примери за деклариране на константи. Тези примери демонстрират как се записват стойности на представяните тук типове данни:

constant EQ: boolean := TRUE;

constant INT: integer := 31;

constant ZERO: std_logic_vector (3 downto 0) := "0000";

constant HI_IMP: std_logic := 'Z';

constant DATA_REZ: (31 downto 0) := x"FF00";

Последната константа е декларирана с шестнадесетично представена стойност

С означението 'Z' се описва високоимпедансно състояние на изход на цифрова схема. В следваща лекция са разглеждани VHDL – описания на цифрови устройства и системи с такива изходи, свързани към обща шина.

VHDL – описанията допускат в тях да бъдат декларирани нови (потребителски) типове. Най-често при проектирането на цифрови устройства върху ИС това са масиви от сигнали. При декларирането се използва ключовата дума array.

На първо място масивите са използвани за описване на памети, реализирани върху ИС. Следващият текст декларира памет RAM с 1024 8 – разрядни думи:

type ram_type is array (1023 downto 0) of std_logic_vector (7 downto 0);

signal RAM : ram_type;

Масивите от сигнали се налага да бъдат декларирани и използвани и при описания на цифрови устройства с итеративна структура, съставена от функционални възли, регистри и шини, които се включват в структурата в повтарящи се конфигурации.
Таблица 3.2

тип операции, реализуеми в структурата на проектираното устройство

означения

особености в приложимостта

логически операции

and, or, nand, nor, xor, xnor, not



реализират се в структурата за типове данни boolean, bit, std_logic, а поразрядно и за типове integer, bit_vector, std_logic_vector

операции на отношение

(сравнение)



=, /=, <, <=, >, >=

реализират се в структурата за всички типове данни, като резултатът е от тип boolean

аритметически операции

+, -, *, /, rem, mod, abs, **

реализират се в структурата за типове данни integer и std_logic_vector с особености, определяни от конкретната развойна среда

операция за слепване (конкатенация)

&

реализира се в структурата за типове данни std_logic и std_logic_vector

Като нови потребителски типове понякога се налага и декларирането и използването на изброими типове. За тях при декларирането трябва да се изброят всички възможни стойности, които те могат да заемат, например:

type code is (ADD, INCR, SUB, MULT, SHL, SHR);

signal CO_ALU1 : code;

Изброимите типове, както е и декларираният тип на горния пример, се използват за описание на (управляващи) кодове с техните имена, разпространявани по шини или приемани на входовете на блокове в структурата на устройствата.

Горната Таблица 3.2 показва най-често използваните операции при VHDL – описанията на цифрови устройства:

Възможностите и начините за реализация в структрата на ИС на операциите от горната таблица зависят от конкретната развойна среда, която се използва за проектиране на цифровите устройства. Развойните среди използват и библиотеки от предварително проектирани блокове за реализацията на някои (най-често аритметични) операции.

Приоритетът при изпълняване в израз на операциите от горната таблица е дефиниран в следващата, Таблица 3:3

Таблица 3.3

тип на операциите

операции от групата

приоритет на изпълнение

логически операции

and, or, nand, nor, xor, xnor

най-нисък

(изпълняват се последни)



операции на отношение

=, /=, <, <=, >, >=




аритметически операции и слепване

+, -,&




унарни операции за знак

+, -




аритметически операции

*, /, rem, mod




операции от различен тип

**, abs, not

най-висок

(изпълняват се първи)


За да представим примери на изрази, използващи горните операции в VHDL – описания, първоначално ще покажем синтаксиса на операторите за присвояване на стойности на променливи и констнанти, които оператори допускат използването на изрази вдясно на знаците за присвояване:



<име на сигнал> <= <израз>;

<име на променлива> := <израз>;

Следват примери на изрази с логически операции. Ако операндите и резултатите в не са от тип boolean, то трябва да са с еднакъв брой разряди и се приема, че логическите операции се извършват за тях поразрядно.

signal A, B, C, Y: std_logic_vector(3 downto 0);

signal D, E, F, G: std_logic_vector(0 to 31);

signal H, I, J, K: std_logic;

signal L, M, N, O, P: boolean;


Y <= (B and not C) or A;

D <= E or (F or G);

H <= (I nand J) nand K;

L <= (M xor N) and (O xor P);

За да има яснота за развойната среда, която трябва за синтезира логическа схема за реализация на израза в ИС, необходимо е използването на скоби и при изрази с операции, които имат еднакъв приоритет, както е показано по-горе. (Има изключение от това изискване за операциите or и and, например: допустимо е E or F or G).

Следват примери на изрази с операции за сравнение. Трябва да се има предвид, че изразите с такива операции са от булев тип:

signal A, B: std_logic_vector(15 downto 0);

signal NUM : integer range 0 to 511;

signal G, LE, BOOL, FL : boolean;
G <= A > B;

LE <= C <= D;

FL <= not BOOL and NUM = 4;

Следват примери на изрази с аритметически операции.

signal A, B: std_logic_vector(7 downto 0);

signal C, Y: std_logic_vector(15 downto 0);

signal RESULT : std_logic_vector(8 downto 0);
Y <= A * B + C;

RESULT <= ‘0’&A + ‘0’& В;

В израз, който съдържа операцията умножение, желателно е броят на разрядите на резултата да е два пъти по-голям от броя на разрядите на операндите, тъй като представянето в структурата е двоично. Така се гарантира, че няма да се загубят цифри от резултата.

Последният израз от горния пример демонстрира често използван начин на описание и реализация в структурата на операция събиране така, че да не се загуби евентуалният пренос от най - старшия разряд на резултата. Преди извършване на операцията към двата операнда A и В се слепва константа ‘0’ като най-старши разряд. Операцията се извършва тогава с операнди с единица по-голям брой разряди (в случая 9) от първоначалния им брой. Резултатът (в случая RESULT) е деклариран със същия (с единица по-голям брой) разряди и в най-старшия му разряд се установява стойността на този пренос. От това описание се синтезира в структурата на ИС 9 – разряден суматор, въпреки че първоначалните операнди са 8 – разрядни.

Последните два примера показват използване на операция конкатенация за описване сливането на две шини в една, а също така и отделяне на част от линиите на шина за формиране на друга, с по-малък брой линии:

signal A, B: std_logic_vector(15 downto 0);

signal СONC: std_logic_vector(31 downto 0);

signal D: std_logic_vector (7 to 0);

CONC <= A & B;

D <= B(7 downto 0);

След въвеждане чрез проект в развойната среда на входно VHDL - описание на цифрово устройство (Фиг.2.5 на предната лекция), средата синтезира върху ИС електрически схеми, реализиращи операциите от описанието. По-рано бяха представени стъпките на проектиране на цифрови устройства върху ИС с помощта на развойна среда. Накратко те бяха:

а)синтезиране на абстрактна RTL – схема;

б)синтезиране на логическа схема;

в)синтезиране на електрическа схема;

г)синтезиране на топологични клетки, разполагане и свързване в чипа.

Процесът на проектиране за операциите от VHDL – описанието спазва тези стъпки, като в някои случаи някои от тях могат да бъдат пропуснати поради това, че развойните среди разполагат с библиотеки от готови модули, реализирани на някои от изброените по-горе нива.

Ще покажем някои примери за проектиране в ИС за операции от VHDL – описания.

За следващите логически операции с четириразрядни сигнали:

signal X1, X2, X3, Y : std_logic_vector (0 to 3);

Y <= (X1 and not X2) or X3;

развойната среда WebPACK синтезира RTL – схемата, показана на Фиг. 3.2. Всеки блок от тази схема би трябвало да реализира операциите за един разряд от декларираните по-горе сигнали – операнди.

Фигура 3.2


След логическо проектиране е получена логическа схема за всеки от горните блокове, показана на Фиг.3.3:

Фигура 3.3
Компонентите на логическата схема – логическите елементи - се синтезират електрически и топологически в логическите блокове на електрически конфигурируема ИС (FPGA). На фиг.3.4 са показани логическите генератори (F и G) в логическите блокове на FPGA - чип от фамилията VirtexII на фирма Xilinx, в които се реализират при програмиране (чрез управление от конфигурационен файл) логическите елементи за горната логическа схема.


Фигура 3.4
При проектиране на цифрово устройство с горните операции върху масково конфигурируеми ИС (ASIC) със стандартни клетки, развойните среди използват библиотеки от стандартни клетки с реализирани предварително на електрическо и топологическо ниво логически елементи. Тези стандартни клетки се разполагат в чипа и се свързват от системата така, че да реализират логическата схема. На Фиг.3.5 е показан топологическия вид на стандартни клетки за два логически елемента.

Фигура 3.5

За операцията abs, представена по-долу, развойната среда синтезира RTL - схема от Фиг.3.6, съдържаща инвертор, мултиплексер и блок, който е синтезиран на Фиг.3.7.

signal IN1, OUTD1 : integer range -8 to 7;

OUTD1 <= abs IN1;

Фигура 3.6



Фигура 3.7
За всеки от блоковете на Фиг.1.18 се синтезира логическата схема от Фиг.3.8, с което завършва логическият синтез за реализацията на тази операция.


Фигура 3.8
За трите операции на сравнение:

OUTB1 <= A > B;

OUTB2 <= A = B;

OUTB3 <= A < B;

развойната среда за проектиране върху FPGA първоначално синтезира RTL – схемата от Фиг.3.9.

Фигура 3.9

Всеки от трите блока – компаратори е синтезиран логически, а след това и електрически, и топологически в блоковете на FPGA – чип, използвайки библиотека на развойната среда – Фиг.3.10.

Фигура 3.10

Аритметическият израз, представен по-долу, също се реализира с помощта на библиотека на развойната среда. Първоначално синтезираната от него, вътрешна за средата RTL – схема е показана на Фиг.3.11.

signal A, B: std_logic_vector(7 downto 0);

signal C, Y: std_logic_vector(15 downto 0);

Y <= A * B + C;



Фигура 3.11

Изразът е проектиран върху FPGA - чип от фамилията VirtexII на фирма Xilinx, в структурата на който има вградени умножители (Фиг.3.12).

Фигура 3.12


Развойната среда директно реализира операцията умножение в един от умножителите, без да синтезира тази операция. Операцията събиране се синтезира в логическите блокове на чипа, като средата използва библиотека.

Ако аритметическата схема се реализира върху FPGA – чип, който не притежава вградени блокове – умножители, развойната среда проектира логическа схема за умножение и я реализира чрез логическите блокове на чипа, както е показано за чип от фамилията VirtexE на фирма Xilinx (Фиг. 3.13):


Използване на VHDL – архитектури с поток



на данните
VHDL – архитектурите с поток на данните (dataflow – архитектури) описват начина на функциониране на проектираните устройства чрез зависимостите на едни сигнали на устройствата (най-често изходни) от други сигнали (най-често входни или вътрешни). Тези зависимости се представят чрез оператори за присвояване и изрази на VHDL най-често логически и аритметически. По-долу ще обсъдим няколко типични примера на такива архитектури, представящи възможностите им за проектиране на цифрови устройства върху FPGA-'чипове.

Първият пример е на dataflow – архитектура на едноразряден суматор с операнди IN1 и IN2, входен пренос C_IN, резултат - сума SUM и изходен пренос C_OUT. Следващата Таблица 4.1 включва таблиците за истинност на логическите функции SUM и C_OUT в зависимост от аргементите IN1, IN2 и C_IN.



Таблица 4.1

IN1

IN2

C_IN

SUM

C_OUT

0

0

0

0

0

0

0

1

1

0

0

1

0

1

0

0

1

1

0

1

1

0

0

1

0

1

0

1

0

1

1

1

0

0

1

1

1

1

1

1

Решавайки задачата за логическо проектиране, можем да получим следните логически изрази за двете функции:

където:


Схемата на устройството, изпълняващо горните изрази, е представена на Фиг.4.1



Фигура 4.1


Следва VHDL – описанието на устройството с име full_adder. В него архитектурата Dataflow1 е с поток на данните (dataflow – архитектура ).

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity full_adder is

Port ( IN1, IN2, C_IN : in std_logic;

SUM, C_OUT : out std_logic );

end full_adder;

architecture Dataflow1 of full_adder is

signal S1, S2, S3 : std_logic;

begin


S1 <= IN1 xor IN2;

S2 <= C_IN and S1;

SUM <= S1 xor C_IN;

S3 <= IN1 and IN2;

C_OUT <= S2 or S3;

end Dataflow1;

Както се вижда от горниия текст, в тялото на архитектурата (между ключовите думи begin и end) са поставени операторите за присвояване на нови стойности на сигнали.

Важно правило, което трябва да се има предвид при dataflow – архитектурите е, че се приема, че операторите за присвояване на нови стойности на сигналите се изпълняват паралелно в тялото на архитектурата. Това е съществено за работата на развойната система, която от VHDL – описанието проектира устройството и за работата на симулатора на функционирането на устройството.

Следвайки това правило, можем да кажем, че операторите за присвояване в горния текст, подредени по всякакъв друг начин , няма да променят проектираното устройство и неговото функциониране.

Както знаем от предната лекция, операторите за присвояване на стойности на сигналимогат да бъдат написани и с по-сложни изрази, съдържащи повече знаци за операции в тях. Долната архитектура Dataflow2, например, описва същото устройство:

architecture Dataflow2 of full_adder is

begin


SUM <= (IN1 xor IN2) xor C_IN;

C_OUT <= ((IN1 xor IN2) and C_IN) or (IN1 and IN2);

end Dataflow2;

Начинът на реализация на едноразрядния суматор върху FPGA – чип е показан на Фиг.4.2. Всяка от двете логически функции, които описват изходите му, е реализирана поотделно върху комбинационни схеми (така наречените логически генератори F и G), настройвани при конфигурирането на чипа да изпълняват съответните логически функции. Изходите на логическите генератори са свързани към изводи на чипа, представящи SUM и C_OUT.



Фигура 4.2


Следващият пример е на dataflow – архитектура на D - тригер, синхронен по ниво на синхронизиращия сигнал C (така нареченият latch). Като всеки друг тригер, и този притежава прав (Q) и обратен изход (NQ). Схемата на тригера е представена на Фиг. 4.3.

Фигура 4.3


VHDL – описанието на тригера е показано по-долу. Този пример илюстрира възможността да се описват чрез dataflow – архитектури и устройства с обратни връзки в структурата си.

В приведената по-долу entity - декларация на тригера изходните сигнали Q и NQ са декларирани като inout, защото се използуват и като аргументи на операции в схемата поради обратните връзки в нея.


library IEEE;

use IEEE.STD_LOGIC_1164.ALL;


entity d_latch is

Port (D, C : in std_logic;

Q, NQ : inout std_logic );

end d_latch;


architecture Dataflow3 of d_latch is

signal NS, NR : std_logic;

begin

NS <= D nand C;



NR <= NS nand C;

Q <= NS nand NQ;

NQ <= NR nand Q;

end Dataflow3;


Реализацията на тригера върху FPGA – чип от фамилията Spartan3 е показана на Фиг.4.4. Интересно в нея е това, че въпреки че чипът притежава в структурата си такива тригери, то за реализацията са използвани логически генератори (F и G), както за комбинационна схема (едноразряден суматор), разгледана по-горе. Това е така, защото развойните системи, проектиращи тригера, не разпознават горното описание като описание на тригер. Начин, по който се съставя VHDL - описание, което се разпознава от развойните системи като тригер, е дадено в следващата лекция.


Фигура 4.4


Следващият пример е на описание на устройство, извършващо изчисления за макрооперацията “пеперуда” за бързо преобразуване на Фурие. Видът и връзките между операциите (с комплексни числа) са представени на диаграмата на Фиг.4.5.

Фигура 4.5

Граф на зависимостта по данни (dataflow - граф), описващ необходимите аритметични операции, е показан на Фиг.4.6.

Фигура 4.6

Имайки предвид графа на зависимостта по данни, е съставена архитектурата Dataflow4 на устройството с име fourier_top:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity fourier_top is

port (


P : in std_logic_vector (15 downto 0);

Q : in std_logic_vector (15 downto 0);

R : in std_logic_vector (15 downto 0);

S : in std_logic_vector (15 downto 0);

M : in std_logic_vector (15 downto 0);

N : in std_logic_vector (15 downto 0);

Mp : out std_logic_vector (15 downto 0);

Np : out std_logic_vector (15 downto 0);

Pp : out std_logic_vector (15 downto 0);

Qp : out std_logic_vector (15 downto 0)

);

end fourier_top;


architecture Dataflow4 of fourier_top is

signal Al1, Al2, Al3, Al4, A, B : std_logic_vector (15 downto 0);

begin

Al1 <= P * R; Al2 <= S * Q; Al3 <= P * S; Al4 <= R * Q;



A <= Al1 - Al2; B <= Al3 - Al4;

Mp <= M - A; Pp <= M + A; Qp <= N + B; Np <= N - B;

end Dataflow4;

Показаната архитектура описва комбинационно устройство, в структурата на което няма регистри. Ако искаме да опишем такова устройство, притежаващо регистри (за синхронизация на функционирането и за работа в конвейерен режим), необходимо е да използваме начините за съставяне на VHDL - архитектури, описани в следващите лекции.

Следващата схема на Фиг.4.7 е на устройство, съставено от умножител и буферна схема с три състояния на изхода си. Входовете за операнди на умножителя са A и B , входът RESET нулира изхода C на умножителя (когато има стойност '1'), входът OE на буфера привежда изхода му във високоимпедансно състояние, когато има стойност, различна от '0' , (тоест '1').

Фигура 4.7

VHDL – описанието на устройството е показано по-долу. С него е демонстрирано това, че във dataflow - архитектура може да бъде използван, освен оператор за присвояване, още и оператор за условно присвояване на стойност на сигнал (това са синтактичните конструкции в архитектурата с ключовите думи when и else).

В entity - декларацията на устройството изходният сигнал C е делариран като inout, защото едновременно е и входен за буферната схема.

Конструкцията (others =>…) описва това, че всички разряди на съответната дума (вектор от битове) приемат означената стойност след стрелката. Ще припомним, че константата 'Z' означава високоимпедансно състояние на едноразряден изход.

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity mult_buff is

Port (A: in std_logic_vector (15 downto 0);

B: in std_logic_vector (15 downto 0);

C: inout std_logic_vector (31 downto 0);

Y: out std_logic_vector (31 downto 0);

RESET: in std_logic;

OE: std_logic

);

end mult_buff;


architecture Dataflow5 of mult_buff is

begin


C <= (others => '0') when (RESET = '1')

else A * B;

Y <= C when (OE = '0')

else (others => 'Z');



end Dataflow5;





Каталог: KST%202%20kurs%20Mag -> 2%20sem -> PSGIS -> Lekcii
Lekcii -> Лекция №2 Проектиране на сгис
Lekcii -> Интегрални Схеми. Определения. Процеси на проектиране и производство. Основни елементи и технологии
Lekcii -> Лекция No 5 Преглед на архитектурните и схемотехнически особености на съвременните fpga чипове
Lekcii -> Лекция №4 Проектиране на сгис памети в компютърните системи архитектура, логически и схемотехнически характеристики
PSGIS -> Проектиране на сгис упражнение No 6
Lekcii -> Стъпки в процеса на проектиране на цифрови устройства върху конфигурируеми чрез маски сгис. Пример за проектиране “отгоре-надолу”


Сподели с приятели:




©obuch.info 2024
отнасят до администрацията

    Начална страница