diff --git a/Makefile b/Makefile index a9c4f94..a450fe7 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,15 @@ all : sim_alu #sim_shifter adder32_tb : adder1.o adder32.o adder32_tb.o ${GHDL} -e -v adder32_tb -shifter_tb : shitfter.o shitfter_tb.o +shifter_tb : shifter.o shifter_tb.o ${GHDL} -e -v shifter_tb alu_tb : adder1.o adder32.o alu.o alu_tb.o ${GHDL} -e -v alu_tb +exec_tb :adder1.o adder32.o alu.o fifo_72b.o shifter.o exec.o exec_tb.o + ${GHDL} -e -v exec_tb + sim_adder32 : adder32_tb ${GHDL} -r adder32_tb --vcd=adder32.vcd @@ -22,5 +25,8 @@ sim_alu : alu_tb sim_shifter : shifter_tb ${GHDL} -r shifter_tb --vcd=shifter.vcd +sim_exec : exec_tb + ${GHDL} -r exec_tb --vcd=exec.vcd + clean : -rm *.o work-obj93.cf *_tb *.vcd diff --git a/exec.vhdl b/exec.vhdl new file mode 100644 index 0000000..bcc8549 --- /dev/null +++ b/exec.vhdl @@ -0,0 +1,254 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity EXec is + port( + -- Decode interface synchro + dec2exe_empty : in Std_logic; + exe_pop : out Std_logic; + + -- Decode interface operands + dec_op1 : in Std_Logic_Vector(31 downto 0); -- first alu input + dec_op2 : in Std_Logic_Vector(31 downto 0); -- shifter input + dec_exe_dest : in Std_Logic_Vector(3 downto 0) ; -- Rd destination + dec_exe_wb : in Std_Logic; -- Rd destination write back + dec_flag_wb : in Std_Logic; -- CSPR modifiy + + -- Decode to mem interface + dec_mem_data : in Std_Logic_Vector(31 downto 0); -- data to MEM W + dec_mem_dest : in Std_Logic_Vector(3 downto 0) ; -- Destination MEM R + dec_pre_index : in Std_logic; + + dec_mem_lw : in Std_Logic; + dec_mem_lb : in Std_Logic; + dec_mem_sw : in Std_Logic; + dec_mem_sb : in Std_Logic; + + -- Shifter command + dec_shift_lsl : in Std_Logic; + dec_shift_lsr : in Std_Logic; + dec_shift_asr : in Std_Logic; + dec_shift_ror : in Std_Logic; + dec_shift_rrx : in Std_Logic; + dec_shift_val : in Std_Logic_Vector(4 downto 0); + dec_cy : in Std_Logic; + + -- Alu operand selection + dec_comp_op1 : in Std_Logic; + dec_comp_op2 : in Std_Logic; + dec_alu_cy : in Std_Logic; + + -- Alu command + dec_alu_cmd : in Std_Logic_Vector(1 downto 0); + + -- Exe bypass to decod + exe_res : out Std_Logic_Vector(31 downto 0); + + exe_c : out Std_Logic; + exe_v : out Std_Logic; + exe_n : out Std_Logic; + exe_z : out Std_Logic; + + exe_dest : out Std_Logic_Vector(3 downto 0); -- Rd destination + exe_wb : out Std_Logic; -- Rd destination write back + exe_flag_wb : out Std_Logic; -- CSPR modifiy + + -- Mem interface + exe_mem_adr : out Std_Logic_Vector(31 downto 0); -- Alu res register + exe_mem_data : out Std_Logic_Vector(31 downto 0); + exe_mem_dest : out Std_Logic_Vector(3 downto 0); + + exe_mem_lw : out Std_Logic; + exe_mem_lb : out Std_Logic; + exe_mem_sw : out Std_Logic; + exe_mem_sb : out Std_Logic; + + exe2mem_empty : out Std_logic; + mem_pop : in Std_logic; + + -- global interface + ck : in Std_logic; + reset_n : in Std_logic; + vdd : in bit; + vss : in bit); +end EXec; + +---------------------------------------------------------------------- + +architecture Behavior OF EXec is + + -- creation des components utilisés par EXEC + component alu + port ( op1 : in Std_Logic_Vector(31 downto 0); + op2 : in Std_Logic_Vector(31 downto 0); + cin : in Std_Logic; + + cmd : in Std_Logic_Vector(1 downto 0); + + res : out Std_Logic_Vector(31 downto 0); + cout : out Std_Logic; + z : out Std_Logic; + n : out Std_Logic; + v : out Std_Logic; + + vdd : in bit; + vss : in bit); + end component; + + component shifter + port ( + shift_lsl : in Std_Logic; + shift_lsr : in Std_Logic; + + shift_asr : in Std_Logic; + + shift_ror : in Std_Logic; -- rotation sans extension + shift_rrx : in Std_Logic; -- avec extension + + shift_val : in Std_Logic_Vector(4 downto 0); + + din : in Std_Logic_Vector(31 downto 0); + cin : in Std_Logic; + + dout : out Std_Logic_Vector(31 downto 0); + cout : out Std_Logic; + + -- global interface + vdd : in bit; + vss : in bit + ); + end component; + + component fifo_72b + port( + din : in std_logic_vector(71 downto 0); + dout : out std_logic_vector(71 downto 0); + + -- commands + push : in std_logic; + pop : in std_logic; + + -- flags + full : out std_logic; + empty : out std_logic; + + reset_n : in std_logic; + ck : in std_logic; + vdd : in bit; + vss : in bit + ); + end component; + + + -- signal reliant les instances + + -- signal sortant du shifter + signal shifter_op2 : std_logic_vector(31 downto 0); + signal shifter_op2_carry : std_logic; + + -- signal entrant de l'alu + signal alu_op1_in, alu_op2_in : std_logic_vector(31 downto 0); + + -- signal sortant de l'alu + signal alu_value_out : std_logic_vector(31 downto 0); + signal alu_value_cout : std_logic; + + -- signal entrant fifo + signal mem_adr : std_logic_vector(31 downto 0); + signal exe_push, exe2mem_full : std_logic; + + begin + -- Component instantiation. + -- shifter + shifter_int : shifter + port map ( + shift_lsl => dec_shift_lsl, + shift_lsr => dec_shift_lsr, + shift_asr => dec_shift_asr, + shift_ror => dec_shift_ror, + shift_rrx => dec_shift_rrx, + shift_val => dec_shift_val, + din => dec_op2, + cin => dec_cy, + dout => shifter_op2, + cout => shifter_op2_carry, + -- global interface + vdd => vdd, + vss => vss + + ); + + -- l'alu + alu_inst : alu + port map ( + op1 => alu_op1_in, + op2 => alu_op2_in, + cin => dec_alu_cy, + cmd => dec_alu_cmd, + + res => alu_value_out, + cout => alu_value_cout, + z => exe_z, + n => exe_n, + v => exe_v, + + -- global interface + vdd => vdd, + vss => vss + ); + + -- étage de pipeline entre exec et mem + exec2mem : fifo_72b + port map ( din(71) => dec_mem_lw, + din(70) => dec_mem_lb, + din(69) => dec_mem_sw, + din(68) => dec_mem_sb, + + din(67 downto 64) => dec_mem_dest, + din(63 downto 32) => dec_mem_data, + din(31 downto 0) => mem_adr, + + dout(71) => exe_mem_lw, + dout(70) => exe_mem_lb, + dout(69) => exe_mem_sw, + dout(68) => exe_mem_sb, + + dout(67 downto 64) => exe_mem_dest, + dout(63 downto 32) => exe_mem_data, + dout(31 downto 0) => exe_mem_adr, + + push => exe_push, + pop => mem_pop, + + empty => exe2mem_empty, + full => exe2mem_full, + + reset_n => reset_n, + ck => ck, + vdd => vdd, + vss => vss + ); + + -- multiplexeurs entrée ALU + alu_op1_in <= (not dec_op1) when dec_comp_op1='1' else dec_op1; + alu_op2_in <= (not shifter_op2) when dec_comp_op2='1' else shifter_op2; + + -- bypass 2 decod + -- resultat ALU + exe_res <= alu_value_out; + -- carry flag + exe_c <= alu_value_cout; + + -- sortie mutex entre ALU et fifo + + mem_adr <= (dec_op1) when dec_pre_index='1' else alu_value_out; + + -- Sortie restante + -- exe_pop <= dec2exe_empty; + + -- exe_dest <= dec_exe_dest; + -- exe_wb <= dec_exe_wb; + -- exe_flag_wb <= dec_flag_wb; + +end Behavior; \ No newline at end of file diff --git a/exec_tb.vhdl b/exec_tb.vhdl new file mode 100644 index 0000000..51daed9 --- /dev/null +++ b/exec_tb.vhdl @@ -0,0 +1,239 @@ +library ieee; +use ieee.math_real.all; +use ieee.numeric_std.all; +use ieee.std_logic_1164.all; + +entity exec_tb is +end exec_tb; + + +architecture Structurel of exec_tb is + + signal dec2exe_empty : Std_logic; + signal exe_pop : Std_logic; + signal dec_op1 : Std_Logic_Vector(31 downto 0); -- first alu input + signal dec_op2 : Std_Logic_Vector(31 downto 0); -- shifter input + signal dec_exe_dest : Std_Logic_Vector(3 downto 0) ; -- Rd destination + signal dec_exe_wb : Std_Logic; -- Rd destination write back + signal dec_flag_wb : Std_Logic; -- CSPR modifiy + signal dec_mem_data : Std_Logic_Vector(31 downto 0); -- data to MEM W + signal dec_mem_dest : Std_Logic_Vector(3 downto 0) ; -- Destination MEM R + signal dec_pre_index : Std_logic; + signal dec_mem_lw : Std_Logic; + signal dec_mem_lb : Std_Logic; + signal dec_mem_sw : Std_Logic; + signal dec_mem_sb : Std_Logic; + signal dec_shift_lsl : Std_Logic; + signal dec_shift_lsr : Std_Logic; + signal dec_shift_asr : Std_Logic; + signal dec_shift_ror : Std_Logic; + signal dec_shift_rrx : Std_Logic; + signal dec_shift_val : Std_Logic_Vector(4 downto 0); + signal dec_cy : Std_Logic; + signal dec_comp_op1 : Std_Logic; + signal dec_comp_op2 : Std_Logic; + signal dec_alu_cy : Std_Logic; + signal dec_alu_cmd : Std_Logic_Vector(1 downto 0); + signal exe_res : Std_Logic_Vector(31 downto 0); + signal exe_c : Std_Logic; + signal exe_v : Std_Logic; + signal exe_n : Std_Logic; + signal exe_z : Std_Logic; + signal exe_dest : Std_Logic_Vector(3 downto 0); -- Rd destination + signal exe_wb : Std_Logic; -- Rd destination write back + signal exe_flag_wb : Std_Logic; -- CSPR modifiy + signal exe_mem_adr : Std_Logic_Vector(31 downto 0); -- Alu res register + signal exe_mem_data : Std_Logic_Vector(31 downto 0); + signal exe_mem_dest : Std_Logic_Vector(3 downto 0); + signal exe_mem_lw : Std_Logic; + signal exe_mem_lb : Std_Logic; + signal exe_mem_sw : Std_Logic; + signal exe_mem_sb : Std_Logic; + signal exe2mem_empty : Std_logic; + signal mem_pop : Std_logic; + signal ck : Std_logic := '0'; + signal reset_n : Std_logic; + signal vdd : bit; + signal vss : bit; +begin + + + ALU_ins: entity work.exec + port map( + dec2exe_empty => dec2exe_empty, + exe_pop => exe_pop, + dec_op1 => dec_op1, + dec_op2 => dec_op2, + dec_exe_dest => dec_exe_dest, + dec_exe_wb => dec_exe_wb, + dec_flag_wb => dec_flag_wb, + dec_mem_data => dec_mem_data, + dec_mem_dest => dec_mem_dest, + dec_pre_index => dec_pre_index, + dec_mem_lw => dec_mem_lw, + dec_mem_lb => dec_mem_lb, + dec_mem_sw => dec_mem_sw, + dec_mem_sb => dec_mem_sb, + dec_shift_lsl => dec_shift_lsl, + dec_shift_lsr => dec_shift_lsr, + dec_shift_asr => dec_shift_asr, + dec_shift_ror => dec_shift_ror, + dec_shift_rrx => dec_shift_rrx, + dec_shift_val => dec_shift_val, + dec_cy => dec_cy, + dec_comp_op1 => dec_comp_op1, + dec_comp_op2 => dec_comp_op2, + dec_alu_cy => dec_alu_cy, + dec_alu_cmd => dec_alu_cmd, + exe_res => exe_res, + exe_c => exe_c, + exe_v => exe_v, + exe_n => exe_n, + exe_z => exe_z, + exe_dest => exe_dest, + exe_wb => exe_wb, + exe_flag_wb => exe_flag_wb, + exe_mem_adr => exe_mem_adr, + exe_mem_data => exe_mem_data, + exe_mem_dest => exe_mem_dest, + exe_mem_lw => exe_mem_lw, + exe_mem_lb => exe_mem_lb, + exe_mem_sw => exe_mem_sw, + exe_mem_sb => exe_mem_sb, + exe2mem_empty => exe2mem_empty, + mem_pop => mem_pop, + ck => ck, + reset_n => reset_n, + vdd => vdd, + vss => vss + ); + + -- HOLORGE + + ck <= not ck after 2 ns; + process + begin + -- decode interface synchro + dec2exe_empty <= '0'; + -- decode interface operands + dec_op1 <= x"00000005"; --important + dec_op2 <= x"00000000"; --important + dec_exe_dest <= x"1"; + dec_exe_wb <= '1'; + dec_flag_wb <= '1'; + -- decode to mem interface + dec_mem_data <= x"00000000"; + dec_mem_dest <= x"2"; + dec_pre_index <= '1'; -- important + dec_mem_lw <= '0'; + dec_mem_lb <= '0'; + dec_mem_sw <= '0'; + dec_mem_sb <= '0'; + --shifter command + dec_shift_lsl <= '0'; + dec_shift_lsr <= '0'; + dec_shift_asr <= '0'; + dec_shift_ror <= '0'; + dec_shift_rrx <= '0'; + dec_shift_val <= "00000"; + dec_cy <= '0'; + -- Alu operand selection + dec_comp_op1 <= '0'; + dec_comp_op2 <= '0'; + dec_alu_cy <= '0'; + -- alu command + dec_alu_cmd <= "01"; + -- mem interface + mem_pop <= '0'; + reset_n <= '1'; + vdd <= '1'; + vss <= '0'; + + wait for 10 ns; + -- addition de 2 et 1 + dec_op1 <= x"00000002"; + dec_op2 <= x"00000001"; + dec_pre_index <= '0'; -- si 1 op1 si 0 op1 op2 + -- + dec_shift_lsl <= '0'; + dec_shift_lsr <= '0'; + dec_shift_asr <= '0'; + dec_shift_ror <= '0'; + dec_shift_rrx <= '0'; + dec_shift_val <= "00000"; + dec_cy <= '0'; + --- + dec_comp_op1 <= '0'; -- ~op1 + dec_comp_op2 <= '0'; -- ~op2 + dec_alu_cy <= '0'; -- carry complement a 2 les ops + dec_alu_cmd <= "00";-- commande "00" == add + + wait for 10 ns; + assert exe_res = x"00000003" report "ERROR EXEC addition (2 et 1)" severity FAILURE; + + -- soustraction de 3 et 1 + dec_op1 <= x"00000002"; + dec_op2 <= x"00000001"; + dec_pre_index <= '0'; -- si 1 op1 si 0 op1 op2 + -- + dec_shift_lsl <= '0'; + dec_shift_lsr <= '0'; + dec_shift_asr <= '0'; + dec_shift_ror <= '0'; + dec_shift_rrx <= '0'; + dec_shift_val <= "00000"; + dec_cy <= '0'; + --- + dec_comp_op1 <= '0'; -- ~op1 + dec_comp_op2 <= '1'; -- ~op2 + dec_alu_cy <= '1'; -- carry complement a 2 les ops + dec_alu_cmd <= "00";-- commande "00" == add + wait for 10 ns; + assert exe_res = x"00000001" report "ERROR EXEC addition (2 et -1)" severity FAILURE; + + -- soustraction de 1 et 3 + dec_op1 <= x"00000001"; + dec_op2 <= x"00000003"; + dec_pre_index <= '0'; -- si 1 op1 si 0 op1 op2 + -- + dec_shift_lsl <= '0'; + dec_shift_lsr <= '0'; + dec_shift_asr <= '0'; + dec_shift_ror <= '0'; + dec_shift_rrx <= '0'; + dec_shift_val <= "00000"; + dec_cy <= '0'; + --- + dec_comp_op1 <= '0'; -- ~op1 + dec_comp_op2 <= '1'; -- ~op2 + dec_alu_cy <= '1'; -- carry complement a 2 les ops + dec_alu_cmd <= "00";-- commande "00" == add + wait for 10 ns; + -- FFFFFFFE => -2 + assert exe_res = x"FFFFFFFE" report "ERROR EXEC addition (1 et -3)" severity FAILURE; + + -- soustraction de 1 et 8 (1 avec shift de 3) + dec_op1 <= x"00000001"; + dec_op2 <= x"00000001"; + dec_pre_index <= '0'; -- si 1 op1 si 0 op1 op2 + -- + dec_shift_lsl <= '1'; -- left shift + dec_shift_lsr <= '0'; + dec_shift_asr <= '0'; + dec_shift_ror <= '0'; + dec_shift_rrx <= '0'; + dec_shift_val <= "00011"; -- decalage de 3 + dec_cy <= '0'; + --- + dec_comp_op1 <= '0'; -- op1 + dec_comp_op2 <= '1'; -- ~op2 + dec_alu_cy <= '1'; -- carry complement a 2 les ops + dec_alu_cmd <= "00";-- commande "00" == add + wait for 10 ns; + -- FFFFFFF9 => -7 + assert exe_res = x"FFFFFFF9" report "ERROR EXEC addition (1 et -3)" severity FAILURE; + + report "fin simu" severity FAILURE; + end process; + +end Structurel; diff --git a/fifo_72b.vhdl b/fifo_72b.vhdl new file mode 100644 index 0000000..bead23e --- /dev/null +++ b/fifo_72b.vhdl @@ -0,0 +1,72 @@ +LIBRARY ieee; +use ieee.std_logic_1164.all; + +ENTITY fifo IS + PORT( + din : in std_logic_vector(71 downto 0); + dout : out std_logic_vector(71 downto 0); + + -- commands + push : in std_logic; + pop : in std_logic; + + -- flags + full : out std_logic; + empty : out std_logic; + + reset_n : in std_logic; + ck : in std_logic; + vdd : in bit; + vss : in bit + ); +END fifo; + +architecture dataflow of fifo is + +signal fifo_d : std_logic_vector(71 downto 0); +signal fifo_v : std_logic; + +begin + + process(ck) + begin + if rising_edge(ck) then + -- Valid bit + if reset_n = '0' then + fifo_v <= '0'; + else + if fifo_v = '0' then + if push = '1' then + fifo_v <= '1'; + else + fifo_v <= '0'; + end if; + else + if pop = '1' then + if push = '1' then + fifo_v <= '1'; + else + fifo_v <= '0'; + end if; + else + fifo_v <= '1'; + end if; + end if; + end if; + + -- data + if fifo_v = '0' then + if push = '1' then + fifo_d <= din; + end if; + elsif push='1' and pop='1' then + fifo_d <= din; + end if; + end if; + end process; + + full <= '1' when fifo_v = '1' and pop = '0' else '0'; + empty <= not fifo_v; + dout <= fifo_d; + +end dataflow; \ No newline at end of file