More Verilog Features
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 operator 會把整個 vector 壓成 1 bit。^in 等價於對所有 bit 做 XOR,可直接得到 parity。
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 = ∈
assign out_or = |in;
assign out_xor = ^in;
endmodule
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
統計 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
題目要求例化 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 寫法,差別是每 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