Android-приложение для поиска дешевых авиабилетов: play.google.com
Главная -> Verilog

0 1 [2] 3 4

str r8,[r2,r0,lsl #2]; adds г8,г10,г6 adc г9.г11,г7 mov r8,r8,lsr #14 orr r8,r8,r9,lsl #18 str r8.[r12,r0,lsl#2]; LDMIA sp!.{r8-r9} subs гВ,г8,г4 sbc г9,г9,г5 mov г8,г8,азг#14 orr r8,r8,r9.lsl#18 str г8,[г2,г1,1з1#2]: subs r10,r10,r6 sbc r11,r11,r7 mov r10,r10,asr#14 orr r10,r10,r11,lsl #18 str r10,[r12,r1.1sl#2]: LDMIA spl,{r4-r12.lr} bx Ir

store ar[b1]

store ai[b1]

store ar[b1mm]

store al[b1mm]

В процедуре использованы очень удобные команды 64-разряднопэ умножения со знаком SMULL и 64-разрядного умножения/сложения со знаком SMLAL Время выполнения

этих команд составляет всего 2-5 тактов в зависимости от размера множителя (при условии отсутствия тактов ожидания при обращении к памяти программ и данных). Как видно из текста программы основное время занимает извлечение данных из памяти, сдвиг результата (вычисления идут с фиксированной точкой, и при умножении она сдвигается влево) и сохранение его в памяти. Несмотря на большое количество режимов адресации памяти и удобную систему команд, не удалось сделать время вычисления бабочки менее 150 тактов.

БПФ вычислялось на процессоре АТ91М40400 фирмы Atmel с тактовой частотой 33 МГц. Функция БПФ работала во внутренней 32-разрядной памяти, коэффициенты хранились там же Исходные данные были во внешней 8-битной памяти с одним тактом ожидания Одно вычисление БПФ занимало время порядка 1/12 секунды. Сама функция БПФ написана на С, поэтому если написать все на ассемблере, результат можно несколько улучшить Исходный текст полной функции БПФ можно скачать по адресу www.platan.ru/shem/.

Павел Филимонов,

paulfillmonov@mail ru

(Продолжение, начало №1-2/2001)

Verilog - инструмент разработки цифровых электронных схем

Временной и событийный контроль

Завершая рассмотрение временного и событийного контроля, следует упомянуть о применении intra-assignment delay в "неблокирующем" присвоении, то есть в конструкциях вида

х<=#1 у;

а<= @(posedge с) Ь;

Поведение этих конструкций таково, что значение выражения вычисляется и блокирования последовательного исполнения операций не происходит, но новое значение будет присвоено только по истечении времени, указаннопэ во временной конструкции, или после совершения события, указанного в событийной конструкции. В терминах работы профаммы Verilog симулятора операция присвоения переносится на другой временной шаг В работе таких конструкций проявляется интересное отличие Verilog симуляторов от VHDL симуляторов. В VHDL каждая следующая по тексту программы операция присвоения одному и тому же сигналу отменяет предыдущую, даже если ее исполнение должно произойти в более ранний момент времени. В Verilog все подобные операции будут помещены в список для соответствующего временного шага, и сигнал, изменение которого вызывают эти операции, будет изменяться в соответствии со всеми операциями. Какой механизм поведения более правильный - вопрос спорный. Так как при синтезе временной контроль итерируется, да и непонятно, каким образом должна синтезироваться конструкция с присвоением из нескольких источников без специальной разрешающей функции, то это отличие может проявляться только на уровне моделирования с несинтезируемы-ми элементами. В то же время для работы с несинтезируе-мыми элементами Verilog предлагает операции, способные отменить (вернее "пересилить") все остальные операции присвоения к одному определенному сигналу Эти операции присвоения записываются с ключевыми словами force и release

Проиллюстрировать поведение можно следующим примером:

это пример на VHDL

LIBRARY leee; USE ieee.STDJogic 1164.all; USE ieee.std logic arith.all;

ENTITY AT91R IS PORT(NRD: OUT stdjogic :=0); END AT91R;

ARCHITECTURE EBI OF AT91R IS BEGIN

modeler : PROCESS BEGIN NRD <=Г AFTER 100 ns; WAIT FOR 30 ns; NRD <=Z AFTER 30ns: WAIT;

END PROCESS modeler; END EBI; */

В результате, через 60 не от начала симуляции выход переходит в Z-состояние и далее не изменяется. Таким образом, можно видеть, что последующая операция отменяет предыдущую.

Если переписать этот модуль на Verilog без учета изложенного выше, получим (обратите внимание на лаконичность языка Verilog):

module AT91R (nrd); output nrd; reg ndr;

initial

begin: modeler ndr<= #100 ГЫ; #30;

ndr<=#30rb2; end

endmodule

пример именованного бпока



При этом поведение будет другое Написав соответствующий testbench, можно увидеть:

Highest level modules: tst

Ox 60 z II

Это значит, что на 60 нс сработает ndr<= #301 bz, а затем на 100 НС расположенный выше по тексту ndr<= #100 1Ы То есть в Verilog предыдущая операция не отменяется. Для того чтобы поведение модуля было таким же, как и поведение VHDL кода, нужно записать его следующим образом:

module AT91R(nrd); output nrd; reg ndr;

initial begin

ndr<= #100 1-Ы;

#30:

#30 force ndr = 1 bz; end

endmodule

Использовать force с "неблокирующим" присвоением и/или intra-assignment delay нельзя Для того чтобы разрешить дальнейшее использование присвоений в друшх параллельных блоках, сигнал должен быть отпущен с помощью release (например, release ndr;).

Завершая обзор временного контроля, следует упомянуть еще об одной форме задержки - нулевой задержке. В Verilog коде встречаются такие конструкции: #0 а=Ь. Нулевая задержка означает, что операция будет выполнена в самом конце текущего временного шага. Еспи в одном временном шаге встречается несколько нулевых задержек, то между собой их порядок не определен.

Поведенческие конструкции

В поведенческих блоках initial или always могут применяться конструкции управления, сходные с операторами процедурных языков. Данные поведенческие конструкции подразделяются на несколько групп:

1) группа принятия решений: if-else-if , case, casez, casex;

