DocsTech
/
VERILOG HDL
/

~ cd 12. generate блоки verilog hdl

12.4 Конструкции generate

Конструкции generate используются для условного или многократного объявления экземпляров блоков генерации в модуле. Блок generate — это набор из одного или нескольких элементов модуля. Блок generate не может содержать объявления портов, parameter, блоки specify или specparam. Все остальные элементы модуля, включая другие конструкции generate, разрешены в блоке generate. Конструкции generate предоставляют возможность значениям параметров влиять на структуру модели. Они также позволяют более лаконично описывать модули с повторяющейся структурой и делают возможным рекурсивное объявление экземпляра модуля.

Существует 2 вида конструкций generate: циклы и условия. Конструкции генерации циклов позволяют объявлять экземпляры в один блок генерации в модель несколько раз. Условные конструкции generate, к которым относятся конструкции if-generate и case-generate, определяет не более одного блока generate из набора альтернативных блоков generate. Термин схема generate относится к методу определения того, какие или сколько блоков generate объявляются. Он включает в себя условные выражения, альтернативы case и управляющие операторы цикла, которые появляются в конструкции generate.

Генерируемые схемы оцениваются во время разработки модели. Разработка происходит после разбора HDL и перед моделированием. Она включает в себя расширение объявления экземпляра модулей, вычисление значений параметров, разрешение иерархических имен (см. 12.5), установление связности сетей и в целом подготовку модели к моделированию. Хотя схемы генерации используют синтаксис, похожий на поведенческие(always, initial, …) объявления, важно понимать, что они не выполняются во время моделирования. Они оцениваются во время разработки, и результат определяется до начала моделирования. Поэтому все выражения в схемах генерации должны быть константными выражениями, детерминированными(известными, константными) во время разработки. Более подробно о разработке см. в разделе 12.8.

В результате разработки конструкции generate создается ноль или более экземпляров блока generate. Экземпляр блока generate в чем-то схож с экземпляром модуля. Он создает новый уровень иерархии. Он вызывает к существованию объекты, поведенческие конструкции и экземпляры модулей в блоке. Эти конструкции действуют так же, как если бы они находились в модуле, созданном с помощью экземпляра модуля, за исключением того, что на объявления объектов из объемлющей области видимости можно ссылаться напрямую (см. 12.7). На имена в экземпляре именованных блоках генерации можно ссылаться иерархически, как описано в 12.5.

Ключевые слова generate и endgenerate могут быть использованы в модуле для определения области генерации. Область генерации — это текстовый участок в описании модуля, где могут появляться конструкции generate. Использование областей генерации(generate) является необязательным. В модуле нет семантических различий, если используется область генерации. Синтаксический анализатор может решить распознать область генерации, чтобы выдавать различные сообщения об ошибках при неправильном использовании ключевых слов конструкции generate. Регионы generate не вложены, и они могут встречаться только непосредственно в модуле. Если используется ключевое слово generate, ему должно соответствовать ключевое слово endgenerate.

Синтаксис для конструкций генерации приведен в Синтаксис 12-5.

...
Копировать
module_or_generate_item ::=
    { attribute_instance } module_or_generate_item_declaration
    | { attribute_instance } local_parameter_declaration ;
    | { attribute_instance } parameter_override
    | { attribute_instance } continuous_assign
    | { attribute_instance } gate_instantiation
    | { attribute_instance } udp_instantiation
    | { attribute_instance } module_instantiation
    | { attribute_instance } initial_construct
    | { attribute_instance } always_construct
    | { attribute_instance } loop_generate_construct
    | { attribute_instance } conditional_generate_construct
generate_region ::=
    generate { module_or_generate_item } endgenerate
genvar_declaration ::=
    genvar list_of_genvar_identifiers ;
list_of_genvar_identifiers ::=
    genvar_identifier { , genvar_identifier }
loop_generate_construct ::=
    for ( genvar_initialization ; genvar_expression ; genvar_iteration )
    generate_block
genvar_initialization ::=
    genvar_identifier = constant_expression
