ПЦУСБ/Лекция 5 — различия между версиями
Материал из Wiki
< ПЦУСБ
ANA (обсуждение | вклад) (Новая страница: «{{ПЦУСБ TOC}} <slideshow style="custis" headingmark="Слайд:" incmark=":step" scaled="true"> ;title: Операторы языка VHDL ;author: Авд…») |
ANA (обсуждение | вклад) м (→Слайд: Последовательные операторы) |
||
(не показаны 11 промежуточных версий 1 участника) | |||
Строка 21: | Строка 21: | ||
* wait | * wait | ||
− | Используются в: | + | Используются в подпрограммах: |
* process | * process | ||
* функциях | * функциях | ||
− | |||
− | === Слайд: | + | === Слайд: Оператор присваивания: <tt><=</tt> === |
+ | |||
+ | {{link|conditional_waveform_assignment}} ::= [§ '''10.5.3'''] | ||
+ | {{ref|target}} <= [ {{ref|delay_mechanism}} ] {{ref|conditional_waveforms}} ; | ||
+ | |||
+ | {{link|delay_mechanism}} ::= [§ '''10.5.2.1'''] | ||
+ | '''transport''' | ||
+ | | [ '''reject''' ''time''_expression ] '''inertial''' | ||
+ | |||
+ | Пример транспортной задержки: | ||
+ | transmission_line : process (line_in) is | ||
+ | begin | ||
+ | line_out <= '''transport''' line_in '''after''' 500 ps; | ||
+ | end process transmission_line; | ||
+ | |||
+ | Пример инерционной задержки: | ||
+ | inv : process (a) is | ||
+ | begin | ||
+ | y <= '''inertial''' not a after 3 ns; | ||
+ | {{Сн|'''или'''}} | ||
+ | y <= not a after 3 ns; | ||
+ | end process inv; | ||
+ | |||
+ | inv : process (a) is | ||
+ | begin | ||
+ | y <= '''reject''' 2 ns '''inertial''' not a after 3 ns; | ||
+ | end process inv; | ||
+ | |||
+ | <small> | ||
+ | * §5.2.5 Transport and Inertial Delay Mechanisms (стр. 158) | ||
+ | </small> | ||
+ | |||
+ | |||
+ | ==== Слайд: Оператор присваивания: <tt><=</tt> ==== | ||
+ | |||
+ | * EXAMPLE 5.10 An asymmetric delay element using transport delay | ||
+ | |||
+ | asym_delay : process (a) is | ||
+ | constant Tpd_01 : time := 800 ps; | ||
+ | constant Tpd_10 : time := 500 ps; | ||
+ | begin | ||
+ | if a then | ||
+ | z <= transport a after Tpd_01; | ||
+ | else -- not a | ||
+ | z <= transport a after Tpd_10; | ||
+ | end if; | ||
+ | end process asym_delay; | ||
+ | |||
+ | |||
+ | === Слайд: Оператор loop === | ||
+ | |||
+ | * бесконечный цикл | ||
+ | |||
+ | loop_statement ⇐ | ||
+ | [ loop_label : ] '''loop''' | ||
+ | { последовательные операторы } | ||
+ | '''end loop''' [ loop_label ] ; | ||
+ | |||
+ | * Пример | ||
+ | entity counter is | ||
+ | port ( clk : in bit; | ||
+ | count : out natural ); | ||
+ | end entity counter; | ||
+ | |||
+ | architecture behavior of counter is | ||
+ | begin | ||
+ | incrementer : process is | ||
+ | variable count_value : natural := 0; | ||
+ | begin | ||
+ | count <= count_value; | ||
+ | '''loop''' | ||
+ | wait until clk; | ||
+ | count_value := (count_value + 1) mod 16; | ||
+ | count <= count_value; | ||
+ | '''end loop'''; | ||
+ | end process incrementer; | ||
+ | end architecture behavior; | ||
+ | |||
+ | <small> | ||
+ | * 3.4 Loop Statements (стр. 84 (76)) | ||
+ | </small> | ||
+ | |||
+ | ==== Слайд: Оператор exit ==== | ||
+ | |||
+ | * Выход из цикла | ||
+ | {{link|exit_statement}} ::= [§ '''10.2'''] | ||
+ | [ {{ref|label}} : ] '''exit''' [ ''loop''_label ] [ '''when''' {{ref|condition}} ] ; | ||
+ | |||
+ | * Пример | ||
+ | {|cellspacing="0" cellpadding="5" border="1" | ||
+ | | <pre> | ||
+ | loop | ||
+ | if condition then | ||
+ | exit; | ||
+ | end if; | ||
+ | end loop; | ||
+ | </pre> | ||
+ | |<pre> | ||
+ | loop | ||
+ | ... | ||
+ | exit when ''условие''; | ||
+ | ... | ||
+ | end loop; | ||
+ | ... -- Управление перейдёт сюда | ||
+ | -- при выполнения условия внутри цикла loop</pre> | ||
+ | |} | ||
+ | |||
+ | loop_name : '''loop''' | ||
+ | ... | ||
+ | '''exit''' loop_name; | ||
+ | ... | ||
+ | '''end loop''' loop_name; | ||
+ | |||
+ | |||
+ | ==== Слайд: Оператор next ==== | ||
+ | |||
+ | * Переход на следующую итерацию цикла | ||
+ | |||
+ | {{link|next_statement}} ::= [§ '''10.11'''] | ||
+ | [ {{ref|label}} : ] '''next''' [ ''loop''_label ] [ '''when''' {{ref|condition}} ] ; | ||
+ | |||
+ | |||
+ | {| cellspacing="0" cellpadding="5" border="1" | ||
+ | |<pre> | ||
+ | loop | ||
+ | statement-1; | ||
+ | next when condition; | ||
+ | statement-2; | ||
+ | end loop;</pre> | ||
+ | |<pre> | ||
+ | loop | ||
+ | statement-1; | ||
+ | if not condition then | ||
+ | statement-2; | ||
+ | end if; | ||
+ | end loop;</pre> | ||
+ | |} | ||
+ | |||
+ | |||
+ | === Слайд: Оператор цикла while..loop=== | ||
+ | |||
+ | loop_statement ⇐ | ||
+ | [ loop_label : ] | ||
+ | '''while''' condition '''loop''' | ||
+ | { sequential_statement } | ||
+ | '''end loop''' [ loop_label ] ; | ||
+ | |||
+ | |||
+ | while index > 0 loop | ||
+ | ... -- statement A: do something with index | ||
+ | end loop; | ||
+ | ... -- statement B | ||
+ | |||
+ | |||
+ | === Слайд: Оператор цикла for..loop=== | ||
+ | |||
+ | loop_statement ⇐ | ||
+ | [ loop_label : ] | ||
+ | '''for''' identifier '''in''' discrete_range '''loop''' | ||
+ | { sequential_statement } | ||
+ | '''end loop''' [ loop_label ] ; | ||
+ | |||
+ | discrete_range ⇐ | ||
+ | simple_expression ( '''to''' | '''downto''' ) simple_expression | ||
+ | |||
+ | |||
+ | '''for''' count_value '''in''' 0 '''to''' 127 '''loop''' | ||
+ | count_out <= count_value; | ||
+ | wait for 5 ns; | ||
+ | '''end loop'''; | ||
+ | |||
+ | |||
+ | === Слайд: Оператор assert (утверждение) === | ||
+ | |||
+ | * проверяет условие (утверждение), в случае нарушения которого может выдаваться сообщение | ||
+ | concurrent_assertion_statement ⇐ | ||
+ | [ label : ] | ||
+ | '''assert''' ''condition'' | ||
+ | [ '''report''' ''expression'' ] [ '''severity''' ''expression'' ] ; | ||
+ | |||
+ | '''assert''' initial_value <= max_value | ||
+ | '''report''' "initial value too large"; | ||
+ | |||
+ | '''assert''' current_character >= '0' '''and''' current_character <= '9' | ||
+ | '''report''' "Input number " & input_string & " contains a non-digit"; | ||
+ | |||
+ | check : '''assert''' not (s and r) | ||
+ | '''report''' "Incorrect use of S_R_flip_flop: " & | ||
+ | "s and r both '1'"; | ||
+ | |||
+ | * в пакете STANDARD: | ||
+ | '''type''' severity_level '''is''' (note, warning, error, failure); | ||
+ | |||
+ | '''assert''' free_memory >= low_water_limit | ||
+ | '''report''' "low on memory, about to start garbage collect" | ||
+ | '''severity''' note; | ||
+ | |||
+ | === Слайд: Оператор wait === | ||
+ | |||
+ | wait_statement ⇐ | ||
+ | [ label : ] '''wait''' [ '''on''' ''имя_сигнала'' { , ... } ] | ||
+ | [ '''until''' ''условие'' ] | ||
+ | [ '''for''' ''выражение_типа_time'' ] ; | ||
+ | |||
+ | |||
+ | {| cellspacing="0" cellpadding="5" border="1" align=center | ||
+ | !colspan=2| Эквивалентные описания процесса | ||
+ | |- | ||
+ | |<pre> | ||
+ | half_add : process is | ||
+ | begin | ||
+ | sum <= a xor b after T_pd; | ||
+ | carry <= a and b after T_pd; | ||
+ | wait on a, b; | ||
+ | end process half_add;</pre> | ||
+ | |<pre> | ||
+ | half_add : process (a, b) is | ||
+ | begin | ||
+ | sum <= a xor b after T_pd; | ||
+ | carry <= a and b after T_pd; | ||
+ | end process half_add;</pre> | ||
+ | |} | ||
+ | |||
+ | <small> | ||
+ | * §5.2.3 Wait Statements | ||
+ | </small> | ||
+ | |||
+ | |||
+ | ==== Слайд: Оператор wait until ==== | ||
+ | |||
+ | signal clk : std_logic; | ||
+ | . . . . | ||
+ | clock_gen : process is | ||
+ | begin | ||
+ | clk <= '1' '''after''' 11 ns, '0' '''after''' 25 ns; | ||
+ | '''wait until''' clk = '0'; | ||
+ | end process clock_gen; | ||
+ | |||
+ | |||
+ | [[Файл:Wait until not clk wave.png|center]] | ||
+ | |||
+ | |||
+ | ==== Слайд: Оператор wait on ==== | ||
+ | |||
+ | {| cellspacing="0" cellpadding="5" border="1" align=center | ||
+ | |colspan=3|<pre> | ||
+ | signal clk1 : std_logic := '0'; | ||
+ | signal clk2,clk3,clk4 : std_logic; | ||
+ | .... | ||
+ | clock_gen : process is | ||
+ | begin | ||
+ | clk1 <= '1' after 11 ns, '0' after 25 ns; | ||
+ | wait until clk1 = '0'; | ||
+ | end process clock_gen; | ||
+ | </pre> | ||
+ | |- | ||
+ | |<pre> | ||
+ | pp1 : process is | ||
+ | begin | ||
+ | wait on clk1; | ||
+ | clk2 <= clk1 after 1 ns; | ||
+ | end process pp1; | ||
+ | </pre> | ||
+ | |<pre> | ||
+ | pp2 : process is | ||
+ | begin | ||
+ | clk3 <= clk1 after 1 ns; | ||
+ | wait on clk1; | ||
+ | end process pp2; | ||
+ | </pre> | ||
+ | |<pre> | ||
+ | pp3 : process (clk1) is | ||
+ | begin | ||
+ | clk4 <= clk1 after 1 ns; | ||
+ | end process pp3; | ||
+ | </pre> | ||
+ | |} | ||
+ | |||
+ | |||
+ | [[Файл:Wait on clk wave.png|center]] | ||
+ | |||
+ | ==== Слайд: Оператор wait for ==== | ||
+ | |||
+ | * ожидание заданное время, т.е. процесс прерывает свою работу на заданное время | ||
+ | |||
+ | process is | ||
+ | begin -- process | ||
+ | strob <= '0'; | ||
+ | wait for 45 ns; | ||
+ | strob <= '1'; | ||
+ | wait for 5 ns; | ||
+ | end process; | ||
+ | |||
+ | |||
+ | ==== Слайд: Комбинации операторов wait ==== | ||
+ | |||
+ | wait on clk until reset = '1'; | ||
+ | |||
+ | * Условие <code>reset = '1'</code> будет проверяться только в момент изменения <code>clk</code> | ||
+ | |||
+ | wait until trigger = '1' for 1 ms; | ||
+ | * ожидание пока не выполнится условие <code>trigger = '1'</code>, но не более 1 мс | ||
+ | |||
+ | === Слайд: Процедуры === | ||
+ | |||
+ | subprogram_body ⇐ | ||
+ | '''procedure''' identifier [ ( parameter_interface_list ) ] '''is''' | ||
+ | { subprogram_declarative_part } | ||
+ | '''begin''' | ||
+ | { sequential_statement } | ||
+ | '''end''' [ procedure ] [ identifier ] ; | ||
+ | |||
+ | return_statement ⇐ [ label : ] '''return''' ; | ||
+ | |||
+ | interface_list ⇐ | ||
+ | ( [ '''constant''' | '''variable''' | '''signal''' ] | ||
+ | identifier { , ... } : [ {{Сн|mode}} ] subtype_indication | ||
+ | [ := static_expression ] ) { ; ... } | ||
+ | {{Сн|mode}} ⇐ '''in''' | '''out''' | '''inout''' | ||
+ | |||
+ | * Пример | ||
+ | |||
+ | '''procedure''' do_arith_op ( op : '''in''' func_code ) '''is''' | ||
+ | variable result : integer; | ||
+ | '''begin''' | ||
+ | case op is | ||
+ | when add => | ||
+ | result := op1 + op2; | ||
+ | when subtract => | ||
+ | result := op1 - op2; | ||
+ | end case; | ||
+ | dest <= result after Tpd; | ||
+ | Z_flag <= result = 0 after Tpd; | ||
+ | '''end procedure''' do_arith_op; | ||
+ | |||
+ | <source lang="vhdl"> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
+ | |||
+ | entity signal_generator is | ||
+ | end entity signal_generator; | ||
+ | |||
+ | architecture top_level of signal_generator is | ||
+ | |||
+ | signal raw_signal : std_ulogic; | ||
+ | |||
+ | procedure generate_pulse_train | ||
+ | ( width, separation : in delay_length; | ||
+ | number : in natural; | ||
+ | signal s : out std_ulogic ) is | ||
+ | begin | ||
+ | for count in 1 to number loop | ||
+ | s <= '1', '0' after width; | ||
+ | wait for width + separation; | ||
+ | end loop; | ||
+ | end procedure generate_pulse_train; | ||
+ | |||
+ | begin | ||
+ | |||
+ | raw_signal_generator : process is | ||
+ | begin | ||
+ | |||
+ | generate_pulse_train ( width => 20 ns, | ||
+ | separation => 10 ns, | ||
+ | number => 10, | ||
+ | s => raw_signal ); | ||
+ | generate_pulse_train ( width => 5 ns, | ||
+ | separation => 20 ns, | ||
+ | number => 10, | ||
+ | s => raw_signal ); | ||
+ | wait; | ||
+ | end process raw_signal_generator; | ||
+ | |||
+ | end architecture top_level; | ||
+ | </source> | ||
+ | |||
+ | === Слайд: Функции === | ||
+ | |||
+ | subprogram_body ⇐ | ||
+ | [ pure I impure ] | ||
+ | '''function''' identifier [ ( parameter_interface_list ) ] '''return''' type_mark '''is''' | ||
+ | { subprogram_declarative_item } | ||
+ | '''begin''' | ||
+ | { sequential_statement } | ||
+ | '''end''' [ '''function''' ] [ identifier ] ; | ||
+ | |||
+ | return_statement ⇐ [ label : ] '''return''' expression ; | ||
+ | |||
+ | function_call ⇐ function_name [ ( parameter_association_list ) ] | ||
+ | |||
+ | |||
+ | '''function''' limit ( value, min, max : integer ) '''return''' integer '''is''' | ||
+ | '''begin''' | ||
+ | if value > max then | ||
+ | '''return''' max; | ||
+ | elsif value < min then | ||
+ | '''return''' min; | ||
+ | else | ||
+ | '''return''' value; | ||
+ | end if; | ||
+ | '''end function''' limit; |
Текущая версия на 22:33, 14 ноября 2013
- Заголовок
- Операторы языка VHDL
- Автор
- Авдеев Н.А.
- Нижний колонтитул
- ПЦУСБ/Лекция 5
- Дополнительный нижний колонтитул
- Авдеев Н.А., 22:33, 14 ноября 2013
Содержание |
Слайд: Последовательные операторы
- :=
- <=
- if
- case
- loop
- next
- exit
- null
- procedure call
- return
- assert
- wait
Используются в подпрограммах:
- process
- функциях
Слайд: Оператор присваивания: <=
conditional_waveform_assignment ::= [§ 10.5.3] target <= [ delay_mechanism ] conditional_waveforms ;
delay_mechanism ::= [§ 10.5.2.1] transport | [ reject time_expression ] inertial
Пример транспортной задержки:
transmission_line : process (line_in) is begin line_out <= transport line_in after 500 ps; end process transmission_line;
Пример инерционной задержки:
inv : process (a) is
begin
y <= inertial not a after 3 ns;
или
y <= not a after 3 ns;
end process inv;
inv : process (a) is begin y <= reject 2 ns inertial not a after 3 ns; end process inv;
- §5.2.5 Transport and Inertial Delay Mechanisms (стр. 158)
Слайд: Оператор присваивания: <=
- EXAMPLE 5.10 An asymmetric delay element using transport delay
asym_delay : process (a) is constant Tpd_01 : time := 800 ps; constant Tpd_10 : time := 500 ps; begin if a then z <= transport a after Tpd_01; else -- not a z <= transport a after Tpd_10; end if; end process asym_delay;
Слайд: Оператор loop
- бесконечный цикл
loop_statement ⇐ [ loop_label : ] loop { последовательные операторы } end loop [ loop_label ] ;
- Пример
entity counter is port ( clk : in bit; count : out natural ); end entity counter; architecture behavior of counter is begin incrementer : process is variable count_value : natural := 0; begin count <= count_value; loop wait until clk; count_value := (count_value + 1) mod 16; count <= count_value; end loop; end process incrementer; end architecture behavior;
- 3.4 Loop Statements (стр. 84 (76))
Слайд: Оператор exit
- Выход из цикла
exit_statement ::= [§ 10.2] [ label : ] exit [ loop_label ] [ when condition ] ;
- Пример
loop if condition then exit; end if; end loop; |
loop ... exit when ''условие''; ... end loop; ... -- Управление перейдёт сюда -- при выполнения условия внутри цикла loop |
loop_name : loop ... exit loop_name; ... end loop loop_name;
Слайд: Оператор next
- Переход на следующую итерацию цикла
next_statement ::= [§ 10.11] [ label : ] next [ loop_label ] [ when condition ] ;
loop statement-1; next when condition; statement-2; end loop; |
loop statement-1; if not condition then statement-2; end if; end loop; |
Слайд: Оператор цикла while..loop
loop_statement ⇐ [ loop_label : ] while condition loop { sequential_statement } end loop [ loop_label ] ;
while index > 0 loop ... -- statement A: do something with index end loop; ... -- statement B
Слайд: Оператор цикла for..loop
loop_statement ⇐ [ loop_label : ] for identifier in discrete_range loop { sequential_statement } end loop [ loop_label ] ;
discrete_range ⇐ simple_expression ( to | downto ) simple_expression
for count_value in 0 to 127 loop count_out <= count_value; wait for 5 ns; end loop;
Слайд: Оператор assert (утверждение)
- проверяет условие (утверждение), в случае нарушения которого может выдаваться сообщение
concurrent_assertion_statement ⇐ [ label : ] assert condition [ report expression ] [ severity expression ] ;
assert initial_value <= max_value report "initial value too large";
assert current_character >= '0' and current_character <= '9' report "Input number " & input_string & " contains a non-digit";
check : assert not (s and r) report "Incorrect use of S_R_flip_flop: " & "s and r both '1'";
- в пакете STANDARD:
type severity_level is (note, warning, error, failure);
assert free_memory >= low_water_limit report "low on memory, about to start garbage collect" severity note;
Слайд: Оператор wait
wait_statement ⇐ [ label : ] wait [ on имя_сигнала { , ... } ] [ until условие ] [ for выражение_типа_time ] ;
Эквивалентные описания процесса | |
---|---|
half_add : process is begin sum <= a xor b after T_pd; carry <= a and b after T_pd; wait on a, b; end process half_add; |
half_add : process (a, b) is begin sum <= a xor b after T_pd; carry <= a and b after T_pd; end process half_add; |
- §5.2.3 Wait Statements
Слайд: Оператор wait until
signal clk : std_logic; . . . . clock_gen : process is begin clk <= '1' after 11 ns, '0' after 25 ns; wait until clk = '0'; end process clock_gen;
Слайд: Оператор wait on
signal clk1 : std_logic := '0'; signal clk2,clk3,clk4 : std_logic; .... clock_gen : process is begin clk1 <= '1' after 11 ns, '0' after 25 ns; wait until clk1 = '0'; end process clock_gen; | ||
pp1 : process is begin wait on clk1; clk2 <= clk1 after 1 ns; end process pp1; |
pp2 : process is begin clk3 <= clk1 after 1 ns; wait on clk1; end process pp2; |
pp3 : process (clk1) is begin clk4 <= clk1 after 1 ns; end process pp3; |
Слайд: Оператор wait for
- ожидание заданное время, т.е. процесс прерывает свою работу на заданное время
process is begin -- process strob <= '0'; wait for 45 ns; strob <= '1'; wait for 5 ns; end process;
Слайд: Комбинации операторов wait
wait on clk until reset = '1';
- Условие
reset = '1'
будет проверяться только в момент измененияclk
wait until trigger = '1' for 1 ms;
- ожидание пока не выполнится условие
trigger = '1'
, но не более 1 мс
Слайд: Процедуры
subprogram_body ⇐ procedure identifier [ ( parameter_interface_list ) ] is { subprogram_declarative_part } begin { sequential_statement } end [ procedure ] [ identifier ] ;
return_statement ⇐ [ label : ] return ;
interface_list ⇐ ( [ constant | variable | signal ] identifier { , ... } : [ mode ] subtype_indication [ := static_expression ] ) { ; ... } mode ⇐ in | out | inout
- Пример
procedure do_arith_op ( op : in func_code ) is variable result : integer; begin case op is when add => result := op1 + op2; when subtract => result := op1 - op2; end case; dest <= result after Tpd; Z_flag <= result = 0 after Tpd; end procedure do_arith_op;
library ieee; use ieee.std_logic_1164.all; entity signal_generator is end entity signal_generator; architecture top_level of signal_generator is signal raw_signal : std_ulogic; procedure generate_pulse_train ( width, separation : in delay_length; number : in natural; signal s : out std_ulogic ) is begin for count in 1 to number loop s <= '1', '0' after width; wait for width + separation; end loop; end procedure generate_pulse_train; begin raw_signal_generator : process is begin generate_pulse_train ( width => 20 ns, separation => 10 ns, number => 10, s => raw_signal ); generate_pulse_train ( width => 5 ns, separation => 20 ns, number => 10, s => raw_signal ); wait; end process raw_signal_generator; end architecture top_level;
Слайд: Функции
subprogram_body ⇐ [ pure I impure ] function identifier [ ( parameter_interface_list ) ] return type_mark is { subprogram_declarative_item } begin { sequential_statement } end [ function ] [ identifier ] ;
return_statement ⇐ [ label : ] return expression ;
function_call ⇐ function_name [ ( parameter_association_list ) ]
function limit ( value, min, max : integer ) return integer is begin if value > max then return max; elsif value < min then return min; else return value; end if; end function limit;