I need to make an arithmetic logic unit in VHDL for the pic16f684. So the instructions for the ALU can be found in the datasheet of the pic16f684.
The instructions I need to make are the following:
This is my code so far, but I get, which is quite logic, the error that a std_logic_vector can't have a character in the vector, but I don't know how to do it in a other way..
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY AluPIC IS
PORT( -- Input Signals
Op_code : in std_logic_vector(6 DOWNTO 0);
win, fin : in std_logic_vector(7 DOWNTO 0);
-- Output Signals
d,z : out std_logic;
ALU_output : out std_logic_vector(7 DOWNTO 0));
END AluPIC;
ARCHITECTURE behavior OF AluPIC IS
-- declare signal(s) internal to module here
SIGNAL temp_output,wout,fout: std_logic_vector(7 DOWNTO 0);
BEGIN
PROCESS (Op_code, win, fin)
BEGIN
-- Select Arithmetic/Logical Operation
CASE Op_Code (6 DOWNTO 0) IS
WHEN "000111d" =>
if d ='0' then
wout <= win + fin;
temp_output <=wout;
else
fout <= win + fin;
temp_output <= fout;
end if;
WHEN "000101d" =>
if d ='0' then
wout <= win and fin;
temp_output <= wout;
else
fout <= win and fin;
temp_output <= fout;
end if;
WHEN "000001l" =>
fout <= fin;
fout <= "00000000";
z <= '1';
temp_output <= fout;
WHEN "001010d" =>
fout <= fin+1;
if d = '0' then
wout <= fout;
temp_output <=wout;
else
fout <= fout;
temp_output <=fout;
end if;
WHEN "001000d" =>
if d = '0' then
wout <= fin;
temp_output <= wout;
z <= '1';
else
fout <= fin;
temp_output <= fout;
z <= '1';
end if;
WHEN "0101bbb" =>
fout <= fin;
temp_output <= fout;
WHEN OTHERS =>
temp_output <= "00000000";
END CASE;
-- Select Shift Operation
IF Op_Code(0) = '1' THEN
-- Shift bits left with zero fill using concatination operator
-- can also use VHDL 1076-1993 shift operator such as SLL
Alu_output <= temp_output(6 DOWNTO 0) & '0';
ELSE
Alu_output <= temp_output;
END IF;
END PROCESS;
END behavior;
Thanks for your time guys!
Lines like
WHEN "000111d" =>
orWHEN "0101bbb" =>
are not valid, because yourcase
statement uses anstd_logic_vector
, but"000111d"
is a string.It is not clear what you are trying to achieve with your
d
andb
characters, but your variouswhen
lines should compare against a validstd_logic_vector
of the correct length, for exampleWHEN "0000111" =>
.Looking at your op code image, it shows a table with lines containing operations, for example 'ADDWF'. In these operations, only the most significant 6 bits seem to select the operation, with the least significant bit being labelled
b
ord
. This least significant bit is actually a parameter for the operation, not part of the opcode. The table does not show what effectd
has on the operation, but you seem to have worked this out. UsingADDWF
as an example, I would change your code like this:The 'BSF' operation is the exception, as it uses the least significant 3 bits as a parameter. You can write this either using a matching case statement, or by listing all the possibilities in one case:
Matching case, requiring VHDL2008:
List all possibilities: