VHDLwhiz

How to use Signed and Unsigned in VHDL

The signed and unsigned types in VHDL are bit vectors, just like the std_logic_vector type. The difference is that while the std_logic_vector is great for implementing data buses, it’s useless for performing arithmetic operations.

If you try to add any number to a std_logic_vector type, ModelSim will produce the compilation error: No feasible entries for infix operator “+” . This is because the compiler doesn’t know how to interpret this collection of bits that the vector is.

This blog post is part of the Basic VHDL Tutorials series.

We must declare our vector as signed or unsigned for the compiler to treat it as a number.

The syntax for declaring signed and unsigned signals is:

Just like with std_logic_vector, the ranges can be to or downto any range. But declaring signals with other ranges than downto 0 is so uncommon, that spending any more time on the subject would only serve to confuse us. The initial value is optional, by default it’s 'U' for all bits.

We have already been using the integer type for arithmetic operations in previous tutorials. So why do we need the signed and unsigned types? For most, digital designers like to have more control of how many bits a signal actually uses.

Also, signed and unsigned values wrap around, while the simulator will throw a run-time error if an integer is incremented beyond bounds. Finally, signed and unsigned can have other values like 'U' and 'X' , while integers can only have number values. These meta-values can help us discovering errors in our design.

In this video we learn how signed and unsigned signals behave alike, and how they behave differently:

The final code we created in this tutorial:

The waveform window in ModelSim, zoomed in on the interesting parts:

signed_unsigned_waveform

Let me send you a Zip with everything you need to get started in 30 seconds

Unsubscribe at any time

The radix of all signals in the waveform are set to hexadecimal so that we can compare them equally.

In the wrapping counter example, we see that the signed and unsigned signals behave exactly the same way. Both UnsCnt and SigCnt start at 0, and are incremented one-by-one up to FF. Hex FF (decimal 255) is the largest value our 8-bit signals can hold. Therefore, the next increment wraps both of them back to 0.

We created the two 4-bit signals Uns4 and Sig4 , and gave them both an initial value of “1000”. We can see from the waveform that they are both just hex 8 (binary 1000).

The last two 8-bit signals we created were Uns8 and Sig8 . We can see from the waveform that their initial values are 0, as one would expect. But from there, they behave differently! Apparently, signed and unsigned types made a difference when adding two signals of different lengths.

This is because of something known as sign extension . Adding positive or negative numbers stored in vectors of equal length, is the same operation in digital logic. This is because of how two’s complement works. If the vectors are of different lengths, the shortest vector will have to be extended.

The unsigned 4-bit binary number “1000” is decimal 8, while the signed 4-bit number “1000” is decimal -8. The “1” at the left-most place of the signed number indicates that this is a negative number. Therefore, the two 4-bit signals are sign extended differently by the compiler.

This is a visualization of how sign extension creates the differing values for the Uns8 and Sig8 signals:

Get exclusive access to exercises and answers!

  • Signals of signed and unsigned type are vectors that can be used in arithmetic operations
  • Signals of signed and unsigned type will overflow silently
  • Sign extension may create differing results for signed and unsigned types

Go to the next tutorial »

' src=

I’m from Norway, but I live in Bangkok, Thailand. Before I started VHDLwhiz, I worked as an FPGA engineer in the defense industry. I earned my master’s degree in informatics at the University of Oslo.

Similar Posts

How to create a clocked process in VHDL

How to create a clocked process in VHDL

The vast majority of VHDL designs uses clocked logic, also known as synchronous logic or sequential logic. A clocked process is triggered only by a master clock signal, not when any of the other input signals change. The basic building block of clocked logic is a component called the flip-flop. There are different variants of…

How to create a concurrent statement in VHDL

How to create a concurrent statement in VHDL

A concurrent statement in VHDL is a signal assignment within the architecture, but outside of a normal process construct. The concurrent statement is also referred to as a concurrent assignment or concurrent process. When you create a concurrent statement, you are actually creating a process with certain, clearly defined characteristics. Concurrent statements are always equivalent…

How to delay time in VHDL: Wait For

How to delay time in VHDL: Wait For

In the previous tutorial we learned that a process can be thought of as a program thread. We also learned that a wait; statement causes the program to pause indefinitely. But is there a way to make a program wait for any other time value than forever? If we remove the wait; altogether and try…

Formal verification in VHDL using PSL

Formal verification in VHDL using PSL

When designing VHDL for safety-critical FPGA applications, it’s not enough to write testbenches at best-effort. You have to present proof that the module works as intended and without undesirable side-effects. Formal verification techniques can help you map a requirement to a test, proving that your VHDL module conforms to the specification. It’s an instrumental tool…

How to stop simulation in a VHDL testbench

How to stop simulation in a VHDL testbench

How do you stop the VHDL simulator when the simulation is complete? There are several ways to do that. In this article, we will examine the most common ways to end a successful testbench run. The VHDL code presented here is universal, and it should work in any capable VHDL simulator. For the methods involving…

How to use Wait On and Wait Until in VHDL

How to use Wait On and Wait Until in VHDL

