Verilog组合逻辑设计选择器、加法器、译码器与三态门组合逻辑的输出只由当前输入决定。设计时最重要的纪律是always *中每条路径都要给输出赋值避免无意推断锁存器。一、表决器最简单的组合判断三人中任意两人同意即通过module vote3(input wire a,b,c, output wire pass); assign pass (ab)|(ac)|(bc); endmodule000、001、010、100不通过011、101、110、111通过。它也能用case写出适合需要列举复杂真值表的场景。二、选择器让一条输入通往输出二选一选择器的本质是sel0选a、sel1选bmodule mux2(input wire a,b,sel, output wire y); assign y sel ? b : a; endmodule四选一选择器可用case{s1,s0}是两位选择码module mux4(input wire [3:0] in, input wire [1:0] sel, output reg y); always * begin case(sel) 2b00:yin[0]; 2b01:yin[1]; 2b10:yin[2]; 2b11:yin[3]; default:y1b0; endcase end endmodule选择器像铁路道岔未被选中的输入怎么变化都不应该影响输出。仿真时应逐个切换4种选择状态再改变未选中输入验证隔离效果。三、加法器与BCD加法器一位全加器module full_add(input wire a,b,cin,output wire sum,cout); assign sum a^b^cin; assign cout (ab)|(cin(a^b)); endmodule4位加法应保留进位module add4(input wire [3:0] a,b,input wire cin, output wire [3:0] sum,output wire cout); assign {cout,sum}{1b0,a}{1b0,b}cin; endmoduleBCD加法器的输入每一位只允许0—9。两数和超过9时加6将二进制进位边界修正为十进制进位边界module add_bcd(input wire [3:0] a,b,input wire cin, output reg [3:0] sum,output reg cout); reg [4:0] t; always * begin t{1b0,a}{1b0,b}cin; if(t9) {cout,sum}t6; else {cout,sum}t; end endmodule例如7512二进制和为01100加00110得到10010因此十进制进位为1、个位为2。四、ALU、译码器与优先编码器ALU把同一组数据按opcode执行不同操作module alu(input wire [7:0] a,b,input wire [2:0] op,output reg [7:0] y); always * begin case(op) 0:yab; 1:ya-b; 2:yab; 3:ya|b; 4:y~a; default:y8h00; endcase end endmodule3-8译码器将3位地址变为8根独立选择线74138类型输出低有效只有使能满足时对应的一位为0。8-3优先编码器则相反多路请求同时到来时先处理优先级最高的一路。用if-else链或casez都可实现关键是明确有效电平和优先级方向。七段数码管译码应先确认段序和共阴/共阳极性。共阴、高电平点亮、段序为{a,b,c,d,e,f,g}时数字0通常为7b1111110数字8为7b1111111。不同开发板的段序和电平可能不同必须按硬件原理图调整。五、三态门与组合逻辑的边界module tri_buf(input wire in,en, output wire out); assign out en ? in : 1bz; endmoduleen1时输出inen0时释放输出为z。z不是0而是“不驱动”。两个模块同时驱动同一根线且输出相反值会产生冲突。FPGA内部的三态描述通常会被综合为选择逻辑真正的三态电气接口主要位于芯片I/O。always *中漏掉else会形成锁存器例如只在ab时给c赋值其他情况c必须记住旧值。普通与门应直接写assign cab;或完整的if/else。