-- Project Step 8 - Integrating Register and ALU in a datapath -- -- NAME: -- ------------------------------------------------------------------------------- -- BE SURE TO TURN IN ALL CODE USED!!! ------------------------------------------------------------------------------- -- Enter ENTITY/ARCHITECTURE for datapath here. -- (you can use the package that you used in step 6 which -- should still be in the library) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Enter your Architecture for a the datapath here ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Test Bench Entity for the Register set ------------------------------------------------------------------------------- ENTITY dp IS END dp; -- ** you will need to use your package for type operations also. **** -- TYPE operations is not declared in the testbench - it relies on -- the definition in your package. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ARCHITECTURE test OF dp IS ------------------------------------------- -- Declare and configure your datapath here ------------------------------------------- -- Enter your name in the ( ) TYPE mname IS (yourname); SIGNAL nm : mname := mname'VAL(0); ------------------------------------------- -- controller signals and busses SIGNAL ABUS,BBUS : std_logic_vector (15 downto 0); SIGNAL Aregload,Bregload,Aregdrive,Bregdrive : std_logic; SIGNAL AregNo,BregNo : integer := 0; SIGNAL A_ALUload,B_ALUload,A_ALUdrive,B_ALUdrive : std_logic; SIGNAL Cin,C,N,Z : std_logic; SIGNAL oper : operations; -- signals for checking of outputs SIGNAL exp_abus,exp_bbus : std_logic_vector (15 downto 0); SIGNAL abus_err,bbus_err : bit; SIGNAL cexp,zexp,nexp : std_logic := '0'; SIGNAL cerr,zerr,nerr : std_logic := '0'; SIGNAL tot_err : Integer := 0; TYPE LDItype IS (Idle,TBLoad,Load,Drive); CONSTANT HighZ : std_logic_vector (15 downto 0) := "ZZZZZZZZZZZZZZZZ"; type value_tbl_type is array (0 to 22) of std_logic_vector(15 downto 0); constant v_tbl : value_tbl_type := ( "0000000000000000", --X0000 "0101010101010101", --X5555 "0000000000000010", --X0002 "0000000000000011", --X0003 "0000000000000100", --X0004 "0000000000000101", --X0005 "0000000000000110", --X0006 "0000000000000111", --X0007 "0000000000001000", --X0008 "0000000000001001", --X0009 "0000000000001010", --X000A "0000000000001011", --X000B "0000000000001100", --X000C "0000000000001101", --X000D "0000000000001110", --X000E "0000000000001111", --X000F "0000000000000001", --X0001 "1010101010101010", --XAAAA "1111111111111010", --XFFFA "0000000000010010", --X0012 "0000000000011100", --X001C "0000000000100111", --X0027 "0000000000011011"); --X001B TYPE final_val_type IS ARRAY (0 to 15) OF INTEGER; CONSTANT fv_seq : final_val_type:=(0,1,2,5,9,15,18,16,9,19,20,21,22,14,13,0); TYPE cnz_val_type IS ARRAY (0 to 8) of std_logic_vector(2 downto 0); CONSTANT cnz_val : cnz_val_type := ("000","001","010","011", "100","101","110","111","---"); ---------------------------------------------------------------------------- BEGIN -- Testbench Architecture ---------------------------------------------------------------------------- -- Instantiate your datapath here ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- applytest : PROCESS ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- PROCEDURE bus_cycle (A_regldi : LDItype; A_reg_no : Integer; A_aluldi : LDItype; A_BUS_VAL : std_logic_vector (15 downto 0); A_BUS_EXP : std_logic_vector (15 downto 0); B_regldi : LDItype; B_reg_no : Integer; B_aluldi : LDItype; B_BUS_VAL : std_logic_vector (15 downto 0); B_BUS_EXP : std_logic_vector (15 downto 0); alu_op : operations; Cinval : std_logic; exp_cc : Integer; checkbus : BOOLEAN) IS BEGIN WAIT FOR 9 NS; -- 9 ns into cycle IF (ABUS /= HighZ) THEN Abus_err <= '1','0' after 1 ns; END IF; IF (BBUS /= HighZ) THEN Bbus_err <= '1','0' after 1 ns; END IF; WAIT FOR 1 NS; -- 10 ns into cycle AregNo <= A_reg_no; BregNo <= B_reg_no; Cin <= Cinval; exp_abus <= A_BUS_EXP; exp_bbus <= B_BUS_EXP; CASE A_regldi IS WHEN TBLoad => Aregload <= '0'; ABUS <= A_BUS_VAL; WHEN Load => Aregload <= '0'; WHEN Drive => Aregdrive <= '0'; WHEN Idle => null; END CASE; CASE B_regldi IS WHEN TBLoad => Bregload <= '0'; BBUS <= B_BUS_VAL; WHEN Load => Bregload <= '0'; WHEN Drive => Bregdrive <= '0'; WHEN Idle => null; END CASE; CASE A_aluldi IS WHEN Load => A_ALUload <= '0'; WHEN Drive => A_ALUdrive <= '0'; WHEN TBLoad | Idle => null; END CASE; CASE B_aluldi IS WHEN Load => B_ALUload <= '0'; WHEN Drive => B_ALUdrive <= '0'; WHEN TBLoad | Idle => null; END CASE; oper <= alu_op; WAIT FOR 10 NS; -- 20 ns into cycle IF checkbus THEN IF (ABUS /= A_BUS_EXP) THEN Abus_err <= '1','0' after 1 ns; END IF; IF (BBUS /= B_BUS_EXP) THEN Bbus_err <= '1','0' after 1 ns; END IF; END IF; WAIT FOR 49 NS; -- 69 ns into cycle IF checkbus THEN IF (ABUS /= A_BUS_EXP) THEN Abus_err <= '1','0' after 1 ns; END IF; IF (BBUS /= B_BUS_EXP) THEN Bbus_err <= '1','0' after 1 ns; END IF; END IF; WAIT FOR 1 NS; -- 70 ns into cycle IF (A_regldi = Load OR A_regldi = TBLoad) THEN Aregload <= '1'; END IF; IF (B_regldi = Load OR B_regldi = TBLoad) THEN Bregload <= '1'; END IF; IF (A_aluldi = Load) THEN A_ALUload <= '1'; END IF; IF (B_aluldi = Load) THEN B_ALUload <= '1'; END IF; WAIT FOR 10 NS; -- 80 ns into cycle IF (A_regldi = Drive) THEN Aregdrive <= '1'; ELSE ABUS <= HighZ; END IF; IF (B_regldi = Drive) THEN Bregdrive <= '1'; ELSE BBUS <= HighZ; END IF; IF (A_aluldi = Drive) THEN A_ALUdrive <= '1'; ELSE ABUS <= HighZ; END IF; IF (B_aluldi = Drive) THEN B_ALUdrive <= '1'; ELSE BBUS <= HighZ; END IF; exp_abus <= HighZ; exp_bbus <= HighZ; IF ((A_aluldi = Drive) or (B_aluldi = Drive)) THEN IF ((exp_cc /= 8) and (C /= cnz_val(exp_cc)(2))) THEN cerr <= '1', '0' after 1 ns; END IF; cexp <= cnz_val(exp_cc)(2); IF ((exp_cc /= 8) and (N /= cnz_val(exp_cc)(1))) THEN nerr <= '1', '0' after 1 ns; END IF; nexp <= cnz_val(exp_cc)(1); IF ((exp_cc /= 8) and (Z /= cnz_val(exp_cc)(0))) THEN zerr <= '1', '0' after 1 ns; END IF; zexp <= cnz_val(exp_cc)(0); END IF; WAIT FOR 11 NS; -- 91 ns into cycle IF (ABUS /= HighZ) THEN Abus_err <= '1','0' after 1 ns; END IF; IF (BBUS /= HighZ) THEN Bbus_err <= '1','0' after 1 ns; END IF; WAIT FOR 9 NS; -- end of 100 ns cycle END bus_cycle; ---------------------------------------------------------------------------- PROCEDURE oneregop (sregno : INTEGER; alu_oper:operations; alu_cin:std_logic; abusc1,bbusc1,abusc2,bbusc2:std_logic_vector(15 downto 0); exp_cc : Integer) IS BEGIN bus_cycle(Drive,sregno,load,highZ,abusc1, Idle,0,idle,highz,bbusc1, alu_oper,alu_cin,8,TRUE); bus_cycle(Idle,0,idle,highZ,abusc2, Load,sregno,Drive,highz,bbusc2, alu_oper,alu_cin,exp_cc,TRUE); END oneregop; ---------------------------------------------------------------------------- PROCEDURE tworegop (s1reg,s2reg:INTEGER; alu_oper:operations; alu_cin:std_logic; abusc1,bbusc1,abusc2,bbusc2:std_logic_vector(15 downto 0); exp_cc : Integer) IS BEGIN bus_cycle(Drive,s1reg,load,highz,abusc1, Drive,s2reg,load,highz,bbusc1, alu_oper,alu_cin,8,TRUE); bus_cycle(Idle,0,idle,highz,abusc2, load,s2reg,drive,highz,bbusc2, alu_oper,alu_cin,exp_cc,TRUE); END tworegop; ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- BEGIN -- Initialize all signals ABUS <= HighZ; BBUS <= HighZ; Aregload <= '1'; Bregload <= '1'; Aregdrive <= '1'; Bregdrive <= '1'; AregNo <= 0; BregNo <= 0; A_ALUload <= '1'; B_ALUload <= '1'; A_ALUdrive <= '1'; B_ALUdrive <= '1'; Cin <= '0'; oper <= op_0; -- load initial values to registers using both Busses FOR I in 0 to 7 Loop bus_cycle(TBLoad,I,Idle,v_tbl(I),v_tbl(I), TBLoad,15-I,Idle,v_tbl(15-I),v_tbl(15-I), op_0,'0',8,TRUE); END LOOP; -- check contents were loaded correctly by dumping onto busses FOR I in 0 to 7 Loop bus_cycle(Drive,15-I,Idle,HighZ,v_tbl(15-I), Drive,I,Idle,HighZ,v_tbl(I), op_0,'0',8,TRUE); END LOOP; -- Start Operations -- R(0) xor R(1) -> R(1) tworegop(0,1,op_AxorB,'0',v_tbl(0),v_tbl(1),highz,v_tbl(1),0); -- R(1) or R(0) -> R(0) tworegop(1,0,op_AorB,'0',v_tbl(1),v_tbl(0),highz,v_tbl(1),0); -- not R(0) -> R(0) oneregop(0,op_notA,'0',v_tbl(1),highz,highz,v_tbl(17),2); -- R(1) and R(0) -> R(0) tworegop(1,0,op_AandB,'0',v_tbl(1),v_tbl(17),highz,v_tbl(0),1); -- R(2) + R(3) -> R(3) tworegop(2,3,op_AplusB,'0',v_tbl(2),v_tbl(3),highz,v_tbl(5),0); -- R(3) + R(4) -> R(4) tworegop(3,4,op_AplusB,'0',v_tbl(5),v_tbl(4),highz,v_tbl(9),0); -- R(4) + R(5) -> R(5) tworegop(4,5,op_AplusBwC,'1',v_tbl(9),v_tbl(5),highz,v_tbl(15),0); -- neg R(6) -> R(6) oneregop(6,op_negA,'1',v_tbl(6),highz,highz,v_tbl(18),2); -- R(6) + R(7) -> R(7) tworegop(6,7,op_AplusB,'0',v_tbl(18),v_tbl(7),highz,v_tbl(16),4); -- R(7) + R(8) -> R(8) tworegop(7,8,op_AplusB,'0',v_tbl(16),v_tbl(8),highz,v_tbl(9),0); -- R(8) + R(9) -> R(9) tworegop(8,9,op_AplusB,'0',v_tbl(9),v_tbl(9),highz,v_tbl(19),0); -- R(9) + R(10) -> R(10) tworegop(9,10,op_AplusB,'0',v_tbl(19),v_tbl(10),highz,v_tbl(20),0); -- R(10) + R(11) -> R(11) tworegop(10,11,op_AplusB,'0',v_tbl(20),v_tbl(11),highz,v_tbl(21),0); -- R(11) - R(12) -> R(12) tworegop(11,12,op_AminB,'0',v_tbl(21),v_tbl(12),highz,v_tbl(22),0); -- inc R(13) -> R(13) oneregop(13,op_incA,'1',v_tbl(13),highz,highz,v_tbl(14),0); -- dec (14) -> R(14) oneregop(14,op_decA,'1',v_tbl(14),highz,highz,v_tbl(13),0); -- "x_0000" -> R(15) oneregop(15,op_0,'0',v_tbl(15),highz,highz,v_tbl(0),1); -- final dump and check of registers using the Bbus FOR I in 0 to 7 Loop bus_cycle(Drive,I,Idle,HighZ,v_tbl(fv_seq(I)), Drive,15-I,Idle,HighZ,v_tbl(fv_seq(15-I)), op_0,'0',8,TRUE); END LOOP; -- done - TA DA!! WAIT; END PROCESS; PROCESS (abus_err,bbus_err,cerr,nerr,zerr) -- process to total errors VARIABLE temp_total : Integer; BEGIN temp_total := tot_err; IF (abus_err = '1' and abus_err'event) THEN temp_total := temp_total + 1; END IF; IF (bbus_err = '1' and bbus_err'event) THEN temp_total := temp_total + 1; END IF; IF (cerr = '1' and cerr'event) THEN temp_total := temp_total + 1; END IF; IF (nerr = '1' and nerr'event) THEN temp_total := temp_total + 1; END IF; IF (zerr = '1' and zerr'event) THEN temp_total := temp_total + 1; END IF; tot_err <= temp_total; END PROCESS; nm <= mname'VAL(0); END test;