Combinational logic, normally refer to a group of digital circuit formed by basic gates like NAND, NOR , NOT, XNOR and etc to perform some logical function like adder, encoder, comparator and a lot more. Unlike flip-flop, they are time-independent and its output changes whenever the input(s) change to other state, at almost instantly.
Let’s get started with few examples.
Or mux, is a digital switch that outputs one signal from multiple inputs. In verilog, we can either use always block or simple assignment to model a multiplexer.
always@(sel) begin case(sel) 1'b0: output_mux = input_mux0; 1'b1: output_mux = input_mux1; default: output_mux = input_mux; endcase end /*or*/ assign output_mux = sel? input_mux1:input_mux0;
Encoder converts one-hot type inputs to binary outputs. It is usually a 2^n bits converter, like 8 to 3 encoder or 4 to 2 encoder. Encoder is a very important part for state-machine and it will impact frequency performance,Fmax if it did not properly code in state machine.
reg [3:0] input_encoder; reg [1:0] output_encoder; reg output_valid; always@(input_encoder) begin case(input_encoder) 4'b0001: begin output_encoder = 2'b00; output_valid = 1'b1; end 4'b0010: begin output_encoder = 2'b01; output_valid = 1'b1; end 4'b0100: begin output_encoder = 2'b10; output_valid = 1'b1; end 4'b1000: begin output_encoder = 2'b11; output_valid = 1'b1; end default: begin output_encoder = 2'b00; output_valid = 1'b0; end endcase end
Arithmetic and Logic Function
This includes adder, subtractor, multiplier, divider and comparator. But bear in mind FPGAs usually will instantiate DSP slices to help on multiply and division operation due to it is inefficient and cost a lot logic elements resources just to model multiplier and divider. We will discuss a simple trick to do multiplier and divider in later topic. And also, comparator should implement carefully since it costs hardware resources as well.
reg [7:0] reg_A; reg [7:0] reg_B; reg [8:0] reg_result; /*Adder*/ assign reg_result = reg_A + reg_B; /*substractor*/ assign reg_result = reg_A - reg_B; /*comparator*/ assign reg_result = (reg_A > reg_B)? 9'h055 : 9'h0FF; /*or*/ assign reg_result = (reg_A < reg_B)? 9'h0BE : 9'h0AF; /*or*/ assign reg_result = (reg_A == reg_B)? 9'h0DE : 9'h0AD;