genvar_expression ::=
    genvar_primary
    | unary_operator { attribute_instance } genvar_primary
    | genvar_expression binary_operator { attribute_instance } genvar_expression
    | genvar_expression ? { attribute_instance } genvar_expression : genvar_expression
genvar_iteration ::=
    genvar_identifier = genvar_expression
genvar_primary ::=
    constant_primary
    | genvar_identifier
conditional_generate_construct ::=
    if_generate_construct
    | case_generate_construct
if_generate_construct ::=
    if ( constant_expression ) generate_block_or_null
    [ else generate_block_or_null ]
case_generate_construct ::=
    case ( constant_expression )
    case_generate_item { case_generate_item } endcase
case_generate_item ::=
    constant_expression { , constant_expression } : generate_block_or_null
    | default [ : ] generate_block_or_null
generate_block ::=
    module_or_generate_item
    | begin [ : generate_block_identifier ] { module_or_generate_item } end
generate_block_or_null ::=
    generate_block | ;
Синтаксис 12-5-Синтаксис для конструкций generate

12.4.1 Конструкции циклов generate

Конструкция циклов генерации позволяет многократно объявлять экземпляры в блоке generate, используя синтаксис, схожий с оператором цикла for. Переменная индекса цикла должна быть объявлена в объявлении genvar до ее использования в схеме генерации цикла.

Genvar используется как целое число во время разработки для оценки цикла generate и создания экземпляров в блоке generate, но он не существует во время моделирования. На genvar нельзя ссылаться нигде, кроме как в схеме генерации цикла.

Назначения инициализации и итерации в схеме генерации циклов должны присваиваться одному и тому же параметру genvar. Назначение инициализации не должно ссылаться на переменную индекса цикла в правой части.

В блоке generate конструкции цикла генерации имеется неявное объявление localparam. Это целочисленный параметр, который имеет то же имя и тип, что и индексная переменная цикла, а его значением в каждом экземпляре блока генерации является значение индексной переменной на момент разработки экземпляра. Этот параметр может быть использован в любом месте блока generate, где может быть использован обычный параметр с целочисленным значением. На него можно ссылаться с иерархическим именем.

Поскольку эта неявная localparam имеет то же имя, что и genvar, любая ссылка на это имя внутри блока генерации цикла будет ссылкой на localparam, а не на genvar. Как следствие, невозможно иметь две вложенные конструкции loop generate, использующие один и тот же genvar.

generate блоки в конструкциях циклов генерации могут быть именованными или неименованными, и они могут состоять только из одного элемента, который не обязательно должен быть окружен ключевыми словами begin/end. Даже если ключевые слова begin/end отсутствуют, это все равно блок generate, который, как и все блоки generate, при объявлении включает отдельную область видимости и новый уровень иерархии.

Если блок generate имеет имя, то это объявление массива экземпляров блока generate. Значения индексов в этом массиве — это значения, принимаемые genvar во время разработки. Это может быть разреженный массив, поскольку значения genvar не обязательно должны образовывать непрерывный диапазон целых чисел. Массив считается объявленным, даже если схема генерации цикла не привела ни к одному экземпляру блока generate. Если блок generate не имеет имени, то на объявления в нем нельзя ссылаться, используя иерархические имена, кроме как из иерархии, созданной самим блоком generate.

Будет ошибкой, если имя массива экземпляров блоков генерации конфликтует с любым другим объявлением, включая любой другой массив экземпляров блоков генерации. Будет ошибкой, если схема генерации цикла не завершается. Будет ошибкой, если значение genvar повторяется во время оценки схемы генерации цикла. Будет ошибкой, если любой бит genvar будет установлен в x или z во время оценки схемы генерации цикла.

Например:

Пример 1-Примеры законных и незаконных порождающих циклов
...
Копировать
module mod_a;
    genvar i;
    // Ключевые слова "generate", "endgenerate" необязательны
    for (i=0; i<5; i=i+1) begin:a
        for (i=0; i<5; i=i+1) begin:b
            ... // ошибка -- использование "i" d в качестве индекса цикла for
            ... // два вложенных порождающих цикла
        end
    end
