<- previous index next ->
The Arithmetic Logic Unit is the section of the CPU that actually performs add, subtract, multiply, divide, and, or, floating point and other operations. The choice of which operations are implemented is determined by the Instruction Set Architecture, ISA. Most modern computers separate the integer unit from the floating point unit. Many modern architectures have simple integer, complex integer, and an assortment of floating point units. The ALU gets inputs from registers reg_use.jpg Where did numbers such as 100010 for subop and 000010 for sllop come from ? cs411_opcodes.txt -- alu_start.vhdl library IEEE; use IEEE.std_logic_1164.all; entity alu_32 is port(inA : in std_logic_vector (31 downto 0); inB : in std_logic_vector (31 downto 0); inst : in std_logic_vector (31 downto 0); result : out std_logic_vector (31 downto 0)); end entity alu_32; architecture schematic of alu_32 is signal cin : std_logic := '0'; signal cout : std_logic; begin -- schematic -- -- REPLACE THIS SECTION FOR PROJECT PART 1 -- (add the signals you need above the "begin" -- add logic below the "begin") adder: entity WORK.add32 port map(a => inA, b => inB, -- change cin => cin, -- change sum => result, -- change cout => cout); -- examples of entity instantiations: -- bsh: entity WORK.bshift port map (left => sllop, -- logical => '1', -- shift => inst(10 downto 6), -- input => inB, -- output => bresult); -- r1: entity WORK.equal6 port map (inst => inst(31 downto 26), -- test => "000000", -- equal => rrop); -- s1: entity WORK.equal6 port map (inst => inst(5 downto 0), -- test => "100010", -- 34 -- equal => subop1); -- s1a: subop <= subop1 and rrop; -- S_sel <= sllop_or_srlop; -- for mux32_6 -- much more end architecture schematic; -- of alu_32 Many variations of subop, subop1, subop_and, subopa Your starter part1ce_start.vhdl uses subopa short for subop_and. part1ce_start.vhdl -- mux32_3.vhdl library IEEE; use IEEE.std_logic_1164.all; entity mux32_3 is port(in0 : in std_logic_vector (31 downto 0); in1 : in std_logic_vector (31 downto 0); in2 : in std_logic_vector (31 downto 0); ct1 : in std_logic; -- pass in1(has priority) ct2 : in std_logic; -- pass in2 result : out std_logic_vector (31 downto 0)); end entity mux32_3; architecture behavior of mux32_3 is begin -- behavior -- no process needed with concurrent statements result <= in1 when ct1='1' else in2 when ct2='1' else in0 after 50 ps; end architecture behavior; -- of mux32_3 -- mux_32_6.vhdl have only zero or one ctl ='1' library IEEE; use IEEE.std_logic_1164.all; entity mux_32_6 is port(in0 : in std_logic_vector (31 downto 0); in1 : in std_logic_vector (31 downto 0); in2 : in std_logic_vector (31 downto 0); in3 : in std_logic_vector (31 downto 0); in4 : in std_logic_vector (31 downto 0); in5 : in std_logic_vector (31 downto 0); ctl1 : in std_logic; ctl2 : in std_logic; ctl3 : in std_logic; ctl4 : in std_logic; ctl5 : in std_logic; result : out std_logic_vector (31 downto 0)); end entity mux_32_6; architecture behavior of mux_32_6 is begin -- behavior -- no process needed with concurrent statements result <= in1 when ctl1='1' else in2 when ctl2='1' else in3 when ctl3='1' else in4 when ctl4='1' else in5 when ctl5='1' else in0 after 10 ps; end architecture behavior; -- of mux_32_6 Note that bshift.vhdl contains two different architectures for the same entity. A behavioral architecture using sequential programming and a circuits architecture using digital logic components. bshift.vhdl An 8-bit version of shift right logical, using single bit signals, three bit shift count, is: There are many ways to build an ALU. Often the choice is based on mask making and requires a repeated pattern. The "bit slice" method uses the same structure for every bit. One example is: Note that 'Operation' is two bits, 0 for logical and, 1 for logical or, 2 for add or subtract, and 3 for an operation called set used for comparison. 'Binvert' and 'CarryIn' would be set to '1' for subtract. 'Binvert' and 'a' set to '0' would be complement. The overflow detection is in every stage yet only used in the last stage. The bit slices are wired together to form a simple ALU: The 'set' operation would give non zero if 'a' < 'b' and zero otherwise. A possible condition status or register value for a "beq" instruction. If overflow was to be detected, the circuit below uses the sign bit of the A and B inputs and the sign bit of the result to detect overflow on twos complement addition. The ALU fits into the machine architecture as shown below: 32-bit and 64-bit ALU architectures are available. A 64-bit architecture, by definition, has 64-bit integer registers. Many computers have had 64-bit IEEE floating point for many years. The 64-bit machines have been around for a while as the Alpha and PowerPC yet have become popular for the desktop with the Intel and AMD 64-bit machines. Software has been dragging well behind computer architecture. The chaos started in 1979 with the following "choices." The full whitepaper www.unix.org/whitepapers/64bit.html My desire is to have the compiler, linker and operating system be ILP64. All my code would work fine. I make no assumptions about word length. I use sizeof(int) sizeof(size_t) etc. when absolutely needed. On my 8GB computer I use a single array of over 4GB thus the subscripts must be 64-bit. The only option, I know of, for gcc is -m64 and that just gives LP64. Yuk! I have to change my source code and use "long" everywhere in place of "int". If you get the idea that I am angry with the compiler vendors, you are correct! Here are sample programs and output to test for 64-bit capability in gcc: Get sizeof on types and variables big.c output from gcc -m64 big.c big.out malloc more than 4GB big_malloc.c output from big_malloc_mac.out Newer Operating Systems and compilers (note 'sizeof' changed to long) Get sizeof on types and variables big12.c output from gcc big12.c big12.out The early 64-bit computers were: DEC Alpha DEC Alpha IBM PowerPC Some history of 64-bit computers: Java for 64-bit, source compatible Then to VHDL resource, FPGA. get free GHDL
<- previous index next ->