In the previous tutorial we learned the main differences between signals and variables. We learned that signals have a broader scope than variables, which are only accessible within one process. So how can we use signals for communication between several processes? We have already learned to use wait; to wait infinitely, and wait for to…

I am confused by the article. To quote your text,

“The unsigned 4-bit binary number “1000” is decimal 8, while the signed 4-bit number “1000” is decimal -4”

Seems to me that “1000” in signed 2’s complement would be -8, not -4…right?

You are correct! I changed the text to -8 now. Fortunately I said -8 in the video 🙂 Thank you for pointing that out.

Thank you Jonas very much for your informative article! Perhaps you could also comment on this approach?

With those in place we can do arithmetic and comparisons on std_logic_vectors directly. For example:

There is one disadvantage that all signals in the same file will be treated as signed or unsigned. Perhaps this approach is not the best way in any case.

Your comment got me thinking about these packages. Even though I’ve been aware of them for quite some time, I don’t recall seeing them used in any projects which I have participated in. Why is that?

I believe this article by Sigasi sums up the main reason: https://insights.sigasi.com/tech/deprecated-ieee-libraries/

The packages are vendor specific extensions, and not really part of the IEEE library.

Even though you save time by implicitly casting the std_logic_vector, I’m not convinced that it will be and advantage in the long run. It becomes difficult for other developers to jump in and understand what the code does.

You would have to look at the imports in the head of the file to see what your code line does. If the std_logic_unsigned is imported, the result may be something else than if std_logic_signed was used. I find it confusing, but that’s just my personal opinion.

Thank you Jonas, I agree with you.

Hello mr Jensen , thank you for all the materials which are huge help. Got one question, How can we determine some bits of an unsigned signal? for example:

But how about “0100”? is there any way to alter desired bits without writing the whole string? Gets difficult when width of signals isn’t a small integer!

Sure, you can achieve that like this:

The range of values for signed 8 bit variable is given by the formula -2^(n-1) to 2^(n-1) – 1, n = 8 = -2^7 to 2^7 -1 = -128 to 127.

The range of values for unsigned 8 bit variable is given by the formula 2(^n) – 1, n = 8 = 2^8 -1 = 256.

For the counter of data type unsigned initialized to zero, the maximum count values is 0xff = 256 For the counter of data type signed initialized to zero, the maximum count value is 0x7f = 127

Do you agree?

Br, Lawrence

This statement is correct for signed types: -2^(n-1) to 2^(n-1) – 1, n = 8 = -2^7 to 2^7 -1 = -128 to 127.

However, the range for unsigned will be 0 to 2^8 -1 = 255 (I’m sure you meant to write 255 and not 256 since you got the formula right).

VHDL signals always default to the leftmost value if you don’t initialize them. For std_logic, which is based on the enumerated type std_ulogic, this is the ‘U’ value.

However, the signed VHDL type is an array of std_logic’s. Therefore, the default initial value of a signed in VHDL isn’t a numeric value. It’s an array of ‘U’s.

Integers, on the other hand, behave as you were thinking the signed would. But the caveat is that it depends on which direction (to/downto) you gave the integer signal or variable when declaring it.

These are some examples of initial/default values:

I know it seems confusing, but it really isn’t. You just have to remember that the default initial value will always be the leftmost possible value of your type, regardless if it’s declared using “to” or “downto” direction.

Leave a Reply Cancel reply

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

Notify me of replies to my comment via email

Dot Matrix VHDL and FPGA Course

This is the most extensive course VHDLwhiz has ever made.

VHDL Expressions Clarification

Understanding VHDL Expressions: Clarification on R and L assignment

Abstract: In this article, we aim to clarify the uncertain behavior of the following VHDL expressions involving std_logic_vector and unsigned literals: R

Understanding VHDL Expressions: Clarification on R <= (&0) - 1; L <= 1 - (&0);

VHDL (VHSIC Hardware Description Language) is a hardware description and design concurrency language used to model, design, and document electronic systems. One of the key aspects of VHDL is the use of expressions to describe assignments, operations, and relationships between signals or variables. In this article, we will clarify the concepts related to VHDL expressions and the assignment operations mentioned in the question.

VHDL Expressions

In VHDL, expressions are used to describe operations between values, signals, or variables. Expressions can be of various types, including arithmetic, relational, logical, and conditional.

Arithmetic Expressions

Arithmetic expressions involve operators that perform mathematical operations on numeric values, signals, or variables. The operators include +, -, *, /, MOD, REM, ABS, NOT, and ** (exponentiation).

Relational Expressions

Relational expressions compare two values, signals, or variables and return a Boolean result (TRUE or FALSE). The operators include =, /=, <, <=, >, and >=.

Logical Expressions

Logical expressions perform Boolean operations on Boolean values, signals, or variables. The operators include AND, OR, NAND, NOR, XOR, and XNOR.

Conditional Expressions

Conditional expressions evaluate an expression based on a condition. If the condition is TRUE, the expression returns one value; otherwise, it returns another value. The syntax is as follows:

(condition'event and condition = '1') or (condition'last_event and condition = '0')

Assignment Operations

In VHDL, there are two types of assignment operations: simple and conditional.

Simple Assignment