endmodule
------
module mod_b;
    genvar i;
    reg a;
    for (i=1; i<0; i=i+1) begin: a
    ... // ошибка -- "a" конфликтует с именем reg "a"
    end
endmodule
------
module mod_c;
    genvar i;
    for (i=1; i<5; i=i+1) begin: a
        ...
    end
    for (i=10; i<15; i=i+1) begin: a
        ... // ошибка -- "a" конфилктует с предыдущем
        ... // циклом даже если индексы уникальны
    end
endmodule
Пример 2 — Параметризованный gray-code–to–binary-code с использованием цикла для генерации непрерывных назначений
...
Копировать
module gray2bin1 (bin, gray);
    parameter SIZE = 8; // этот модуль параметризированный
    output [SIZE-1:0] bin;
    input [SIZE-1:0] gray;
    genvar i;
    generate
        for (i=0; i<SIZE; i=i+1) begin:bit
            assign bin[i] = ^gray[SIZE-1:i];
                        // i ссылается на неявно объявленный localparam чьё
                        // значение в каждом экземпляре блока generate является
                        // значение genvar на момент его разработки.
        end
    endgenerate
endmodule

Модули в примерах 3 и 4 представляют собой параметризованные модули пульсирующих сумматоров, использующие цикл for генерации примитивов вентилей Verilog. В примере 3 используется объявление двумерной сети вне цикла генерации для создания соединений между примитивами вентилей, а в примере 4 объявление сети находится внутри цикла генерации для создания проводов, необходимых для соединения примитивов вентилей для каждой итерации цикла.

Пример 3 — Генерируемый пульсационный сумматор с объявлением двумерной сети вне цикла генерации
...
Копировать
module addergen1 (co, sum, a, b, ci);
    parameter SIZE = 4;
    output [SIZE-1:0] sum;
    output co;
    input [SIZE-1:0] a, b;
    input ci;
    wire [SIZE :0] c;
    wire [SIZE-1:0] t [1:3];
    genvar i;
    assign c[0] = ci;
    // Иерархические имена экземпляров вентилей:
    // xor вентили: bit[0].g1 bit[1].g1 bit[2].g1 bit[3].g1
    // bit[0].g2 bit[1].g2 bit[2].g2 bit[3].g2
    // and вентили: bit[0].g3 bit[1].g3 bit[2].g3 bit[3].g3
    // bit[0].g4 bit[1].g4 bit[2].g4 bit[3].g4
    // or вентили: bit[0].g5 bit[1].g5 bit[2].g5 bit[3].g5
    // Сгенерированные экземпляры связаны с
    // многомерные сети t[1][3:0] t[2][3:0] t[3][3:0]
    // (Всего 12 сетей)
    for(i=0; i<SIZE; i=i+1) begin:bit
        xor g1 ( t[1][i], a[i], b[i]);
        xor g2 ( sum[i], t[1][i], c[i]);
        and g3 ( t[2][i], a[i], b[i]);
        and g4 ( t[3][i], t[1][i], c[i]);
        or g5 ( c[i+1], t[2][i], t[3][i]);
    end
    assign co = c[SIZE];
endmodule
Пример 4 — Сгенерированный пульсирующий сумматор с объявлением сети внутри цикла генерации
...
Копировать
module addergen1 (co, sum, a, b, ci);
    parameter SIZE = 4;
    output [SIZE-1:0] sum;
    output co;
    input [SIZE-1:0] a, b;
    input ci;
    wire [SIZE :0] c;
    genvar i;
    assign c[0] = ci;
    // Иерархические имена экземпляров вентилей:
    // xor вентили: bit[0].g1 bit[1].g1 bit[2].g1 bit[3].g1
    // bit[0].g2 bit[1].g2 bit[2].g2 bit[3].g2
    // and вентили: bit[0].g3 bit[1].g3 bit[2].g3 bit[3].g3
    // bit[0].g4 bit[1].g4 bit[2].g4 bit[3].g4
    // or вентили: bit[0].g5 bit[1].g5 bit[2].g5 bit[3].g5
    // Экземпляры вентилей соединенные сетями с именами:
    // bit[0].t1 bit[1].t1 bit[2].t1 bit[3].t1
    // bit[0].t2 bit[1].t2 bit[2].t2 bit[3].t2
    // bit[0].t3 bit[1].t3 bit[2].t3 bit[3].t3
    for(i=0; i<SIZE; i=i+1) begin:bit
        wire t1, t2, t3;
        xor g1 ( t1, a[i], b[i]);
        xor g2 ( sum[i], t1, c[i]);
        and g3 ( t2, a[i], b[i]);
        and g4 ( t3, t1, c[i]);
        or g5 ( c[i+1], t2, t3);
    end
    assign co = c[SIZE];