2) группа повторений: repeat, while, for, forever;

3) группа параллельного исполнения: fork-join;

4) оператор wait;

Конструкция if записывается следующим образом:

if (<expression>)

<statement1> else

<statement2>

Для выбора из нескольких вариантов могут применяться вложенные if. if (<expression>)

<statement> else if (<expression>)

<statement> else if (<expression>)

<statement> else

<statement>

Здесь expression - любое выражение языка a statement -оператор или группа операторов ме>кду begin и end. Ветвь else может отсутствовать, но если имеются вложенные if (как в примере), то else относится к ближайшему if Для изменения порядка следует пользоваться begin и end. Если полу-

чаемое f выражении expression значение не равно О и не является неопределенной (х или z), то выполняется ветвь statementl, иначе - statement2. Следует помнить, что так же, как и в языке С, операция сравнения записывается == (два знака "="), в отличие от операции присваивания = (один знак). Но операции сравнения при неопределенных операндах возвращают неопределенное значение (х). Поэтому в поведенческом моделировании (не принимается средствами синтеза) могут использоваться операции === (три знака =) и !==. Эти операции позволяют произвести литеральное сравнение определенных битов в выражении. Еще раз обращаю внимание, что выражение expression не является выражением какого-либо специального типа (boolean), а является любым выражением, которое может быть приведено к типу integer. Здесь прослеживается аналогия с языком С, единственное отличие от которого состоит в том, что Verilog integer может принимать неопределенные значения (х или z). В этом случае выполняется ветвь else Исполнение такого кода:

module if test;

Initial

begin

if (2*5) $display("2*5 != 0 ==> tme"); if (2*0) $display("never print this");

else $display("2*0 != 0 ==> false"); if (Vbz) Sdisplay ("never print this");

else $display("undefined ==> false"); if (1bx) $display("never print this):

else $display("undefined ==> false");

endmodule

даст следующее:

Highest level modules: ifjest

2*5 != 0 ==> tme 2*0 != 0 ==> false undefined ==> false undefined ==> false

Следующий пример иллюстрирует применение операторов сравнения (сколько = в каком случае ставить)

module ifjest; reg a,b,c,d; initial jin

a=(2b10>3b001 );Ь=(2Ы 0==3b001 );c=(2b10>2b0x);d=(2b10=2bzO); $display("a=%b b=%b c=%b d=ob",a.b,c,d);

a=(2bia==3W),t=(2b10===2b10);cK2t)10!====2b0x);d==(2bx1===2bz1); $display("a=%b b=%b c=%b d=%b",a.b,c.d);

a=(2b0x==2b0x):b=(2bx1 I=2bx1);c=(2b0x=2b0x);d=(2bx11==2 bxi); $display("a=%b b=%b c=%b d=%b",a,b,c,d):

endmodule

Результат:

a=1 b=0 c=x d=x a=1 b=1 c=1 d=0 a=x b=x c=1 d=0

Для выбора из нескольких вариантов также применяется оператор case. Например, данная конструкция реализует дешифратор, подобный К155ИДЗ.

case (rega)

4dO: result = 10b0111111111; 4d1: result = 10Ы011111111;



4d2: result = 4d3: result = 4d4: result = 4d5: result = 4d6: result = 4d7: result = 4d8: result = 4d9: result =

