Verilog设计的32位ALU

时间:2015-11-04 11:36:18

标签: verilog alu

你能帮助我做一个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

2 个答案:

答案 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设计的thisthis链接也很有用。

答案 1 :(得分:1)

2的补码-B~B+1~是位反转)。因此A - B == A + (-B) == A + ~B + 1。但是你在做RTL,所以你不需要为减法编写2的补码,因为它是默认的。 A - BA + ~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用于对电平敏感的锁存逻辑。