Putting a 5-bit value to a byte in VHDL - Will this generate a latch? - byte

I have the following problem:
I have an adder whose output has 5 bits. I want to send this output to an 8-bit register.
I've declared the register input signal as tot_sig, and the adder output as add_out. Both the register and the adder are declared as separate components in my entity.
In the adder port map, I've tried to write the following:
add_out => tot_sig(4 downto 0)
But that won't work (ISE tells me that tot_sig and add_out have different sizes).
So I tought of declaring 2 signals, which would be the same thing, but in different sizes. I would first declare a signal called intermediary, which would be an 4-bit bus. Then, I would be adding the intermediary to an (initially set as "00000000") byte (total_sig). Then the total_sig byte would be connected at the input of the register.
I am worried that this may generate a latch. Can it? I tried thinking of simpler solutions but couldn't arrive to any.
Any solution that could work without the necessity of declaring another signal would be nicer.
Thank you for your help and time.
I am using Xilix ISE Design Suite version 14.6.

The simple solution is to define an 8-bit vector an concatenate 3 zeros when assigning a 5-bit vector to it:
signal len5 : std_logic_vector (4 down to 0);
signal len8 : std_logic_vector (7 down to 0);
len8 <= "000" & len5;
-- Now you can pass len8 into an 8-bit port.
You do not get a latch. Latches only appear when you use a condition outside a clocked process and you have unresolved branches.
e.g. an if with no else or a case with not all possibilities covered.

Related

how to use the force command with a type unsigned(n downto 0) in modelsim when simulating a VHDL file?

When initializing inputs for a test, as I understand, you have to use the force command. For example to create a clock cycle, counting that the entity I'm simulating has an input named clock, which is of type std_logic, I would usually write
force clock 0 0, 1 1 -repeat 2
in thee terminal of modelsim
how can I do something similar but with the type unsigned(8 downto 0) for example?

Vhdl signal declaration usage

I am a beginner in vhdl with not much grasp on signal.
My understanding is you can assign signal value such as
signal<='100' but you don't have to declare it. Is that correct?
Also, for sign extension ext_imme<=(31 downto 16=> imme(15)) & imme; why would this work for extending 16 bit to 32 bit by repeating imme(15) twice?
1) You can not assign signal value such as signal<='100' without declaring it it. You are not correct.
VHDL doesn't like surprises. Everything always must be declared before you use it.
So, you must declare a signal (in the declarative region of the architecture, ie between architecture and begin):
architecture SOME_NAME of SOME_OTHER_NAME is
-- declare signals (and other things) here, eg
signal SOME_SIGNAL_NAME : std_logic; -- or some other type
begin
You can also initialise signals when you declare them, but I would be very careful doing this if you intend to synthesise the code, eg:
signal SOME_SIGNAL_NAME : std_logic := '0';
2) This ext_imme<=(31 downto 16=> imme(15)) & imme is an example of an aggregate and a concatenation. An aggregate is a way of assigning to the elements of an array. A concatenation is a way of joining two arrays together to make a bigger array.
In your example, this is the aggregate: (31 downto 16=> imme(15)). Here you are making bits 31 down to 16 equal to bit 15 of imme. This gives you 16 bits all equal to bit 15 of imme.
The '&' operation is the concatenation operator. In your example, you are joining the 16 bits of the aggregate to the 16 bits of imme to make 32 bits in total.
Here some other examples of using aggregates: http://www.edaplayground.com/x/CQm.

Design of MAC unit (dsp processors) using VHDL

My project is design of 32bit MAC(Multiply and Accumlate) unit using reversible logic. For the project , i have designed 32bit mulitplier and 64 bit adder using reversible logic. Now, in the next step i want to design a 64 bit accumlator which takes the value from the adder and stores it and adds with the previous value present in it. I am not getting any idea how to design Accumlator.
Please help in completion of my project.
A basic VHDL accumulator can be implemented in only a few lines of code. How you decide to implement it, and any additional features necessary are going to depend on your specific requirements.
For example:
Are the inputs signed or unsigned?
What is the type of the inputs?
Does the accumulator saturate, or will it roll over?
Here is a sample unsigned accumulator to give you an idea of what you need to implement (based on this source):
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity accumulator is
port (
DIN: in std_logic_vector(3 downto 0);
CLK: in std_logic;
RST: in std_logic;
DOUT: out std_logic_vector(3 downto 0)
);
end entity accumulator;
architecture behave of accumulator is
signal acc_value : std_logic_vector(3 downto 0);
begin
process(CLK)
begin
if rising_edge(CLK) then
if RST='1' then
acc_value <= (others => '0'); -- reset accumulated value to 0
else
acc_value <= std_logic_vector( unsigned(acc_value) + unsigned(DIN) );
end if;
end if;
end process;
-- Assign output
DOUT <= acc_value;
end behave;
To describe what this design does in words: Every clock cycle on the rising edge, the data input DIN is interpreted as an unsigned value, and added to the currently accumulated value acc_value. If the RST input is asserted, instead of accumulating the DIN input, the accumulated value is cleared back to 0. The value of the accumulator is always presented on the output of the block, DOUT.
Based on what you are interfacing with, you might want to consider the following changes/modifications:
Perhaps DIN should be signed or unsigned types instead of std_logic_vector. I actually recommend this, but it depends on how you are representing your values in other places of your design.
DOUT could also be a signed or unsigned value instead of std_logic_vector - it depends your requirements.
In this case, acc_value, the accumulated value register, will rollover if the values accumulated get too high. Maybe you want to generate an error condition when this happens, or perform a check to ensure that you saturate at the maximum value of acc_value instead.
acc_value need not be the same width as DIN -- it could be twice as wide (or whatever your requirements are). The wider it is, the more you can accumulate before the rollover condition occurs.

