Как реализовать код переполнения? Я не знаю что не так - PullRequest
1 голос
/ 30 мая 2019

Как мне реализовать код переполнения?

Я не знаю, что не так.Результатом является отрицательное число в середине. Ниже приведен фрагмент кода

module fibonacci(input clk, input rst, output [7:0]out, output reg overflow);

reg [7:0]a,b;

always@(posedge rst)
begin
    a =8'b0;
    b =8'b1;
end
always@(posedge clk)
begin
    if ( a < 8'b11111111 ) begin
        b = a + b ;
        a = b - a ;

    end

    else begin

    overflow = 1'b1;   //is that wrong??

    end
end

assign out = a ;

endmodule

и код тестового стенда здесь

initial begin

rst = 1;
clk =0;

#0.5
rst = 0;
end

always begin
#1 
clk = !clk;
end

fibonacci fib(clk,rst,out,overflow);
endmodule

enter image description here

Дайте мне знать, что не так

1 Ответ

1 голос
/ 30 мая 2019

Причина этого отрицательного числа состоит в том, что число интерпретируется в представлении дополнения до двух . Фактическое число, которое вы ожидаете после 89, равно 144, что составляет 10010000 в двоичном виде. Однако в представлении дополнения двух наиболее значимым битом является знак числа. «1» означает, что это должно быть отрицательное число, которое можно рассчитать следующим образом:

~10010000 + 1 = 01101111 + 1 = 01110000 = (-)112

Между прочим, есть несколько других уловок кода, который вы опубликовали. Позвольте мне сначала ответить на этот вопрос:

переполнение = 1'b1; // это неправильно ??

Не эта конкретная строка, но способ обработки overflow не совсем корректен. В вашем коде overflow может стать только x или 1. Это никогда не будет 0. Вы должны назначить overflow на 0 в первой части вашего условного блока и в части сброса.

Во-вторых, вы должны использовать неблокирующие назначения в Verilog для создания последовательной логики. В вашем коде вы используете блокирующие назначения, что означает, что вы сначала обновите b, а затем обновите a с уже обновленным значением b. Если вам нужно использовать блокирующие назначения, вы должны создать комбинационный блок .

Кроме того, вы должны объединить чувствительную к часам часть и чувствительную к сбросу часть, чтобы все a, b и overflow были изменены одним и тем же блоком always.

Все эти предложения примерно переведены на:

always @(*)
begin
    b_next = a + b;
    a_next = b_next - a;
end 

always @(posedge clk or negedge rst)
begin
    if (~rst) begin
        a <= 8'b0;
        b <= 8'b1;
        overflow <= 1'b0;
    end
    else if (a < 8'b11111111) begin
        b <= b_next;
        a <= a_next;
        overflow <= 1'b0    
    end
    else begin
        overflow <= 1'b1;
    end
end

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

...