三目運算符
Verilog 有一個三元條件運算符 ( ? : ) 很像 C:
(condition ? if_true : if_false)
這可用于根據一行上的條件(多路復用器)選擇兩個值之一,而無需在組合 always 塊中使用 if-then。 Examples:
(0 ? 3 : 5) // Thisis 5 becausetheconditionisfalse.
(sel ? b : a) // A 2-to-1multiplexerbetweenaandbselectedbysel.
always @(posedge clk) // A T-flip-flop.
q <= toggle ? ~q : q;
always @(*) // State transition logic for a one-input FSM
case (state)
A: next = w ? B : A;
B: next = w ? A : B;
endcase
assignout = ena ? q : 1'bz; // Atri-statebuffer
((sel[1:0] == 2'h0) ? a : // A 3-to-1mux
(sel[1:0] == 2'h1) ? b :
c )
練習
給定四個無符號數,找出最小值。無符號數可以與標準比較運算符 (a < b) 進行比較。使用條件運算符創建兩路最小電路,然后組合其中的一些來創建 4 路最小電路。可能需要一些用于中間結果的線向量。
Module Declaration
moduletop_module (
input[7:0]a, b, c, d,
output[7:0]min);
答案
moduletop_module (
input[7:0]a, b, c, d,
output[7:0]min);//
wire[7:0]out_t0;
wire[7:0]out_t1;
assignout_t0 = (a
歸約運算符
已經熟悉兩個值之間的按位運算,例如a & b或a ^ b。有時,您想創建一個對一個向量的所有位進行操作的寬門,例如(a[0] & a[1] & a[2] & a[3] ... ),如果向量很長。
的減少運營商可以做AND,OR,以及向量的比特的XOR,產生輸出的一個比特:
& a[3:0] // AND: a[3]&a[2]&a[1]&a[0]. Equivalentto (a[3:0] == 4'hf)
| b[3:0] // OR: b[3]|b[2]|b[1]|b[0]. Equivalentto (b[3:0] != 4'h0)
^ c[2:0] // XOR: c[2]^c[1]^c[0]
這些是只有一個操作數的一元操作符(類似于NOT操作符!和~ )。你也可以將這些門的輸出倒轉來創建NAND、NOR和XNOR門,例如(~& d[7:0])。
練習
當通過不完善的信道傳輸數據時,奇偶校驗通常用作檢測錯誤的簡單方法。創建一個電路來計算 8 位字節的奇偶校驗位(這將向字節添加第 9 位)。我們將使用“偶數”奇偶校驗,其中奇偶校驗位只是所有 8 個數據位的異或。
Module Declaration
module top_module (
input [7:0] in,
output parity);
答案
module top_module (
input [7:0] in,
output parity);
assign parity = ^ in[7:0];
endmodule
歸約練習
問題
在 [99:0] 中構建一個具有 100 個輸入的組合電路。 有3個輸出:
- out_and:100 輸入與門的輸出。
- out_or:100 輸入或門的輸出。
- out_xor:100 輸入異或門的輸出。
Module Declaration
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
答案
module top_module(
input [99:0] in,
output out_and,
output out_or,
output out_xor
);
assign out_and = &in[99:0];
assign out_or = |in[99:0];
assign out_xor = ^in[99:0];
endmodule
反轉
問題
給定一個 100 位的輸入向量 [99:0],反轉其位順序。
Module Declaration
module top_module(
input [99:0] in,
output [99:0] out
);
答案
module top_module(
input [99:0] in,
output [99:0] out
);
genvar i ;
generate
for (i = 0 ; i <= 99 ; i = i+1)
begin : loop0
assign out[i]=in[99-i];
end
endgenerate
endmodule
人口計數電路
問題
“人口計數”電路計算輸入向量中“1”的數量。為 255 位輸入向量構建人口計數電路。
Module Declaration
module top_module(
input [254:0] in,
output [7:0] out );
答案
module top_module(
input [254:0] in,
output [7:0] out );
int i;
always @ (*)begin
out = 8'b0000_0000;
for (i=0; i<=254; i++)begin
if(in[i] == 1'b1)
out = out + 1'b1;
else
out = out + 1'b0;
end
end
endmodule
100位加法器
問題
通過實例化 100 個全加器來創建一個 100 位二進制紋波進位加法器。加法器將兩個 100 位數字和一個進位相加,以產生 100 位總和并進位。為了鼓勵您實際實例化全加器,還要輸出紋波進位加法器中每個全加器的進位。cout[99] 是最后一個全加器的最后一個進位,也是你經常看到的進位。
Module Declaration
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
答案
module top_module(
input [99:0] a, b,
input cin,
output [99:0] cout,
output [99:0] sum );
genvar i ;
generate
for (i = 0 ; i <= 99 ; i = i+1)
begin : loop0
if(i==0)begin
assign {cout[i],sum[i]} = a[i]+b[i]+cin;
end
else begin
assign {cout[i],sum[i]} = a[i]+b[i]+cout[i-1];
end
end
endgenerate
endmodule
100位BCD加法器
問題
為您提供了一個名為bcd_fadd的 BCD 一位加法器,它將兩個 BCD 數字和進位相加,并產生一個總和和進位。
module bcd_fadd {
input [3:0] a,
input [3:0] b,
input cin,
output cout,
output [3:0] sum );
實例化 100 個bcd_fadd副本以創建 100 位 BCD 紋波進位加法器。您的加法器應將兩個 100 位 BCD 數(打包成 400 位向量)和一個進位相加,以產生 100 位總和并執行。
Module Declaration
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
答案
module top_module(
input [399:0] a, b,
input cin,
output cout,
output [399:0] sum );
wire [99:0] cout_in;
genvar i ;
generate
for (i = 0 ; i <= 99 ; i = i+1)
begin : loop0
if(i==0)begin
bcd_fadd u_bcd_fadd(
.a (a[4 * i + 3: 4 * i] ),
.b (b[4 * i + 3: 4 * i] ),
.cin (cin ),
.cout(cout_in[i]),
.sum (sum[4 * i + 3: 4 * i])
);
end
else begin
bcd_fadd ui_bcd_fadd(
.a (a[4 * i + 3: 4 * i] ),
.b (b[4 * i + 3: 4 * i] ),
.cin (cout_in[i-1] ),
.cout(cout_in[i]),
.sum (sum[4 * i + 3: 4 * i])
);
end
end
endgenerate
assign cout = cout_in[99];
endmodule