Guide to VHDL for embedded software developers: Part 3 - ALU logic & FSMs

Peter Wilson

July 25, 2011

Peter WilsonJuly 25, 2011

Editor’s Note: In this series of articles based on his book – Design Recipes for FPGAs – Peter Wilson provides a basic quick overview of VHDL (VHSIC hardware description language) followed by examples of its use in describing - in HDL code form - functions familiar to most embedded software developers such as arithmetic logic units (ALUs) and finite state machines (FSMs). It is not intended as a comprehensive VHDL reference. For that, he recommends “Digital System Design with VHDL,” by Mark Zwolinski; ”VHDL: Analysis and modeling of digital systems,” by Zainalabedin Navabi or “Designer’s Guide to VHDL” by Peter Ashenden.

This third part in a series describes how low-level logic and arithmetic functions can be implemented in VHDL to build simple arithmetic logic units and finite state machines.

 

A central part of microprocessors is the ALU (Arithmetic Logic Unit). This block in a processor takes a number of inputs from registers and as its name suggests carries out either logic functions (such as NOT, AND, OR and XOR) on the inputs,or arithmetic functions (addition or subtraction as a minimum).

Logic functions
If we consider a simple inverter in VHDL, this takes a single input bit, inverts it and applies this to the output bit. This simple VHDL code sequence is shown below:

Library ieee;
Use ieee.std_logic_1164.all;
Entity inverter is
     Port (
          A : in std_logic;
          Q : out std_logic
     );
End entity inverter;
Architecture simple of inverter is
Begin
     Q <= NOT A;
End architecture simple;

Clearly the inputs and output are defined as single std_logic pins, with direction in and out respectively. The logic equation is also intuitive and straightforward to implement. We can extend this be applicable to n bit logic busses by changing the entity (the architecture remains the same) and simply assigning the input and outputs the type std_logic_vector instead of std_logic as follows:

Library ieee; Use ieee.std_logic_1164.all;
Entity bus_inverter is
    Port (
         A : in std_logic_vector(15 downto 0);
         Q : out std_logic_vector(15 downto 0)
    );
End entity bus_inverter;
Architecture simple of bus_inverter is
Begin
    Q <= NOT A;
End architecture simple;

As can be seen from the VHDL, we have defined a specific 16 bit bus in this example, and while this is generally fine for processor design with a fixed architecture, sometimes it is useful to have a more general case, with a configurable bus width. In this case we can modify the entity again to make the bus width a parameter of the model:

Library ieee;
Use ieee.std_logic_1164.all;
Entity n_inverter is
     Generic (
          N : natural := 16
     );
     Port (
          A : in std_logic_vector((n-1) downto 0);
          Q : out std_logic_vector((n-1) downto 0)
     );
End entity n_inverter;
Architecture simple of n_inverter is
Begin
     Q <= NOT A;
End architecture simple;

We can of course create separate models of this for m to implement multiple logic functions, but we can also create a compact multiple function logic block by using a set of configuration pins to define which function is required.

Table 3

If we define a general logic block that has 2 n-bit inputs (A & B), a control bus (S) and an n-bit output (Q), then by setting the 2 bit control word (S) we can select an appropriate logic function according to the Table 3 above.

< Previous
Page 1 of 5
Next >

Loading comments...

Parts Search Datasheets.com

KNOWLEDGE CENTER