HDLbits--Comb組合邏輯
- 1.5 組合邏輯
- 1.5 Demo
在 Verilog 中,組合邏輯(Combinational Logic)是指輸出僅依賴于當前輸入的邏輯電路,沒有記憶功能(即沒有狀態存儲)。組合邏輯的特點是:
- 無時鐘信號:不依賴于時鐘邊沿觸發。
- 即時響應:輸入變化時,輸出立即更新(在仿真中表現為零延遲,實際硬件中有傳播延遲)。
1.5 組合邏輯
組合邏輯的實現方式
在 Verilog 中,組合邏輯通常通過以下方式實現:
- assign 語句
用于簡單的組合邏輯表達式。
語法:
assign output_signal = expression;
示例:
wire a, b, c;
assign c = a & b; // c 是 a 和 b 的按位與
- always 塊
用于描述更復雜的組合邏輯。
必須使用 always @(*) 或 always @(sensitivity_list) 來觸發。
注意:在 always 塊中賦值的信號必須聲明為 reg 類型。
示例:
reg c;
always @(*) beginc = a & b; // c 是 a 和 b 的按位與
end
- 條件運算符(三元運算符)
用于簡單的條件邏輯。
語法:
assign output_signal = condition ? value_if_true : value_if_false;
示例:
wire a, b, sel, c;
assign c = sel ? a : b; // 如果 sel 為 1,c = a;否則 c = b
- case 語句
用于多路選擇邏輯。
必須在 always 塊中使用。
示例:
reg [1:0] sel;
reg [3:0] out;
always @(*) begincase (sel)2'b00: out = 4'b0001;2'b01: out = 4'b0010;2'b10: out = 4'b0100;2'b11: out = 4'b1000;default: out = 4'b0000;endcase
end
- if-else 語句
用于條件邏輯。
必須在 always 塊中使用。
示例:
reg a, b, sel, c;
always @(*) beginif (sel)c = a;elsec = b;
end
組合邏輯的設計規則
避免鎖存器(Latch):
在 always 塊中,必須為所有可能的輸入條件明確賦值,否則會推斷出鎖存器。
示例:
always @(*) beginif (sel)c = a;// 缺少 else 分支,會推斷出鎖存器
end
敏感列表:
在 always 塊中,敏感列表必須包含所有影響輸出的信號。
使用 always @(*) 可以自動推斷敏感列表,避免遺漏。
避免組合邏輯環路:
組合邏輯的輸出不能直接或間接反饋到輸入,否則會導致環路。
示例:
assign a = a + 1; // 組合邏輯環路,非法
組合邏輯的示例
以下是一個 4:1 多路選擇器的 Verilog 實現:
module mux4to1 (input [3:0] data, // 4 位輸入input [1:0] sel, // 2 位選擇信號output reg out // 輸出
);always @(*) begincase (sel)2'b00: out = data[0];2'b01: out = data[1];2'b10: out = data[2];2'b11: out = data[3];default: out = 1'b0; // 避免鎖存器endcaseend
endmodule
總結
- 組合邏輯的輸出僅依賴于當前輸入,沒有記憶功能。
- 可以通過 assign 語句、always 塊、條件運算符、case 語句和 if-else 語句實現。
- 設計時需避免鎖存器和組合邏輯環路。
- 組合邏輯是數字電路設計的基礎,廣泛應用于多路選擇器、加法器、譯碼器等電路中。
1.5 Demo
組合邏輯電路:主要是包括條件組合、算數運算,卡諾真值表運算;
題目:計算模式
module top_module (input too_cold,input too_hot,input mode,input fan_on,output heater,output aircon,output fan
); assign heater = (mode == 1'b1) && (too_cold==1'b1);assign aircon = (mode == 1'b0) && (too_hot==1'b1);assign fan = (heater || aircon) || (fan_on);
endmodule
題目:計算輸入向量中的1數量;
module top_module( input [2:0] in,output [1:0] out );always @(*) begincase(in[2:0])3'b001,3'b010,3'b100: out[1:0] = 1;3'b011,3'b101,3'b110: out[1:0] = 2;3'b111: out[1:0] = 3;default: out[1:0] = 0;endcaseendendmodule
題目:計算向量中的index和他相鄰位置的關系
module top_module( input [3:0] in,output [2:0] out_both,output [3:1] out_any,output [3:0] out_different );assign out_both[2:0] = {{in[3] & in[2]},{in[2] & in[1]}, {in[1] & in[0]}};assign out_any[3:1] = {{in[3] | in[2]}, {in[2] | in[1]}, {in[1] | in[0]}};assign out_different[3:0] = {{in[3] ^ in[0]}, {in[3] ^ in[2]}, {in[2] ^ in[1]}, {in[1] ^ in[0]}};endmodule
題目:全加器–多位全加器例化低全加器
module top_module( input [2:0] a, b,input cin,output [2:0] cout,output [2:0] sum );fadd u0_fadd(a[0],b[0],cin,cout[0],sum[0]);fadd u1_fadd(a[1],b[1],cout[0],cout[1],sum[1]);fadd u2_fadd(a[2],b[2],cout[1],cout[2],sum[2]);endmodulemodule fadd( input a, b, cin,output cout, sum );assign cout = a&b|a&cin|b&cin;assign sum = a^b^cin;
endmodule//==變式
module top_module (input [3:0] x,input [3:0] y, output [4:0] sum);wire [2:0] cout;wire cin;assign cin = 1'b0;fadd fadd0 (x[0],y[0],cin,cout[0],sum[0]);fadd fadd1 (x[1],y[1],cout[0],cout[1],sum[1]);fadd fadd2 (x[2],y[2],cout[1],cout[2],sum[2]);fadd fadd3 (x[3],y[3],cout[2],sum[4],sum[3]);
endmodulemodule fadd( input a, b, cin,output cout, sum );assign cout = a&b|a&cin|b&cin;assign sum = a^b^cin;
endmodule