what exactly is a variable in VHDL?

I know how to use variables in VHDL and what I can do with that, but I don't know exactly what it is in hardware ?
What is the difference between signals and variables in hardware and where the value of a variable store ?
Is it a wire or it depends on my code ?
According to the "QuantumRipple" comments I extend this question :
I synthesized the following simple code with ISE (Xilinx synthesis tool) and the variable (var) synthesized into a D flip flop ??
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY test IS
port(
clk : in std_logic;
input : in std_logic;
output : out std_logic
);
END test;
ARCHITECTURE Behavioral OF test IS
BEGIN
PROCESS(clk)
VARIABLE var : std_logic;
BEGIN
IF clk'event AND clk = '1' THEN
var := input;
END IF;
output <= var;
END PROCESS;
END Behavioral;
Thanks for comments and answers ...
Variables can be used in several functionally distinct ways. As a result, the synthesizer can implement them in several ways.
The following applies to clocked processes:
If you independently set the variable in a process before you read it, it will synthesize purely into [a group of] LUTs. (complicated logical functions or a vector variable will require more than one LUT even for a single assignment)
If you update a variable multiple times and read it between updates, it will synthesize into several [groups of] LUTs. This case is no different than if you created a different named variable for each update, read pair.
If you read the value of the variable before it is set in the process and assign it after all reads it will synthesize into a flip flop. Variables in this configuration behave equivalently to signals.
If you set the variable based of a combination of itself and another value before it is independently set, it will synthesize into an (unnamed) flip flop and a [group of] LUTs hanging off of that.
These can also be combined to an extent. For example, if you read a variable at the start of a process and assign it at the end, but also update and read the variable in the middle, it will generate a flip flop whose output is used for the first read, and also some LUTs whose output is used for the second read.
Multiple assignments without intermediary reads also get collapsed into one group of LUTs (nothing taps off of the intermediary value).
Another important thing to understand about how VHDL is synthesized is that signals and variables do not really get translated into specific things. A signal refers to a specific wire in the design (not the stuff in between like LUTs and Flip Flops). Signals that are assigned in clocked processes will usually refer to the Dout wire from a certain Flip Flop and signals that are assigned in a combinatorial process or concurrent statement will usually refer to a wire coming out of a LUT, although it might refer to the same wire as another signal (including clocked signals!) if there was no logic in the assignment (a simple a <= b).
The assignment statements describe the relationship between wires.
Variables do not refer to a fixed wire, but rather just describe behavior.
Each variable assignment that is used to assign something else before it is assigned again creates a reference to a different wire (although these wires will typically not be explicitly named like signal wires - that's the point of variables).
The synthesizer takes that behavior and tries to determine what set of LUTs and Flip Flops are required to make the hardware do that. Note that while signals refer to some fixed wires, they don't refer to all wires. The synthesizer creates many un-named (the synthesizer generates an arbitrary name) wires to connect the generated components (LUTs and flip flops) between each explicitly named wire. It is because variables are so flexible in what the describe (not a fixed wire) that they can cause the generation of so many different combinations of basic components depending on how they are used.
For your specific code, yes, the variable var will cause a flip flop to be synthesized.
It would also do the exact same thing if 'var' was a signal and the output <= var; assignment was outside of the process.
In your code, var is set based on the sole assignment to refer to the Dout wire of a clocked element (flip flop) that has a Din of input, then the output is assigned to refer to the same wire as var.
In fact, it does the exact same thing as just doing
IF clk'event and clk = '1' THEN
output <= input;
END IF;
in this case, output is just directly assigned to refer to the Dout wire of the clocked element that has a Din of input instead of using var as a proxy.

VHDL - creating a variable number of signals

I'm creating a full adder with a variable number of bits. I've got a component that is a half-adder which takes in three inputs (the two bits to add, and a carry in bit) and gives 2 outputs (one bit output and a carry out bit).
I need to tie the carry out of one half-adder to the carry in of another. And I need to do this a variable number of times (if I'm adding 4 digit numbers, I'll need 4 half adders. If I'm doing 32 bit numbers, I'll need 32 half adders).
I was going to tie the carry outs of one half-adder to the carry in of another using signals, but I don't know how to create a variable number of signals.
I can instantiate a variable number of half-adders using a for-loop in a process, but since signals are defined outside of processes, I can't use a for loop for it. I don't know how I should tie the half-adders together.
The easiest way to write an adder in VHDL is not to worry about full adders and half adders, but just type:
a <= b + c;
where a,b and c are signed or unsigned
95% of the time, the synthesis tools will do a better job than you would.
I think you want variable-width signals not variable numbers of signals
Your signals need to be std_logic_vector(31 downto 0) for example - and then you wire up the bits of those signals to your half-adders appropriately.
Of course, as those signals are numbers, then don't use std_logic_vector use signed or unsigned (and the ieee.numeric_std lib).
And (as Philippe rightly points out) unless this is a learning exercise, just use the + operator.

Resources