The simple assignment operator (<=) is used to assign a value, signal, or variable to another signal or variable. The syntax is as follows:

target_signal <= expression;

Conditional Assignment

Conditional assignment is used to assign a value, signal, or variable to another signal or variable based on a condition. The syntax is as follows:

target_signal <= expression when condition else expression;

Question Clarification

The question mentions the following operations:

R <= (&0) - 1; L <= 1 - (&0);

In this case, (&0) is a function call to the NOT operator, which negates the value of the input. Therefore, (&0) returns 1 if the input is 0 and 0 if the input is 1.

In the first line, R is assigned the value of (&0) - 1, which is 0 if the input is 0 and -1 if the input is 1.

In the second line, L is assigned the value of 1 - (&0), which is 1 if the input is 0 and 0 if the input is 1.

  • VHDL is a hardware description and design concurrency language used to model, design, and document electronic systems.
  • VHDL expressions are used to describe operations between values, signals, or variables.
  • Arithmetic, relational, logical, and conditional expressions are the main types of expressions in VHDL.
  • Simple and conditional assignments are used to assign values, signals, or variables to other signals or variables.
  • The question mentions the operations R <= (&0) - 1; L <= 1 - (&0);, where (&0) is a function call to the NOT operator.
  • IEEE Std 1076-2008, IEEE Standard VHDL Language Reference Manual.
  • Ashenden, P. (2010). The Designer's Guide to VHDL. Morgan Kaufmann.
  • Pongelli, D. (2018). VHDL Programming. Packt Publishing.

Tags: :  VHDL Digital Logic Compiler Interpretation

Latest news

  • Efficiently Handling Chat History in Gemini 1.0 Pro with Latest Version
  • Making TypeKeys Another Type: Handling New Keys with throw error
  • Pygame Mod Plug: Load Failed - 'Isnotworking??' - Troubleshooting
  • Differences in FCM Notification Behavior in App Foreground and Background Modes
  • Formatting Django in IOSSafari for Search Bar
  • Managing Native Binaries in NPM Packages: Platform-Specific Dependencies
  • Streamlining Stripe Account Onboarding with API and MCC Codes
  • Debugging Radare2: Print Data Pointer with Offset
  • Calculating Standard Deviation Distribution in Software Development
  • Adding Simple Attributes to Users in OpenLDAP using LDIF/LDAP Modify
  • Python-jinja2: Template Syntax Error with Print Statements in Character Creator TTRPG
  • Designing Data Structures: Choosing Technologies for Reporting Multiple Applications
  • Intercepting Requests with Burp Suite in Chrome on MacOS
  • Mastering Weka with Large Datasets: 14k Instances and 70 Attributes
  • Sum of C5, C6, B4, and B5 in Specific Rows from Dec 23, Nov 24
  • Customizing Grafana: Add Vertical Line and Background Color for Specified Duration in Time Series Panels with InfluxDB
  • Live Preview and Real-Time Execution in Eclipse IDE: A VSCode Equivalent
  • Understanding ApplicativeError and MonadError in Software Development
  • Splitting a Long-Running Feature Branch into Two: Best Practices
  • Incorporating Residual Variance Predictions in MGCV's gam() Function
  • Creating Custom 'CardControls' Pages with Banno's Digital Toolkit
  • Digital Signing of PDF Files using PowerShell: A Simple Tool
  • Saving Microsoft Authentication Requests in JMeter: A Workaround for har File and Dynamic Values
  • Making a Difference: Initializing Google Tag Manager GAU Property vs. GA4 Measurement ID
  • Creating an Infrastructure Pipeline with Terraform and Jenkins: Initializing Terraform in a Jenkins Pipeline
  • Resolving Issue with Authentication using Twitter APIv2 Endpoints: Error 403 Forbidden
  • Securing MQTT Websocket Connections with Self-Signed Certificates
  • Configuring env-vars for R Studio Server users on RHEL8 with SystemD
  • Real-Time City, State, Country Fetching with Top Notch Moving Services
  • Transferring Solana Tokens Between Two Wallets using Python
  • Building Docker Container for R Shiny App: TinyTeX Not Connecting to CTAN Mirrors during Docker Build
  • Making MUI5 PIE Chart Behave: Display Legend Items
  • Creating Colored Cleveland Dotplots with Identity-Based Coloring for Larger Values
  • Preventing a Persistent Stop Message in Terminal Output
  • Understanding Unsafe Assignment of 'value' in TypeScript

Designing Circuits with VHDL

1. introduction, 2. combinational circuits, signal assignments in vhdl.

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity fullAdder is     port(  A,B: in  std_logic;  -- input bits for this stage            Ci:   in  std_logic; -- carry into this stage            S:    out std_logic; -- sum bit            Co:   out std_logic  -- carry out of this stage     ); end fullAdder; architecture a1 of fullAdder is begin     S <= A xor B xor Ci;     Co <= (A and B) or ((A xor B) and Ci); end a1;

Processes and Conditional Statements

if a = '0' then     x <= a;     y <= b; elsif a = b then     x <= '0';   y <= '1'; else     x <= not b; y <= not b; end if;
Every signal that is assigned a value inside a process must be defined for all possible conditions.

