繁体   English   中英

使用Verilog在32位ALU中实现一位标志

[英]Implementing one-bit flags in a 32Bit ALU using Verilog

我正在做作业,有点迷路,不知道该如何上手。 我需要在32Bit ALU中实现以下标志:

•Z(“零”):如果运算结果为零,则设置为1(“ True”)

•N(“负”):如果结果的第一位为1,则设置为1(“ True”),表示负数

•O(“溢出”):设置为1(“ True”)表示操作超出了总线宽度。

此外,还有一个比较函数,将输入a与输入b进行比较,然后设置三个标志之一:

•如果输入a小于输入b,则为LT

•GT,如果输入a大于输入b

•如果输入a等于输入b则等于

我需要修改此ALU以包括三个标志和比较输出,然后更改测试台以测试所有这些修改。

这是我收到的有关此作业的所有信息,实际上没有教科书或任何其他资源。 这是在线课程,我无法从老师那里得到答复。 因此,我对如何开始感到困惑。 在数字逻辑方面,我还是一个新手,请耐心等待。 我只需要一些帮助来了解这些标志和比较的工作原理。 如果有人能更好地向我解释它们的工作方式和作用,以及可能如何将它们实现到ALU和测试平台中,我将非常感激。

我不希望有人来做我的作业,我真的只需要帮助就可以理解它。

ALU

module alu32 (a, b, out, sel);      
    input [31:0] a, b;    
    input [3:0] sel;   
    output [31:0] out,
    reg [31:0] out;  

    //Code starts here 
    always @(a, b, sel)   
    begin     
        case (sel)       
            //Arithmetic Functions       
            0  : out <= a + b;       
            1  : out <= a - b;       
            2  : out <= b - a;       
            3  : out <= a * b;       
            4  : out <= a / b;       
            5  : out <= b % a;       
            //Bit-wise Logic Functions       
            6  : out <= ~a; //Not       
            7  : out <= a & b; //And       
            8  : out <= a | b; //Or       
            9  : out <= a ^ b; //XOR       
            10 : out <= a ^~ b; //XNOR       
            //Logic Functions       
            11 : out <= !a;       
            12 : out <= a && b;       
            13 : out <= a || b;       
            default: out <= a + b;     
        endcase
    end  
endmodule 

ALU测试台

module alu32_tb();  
    reg [31:0] a, b; 
    reg [3:0] sel; 
    wire [31:0] out; 

initial begin

$monitor("sel=%d a=%d b=%d out=%d", sel,a,b,out);   
    //Fundamental tests - all a+b   
    #0 sel=4'd0; a = 8'd0; b = 8'd0;    
    #1 sel=4'd0; a = 8'd0; b = 8'd25;   
    #1 sel=4'd0; a = 8'd37; b = 8'd0;   
    #1 sel=4'd0; a = 8'd45; b = 8'd75;  
    //Arithmetic   
    #1 sel=4'd1; a = 8'd120; b = 8'd25; //a-b   
    #1 sel=4'd2; a = 8'd30; b = 8'd120; //b-a   
    #1 sel=4'd3; a = 8'd75; b = 8'd3; //a*b   
    #1 sel=4'd4; a = 8'd75; b = 8'd3; //a/b   
    #1 sel=4'd5; a = 8'd74; b = 8'd3; //a%b  
    //Bit-wise Logic Functions   
    #1 sel=4'd6; a = 8'd31; //Not   
    #1 sel=4'd7; a = 8'd31; b = 8'd31; //And   
    #1 sel=4'd8; a = 8'd30; b = 8'd1; //Or   
    #1 sel=4'd9; a = 8'd30; b = 8'd1; //XOR   
    #1 sel=4'd10; a = 8'd30; b = 8'd1; //XNOR  
    //Logic Functions   
    #1 sel=4'd11; a = 8'd25; //Not   
    #1 sel=4'd12; a = 8'd30; b = 8'd0; //And   
    #1 sel=4'd13; a = 8'd0; b = 8'd30; //Or      
    #1 $finish; 
end  

alu32 myalu (.a(a), .b(b), .out(out), .sel(sel));  
endmodule  

您可以将这些标志输出添加到设计中 像下面这样。 只需它们连接到测试台即可。

// In design:
output zero;
output overflow;
output negative;

// In testbench:
wire zero,overflow,negative;
alu32 myalu (.a(a), .b(b), .out(out), .sel(sel), .zero(zero), .overflow(overflow),.negative(negative));  

对于逻辑部分,您可以通过连续分配来完成 您可能需要添加一些 sel 特定值期间使用这些标志的逻辑

Z(“零”):如果运算结果为零,则设置为1(“ True”)

因此,我们可以有条件,例如out 所有位必须为零 这可以通过许多其他方式来完成。

// Bit wise OR-ing on out
assign zero = ~(|out);

O(“溢出”):设置为1(“ True”)表示操作超出了总线宽度。

根据描述和所示代码,您只需要在这里带有进位标志 ,即加法操作的带符号扩展名 有关溢出情况,请参阅WikiPedia上的此页面

但是, 溢出条件一样的位。 溢出表示数据丢失,而进位表示下一阶段用于计算的位

因此,执行以下操作可能会很有用:

// Extend the result for capturing carry bit
// Simply use this bit if you want result > bus width
{carry,out} <= a+b;
// overflow in signed arithmetic:
assign overflow = ({carry,out[31]} == 2'b01);

N(“负”):如果结果的第一位为1,则设置为1(“ True”),表示负数

同样,这只是out寄存器的MSB 但是, 下溢条件完全不同

// Depending on sel, subtraction must be performed here
assign negative = (out[31] == 1 && (sel == 1 || sel == 2));

同样,简单条件如assign lt = (a<b) ? 1 : 0; assign lt = (a<b) ? 1 : 0; 其他人可以检测输入的LT,GT和EQ条件。

请参考此处的答案了解上溢/下溢标志 溢出传送链接也可能有用。

有关ALU实现的更多信息,请参见Carryout-OverflowVerilog中的 ALUALU PDF

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM