2016-03-02 349 views
0

我有一个任务要求创建一个模块,如标题中所述。我需要添加,减去AND和XOR两个输入并设置必要的标志。这个任务并不是100%清晰的,但我假设溢出标志会使其他一切无效,所以我不需要担心任何超过32位结果的内容。我的问题伴随着零和溢出标志,无论我尝试什么,它都不会被设置。我已经将我在网上找到的一些方法放在一起,但我不确定这些方法是错误的还是我编写错误。一切都编译和运行,但我的旗帜从来没有设置,不管我使用什么输入。我只参加了一个Verilog课程,不记得很多约束条件,所以不胜感激。具有溢出,符号和零标记的Verilog 32位ALU

module alu(clk, rst, CTRL, A, B, Overflow, Z_flag, Negative, d_out); 

input wire clk , rst; 
input wire [1:0] CTRL; 
input wire signed [31:0] A, B; 

output wire Negative; 
output reg Z_flag; 
output reg [1:0] Overflow; 
output wire [31:0] d_out; 
reg signed [32+32:0] Result; 

assign Negative = Result[31]; // Negative Flag 
assign d_out [31:0] = Result [31:0]; 

[email protected](posedge clk) 
begin 
    if(!rst) 
    begin 
     if(rst) 
     begin 
     Result [31:0] <= 0; 
     end 

     case(CTRL)  
     2'b00: 
     begin 
      Result [32:0] <= {A[31], A [31:0]} + {B[31], B [31:0]}; // Add A + B 
       if(Result [32:31] == (2'b11 | 2'b10)) Overflow <= 1'b1; 
      else Overflow <= 1'b0; 
     end 

     2'b01: 
     begin 
      Result [32:0] <= {A[31], A [31:0]} - {B[31], B [31:0]}; // Subtract A - B 
       if((Result[32+32]) && (~Result [32+31:31] != 0)) Overflow <= 1'b1; 
      else if ((~Result[32+32]) && (Result [32+31:31] != 0)) Overflow <= 1'b1; 
       else Overflow <= 1'b0; 
     end 

     2'b10: 
     begin 
      Result [31:0] <= A [31:0] & B [31:0]; // Bitwise AND 
     end 

     2'b11: 
     begin 
      Result [31:0] <= A [31:0]^B [31:0]; // Bitwise XOR 
     end 
     endcase 

     if (Result == "32h'00000000") Z_flag <= 1'b1; // Zero detection 
     else Z_flag <= 1'b0; 
    end 
end 

这里是我的测试平台:

module ALU_stimulus; 


    reg clk; 
    reg rst; 
    reg [1:0] CTRL; 
    reg [31:0] A; 
    reg [31:0] B; 


    wire Overflow; 
    wire Z_flag; 
    wire Negative; 
    wire [31:0] d_out; 


    alu uut (
     .clk(clk), 
     .rst(rst), 
     .CTRL(CTRL), 
     .A(A), 
     .B(B), 
     .Overflow(Overflow), 
     .Z_flag(Z_flag), 
     .Negative(Negative), 
     .d_out(d_out) 
    ); 

    initial begin 

    clk = 0; 
    rst = 0; 
    CTRL = 0; 
    A = 0; 
    B = 0; 


    #100; 
    clk=1'b1; 
    A=32'h00000000; 
    B=32'h00000000; 
    rst=1'b0; 
    CTRL=2'b00; 
    #100; 
    clk=1'b0; 
    #100 $stop; 

    end 

endmodule 
+1

如何发布一个编译包含你的测试平台的例子?为了回答你的问题,有人需要做一些工作来做到这一点。 [http://stackoverflow.com/help/mcve](http://stackoverflow.com/help/mcve) –

+0

您发布的代码未编译,因为未声明chk_oflow。你确定这是你的EXACT代码吗? ''“32h'00000000”'也看起来很腥。 – toolic

+0

我注意到驱动'Overflow'输出的逻辑输入本身是由时钟进程中的非阻塞赋值('<=')驱动的 - “always @(posedge clk)'。 (换句话说,你正在使用非阻塞赋值分配给它后立即测试'Result')。这意味着它们将相对于'Result'延迟一个时钟周期。我怀疑这不是你以后的行为。 –

回答

1

为便于说明例如考虑1位符号扩展4位值。

1 + 1 = 2;没有溢出

0 0001; //1 
0 0001; //1 
0 0010; //2 

7 + 7 = 14; 4位最大溢出值为7

0 0111; //1 
0 0111; //1 
0 1110; //-2 

-1 + -1 = -2;无下溢

1 1111 //-1 
1 1111 //-1 
1 1110 //-2 

-8 + -8 = -16分钟下溢值是-8

1 1000 //-8 
1 1000 //-8 
1 0000 // 0 

望着最高位(符号扩展和MSB),我们可以看到:

00 => normal 
01 => Overflow 
10 => Underflow 
11 => normal