Причина этого отрицательного числа состоит в том, что число интерпретируется в представлении дополнения до двух . Фактическое число, которое вы ожидаете после 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
Как видите, я также преобразовал сброс в асинхронный сброс с активным низким уровнем. Хотя это не является обязательным, это довольно распространено. Сигнал сброса предназначен для поддержания всех флопов в состоянии сброса, даже когда питание устройства медленно повышается. Если активен высокий уровень сигнала сброса, сам сигнал может появляться медленно.