2-битный счетчик с использованием JK-триггера в Verilog

Я пишу код Verilog для 2-битного счетчика, используя JK Flip Flop, который считает 0-3 и возвращается к 0. Я использую Xilinx EDA. Однако я продолжаю получать одну ошибку, и я не знаю, что это значит? Номера строк здесь не отображаются, но ошибка находится в "always @(posedge clk)".

ОШИБКА: HDLCompiler: 1401 - «C: \ Users \ Eduardo \ Documents \ SFSU \ Fall 2014 \ Engr 378 \ Lab 3 \ TwoBitCounter \ twobitcounter.v» Строка 30: Сигнал q в модуле jkff связан со следующими несколькими драйверами:

`timescale 1ns / 1ps
module twobitcounter( q_out, qbar_out, j,k, clk, reset);
    input [1:0] j; input [1:0] k; input clk; input reset;
    output [1:0] q_out;
    output [1:0] qbar_out;
    wire [1:0] q_out;
    wire [1:0] qbar_out;
    wire clk;

    assign qbar_out[0] = ~q_out[0];
    assign j[0] = 1;
    assign k[0] = 1;
    assign j[1] = q_out[0];
    assign k[1] = q_out[0]; 

    jkff M1(q_out[0], qbar_out[0], j[0], k[0], clk, reset);
    jkff M2(q_out[1], qbar_out[1], j[1], k[1], qbar_out[0]);

endmodule

module jkff(output q_out, output qbar_out,
  input j, input k, input clk, input reset);

    reg q;
    assign q_out = q;
    assign qbar_out = ~q;

    initial begin 
        q = 1'b0;
        end
    always @(posedge clk)
        begin
        case({j,k})
        {1'b0, 1'b0}: begin
            q = q;
            end
        {1'b0, 1'b1}: begin
            q = 1'b0;
            end
        {1'b1, 1'b0}: begin
            q = 1'b1;
            end
        {1'b1, 1'b1}: begin
            q = ~q;
            end
        endcase
        end

    always @(posedge reset)
        begin
        q = 1'b0;
        end
endmodule

person Eduardo Romero    schedule 02.10.2014    source источник


Ответы (2)


Проблема в том, что q задается двумя always блоками, что недопустимо в синтезе. Объедините два всегда блока. Кроме того, q является ошибочным, поэтому его следует назначать с использованием неблокирующего назначения (<=), а не блокирующего назначения (=).

always @(posedge clk or posedge reset)
begin
  if (reset == 1'b1) begin
    q <= 1'b0;
  end
  else begin
    case({j,k})
    {1'b0, 1'b0}: begin
        q <= q;
        end
    {1'b0, 1'b1}: begin
        q <= 1'b0;
        end
    {1'b1, 1'b0}: begin
        q <= 1'b1;
        end
    {1'b1, 1'b1}: begin
        q <= ~q;
        end
    endcase
  end
end

Практически никогда не следует использовать initial блоков в синтезируемом коде. Большинство ПЛИС допускают его инициализацию. Однако конструкции ASIC не поддерживают его. В обоих случаях, если есть асинхронный сброс / установка, то его начальный блок использовать не следует.

person Greg    schedule 02.10.2014
comment
Я попробовал ваш совет, но он дал мне ту же ошибку для модуля twobitcounter. Я получаю сообщение об ошибке при назначении qbar_out [0] = ~ q_out [0]; В нем указано, что qbar_out [0] подключен к следующим нескольким драйверам - person Eduardo Romero; 05.10.2014
comment
q_out[0] и qbar_out[0] являются выходами M1. Это делает его двойным драйвером, что является незаконным. Закомментируйте assign qbar_out[0] = ~q_out[0];. У вас также отсутствует соединение с портом на M2 - person Greg; 06.10.2014

Ошибка сообщает вам, что вы назначаете q в разных блоках. Это создает ошибку. Вы назначаете q как в блоке initial, так и в блоке always.

Вы никогда не должны использовать initial блоков в синтезируемом коде.

person Russell    schedule 02.10.2014
comment
** Практически никогда не используйте начальные блоки (большинство инструментов синтеза для FPGA в определенных случаях выделяют начальные блоки, например, при инициализации элементов памяти). Кроме того, q также назначается в блоке @ (сброс позиции). - person Unn; 02.10.2014