2015-11-04 230 views
-3

你能幫我們做一個32位ALU並解釋一些事情嗎? 想做的事:32位ALU的Verilog設計

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

目前尚不清楚你卡在哪裏以及你不明白的東西。 – abrunet

+0

想要做其他代碼,不知道該怎麼做,因爲我對我看過的所有這些視頻/帖子有點困惑。不知道好的verilog也知道我的代碼是否正確:/另外我不知道如何使用verilog中的2完成來編寫se減法 –

+0

這與之間有什麼區別: 4'b0010:ALUOut [N-1 :0] = ALUinA [N-1:0] + ALUinB [N-1:0]; 而這個: 4'b0010:ALUOut = ALUinA + ALUinB; –

回答

2

你的代碼是好的。只需要一些修改。 ALUOut必須是[N:0],因爲在加法的情況下你需要一個進位位。而且,在減法的情況下,必須要求借位。

參照的SystemVerilog LRM 1800-2012 11.6節表達位長度

SystemVerilog的使用的操作數的位長度以確定有多少個比特,而評估一個 表達來使用。

所以,ALUOut[N-1:0] = ALUinA[N-1:0] + ALUinB[N-1:0];嚴格ALUOut = ALUinA + ALUinB;將 評估取決於ALUOut大小評價N的表達。在這裏,你看不到差異,因爲所有的youe操作數都是N位寬,但是當ALUOut增加到N+1位(包括carry),那麼它可以創建一個差異。

例如,

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

參考LRM 1800-2012,第11.6節以獲得更多信息。 另外,有關ALU設計的鏈接thisthis可能很有用。

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聲明爲input signed [N-1:0] A, B,則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標準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用於電平敏感的鎖存邏輯。