Width mismatch in assignment: VHDL - 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.

Related

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;

VHDL multiplication for std_logic_vector

When simulating, I get a run time error, so I'm trying to run a RTL analysis in Vivado to see if the schematic of the component can be created at least. My code is the following:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity multiplicator_test is
generic(
WORD_SIZE: natural := 8;
EXP_SIZE: natural := 3
);
port(
input_1: in std_logic_vector(WORD_SIZE-1 downto 0);
input_2: in std_logic_vector(WORD_SIZE-1 downto 0);
result: out std_logic_vector(WORD_SIZE-1 downto 0)
);
end entity multiplicator_test;
architecture multiplicator_test_arch of multiplicator_test is
constant SIGNIFICAND_SIZE: natural := WORD_SIZE - EXP_SIZE - 1;
signal significand: std_logic_vector(SIGNIFICAND_SIZE-1 downto 0) := (others => '0');
signal exponent: std_logic_vector(EXP_SIZE-1 downto 0) := (others => '0');
signal sign: std_logic := '0';
signal aux: std_logic_vector((2*SIGNIFICAND_SIZE)-1 downto 0) := (others => '0');
begin
aux <= std_logic_vector(signed(input_1(SIGNIFICAND_SIZE-1 downto 0))*signed(input_2(SIGNIFICAND_SIZE - 1 downto 0)));
significand <= aux(SIGNIFICAND_SIZE - 1 downto 0);
exponent <= std_logic_vector(unsigned(input_1(WORD_SIZE-2 downto WORD_SIZE-EXP_SIZE-2))+unsigned(input_2(WORD_SIZE-2 downto WORD_SIZE-EXP_SIZE-2)));
sign <= input_1(WORD_SIZE-1) or input_2(WORD_SIZE-1);
result <= sign & exponent & significand;
end architecture multiplicator_test_arch;
When running the analysis, I get:
ERROR: [Synth 8-690] width mismatch in assignment; target has 3 bits, source has 4 bits [(...)/multiplicador.vhd:27]
The line with the error is 27:
aux <= std_logic_vector(signed(input_1(SIGNIFICAND_SIZE-1 downto 0))*signed(input_2(SIGNIFICAND_SIZE - 1 downto 0)));
Apparently the target (aux) is 3 bits, but really it should be 8.
The line you've posted is not line 27, line 27 is the following:
exponent <= std_logic_vector(unsigned(input_1(WORD_SIZE-2 downto WORD_SIZE-EXP_SIZE-2))+unsigned(input_2(WORD_SIZE-2 downto WORD_SIZE-EXP_SIZE-2)));
As you can see, exponent only has 3 bits:
The unsigned addition will need an additional bit for carry-out.
Basically, there's an issue that you might overflow on the multiplication.
One way to solve this is to make your result and exponent one bit wider:
result: out std_logic_vector(WORD_SIZE downto 0)
signal exponent: std_logic_vector(EXP_SIZE downto 0) := (others => '0');
Yields:

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!

8 bit error tolerant adder in vhdl .I have tried the codes available but they do not seem to work

"Unsigned 8-bit Error Tolerant Adder" to add two 8-bit numbers in "vhdl code". I have already tried the code below.It gives these errors
** Error: C:/Modeltech_pe_edu_10.4a/examples/etl1.vhd(34): near "Signal": syntax error
** Error: C:/Modeltech_pe_edu_10.4a/examples/etl1.vhd(41): near "EOF": syntax error
#
code below
enter code here
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity adr is
port (a,b: in std_logic_vector(7 downto 0);
output : out std_logic_vector(7 downto 0));
end adr ;
architecture eta of adr is
signal hn,ln: std_logic_vector(7 downto 0);
signal parta2,partb2,hno:std_logic_vector(3 downto 0);
signal parta1,partb1: std_logic_vector(3 downto 0);
signal lno:std_logic_vector(3 downto 0);
begin
process (a,b)
begin
parta1<= a(7 downto 4); -- parta1<= a(7 downto 4);
parta2<= a(3 downto 0); --parta2<= a(3 downto 0);
partb1<= b(7 downto 4); --partb1<= b(7 downto 4);
partb2<= b(3 downto 0); -- partb2<= b(3 downto 0);
hno<= std_logic_vector(unsigned(parta1)+ unsigned(partb1)); --4 bit msb
lno<= std_logic_vector((unsigned(partb2))xor(unsigned(partb2)));--4bit lsb
Signal hn: std_logic_vector(7 downto 0) := hno(3 downto 0) & B"0000";-- concatenation of hn with zeros
Signal ln: std_logic_vector(7 downto 0) := B"0000" & lno(3 downto 0);--concatenation ln with zeros
output<=(hn or ln);
end process ;
.Thanks in Advance..
OK, you have three issues preventing this from compiling:
Signal hn: std_logic_vector(7 downto 0) := hno(3 downto 0) & B"0000";
In this line, you have already declared hn, and are trying to declare it again here. You can only declare a signal in the declarative region where most of your signals are defined. The second error is the B"0000"; I suspect you are trying to specify that your literal "0000" is binary, but this is the default when assigning to an std_logic_vector anyway. Your correct line would be:
hn <= hno(3 downto 0) & "0000";
The same errors are present in the line below this one.
The third error is pretty trivial. You have remembered an end process;, but forgotten the end architecture;.

