Почему моя форма сигнала Verilog внезапно останавливается, когда значение меняется на 1 - PullRequest
0 голосов
/ 29 марта 2020

Я создаю конвейерный процессор с блоком опасности. Во время моделирования, когда Flu sh = 1, форма сигнала программы останавливается. Я считаю, что в моем коде есть какое-то бесконечное число l oop, и эта единица опасности не возвращает никакого значения. На изображении, которое я прикрепил, в столбце значений видно, что Flu sh становится равным 1. Но в модуле, из которого он вызывается, он по-прежнему равен нулю, поэтому вполне вероятно, что в этот момент он зацикливается.

Изображение формы волны

`timescale 1ns / 1ps

module Hazard_Unit(input BranchD, MtoRFSelE, MtoRFSelM, RFWEE, RFWEM, RFWEW, RST, input [4:0] RsD, RtD, RsE, RtE, RFAE, RFAM, RFAW,
                   output reg Stall, ForwardAD, ForwardBD, Flush, output reg [1:0] ForwardAE, ForwardBE);

reg LWStall, BRStall;

always @(*) begin
    if (RST) begin
        ForwardAD = 1'b0;
        ForwardBD = 1'b0;
        ForwardAE = 2'b00;
        ForwardBE = 2'b00;
        LWStall = 1'b0;
        BRStall = 1'b0;
        Stall = 1'b0;
        Flush = 1'b0;
    end

    else begin
        if ((RsE != 0) && RFWEM && (RsE == RFAM)) ForwardAE = 2'b10;
        else if ((RsE != 0) && RFWEW && (RsE == RFAW)) ForwardAE = 2'b01;
        else ForwardAE = 2'b00;

        if ((RtE != 0) && RFWEM && (RtE == RFAM)) ForwardBE = 2'b10;
        else if ((RtE != 0) && RFWEW && (RtE == RFAW)) ForwardBE = 2'b01;
        else ForwardBE = 2'b00;

        if (MtoRFSelE && ((RtE == RsD) || (RtE == RtD))) LWStall = 1'b1;
        else LWStall = 1'b0;

        if ((RsD != 0) && (RsD == RFAM) && RFWEM) ForwardAD = 1'b1;
        else ForwardAD = 1'b0;

        if ((RtD != 0) && (RtD == RFAM) && RFWEM) ForwardBD = 1'b1;
        else ForwardBD = 1'b0;

        if ((RsD == RFAE || RtD == RFAE) && BranchD && RFWEE || (RsD == RFAM || RtD == RFAM) && BranchD && MtoRFSelM) BRStall = 1'b1;
        else BRStall = 1'b0;

        if (LWStall || BRStall) begin
            Flush = 1'b1;
            Stall = 1'b0;
        end
        else begin
            Flush = 1'b0;
            Stall = 1'b1;
        end
    end
end
endmodule

1 Ответ

1 голос
/ 29 марта 2020

Действительно, вполне вероятно, что у вас есть комбинаторный l oop.

Я мог бы найти, где это, но я предпочитаю дать вам общий метод решения этих проблем. Этим я пользуюсь, если это происходит со мной (один раз в голубой луне: -)

  1. Убедитесь, что вы используете достаточно длинные часы. например, 100 или 500 единиц времени. Это в целом хорошая практика. Часы с 1 максимумом и 1 минимумом - это катастрофа в процессе становления. Ваше моделирование не будет работать медленнее из-за этого
  2. Поместите #5 между операторами.

    if ((RsE != 0) && RFWEM && (RsE == RFAM)) ForwardAE = 2'b10;
    else if ((RsE != 0) && RFWEW && (RsE == RFAW)) ForwardAE = 2'b01;
    else ForwardAE = 2'b00;
    #5;
    
    if ((RtE != 0) && RFWEM && (RtE == RFAM)) ForwardBE = 2'b10;
    else if ((RtE != 0) && RFWEW && (RtE == RFAW)) ForwardBE = 2'b01;
    else ForwardBE = 2'b00;
    #5;
    ...
    

Теперь ваш сигнал, вероятно, будет продолжать работать и покажу вам, где колебание. Не забудьте удалить номер 5 после исправления кода.

Следующая точка:
Ваш код, как правило, неверен. Вы производите много защелок в этом утверждении if. Каждой из ваших переменных ForwardAD, ForwardBD, ForwardAE ... должно быть присвоено значение в каждом операторе if. Или вы должны начать с задания значения по умолчанию сразу после else:

else begin
    ForwardAD = ..;
    ForwardBD = ..;
    ForwardAE = .;
    ...
    if ((RsE != 0) &....

Если вы не можете этого сделать, вероятно, весь раздел должен быть синхронизированным:

always @(posedge some_clock) begin
...