|
Главная -> 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.0272 |
|