endmodule

Иерархические имена экземпляров блока generate в многоуровневом цикле генерации показаны в примере 5. Для каждого экземпляра блока, созданного циклом генерации, идентификатор блока generate для цикла индексируется путем добавления «[значение genvar]» к концу идентификатора блока generate. Эти имена можно использовать в иерархических именах путей (см. 12.5).

Пример 5 — Многоуровневый генерирующий цикл
...
Копировать
parameter SIZE = 2;
genvar i, j, k, m;
generate
    for (i=0; i<SIZE; i=i+1) begin:B1 // область B1[i]
        M1 N1(); // экземпляры B1[i].N1
        for (j=0; j<SIZE; j=j+1) begin:B2 // область B1[i].B2[j]
        M2 N2(); // instantiates B1[i].B2[j].N2
            for (k=0; k<SIZE; k=k+1) begin:B3 // область B1[i].B2[j].B3[k]
                M3 N3(); // экземпляры B1[i].B2[j].B3[k].N3
            end
        end
        if (i>0) begin:B4 // область B1[i].B4
            for (m=0; m<SIZE; m=m+1) begin:B5 // область B1[i].B4.B5[m]
                M4 N4(); // экземпляры B1[i].B4.B5[m].N4
            end
        end
    end
endgenerate
    // Некоторые примеры иерархических имен для экземпляров модуля:
    // B1[0].N1 B1[1].N1
    // B1[0].B2[0].N2 B1[0].B2[1].N2
    // B1[0].B2[0].B3[0].N3 B1[0].B2[0].B3[1].N3
    // B1[0].B2[1].B3[0].N3
    // B1[1].B4.B5[0].N4 B1[1].B4.B5[1].N4

12.4.2 Условные конструкции generate

Условные конструкции generate if-generate и case-generate выбирают не более одного блока generate из набора альтернативных блоков generate на основе константных выражений, оцениваемых в процессе разработки. Выбранный блок generate, если таковой имеется, объявляется экземпляром в модуле.

Блоки генерации в условных конструкциях генерации могут быть именованными или неименованными, и они могут состоять только из одного элемента, который не обязательно должен быть окружен ключевыми словами begin/end. Даже если ключевые слова begin/end отсутствуют, это все равно блок generate, который, как и все блоки generate, включает в себя отдельную область видимости и новый уровень иерархии, когда он объявляется.

Поскольку объявляется экземпляр только один из альтернативных блоков generate, допускается наличие более одного блока с одинаковым именем в одной условной конструкции generate. Не допускается, чтобы любой из именованных блоков generate имел то же имя, что и блоки generate в любой другой условной или циклической конструкции generate в той же области видимости, даже если блоки с тем же именем не выбраны для объявления экзнмпляров. Не допускается, чтобы любой из именованных блоков generate имел то же имя, что и любое другое объявление в той же области видимости, даже если этот блок не выбран для объявления экзнмпляров.

Если выбранный для определения блок генерации имеет имя, то это имя объявляет экземпляр блока генерации и является именем для создаваемой им области видимости. Применяются обычные правила иерархического именования. Если блок генерации, выбранный для объявления экземпляров, не имеет имени, он все равно создает область видимости. Однако, в объявлении в ней нельзя ссылаться, используя иерархические имена, кроме как из иерархии, созданной самим блоком генерации.

