-- Maura Dailey -- CSE 331 Section: 2 -- Homework 8 -- Disclaimer: I'm tired and I want to go to bed, so I'm making this short -- and to the point. You didn't say we had to use NANDs, NORs, and NOTs -- for the mux5x2, the 32 bit adders, or inside the datapath. So I didn't. -- I already commented all this code, except for the mux5x2, the pc, and -- the 32 bit adders. So I'm not doing it twice. I know how the clock works -- and thats the only thing that's been changed worth noting (outside of -- the fact that a few of the signals changed their types). yay. Page -- waaaaay down for commenting. --********************************************** -- Mux2x1 --********************************************** -- Delay is 5 ns. --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity mux2x1 is port (ins1, ins0 : in std_logic; sel : in std_logic; outs : out std_logic ); end mux2x1; architecture behavior of mux2x1 is signal t0,t1,nsel : std_logic; begin nsel <= not sel after 1 ns; t1 <= ins1 nand sel after 2 ns; t0 <= ins0 nand nsel after 2 ns; outs <= t1 nand t0 after 2 ns; end behavior; --********************************************** -- Mux32x2 --********************************************** -- Delay is 5 ns. -- No its not. --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity mux32x2 is port (inv1, inv0 : in std_logic_vector (31 downto 0); sel : in std_logic; outv : out std_logic_vector (31 downto 0)); end mux32x2; architecture behavior of mux32x2 is signal t0,t1 : std_logic_vector (31 downto 0); signal nsel : std_logic; begin nsel <= not sel after 1 ns; t1(0)<= inv1(0) nand sel after 2 ns; t1(1)<= inv1(1) nand sel after 2 ns; t1(2)<= inv1(2) nand sel after 2 ns; t1(3)<= inv1(3) nand sel after 2 ns; t1(4)<= inv1(4) nand sel after 2 ns; t1(5)<= inv1(5) nand sel after 2 ns; t1(6)<= inv1(6) nand sel after 2 ns; t1(7)<= inv1(7) nand sel after 2 ns; t1(8)<= inv1(8) nand sel after 2 ns; t1(9)<= inv1(9) nand sel after 2 ns; t1(10)<= inv1(10) nand sel after 2 ns; t1(11)<= inv1(11) nand sel after 2 ns; t1(12)<= inv1(12) nand sel after 2 ns; t1(13)<= inv1(13) nand sel after 2 ns; t1(14)<= inv1(14) nand sel after 2 ns; t1(15)<= inv1(15) nand sel after 2 ns; t1(16)<= inv1(16) nand sel after 2 ns; t1(17)<= inv1(17) nand sel after 2 ns; t1(18)<= inv1(18) nand sel after 2 ns; t1(19)<= inv1(19) nand sel after 2 ns; t1(20)<= inv1(20) nand sel after 2 ns; t1(21)<= inv1(21) nand sel after 2 ns; t1(22)<= inv1(22) nand sel after 2 ns; t1(23)<= inv1(23) nand sel after 2 ns; t1(24)<= inv1(24) nand sel after 2 ns; t1(25)<= inv1(25) nand sel after 2 ns; t1(26)<= inv1(26) nand sel after 2 ns; t1(27)<= inv1(27) nand sel after 2 ns; t1(28)<= inv1(28) nand sel after 2 ns; t1(29)<= inv1(29) nand sel after 2 ns; t1(30)<= inv1(30) nand sel after 2 ns; t1(31)<= inv1(31) nand sel after 2 ns; t0(0)<= inv0(0) nand nsel after 2 ns; t0(1)<= inv0(1) nand nsel after 2 ns; t0(2)<= inv0(2) nand nsel after 2 ns; t0(3)<= inv0(3) nand nsel after 2 ns; t0(4)<= inv0(4) nand nsel after 2 ns; t0(5)<= inv0(5) nand nsel after 2 ns; t0(6)<= inv0(6) nand nsel after 2 ns; t0(7)<= inv0(7) nand nsel after 2 ns; t0(8)<= inv0(8) nand nsel after 2 ns; t0(9)<= inv0(9) nand nsel after 2 ns; t0(10)<= inv0(10) nand nsel after 2 ns; t0(11)<= inv0(11) nand nsel after 2 ns; t0(12)<= inv0(12) nand nsel after 2 ns; t0(13)<= inv0(13) nand nsel after 2 ns; t0(14)<= inv0(14) nand nsel after 2 ns; t0(15)<= inv0(15) nand nsel after 2 ns; t0(16)<= inv0(16) nand nsel after 2 ns; t0(17)<= inv0(17) nand nsel after 2 ns; t0(18)<= inv0(18) nand nsel after 2 ns; t0(19)<= inv0(19) nand nsel after 2 ns; t0(20)<= inv0(20) nand nsel after 2 ns; t0(21)<= inv0(21) nand nsel after 2 ns; t0(22)<= inv0(22) nand nsel after 2 ns; t0(23)<= inv0(23) nand nsel after 2 ns; t0(24)<= inv0(24) nand nsel after 2 ns; t0(25)<= inv0(25) nand nsel after 2 ns; t0(26)<= inv0(26) nand nsel after 2 ns; t0(27)<= inv0(27) nand nsel after 2 ns; t0(28)<= inv0(28) nand nsel after 2 ns; t0(29)<= inv0(29) nand nsel after 2 ns; t0(30)<= inv0(30) nand nsel after 2 ns; t0(31)<= inv0(31) nand nsel after 2 ns; outv <= t1 nand t0 after 2 ns; end behavior; --********************************************** -- Mux4x1 --********************************************** -- Delay is 10 ns. --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity mux4x1 is port (inv : in std_logic_vector (3 downto 0); selv : in std_logic_vector (1 downto 0); outs : out std_logic ); end mux4x1; architecture structure of mux4x1 is signal s0, s1 : std_logic; component mux2x1 port (ins1, ins0 : in std_logic; sel : in std_logic; outs : out std_logic ); end component; for all : mux2x1 use entity work.mux2x1(behavior); begin m0 : mux2x1 port map (inv(1), inv(0), selv(0), s0); m1 : mux2x1 port map (inv(3), inv(2), selv(0), s1); m2 : mux2x1 port map (s1, s0, selv(1), outs); end structure; --********************************************** -- Register File --********************************************** library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_signed.all; entity regfile is port(write_data : in std_logic_vector (31 downto 0); src1_addr, src2_addr, dst_addr: in std_logic_vector (4 downto 0); write_cntrl: in std_logic; src1_data, src2_data: out std_logic_vector (31 downto 0)); end regfile; architecture process_behavior of regfile is type reg_array is array(0 to 31) of std_logic_vector (31 downto 0); begin regfile_process: process(src1_addr,src2_addr,write_cntrl) variable data_array: reg_array := ( (X"00000000"), -- $zero (X"00000000"), -- $at (X"00000000"), -- $v0 (X"00000000"), -- $v1 (X"00000000"), -- $a0 (X"00000000"), -- $a1 (X"00000000"), -- $a2 (X"00000000"), -- $a3 (X"00000000"), -- $t0 (X"00000000"), -- $t1 (X"00000000"), -- $t2 (X"00000000"), -- $t3 (X"00000000"), -- $t4 (X"00000000"), -- $t5 (X"00000000"), -- $t6 (X"00000000"), -- $t7 (X"00000000"), -- $s0 (X"00000000"), -- $s1 (X"00000000"), -- $s2 (X"00000000"), -- $s3 (X"00000000"), -- $s4 (X"00000000"), -- $s5 (X"00000000"), -- $s6 (X"00000000"), -- $s7 (X"00000000"), -- $t8 (X"00000000"), -- $t9 (X"00000000"), -- $k0 (X"00000000"), -- $k1 (X"00000000"), -- $gp (X"7fffffff"), -- $sp (X"10008000"), -- $fp (X"00000000")); -- $ra variable addrofsrc1, addrofsrc2, addrofdst: integer; variable p_src1_addr, p_src2_addr, p_dst_addr : std_logic_vector(5 downto 0); begin --pad address with a zero as conv_integer will take it as a signed value p_src1_addr(4 downto 0) := src1_addr(4 downto 0); p_src1_addr(5) := '0'; p_src2_addr(4 downto 0) := src2_addr(4 downto 0); p_src2_addr(5) := '0'; p_dst_addr(4 downto 0) := dst_addr(4 downto 0); p_dst_addr(5) := '0'; addrofsrc1 := conv_integer(p_src1_addr); addrofsrc2 := conv_integer(p_src2_addr); addrofdst := conv_integer(p_dst_addr); if (write_cntrl'event and write_cntrl = '0') then if (addrofdst /= 0) then data_array(addrofdst) := write_data; end if; end if; src1_data <= data_array(addrofsrc1) after 100 ns; src2_data <= data_array(addrofsrc2) after 100 ns; end process regfile_process; end process_behavior; --********************************************** -- Clock --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity clock is port(o : out std_logic); end clock; architecture process_behavior of clock is begin clock_process : process begin o <= '0', '1' after 424 ns; -- See, I changed it wait for 848 ns; -- I changed this too! end process clock_process; end process_behavior; --********************************************** -- FULL_ADDER --********************************************** -- Delay of cout is 7 ns; -- Delay of sum is 9 ns; --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity full_adder is port(a,b,cin : in std_logic; sum,cout: out std_logic); end full_adder; architecture behavior of full_adder is signal s0,s1,s2,s3,s4,s5,s6,s7 : std_logic; signal s8,s9,sa,sb,sc,sd,se : std_logic; begin s0 <= not (a) after 1 ns; s1 <= not (b) after 1 ns; s2 <= not (cin) after 1 ns; s3 <= s1 nand cin after 2 ns; s4 <= b nand s2 after 2 ns; s5 <= s1 nand s2 after 2 ns; s6 <= b nand cin after 2 ns; s7 <= s3 nand s4 after 2 ns; s8 <= s5 nand s6 after 2 ns; s9 <= s0 nand s7 after 2 ns; sa <= a nand s8 after 2 ns; sum <= s9 nand sa after 2 ns; sb <= a nand cin after 2 ns; sc <= a nand b after 2 ns; sd <= s6 nand sb after 2 ns; se <= not (sd) after 1 ns; cout<= se nand sc after 2 ns; end behavior; --********************************************** -- 1 BIT ALU ( NOT SIGNIFICANT BIT ) --********************************************** -- Delay of resdult is 25 ns; -- Delay of cout is 13 ns; --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity alu1bit is port(a,b,less,binvert,cin : in std_logic; op1,op0 : in std_logic; result,cout: out std_logic); end alu1bit; architecture structure_behavior of alu1bit is signal s0,s1,s2,s3,s4,s5,s6,s7,s8 : std_logic; component full_adder port(a,b,cin : in std_logic; sum,cout: out std_logic); end component; component mux2x1 port (ins1, ins0 : in std_logic; sel : in std_logic; outs : out std_logic ); end component; component mux4x1 port (inv : in std_logic_vector (3 downto 0); selv : in std_logic_vector (1 downto 0); outs : out std_logic ); end component; for all : full_adder use entity work.full_adder(behavior); for all : mux4x1 use entity work.mux4x1(structure); for all : mux2x1 use entity work.mux2x1(behavior); begin s0 <= not (b) after 1 ns; m1 : mux2x1 port map (s0,b,binvert,s1); s2 <= not (s1) after 1 ns; s3 <= not (a) after 1 ns; s4 <= s2 nand a after 2 ns; s5 <= s1 nand s3 after 2 ns; s6 <= s4 nand s5 after 2 ns; s7 <= a nor s1 after 2 ns; f1 : full_adder port map (a,s1,cin,s8,cout); m2 : mux4x1 port map (inv(3)=>less,inv(2)=>s8,inv(1)=>s7,inv(0)=>s6, selv(1)=>op1,selv(0)=>op0,outs=>result); end structure_behavior; --********************************************** -- 1 BIT ALU ( THE SIGNIFICANT BIT ) --********************************************** -- Delay of result is 25 ns; -- Delay of set is 15 ns; -- Delay of overflow is 18 ns; --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity alu1bit_s is port(a,b,less,binvert,cin : in std_logic; op1,op0 : in std_logic; result,set,overflow: out std_logic); end alu1bit_s; architecture structure_behavior of alu1bit_s is signal s0,s1,s2,s3,s4,s5,s6,s7,s8,s9 : std_logic; signal sa,sb,sc,sd : std_logic; component full_adder port(a,b,cin : in std_logic; sum,cout: out std_logic); end component; component mux2x1 port (ins1, ins0 : in std_logic; sel : in std_logic; outs : out std_logic ); end component; component mux4x1 port (inv : in std_logic_vector (3 downto 0); selv : in std_logic_vector (1 downto 0); outs : out std_logic ); end component; for all : full_adder use entity work.full_adder(behavior); for all : mux4x1 use entity work.mux4x1(structure); for all : mux2x1 use entity work.mux2x1(behavior); begin s0 <= not (b) after 1 ns; m1 : mux2x1 port map (s0,b,binvert,s1); s2 <= not (s1) after 1 ns; s3 <= not (a) after 1 ns; s4 <= s2 nand a after 2 ns; s5 <= s1 nand s3 after 2 ns; s6 <= s4 nand s5 after 2 ns; s7 <= a nor s1 after 2 ns; f1 : full_adder port map (a,s1,cin,s8,s9); m2 : mux4x1 port map (inv(3)=>less,inv(2)=>s8,inv(1)=>s7,inv(0)=>s6, selv(1)=>op1,selv(0)=>op0,outs=>result); set <= s8; sa <= not (s9) after 1 ns; sb <= not (cin) after 1 ns; sc <= s9 nand sb after 2 ns; sd <= sa nand cin after 2 ns; overflow <= sc nand sd after 2 ns; end structure_behavior; --********************************************** -- DETECT0 --********************************************** -- delay of output is 10 ns; --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity detect0 is port(input :in std_logic_vector(31 downto 0); output:out std_logic); end detect0; architecture behavior of detect0 is signal s0,s1,s2,s3,s4,s5,s6,s7:std_logic; signal s8,s9,sa,sb,sc,sd,se,sf:std_logic; signal t0,t1,t2,t3,t4,t5,t6,t7:std_logic; signal u0,u1,u2,u3,v0,v1:std_logic; begin s0 <= input(0) nor input(1) after 2 ns; s1 <= input(2) nor input(3) after 2 ns; s2 <= input(4) nor input(5) after 2 ns; s3 <= input(6) nor input(7) after 2 ns; s4 <= input(8) nor input(9) after 2 ns; s5 <= input(10) nor input(11) after 2 ns; s6 <= input(12) nor input(13) after 2 ns; s7 <= input(14) nor input(15) after 2 ns; s8 <= input(16) nor input(17) after 2 ns; s9 <= input(18) nor input(19) after 2 ns; sa <= input(20) nor input(21) after 2 ns; sb <= input(22) nor input(23) after 2 ns; sc <= input(24) nor input(25) after 2 ns; sd <= input(26) nor input(27) after 2 ns; se <= input(28) nor input(29) after 2 ns; sf <= input(30) nor input(31) after 2 ns; t0 <= s0 nand s1 after 2 ns; t1 <= s2 nand s3 after 2 ns; t2 <= s4 nand s5 after 2 ns; t3 <= s6 nand s7 after 2 ns; t4 <= s8 nand s9 after 2 ns; t5 <= sa nand sb after 2 ns; t6 <= sc nand sd after 2 ns; t7 <= se nand sf after 2 ns; u0 <= t0 nor t1 after 2 ns; u1 <= t2 nor t3 after 2 ns; u2 <= t4 nor t5 after 2 ns; u3 <= t6 nor t7 after 2 ns; v0 <= u0 nand u1 after 2 ns; v1 <= u2 nand u3 after 2 ns; output <= v0 nor v1 after 2 ns; end behavior; --********************************************** -- 32 BIT ALU --********************************************** -- Delay of result is 242 ns; -- Delay of zero is 252 ns; -- Delay of overflow is 235 ns; --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity alu32bit is port(a,b : in std_logic_vector (31 downto 0); op2,op1,op0 : in std_logic; result : out std_logic_vector (31 downto 0); zero,overflow: out std_logic); end alu32bit; architecture structure_behavior of alu32bit is signal s0,s1,t0 : std_logic; signal r : std_logic_vector(31 downto 0); signal cout0,cout1,cout2,cout3,cout4,cout5: std_logic; signal cout6,cout7,cout8,cout9,cout10: std_logic; signal cout11,cout12,cout13,cout14,cout15: std_logic; signal cout16,cout17,cout18,cout19,cout20: std_logic; signal cout21,cout22,cout23,cout24,cout25: std_logic; signal cout26,cout27,cout28,cout29,cout30: std_logic; component alu1bit port(a,b,less,binvert,cin : in std_logic; op1,op0 : in std_logic; result,cout: out std_logic); end component; component alu1bit_s port(a,b,less,binvert,cin : in std_logic; op1,op0 : in std_logic; result,set,overflow: out std_logic); end component; component detect0 port(input :in std_logic_vector(31 downto 0); output:out std_logic); end component; for all : alu1bit use entity work.alu1bit(structure_behavior); for all : alu1bit_s use entity work.alu1bit_s(structure_behavior); for all : detect0 use entity work.detect0(behavior); begin t0 <= '0'; a00 : alu1bit port map(a(0),b(0),s0,op2,op2,op1,op0,r(0),cout0); a01 : alu1bit port map(a(1),b(1),t0,op2,cout0,op1,op0,r(1),cout1); a02 : alu1bit port map(a(2),b(2),t0,op2,cout1,op1,op0,r(2),cout2); a03 : alu1bit port map(a(3),b(3),t0,op2,cout2,op1,op0,r(3),cout3); a04 : alu1bit port map(a(4),b(4),t0,op2,cout3,op1,op0,r(4),cout4); a05 : alu1bit port map(a(5),b(5),t0,op2,cout4,op1,op0,r(5),cout5); a06 : alu1bit port map(a(6),b(6),t0,op2,cout5,op1,op0,r(6),cout6); a07 : alu1bit port map(a(7),b(7),t0,op2,cout6,op1,op0,r(7),cout7); a08 : alu1bit port map(a(8),b(8),t0,op2,cout7,op1,op0,r(8),cout8); a09 : alu1bit port map(a(9),b(9),t0,op2,cout8,op1,op0,r(9),cout9); a10 : alu1bit port map(a(10),b(10),t0,op2,cout9,op1,op0,r(10),cout10); a11 : alu1bit port map(a(11),b(11),t0,op2,cout10,op1,op0,r(11),cout11); a12 : alu1bit port map(a(12),b(12),t0,op2,cout11,op1,op0,r(12),cout12); a13 : alu1bit port map(a(13),b(13),t0,op2,cout12,op1,op0,r(13),cout13); a14 : alu1bit port map(a(14),b(14),t0,op2,cout13,op1,op0,r(14),cout14); a15 : alu1bit port map(a(15),b(15),t0,op2,cout14,op1,op0,r(15),cout15); a16 : alu1bit port map(a(16),b(16),t0,op2,cout15,op1,op0,r(16),cout16); a17 : alu1bit port map(a(17),b(17),t0,op2,cout16,op1,op0,r(17),cout17); a18 : alu1bit port map(a(18),b(18),t0,op2,cout17,op1,op0,r(18),cout18); a19 : alu1bit port map(a(19),b(19),t0,op2,cout18,op1,op0,r(19),cout19); a20 : alu1bit port map(a(20),b(20),t0,op2,cout19,op1,op0,r(20),cout20); a21 : alu1bit port map(a(21),b(21),t0,op2,cout20,op1,op0,r(21),cout21); a22 : alu1bit port map(a(22),b(22),t0,op2,cout21,op1,op0,r(22),cout22); a23 : alu1bit port map(a(23),b(23),t0,op2,cout22,op1,op0,r(23),cout23); a24 : alu1bit port map(a(24),b(24),t0,op2,cout23,op1,op0,r(24),cout24); a25 : alu1bit port map(a(25),b(25),t0,op2,cout24,op1,op0,r(25),cout25); a26 : alu1bit port map(a(26),b(26),t0,op2,cout25,op1,op0,r(26),cout26); a27 : alu1bit port map(a(27),b(27),t0,op2,cout26,op1,op0,r(27),cout27); a28 : alu1bit port map(a(28),b(28),t0,op2,cout27,op1,op0,r(28),cout28); a29 : alu1bit port map(a(29),b(29),t0,op2,cout28,op1,op0,r(29),cout29); a30 : alu1bit port map(a(30),b(30),t0,op2,cout29,op1,op0,r(30),cout30); a31 : alu1bit_s port map(a(31),b(31),t0,op2,cout30,op1,op0,r(31),s0,s1); d0 : detect0 port map(r,zero); result <= r; overflow <= s1; end structure_behavior; --********************************************** -- Instruction Memory --********************************************** library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_signed.all; entity Instr_Memory is port (Read_Addr: in std_logic_vector (31 downto 0); Instr: out std_logic_vector (31 downto 0)); end Instr_Memory; architecture process_behavior of Instr_Memory is type mem_array is array(0 to 9) of std_logic_vector (31 downto 0); begin Instr_Memory_process: process(Read_Addr) variable code_array: mem_array := ( (X"8D080010"), (X"8D090008"), (X"01095026"), (X"01095827"), (X"01096020"), (X"AC0C0000"), (X"11890002"), (X"01886022"), (X"08000006"), (X"00000000")); variable byteaddr,wordaddr:integer; begin byteaddr := conv_integer(Read_Addr); wordaddr := byteaddr / 4; Instr <= code_array(wordaddr) after 200 ns; end process Instr_Memory_process; end process_behavior; --********************************************** -- Data Memory --********************************************** library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_signed.all; entity Data_Memory is port (Address, Write_Data : in std_logic_vector (31 downto 0); MemWrite, MemRead : in std_logic; Read_Data : out std_logic_vector (31 downto 0)); end Data_Memory; architecture process_behavior of Data_Memory is type mem_array is array(0 to 7) of std_logic_vector (31 downto 0); begin Data_Memory_process: process(Address,MemWrite,MemRead) variable data_array: mem_array := ( (X"00000000"), (X"00000001"), (X"00000002"), (X"00000003"), (X"00000004"), (X"00000005"), (X"00000006"), (X"00000007")); variable byteaddr,wordaddr:integer; variable start : std_logic := '1'; begin byteaddr := conv_integer(Address); wordaddr := byteaddr / 4; if(MemWrite'event and MemWrite = '0') then if (start ='0') then data_array(wordaddr) := Write_Data; else start := '0'; end if; end if; if(MemRead = '1') then Read_Data <= data_array(wordaddr) after 200 ns; end if; end process Data_Memory_process; end process_behavior; --********************************************** -- Main Control --********************************************** -- Delay is 10 ns. --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity maincontrol is port(inv : in std_logic_vector(5 downto 0); Jump,RegDst,ALUsrc,MemtoReg : out std_logic; RegWrite,MemRead,MemWrite,Branch : out std_logic; ALUop : out std_logic_vector(1 downto 0)); end maincontrol; architecture behavior of maincontrol is signal t : std_logic_vector(30 downto 0); signal ninv : std_logic_vector(5 downto 0); begin ninv <= not inv after 1 ns; t(0) <= inv(5) nor inv(4) after 2 ns; t(1) <= inv(3) nor inv(2) after 2 ns; t(2) <= inv(1) nor inv(0) after 2 ns; t(3) <= t(0) nand t(1) after 2 ns; t(4) <= not t(2) after 1 ns; t(5) <= t(3) nor t(4) after 2 ns; t(6) <= ninv(5) nor inv(4) after 2 ns; t(7) <= inv(3) nor inv(2) after 2 ns; t(8) <= ninv(1) nor ninv(0) after 2 ns; t(9) <= t(6) nand t(7) after 2 ns; t(10) <= not t(8) after 1 ns; t(11) <= t(9) nor t(10) after 2 ns; t(12) <= ninv(5) nor inv(4) after 2 ns; t(13) <= ninv(3) nor inv(2) after 2 ns; t(14) <= ninv(1) nor ninv(0) after 2 ns; t(15) <= t(12) nand t(13) after 2 ns; t(16) <= not t(14) after 1 ns; t(17) <= t(15) nor t(16) after 2 ns; t(18) <= inv(5) nor inv(4) after 2 ns; t(19) <= inv(3) nor ninv(2) after 2 ns; t(20) <= inv(1) nor inv(0) after 2 ns; t(21) <= t(18) nand t(19) after 2 ns; t(22) <= not t(20) after 1 ns; t(23) <= t(21) nor t(22) after 2 ns; t(24) <= inv(5) nor inv(4) after 2 ns; t(25) <= inv(3) nor inv(2) after 2 ns; t(26) <= ninv(1) nor inv(0) after 2 ns; t(27) <= t(24) nand t(25) after 2 ns; t(28) <= not t(26) after 1 ns; Jump <= t(27) nor t(28) after 2 ns; RegDst <= t(5); t(29) <= t(11) nor t(17) after 2 ns; ALUSrc <= not t(29) after 1 ns; MemtoReg <= t(11); t(30) <= t(5) nor t(11) after 2 ns; RegWrite<= not t(30) after 1 ns; MemRead <= t(11); MemWrite<= t(17); Branch<= t(23); ALUop(1)<= t(5); ALUop(0)<= t(23); end behavior; --********************************************** -- ALU Control --********************************************** -- Delay is 7 ns. --********************************************** library IEEE; use IEEE.std_logic_1164.all; entity alucontrol is port(inv : in std_logic_vector(5 downto 0); ALUop : in std_logic_vector(1 downto 0); outv : out std_logic_vector(2 downto 0)); end alucontrol; architecture behavior of alucontrol is signal nop : std_logic_vector(1 downto 0); signal ninv : std_logic_vector(5 downto 0); signal s1,s2,s3 : std_logic; begin nop <= not ALUop after 1 ns; ninv <= not inv after 1 ns; s1 <= ninv(1) nor inv(2) after 2 ns; s2 <= ALUop(1) nand s1 after 2 ns; outv(2) <= s2 nand nop(0) after 2 ns; outv(1) <= ALUop(1) nand inv(2) after 2 ns; s3 <= inv(3) nor inv(0) after 2 ns; outv(0) <= s3 nor nop(1) after 2 ns; end behavior; ----------------------------------------------------------------------- -- Mux5x2 -- Expected Behavior : Two 5 bit inputs are chosen by a 1 bit selector library IEEE; use IEEE.std_logic_1164.all; entity mux5x2 is -- This is an entity port (inv1, inv0 : in std_logic_vector (4 downto 0); sel : in std_logic; outv : out std_logic_vector (4 downto 0)); end mux5x2; architecture behavior of mux5x2 is -- this entity does the following: signal Tinv1, Tinv0 : std_logic_vector (4 downto 0); signal selbar : std_logic; begin selbar <= not sel after 1 ns; Tinv0(0) <= inv0(0) nand selbar after 2 ns; -- basically, we do a bunch of nand-ing Tinv0(1) <= inv0(1) nand selbar after 2 ns; -- intended to either eliminate the first Tinv0(2) <= inv0(2) nand selbar after 2 ns; -- signal or the second signal from the Tinv0(3) <= inv0(3) nand selbar after 2 ns; -- rankings. then we set that to the output Tinv0(4) <= inv0(4) nand selbar after 2 ns; Tinv1(0) <= inv1(0) nand sel after 2 ns; Tinv1(1) <= inv1(1) nand sel after 2 ns; Tinv1(2) <= inv1(2) nand sel after 2 ns; Tinv1(3) <= inv1(3) nand sel after 2 ns; Tinv1(4) <= inv1(4) nand sel after 2 ns; outv(0) <= Tinv1(0) nand Tinv0(0) after 2 ns; outv(1) <= Tinv1(1) nand Tinv0(1) after 2 ns; outv(2) <= Tinv1(2) nand Tinv0(2) after 2 ns; outv(3) <= Tinv1(3) nand Tinv0(3) after 2 ns; outv(4) <= Tinv1(4) nand Tinv0(4) after 2 ns; end behavior; -- PC -- Expected Behavior: Simple memory initializes to zero, then politely waits -- for the clock to turn to zero and writes a new value. Unless of course, -- its zero for the first time. Because we don't want it to overwrite its -- initial zero value inside. library IEEE; use IEEE.std_logic_1164.all; entity pc is port (clock: in std_logic; input : in std_logic_vector(31 downto 0); output: out std_logic_vector(31 downto 0)); end pc; architecture behavior of pc is begin pc_process: process(input,clock) -- Process for PC variable start : std_logic := '1'; -- Magic variable that lets us -- ensure that PC won't get written -- to when the clock is initialized -- for the first time. variable pc_pointer : std_logic_vector(31 downto 0) := x"00000000"; -- And of course, we initialize to 0 begin if (clock'event and clock = '0') -- It's an if statement. It makes then -- sure to write to PC when clock if (start = '0') -- turns 0, but only if its not then -- been initialized for the first time pc_pointer := input; else start := '0'; end if; end if; output <= pc_pointer; -- TADA! Output the contents of PC end process pc_process; end behavior; -- Adder32bit (So named because VHDL wasn't very fond of 32bitadder) -- Expected Behavior : Two 32 bit numbers are added. Yay. A 32 output results. -- There is a delay of 100 ns. Cin and cout are also present. library IEEE; use IEEE.std_logic_1164.all; entity adder32bit is -- An entity! Huzzah for adders! port(a,b : in std_logic_vector(31 downto 0); cin : in std_logic; sum : out std_logic_vector(31 downto 0); cout : out std_logic); end adder32bit; architecture behavior of adder32bit is begin adder32bit_process : process(a,b,cin) -- And here's the process that makes it -- all possible variable result : std_logic_vector(31 downto 0); variable scin : std_logic; begin scin := cin; result(0) := ((a(0) xor b(0) xor scin) or (a(0) and b(0) and scin)); -- This is a bit hideous, but it scin := (a(0) and b(0)) or (a(0) and scin) or (b(0) and scin); -- works. Go figure. Anyway, this -- goes on for the next 31 bits as -- well. result(1) := ((a(1) xor b(1) xor scin) or (a(1) and b(1) and scin)); scin := (a(1) and b(1)) or (a(1) and scin) or (b(1) and scin); result(2) := ((a(2) xor b(2) xor scin) or (a(2) and b(2) and scin)); scin := (a(2) and b(2)) or (a(2) and scin) or (b(2) and scin); result(3) := ((a(3) xor b(3) xor scin) or (a(3) and b(3) and scin)); scin := (a(3) and b(3)) or (a(3) and scin) or (b(3) and scin); result(4) := ((a(4) xor b(4) xor scin) or (a(4) and b(4) and scin)); scin := (a(4) and b(4)) or (a(4) and scin) or (b(4) and scin); result(5) := ((a(5) xor b(5) xor scin) or (a(5) and b(5) and scin)); scin := (a(5) and b(5)) or (a(5) and scin) or (b(5) and scin); result(6) := ((a(6) xor b(6) xor scin) or (a(6) and b(6) and scin)); scin := (a(6) and b(6)) or (a(6) and scin) or (b(6) and scin); result(7) := ((a(7) xor b(7) xor scin) or (a(7) and b(7) and scin)); scin := (a(7) and b(7)) or (a(7) and scin) or (b(7) and scin); result(8) := ((a(8) xor b(8) xor scin) or (a(8) and b(8) and scin)); scin := (a(8) and b(8)) or (a(8) and scin) or (b(8) and scin); result(9) := ((a(9) xor b(9) xor scin) or (a(9) and b(9) and scin)); scin := (a(9) and b(9)) or (a(9) and scin) or (b(9) and scin); result(10) := ((a(10) xor b(10) xor scin) or (a(10) and b(10) and scin)); scin := (a(10) and b(10)) or (a(10) and scin) or (b(10) and scin); result(11) := ((a(11) xor b(11) xor scin) or (a(11) and b(11) and scin)); scin := (a(11) and b(11)) or (a(11) and scin) or (b(11) and scin); result(12) := ((a(12) xor b(12) xor scin) or (a(12) and b(12) and scin)); scin := (a(12) and b(12)) or (a(12) and scin) or (b(12) and scin); result(13) := ((a(13) xor b(13) xor scin) or (a(13) and b(13) and scin)); scin := (a(13) and b(13)) or (a(13) and scin) or (b(13) and scin); result(14) := ((a(14) xor b(14) xor scin) or (a(14) and b(14) and scin)); scin := (a(14) and b(14)) or (a(14) and scin) or (b(14) and scin); result(15) := ((a(15) xor b(15) xor scin) or (a(15) and b(15) and scin)); scin := (a(15) and b(15)) or (a(15) and scin) or (b(15) and scin); result(16) := ((a(16) xor b(16) xor scin) or (a(16) and b(16) and scin)); scin := (a(16) and b(16)) or (a(16) and scin) or (b(16) and scin); result(17) := ((a(17) xor b(17) xor scin) or (a(17) and b(17) and scin)); scin := (a(17) and b(17)) or (a(17) and scin) or (b(17) and scin); result(18) := ((a(18) xor b(18) xor scin) or (a(18) and b(18) and scin)); scin := (a(18) and b(18)) or (a(18) and scin) or (b(18) and scin); result(19) := ((a(19) xor b(19) xor scin) or (a(19) and b(19) and scin)); scin := (a(19) and b(19)) or (a(19) and scin) or (b(19) and scin); result(20) := ((a(20) xor b(20) xor scin) or (a(20) and b(20) and scin)); scin := (a(20) and b(20)) or (a(20) and scin) or (b(20) and scin); result(21) := ((a(21) xor b(21) xor scin) or (a(21) and b(21) and scin)); scin := (a(21) and b(21)) or (a(21) and scin) or (b(21) and scin); result(22) := ((a(22) xor b(22) xor scin) or (a(22) and b(22) and scin)); scin := (a(22) and b(22)) or (a(22) and scin) or (b(22) and scin); result(23) := ((a(23) xor b(23) xor scin) or (a(23) and b(23) and scin)); scin := (a(23) and b(23)) or (a(23) and scin) or (b(23) and scin); result(24) := ((a(24) xor b(24) xor scin) or (a(24) and b(24) and scin)); scin := (a(24) and b(24)) or (a(24) and scin) or (b(24) and scin); result(25) := ((a(25) xor b(25) xor scin) or (a(25) and b(25) and scin)); scin := (a(25) and b(25)) or (a(25) and scin) or (b(25) and scin); result(26) := ((a(26) xor b(26) xor scin) or (a(26) and b(26) and scin)); scin := (a(26) and b(26)) or (a(26) and scin) or (b(26) and scin); result(27) := ((a(27) xor b(27) xor scin) or (a(27) and b(27) and scin)); scin := (a(27) and b(27)) or (a(27) and scin) or (b(27) and scin); result(28) := ((a(28) xor b(28) xor scin) or (a(28) and b(28) and scin)); scin := (a(28) and b(28)) or (a(28) and scin) or (b(28) and scin); result(29) := ((a(29) xor b(29) xor scin) or (a(29) and b(29) and scin)); scin := (a(29) and b(29)) or (a(29) and scin) or (b(29) and scin); result(30) := ((a(30) xor b(30) xor scin) or (a(30) and b(30) and scin)); scin := (a(30) and b(30)) or (a(30) and scin) or (b(30) and scin); result(31) := ((a(31) xor b(31) xor scin) or (a(31) and b(31) and scin)); scin := (a(31) and b(31)) or (a(31) and scin) or (b(31) and scin); sum <= result after 100 ns; -- OK, we're done. Output cout <= scin after 100 ns; -- the sum and cout. end process adder32bit_process; end behavior; -- Datapath -- Expected Behavior : Instructions placed in the instruction memory will be executed. Things -- may appear in the register file or data memory. PC will increment. And it will all be glued -- together with a falling edge clock. library IEEE; use IEEE.std_logic_1164.all; entity datapath is end datapath; architecture behavior of datapath is signal pc_input,pc_value,pc_next,four,instruct,reg_write_data,reg_read1,reg_read2,instruct_itype,instruct_branch,instruct_jump,alu_input,pcorbranch,alu_out,dm_read,branch_addr : std_logic_vector(31 downto 0); -- These are 32 bit signals signal instruct_control,instruct_alu : std_logic_vector(5 downto 0); -- These are 6 bit signals signal instruct_read1,instruct_read2,instruct_write,reg_write_addr : std_logic_vector(4 downto 0); -- These are 5 bit signals signal opcodes : std_logic_vector(2 downto 0); -- These are 3 bit signals signal aluop : std_logic_vector(1 downto 0); -- These are 2 bit signals signal clk,junk0,junk1,zro,zero,overflow,jump,regdst,alusrc,memtoreg,regwrite,memread,memwrite,branch,reg_trigger,data_trigger,pcsrc : std_logic; -- These are 1 bit signals component mux5x2 -- Here's our special MUX created port(inv1,inv0 : in std_logic_vector(4 downto 0); -- just for this entity! Wow! sel : in std_logic; outv : out std_logic_vector(4 downto 0)); end component; for all : mux5x2 use entity work.mux5x2(behavior); component mux32x2 -- And this MUX is a return visitor... port(inv1,inv0 : in std_logic_vector(31 downto 0); sel : in std_logic; outv : out std_logic_vector(31 downto 0)); end component; for all : mux32x2 use entity work.mux32x2(behavior); component regfile -- The register file stores and retrieves port(write_data : in std_logic_vector(31 downto 0); -- from a limited bank of memory locations src1_addr,src2_addr,dst_addr : in std_logic_vector(4 downto 0); write_cntrl : in std_logic; src1_data,src2_data : out std_logic_vector(31 downto 0)); end component; for all : regfile use entity work.regfile(process_behavior); component clock -- This clock has been modified from what was port(o : out std_logic); -- given, as per question number 2 end component; for all : clock use entity work.clock(process_behavior); component alu32bit -- This is our trusty ALU. It can add, subtract, port(a,b : in std_logic_vector(31 downto 0); -- XOR, and NOR. Not a standard ALU. op2,op1,op0 : in std_logic; result : out std_logic_vector(31 downto 0); zero,overflow : out std_logic); end component; for all : alu32bit use entity work.alu32bit(structure_behavior); component instr_memory -- Put instructions to be executed here, preferably port(read_addr : in std_logic_vector(31 downto 0); -- in hex, unless you're just masochistic. instr : out std_logic_vector(31 downto 0)); end component; for all : instr_memory use entity work.instr_memory(process_behavior); component data_memory -- Data can be stored and retrieved from this memory port(address,write_data : in std_logic_vector(31 downto 0); memwrite,memread : in std_logic; read_data : out std_logic_vector(31 downto 0)); end component; for all : data_memory use entity work.data_memory(process_behavior); component maincontrol -- This device just pumps out binary signals that tell port(inv : in std_logic_vector(5 downto 0); -- everything else what to do jump,regdst,alusrc,memtoreg : out std_logic; regwrite,memread,memwrite,branch : out std_logic; aluop : out std_logic_vector(1 downto 0)); end component; for all : maincontrol use entity work.maincontrol(behavior); component alucontrol -- This is main control's little brother. He tells the port(inv : in std_logic_vector(5 downto 0); -- ALU what to do. aluop : in std_logic_vector(1 downto 0); outv : out std_logic_vector(2 downto 0)); end component; for all : alucontrol use entity work.alucontrol(behavior); component pc -- This is a very simple memory that stores the address port(clock : in std_logic; -- of the current instnuction. input : in std_logic_vector(31 downto 0); output : out std_logic_vector(31 downto 0)); end component; for all : pc use entity work.pc(behavior); component adder32bit -- I kept PC adder and that Branch Adder very generic so port(a,b : in std_logic_vector(31 downto 0); -- they could share one reusable component. I'm smart cin : in std_logic; -- that way. sum : out std_logic_vector(31 downto 0); cout : out std_logic); end component; for all : adder32bit use entity work.adder32bit(behavior); begin four <= "00000000000000000000000000000100"; -- It's the number four. Duh. zro <= '0'; -- zeeeee rohhhh. :) clok : clock port map(clk); -- My clock! pc_mem : pc port map(clk,pc_input,pc_value); -- My PC! pc_adder : adder32bit port map(pc_value,four,zro,pc_next,junk0); -- The adder that increments PC! imemory : instr_memory port map(pc_value,instruct); -- Stores instructions and passes them to its -- friends (register file, adders, muxes, etc) instruct_read1(0) <= instruct(21); -- We're realigning signals here. Register, instruct_read1(1) <= instruct(22); -- Read Addr One instruct_read1(2) <= instruct(23); instruct_read1(3) <= instruct(24); instruct_read1(4) <= instruct(25); instruct_write(0) <= instruct(11); -- Input to that 5x2mux going into write_addr instruct_write(1) <= instruct(12); instruct_write(2) <= instruct(13); instruct_write(3) <= instruct(14); instruct_write(4) <= instruct(15); instruct_read2(0) <= instruct(16); -- Read Addr Two instruct_read2(1) <= instruct(17); instruct_read2(2) <= instruct(18); instruct_read2(3) <= instruct(19); instruct_read2(4) <= instruct(20); instruct_control(0) <= instruct(26); -- 6 bit input to maincontrol instruct_control(1) <= instruct(27); instruct_control(2) <= instruct(28); instruct_control(3) <= instruct(29); instruct_control(4) <= instruct(30); instruct_control(5) <= instruct(31); instruct_alu(0) <= instruct(0); -- 6 bit input to alucontrol instruct_alu(1) <= instruct(1); instruct_alu(2) <= instruct(2); instruct_alu(3) <= instruct(3); instruct_alu(4) <= instruct(4); instruct_alu(5) <= instruct(5); instruct_itype(0) <= instruct(0); -- Sign extended 16 rightmost bits instruct_itype(1) <= instruct(1); instruct_itype(2) <= instruct(2); instruct_itype(3) <= instruct(3); instruct_itype(4) <= instruct(4); instruct_itype(5) <= instruct(5); instruct_itype(6) <= instruct(6); instruct_itype(7) <= instruct(7); instruct_itype(8) <= instruct(8); instruct_itype(9) <= instruct(9); instruct_itype(10) <= instruct(10); instruct_itype(11) <= instruct(11); instruct_itype(12) <= instruct(12); instruct_itype(13) <= instruct(13); instruct_itype(14) <= instruct(14); instruct_itype(15) <= instruct(15); instruct_itype(16) <= instruct(15); instruct_itype(17) <= instruct(15); instruct_itype(18) <= instruct(15); instruct_itype(19) <= instruct(15); instruct_itype(20) <= instruct(15); instruct_itype(21) <= instruct(15); instruct_itype(22) <= instruct(15); instruct_itype(23) <= instruct(15); instruct_itype(24) <= instruct(15); instruct_itype(25) <= instruct(15); instruct_itype(26) <= instruct(15); instruct_itype(27) <= instruct(15); instruct_itype(28) <= instruct(15); instruct_itype(29) <= instruct(15); instruct_itype(30) <= instruct(15); instruct_itype(31) <= instruct(15); instruct_branch(0) <= zro; -- Shifted and sign extended instruct_branch(1) <= zro; instruct_branch(2) <= instruct(0); instruct_branch(3) <= instruct(1); instruct_branch(4) <= instruct(2); instruct_branch(5) <= instruct(3); instruct_branch(6) <= instruct(4); instruct_branch(7) <= instruct(5); instruct_branch(8) <= instruct(6); instruct_branch(9) <= instruct(7); instruct_branch(10) <= instruct(8); instruct_branch(11) <= instruct(9); instruct_branch(12) <= instruct(10); instruct_branch(13) <= instruct(11); instruct_branch(14) <= instruct(12); instruct_branch(15) <= instruct(13); instruct_branch(16) <= instruct(14); instruct_branch(17) <= instruct(15); instruct_branch(18) <= instruct(15); instruct_branch(19) <= instruct(15); instruct_branch(20) <= instruct(15); instruct_branch(21) <= instruct(15); instruct_branch(22) <= instruct(15); instruct_branch(23) <= instruct(15); instruct_branch(24) <= instruct(15); instruct_branch(25) <= instruct(15); instruct_branch(26) <= instruct(15); instruct_branch(27) <= instruct(15); instruct_branch(28) <= instruct(15); instruct_branch(29) <= instruct(15); instruct_branch(30) <= instruct(15); instruct_branch(31) <= instruct(15); instruct_jump(0) <= zro; -- Shifted, sign extended, AND instruct_jump(1) <= zro; -- concatenated with the top 4 bits instruct_jump(2) <= instruct(0); -- of PC+4 to boot! Wow wow! instruct_jump(3) <= instruct(1); instruct_jump(4) <= instruct(2); instruct_jump(5) <= instruct(3); instruct_jump(6) <= instruct(4); instruct_jump(7) <= instruct(5); instruct_jump(8) <= instruct(6); instruct_jump(9) <= instruct(7); instruct_jump(10) <= instruct(8); instruct_jump(11) <= instruct(9); instruct_jump(12) <= instruct(10); instruct_jump(13) <= instruct(11); instruct_jump(14) <= instruct(12); instruct_jump(15) <= instruct(13); instruct_jump(16) <= instruct(14); instruct_jump(17) <= instruct(15); instruct_jump(18) <= instruct(16); instruct_jump(19) <= instruct(17); instruct_jump(20) <= instruct(18); instruct_jump(21) <= instruct(19); instruct_jump(22) <= instruct(20); instruct_jump(23) <= instruct(21); instruct_jump(24) <= instruct(22); instruct_jump(25) <= instruct(23); instruct_jump(26) <= instruct(24); instruct_jump(27) <= instruct(25); instruct_jump(28) <= pc_value(28); instruct_jump(29) <= pc_value(29); instruct_jump(30) <= pc_value(30); instruct_jump(31) <= pc_value(31); control : maincontrol port map(instruct_control,jump,regdst,alusrc,memtoreg,regwrite,memread,memwrite,branch,aluop); -- My main control! mux5x2x : mux5x2 port map(instruct_write,instruct_read2,regdst,reg_write_addr); -- My 5x2 mux! alucon : alucontrol port map(instruct_alu,aluop,opcodes); -- My alu control! reg_trigger <= clk and regwrite; -- Clock substitution for Register registerfile : regfile port map(reg_write_data,instruct_read1,instruct_read2,reg_write_addr,reg_trigger,reg_read1,reg_read2); -- My register file! alumux : mux32x2 port map(instruct_itype,reg_read2,alusrc,alu_input); -- That mux that goes right after read data 2 from the register file branch_adder : adder32bit port map(pc_next,instruct_branch,zro,branch_addr,junk1); -- Add the shifted, extended variable to PC+4 alu : alu32bit port map(reg_read1,alu_input,opcodes(2),opcodes(1),opcodes(0),alu_out,zero,overflow); -- My ALU! pcsrc <= branch and zero; -- Selector for Branch or Next Pc mux. branch_mux : mux32x2 port map(branch_addr,pc_next,pcsrc,pcorbranch); -- That mux that determines whether to use branch or PC+4 jump_mux : mux32x2 port map(instruct_jump,pcorbranch,jump,pc_input); -- The mux that determines whether to use (branch or PC+4) or jump data_trigger <= clk and memwrite; -- Clock substitute for Data Memory datamemory : data_memory port map(alu_out,reg_read2,data_trigger,memread,dm_read); -- My data memory! dm_mux : mux32x2 port map(dm_read,alu_out,memtoreg,reg_write_data); -- That mux that sits at the end of the data memory and determines what gets -- to go back in the register file end behavior; -- Gah, that took forever.