Error in Xilinx for case statement (case-when) - vhdl

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sammy_2018314405 is
Port ( codeword : in STD_LOGIC_VECTOR (6 downto 0);
syndrome : out STD_LOGIC_VECTOR (2 downto 0);
dataword : out STD_LOGIC_VECTOR (3 downto 0));
end sammy_2018314405;
architecture Behavioral of sammy_2018314405 is
signal s : std_logic_vector(2 downto 0);
signal b3, b2, b1, b0, q2, q1, q0 : std_logic;
signal temp : std_logic_vector(6 downto 0);
begin
b3 <= codeword(6);
b2 <= codeword(5);
b1 <= codeword(4);
b0 <= codeword(3);
q2 <= codeword(2);
q1 <= codeword(1);
q0 <= codeword(0);
s(0) <= b0 xor b1 xor b2 xor q0;
s(1) <= b1 xor b2 xor b3 xor q1;
s(2) <= b0 xor b1 xor b3 xor q2;
temp <= (b3,b2,b1,b0,q2,q1,q0);
--this part show error, can I put case in the middle of the code?
process(s)
begin
case s is
when "001" => temp(0) <= not temp(0);
when "010" => temp(1) <= not temp(1);
when "011" => temp(5) <= not temp(5);
when "100" => temp(2) <= not temp(2);
when "101" => temp(3) <= not temp(3);
when "110" => temp(6) <= not temp(6);
when "111" => temp(4) <= not temp(4);
when others => null;
end case;
end process;
syndrome(2 downto 0) <= s(2 downto 0);
dataword(3 downto 0) <= temp(6 downto 3);
end Behavioral;
Line 51: Net <temp[6]> is already driven by input port <codeword[6]>.
Net <temp[5]> is already driven by input port <codeword[5]>.
(This is code for 7 4 Hamming decoder.)
What should I do?

Related

7 4 Hamming decoder in xilinx (Shows warning "temp should be on the sensitivity list of process")

This is what I am implementing.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sammy_2018314405 is
Port ( codeword : in STD_LOGIC_VECTOR (6 downto 0);
syndrome : out STD_LOGIC_VECTOR (2 downto 0);
dataword : out STD_LOGIC_VECTOR (3 downto 0));
end sammy_2018314405;
architecture Behavioral of sammy_2018314405 is
signal s : std_logic_vector(2 downto 0);
signal b3, b2, b1, b0, q2, q1, q0 : std_logic;
signal temp : std_logic_vector(6 downto 0);
begin
b3 <= codeword(6);
b2 <= codeword(5);
b1 <= codeword(4);
b0 <= codeword(3);
q2 <= codeword(2);
q1 <= codeword(1);
q0 <= codeword(0);
s(0) <= b0 xor b1 xor b2 xor q0;
s(1) <= b1 xor b2 xor b3 xor q1;
s(2) <= b0 xor b1 xor b3 xor q2;
temp <= (b3,b2,b1,b0,q2,q1,q0);
process(s)
begin
case s is
when "001" => temp(0) <= not temp(0);
when "010" => temp(1) <= not temp(1);
when "011" => temp(5) <= not temp(5);
when "100" => temp(2) <= not temp(2);
when "101" => temp(3) <= not temp(3);
when "110" => temp(6) <= not temp(6);
when "111" => temp(4) <= not temp(4);
when others => null;
end case;
end process;
syndrome(2 downto 0) <= s(2 downto 0);
dataword(3 downto 0) <= temp(6 downto 3);
end Behavioral;
--I get warnings that show temp should be on the sensitivity list of process. I do not understand what does this means. I should get a result something like the picture below.
Result for the implementation

why does not compile a VHDL program