default result

endcase

10b1101111111 10b1110111111 10Ъ1111011111 1ОЫ111101111 10Ъ1111110111 ЮЫШШОП 10Ы111111101 10Ы111111110; = Ьх;

Оператор сазе является "непроваливающимся", в отличие от оператора switch языка С, и гарантирует исполнение одной ветви В случае если ни одно из условий не совпадает, выполняется ветвь default. Допустимо другое применение -наоборот, в сазе константа, а в ветвях вычисляемые выражения, либо переменные находятся и там, и там (такого использования оператора выбора в про14едурных языках, как правило, нет). Оператор сазе часто используется в синтезируемом коде для синтеза FSM и мультиплексоров. При этом в несинтезируемых моделях (а в некоторых средствах синтеза и в синтезируемых) в выражениях case могут использоваться литералы с неопределенными значениями. Для поведенческого моделирования используются операторы casez и casex, которые особым образом обрабатывают неопределенные состояния Синтаксис casez и сазех подобен синтаксису case. При этом добавляется символ"?", используемый в двоичной записи литерала для того, чтобы замаскировать биты, которые не должны влиять на принятие решения.

Для демонстрации обработки неопределенных состояний операторами case, casez и casex рассмотрим следующий пример.

module case test; integer a,b,c,d; reg dk;

always #5 clk=~clk;

always begin : demo integer i;

for(i=0: i<16: N+1) begin

Swritefi = %d M);

casex (i) x, z, ? - the same function - ignore bit

4bOxxx : Sdispiay ("less than 8"):

4b10zz : Sdisplay ("not less than 8 and less than 12");

4b11?1 : Sdisplay ("not less than 12 and odd");

4bx?z? ; Sdisplay ("other case); default Sdisplay ("never pnnt this"); endcase

wait (clk==1b1); the same as @(posedge elk) end

end demo initial clk=0: endmodule

Данный пример не содержит Sfinish, а события будут происходить непрерывно из-за always блоков Поэтому он будет исполняться "вечно". Чтобы его остановить, нужно воспользоваться средствами среды.

Фрагмент результата работы:

0 less

1 less

2 less

3 less

4 less

5 less

6 less

7 less

than 8 than 8 than 8 than 8 than 8 than 8 than 8 than 8

8 not less than 8 and less than 12

9 not less than 8 and less than 12

10 not less than 8 and less than 12

11 not less than 8 and less than 12

12 other case

13 not less than 12 and odd

14 other case

15 not less than 12 and odd

0 less than 8

Таким образом, case проверяет литеральные совпадения, его можно сравнить с использованием if и === ("=" три раза). В операторах casex и casez биты со значениями х и z или только Z игнорируются. В литералах сравнения х и z (casex) или Z (casez) могут быть заменены "?".

Операторы повторения могут встречаться в синтезируемом коде. При этом упрощается и становится более понятной запись. В испытательных стендах и несинтезируемых моделях использование операторов повторения имеет такой же смысл, как и в процедурных языках программирования. Операторы for и repeat были продемонстрированы ранее. Так как Verilog не позволяет воспользоваться вечным циклом языка С (for(;;)), то введен оператор forever. Дпя выхода из циклов (блоки должны быть именованы) служит оператор disable. Продолжая сравнение с языком С: disable работает, как С операторы break и continue.

initial

begin :break for(i = 0;l <n;i =i+1) begin :continue @clk

if(a == 0) "continue" loop disable continue; ... <statements>... @clk

if(a == b) "break" from loop

disable break;

...<statements>... end end

Еще один цикл while имеет следующую форму:

while (condition) begin

statement

step assignment; end

Операторы циклов взаимозаменяемы, и выбор определяется личными предпочтениями программиста.

Цикл repeat может использоваться в intra-assignment delay дпя описания задержки в несколько циклов. Например, таким образом: а = repeat(3)@(posedge elk) b.

Операторы fork-join служат для параллельного исполнения ветвей кода в одном процедурном блоке. Это является несинтезируемой конструкцией и используется редко.

Оператор wait (см. пример casex) используется для приостановки конкурентно исполняемого блока до тех пор, пока не будет выполнено его условие (как правило, элементы выражения условия wait должны изменяться в другом блоке).

Про1дедуры и функции

Функции применяются, как правило, для моделирования комбинаторной логики которую средства синтеза генерируют по описанию функции. В функциях запрещен временной контроль. При вызове функции создается регистр, размерность и имя которого совпадают с размерностью и именем функции. Через этот регистр функция возвращает результат своей работы. Функция может возвращать также целое или вещественное число. Все параметры, передаваемые в функцию, имеют тип input



0 1 [2] 3 4



0.0145
Яндекс.Метрика