Если блок генерации в условной конструкции генерации состоит только из одного элемента, который сам является условной конструкцией генерации, и если этот элемент не окружен ключевыми словами begin/end, то этот блок генерации не рассматривается как отдельная область видимости. Конструкция generate внутри этого блока считается непосредственно вложенной. Блоки генерации непосредственно вложенной конструкции рассматриваются так, как если бы они принадлежали внешней конструкции. Поэтому они могут иметь то же имя, что и блоки generate внешней конструкции, и не могут иметь то же имя, что и любое объявление в области видимости, охватывающей внешнюю конструкцию (включая другие блоки generate в других конструкциях generate в этой области видимости). Это позволяет выражать сложные условные схемы генерации без создания ненужных уровней иерархии блоков генерации.

Чаще всего это используется для создания схемы генерации if-else-if с любым количеством пунктов else-if, все из которых могут иметь блоки генерации с одинаковым именем, поскольку для объявления экземпляров будет выбран только один. Допустимо объединять конструкции if-generate и case-generate в одной сложной схеме генерации. Прямое вложение применяется только к условным конструкциям generate, вложенным в условные конструкции generate. Она никак не относится к конструкциям генерации циклов.

Пример 1
...
Копировать
module test;
    parameter p = 0, q = 0;
    wire a, b, c;
    //---------------------------------------------------------
    // Код для генерации экземпляра u1.g1 или отсутствия экземпляра.
    // Экземпляр u1.g1 одного из следующих вентилей:
    // (and, or, xor, xnor) генерируются если
    // {p,q} == {1,0}, {1,2}, {2,0}, {2,1}, {2,2}, {2, default}
    //---------------------------------------------------------
    if (p == 1)
        if (q == 0)
        begin : u1 // Если p==1 и q==0, то объявляет экземпляр
            and g1(a, b, c); // AND с иерархическим именем test.u1.g1
        end
    else if (q == 2)
        begin : u1 // Если p==1 и q==2, то объявляет экземпляр
            or g1(a, b, c); // OR с иерархическим именем test.u1.g1
        end
        // "else" добавлено в конец объявления "if (q == 2)".
        else ; // Если p==1 и q!=0 или 2, то не объявляет экземпляр
    else if (p == 2)
        case (q)
        0, 1, 2:
            begin : u1 // Если p==2 т q==0,1, или 2, то объявляет экземпляр
                xor g1(a, b, c);// XOR с иерархическим именем test.u1.g1
            end
        default:
            begin : u1 // Если p==2 и q!=0,1, или 2, то объявляет экземпляр
                xnor g1(a, b, c);// XNOR с иерархическим именем test.u1.g1
            end
    endcase
endmodule

Эта конструкция generate выберет не более одного блока generate с именем u1. Иерархическое имя инстанцирования вентиля в этом блоке будет test.u1.g1. При вложении конструкций if-generate, else всегда принадлежит ближайшей конструкции if.

Как и в приведенном выше примере, блок generate else с нулем может быть вставлен для того, чтобы последующий else принадлежал внешней конструкции if. Ключевые слова begin/end также могут быть использованы для разграничения. Однако это нарушит критерии прямой вложенности, и будет создан дополнительный уровень иерархии блоков generate.

Перевод Официального Стандарта Verilog HDL

Условные конструкции generate позволяют модулю содержать экземпляра самого себя. Тоже самое можно сказать о конструкциях loop generate, но это легче сделать помощью условных generate.

При правильном использовании параметров, результирующая рекурсия может быть завершена, что приводит к созданию правильной иерархии модели. Из-за правил определения модулей верхнего уровня модуль, содержащий экземпляр самого себя, не будет модулем верхнего уровня.

