Lecture 2
Code majority.vhdl
Class ObjectivesTT to VHDL, STD_LOGIC_VECTOR, Literals, when/else statement

VHDL

Your personality can be expressed through the code that you write. In lecture 1 we examined a structural method of describing a circuit; we transformed the circuit diagram into a textual description. Today we will examine another method of VHDL coding; behavioral.

Behavioral

A behavioral description of a component describes what the circuit does rather than how it is done. One way to do this is to encode the truth table for a circuit directly into VHDL code. You can do this by assigning the output signal a value using the when/else structure. The idea is that you assign the output signal a value when the input signals have a specific value. Since the input signals can be arranged in variety of ways, you may need to use the else clause to specify a different output value associated with a different input signal.

Let's look at a familiar example to see how this works, the 3-input majority circuit from lecture 1. Remember that this circuit outputs 1 when a majority of the three inputs are 1. In other words, when 2 or 3 of the inputs bits are 1, the output equals 1, else the output equals 0. The truth table for this circuit if given below.
a b c | f
------|--
0 0 0 | 0
0 0 1 | 0
0 1 0 | 0
0 1 1 | 1
1 0 0 | 0
1 0 1 | 1
1 1 0 | 1
1 1 1 | 1


The code snippet below uses this truth table to assign the output f a value using the multi-line when/else statement. I purposely structured this statement in the same row-order as the truth table. The first line of the when/else statement corresponds to the input a,b,c = 0,0,0. The last line of the when/else statement corresponds to the input a,b,c =1,1,1 because it was the only input combination not enumerated in the preceding 7-lines. The last line of a when/else should never be accompanied with a when statement . The reasons is because std_logic contains values beyond just 0 and 1 and as a consequence the last line of the when/else catches all these combinations of bit values not covered in the preceding when clauses. Notice that we need to put single quotes around the values of '0' and '1'. We'll come back to this.
------------------------------------------
-- Author:      Chris Coulston
-- Date:        Fall 2023
-- Purp:	Behavior Majority circuit
------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;

entity majority is
        port(	a, b, c	: in std_logic; 
		f	: out std_logic);
end majority;

architecture behavior of majority is

begin
	
	f <=	'0' when a='0' and b='0' and c='0' else
		'0' when a='0' and b='0' and c='1' else
		'0' when a='0' and b='1' and c='0' else
		'1' when a='0' and b='1' and c='1' else
		'0' when a='1' and b='0' and c='0' else
		'1' when a='1' and b='0' and c='1' else
		'1' when a='1' and b='1' and c='0' else
		'1';

end behavior;
The when/else statement in the architecture acts as a single concurrent signal assignment statements. Thus, this CSA acts in parallel with any other statements that might be in the architecture.

Now let's return to the discussion surrounding the single quotes around literals.

Literals

A literal are fixed values that cannot be modified. Things like number or ASCII strings are common examples that you may have seen in previous courses. In VHDL single bits are surrounded with single quotes symbol ' and groups of bits are surrounded with the double quotes symbol ". You can specify a radix for a group of bits in front.
	'0'		-- constant represents a single logic 0 bit
	"1010"		-- constant represents four bits, default radix is binary
	x"a"		-- constant represents for bits in hexadecimal

Vectors

So far, we have been dealing with individual bits with the datatype std_logic. While we could build almost any digital system with this datatype it would be laborious when we deal with multi-bit signals like the input and output from an adder circuit. So the creators of VHDL provide use with a datatype called std_logic_vector that allows us to manipulate a collection of signals using a single name, much like an array in a procedural programming language. When you want to use std_logic_vector you will need to Let's look at a couple of examples to see how they work.
architecture silly of vectorExample is

	signal a3: std_logic_vector(2 downto 0);
	signal b4: std_logic_vector(3 downto 0);
	signal c5: std_logic_vector(4 downto 0);
	signal x: std_logic;

begin

	a3 <= "101";
	x <= a3[2] and '1';
	b4 <= a3 & '1';
	c5 <= b4[3 downto 2] & a3[1 downto 0];

end silly;
The bits of a std_logic_vector are given indicies specified by the bounds specified in parenthesis. We will always specify the largest bit index first followed by downto and then the index 0. Thus, the std_logic_vector a3 is 3-bits wide with its bits indexed as 2, 1 and 0. Likewise b4 is 4-bits wide and c5 is 5-bits wide.

You can grab individual or groups of bits from a vector using the the square bracket operator and listing the bit index or subvector range inside. If you select an individual bit from a vector, then you can use this signal just like any std_logic signal, like as the input to an AND gate.

You can combine bits using the concatenation operator &. When you concatenate two signals, the signal on the left becomes the most significant bits of the result and the right signal forms the least significant bits of the result.

So what are the resulting values of the signals is the above code snippet? Try it by yourself first, then look at the HTML source code for the comment just below for the answers.

Majority Circuit

Let's re-imagine the architecture of the majority circuit from earlier using vectors. Let's take advantage of the concatenation operator to make a vector out of the inputs a,b,c. We can do this by creating a signal in the architecture and assigning it the concatenation of a,b and c. The when/else then uses this vector to streamline the code and make it more readable.
architecture behavior of majority is

	signal temp: std_logic_vector(2 downto 0);
begin
	
	temp <= a & b & c;
	f <=	'0' when temp = "000" else
		'0' when temp = "001" else
		'0' when temp = "010" else
		'1' when temp = "011" else
		'0' when temp = "100" else
		'1' when temp = "101" else
		'1' when temp = "110" else
		'1'; 
		
end behavior;

Don't cares in when/else statements

You can use don't cares in the when portion of a when/else statement to simply the logic and number of lines in the statement. If a bit of the input can equal 0 or 1 with no change in the output, you can replace that bit value with a don't care. The symbol for a don't care is the dash, -.

As an exercise, determine the truth table for the following when/else statement. The solutions are viewable in the page source as a comment.
	temp <= a & b & c;
	f <=	'1' when temp = "10-" else
		'1' when temp = "-10" else
		'0' when temp = "0-1" else
		'0' when temp = "00-" else
		'1'; 

Hex to Seven Segment converter

The hexadecimal-to-seven-segment-decoder is a combinational circuit that converts a 4-bit hexadecimal number to an appropriate code that drives a 7-segment display the corresponding value. Let's assume that the LEDs in our 7-segment display are active low, meaning that they illuminate when you send them a logic 0. The following shows the bit index for the individual segments of the 7-segment display. So in order to produce an illuminated pattern that looks like the number 4 we would have to send the 7-segment display the vector "0011001"


Now let's turn to writing the VHDL code for the hex2Seven component. Let's start with entity and describe the inputs and outputs. The input is 4-bits so we should make it a std_logic_vector(3 downto 0). I'd give the input a name like "hex" and the output "sevenSeg".

We will use an when/else statement to describe the behavior of the hex2Seven component. All we really need to know is the bit patterns needed to correctly illuminate the LEDs for each hex input. To help with this, I've included the expected output for each hex input.


If you still have your EENG 284 labs lying around, you will be able to look at the Verilog code for lab #2 to get the bit patterns for each input. I'd like you to try to write the code yourself using the provided code in this lecture note as a template. When you are complete, look at the source code for this web page to find the solution in the comments.