module accumulator (
input [7:0] A ,
input reset,
input clk,
output reg carryout,
output reg overflow,
output reg [8:0] S,
output reg HEX0,
output reg HEX1,
output reg HEX2,
output reg HEX3
);
reg signA;
reg signS;
reg [7:0] magA;
reg [7:0] magS;
reg Alarger;
initial begin
S = 9'b000000000;
end
always_ff @ (posedge clk, posedge reset) begin
if (reset) begin
S = 9'b000000000;
end
else begin
begin
signA <= A[7]; //Is A negative or positive
signS <= S[7];
S <= A + S;
end
if (signA == 1) begin //A is negative so magnitude is of 2s compliment
magA <= (~A[7:0] + 1'b1);
end
else begin
magA <= A;
end
if (signS == 1) begin //sum is negative so magnitude is of 2s compliment
magS <= (~S[7:0] + 1'b1);
end
else begin
magS <= S;
end
if (magA > magS) begin
Alarger <= 1'b1; //Magnitude of A is larger than magnitude of sum
end
else begin
Alarger <= 1'b0;
end
if ((signA == 1) & (Alarger == 1) & (S[7] == 0)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if ((signS == 1) & (Alarger == 0) & (S[7] == 0)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if ((signS == 1) & (signA == 1) & (S[7] == 0)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if ((signS == 0) & (signA == 0) & (S[7] == 1)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if (S[8] == 1) begin //carryout occurred
carryout <= 1'b1;
overflow <= 1'b0;
S <= 9'b000000000; //sum no longer valid
end
else begin
carryout <= 1'b0;
end
display_hex h1 //display of A
(
.bin (magA),
.hexl (HEX2),
.hexh (HEX3)
);
display_hex h2 //display of sum
(
.bin (S[7:0]),
.hexl (HEX0),
.hexh (HEX1)
);
end
end
endmodule
我正在尝试创建一个累加器,它将A(8位二进制值,可以是有符号或无符号)重复加到总和中。计算总和后,sum和A应显示4个十六进制显示LED上的值(A为2个LED,总和为2个LED)。但是,我很难将其编译。我已经搜索了错误代码,它似乎是语法错误的一般错误,可以有多种含义。
答案 0 :(得分:1)
错误是这两行的结果:
display_hex h1 //display of A
(
.bin (magA),
.hexl (HEX2),
.hexh (HEX3)
);
display_hex h2 //display of sum
(
.bin (S[7:0]),
.hexl (HEX0),
.hexh (HEX1)
);
在这里,您似乎有一个名为display_hex
的模块,它将8位值转换为七段显示所需的数字。您正在尝试使用该模块,就好像它是一个函数而模块非常不是函数。 Verilog中的模块(或者你正在使用的SystemVerilog,但此时的差异实际上是令牌)可以作为一组硬件接收一些输入并吐出一些输出;重要的是要注意它们是静态的东西。它们要么存在于设计中,要么不存在;就像在面包板上使用IC一样。顶部模块是面包板,您在该模块下声明的模块是您插入电路板的组件。输入和输出是必须连接的各种连接(引脚),以使一切正常。
也就是说,总是阻塞(就像你正在使用的always_ff
)形成一种描述模块内逻辑和寄存器的方式。因此,您确实认为在其中分配logic
/ reg
变量来描述硬件的行为方式。如果你看一下你的逻辑,你会注意到模块声明依赖于reset
;即如果reset
被断言,这些模块将不存在,这没有任何意义。电信号不会使电路中的整个IC消失!因此,您需要从您的acculumator的逻辑描述中提取模块声明,如下所示:
module accumulator (
...
);
...
display_hex h1 //display of A
(
.bin (magA),
.hexl (HEX2),
.hexh (HEX3)
);
display_hex h2 //display of sum
(
.bin (S[7:0]),
.hexl (HEX0),
.hexh (HEX1)
);
...
always_ff @(posedge clk, posedge reset) begin
// Your accumulator logic here
...
end
endmodule
请注意,display_hex
模块的模块声明是独立的,因为我声明这些模块存在,而不是依赖于任何东西!
但是,除此之外,您的设计还存在许多问题:
当您使用SystemVerilog构造(always_ff
)时,您应声明所有变量类型logic
,而不是reg
或留空(即{{1} }应为input clk
,input logic clk
应为reg signA
)。 logic signA
类型只会让一切变得更简单,所以请使用它:)
在logic
区块中,您正确always_ff
,但分配应该是NBA(使用reset
,而不是S <= 9'b0;
S = 9'b0;
}})
您在if (reset)
内使用NBA,这是正确的,但是,您似乎需要在以下逻辑中立即使用这些值。这不会按预期工作,或者至少它不会在同一个时钟周期内起作用。要解决这个问题,你需要确定什么应该是一个寄存器,什么应该只是中间逻辑产生的值,然后为中间值创建一个单独的always_ff
。
我假设always_comb
变量适用于七个段显示,因此它们应该至少声明为HEX
答案 1 :(得分:0)
我无法重现确切的错误,但将display_hex
移出always_ff
的实例化解决了主要问题:
module accumulator
(
/* ... */
);
// ...
always_ff @ (posedge clk, posedge reset) begin
/* ... */
end
display_hex h1 (
/* ... */
);
display_hex h2 (
/* ... */
);
endmodule
另一件事:代码驱动initial
的变量S以及always
。这会创建多个驱动程序,代码将无法编译。要解决此问题,请完全删除初始内容,因为S
被置位时reset
将设置为0,所以您不需要它。
OR
您可以将所有逻辑移动到初始块中;它看起来像这样(但这很可能,不会合成):
initial begin
S = 0;
forever begin
wait @(posedge clock);
// Do stuff here ..
end
end