16 bit std_logic_vector to lower 8 bit std_logic-vector in vhdl - vhdl

Am having an output of 16 bit std_logic_vector from one block.But in the later stage i have to use only lower 8 bit std_logic_vector.it creating synthesis problem...please tell me how to avoid this..

If you have a 16-bit std_logic_vector you can access the individual bytes like this:
signal largeVariable : std_logic_vector(15 downto 0);
signal lower8bitsVariable : std_logic_vector(7 downto 0);
signal upper8bitsVariable : std_logic_vector(7 downto 0);
(...)
lower8bitsVariable <= largeVariable(7 downto 0); --Store the lower 8 bits of largeVariable
upper8bitsVariable <= largeVariable(15 downto 8); --Store the upper 8 bits of largeVariable

Related

Concatenation VHDL (2 8-bit vectors)

I was just wondering, how could I concatenate two 8 bit vectors together into a 16-bit vector with odata_H having the MSB and odata_L having the LSB? Any help would be appreciated. The vectors are data points given off from an ADT7420 temperature sensor.
signal BCD: std_logic_vector(11 downto 0);
signal Bin_Temp: std_logic_vector(7 downto 0);
signal Bin_Acc: std_logic_vector(7 downto 0);
signal Buff_Temp: std_logic_vector(7 downto 0);
signal Buff_Acc: std_logic_vector(7 downto 0);
signal odata_L: std_logic_vector(7 downto 0);
signal odata_H: std_logic_vector(7 downto 0);
signal notEN: std_logic;
signal odataT: std_logic_vector(15 downto 0);
begin
odataT <= odata_H & odata_L;
Bin_Temp <= odataT(8 downto 1);
notEN <= not(EN);
I don't know why in this case the concatenation apparently doesn't work. Nevertheless, another way of achieving it is by using the resize() function of the numeric_std library.
library ieee;
use ieee.numeric_std.all;
[...]
odataT <= std_logic_vector(resize(signed(odata_H), odata_L'length));
The concatenation (odata_H, odata_L) will be resized with a length of length (16 in this case).
Of course unsigned instead of signed is possible, if applicable.

Width mismatch in assignment: VHDL

My code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library work;
use work.costanti.all;
entity Multiplier is
generic(nbA:integer:=nbA;
nbB:integer:=nbB);
port (
A: in STD_LOGIC_VECTOR(nbA-1 downto 0);
B: in STD_LOGIC_VECTOR(nbB-1 downto 0);
clk: in STD_LOGIC;
R: out STD_LOGIC_VECTOR(nbA+nbB-1 downto 0));
end Multiplier;
architecture Behavioral of Multiplier is
component AdderTree is
generic(nbit: integer:=nbA+nbB);
port (
IN1: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN2: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN3: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN4: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN5: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN6: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN7: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN8: in STD_LOGIC_VECTOR(nbit-1 downto 0);
IN9: in STD_LOGIC_VECTOR(nbit-1 downto 0);
S: out STD_LOGIC_VECTOR(nbit-1 downto 0)
);
end component;
signal V : STD_LOGIC_VECTOR(nbA-1 downto 0);
signal P : STD_LOGIC_VECTOR((nbA*nbB)-1 downto 0);
signal PP_0to6 : STD_LOGIC_VECTOR( (nbA)+(nbA+1)+(nbA+2)+(nbA+3)+(nbA+4)+(nbA+5)+(nbA+6)-1 downto 0); --(dim(pp0+PP1+PP2+PP3+PP4+PP5+PP6) downto 0 )
signal PP7 : STD_LOGIC_VECTOR(nbA+nbB-1 downto 0);
signal P7 : STD_LOGIC_VECTOR(nbA downto 0);
signal PPP : STD_LOGIC_VECTOR((nbA+nbB)*(nbB+1)-1 downto 0);
begin
for_g: for i in 0 to nbB-1 generate
V <= (others => B(i));
P((nbB)*(i)+(nbB-1) downto (nbB)*(i)) <= V and A;
end generate for_g;
P7 <= '0' & P((nbA*nbB)-1 downto (nbA*nbB)-1-(nbB-1));
PP_0to6(nbB-1 downto 0) <= P(nbB-1 downto 0); --PP0
for_g2: for i in 0 to nbB-3 generate
PP_0to6((nbB+1)*(i+1)+(i*(i+1)/2)+7 downto (nbB+1)*(i+1)+(i*(i+1)/2)) <= P(nbB*(i+1)+(nbB-1) downto nbB*(i+1)); --PP1 to PP6
PP_0to6((nbB+1)*(i+1)+(i*(i+1)/2)-1 downto (nbB+1)*(i)+((i-1)*(i)/2)+7+1) <= (others => '0');
end generate for_g2;
PP7(nbA+nbB-1 downto nbA-1) <= P7;
PP7(nbA-2 downto 0) <= (others => '0');
PPP_0to6: for i in 3 to nbB-2 generate
PPP(((i+1)*(nbA+nbB-1)+i)-(8-i) downto i*(nbA+nbB)) <= PP_0to6( (i+1)*(nbB-1)+((1/2)*((i*i)+(3*i))) downto i*(nbB)+(i-1)*i/2); --PP0 to PP6
PPP(((i+1)*(nbA+nbB-1)+i) downto ((i+1)*(nbA+nbB-1)+i)-(8-i)+1)<= (others => '0');
end generate PPP_0to6;
-- Fill last 32 bits of PPP
--Insert ADDER TREE
end Behavioral;
Portion of the error code: portion of code
PPP_0to6: for i in 0 to nbB-2 generate
PPP(((i+1)*(nbA+nbB-1)+i)-(8-i) downto i*(nbA+nbB)) <= PP_0to6( (i+1)*(nbB-1)+((1/2)*((i*i)+(3*i))) downto i*(nbB)+(i-1)*i/2); --PP0 to PP6
PPP(((i+1)*(nbA+nbB-1)+i) downto ((i+1)*(nbA+nbB-1)+i)-(8-i)+1)<= (others => '0');
end generate PPP_0to6;
Hi, I'm making a multiplier on vhdl, but on line 66 it reports me the following error:
if i=1: [Synth 8-690] width mismatch in assignment; target has 9 bits, source has 7 bits ["...Multiplier.vhd":66]
if i=2: [Synth 8-690] width mismatch in assignment; target has 10 bits, source has 5 bits ["...Multiplier.vhd":66]
if i=3: [Synth 8-690] width mismatch in assignment; target has 11 bits, source has 2 bits ["...Multiplier.vhd":66]
and so on..
I can't understand why, they seem to be the same size ..
my constant are:
nbA=8
nbB=8
and the signal P, PP_0to6 and PPP:
signal P : STD_LOGIC_VECTOR((nbA*nbB)-1 downto 0);
signal PP_0to6 : STD_LOGIC_VECTOR( (nbA)+(nbA+1)+(nbA+2)+(nbA+3)+(nbA+4)+(nbA+5)+(nbA+6)-1 downto 0);
signal PPP : STD_LOGIC_VECTOR((nbA+nbB)*(nbB+1)-1 downto 0);
N.B. I make sure to shift to the rigth by adding zeros as in the figure:
schema
The error is here:
PPP(((i+1)*(nbA+nbB-1)+i)-(8-i) downto i*(nbA+nbB)) <= PP_0to6( (i+1)*(nbB-1)+((1/2)*((i*i)+(3*i))) downto i*(nbB)+(i-1)*i/2);
but if I tried to replace the value of i:
i=0: PPP(7 downto 0) <= PP_0to6(7 downto 0);
i=1: PPP(24 downto 16)<=PP_0to6(16 downto 8)
i=2: PPP(41 downto 32)<=PP_0to6(26 downto 17)
i=3: PPP(58 downto 48)<=PP_0to6(37 downto 27)
...
...
the dimensions look the same.
I guess strictly speaking this answer doesn't really answer your question, since I'm not trying to figure out where your error is. But I'm convinced that if you change your coding style you won't encounter such difficult to debug errors any more.
As mentioned in my comments, your code will become must clearer and easier to debug if you split the signal up properly. I.e. don't create one giant signal for everything.
VHDL has arrays and records, use them, they won't make your circuit any larger, but the code will be much easier to reason about.
It's been a while since I actually wrote VHDL, so the syntax below might contain typo's, but hopefully the idea behind the code is clear:
constant c_AllZeros : std_logic_vector(c_MaxZeros - 1 downto 0) := (others => '0');
...
type t_P is std_logic_vector(c_SomeLength - 1 downto 0);
subtype t_P_Array is array (natural range <>) of t_P;
...
signal P : t_P_Array(0 to c_NumInputs - 1);
...
PPP_0to6: for i in PPP'range generate
PP(i) <= P(i) & c_AllZeros(index downto 0);
PPP(i) <= c_AllZeros(c_MaxZeros - index downto 0) & PP(i);
end generate PPP_0to6;
As you might notice, I also got rid of the explicit indices for the for-loop in the generate. There's still a magic number when indexing the all_zeroes signal to generate PPP. If I was writing this code, I'd replace that with some (calculated) constant with a meaningful name. This will make the code both more readable and trivial to change later on.
Note that there's other ways to do this. E.g. you could first set all bits of all PP signals to 0 and then assign a slice of them the P value.

Slicing a STD_LOGIC_VECTOR and putting back together?

I have sliced a 16 bit STD_LOGIC_VECTOR into 3 parts. I want to leave the first 8 MSBs untouched and break the 8 LSBs into 2 nibbles to do some processing on them.
I can do all this and the processing is all fine but when I try to put them all together into a 16 bit STD_LOGIC_VECTOR output it just stays UUUU. is there a special way that putting it back together should go?
signal fullout : std_logic_vector(15 downto 0);
signal Sbox1 : integer;
signal Sbox2 : integer;
signal tophalf : std_logic_vector(7 downto 0);
signal secondnibble, firstnibble : std_logic_vector(3 downto 0); --break the LSH into 2 nibbles
begin
tophalf(7 downto 0) <= LUTin(15 downto 8);
secondnibble(3 downto 0) <= LUTin(7 downto 4);
-- Sbox1 <= to_integer(unsigned(secondnibble));
firstnibble(3 downto 0) <= LUTin(3 downto 0);
-- Sbox2 <= to_integer(unsigned(firstnibble));
p1: process(LUTin)
begin
fullout(15 downto 8) <= tophalf(7 downto 0);
fullout(7 downto 4) <= secondnibble(3 downto 0);
fullout(3 downto 0) <= firstnibble(3 downto 0);
Always initialize outputs. In your case, its not clear that what is output, so here is my guess:
architecture xyz of zyx is
signal fullout : std_logic_vector(15 downto 0) := (others =>'0');
signal tophalf : std_logic_vector(7 downto 0):= (others =>'0');
signal secondnibble, firstnibble : std_logic_vector(3 downto 0):= (others =>'0');
.....
begin
....
end xyz;

Specialized calculator using VHDL

I have to project a specialized calculator on a Basys3 board using VHDL. The calculator should be able to group numbers using brackets, perform additions and substractions, AND and OR operations. For example, an expression could be: 4 + 5 AND 6 +(7 OR 1) - (4 AND 10)
The input numbers are 4 bit numbers (in my code I used 5 bit numbers, the most significant bit being the sign bit) and the output can be max. 16 bits long (i used 17 bits in my code, the most significant being the sign bit).
I wrote the code for the ALU (the adder/substractor, AND/OR) and I managed to make the calculator work for 2 numbers as inputs(using 2 in ports). This is the "main" code for the calculator, that i have written:
library IEEE;
use ieee.STD_LOGIC_1164.all;
use ieee.STD_LOGIC_UNSIGNED.all;
entity calculator is
port(X: in STD_LOGIC_VECTOR(4 downto 0); -- X(4) sign
Y: in STD_LOGIC_VECTOR(4 downto 0);
OPERATIE: in STD_LOGIC_VECTOR(4 downto 0);
CLK, CLR: in STD_LOGIC;
a_to_g: out STD_LOGIC_VECTOR(6 downto 0);
an: out STD_LOGIC_VECTOR(3 downto 0);
negativ: out std_logic);
end calculator;
architecture calculator of calculator is
component ALU is
port(A,B: in STD_LOGIC_VECTOR(16 downto 0);
COMANDA: in STD_LOGIC_VECTOR(4 downto 0);
RESULT: out STD_LOGIC_VECTOR(16 downto 0));
end component;
component BCD_7seg is
port(X: in STD_LOGIC_VECTOR(15 downto 0);
CLK, CLR: in STD_LOGIC;
a_to_g: out STD_LOGIC_VECTOR(6 downto 0);
an: out STD_LOGIC_VECTOR(3 downto 0));
end component;
signal OPERAND_1: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
signal OPERAND_2: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
signal TEMP_RESULT: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
begin
operand_1(3 downto 0) <= x(3 downto 0);
operand_1(16) <= x(4);
operand_2(3 downto 0) <= y(3 downto 0);
operand_2(16) <= y(4);
calculate: ALU port map(operand_1, operand_2, operatie, temp_result);
afis: BCD_7seg port map(temp_result(15 downto 0), clk, clr, a_to_g, an);
negativ <= temp_result(16);
end calculator;
However, the calculator should work for N numbers as inputs (using only one in port) and I don't know how to do it. I thought about memorising the whole expression(operartors and operands) in a FIFO or LIFO memory (but I'm not sure if that could work) and then making the calculations but I don't know how to calculate everything in the correct order given by the priorities and where(and how) to memorise the temporary results.
I thought that maybe you could give me some ideas, I'm new to VHDL, I'm a student and I have just started learning it and got stuck at this part in the project.
Thanks!

How do I split 16-bit data into 2 8-bit data in VHDL?

How do I split 16-bit data into 2 8-bit data?
signal part : std_logic_vector (16 downto 0);
signal part_1 : std_logic_vector (8 downto 0);
signal part_2 : std_logic_vector (8 downto 0);
The part is actually 17 bit, since 16 downto 0 is a 17 bit range, and the part_* are likewise 9 bit.
If the ranges are 15 downto 0 and 7 downto 0, then you can do the split with:
part_1 <= part( 7 downto 0);
part_2 <= part(15 downto 8);
Btw, quote by Martin Fowler / Phil Karlton:
There are two hard things in computer science:
cache invalidation, naming things, and off-by-one errors.
Why are your signals 17 bits and 9 bits long? I think they should be 16 and 8...
signal part : std_logic_vector (15 downto 0);
signal part_1 : std_logic_vector (7 downto 0);
signal part_2 : std_logic_vector (7 downto 0);
begin -- architecture begin
part_1 <= part(15 downto 8);
part_2 <= part(7 downto 0);
Pretty simple stuff... I'm surprised you didn't run across this in looking at a VHDL example.
There's also aggregate target assignment:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
end entity;
architecture fum of foo is
type fie is array (natural range 0 to 1) of std_logic_vector (7 downto 0);
signal part: std_logic_vector (15 downto 0);
signal part_1: std_logic_vector (7 downto 0);
signal part_2: std_logic_vector (7 downto 0);
begin
(part_1, part_2) <= fie'(part(15 downto 8), part(7 downto 0));
end architecture;
Which is admittedly more useful for extracting elements of records in one fell swoop. What's slick here is that there's no place there's any named signal of type fie.
The reason for the aggregate on the right hand side is because the element size has to match on both sides of the assignment operator, both aggregates are treated as if they are type fie.
Doing this with records allows you to extract elements of varying sizes. Extracting fields from CPU machine instruction formats comes to mind. It allows you to use simple names without requiring aliases for element selected names. (There would be no named record).
When the element size is the same on both sides you can simply use a target aggregate:
library ieee;
use ieee.std_logic_1164.all;
entity fie is
end entity;
architecture fum of fie is
signal part: std_logic_vector (2 downto 0);
signal part_1: std_logic;
signal part_2: std_logic;
signal part_3: std_logic;
begin
(part_1, part_2, part_3) <= part;
end architecture;
These aggregates all use positional association. You can also use named association. Record aggregates require an others choice represent at least one element and all the elements have to have the same type (e.g. std_logic_vector).
Just for completeness: you can also use aliases which makes the signal assignment obsolete:
signal part : std_logic_vector (15 downto 0);
alias part_1 : std_logic_vector(7 downto 0) is part(15 downto 8);
alias part_2 : std_logic_vector(7 downto 0) is part(7 downto 0);

Resources