= can not have such operands in this context

Here's the full error: ERROR:HDLParsers:808 - "C:/Users/vROG/Desktop/.../CacheController.vhd" Line 72. = can not have such operands in this context.
I'd understand how to fix this if I was used '+' or '*', but equal sign?
As you can tell, the code isn't nearly being close to completely, but I can't understand why my second nested if isn't working. I've tried turning dirtyBIT to type int, but it still gives me the same error, which leads me to believe that I made a trivial error somewhere.
FIXED (Using user1155120's advice) However how do I resolve the issue with offset and tag?
architecture Behavioral of CacheController is
signal tagFROMCPU : STD_LOGIC_VECTOR(7 downto 0) := CPU_addr(15 downto 8);
signal indexFROMCPU: STD_LOGIC_VECTOR(2 downto 0) := CPU_addr(7 downto 5);
signal offsetFROMCPU: STD_LOGIC_VECTOR(4 downto 0) := CPU_addr(4 downto 0);
TYPE STATETYPE IS (state_0, state_1, state_2, state_3);
SIGNAL present_state : STATETYPE;
--Variables
signal dirtyBIT: std_logic_vector (7 downto 0);
signal validBIT: std_logic_vector (7 downto 0);
TYPE tag is array (7 downto 0) of STD_LOGIC_VECTOR(7 downto 0);
TYPE offset is array (7 downto 0) of STD_LOGIC_VECTOR(4 downto 0);
signal myTag: tag;
signal myOFFSET : offset;
begin
--STATE MACHINE
process(clk)
begin
if (present_state = state_0) then --Start State : Checks for HIT or MISS, PERFORMS HIT OPERATION or MOVES TO STATE_1
if ((myTag(to_integer(unsigned(indexFROMCPU)) = tagFROMCPU)) then
--HIT
else
present_state <= state_1;
end if;
elsIF (present_state = state_1) then --CHECKS DIRTY BIT. IF 0, LOADS DATA, MOVES TO STATE_0 ELSE move to state_2
if (dirtyBit(to_integer(unsigned(indexFROMCPU))) = '0') then
present_state <= state_0;
else
present_state <= state_2;
end if;
elsIF(present_state = state_2) then -- DIRTY BIT IS 1, SAVES DATA, goes back to STATE_1
present_state <= state_1;
end if;
end process;
end Behavioral;
OLD CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity CacheController is
Port (
clk : in STD_LOGIC;
CPU_addr : in STD_LOGIC_VECTOR (15 downto 0);
CPU_WR_RD : in STD_LOGIC;
CPU_CS : in STD_LOGIC;
CPU_RDY : out STD_LOGIC;
SDRAM_Addr : out STD_LOGIC_VECTOR (15 downto 0);
SDRAM_WR_RD : out STD_LOGIC;
SDRAM_MSTRB : out STD_LOGIC;
MUX1,MUX2 : out STD_LOGIC;
SRAM_Addr : out STD_LOGIC_VECTOR (7 downto 0);
SRAM_WEN : out STD_LOGIC
);
end CacheController;
architecture Behavioral of CacheController is
signal tagFROMCPU : STD_LOGIC_VECTOR(7 downto 0) := CPU_addr(15 downto 8);
signal indexFROMCPU: STD_LOGIC_VECTOR(2 downto 0) := CPU_addr(7 downto 5);
signal offsetFROMCPU: STD_LOGIC_VECTOR(4 downto 0) := CPU_addr(4 downto 0);
TYPE STATETYPE IS (state_0, state_1, state_2, state_3);
SIGNAL present_state : STATETYPE;
--Variables to emulate SRAM
TYPE dirtyBIT is array (7 downto 0) of std_logic;
TYPE validBIT is array (7 downto 0) of std_logic;
TYPE tag is array (7 downto 0,7 downto 0) of std_logic;
TYPE offset is array (7 downto 0,4 downto 0) of std_logic;
begin
--STATE MACHINE
process(clk)
begin
if (present_state = state_0) then --Start State : Checks for HIT or MISS, PERFORMS HIT OPERATION or MOVES TO STATE_1
elsIF (present_state = state_1) then --CHECKS DIRTY BIT. IF 0, LOADS DATA, MOVES TO STATE_0 ELSE move to state_2
if (dirtyBit(to_integer(unsigned(indexFROMCPU))) = '0') then
present_state <= state_0;
else
present_state <= state_2;
end if;
elsIF(present_state = state_2) then -- DIRTY BIT IS 1, SAVES DATA, goes back to STATE_1
present_state <= state_1;
end if;
end process;
end Behavioral;
Operator overload resolution (for the "=" operator) requires a function be declared with a matching signature (types of the left and right inputs and the return type).
if (dirtyBit(to_integer(unsigned(indexFROMCPU))) = '0') then
Change the declaration for dirtyBit:
--Variables to emulate SRAM
-- TYPE dirtyBIT is array (7 downto 0) of std_logic;
signal dirtyBIT: std_logic_vector (7 downto 0);
And your code analyzes. I'd suggest the other type declaration (validBIT, tag and offset) should be similarly treated.
It looks like there should be an array type where offset is used. The type name might be changed to preserve offset as a signal name.

Resources