ΕΛΛΗΝΙΚΟ ΑΝΟΙΚΤΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΚΑΙ ΤΕΧΝΟΛΟΓΙΑΣ ΠΡΟΠΤΥΧΙΑΚΟ ΠΡΟΓΡΑΜΜΑ ΣΠΟΥΔΩΝ ΠΛΗΡΟΦΟΡΙΚΗ ΘΕΜΑΤΙΚΗ ΕΝΟΤΗΤΑ ΕΡΓΑΣΤΗΡΙΟ ΨΗΦΙΑΚΩΝ ΣΥΣΤΗΜΑΤΩΝ ΛΥΣΕΙΣ 3 ης ΓΡΑΠΤΗΣ ΕΡΓΑΣΙΑΣ ΠΑΤΡΑ 2006
9. Αριθμητική / Λογική Μονάδα 9.1. α) LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY FA IS PORT (x, y, Cin : IN std_logic; s, Cout : OUT std_logic); END FA; ARCHITECTURE struct OF FA IS BEGIN s <= x XOR y XOR Cin ; Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; END struct; β) LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY par_adder8 IS PORT (A, B : IN std_logic_vector (7 downto 0) ; Cin : IN std_logic; sum : OUT std_logic_vector (7 downto 0)); END par_adder8 ; ARCHITECTURE arc OF par_adder8 IS component FA PORT (x, y, Cin : IN std_logic ; s, Cout : OUT std_logic ) ; end component ; Signal C : std_logic_vector(7 downto 0); BEGIN FA_1: FA PORT MAP (A(0), B(0), Cin, sum(0), C(0)); p1: FOR i IN 1 TO 7 GENERATE FA_2: FA PORT MAP (A(i), B(i), C(i-1), sum(i), C(i)); END GENERATE; END arc ; 2
9.2. α) ENTITY mux2to1_8bit IS PORT (A, B : IN std_logic_vector(7 downto 0) ; sel : IN std_logic ; f : OUT std_logic_vector(7 downto 0) ) ; END mux2to1_8bit ; ARCHITECTURE arc OF mux2to1_8bit IS BEGIN WITH sel SELECT f <= A WHEN '0', B WHEN OTHERS ; END arc ; β) ENTITY mux4to1_8bit IS PORT (A, B, C, D : IN std_logic_vector(7 downto 0) ; sel_0, sel_1 : IN std_logic ; f : OUT std_logic_vector(7 downto 0) ) ; END mux4to1_8bit ; ARCHITECTURE arc OF mux4to1_8bit IS Signal sel : std_logic_vector(1 downto 0); BEGIN sel <= sel_1 & sel_0 ; WITH sel SELECT f <= A WHEN "00", B WHEN "01", C WHEN "10", D WHEN OTHERS ; END arc ; 3
9.3. ENTITY ALU IS PORT (AC_signal : IN std_logic_vector(7 downto 0) ; BUS_signal : IN std_logic_vector(7 downto 0) ; ALUS_0, ALUS_1 : IN std_logic ; ALUS_2, ALUS_3 : IN std_logic ; ALUS_4, ALUS_5 : IN std_logic ; ALU_out : OUT std_logic_vector(7 downto 0)) ; END ALU; Architecture alu_arc of ALU is component mux2to1_8bit PORT (A, B : IN std_logic_vector(7 downto 0) ; sel : IN std_logic ; f : OUT std_logic_vector(7 downto 0)); end component; component mux4to1_8bit PORT (A, B, C, D : IN std_logic_vector(7 downto 0) ; sel_0, sel_1 : IN std_logic ; f : OUT std_logic_vector(7 downto 0) ) ; end component; component par_adder8 PORT (A, B : IN std_logic_vector (7 downto 0) ; Cin : IN std_logic; sum : OUT std_logic_vector (7 downto 0)); end component ; Signal f1, f2, f3, f4 : std_logic_vector (7 downto 0); Signal zero_signal : std_logic_vector (7 downto 0); Signal BUS_not_signal : std_logic_vector (7 downto 0); Signal AND_signal, XOR_signal : std_logic_vector (7 downto 0); zero_signal <= "00000000" ; BUS_not_signal <= NOT(BUS_signal); AND_signal <= AC_signal AND BUS_signal; XOR_signal <= AC_signal XOR BUS_signal; MUX_1: mux2to1_8bit PORT MAP(AC_signal, zero_signal, ALUS_0, f1); MUX_2: mux4to1_8bit PORT MAP(BUS_signal, BUS_not_signal, zero_signal, zero_signal, ALUS_1, ALUS_2, f2); PADD: par_adder8 PORT MAP(f1, f2, ALUS_3, f3); -- Arithmetic Unit MUX_3: mux2to1_8bit PORT MAP(AND_signal, XOR_signal, ALUS_5, f4); -- Logic Unit MUX_4: mux2to1_8bit PORT MAP(f3, f4, ALUS_4, ALU_out); END alu_arc ; 4
9.4. Εντολή Διεργασία Αποτέλεσμα (ALU_OUT) ADD ALU_OUT AC + BUS 11001010 SUB ALU_OUT AC - BUS 10011000 AND ALU_OUT AC ^ BUS 00010001 XOR ALU_OUT AC BUS 10101000 CLR ALU_OUT 00000000 00000000 INC ALU_OUT AC + 1 10110010 LDA ALU_OUT BUS 00011001 9.5. 5
9.6. Αρχικά θα ορίσουμε το σήμα «OR_signal» και έπειτα θα εκτελέσουμε την πράξη OR μεταξύ του συσσωρευτή (AC) και των δεδομένων του διαύλου (BUS). Έπειτα χρησιμοποιούμε έναν πολυπλέκτη 2x1 των 8-bit για να επιλέξουμε είτε την έξοδο f4 του MUX_3 (πράξη AND ή XOR) είτε την πράξη OR. Ο έλεγχος του επιπλέον πολυπλέκτη γίνεται μέσω του νέου σήματος ελέγχου «ALUS_6». Τέλος ο πολυπλέκτης «εξόδου» (MUX_4) θα έχει στην είσοδό του το σήμα f5 αντί του f4. Όλα τα βήματα περιγράφονται διαδοχικά παρακάτω (με κόκκινη και bold γραματοσειρά). Signal BUS_not_signal : std_logic_vector (7 downto 0); Signal AND_signal, XOR_signal, OR_signal : std_logic_vector (7 downto 0); AND_signal <= AC_signal AND BUS_signal; XOR_signal <= AC_signal XOR BUS_signal; OR_signal <= AC_signal OR BUS_signal; MUX_5: mux2to1_8bit PORT MAP(f4, OR_signal, ALUS_6, f5);. MUX_4: mux2to1_8bit PORT MAP(f3, f5, ALUS_4, ALU_out);... 6
10. Η Μονάδα Δεδομένων 10.1. ENTITY AR_register IS PORT (AR_in : IN std_logic_vector(4 downto 0) ; load : IN std_logic ; AR_out : OUT std_logic_vector(4 downto 0)) ; END AR_register ; ARCHITECTURE AR_arc OF AR_register IS BEGIN p1: Process (clk, reset) If reset = '1' then AR_out <= "00000" ; elsif falling_edge(clk) then If load = '1' then AR_out <= AR_in; End process ; End AR_arc ; 10.2. 7
10.3. USE ieee.std_logic_unsigned.all ; ENTITY PC_register IS PORT (PC_in : IN std_logic_vector(4 downto 0) ; load, inc : IN std_logic ; PC_out : OUT std_logic_vector(4 downto 0)) ; END PC_register ; ARCHITECTURE PC_arc OF PC_register IS SIGNAL PCout : std_logic_vector(4 downto 0); BEGIN p1: Process (clk, reset) If reset = '1' then PCout <= "00000" ; elsif falling_edge(clk) then If load = '1' then PCout <= PC_in; elsif inc = '1' then PCout <= PCout + 1 ; End process ; PC_out <= PCout ; END PC_arc ; 10.4. 8
10.5. ENTITY DR_register IS PORT (DR_in : IN std_logic_vector(7 downto 0) ; load : IN std_logic ; DR_out : OUT std_logic_vector(7 downto 0)) ; END DR_register ; ARCHITECTURE DR_arc OF DR_register IS BEGIN p1: Process (clk, reset) IF reset = '1' then DR_out <= "00000000" ; elsif falling_edge(clk) then IF load = '1' then DR_out <= DR_in; End process ; End DR_arc ; 10.6. 9
10.7. ENTITY AC_register IS PORT (AC_in : IN std_logic_vector(7 downto 0) ; load : IN std_logic ; AC_out : OUT std_logic_vector(7 downto 0)) ; END AC_register ; ARCHITECTURE AC_arc OF AC_register IS BEGIN p1: Process (clk, reset) If reset = '1' then AC_out <= "00000000" ; Elsif falling_edge(clk) then IF load = '1' then AC_out <= AC_in; End process ; END AC_arc ; 10
10.8. ENTITY IR_register IS PORT (IR_in : IN std_logic_vector(2 downto 0) ; load : IN std_logic ; IR_out : OUT std_logic_vector(2 downto 0)) ; END IR_register ; ARCHITECTURE IR_arc OF IR_register IS BEGIN p1: Process (clk, reset) If reset = '1' then IR_out <= "000" ; Elsif falling_edge(clk) then IF load = '1' then IR_out <= IR_in; End process ; End IR_arc ; 10.9. 11
10.10. ENTITY system_bus IS PORT (sysbus : OUT std_logic_vector(7 downto 0) ; PC_BUS, DR_BUS, AC_BUS : IN std_logic ; MEM_BUS : IN std_logic ; MEM_data, DR_data, AC_data : IN std_logic_vector(7 downto 0); PC_data : IN std_logic_vector(4 downto 0)); END system_bus ; ARCHITECTURE BUS_arc OF system_bus IS Signal sys_bus : std_logic_vector(7 downto 0); Signal BUS_control : std_logic_vector(3 downto 0); BEGIN BUS_control <= PC_BUS & DR_BUS & AC_BUS & MEM_BUS ; Process(BUS_control) CASE BUS_control IS WHEN "1000" => sys_bus <= "000" & PC_data; WHEN "0001" => sys_bus <= MEM_data; WHEN "0100" => sys_bus <= DR_data; WHEN "0010" => sys_bus <= AC_data; WHEN others => sys_bus <= "00000000" ; END CASE; End process ; sysbus <= sys_bus ; End BUS_arc ; 12
11. Η Μονάδα Ελέγχου 11.1. ENTITY micro_mux IS PORT (A, B : IN std_logic_vector(4 downto 0) ; s : IN std_logic ; f : OUT std_logic_vector(4 downto 0) ) ; END micro_mux ; ARCHITECTURE arc OF micro_mux IS End arc ; WITH s SELECT f <= B WHEN '0', A WHEN OTHERS ; 13
11.2. ENTITY micro_reg IS PORT (Rin : IN std_logic_vector(4 downto 0) ; Rout : OUT std_logic_vector(4 downto 0)) ; END micro_reg ; ARCHITECTURE arc OF micro_reg IS BEGIN p1: Process (clk, reset) IF reset = '1' then Rout <= "00000" ; ELSIF falling_edge(clk) then Rout <= Rin; End process ; End arc ; 14
11.3. depth = 32; -- 5-bit address ---> 0-32 dec width = 22; -- 22-bit data address_radix = bin; data_radix = bin; content begin 00001 : 0000000100000100000010 ; -- FETCH 1 00010 : 0000000001100000100011 ; -- FETCH 2 00011 : 1000000100001010000000 ; -- FETCH 3 00100 : 0000000000100000100101 ; -- AND 1 00101 : 0010000000010010000001 ; -- AND 2 01000 : 0000000000100000101001 ; -- XOR 1 01001 : 0110000000010010000001 ; -- XOR 2 01100 : 0000000000100000101101 ; -- ADD 1 01101 : 0000000000010010000001 ; -- ADD 2 10000 : 0000000000100000110001 ; -- SUB 1 10001 : 0001010000010010000001 ; -- SUB 2 11100 : 0001110000010001000001 ; -- INC 1 00000 : 0000111000010000000001 ; -- CLAC 1 10100 : 0000000000100000110101 ; -- LDAC 1 10101 : 0000000100000010010110 ; -- LDAC 2 10110 : 0000000000100000110111 ; -- LDAC 3 10111 : 0000001000010010000001 ; -- LDAC 4 end; 15
11.4. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library lpm; use lpm.lpm_components.all; ENTITY micro_mem IS PORT(address : in std_logic_vector(4 downto 0); data_out : out std_logic_vector(21 downto 0)); End micro_mem; ARCHITECTURE arc OF micro_mem IS begin micro_mem: lpm_rom generic map (lpm_widthad => 5, lpm_outdata => "unregistered", lpm_address_control => "unregistered", lpm_file => "microcode.mif", lpm_width => 22) End arc; port map ( address => address, q => data_out); 11.5. 16
11.6. Library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library lpm; use lpm.lpm_components.all; ENTITY microsequencer IS PORT (IR_signal : IN std_logic_vector(2 downto 0) ; clock, reset : IN std_logic ; mops : OUT std_logic_vector(15 downto 0)) ; END microsequencer ; ARCHITECTURE seq_arc OF microsequencer IS component micro_mux PORT (A, B : IN std_logic_vector(4 downto 0) ; s : IN std_logic ; f : OUT std_logic_vector(4 downto 0) ) ; end component; component micro_reg PORT (Rin : IN std_logic_vector(4 downto 0) ; Rout : OUT std_logic_vector(4 downto 0)) ; end component; component micro_mem PORT(address : in std_logic_vector(4 downto 0); data_out : out std_logic_vector(21 downto 0)); end component; Signal SEL, SEL_MUX : std_logic ; Signal ADDR, ADDR_MUX : std_logic_vector(4 downto 0); Signal IRMAP : std_logic_vector(4 downto 0); Signal MUX_out : std_logic_vector(4 downto 0); Signal REG_out : std_logic_vector(4 downto 0); Signal SEQ_out : std_logic_vector(21 downto 0); IRMAP <= IR_signal & "00" ; p1: Process (reset) IF reset = '1' then SEL_MUX <= '0' ; ADDR_MUX <= "00000"; Else SEL_MUX <= SEL ; ADDR_MUX <= ADDR ; End Process ; MUXproc : micro_mux PORT MAP (IRMAP, ADDR_MUX, SEL_MUX, MUX_out); REGproc : micro_reg PORT MAP (MUX_out, clock, reset, REG_out); MEMproc : micro_mem PORT MAP (REG_out, SEQ_out); SEL <= SEQ_out(21); 17
g1: for j in 0 to 4 generate ADDR(j) <= SEQ_out(j) ; end generate; g2: for j in 0 to 15 generate mops(j) <= SEQ_out(j+5) ; end generate; EndD seq_arc ; 11.7. 18
12. Συνολική Υλοποίηση της CPU 12.1. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; library lpm; use lpm.lpm_components.all; ENTITY external_mem IS PORT(address : IN std_logic_vector(4 downto 0); data_out : OUT std_logic_vector(7 downto 0)); end external_mem; ARCHITECTURE arc OF external_mem IS external_mem: lpm_rom generic map ( lpm_widthad => 5, lpm_outdata => "unregistered", lpm_address_control => "unregistered", lpm_file => "external_mem.mif", lpm_width => 8) End arc; port map ( address => address, q => data_out); 19
12.2. USE ieee.std_logic_unsigned.all ; ENTITY CPU_final IS PORT (AR_data, PC_data : OUT std_logic_vector(4 downto 0); DR_data, AC_data : OUT std_logic_vector(7 downto 0); IR_data : OUT std_logic_vector(2 downto 0); sbus : BUFFER std_logic_vector(7 downto 0) ; clock, reset : IN std_logic; opcode : OUT std_logic_vector(15 downto 0)); END CPU_final ; ARCHITECTURE CPU_arc OF CPU_final IS component microsequencer PORT (IR_signal : IN std_logic_vector(2 downto 0) ; clock, reset : IN std_logic ; mops : OUT std_logic_vector(15 downto 0)) ; end component ; component AR_register PORT (AR_in : IN std_logic_vector(4 downto 0) ; load : IN std_logic ; AR_out : OUT std_logic_vector(4 downto 0)) ; end component ; component PC_register PORT (PC_in : IN std_logic_vector(4 downto 0) ; load, inc : IN std_logic ; PC_out : OUT std_logic_vector(4 downto 0)) ; end component ; component DR_register PORT (DR_in : IN std_logic_vector(7 downto 0) ; load : IN std_logic ; DR_out : OUT std_logic_vector(7 downto 0)) ; end component ; component AC_register PORT (AC_in : IN std_logic_vector(7 downto 0) ; load : IN std_logic ; AC_out : OUT std_logic_vector(7 downto 0)) ; end component ; component ALU PORT (AC_signal : IN std_logic_vector(7 downto 0) ; BUS_signal : IN std_logic_vector(7 downto 0) ; ALUS_0, ALUS_1 : IN std_logic ; ALUS_2, ALUS_3 : IN std_logic ; ALUS_4, ALUS_5 : IN std_logic ; ALU_out : OUT std_logic_vector(7 downto 0)) ; end component; 20
component IR_register PORT (IR_in : IN std_logic_vector(2 downto 0) ; load : IN std_logic ; IR_out : OUT std_logic_vector(2 downto 0)) ; end component; component system_bus PORT (sysbus : OUT std_logic_vector(7 downto 0); PC_BUS, DR_BUS, AC_BUS : IN std_logic ; MEM_BUS : IN std_logic ; MEM_data, DR_data, AC_data : IN std_logic_vector(7 downto 0); PC_data : IN std_logic_vector(4 downto 0)); end component ; component external_mem PORT(address : IN std_logic_vector(4 downto 0); data_out : OUT std_logic_vector(7 downto 0)); end component ; Signal ARLOAD, PCLOAD, PCINC : std_logic ; Signal DRLOAD, ACLOAD, IRLOAD : std_logic ; Signal ALUS_5, ALUS_4, ALUS_3 : std_logic ; Signal ALUS_2, ALUS_1, ALUS_0 : std_logic ; Signal PCBUS, DRBUS, ACBUS : std_logic ; Signal MEMBUS, BUSMEM : std_logic ; Signal mop : std_logic_vector(16 downto 0) ; Signal databus : std_logic_vector(7 downto 0) ; Signal ARin, ARout, PCin, PCout : std_logic_vector(4 downto 0) ; Signal DRin, DRout, ACin, ACout : std_logic_vector(7 downto 0) ; Signal IRin, IRout : std_logic_vector(2 downto 0) ; Signal MEMdata : std_logic_vector(7 downto 0); Signal ALU_DR : std_logic_vector(7 downto 0) ; p1: for j in 0 to 4 generate ARin(j) <= databus(j); end generate; p2: for j in 0 to 4 generate PCin(j) <= databus(j); end generate; DRin <= databus; p3: for j in 0 to 2 generate IRin(j) <= databus(j+5); end generate; ALU_DR <= databus; mseq: microsequencer PORT MAP (IRin, clock, reset, mop); MEMBUS <= mop(0); ACBUS <= mop(1); DRBUS <= mop(2); PCBUS <= mop(3); IRLOAD <= mop(4); ACLOAD <= mop(5); 21
DRLOAD <= mop(6); PCINC <= mop(7); PCLOAD <= mop(8); ARLOAD <= mop(9); ALUS_0 <= mop(10); ALUS_1 <= mop(11); ALUS_2 <= mop(12); ALUS_3 <= mop(13); ALUS_4 <= mop(14); ALUS_5 <= mop(15); BUSproc: system_bus PORT MAP(dataBUS, PCBUS, DRBUS, ACBUS, MEMBUS, MEMdata, DRout, ACout, PCout); ROM: external_mem PORT MAP(ARout, MEMdata); ARproc: AR_register PORT MAP (ARin, clock, reset, ARLOAD, ARout); PCproc: PC_register PORT MAP (PCin, clock, reset, PCLOAD, PCINC, PCout); DRproc: DR_register PORT MAP(DRin, clock, reset, DRLOAD, DRout) ; ACproc: AC_register PORT MAP(ACin, clock, reset, ACLOAD, ACout); ALUproc: ALU PORT MAP(ACout, ALU_DR, ALUS_0, ALUS_1, ALUS_2, ALUS_3, ALUS_4, ALUS_5, ACin); IRproc: IR_register PORT MAP(IRin, clock, reset, IRLOAD, IRout); AR_data <= ARout ; PC_data <= PCout ; DR_data <= DRout ; AC_data <= ACout ; IR_data <= IRout ; sbus <= databus ; opcode <= mop; End CPU_arc ; 12.3. 22
Αναλυτική Βαθμολογία για Κάθε Ερώτημα Ερώτημα Μονάδες Ο βαθμός σας 9.1 (α) 2 9.1 (β) 3 9.2 (α) 2 9.2 (β) 3 9.3 10 27 9.4 2 9.5 2 9.6 3 10.1 4 10.2 2 10.3 2 10.4 2 10.5 2 10.6 2 28 10.7 2 10.8 2 10.9 2 10.10 8 11.1 2 11.2 2 11.3 4 11.4 4 26 11.5 2 11.6 9 11.7 3 12.1 2 12.2 13 19 12.3 4 Σύνολο 100 Τελικός Βαθμός 10,0 23