i tried to compile the following VHDL code but i got an error message:
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
ENTITY testdoublemux IS
END testdoublemux;
ARCHITECTURE test_doublemux OF testdoublemux IS
SIGNAL A1,B1,D1 : std_logic_vector(2 downto 0); S1 : std_logic;
COMPONENT mux_double_2to1 port ( a,b: in std_logic_vector(2 downto 0); s : in std_logic; d : out std_logic_vector(2 downto 0) );
END COMPONENT;
BEGIN
M1: mux_double_2to1 PORT MAP ( a => A1 , b => B1 , s => S1 , d => D1 );
PROCESS
BEGIN
A1 <= '001'; B1 <= '010'; S1 <= '0'; wait for 20ps;
A1 <= '010'; B1 <= '100'; S1 <= '0'; wait for 20ps;
A1 <= '111'; B1 <= '011'; S1 <= '0'; wait for 20ps;
A1 <= '101'; B1 <= '111'; S1 <= '0'; wait for 20ps;
A1 <= '010'; B1 <= '001'; S1 <= '1'; wait for 20ps;
A1 <= '000'; B1 <= '101'; S1 <= '1'; wait for 20ps;
A1 <= '101'; B1 <= '010'; S1 <= '1'; wait for 20ps;
A1 <= '111'; B1 <= '101'; S1 <= '1'; wait for 20ps;
END PROCESS;
END test_doublemux;
The error message is:
** Error: D:\apps\modelsim starter edition\modelsim workspace\mux_doubletb.vhd(8): near "S1": (vcom-1576) expecting BEGIN.
The entity code is:
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
ENTITY mux_double_2to1 is
PORT
(a, b: in std_logic_vector(2 downto 0);
s: in std_logic;
d: out std_logic_vector(2 downto 0)
);
END mux_double_2to1;
ARCHITECTURE dataflow3 OF mux_double_2to1 IS
BEGIN
d <= a WHEN s='0' ELSE b;
END dataflow3;

Adder and Subtractor code not working VHDL

