Help with creating a very small CPU

T

TweedleDee

Disclaimer: I'm fairly new to VHDL

I am trying to do operations on my accumulator using different bits of
the instruction register. For instance, bit 2 will clear A and bit 3
will increment A. I want these operations to be able to happen in one
cycle with one instruction in order (e.g. Clear A, then increment).
This piece of code is what I came up with but it will only do one of
the operations, not both. I could break these down into different
clock cycles, but I'm hoping there is a way to do it in one. Any
ideas?

process (clk) begin
if rising_edge (clk) then
if en_execute = '1' then
if IR(2) = '1' then --clear accumulator
A <= "00000000";
end if;

if IR(3) = '1' then --increment accumulator
A <= A + 1;
end if;
end if;
end if;
end process;
 
K

kennheinrich

Disclaimer: I'm fairly new to VHDL

I am trying to do operations on my accumulator using different bits of
the instruction register.  For instance, bit 2 will clear A and bit 3
will increment A.  I want these operations to be able to happen in one
cycle with one instruction in order (e.g. Clear A, then increment).
This piece of code is what I came up with but it will only do one of
the operations, not both.  I could break these down into different
clock cycles, but I'm hoping there is a way to do it in one.  Any
ideas?

process (clk) begin
    if rising_edge (clk) then
      if en_execute = '1' then
         if IR(2) = '1' then    --clear accumulator
            A <= "00000000";
         end if;

         if IR(3) = '1' then    --increment accumulator
            A <= A + 1;
         end if;
      end if;
    end if;
end process;


Variables can be used to hold intermediate results, so everything
happens in one clock cycle:

process (clk)
variable tmpA : T; -- T is whatever type A is
begin
if rising_edge (clk) then
if en_execute = '1' then
tmpA := A; -- starting off fresh!
if IR(2) = '1' then --clear accumulator
tmpA <= "00000000"; -- use tmpA!
end if;

if IR(3) = '1' then --increment accumulator
tmpA <= tmpA + 1; -- use tmpA!
end if;
A <= tmpA; -- all done!

end if;
end if;
end process;

Of course, if you want to dynamically change the order you'll need
more bits and more complicated decoding.

HTH,

- Kenn
 
K

kennheinrich

Variables can be used to hold intermediate results, so everything
happens in one clock cycle:

process (clk)
  variable tmpA : T; -- T is whatever type A is
begin
     if rising_edge (clk) then
       if en_execute = '1' then
          tmpA := A; -- starting off fresh!
          if IR(2) = '1' then    --clear accumulator
             tmpA <= "00000000"; -- use tmpA!
          end if;

          if IR(3) = '1' then    --increment accumulator
             tmpA <= tmpA + 1; -- use tmpA!
          end if;
        A <= tmpA; -- all done!

       end if;
     end if;
 end process;

Of course, if you want to dynamically change the order you'll need
more bits and more complicated decoding.

HTH,

 - Kenn

Oops, forgot to finish the edits! Variables are always assigned using
the ":=" instead of the "<=" operator, so change the above to read:

tmpA := "00000000"; -- use tmpA!

tmpA := tmpA + 1; -- use tmpA!


- Kenn
 
P

Pieter Hulshoff

TweedleDee said:
I am trying to do operations on my accumulator using different bits of
the instruction register. For instance, bit 2 will clear A and bit 3
will increment A. I want these operations to be able to happen in one
cycle with one instruction in order (e.g. Clear A, then increment).
This piece of code is what I came up with but it will only do one of
the operations, not both. I could break these down into different
clock cycles, but I'm hoping there is a way to do it in one. Any
ideas?

process (clk) begin
if rising_edge (clk) then
if en_execute = '1' then
if IR(2) = '1' then --clear accumulator
A <= "00000000";
end if;

if IR(3) = '1' then --increment accumulator
A <= A + 1;
end if;
end if;
end if;
end process;


IF ir(2) = '1' AND ir(3) = '1' THEN
a <= "00000001";
ELSIF ir(2) = '1' THEN
a <= "00000000";
ELSIF ir(3) = '1' THEN
a <= a + 1;
END IF;

or

CASE ir(3 DOWNTO 2) IS
WHEN "01" => a <= "00000000";
WHEN "10" => a <= a + 1;
WHEN "11" => a <= "00000001";
WHEN OTHERS => NULL;
END CASE;

Kind regards,

Pieter Hulshoff
 
J

jacko

Disclaimer: I'm fairly new to VHDL

I am trying to do operations on my accumulator using different bits of
the instruction register.  For instance, bit 2 will clear A and bit 3
will increment A.  I want these operations to be able to happen in one
cycle with one instruction in order (e.g. Clear A, then increment).
This piece of code is what I came up with but it will only do one of
the operations, not both.  I could break these down into different
clock cycles, but I'm hoping there is a way to do it in one.  Any
ideas?

process (clk) begin
    if rising_edge (clk) then
      if en_execute = '1' then
         if IR(2) = '1' then    --clear accumulator
            A <= "00000000";
         end if;

         if IR(3) = '1' then    --increment accumulator
            A <= A + 1;
         end if;
      end if;
    end if;
end process;

Do bare in mind that such a thing may expand to many cascaded logic
operations bypassed by a two way multiplexer, cascaded together. Such
an arrangement may reduce the Fmax of the CPU significantly. A full
expansion of the logic functions may lead to quite a large CPU, but
faster. You may find a pipeline at each stage (or IR bit) keeps the
size small (register in mux LUT cell), so no real extra logic appart
from delay line for bits of IR. Significant differences in execution
time of logic operations, can limit design Fmax to lowest speed of all
ops. Making the slowest op take 2 pipeline clocks can often boost
performance.

cheers jacko

http://nibz.googlecode.com VHDL microprocessor. *****<570 Altera
LEs***** (16 bit), 20MHz in C5 grade MAXIIZ, 40 I/O pins (programmable
direction), Clocked Counter...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top