你能帮助我做一个32位的ALU并向我解释一些事情吗? 想做:
0 bitwise AND: out = inA & inB.
1 bitwise OR: out = inA | inB.
2 addition: out = inA + inB.
6 subtraction: out = inA – inB //2's complement
7 Set On Less Than: out = ((inA < inB)?1:0)
12 NOR: out = ~( inA | inB)
到目前为止完成此事:
module ALU #(parameter N=32)(ALUOut, Zero, ALUinA, ALUinB, ALUop);
output [N-1:0] ALUOut;
reg [N-1:0] ALUOut;
output Zero;
reg Zero;
input [3:0] ALUop;
input [N-1:0] ALUinA, ALUinB;
always @(ALUinA or ALUinB or ALUop)
begin
case (ALUop)
4'b0000: ALUOut = ALUinA & ALUinB ; // 0:AND
答案 0 :(得分:2)
你的代码很好。只需要进行一些修改。 ALUOut
必须为[N:0]
,因为您在添加时需要进位。此外,在减法的情况下,必须要求借位。
参考SystemVerilog LRM 1800-2012第11.6节表达式位长,
SystemVerilog使用操作数的位长来确定在评估时使用的位数 表达
因此,ALUOut[N-1:0] = ALUinA[N-1:0] + ALUinB[N-1:0];
将严格评估N
的表达式,ALUOut = ALUinA + ALUinB;
将ALUOut
评估取决于N
的大小。在这里,您无法看到差异,因为所有操作数都是ALUOut
位宽,但当N+1
增加到module top();
bit [3:0] a,b;
logic [3:0] sum;
bit carry;
assign sum[3:0] = a[3:0] + b[3:0];
// assign {carry,sum}= a + b;
initial
$monitor("a = %0d b = %0d carry = %0d sum = %0d",a,b,carry,sum);
initial
begin
a = 5; b = 1;
#5 ; a = 15; b = 1;
end
endmodule
位(包括进位)时,它可以创建差异。
例如,
a = 15 b = 1 carry = 0 sum = 0
执行到a = 15 b = 1 carry = 1 sum = 0
,同时使用注释的assign语句执行var fruitsStrings = ["apple", "banana", "orange" ];
var fruitsObjects = [];
$.map( fruitsStrings, function( val, i ) {
fruitsObjects.push({ fruits: val });
});
有关详细信息,请参阅LRM 1800-2012,第11.6节。 此外,有关ALU设计的this和this链接也很有用。
答案 1 :(得分:1)
2的补码-B
是~B+1
(~
是位反转)。因此A - B == A + (-B) == A + ~B + 1
。但是你在做RTL,所以你不需要为减法编写2的补码,因为它是默认的。 A - B
和A + ~B + 1
将合成相同的内容。
A[N-1:0] + B[N-1:0]
始终是无符号操作。如果A和B声明为A + B
,则input signed [N-1:0] A, B
可以是带符号的操作,否则它是无符号操作。
其他说明:
标题存在问题。许多模拟器,合成器和其他Verilog工具都会接受您所拥有的,但它不符合IEEE标准。有两种标题样式,ANSI和非ANSI。除非要求遵循标准的IEEE1364-1995版本,否则我建议使用ANSI。
ANSI样式(IEEE标准1364-2001及以上):
module ALU #(parameter N=32)(
output reg [N-1:0] ALUOut,
output reg Zero,
input [N-1:0] ALUinA, ALUinB,
input [3:0] ALUop );
非ANSI样式(IEEE Std 1364-1995及以上):
module ALU (ALUOut, Zero, ALUinA, ALUinB, ALUop);
parameter N=32;
output [N-1:0] ALUOut;
output Zero;
input [3:0] ALUop;
input [N-1:0] ALUinA, ALUinB;
reg [N-1:0] ALUOut;
reg Zero;
always @(ALUinA or ALUinB or ALUop)
语法合法。但是,由于IEEE1364-2001组合逻辑被重新编写为always @*
或always @(*)
(@*
和@(*)
是同义的,用户首选项)。对于SystemVerilog(IEEE1800),Verilog(IEEE1364)的后继者,always_comb
推荐用于always @*
用于组合逻辑,always_latch
用于对电平敏感的锁存逻辑。