This code works except for the add and subtract operations denoted by opcode 010 and 110 respectively. When I try to add the numbers the result looks as though a and b are being XOR'd and subtracting does A XNOR B. I have no idea why this is happening pls help. Also I am not allowed to use arithmetic plus or minus in my code the point of it is to add logically.
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.numeric_std.ALL;
ENTITY Lab3ALU IS
PORT(
opcode :IN STD_LOGIC_VECTOR(2 DOWNTO 0);--INPUT
a :IN STD_LOGIC_VECTOR(31 DOWNTO 0);--INPUT
b :IN STD_LOGIC_VECTOR(31 DOWNTO 0);--INPUT
Cout :OUT STD_LOGIC;
Zero :OUT STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(31 DOWNTO 0));--OUTPUT
END Lab3ALU;
ARCHITECTURE description of Lab3ALU IS
SIGNAL Reg1, Reg2, Reg3, Result : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL Cin, Sum, Carry : STD_LOGIC;
BEGIN
-- Update the register output on the clock's rising edge
process (a,b, opcode)
begin
Cin <= opcode(2);
Reg1 <= a;--temporarirly store A in Reg1 local variable
Reg2 <= b;--temporarily store B in Reg2 local variable
Reg3 <= NOT b;
case opcode is
When "000" => Result <= Reg1 AND Reg2;--AND
When "001" => Result <= Reg1 OR Reg2;--OR
When "010" =>
addloop: for i in 0 to 31 loop
Result(i) <= ((Reg1(i) XOR Reg2(i)) XOR Cin);
Cin <= (((Reg1(i) XOR Reg2(i))AND Cin)OR (Reg1(i) AND Reg2(i)));
end loop addloop;
When "110" =>
subloop: for i in 0 to 31 loop
Result(i) <= ((Reg1(i) XOR Reg3(i)) XOR Cin);
Cin <= (((Reg1(i) XOR Reg3(i))AND Cin)OR (Reg1(i) AND Reg3(i)));
end loop subloop;
When "100" => Result(31 downto 1) <= reg1(30 downto 0);
Result(0) <= '0';
Cin <= '0';
When "101" => Result(30 downto 0) <= reg1(31 downto 1);
Result(31) <= '0';
Cin <= '0';
When others => Result <= "00000000000000000000000000000000";
end case;
if Result = "00000000000000000000000000000000" then
Zero <= '1';
else
Zero <= '0';
end if;
q<= Result;
Cout<= Cin;
end process;
END description;```

VHDL - Carry Look Ahead Adder isn't adding odd and even numbers

I coded a CLA 4-Bit adder for a project for EE, and while it'll add Even/Even and Odd/Odd, it won't add A and B if only one of them is Odd.
So basically:
0001 + 0001 = 0010
0001 + 0010 = 0010 (Doesn't detect 0001)
Help is much appreciated!
Code in top-level entity:
signal g1 : unsigned(3 downto 0);
signal g2 : unsigned(3 downto 0);
signal g3 : unsigned(3 downto 0);
signal p1 : unsigned(3 downto 0);
signal p2 : unsigned(3 downto 0);
signal p3 : unsigned(3 downto 0);
signal c1 : unsigned(4 downto 0);
signal c2 : unsigned(4 downto 0);
signal c3 : unsigned(4 downto 0);
signal ci1 : std_logic;
signal ci2 : std_logic;
signal ci3 : std_logic;
signal co1 : std_logic;
signal co2 : std_logic;
signal co3 : std_logic;
signal sum : unsigned(4 downto 0);
signal sum1 : unsigned(3 downto 0);
signal sum2 : unsigned(3 downto 0);
signal sum3 : unsigned(3 downto 0);
signal tn : unsigned(3 downto 0) := "1010";
--A + B
p1 <= unsigned(A xor B);
g1 <= unsigned(A and B);
k1 : CLA1 port map (p1,g1,c1,ci1);
sum1 <= (p1 xor c1(3 downto 0));
co1 <= c1(4);
--A + 1
p2 <= unsigned(A xor "0001");
g2 <= unsigned(A and "0001");
k2 : CLA2 port map (p2,g2,c2,ci2);
sum2 <= (p2 xor c2(3 downto 0));
co2 <= c2(4);
--A + A
p3 <= unsigned(A xor A);
g3 <= unsigned(A and A);
k3 : CLA3 port map (p3,g3,c3,ci3);
sum3 <= (p3 xor c3(3 downto 0));
co3 <= c3(4);
Code in CLA.vhd:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity CLA1 is
port (
ci : in std_logic;
p : in unsigned(3 downto 0);
g : in unsigned(3 downto 0);
c : out unsigned(4 downto 0)
);
end CLA1;
architecture Behavioral of CLA1 is
begin
c(0) <= ci;
c(1) <= g(0) or (p(0) and ci);
c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and ci);
c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
or (p(2) and p(1) and p(0) and ci);
c(4) <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
or (p(3) and p(2) and p(1) and g(0)) or (p(3)
and p(2) and p(1) and p(0) and ci);
end Behavioral;
You have done port map in wrong order. i.e. k1 : CLA1 port map (p1,g1,c1,ci1); But it suppose to be k1 : CLA1 port map (ci1,p1,g1,c1);
Do this change and try
You have several errors.
First your code example for the top level is incomplete it's not a Minimal, Complete, and Verifiable example, meaning someone else can't duplicate the error(s) you're encountering.
Second CLA2 and CLA3 appear to have u component declarations (otherwise your code wouldn't analyze, elaborate and simulate). This results in those components being unbound (and their signals not showing up in your node finder). That's correct by using CLA1 instead of CLA2 and CLA3 in k2 and k3.
Third as Aril points out you've messed up the positional port association in the instantiations of k1, k2 and k3 (and as Brian notes this is why we use formal port association). You could also note that k1 (which is bound during elaboration if the entity and architecture pair for CLA1 has previously been analyzed) shouldn't successfully elaborate. It indicates your code snippet doesn't match the description of your errors.
Fix those things and you get better results:
This waveform dump was produced using this stimulus:
STIMULUS:
process
begin
wait for 10 ns;
for i in 0 to 15 loop
B <= std_logic_vector(to_unsigned(i,4));
for j in 0 to 15 loop
A <= std_logic_vector(to_unsigned(j,4));
ci1 <= '0';
ci2 <= '0';
ci3 <= '0';
wait for 10 ns;
ci1 <= '1';
ci2 <= '1';
ci3 <= '1';
wait for 10 ns;
end loop;
end loop;
wait;
end process;
Notice the assumption that A and B are std_logic_vector subtypes, born out by the likes of:
p1 <= unsigned(A xor B);
g1 <= unsigned(A and B);
(All without doing your class work for you while telling you where your errors lie).

VHDL Hamming code for correcting error

Please help me with checking this code for correcting error using hamming code in VHDL. I have being able to detect error but not correct it.
I have three modules my encoder, decoder and an error injector. I have a feeling it my decoder that is having issues. Below is my decoder code
library ieee;
use ieee.std_logic_1164.all;
entity hamdec8 is
port(
datain: in std_logic_vector (7 downto 0);
parin : in std_logic_vector(4 downto 0);
Dataout : out std_logic_vector(7 downto 0);
Parout : out std_logic_vector(4 downto 0);
NE : out std_logic;
DED : out std_logic;
SEC : out std_logic
);
Constant MaskP1 : std_logic_vector(7 downto 0) := "01011011";
Constant MaskP2 : std_logic_vector(7 downto 0) := "01101101";
Constant MaskP3 : std_logic_vector(7 downto 0) := "10001110";
Constant MaskP4 : std_logic_vector(7 downto 0) := "11110000";
end hamdec8;
architecture beh of hamdec8 is
signal synd : std_logic_vector(4 downto 1);
signal P0 : std_logic;
signal din1, din2, din3, din4 : std_logic_vector(7 downto 0); --to hold datain AND maskp
begin
process(Datain, Parin)
begin
NE <= '1';
DED <= '0';
SEC <= '0';
Dataout <= Datain;
Parout <= Parin;
P0 <= (Parin(0) XOR Parin(1) XOR Parin(2) XOR Parin(3) XOR
Parin(4) XOR Datain(0) XOR Datain(1) XOR Datain(2) XOR
Datain(3) XOR Datain(4) XOR Datain(5) XOR Datain(6) XOR
Datain(7));
din1 <= Datain AND MaskP1;
Synd(1) <= din1(0) XOR din1(1) XOR din1(2) XOR din1(3) XOR
din1(4) XOR din1(5) XOR din1(6) XOR din1(7) XOR Parin(1);
din2 <= Datain AND MaskP2;
Synd(2) <= din2(0) XOR din2(1) XOR din2(2) XOR din2(3) XOR
din2(4) XOR din2(5) XOR din2(6) XOR din2(7) XOR Parin(2);
din3 <= Datain AND MaskP3;
Synd(3) <= din3(0) XOR din3(1) XOR din3(2) XOR din3(3) XOR
din3(4) XOR din3(5) XOR din3(6) XOR din3(7) XOR Parin(3);
din4 <= Datain AND MaskP4;
Synd(4) <= din4(0) XOR din4(1) XOR din4(2) XOR din4(3) XOR
din4(4) XOR din4(5) XOR din4(6) XOR din4(7) XOR Parin(4);
if (synd = "0000") then
IF (P0 = '0') then
--Dataout <= Datain;
--NE <= '1';
--DED <= '0';
--SEC <= '0';
--Parout <= Parin;
null;
elsif (P0 = '1') then --single error
NE <= '0';
DED <= '0';
SEC <= '1';
case synd is
when "0000" => Parout(0) <= NOT Parin(0);
when "0001" => Parout(1) <= NOT Parin(1);
when "0010" => Parout(2) <= NOT Parin(2);
when "0011" => Dataout(0) <= NOT Datain(0);
when "0100" => Parout(3) <= NOT parin(3);
when "0101" => Dataout(1) <= NOT Datain(1);
when "0110" => Dataout(2) <= NOT Datain(2);
when "0111" => Dataout(3) <= NOT Datain(3);
when "1000" => parout(4) <= parin(4);
when "1001" => Dataout(4) <= NOT Datain(4);
when "1010" => Dataout(5) <= NOT Datain(5);
when "1011" => Dataout(6) <= NOT Datain(6);
when "1100" => Dataout(7) <= NOT Datain(7);
when others =>
Parout <= parin;
Dataout <= Datain;
end case;
Dataout <= "00000000";
Parout <= "00000";
end if;
elsif (P0 = '0') then
if (synd /= "0000") then
NE <= '0';
DED <= '1';
SEC <= '0';
Dataout <= "00000000";
Parout <= "00000";
end if;
end if;
end process;
end beh;
Thank you
The correction logic implemented in the case statement is only reached when the syndrome is "0000" and the overall parity is '1'. That doesn't cover all the other possible syndrome values. The indentation of the single-error elsif makes this confusing. You need to rework the nested if statements so that correction is applied for all syndromes.
Your signals P0, synd, din1, din2, din3, din4 should be declared as variables in the process or you should extract the xor calculation from process.
Second variant with extracted xor calculation, extended sensitivity list and fixed code indentation:
library ieee;
use ieee.std_logic_1164.all;
entity hamdec8 is
port (
datain: in std_logic_vector (7 downto 0);
parin : in std_logic_vector(4 downto 0);
Dataout : out std_logic_vector(7 downto 0);
Parout : out std_logic_vector(4 downto 0);
NE : out std_logic;
DED : out std_logic;
SEC : out std_logic
);
end hamdec8;
architecture beh of hamdec8 is
Constant MaskP1 : std_logic_vector(7 downto 0) := "01011011";
Constant MaskP2 : std_logic_vector(7 downto 0) := "01101101";
Constant MaskP3 : std_logic_vector(7 downto 0) := "10001110";
Constant MaskP4 : std_logic_vector(7 downto 0) := "11110000";
signal synd : std_logic_vector(4 downto 1);
signal P0 : std_logic;
signal din1, din2, din3, din4 : std_logic_vector(7 downto 0); --to hold datain AND maskp
begin
P0 <= Parin(0) XOR Parin(1) XOR Parin(2) XOR Parin(3) XOR Parin(4) XOR
Datain(0) XOR Datain(1) XOR Datain(2) XOR Datain(3) XOR Datain(4) XOR
Datain(5) XOR Datain(6) XOR Datain(7);
din1 <= Datain AND MaskP1;
din2 <= Datain AND MaskP2;
din3 <= Datain AND MaskP3;
din4 <= Datain AND MaskP4;
Synd(1) <= din1(0) XOR din1(1) XOR din1(2) XOR din1(3) XOR
din1(4) XOR din1(5) XOR din1(6) XOR din1(7) XOR Parin(1);
Synd(2) <= din2(0) XOR din2(1) XOR din2(2) XOR din2(3) XOR
din2(4) XOR din2(5) XOR din2(6) XOR din2(7) XOR Parin(2);
Synd(3) <= din3(0) XOR din3(1) XOR din3(2) XOR din3(3) XOR
din3(4) XOR din3(5) XOR din3(6) XOR din3(7) XOR Parin(3);
Synd(4) <= din4(0) XOR din4(1) XOR din4(2) XOR din4(3) XOR
din4(4) XOR din4(5) XOR din4(6) XOR din4(7) XOR Parin(4);
process(Datain, Parin, synd, P0)
begin
NE <= '1';
DED <= '0';
SEC <= '0';
Dataout <= Datain;
Parout <= Parin;
if (synd = "0000") then
IF (P0 = '0') then
--Dataout <= Datain;
--NE <= '1';
--DED <= '0';
--SEC <= '0';
--Parout <= Parin;
null;
elsif (P0 = '1') then --single error
NE <= '0';
DED <= '0';
SEC <= '1';
case synd is
when "0000" => Parout(0) <= NOT Parin(0);
when "0001" => Parout(1) <= NOT Parin(1);
when "0010" => Parout(2) <= NOT Parin(2);
when "0011" => Dataout(0) <= NOT Datain(0);
when "0100" => Parout(3) <= NOT parin(3);
when "0101" => Dataout(1) <= NOT Datain(1);
when "0110" => Dataout(2) <= NOT Datain(2);
when "0111" => Dataout(3) <= NOT Datain(3);
when "1000" => parout(4) <= parin(4);
when "1001" => Dataout(4) <= NOT Datain(4);
when "1010" => Dataout(5) <= NOT Datain(5);
when "1011" => Dataout(6) <= NOT Datain(6);
when "1100" => Dataout(7) <= NOT Datain(7);
when others => null;
end case;
--Dataout <= "00000000"; -- these lines override all calculations
--Parout <= "00000"; -- from previous case statement
end if;
elsif (P0 = '0') then
if (synd /= "0000") then
NE <= '0';
DED <= '1';
SEC <= '0';
Dataout <= "00000000";
Parout <= "00000";
end if;
end if;
end process;
end beh;
What's up with this code?
IF (P0 = '0') then
-- commented out stuff
[...]
null;
elsif (P0 = '1') then --single error
[...]
end if;
Why not just use:
if p0 = '1' then
[...]
end if;
or at least
if p0 = '0' then
[stuff for when p0 is '0']
else
[stuff for when p0 is not '0']
end if;

Resources