电路的分类

在这里插入图片描述

一般使用十六进制表示二进制更加方便

在这里插入图片描述

一位加法器也就是半加器电路设计

在这里插入图片描述
实际的二进制加法还需要考虑上一位的进位c
代码实现

`ifndef A_half_adder_V
`define A_half_adder_V

`include "a_xor.v"
`include "a_and.v"

module half_adder(output s, c, input a, b);
    wire w;
    a_xor x1(s, a, b);
    a_and and1(c, a, b);
endmodule;

`endif

测试

`include "half_adder.v"

module half_adder_tb;
    reg a, b;
    wire sum, c;
    
    half_adder obj(sum, c, a, b);
    
    initial begin
        // 将 $monitor 放在最开始,确保能监控到所有变化
        $monitor("Time=%0t: a=%b, b=%b, sum=%b, carry=%b", $time, a, b, sum, c);
        
        a = 0; b = 0; #10;
        a = 0; b = 1; #10;
        a = 1; b = 0; #10;
        a = 1; b = 1; #10;
        
        $finish;
    end
endmodule

全加器电路设计

在这里插入图片描述
这里使用两个半加器组成一个全加器
代码实现

`ifndef full_adder_V
`define full_adder_V

`include "half_adder.v"
`include "a_or.v"

module full_adder(output sum, nc, input a, b, c);
    wire val1, c1, val2, c2;
    half_adder h1(val1, c1, a, b);
    half_adder h2(sum, c2, val1, c);
    a_or o1(nc, c1, c2);
endmodule;

`endif

测试

`include "full_adder.v"

module full_adder_V;
    reg a, b, c;
    wire sum, nc;
    
    full_adder obj(sum, nc, a, b, c);
    
    initial begin
        // 将 $monitor 放在最开始,确保能监控到所有变化
        $monitor("Time=%0t: a=%b, b=%b, c=%b, sum=%b, carry=%b", $time, a, b, c, sum, nc);
        
        a = 0; b = 0; c = 1; #10;
        a = 0; b = 1; c = 0; #10;
        a = 0; b = 1; c = 1; #10;
        a = 1; b = 0; c = 0; #10;
        a = 1; b = 0; c = 1; #10;
        a = 1; b = 1; c = 0; #10;
        a = 1; b = 1; c = 1; #10;
        a = 0; b = 0; c = 0; #10;
        
        $finish;
    end
endmodule

16位加法器设计

16个全加器串联将上一个全加器的进位当作当前全加器的一个输入
代码实现

`ifndef add16_V
`define add16_V

`include "full_adder.v"

module add16(output [15:0] sum, input [15:0] a, input [15:0] b);
    supply0 gnd;
    wire [15:0] tmp;
    
    full_adder f1(sum[0], tmp[0], a[0], b[0], gnd);
    full_adder f2(sum[1], tmp[1], a[1], b[1], tmp[0]);
    full_adder f3(sum[2], tmp[2], a[2], b[2], tmp[1]);
    full_adder f4(sum[3], tmp[3], a[3], b[3], tmp[2]);
    full_adder f5(sum[4], tmp[4], a[4], b[4], tmp[3]);
    full_adder f6(sum[5], tmp[5], a[5], b[5], tmp[4]);
    full_adder f7(sum[6], tmp[6], a[6], b[6], tmp[5]);
    full_adder f8(sum[7], tmp[7], a[7], b[7], tmp[6]);
    full_adder f9(sum[8], tmp[8], a[8], b[8], tmp[7]);
    full_adder f10(sum[9], tmp[9], a[9], b[9], tmp[8]);
    full_adder f11(sum[10], tmp[10], a[10], b[10], tmp[9]);
    full_adder f12(sum[11], tmp[11], a[11], b[11], tmp[10]);
    full_adder f13(sum[12], tmp[12], a[12], b[12], tmp[11]);
    full_adder f14(sum[13], tmp[13], a[13], b[13], tmp[12]);
    full_adder f15(sum[14], tmp[14], a[14], b[14], tmp[13]);
    full_adder f16(sum[15], tmp[15], a[15], b[15], tmp[14]);
    
endmodule

`endif

测试

