title: How to implement a 4 bit ALU in VHDL using an opcode
body: <p>So I have this lab assignment which carries on from a previous one where I implemented a single bit ALU in VHDL. The single bit ALU module takes an opcode and performs an operation based on this opcode e.g. addition or subtraction. </p>
  
  <pre><code>entity alu_slice is
       Port ( a : in STD_LOGIC;
             b : in STD_LOGIC;
             s : out STD_LOGIC;
             opcode : in STD_LOGIC_VECTOR (2 downto 0);
             cin : in STD_LOGIC;
             cout : out STD_LOGIC);
  end alu_slice;
  </code></pre>
  
  <p>The opcode vector above is where the 3 bit opcode is placed at the time of simulation to tell the ALU what arithmetic operation to perform. The behavioural of the single bit ALU is given below:</p>
  
  <pre><code>architecture Behavioural of alu_slice is
  architecture Behavioural of alu_slice is
  
  begin 
  
  multiplex: process(a, b, opcode, cin)  is begin
  
  case opcode is
  when "000" =&gt;
  --cin &lt;= '0';
  --s &lt;= (a xor b) xor cin;
  s &lt;= (a xor b) xor cin;
  cout &lt;= (a and b) xor ((a xor b) and cin);
  
  
  when "001" =&gt;
  s &lt;= (a xor not b) xor cin;
  cout &lt;= (a and not b) xor ((a xor not b) and cin);
  
  
  when "010" =&gt;
  s &lt;= a and b;
  
  when "011" =&gt;
  s &lt;= a or b;
  
  when "100" =&gt;
  s &lt;= a xor b;
  
  when "101" =&gt;
  s &lt;= not a;
  
  when "110" =&gt;
  --a &lt;= cin;
  cout &lt;= a;
  
  when "111" =&gt;
  s &lt;= a xor cin;
  cout &lt;= a and cin;
  
  when others =&gt;
  s &lt;= (a xor b) xor cin;
  cout &lt;= (a and b) xor ((a xor b) and cin);
  
  
  end case;
  
  end process;
  
  end behavioural;
  </code></pre>
  
  <p>I won't go into detail about what each of the opcodes are because that isn't part of the problem I'm having. I am supposed to use this alu slice as part of the architecture of a 4 bit ALU with four seperate instantiations of the alu_slice entity. The issue I am having is that if the code for the opcode is all inside the beavioural of the alu slice how is it supposed to be changed from the 4 bit module during simulation? </p>
  
  <p>Here is the 4 bit alu entity I have made.</p>
  
  <pre><code>entity alu_pb is
      Port ( a : in STD_LOGIC_VECTOR (3 downto 0);
             b : in STD_LOGIC_VECTOR (3 downto 0);
             s : out STD_LOGIC_VECTOR (3 downto 0);
             --op: in STD_LOGIC_VECTOR (2 downto 0);
             overflow : out STD_LOGIC;
             compl_overflow : out STD_LOGIC;
             zero : out STD_LOGIC);
  end alu_pb;
  </code></pre>
  
  <p>This is using all of the signals I was told to use in my notes. I commented out the op vector because that is something I added trying to solve this problem. And so finally I have four ALU slices in the architecture of the project but I can't compile because I can't seem to figure out a way of updating the opcode logic vector in the alu slice component such that it is replicated across all of the separate slices performing the appropriate operation between each of the four bits. </p>
  
  <p>Here is the rest of the code in the architecture:</p>
  
  <pre><code>architecture Behavioral of alu_pb is
  
  component alu_slice is
    Port(a: in STD_LOGIC;
         b: in STD_LOGIC;
         s: out STD_LOGIC;
         opcode: in STD_LOGIC_VECTOR(2 down to 0);
         cin: in STD_LOGIC;
         cout: out STD_LOGIC);
         end component;
  
  signal carry: STD_LOGIC_VECTOR(3 down to 0);
  signal op_carry: STD_LOGIC_VECTOR(2 down to 0);
  signal sum_buffer: STD_LOGIC_VECTOR(3 down to 0);
  signal carry_in: STD_LOGIC;
  
  
  begin
  
  slice_zero: alu_slice
  port map(
  --opcode(0) =&gt; op(0);
  --opcode(1) =&gt; op(1);
  --opcode(2) =&gt; op(2);
  a =&gt; a(0),
  b =&gt; b(0),
  s =&gt; s(0),
  --s =&gt; sum_buffer(0),
  cin =&gt; carry_in,
  cout=&gt;carry(0)
  );
  
  slice_one: alu_slice
  port map(
  --op(0) =&gt; opcode(0),
  --op(1) =&gt; opcode(1),
  --op(2) =&gt; opcode(2),
  a =&gt; a(1),
  b =&gt; b(1),
  s =&gt; s(1),
  --s =&gt; sum_buffer(1)
  cin =&gt; carry(0),
  cout =&gt; carry(1)
  );
  
  slice_two: alu_slice
  port map(
  --op(0) =&gt; opcode(0),
  --op(1) =&gt; opcode(1),
  --op(2) =&gt; opcode(2),
  a =&gt; a(2),
  b =&gt; b(2),
  s =&gt; s(2),
  --s =&gt; sum_buffer(2)
  cin =&gt; carry(1),
  cout =&gt; carry(2)
  );
  
  slice_three: alu_slice
  port map(
  --op(0) =&gt; opcode(0),
  --op(1) =&gt; opcode(1),
  --op(2) =&gt; opcode(2),
  a =&gt; a(3),
  b =&gt; b(3),
  s =&gt; s(3),
  --s =&gt; sum_buffer(3),
  cin =&gt; carry(2),
  cout =&gt; carry(3)
  );
  
  
  
  --op_carry(0) &lt;= op(0);
  --op_carry(1) &lt;= op(1);
  --op_carry(2) &lt;= op(2);
  
  
  
  end Behavioral;
  </code></pre>
  
  <p>There is some other commented code at the end before 'end behavioral' but I omitted them because they are irrelevant to the actual problem and are to with the conditions whereby some of the ports of the alu_pb entity are set (compl_overflow, overflow, zero etc.)</p>
  
  <p>If I try to simulate my model as is I get this error message:</p>
  
  <p>"ERROR: [VRFC 10-704] formal opcode has no actual or default value [U:/alu/alu_pb.vhd:63]".</p>
  
  <p>Hopefully one of you experienced VHDL guys will be able to help me track down a solution.</p>
  
  <p>Thanks in advance,</p>
  
  <p>Simon.  </p>