如何实现溢出代码?
我不知道怎么了。结果中间是负数。下面是代码段
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
让我知道怎么了
答案 0 :(得分:1)
此负数的原因是该数字在two's complement representation中进行了解释。在89
之后,您期望的实际数字是144
,它是二进制的10010000
。但是,在二进制补码表示中,最重要的位是数字的符号。 “ 1”表示该数字应为负数,可以通过以下方式计算:
~10010000 + 1 = 01101111 + 1 = 01110000 = (-)112
顺便提一下,您发布的代码还有其他一些问题。首先让我回答这个问题:
溢出= 1'b1; //是错了吗?
不是这一行,但是处理overflow
的方式并不完全正确。在您的代码中,overflow
只能成为x
或1
。永远不会是0
。您应该在条件块的第一部分和重置部分中将overflow
分配给0
。
第二件事是您应该在Verilog中使用non-blocking assignments来创建顺序逻辑。在代码中,您正在使用阻塞分配,这意味着您首先更新b
,然后使用已经更新的值a
更新b
。如果需要使用阻止分配,则应创建一个combinational block。
此外,您应该组合时钟敏感部分和复位敏感部分,以使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
如您所见,我还将重设转换为异步,低电平有效的重设。尽管这不是强制性的,但很常见。复位信号旨在将所有触发器保持在复位状态,即使设备的电源缓慢上升也是如此。如果复位信号为高电平有效,则信号本身可能会缓慢上升。