`include "add16.v"


module add16_tb;
    reg signed [15:0] a, b;
    wire signed [15:0] out;
    add16 obj(out, a, b);

    initial begin
        a=16'h0001;
        b=16'h1080;
        #10 b=16'h0001;
        #10 a=16'ha211;
            b=16'h0730;
        #10 a=16'h8001;
            b=16'h8003;
        #10 a=1;
            b=-5;
    end

    initial begin
        $monitor("%x + %x =%x , %d + %d =%d\n", a, b, out, a, b, out);
    end

endmodule

测试结果无符号表示

0001 + 1080 =1081 ,     1 +  4224 = 4225

0001 + 0001 =0002 ,     1 +     1 =    2

a211 + 0730 =a941 , 41489 +  1840 =43329

8001 + 8003 =0004 , 32769 + 32771 =    4

0001 + fffb =fffc ,     1 + 65531 =65532

测试结果有符号表示, 如果最高位是1认为当前数字是负数

0001 + 1080 =1081 ,      1 +   4224 =  4225

0001 + 0001 =0002 ,      1 +      1 =     2

a211 + 0730 =a941 , -24047 +   1840 =-22207

8001 + 8003 =0004 , -32767 + -32765 =     4

0001 + fffb =fffc ,      1 +     -5 =    -4

CPU不区分有符号无符号只有编程语言区分

减法原理

对于正数的补码就是原数本身, 负数的补码是对应的正数取反+ 1
在这里插入图片描述
上图是-5的补码表示, 对于16位有符号的数据来说, 减去5相当于加上32768 - 5, 具体的实现就是将正数的二进制取反+ 1, 16位无符号的数据可以拆分为15位有符号的数据数据范围[-32768, 32767]

对于CPU来说有符号数和无符号数是一样的, 只有编程语言对其进行区分

正溢负溢判断

溢出分为正溢和负溢, 前者是两个正数相加结果是负数, 后者是两个负数相加结果是正数
既然分为加减法, 那么默认每个数据都是带符号的, 例如1011就是-3
在这里插入图片描述
上图是正溢的情况, 最高有效位相产生了进位并且符号位相加没有进位
在这里插入图片描述
上图是负溢的情况, 最高有效位未产生进位并且符号位产生了进位

带溢出判断的加减法器的实现

在这里插入图片描述
代码实现

`ifndef signed_addsub_V
`define signed_addsub_V

`include "full_adder.v"
`include "a_not.v"
`include "a_xor.v"

module signed_addsub(output [15:0] sum, output overflow, input [15:0] a, b, input op);
    wire [15:0] d2;
    wire [15:0] b_final;
    wire [15:0] carry;
    
    genvar i;
    generate
        for (i = 0; i < 16; i = i + 1) begin : digit_convert
            a_not not_gate(d2[i], b[i]);
        end
    endgenerate
    
    assign b_final = op ? d2 : b;
    
    full_adder f1(sum[0], carry[0], a[0], b_final[0], op);
    full_adder f2(sum[1], carry[1], a[1], b_final[1], carry[0]);
    full_adder f3(sum[2], carry[2], a[2], b_final[2], carry[1]);
    full_adder f4(sum[3], carry[3], a[3], b_final[3], carry[2]);
    full_adder f5(sum[4], carry[4], a[4], b_final[4], carry[3]);
    full_adder f6(sum[5], carry[5], a[5], b_final[5], carry[4]);
    full_adder f7(sum[6], carry[6], a[6], b_final[6], carry[5]);
    full_adder f8(sum[7], carry[7], a[7], b_final[7], carry[6]);
    full_adder f9(sum[8], carry[8], a[8], b_final[8], carry[7]);
    full_adder f10(sum[9], carry[9], a[9], b_final[9], carry[8]);
    full_adder f11(sum[10], carry[10], a[10], b_final[10], carry[9]);
    full_adder f12(sum[11], carry[11], a[11], b_final[11], carry[10]);
    full_adder f13(sum[12], carry[12], a[12], b_final[12], carry[11]);
    full_adder f14(sum[13], carry[13], a[13], b_final[13], carry[12]);
    full_adder f15(sum[14], carry[14], a[14], b_final[14], carry[13]);
    full_adder f16(sum[15], carry[15], a[15], b_final[15], carry[14]);
    
    // 溢出逻辑判断
    wire c1 = carry[14];
    wire c2 = carry[15];
    a_xor xor1(overflow, c1, c2);
endmodule

`endif

测试
主要测试在数据范围内的加减法, 以及计算溢出的情况

`include "signed_addsub.v"

