diff --git a/firmware/alu/.gitignore b/firmware/alu/.gitignore new file mode 100644 index 0000000..d294f06 --- /dev/null +++ b/firmware/alu/.gitignore @@ -0,0 +1,99 @@ +# intermediate build files +*.bgn +*.bit +*.bld +*.cmd_log +*.drc +*.ll +*.lso +*.msd +*.msk +*.ncd +*.ngc +*.ngd +*.ngr +*.pad +*.par +*.pcf +*.prj +*.ptwx +*.rbb +*.rbd +*.stx +*.syr +*.twr +*.twx +*.unroutes +*.ut +*.xpi +*.xst +*_bitgen.xwbt +*_envsettings.html +*_map.map +*_map.mrp +*_map.ngm +*_map.xrpt +*_ngdbuild.xrpt +*_pad.csv +*_pad.txt +*_par.xrpt +*_summary.html +*_summary.xml +*_usage.xml +*_xst.xrpt + +# iMPACT generated files +_impactbatch.log +impact.xsl +impact_impact.xwbt +ise_impact.cmd +webtalk_impact.xml + +# Core Generator generated files +xaw2verilog.log + +# project-wide generated files +*.gise +par_usage_statistics.html +usage_statistics_webtalk.html +webtalk.log +webtalk_pn.xml + +# generated folders +iseconfig/ +xlnx_auto_0_xdb/ +xst/ +_ngo/ +_xmsgs/ + +# isim +/isim* +/fuse* +*.exe +*.wdb +xilinxsim.ini + +# log files +*.log + +# ip cores +/ipcore_dir/*.cgc +/ipcore_dir/*.cgp +/ipcore_dir/*.tcl +/ipcore_dir/*.vhd +/ipcore_dir/*flist.txt +/ipcore_dir/_xmsgs/ +/ipcore_dir/tmp/ + +# cpld +/main_html/ +*.gyd +*.jed +*.mfd +*.nga +*.pnx +*.rpt +*.vm6 +*.xml +*.err + diff --git a/firmware/alu/adder.vhd b/firmware/alu/adder.vhd new file mode 100644 index 0000000..3902804 --- /dev/null +++ b/firmware/alu/adder.vhd @@ -0,0 +1,30 @@ +library ieee; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.ALL; + +entity adder is + generic ( + WIDTH: integer + ); + port ( + x: in std_logic_vector(WIDTH-1 downto 0); + y: in std_logic_vector(WIDTH-1 downto 0); + cin: in std_logic; + sum: out std_logic_vector(WIDTH-1 downto 0); + cout: out std_logic + ); +end adder; + +architecture rtl of adder is + signal result: unsigned(WIDTH downto 0); +begin + + result <= resize(unsigned(x), WIDTH+1) + + resize(unsigned(y), WIDTH+1) + + ("" & cin); + + sum <= std_logic_vector(result(WIDTH-1 downto 0)); + cout <= result(WIDTH); + +end rtl; diff --git a/firmware/alu/alu.xise b/firmware/alu/alu.xise new file mode 100644 index 0000000..a69d833 --- /dev/null +++ b/firmware/alu/alu.xise @@ -0,0 +1,245 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/firmware/alu/main.vhd b/firmware/alu/main.vhd new file mode 100644 index 0000000..1352b07 --- /dev/null +++ b/firmware/alu/main.vhd @@ -0,0 +1,96 @@ +library ieee; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.ALL; + +entity main is + generic ( + WIDTH: integer := 8 + ); + port ( + func: in std_logic_vector(3 downto 0); + accu: in std_logic_vector(WIDTH-1 downto 0); + ram: in std_logic_vector(WIDTH-1 downto 0); + carry_in: in std_logic; + result: out std_logic_vector(WIDTH-1 downto 0); + carry_out: out std_logic + ); +end main; + +architecture rtl of main is + signal x: std_logic_vector(WIDTH-1 downto 0); + signal y: std_logic_vector(WIDTH-1 downto 0); + signal cin: std_logic; + signal sum: std_logic_vector(WIDTH-1 downto 0); + signal cout: std_logic; +begin + + adder: entity work.adder generic map ( + WIDTH => WIDTH + ) port map ( + x => x, + y => y, + cin => cin, + sum => sum, + cout => cout + ); + + process(func, accu, ram, carry_in, sum, cout) + variable carry: std_logic; + begin + -- This default value will be overwritten in the add/sub cases + carry_out <= '0'; + + -- Avoid generating latches by leaving the adder inputs unspecified + -- when it is not beeing used (otherwise these are overwritten) + x <= (others => '-'); + y <= (others => '-'); + cin <= '-'; + + case func is + when "0000" => -- STORE + result <= accu; + when "0001" => -- LOAD + result <= ram; + when "0010" => -- JMP + result <= (others => '-'); + when "0011" => -- ADD + x <= accu; + y <= ram; + cin <= carry_in; + result <= sum; + carry_out <= cout; + when "0100" => -- SUB + x <= accu; + y <= not ram; + cin <= not carry_in; + result <= sum; + carry_out <= not cout; + when "0101" => -- OR + result <= accu or ram; + when "0110" => -- AND + result <= accu and ram; + when "0111" => -- XOR + result <= accu xor ram; + when "1000" => -- NOT + result <= not accu; + when "1001" => -- INC + x <= accu; + y <= (others => '0'); + cin <= '1'; + result <= sum; + carry_out <= cout; + when "1010" => -- DEC + x <= accu; + y <= (others => '1'); + cin <= '0'; + result <= sum; + carry_out <= not cout; + when "1011" => -- ZERO + result <= (others => '0'); + when others => -- NOPs + result <= (others => '-'); + end case; + end process; + +end rtl; diff --git a/firmware/alu/tests/toy_16.vhd b/firmware/alu/tests/toy_16.vhd new file mode 100644 index 0000000..3590073 --- /dev/null +++ b/firmware/alu/tests/toy_16.vhd @@ -0,0 +1,141 @@ +library ieee; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity toy_16 is +end toy_16; + +architecture test of toy_16 is + + constant period: time := 1us; + + component main + port ( + func: in std_logic_vector(3 downto 0); + accu: in std_logic_vector(7 downto 0); + ram: in std_logic_vector(7 downto 0); + carry_in: in std_logic; + result: out std_logic_vector(7 downto 0); + carry_out: out std_logic + ); + end component; + + --Inputs + signal func: std_logic_vector(3 downto 0) := (others => '0'); + signal accu: std_logic_vector(15 downto 0) := (others => '0'); + signal ram: std_logic_vector(15 downto 0) := (others => '0'); + signal carry_in: std_logic := '0'; + + --Outputs + signal result: std_logic_vector(15 downto 0); + signal carry_out: std_logic; + + -- Internal signals + signal carry_propagation: std_logic; + + -- Test constants + constant A: std_logic_vector(15 downto 0) := "1010101010101010"; + constant B: std_logic_vector(15 downto 0) := "1100110011001100"; + + -- Info String (driven by procedure in test_process) + signal info_string: string(1 to 10); + +begin + + alu1: main port map ( + func => func, + accu => accu(7 downto 0), + ram => ram(7 downto 0), + carry_in => '0', + result => result(7 downto 0), + carry_out => carry_propagation + ); + + alu2: main port map ( + func => func, + accu => accu(15 downto 8), + ram => ram(15 downto 8), + carry_in => carry_propagation, + result => result(15 downto 8), + carry_out => open + ); + + test_process: process + procedure info(info: string) is + begin + info_string <= (others => ' '); + info_string(1 to info'length) <= info; + end procedure; + begin + -- + -- logic tests + -- + accu <= A; ram <= B; carry_in <= '0'; + + info("STORE"); + func <= "0000"; + wait for period; + assert result = A report "STORE failed"; + + info("LOAD"); + func <= "0001"; + wait for period; + assert result = B report "LOAD failed"; + + info("OR"); + func <= "0101"; + wait for period; + assert result = (A or B) report "OR failed"; + + info("AND"); + func <= "0110"; + wait for period; + assert result = (A and B) report "AND failed"; + + info("XOR"); + func <= "0111"; + wait for period; + assert result = (A xor B) report "XOR failed"; + + info("NOT"); + func <= "1000"; + wait for period; + assert result = not A report "NOT failed"; + + info("ZERO"); + func <= "1011"; + wait for period; + assert result = "0000000000000000" report "ZERO failed"; + + -- + -- arithmatic tests + -- + + info("ADD"); + accu <= "0100010011110011"; + ram <= "0011100010101010"; carry_in <= '0'; + func <= "0011"; + wait for period; + assert result = "0111110110011101" report "ADD failed"; + + info("SUB"); + accu <= "0100010000110011"; + ram <= "0011100000101010"; carry_in <= '0'; + func <= "0100"; + wait for period; + assert result = "0000110000001001" report "SUB failed"; + + info("SUB-B"); + accu <= "0100010010110011"; + ram <= "0011100011101010"; carry_in <= '0'; + func <= "0100"; + wait for period; + assert result = "0000101111001001" report "SUB failed"; + + -- terminate test + wait; + + end process; + +end test;