FPGA 101 : Combinational Logic

Introduction

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.

Multiplexer

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;

Multiplexer Symbol

Encoder

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

Encoder Symbol

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;

 

Spread the word. Share this post!

Leave a comment

Your email address will not be published. Required fields are marked *