module signed_addsub_tb;
    reg [15:0] a, b;
    reg op;
    wire [15:0] out;
    wire overflow;
    
    signed_addsub obj(out, overflow, a, b, op);

    initial begin
        $dumpfile("signed_addsub_tb.vcd");
        $dumpvars(0, signed_addsub_tb);
        
        $display("=== SIGNED ADD/SUB TEST BENCH ===");
        $display("Op: 0=ADD, 1=SUB");
        $display("=================================");
        
        // Test case 1: Basic positive addition
        op = 0;  // ADD
        a = 16'h0001;  // 1
        b = 16'h1080;  // 4224
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 2: Basic positive addition with same numbers
        op = 0;
        a = 16'h0001;  // 1
        b = 16'h0001;  // 1
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 3: Negative + positive addition
        op = 0;
        a = 16'ha211;  // -24047
        b = 16'h0730;  // 1840
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 4: Both negative numbers addition
        op = 0;
        a = 16'h8001;  // -32767
        b = 16'h8003;  // -32765
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 5: Mixed positive and negative
        op = 0;
        a = 16'sd1;    // 1
        b = -16'sd5;   // -5
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 6: Basic positive subtraction
        op = 1;  // SUB
        a = 16'h0005;  // 5
        b = 16'h0002;  // 2
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 7: Subtraction with negative result
        op = 1;
        a = 16'h0002;  // 2
        b = 16'h0005;  // 5
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 8: Negative number subtraction
        op = 1;
        a = 16'hFFFB;  // -5
        b = 16'hFFFE;  // -2
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 9: Edge case - maximum positive + positive (potential overflow)
        op = 0;
        a = 16'h7FFF;  // 32767
        b = 16'h0001;  // 1
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 10: Edge case - minimum negative + negative (potential overflow)
        op = 0;
        a = 16'h8000;  // -32768
        b = 16'hFFFF;  // -1
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 11: Zero addition
        op = 0;
        a = 16'h0000;  // 0
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 12: Zero subtraction
        op = 1;
        a = 16'h0000;  // 0
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 13: Large positive subtraction
        op = 1;
        a = 16'h7FFF;  // 32767
        b = 16'h7FFE;  // 32766
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 14: Maximum positive - negative (potential overflow)
        op = 1;
        a = 16'h7FFF;  // 32767
        b = 16'h8001;  // -32767
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 15: Minimum negative - positive (potential overflow)
        op = 1;
        a = 16'h8000;  // -32768
        b = 16'h0001;  // 1
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 16: Identity addition (a + 0)
        op = 0;
        a = 16'h1234;  // 4660
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 17: Identity subtraction (a - 0)
        op = 1;
        a = 16'h1234;  // 4660
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 18: Subtraction to get zero
        op = 1;
        a = 16'h0005;  // 5
        b = 16'h0005;  // 5
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 19: Complementary numbers addition (a + (-a) = 0)
        op = 0;
        a = 16'h00FF;  // 255
        b = 16'hFF01;  // -255
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        // Test case 20: Boundary values test
        op = 0;
        a = 16'h7FFF;  // 32767 (max positive)
        b = 16'h8000;  // -32768 (min negative)
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), Overflow=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), overflow);
        
        $display("=================================");
        $display("=== TEST COMPLETE ===");
        
        #10 $finish;
    end
endmodule

带标志位的加减法器的实现

在这里插入图片描述
代码实现

`ifndef signal_mark_addsub_V
`define signal_mark_addsub_V

`include "full_adder.v"
`include "a_not.v"
`include "a_xor.v"
`include "nor16.v"