Пример 2 — реализация модуля параметризованного умножения
...
Копировать
module multiplier(a,b,product);
    parameter a_width = 8, b_width = 8;
    localparam product_width = a_width+b_width;
                // не может быть изменен непосредственно с помощью объявления defparam
                // или объявления экземпляра модуля #
    input [a_width-1:0] a;
    input [b_width-1:0] b;
    output [product_width-1:0] product;

    generate
        if((a_width < 8) || (b_width < 8)) begin: mult
        CLA_multiplier #(a_width,b_width) u1(a, b, product);
        // объявление экземпляра множителя CLA
        end
        else begin: mult
        WALLACE_multiplier #(a_width,b_width) u1(a, b, product);
        // объявление экземпляра множителя дерева Уоллеса
        end
    endgenerate
    // Иерархическое имя экземпляра mult.u1

endmodule
Пример 3 — Генерация с помощью case для обработки шириной менее 3
...
Копировать
generate
    case (WIDTH)
        1: begin: adder     // реализация 1-битного сумматора
            adder_1bit x1(co, sum, a, b, ci);
        end
        2: begin: adder     // реализация 2-битного сумматора
            adder_2bit x1(co, sum, a, b, ci);
        end
        default:
        begin: adder        // другие - неопреленные ширины сумматоры с переносом
            adder_cla #(WIDTH) x1(co, sum, a, b, ci);
        end
    endcase
    // Иерархическое имя экземпляра - adder.x1
endgenerate
Пример 4 — модуль памяти dimm
...
Копировать
module dimm(addr, ba, rasx, casx, csx, wex, cke, clk, dqm, data, dev_id);

    parameter [31:0] MEM_WIDTH = 16, MEM_SIZE = 8; // в мегабайтах

    input [10:0] addr;
    input ba, rasx, casx, csx, wex, cke, clk;
    input [ 7:0] dqm;
    inout [63:0] data;
    input [ 4:0] dev_id;

    genvar i;

    case ({MEM_SIZE, MEM_WIDTH})
    {32'd8, 32'd16}: // 8Meg x 16 бит в ширину
    begin: memory
        for (i=0; i<4; i=i+1) begin:word
            sms_08b216t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
                        .addr(addr), .rasb(rasx), .casb(casx),
                        .web(wex), .udqm(dqm[2*i+1]), .ldqm(dqm[2*i]),
                        .dqi(data[15+16*i:16*i]), .dev_id(dev_id));
            // Иерархические имена экземпляров - memory.word[3].p,
            // memory.word[2].p, memory.word[1].p, memory.word[0].p,
            // и задача memory.read_mem
        end
        task read_mem;
            input [31:0] address;
            output [63:0] data;
            begin                   // вызов read_mem в sms модуле
                word[3].p.read_mem(address, data[63:48]);
                word[2].p.read_mem(address, data[47:32]);
                word[1].p.read_mem(address, data[31:16]);
                word[0].p.read_mem(address, data[15: 0]);
            end
        endtask
    end
    {32'd16, 32'd8}: // 16Meg x 8 бит в ширину
    begin: memory
        for (i=0; i<8; i=i+1) begin:byte
            sms_16b208t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
                        .addr(addr), .rasb(rasx), .casb(casx),
                        .web(wex), .dqm(dqm[i]),
                        .dqi(data[7+8*i:8*i]), .dev_id(dev_id));
            // Иерархические имена экземпляров - memory.byte[7].p,
            // memory.byte[6].p, ... , memory.byte[1].p, memory.byte[0].p,
            // и задача memory.read_mem
        end
        task read_mem;
            input [31:0] address;
            output [63:0] data;
            begin // call read_mem in sms module
                byte[7].p.read_mem(address, data[63:56]);
                byte[6].p.read_mem(address, data[55:48]);
                byte[5].p.read_mem(address, data[47:40]);
                byte[4].p.read_mem(address, data[39:32]);
                byte[3].p.read_mem(address, data[31:24]);
                byte[2].p.read_mem(address, data[23:16]);
                byte[1].p.read_mem(address, data[15: 8]);
                byte[0].p.read_mem(address, data[ 7: 0]);
            end
        endtask
    end
    // Другие случаи памяти ...
    endcase
endmodule

12.4.3 Внешние имена для безымянных генерируемых блоков

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