Case Statements

Structural vhdl, 3. sequential circuits.

vhdl unsigned assignment

busy   is high when the circuit is in the middle of performing an operation;             while busy is high, the insert and delete inputs are ignored; the             outputs are not required to have the correct values when busy is high empty     is high when there are no pairs stored in the priority queue; delete             operations are ignored in this case full      is high when there is no room for any additional pairs to be stored;             insert operations are ignored in this case
  • For adjacent pairs in the bottom row, the pair to the left has a key that is less than or equal to that of the pair on the right.
  • For pairs that are in the same column, the key of the pair in the bottom row is less than or equal to that of the pair in the top row.
  • In both rows, the empty blocks (those with dp =0) are to the right and either both rows have the same number of empty blocks or the top row has one more than the bottom row.
entity priQueue is     Port (clk, reset : in std_logic;           insert, delete : in std_logic;           key, value : in std_logic_vector(wordSize-1 downto 0);           smallValue : out std_logic_vector(wordSize-1 downto 0);           busy, empty, full : out std_logic     );    end priQueue; architecture a1 of priQueue is constant rowSize: integer := 4; -- local constant declaration type pqElement is record     dp: std_logic;     key: std_logic_vector(wordSize-1 downto 0);     value: std_logic_vector(wordSize-1 downto 0); end record pqElement; type rowTyp is array(0 to rowSize-1) of pqElement; signal top, bot: rowTyp; type state_type is (ready, inserting, deleting); signal state: state_type; begin     process(clk) begin         if rising_edge(clk) then             if reset = '1' then                 for i in 0 to rowSize-1 loop                     top(i).dp <= '0'; bot(i).dp <= '0';                 end loop;                 state <= ready;             elsif state = ready and insert = '1' then                 if top(rowSize-1).dp /= '1' then                     for i in 1 to rowSize-1 loop                         top(i) <= top(i-1);                     end loop;                     top(0) <= ('1',key,value);                     state <= inserting;                 end if;             elsif state = ready and delete = '1' then                 if bot(0).dp /= '0' then                     for i in 0 to rowSize-2 loop                         bot(i) <= bot(i+1);                     end loop;                     bot(rowSize-1).dp <= '0';                     state <= deleting;                 end if;             elsif state = inserting or state = deleting then                 for i in 0 to rowSize-1 loop                     if top(i).dp = '1' and                         (top(i).key < bot(i).key                          or bot(i).dp = '0') then                         bot(i) <= top(i); top(i) <= bot(i);                     end if;                end loop;                 state <= ready;             end if;         end if;     end process;     smallValue <= bot(0).value when bot(0).dp = '1' else                   (others => '0');     empty <= not bot(0).dp;     full <= top(rowSize-1).dp;     busy <= '1' when state /= ready else '0'; end a1;

4. Functions and Procedures