module signal_mark_addsub(output [15:0] out, output of, sf, zf, cf, input [15:0] a, b, input op);
    wire [15:0] d2;
    wire [15:0] b_final;
    wire [15:0] carry;
    
    genvar i;
    generate
        for (i = 0; i < 16; i = i + 1) begin : digit_convert
            a_not not_gate(d2[i], b[i]);
        end
    endgenerate
    
    assign b_final = op ? d2 : b;
    
    full_adder f1(out[0], carry[0], a[0], b_final[0], op);
    full_adder f2(out[1], carry[1], a[1], b_final[1], carry[0]);
    full_adder f3(out[2], carry[2], a[2], b_final[2], carry[1]);
    full_adder f4(out[3], carry[3], a[3], b_final[3], carry[2]);
    full_adder f5(out[4], carry[4], a[4], b_final[4], carry[3]);
    full_adder f6(out[5], carry[5], a[5], b_final[5], carry[4]);
    full_adder f7(out[6], carry[6], a[6], b_final[6], carry[5]);
    full_adder f8(out[7], carry[7], a[7], b_final[7], carry[6]);
    full_adder f9(out[8], carry[8], a[8], b_final[8], carry[7]);
    full_adder f10(out[9], carry[9], a[9], b_final[9], carry[8]);
    full_adder f11(out[10], carry[10], a[10], b_final[10], carry[9]);
    full_adder f12(out[11], carry[11], a[11], b_final[11], carry[10]);
    full_adder f13(out[12], carry[12], a[12], b_final[12], carry[11]);
    full_adder f14(out[13], carry[13], a[13], b_final[13], carry[12]);
    full_adder f15(out[14], carry[14], a[14], b_final[14], carry[13]);
    full_adder f16(out[15], carry[15], a[15], b_final[15], carry[14]);
    
    // 溢出逻辑判断
    wire c1 = carry[14];
    wire c2 = carry[15];
    a_xor xor1(of, c1, c2);
    
    // 符号标志位
    assign sf = out[15];

    // 0 标志位置
    nor16 nor16_1(zf, 16'b0, out);
    assign cf = carry[15];
endmodule

`endif

测试

`include "signal_mark_addsub.v"

module signal_mark_addsub_tb;
    reg [15:0] a, b;
    reg op;
    wire [15:0] out;
    wire of, sf, zf, cf;
    
    signal_mark_addsub dut(out, of, sf, zf, cf, a, b, op);

    initial begin
        $dumpfile("signal_mark_addsub_tb.vcd");
        $dumpvars(0, signal_mark_addsub_tb);
        
        $display("=== SIGNAL MARK ADD/SUB TEST BENCH ===");
        $display("Op: 0=ADD, 1=SUB");
        $display("Flags: OF=Overflow, SF=Sign, ZF=Zero, CF=Carry");
        $display("=======================================");
        
        // Test case 1: Basic positive addition
        op = 0;  // ADD
        a = 16'h0001;  // 1
        b = 16'h1080;  // 4224
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 2: Basic positive addition with same numbers
        op = 0;
        a = 16'h0001;  // 1
        b = 16'h0001;  // 1
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 3: Negative + positive addition
        op = 0;
        a = 16'ha211;  // -24047
        b = 16'h0730;  // 1840
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 4: Both negative numbers addition
        op = 0;
        a = 16'h8001;  // -32767
        b = 16'h8003;  // -32765
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 5: Mixed positive and negative
        op = 0;
        a = 16'sd1;    // 1
        b = -16'sd5;   // -5
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 6: Basic positive subtraction
        op = 1;  // SUB
        a = 16'h0005;  // 5
        b = 16'h0002;  // 2
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 7: Subtraction with negative result
        op = 1;
        a = 16'h0002;  // 2
        b = 16'h0005;  // 5
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 8: Negative number subtraction
        op = 1;
        a = 16'hFFFB;  // -5
        b = 16'hFFFE;  // -2
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 9: Edge case - maximum positive + positive (potential overflow)
        op = 0;
        a = 16'h7FFF;  // 32767
        b = 16'h0001;  // 1
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 10: Edge case - minimum negative + negative (potential overflow)
        op = 0;
        a = 16'h8000;  // -32768
        b = 16'hFFFF;  // -1
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 11: Zero addition
        op = 0;
        a = 16'h0000;  // 0
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 12: Zero subtraction
        op = 1;
        a = 16'h0000;  // 0
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 13: Large positive subtraction
        op = 1;
        a = 16'h7FFF;  // 32767
        b = 16'h7FFE;  // 32766
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 14: Maximum positive - negative (potential overflow)
        op = 1;
        a = 16'h7FFF;  // 32767
        b = 16'h8001;  // -32767
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 15: Minimum negative - positive (potential overflow)
        op = 1;
        a = 16'h8000;  // -32768
        b = 16'h0001;  // 1
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 16: Identity addition (a + 0)
        op = 0;
        a = 16'h1234;  // 4660
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 17: Identity subtraction (a - 0)
        op = 1;
        a = 16'h1234;  // 4660
        b = 16'h0000;  // 0
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 18: Subtraction to get zero
        op = 1;
        a = 16'h0005;  // 5
        b = 16'h0005;  // 5
        #10 $display("Time=%0t, Op=SUB, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 19: Complementary numbers addition (a + (-a) = 0)
        op = 0;
        a = 16'h00FF;  // 255
        b = 16'hFF01;  // -255
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        // Test case 20: Boundary values test
        op = 0;
        a = 16'h7FFF;  // 32767 (max positive)
        b = 16'h8000;  // -32768 (min negative)
        #10 $display("Time=%0t, Op=ADD, A=%h(%d), B=%h(%d), Out=%h(%d), OF=%b, SF=%b, ZF=%b, CF=%b", 
                    $time, a, $signed(a), b, $signed(b), out, $signed(out), of, sf, zf, cf);
        
        $display("=================================");
        $display("=== TEST COMPLETE ===");
        
        #10 $finish;
    end
endmodule

遇到的Verilog语法问题解释

verilog语言的语法, 主要作用是编译时生成重复的硬件结构
在这里插入图片描述genvar 是专门用于在 generate 模块中声明循环变量的, 每个循环都需要独特的标识
代码实现

关于类似于1'b0这种写法语法的解释如下

  • 1:指定这是一个 1 位 宽度的值
  • 'b:指定使用 二进制 进制
  • 0:具体的值为 逻辑 0

在这里插入图片描述
generate块是编译阶段创建硬件或者连线, always块是硬件运行时的行为描述