Каждой generate конструкции в данной области видимости присваивается номер. Номер будет равен 1 для конструкции, которая текстово появляется первой в этой области видимости, и будет увеличиваться на 1 для каждой последующей конструкции generate в этой области видимости. Всем безымянным блокам генерации присваивается имя «genblk», где — номер, присвоенный конструкции generate. Если такое имя будет конфликтовать с явно объявленным именем, то перед номером добавляются ведущие нули до тех пор, пока имя не перестанет конфликтовать.

Каждой генераторной конструкции присваивается свой номер, как описано в предыдущем параграфе, даже если она не содержит никаких безымянных generate блоков.

Перевод Официального Стандарта Verilog HDL
Например:
...
Копировать
module top;

    parameter genblk2 = 0;
    genvar i;

    // Следующий блок генерации неявно назван genblk1

    if (genblk2) reg a; // top.genblk1.a
    else reg b; // top.genblk1.b

    // Следующий блок генерации имеет неявное имя genblk02
    // поскольку genblk2 уже является объявленным идентификатором

    if (genblk2) reg a; // top.genblk02.a
    else reg b; // top.genblk02.b

    // Следующий блок generate был бы назван genblk3
    // но имеет явное название g1

    for (i = 0; i < 1; i = i + 1) begin : g1 // Имя блока
        // Следующий блок генерации неявно назван genblk1
        // как первая вложенная область видимости внутри g1
        if (1) reg a; // top.g1[0].genblk1.a
    end

    // Следующий блок генерации неявно назван genblk4, поскольку
    // он принадлежит четвертой конструкции generate в области видимости "top".
    // Предыдущий блок генерации был бы
    // назван genblk3, если он не был явно назван g1

    for (i = 0; i < 1; i = i + 1)
        // Следующий блок генерации неявно назван genblk1
        // как первый вложенный блок generate в genblk4
        if (1) reg a; // top.genblk4[0].genblk1.a

    // Следующий блок генерации имеет неявное имя genblk5
    if (1) reg a; // top.genblk5.a

endmodule
Главная
Курсы
Вебинары
3. Лексические правила(Синтаксис) Verilog HDL
4. Типы данных Verilog HDL
5. Выражения и Операторы Verilog HDL
6. Назначения (Assignments) в Verilog HDL
7. Моделирование на уровне вентилей и переключателей в Verilog HDL
8. Примитивы, объявляемые пользователем (UDP) Verilog HDL
9. Процедурные назначения. Поведенческое моделирование в Verilog HDL.
9. If, case for, while и repeat Verilog HDL
9. Initial, always, задержки, блоки Verilog HDL
10. Задачи(task) и функции (function) в Verilog HDL
11. Семантика планирования. Стек (stack) в Verilog HDL
12. Модули(module). Переопределение параметров(defparam).
12. Порты. Иерархические имена в Verilog HDL
12. Generate блоки Verilog HDL
12. Иерархические имена Verilog HDL
13. Конфигурирование содержимого конструкции
13. Использование библиотек. Конфигурирование содержимого конструкции в Verilog HDL
14. Specify блоки в Verilog HDL
15. Setup, hold, setuphold и recovery в Verilog HDL
15. Skew, period, width и nochange Verilog HDL
15. Проверка синхронизации сигналов в Verilog HDL
16. Бэканнотирование с использованием стандартного формата задержки (SDF) в Verilog HDL
17. Системные задачи и функции
17.2 Файлы. Запись и чтение файлов Verilog
17. Задачи временной шкалы, управления, PLA и стохастического анализа Verilog
$time, $stime и $realtime Verilog
17.8. Функции преобразования Verilog
17.9. Функции распределения вероятностей Verilog
17.10. Ввод командной строки. 17.11. Математические функции
18. Дамп файлы изменения значений (VCD)
18. Формат файла VCD расширенные и четырьмя состояниями
19. Директивы компилятора Verilog HDL
20. Обзор интерфейса языка программирования (PLI) Verilog
28. Зашифрованные оболочки
Закрыть