package commonConstants is     constant lgWordSize: integer := 4;        constant wordSize: integer := 2**lgWordSize; end package commonConstants; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.commonConstants.all; entity firstOne is     Port (a: in std_logic_vector(0 to wordSize-1);           x: out std_logic_vector (lgWordSize downto 0)      ); end firstOne; architecture a1 of firstOne is procedure encode(x: in std_logic_vector(0 to wordSize-1);                 indx: out std_logic_vector(lgWordSize-1 downto 0);                 errFlag: out std_logic) is -- Unary to binary encoder. -- Input x is assumed to have at most a single 1 bit. -- Indx is equal to the index of the bit that is set. -- If no bits are set, errFlag bit is made high. -- This is conceptually simple. -- --        indx(0) is OR of x(1),x(3),x(5), ... --        indx(1) is OR of x(2),x(3), x(6),x(7), x(10),x(11), ... --        indx(2) is OR of x(4),x(5),x(6),x(7), x(12),x(13),x(14(,x(15),... -- -- but it's tricky to code so it works for different word sizes. type vec is array(0 to lgWordSize-1) of std_logic_vector(0 to (wordSize/2)-1); variable fOne: vec; variable anyOne: std_logic_vector(0 to wordSize-1); begin     -- fOne(0)(j) is OR of first j bits in x1,x3,x5,...     -- fOne(1)(j) is OR of first j bits in x2,x3, x6,x7, x10,x11,...     -- fOne(2)(j) is OR of first j bits in x4,x5,x6,x7, x12,x13,x14,x15,...     for i in 0 to lgWordSize-1 loop         for j in 0 to (wordSize/(2**(i+1)))-1 loop                        for h in 0 to (2**i)-1 loop                 if j = 0 and h = 0 then                     fOne(i)(0) := x(2**i);                 else                     fOne(i)((2**i)*j+h) := fOne(i)((2**i)*j+h-1) or                                            x(((2**i)*(2*j+1))+h);                 end if;             end loop;         end loop;         indx(i) := fOne(i)((wordSize/2)-1);     end loop;     anyOne(0) := x(0);     for i in 1 to wordSize-1 loop         anyOne(i) := anyOne(i-1) or x(i);     end loop;     errFlag := not anyOne(wordSize-1); end procedure encode; function firstOne(x: std_logic_vector(0 to wordSize-1))                         return std_logic_vector is -- Returns the index of the first 1 in bit string x. -- If there are no 1's in x, the value returned has a -- 1 in the high order bit. variable allZero: std_logic_vector(0 to wordSize-1); variable fOne: std_logic_vector(0 to wordSize-1); variable rslt: std_logic_vector(lgWordSize downto 0); begin     allZero(0) := not x(0);     fOne(0) := x(0);     for i in 1 to wordSize-1 loop         allZero(i) := (not x(i)) and allZero(i-1);         fOne(i) := x(i) and allZero(i-1);     end loop;     encode(fOne,rslt(lgWordSize-1 downto 0),rslt(lgWordSize));     return rslt; end function firstOne; begin     x <= firstOne(a); end a1;

5. Closing Remarks

VHDL Logical Operators and Signal Assignments for Combinational Logic

In this post, we discuss the VHDL logical operators, when-else statements , with-select statements and instantiation . These basic techniques allow us to model simple digital circuits.

In a previous post in this series, we looked at the way we use the VHDL entity, architecture and library keywords. These are important concepts which provide structure to our code and allow us to define the inputs and outputs of a component.

However, we can't do anything more than define inputs and outputs using this technique. In order to model digital circuits in VHDL, we need to take a closer look at the syntax of the language.

There are two main classes of digital circuit we can model in VHDL – combinational and sequential .

Combinational logic is the simplest of the two, consisting primarily of basic logic gates , such as ANDs, ORs and NOTs. When the circuit input changes, the output changes almost immediately (there is a small delay as signals propagate through the circuit).

Sequential circuits use a clock and require storage elements such as flip flops . As a result, changes in the output are synchronised to the circuit clock and are not immediate. We talk more specifically about modelling combinational logic in this post, whilst sequential logic is discussed in the next post.

Combinational Logic

The simplest elements to model in VHDL are the basic logic gates – AND, OR, NOR, NAND, NOT and XOR.

Each of these type of gates has a corresponding operator which implements their functionality. Collectively, these are known as logical operators in VHDL.

To demonstrate this concept, let us consider a simple two input AND gate such as that shown below.

The VHDL code shown below uses one of the logical operators to implement this basic circuit.

Although this code is simple, there are a couple of important concepts to consider. The first of these is the VHDL assignment operator (<=) which must be used for all signals. This is roughly equivalent to the = operator in most other programming languages.

In addition to signals, we can also define variables which we use inside of processes. In this case, we would have to use a different assignment operator (:=).

It is not important to understand variables in any detail to model combinational logic but we talk about them in the post on the VHDL process block .

The type of signal used is another important consideration. We talked about the most basic and common VHDL data types in a previous post.

As they represent some quantity or number, types such as real, time or integer are known as scalar types. We can't use the VHDL logical operators with these types and we most commonly use them with std_logic or std_logic_vectors.

Despite these considerations, this code example demonstrates how simple it is to model basic logic gates.

We can change the functionality of this circuit by replacing the AND operator with one of the other VHDL logical operators.

As an example, the VHDL code below models a three input XOR gate.

The NOT operator is slightly different to the other VHDL logical operators as it only has one input. The code snippet below shows the basic syntax for a NOT gate.

  • Mixing VHDL Logical Operators

Combinational logic circuits almost always feature more than one type of gate. As a result of this, VHDL allows us to mix logical operators in order to create models of more complex circuits.

To demonstrate this concept, let’s consider a circuit featuring an AND gate and an OR gate. The circuit diagram below shows this circuit.

The code below shows the implementation of this circuit using VHDL.

This code should be easy to understand as it makes use of the logical operators we have already talked about. However, it is important to use brackets when modelling circuits with multiple logic gates, as shown in the above example. Not only does this ensure that the design works as intended, it also makes the intention of the code easier to understand.

  • Reduction Functions

We can also use the logical operators on vector types in order to reduce them to a single bit. This is a useful feature as we can determine when all the bits in a vector are either 1 or 0.

We commonly do this for counters where we may want to know when the count reaches its maximum or minimum value.

The logical reduction functions were only introduced in VHDL-2008. Therefore, we can not use the logical operators to reduce vector types to a single bit when working with earlier standards.

The code snippet below shows the most common use cases for the VHDL reduction functions.

Mulitplexors in VHDL

In addition to logic gates, we often use multiplexors (mux for short) in combinational digital circuits. In VHDL, there are two different concurrent statements which we can use to model a mux.

The VHDL with select statement, also commonly referred to as selected signal assignment, is one of these constructs.

The other method we can use to concurrently model a mux is the VHDL when else statement.

In addition to this, we can also use a case statement to model a mux in VHDL . However, we talk about this in more detail in a later post as this method also requires us to have an understanding of the VHDL process block .

Let's look at the VHDL concurrent statements we can use to model a mux in more detail.

VHDL With Select Statement

When we use the with select statement in a VHDL design, we can assign different values to a signal based on the value of some other signal in our design.

The with select statement is probably the most intuitive way of modelling a mux in VHDL.

The code snippet below shows the basic syntax for the with select statement in VHDL.

When we use the VHDL with select statement, the <mux_out> field is assigned data based on the value of the <address> field.

When the <address> field is equal to <address1> then the <mux_out> signal is assigned to <a>, for example.

We use the the others clause at the end of the statement to capture instance when the address is a value other than those explicitly listed.

We can exclude the others clause if we explicitly list all of the possible input combinations.

  • With Select Mux Example

Let’s consider a simple four to one multiplexer to give a practical example of the with select statement. The output Q is set to one of the four inputs (A,B, C or D) depending on the value of the addr input signal.

The circuit diagram below shows this circuit.

This circuit is simple to implement using the VHDL with select statement, as shown in the code snippet below.

VHDL When Else Statements

We use the when statement in VHDL to assign different values to a signal based on boolean expressions .

In this case, we actually write a different expression for each of the values which could be assigned to a signal. When one of these conditions evaluates as true, the signal is assigned the value associated with this condition.

The code snippet below shows the basic syntax for the VHDL when else statement.

When we use the when else statement in VHDL, the boolean expression is written after the when keyword. If this condition evaluates as true, then the <mux_out> field is assigned to the value stated before the relevant when keyword.

For example, if the <address> field in the above example is equal to <address1> then the value of <a> is assigned to <mux_out>.

When this condition evaluates as false, the next condition in the sequence is evaluated.

We use the else keyword to separate the different conditions and assignments in our code.

The final else statement captures the instances when the address is a value other than those explicitly listed. We only use this if we haven't explicitly listed all possible combinations of the <address> field.

  • When Else Mux Example

Let’s consider the simple four to one multiplexer again in order to give a practical example of the when else statement in VHDL. The output Q is set to one of the four inputs (A,B, C or D) based on the value of the addr signal. This is exactly the same as the previous example we used for the with select statement.

The VHDL code shown below implements this circuit using the when else statement.

  • Comparison of Mux Modelling Techniques in VHDL

When we write VHDL code, the with select and when else statements perform the same function. In addition, we will get the same synthesis results from both statements in almost all cases.

In a purely technical sense, there is no major advantage to using one over the other. The choice of which one to use is often a purely stylistic choice.

When we use the with select statement, we can only use a single signal to determine which data will get assigned.

This is in contrast to the when else statements which can also include logical descriptors.

This means we can often write more succinct VHDL code by using the when else statement. This is especially true when we need to use a logic circuit to drive the address bits.

Let's consider the circuit shown below as an example.

To model this using a using a with select statement in VHDL, we would need to write code which specifically models the AND gate.

We must then include the output of this code in the with select statement which models the multiplexer.

The code snippet below shows this implementation.

Although this code would function as needed, using a when else statement would give us more succinct code. Whilst this will have no impact on the way the device works, it is good practice to write clear code. This help to make the design more maintainable for anyone who has to modify it in the future.

The VHDL code snippet below shows the same circuit implemented with a when else statement.

Instantiating Components in VHDL

Up until this point, we have shown how we can use the VHDL language to describe the behavior of circuits.

However, we can also connect a number of previously defined VHDL entity architecture pairs in order to build a more complex circuit.

This is similar to connecting electronic components in a physical circuit.

There are two methods we can use for this in VHDL – component instantiation and direct entity instantiation .

  • VHDL Component Instantiation

When using component instantiation in VHDL, we must define a component before it is used.

We can either do this before the main code, in the same way we would declare a signal, or in a separate package.

VHDL packages are similar to headers or libraries in other programming languages and we discuss these in a later post.

When writing VHDL, we declare a component using the syntax shown below. The component name and the ports must match the names in the original entity.

After declaring our component, we can instantiate it within an architecture using the syntax shown below. The <instance_name> must be unique for every instantiation within an architecture.

In VHDL, we use a port map to connect the ports of our component to signals in our architecture.

The signals which we use in our VHDL port map, such as <signal_name1> in the example above, must be declared before they can be used.

As VHDL is a strongly typed language, the signals we use in the port map must also match the type of the port they connect to.

When we write VHDL code, we may also wish to leave some ports unconnected.

For example, we may have a component which models the behaviour of a JK flip flop . However, we only need to use the inverted output in our design meaning. Therefore, we do not want to connect the non-inverted output to a signal in our architecture.

We can use the open keyword to indicate that we don't make a connection to one of the ports.

However, we can only use the open VHDL keyword for outputs.

If we attempt to leave inputs to our components open, our VHDL compiler will raise an error.

  • VHDL Direct Entity Instantiation

The second instantiation technique is known as direct entity instantiation.

Using this method we can directly connect the entity in a new design without declaring a component first.

The code snippet below shows how we use direct entity instantiation in VHDL.

As with the component instantiation technique, <instance_name> must be unique for each instantiation in an architecture.

There are two extra requirements for this type of instantiation. We must explicitly state the name of both the library and the architecture which we want to use. This is shown in the example above by the <library_name> and <architecture_name> labels.

Once the component is instantiated within a VHDL architecture, we use a port map to connect signals to the ports. We use the VHDL port map in the same way for both direct entity and component instantiation.

Which types can not be used with the VHDL logical operators?

Scalar types such as integer and real.

Write the code for a 4 input NAND gate

We can use two different types of statement to model multiplexors in VHDL, what are they?

The with select statement and the when else statement

Write the code for an 8 input multiplexor using both types of statement

Write the code to instantiate a two input AND component using both direct entity and component instantiation. Assume that the AND gate is compiled in the work library and the architecture is named rtl.

Leave a Reply Cancel reply

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

Save my name, email, and website in this browser for the next time I comment.

Table of Contents

Sign up free for exclusive content.

Don't Miss Out

We are about to launch exclusive video content. Sign up to hear about it first.

GitHub

Variables – VHDL Example

Variables in VHDL act similarly to variables in C. Their value is valid at the exact location in the code where the variable is modified. Therefore, if a signal uses the value of the variable before the assignment , it will have the old variable value. If a signal uses the value of the variable after the assignment it will have the new variable value.

Rules of Variables:

  • Variables can only be used inside processes
  • Any variable that is created in one process cannot be used in another process
  • Variables need to be defined after the keyword process but before the keyword begin
  • Variables are assigned using the := assignment symbol
  • Variables that are assigned immediately take the value of the assignment

The most important thing to understand is that variables immediately take the value of their assignment. Here’s an example that shows one useful way to use variables: storing data for temporary use . It uses a case statement and the ampersand (&) concatenation operator .

In the previous example, we concatenated the two signals so that they could be used in the case statement. The variable v_Choices was immediately available for use as soon as it was assigned. Let’s look at another example. The example below is more comprehensive and demonstrates how variables immediately take the value of their assignment. The signals r_Var_Copy1 and r_Var_Copy2 appear to be the same, but r_Var_Copy2 is never able to get to 5 before it is reset.

In order to simulate our design, we need to create a testbench . Also, variables can be a bit tricky to display in simulation. If you are using Modelsim, read more about how to see your variables in Modelsim’s waveform window .

The example above demonstrates how variables act differently from signals. The signals r_Var_Copy1 and r_Var_Copy2 appear to be the same, but r_Var_Copy2 is never able to get to 5 before it is reset.

Read more about how variables and signals are different

Learn Verilog

Leave A Comment Cancel reply

Save my name, email, and website in this browser for the next time I comment.

404 Not found

vhdl unsigned assignment

jliu83 (Member) asked a question.

  • process ( clk ) begin
  • if rising_edge ( clk ) then
  • -- multiply , truncate then assign
  • res <= ( a * b )( 15 downto 8 );
  • end process ;
  • General Discussion

vhdl unsigned assignment

hgleamon1 (Member)

jliu83 (Member)

vhdl unsigned assignment

bassman59 (Member)

> -------------------------------------------------------------------------------- > > @jliu83 wrote: > > > Hi, I was wondering if anyone with a greater understanding of VHDL syntax can > help me with this. > >   > > I am using "use IEEE.std_logic_unsigned.all;" so that all my > STD_LOGIC_VECTOR's are treated as unsigned numbers. > >   > > --------------------------------------------------------------------------------

That's a mistake.

> -------------------------------------------------------------------------------- > > @jliu83 wrote: > > > Thank you.  I guess a few extra registers in the pipeline doesn't hurt.  On > the subject of the libraries, numeric_std would require manual casting of all > incoming signals from vectors to unsigned.  Any tricks around this tedious > task?  If doing something like bicubic interpolation, that's a lot of casts > (to and from unsigned). > >   > > -J > > --------------------------------------------------------------------------------

The simple answer is that ports don't need to be std_logic_vector. You can declare ports as unsigned or signed. It works. Keep the signals as unsigned throughout the design.

Related Questions

Community Feedback?

IMAGES

  1. How to use Signed and Unsigned in VHDL

    vhdl unsigned assignment

  2. How to use Signed and Unsigned in VHDL

    vhdl unsigned assignment

  3. Signed vs. Unsigned

    vhdl unsigned assignment

  4. VHDL Type Conversion

    vhdl unsigned assignment

  5. PPT

    vhdl unsigned assignment

  6. Review of VHDL Signed/Unsigned Data Types

    vhdl unsigned assignment

VIDEO

  1. Rhett Butler

  2. Student Project 1 FPGA Shift Register with LPMs and VHDL

  3. 62. VHDL Structural Modeling

  4. 7 segment display using VHDL programming

  5. VHDL concurrent

  6. VhDL VGA assignment(2)

COMMENTS

  1. unsigned integer

    7. I'm trying to use unsigned integers in VHDL with well defined bit widths. It seems VHDL does not like me trying to assign literal values to these types defined as: variable LCD_DATA: unsigned(19 downto 0) := 0; But in my IDE (Quartus), I get a complaint "UNSIGNED type does not match integer literal." I also get complaints for adding numbers ...

  2. How to use Signed and Unsigned in VHDL

    We must declare our vector as signed or unsigned for the compiler to treat it as a number. The syntax for declaring signed and unsigned signals is: signal <name> : signed(<N-bits> downto 0) := <initial_value>; signal <name> : unsigned(<N-bits> downto 0) := <initial_value>; Just like with std_logic_vector, the ranges can be to or downto any ...

  3. Examples of VHDL Conversions

    Convert from Unsigned to Integer using Std_Logic_Arith. This is an easy conversion, all you need to do is use the conv_integer function call from std_logic_arith as shown below: signal input_7 : unsigned(3 downto 0); signal output_7 : integer; output_7 <= conv_integer(input_7); Convert from Unsigned to Signed using Std_Logic_Arith

  4. An Introduction to VHDL Data Types

    Signed and Unsigned VHDL Types. There are two more vector types which we often use in VHDL - signed and unsigned. In order to use these types, we need to include the numeric_std package from the standard ieee library. When we use the signed type, the data is interpreted as a 2's complement number. This is in contrast to the unsigned type which ...

  5. Review of VHDL Signed/Unsigned Data Types

    The "signed" and "unsigned" data types are defined in the numeric_std package. To use "signed" and "unsigned" data types, we need to include the following lines in our code: 1library ieee; 2use ieee.std_logic_1164.all; 3use ieee.numeric_std.all; Note that the "std_logic_1164" package is required because the "numeric_std ...

  6. Unsigned in VHDL

    Resizing, which adapt to argument as either signed or unsigned, can be used, but you need to resize before the addition in order to extend the result for the carry bit, as I assume is the intention. So generic and maintainable code may be like, where you may add a suitable comment to describe the purpose of the resizing:

  7. Signed vs. Unsigned

    What needs to be understood is that whether or not the signals are defined as signed or unsigned does not affect how the actual binary math is performed. For example: For two signed vectors 10001 + 00010 the answer is still 10011, BUT it's the interpretation of the result that is different. For the unsigned case, the answer (10011) represents 19.

  8. Assignment Symbol

    In VHDL there are two assignment symbols: <= Assignment of Signals. := Assignment of Variables and Signal Initialization. Either of these assignment statements can be said out loud as the word "gets". So for example in the assignment: test <= input_1; You could say out loud, "The signal test gets (assigned the value from) input_1.".

  9. Understanding VHDL Expressions: Clarification on R and L assignment

    In this article, we aim to clarify the uncertain behavior of the following VHDL expressions involving std_logic_vector and unsigned literals: R <= (&0) - 1; L <= 1 - (&0). We will discuss the potential issues and suggest alternative ways to write these expressions.

  10. VHDL: Setting upper bits of variable to zero during assignment with

    When one has something like . variable a : unsigned (3 downto 0); variable b : unsigned (1 downto 0); and one wants to assign the lower b'length bits of b to a, is it necesary to do . a)

  11. Designing Circuits with VHDL

    The signal assignments are only part of a VHDL specification. Here is the complete specification of the full adder. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity fullAdder is port( A,B: in std_logic; -- input bits for this stage Ci: in std_logic; -- carry into this stage

  12. VHDL Logical Operators and Signal Assignments for Combinational Logic

    The VHDL code shown below uses one of the logical operators to implement this basic circuit. and_out <= a and b; Although this code is simple, there are a couple of important concepts to consider. The first of these is the VHDL assignment operator (<=) which must be used for all signals.

  13. Variable

    Variables - VHDL Example. Variables in VHDL act similarly to variables in C. Their value is valid at the exact location in the code where the variable is modified. Therefore, if a signal uses the value of the variable before the assignment, it will have the old variable value.

  14. How to use Signed and Unsigned in VHDL

    The signed and unlocked types to VHDL are single vectors which can be used in calculations. They overflowed silently, and they get sign-extended to the compiler. ... Of signed furthermore unsigned types inside VHDL exist bit vectors, just like the std_logic_vector type. The difference is that while the std_logic_vector is great for implementing ...

  15. Assignment of partial vector using std_logic_unsigned.all, VHDL syntax

    process (clk) begin. if rising_edge(clk) then. --multiply, truncate then assign. res <= (a * b)(15 downto 8); end if; end process; Where res, a, b are all 8 bit wide std_logic_vectors. This would be very useful in multiplcations and additions since the number of bits grow all the time and would save a several lines of code, making the code ...

  16. What does "others=>'0'" mean in an assignment statement?

    The statement "Others => '0'" is a feature of the VHDL when the coder want to defined several items in an array with the same value. In your example, all item std_logic in the array are set to '0'. Another application of this statement is to set some items at a specific value and all others at a default value : cmd_r <= (0 => '1', 4 => '1',

  17. Concurrent Conditional and Selected Signal Assignment in VHDL

    Conditional Signal Assignment or the "When/Else" Statement. The "when/else" statement is another way to describe the concurrent signal assignments similar to those in Examples 1 and 2. Since the syntax of this type of signal assignment is quite descriptive, let's first see the VHDL code of a one-bit 4-to-1 multiplexer using the ...

  18. Assign values to an array partially in VHDL?

    1. I have an array in VHDL of the form, type CacheArray is array(0 to 15) of std_logic_vector(33 downto 0); signal cache_array: CacheArray := (others => (others => '0')); I wish to assign values to this array such that only one bit of each index is initialized. I suspected something like this will work,