跳轉到

More Verilog Features

Conditional ternary operator

原題:Conditional ternary operator

用三元運算子比較四個 8-bit 值。做法是先兩兩比較,再從兩個中間結果取較小值。

Verilog
module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min
);
    // assign intermediate_result1 = compare? true: false;
    wire [7:0] w1, w2;

    assign w1 = (a < b) ? a : b;
    assign w2 = (c < d) ? c : d;
    assign min = (w1 < w2) ? w1 : w2;
endmodule

Reduction operators

原題:Reduction operators

Reduction operator 會把整個 vector 壓成 1 bit。^in 等價於對所有 bit 做 XOR,可直接得到 parity。

Verilog
module top_module (
    input [7:0] in,
    output parity
);

    assign parity = ^in;
endmodule

Reduction: Even wider gates

原題:Reduction: Even wider gates

延續 reduction operator 的用法。對 100-bit vector 取 AND、OR、XOR 時,直接使用 &in|in^in,避免手動展開。

Verilog
module top_module( 
    input [99:0] in,
    output out_and,
    output out_or,
    output out_xor 
);
    assign out_and = &in;
    assign out_or = |in;
    assign out_xor = ^in;
endmodule

Combinational for-loop: Vector reversal 2

原題:Combinational for-loop: Vector reversal 2

用 combinational always @(*) 搭配 for loop 反轉 vector。因為 out 在 procedural block 內賦值,需要宣告成 reg

Verilog
module top_module( 
    input [99:0] in,
    output reg [99:0] out
);
    integer i;

    always @(*) begin
        for (i = 0; i < 100; i = i + 1) begin
            out[i] = in[99-i];
        end
    end
endmodule

Combinational for-loop: 255-bit population count

原題:Combinational for-loop: 255-bit population count

統計 255-bit vector 中有多少個 1。進入迴圈前先把 out 歸零,避免累加到前一次 combinational 計算的結果。

Verilog
module top_module( 
    input [254:0] in,
    output reg [7:0] out
);
    integer i;

    always @(*) begin
        out = 8'b00000000;
        for (i = 0; i < 255; i = i + 1) begin
            out = out + in[i];
        end
    end
endmodule

Generate for-loop: 100-bit binary adder 2

原題:Generate for-loop: 100-bit binary adder 2

題目要求例化 100 個 1-bit full adder,因此用 generate 建立重複的 adder chain。第一個 adder 的 cin 來自 module input,其餘 adder 則接前一級的 cout

Verilog
module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum
);
    full_adder fa_first(
        .a(a[0]),
        .b(b[0]),
        .cin(cin),
        .cout(cout[0]),
        .sum(sum[0])
    );

    genvar i;
    generate
        for (i = 1; i < 100; i = i + 1) begin: block_name
            full_adder fa(
                .a(a[i]),
                .b(b[i]),
                .cin(cout[i-1]),
                .cout(cout[i]),
                .sum(sum[i])
            );
        end
    endgenerate
endmodule

module full_adder(
    input a,
    input b,
    input cin,
    output cout,
    output sum
);
    assign {cout,sum} = a + b + cin;
endmodule

Generate for-loop: 100-digit BCD adder

原題:Generate for-loop: 100-digit BCD adder

延續 generate 寫法,差別是每 4 bit 代表一個 BCD digit。每一級 bcd_fadd 負責一個 digit,carry 串到下一級。

Verilog
module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum
);
    wire [99:0] w;

    assign cout = w[99];
    bcd_fadd bcd_fadd_first(
        .a(a[3:0]),
        .b(b[3:0]),
        .cin(cin),
        .cout(w[0]),
        .sum(sum[3:0])
    );

    genvar i;
    generate
        for (i = 1; i < 100; i = i + 1) begin: block_bcd
            bcd_fadd bf(
                .a(a[4*i+3:4*i]),
                .b(b[4*i+3:4*i]),
                .cin(w[i-1]),
                .cout(w[i]),
                .sum(sum[4*i+3:4*i])
            );
        end
    endgenerate
endmodule