From 1cff60582edd3e6c7ae4318ef5ec4af227e9c5b9 Mon Sep 17 00:00:00 2001 From: rlindsberg Date: Mon, 8 Oct 2018 22:08:26 +0200 Subject: [PATCH] Change name to processor code name --- AR4003/ALU.vhd | 76 ++++++ AR4003/AR4003.vhd | 160 +++++++++++ AR4003/controller.vhd | 253 ++++++++++++++++++ cpu_package.vhd => AR4003/cpu_package.vhd | 0 AR4003/data_buffer.vhd | 21 ++ AR4003/multiplexer.vhd | 21 ++ register_file.vhd => AR4003/register_file.vhd | 0 .../tb_register_file.vhd | 0 README.md | 2 +- processor/enchip.vhd | 4 +- processor/processor.vhd | 4 +- processor/tb_processor.vhd | 8 +- 12 files changed, 540 insertions(+), 9 deletions(-) create mode 100644 AR4003/ALU.vhd create mode 100644 AR4003/AR4003.vhd create mode 100644 AR4003/controller.vhd rename cpu_package.vhd => AR4003/cpu_package.vhd (100%) create mode 100644 AR4003/data_buffer.vhd create mode 100644 AR4003/multiplexer.vhd rename register_file.vhd => AR4003/register_file.vhd (100%) rename tb_register_file.vhd => AR4003/tb_register_file.vhd (100%) diff --git a/AR4003/ALU.vhd b/AR4003/ALU.vhd new file mode 100644 index 0000000..a6580da --- /dev/null +++ b/AR4003/ALU.vhd @@ -0,0 +1,76 @@ +Library IEEE; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.cpu_package.all; + +Entity ALU is + Port ( in_Op : in std_logic_vector(2 downto 0); + in_A : in data_word; + in_B : in data_word; + in_En : in std_logic; + clk : in std_logic; + out_y : out data_word; + out_n_flag : out std_logic := '0'; + out_z_flag : out std_logic := '0'; + out_o_flag : out std_logic := '0' + ); +End Entity; + +Architecture RTL of ALU is + Begin + + -- we need a process since functions from cpu_package can't be called outside one. + Process(clk, in_En, in_Op, in_A, in_B) + -- data_bus because it is only a midpoint between destinations + Variable S : data_bus; + Variable al : std_logic; + Variable bl : std_logic; + Variable sl : std_logic; + + Begin + -- time is needed for a value to propagate ergo we need to assign it after "begin". + al := in_A(in_A'length-1); + bl := in_B(in_B'length-1); + + -- with..select..others is a concurrent signal assignment statement used outside of a process. Thus, useing if. + if (Rising_edge(clk) AND in_En='1') then + -- reset flags + out_n_flag <= '0'; + out_o_flag <= '0'; + out_z_flag <= '0'; + + -- decoding Op + S_CASE : case in_Op is + when "000" => S := add_overflow(in_A, in_B); + when "001" => S := sub_overflow(in_A, in_B); + when "010" => S := in_A and in_B; + when "011" => S := in_A or in_B; + when "100" => S := in_A xor in_B; + when "101" => S := not in_A; + when "110" => S := in_A; + when others => S := S; + end case; + + -- S gets its value in S_CASE and processes are sequential + sl := S(S'length-1); + + -- using Op for deciding the way to calculate overflow flag. + O_CASE : case in_Op is + when "000" => out_o_flag <= (not al and not bl and sl) or (al and bl and not sl); + when "001" => out_o_flag <= (not al and bl and sl) or (al and not bl and not sl); + when others => out_o_flag <= '0'; + end case; + + -- setting y to S + out_y <= S; + + -- negative flag + out_n_flag <= sl; + + -- zero flag + if unsigned(S) = 0 then out_z_flag <= '1'; + end if; + + end if; + End Process; +End Architecture; diff --git a/AR4003/AR4003.vhd b/AR4003/AR4003.vhd new file mode 100644 index 0000000..52c3afe --- /dev/null +++ b/AR4003/AR4003.vhd @@ -0,0 +1,160 @@ +Library IEEE; +Use IEEE.std_logic_1164.all; +Use IEEE.numeric_std.all; +Use work.cpu_package.all; + +Entity AR4003 is + Port( out_adr : out address_bus; + in_data : instruction_bus; + in_stop : std_logic; + inout_RWM_data : inout data_bus; + out_rw_RWM : out std_logic; + out_ROM_en : out std_logic; + out_RWM_en : out std_logic; + clk : std_logic; + in_reset : std_logic); +end Entity; + +Architecture Structure of AR4003 is + Component ALU + Port ( in_Op : in std_logic_vector(2 downto 0); + in_A : in data_word; + in_B : in data_word; + in_En : in std_logic; + clk : in std_logic; + out_y : out data_word; + out_n_flag : out std_logic; + out_z_flag : out std_logic; + out_o_flag : out std_logic); + end Component; + + Component controller + Port( out_adr : out address_bus; -- unsigned + in_data : program_word; -- unsigned + out_rw_RWM : out std_logic; -- read on high + out_RWM_en : out std_logic; -- active low + out_ROM_en : out std_logic; -- active low + clk : std_logic; + in_reset : std_logic; -- active high + out_rw_reg : out std_logic; -- read on high + out_sel_op_1 : out unsigned(1 downto 0); + out_sel_op_0 : out unsigned(1 downto 0); + out_sel_in : out unsigned(1 downto 0); + out_sel_mux : out unsigned(1 downto 0); + out_alu_op : out unsigned(2 downto 0); + out_alu_en : out std_logic; -- active high + in_z_flag : std_logic; -- active high + in_n_flag : std_logic; -- active high + in_o_flag : std_logic; -- active high + out_out_en : out std_logic; -- active high + out_data_imm : out data_word; -- signed + in_stop : std_logic); + end Component; + + Component data_buffer + Port( in_out_en : std_logic; + in_data_in : data_word; + out_data_out : out data_word); + end component; + + Component multiplexer + Port( in_sel : std_logic_vector(1 downto 0); + in_data_in_2 : data_word; + in_data_in_1 : data_word; + in_data_in_0 : data_word; + out_data_out : out data_word); + end Component; + + Component register_file + Port( clk : in std_logic; + in_data_in : in data_word; + out_data_out_1 : out data_word; + out_data_out_0 : out data_word; + in_sel_in : in std_logic_vector (1 downto 0); + in_sel_out_1 : in std_logic_vector (1 downto 0); + in_sel_out_0 : in std_logic_vector (1 downto 0); + in_rw_reg : in std_logic); + end Component; + + -- ALU signals + signal sig_z_flag, sig_n_flag, sig_o_flag, sig_alu_en : std_logic; + signal sig_alu_op : unsigned(2 downto 0); + signal sig_alu_out : data_word; + + -- controller signal + signal sig_data_imm : data_word; + + -- register_file signals + signal sig_rw_reg : std_logic; + signal sig_sel_out_0, sig_sel_out_1, sig_sel_in : unsigned(1 downto 0); + signal sig_reg_data_out_0, sig_reg_data_out_1 : data_word; + + -- multiplexer signals + signal sig_sel_mux : unsigned(1 downto 0); + signal sig_mux_data_out : data_word; + + -- data_buffer signals + signal sig_out_en : std_logic; + +Begin + Ctl_inst: controller port map ( + out_adr => out_adr, -- out + in_data => in_data, + out_rw_RWM => out_rw_RWM, -- out + out_RWM_en => out_RWM_en, -- out + out_ROM_en => out_ROM_en, -- out + clk => clk, + in_reset => in_reset, + out_rw_reg => sig_rw_reg, -- out + out_sel_op_1 => sig_sel_out_1, -- out + out_sel_op_0 => sig_sel_out_0, -- out + out_sel_in => sig_sel_in, -- out + out_sel_mux => sig_sel_mux, -- out + out_alu_op => sig_alu_op, -- out + out_alu_en => sig_alu_en, -- out + in_z_flag => sig_z_flag, + in_n_flag => sig_n_flag, + in_o_flag => sig_o_flag, + out_out_en => sig_out_en, -- out + out_data_imm => sig_data_imm, -- out + in_stop => in_stop + ); + + ALU_inst: ALU port map ( + in_Op => std_logic_vector(sig_alu_op), + in_A => sig_reg_data_out_1, + in_B => sig_reg_data_out_0, + in_En => sig_alu_en, + clk => clk, + out_y => sig_alu_out, -- out + out_n_flag => sig_n_flag, -- out + out_z_flag => sig_z_flag, -- out + out_o_flag => sig_o_flag -- out + ); + + reg_file_inst: register_file port map ( + clk => clk, + in_data_in => sig_mux_data_out, + out_data_out_1 => sig_reg_data_out_1, -- out + out_data_out_0 => sig_reg_data_out_0, -- out + in_sel_in => std_logic_vector(sig_sel_in), + in_sel_out_1 => std_logic_vector(sig_sel_out_1), + in_sel_out_0 => std_logic_vector(sig_sel_out_0), + in_rw_reg => sig_rw_reg + ); + + MUX_inst: multiplexer port map ( + in_sel => std_logic_vector(sig_sel_mux), + in_data_in_2 => sig_data_imm, + in_data_in_1 => inout_RWM_data, + in_data_in_0 => sig_alu_out, + out_data_out => sig_mux_data_out -- out + ); + + buffer_inst: data_buffer port map ( + in_out_en => sig_out_en, + in_data_in => sig_reg_data_out_1, + out_data_out => inout_RWM_data -- out + ); + +end Architecture; diff --git a/AR4003/controller.vhd b/AR4003/controller.vhd new file mode 100644 index 0000000..e41ef64 --- /dev/null +++ b/AR4003/controller.vhd @@ -0,0 +1,253 @@ +Library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.cpu_package.all; + +entity controller is + Port( out_adr : out address_bus; -- unsigned + in_data : program_word; -- unsigned + out_rw_RWM : out std_logic; -- read on high + out_RWM_en : out std_logic; -- active low + out_ROM_en : out std_logic; -- active low + clk : std_logic; + in_reset : std_logic; -- active high + out_rw_reg : out std_logic; -- read on high + out_sel_op_1 : out unsigned(1 downto 0); + out_sel_op_0 : out unsigned(1 downto 0); + out_sel_in : out unsigned(1 downto 0); + out_sel_mux : out unsigned(1 downto 0); + out_alu_op : out unsigned(2 downto 0); + out_alu_en : out std_logic; -- active high + in_z_flag : std_logic; -- active high + in_n_flag : std_logic; -- active high + in_o_flag : std_logic; -- active high + out_out_en : out std_logic; -- active high + out_data_imm : out data_word; -- signed + in_stop : std_logic); +end entity; + +architecture fun_part of controller is + subtype state_type is integer range 0 to 3; + signal state : state_type := 0; + signal next_state : state_type := 0; + signal next_pc : integer := 0; + + signal inst : program_word; + signal pc : integer := 0; + + alias inst_op : std_logic_vector(3 downto 0) is inst(9 downto 6); + alias inst_alu_op : std_logic_vector(2 downto 0) is inst(8 downto 6); + alias inst_r1 : std_logic_vector(1 downto 0) is inst(5 downto 4); + alias inst_r2 : std_logic_vector(1 downto 0) is inst(3 downto 2); + alias inst_r3 : std_logic_vector(1 downto 0) is inst(1 downto 0); + alias inst_mem : std_logic_vector(3 downto 0) is inst(3 downto 0); + alias inst_data_imm : std_logic_vector(3 downto 0) is inst(3 downto 0); + +begin + + COUNT : process(clk, in_reset, in_stop) + begin + if in_reset = '1' then + state <= 0; + elsif rising_edge(clk) and in_stop = '0' then + state <= next_state; + end if; + end process; + + LOGIC : process(clk, state) -- decode + branching + begin + if rising_edge(clk) then + case state is + when 0 => + out_ROM_en <= '1'; + next_pc <= 0; + out_out_en <= '0'; + out_rw_reg <= '1'; + next_state <= state + 1; + + when 1 => + out_adr <= std_logic_vector(to_unsigned(pc, address_size)); + pc <= next_pc; + next_state <= state + 1; + + when 2 => + + -- -- test 1: testing out_ROM_en's value from state 1 + -- -- test 1 should success at 1000 ps, 7000 ps and 1300 ps + + -- moved from state 1 + out_ROM_en <= '1'; -- deactive high + inst <= in_data; + next_state <= state + 1; + + case inst_op is + when "1000" => + out_RWM_en <= '0'; -- deactive high + out_adr <= in_data(3 downto 0); -- out_adr is connected texpressiono both RWM and ROM + when "1001" => + out_RWM_en <= '0'; -- deactive high + out_adr <= in_data(3 downto 0); -- out_adr is connected texpressiono both RWM and ROM + when others => + out_RWM_en <= '1'; -- deactive high + end case; + + when 3 => + + -- test 2: testing out_ROM_en's value from state 2 + -- test 2 should success at 2500 ps, 8500 ps, 14500 ps + + case inst_op is + -- add + when "0000" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= unsigned(inst_r2); -- r2 + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- sub + when "0001" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= unsigned(inst_r2); -- r2 + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- and + when "0010" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= unsigned(inst_r2); -- r2 + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- or + when "0011" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= unsigned(inst_r2); -- r2 + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- xor + when "0100" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= unsigned(inst_r2); -- r2 + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- not + when "0101" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= "00"; + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- mov + when "0110" => + out_alu_op <= unsigned(inst_alu_op); + out_sel_op_1 <= unsigned(inst_r1); -- r1; reg to read from + -- out_sel_in chooses to which register data_in is written + out_sel_in <= unsigned(inst_r3); -- r3; reg to save to + out_sel_mux <= "00"; -- alu output + out_sel_op_0 <= "00"; + out_alu_en <= '1'; -- enable alu + out_rw_reg <= '0'; -- enable write to reg + next_pc <= pc + 1; + + -- ldr + when "1000" => + out_rw_RWM <= '1'; -- set RWM in 'read from' mode + out_sel_mux <= "01"; -- inst from RWM + out_sel_in <= unsigned(inst_r1); -- r1; reg to save to + out_rw_reg <= '0'; + next_pc <= pc + 1; + + -- str + when "1001" => + out_rw_RWM <= '0'; -- set RWM in 'write to' mode + out_sel_op_1 <= unsigned(inst_r1); + out_out_en <= '1'; + next_pc <= pc + 1; + + -- ldi + when "1010" => + out_sel_in <= unsigned(inst_r1); + out_sel_mux <= "10"; + out_data_imm <= inst_data_imm; + next_pc <= pc + 1; + + -- nop + when "1011" => + next_pc <= pc + 1; + + -- brz + when "1100" => + if in_z_flag = '1' then + next_pc <= to_integer(unsigned(inst_mem)); + elsif state = next_state then + next_pc <= pc + 1; + end if; + + -- brn + when "1101" => + if in_n_flag = '1' then + next_pc <= to_integer(unsigned(inst_mem)); + elsif state = next_state then + next_pc <= pc + 1; + end if; + + -- bro + when "1110" => + if in_o_flag = '1' then + next_pc <= to_integer(unsigned(inst_mem)); + elsif state = next_state then + next_pc <= pc + 1; + end if; + + -- bra + when "1111" => + next_pc <= to_integer(unsigned(inst_mem)); + + when others => + next_pc <= 0; + + end case; + + -- prepare for state 1 + out_RWM_en <= '1' after 100 ps; -- active low + out_ROM_en <= '0' after 100 ps; + out_out_en <= '0' after 100 ps; + out_rw_reg <= '1' after 100 ps; + + next_state <= 1 after 100 ps; + end case; + end if; + end process; +end architecture; diff --git a/cpu_package.vhd b/AR4003/cpu_package.vhd similarity index 100% rename from cpu_package.vhd rename to AR4003/cpu_package.vhd diff --git a/AR4003/data_buffer.vhd b/AR4003/data_buffer.vhd new file mode 100644 index 0000000..d8dcfbd --- /dev/null +++ b/AR4003/data_buffer.vhd @@ -0,0 +1,21 @@ +Library IEEE; +Use IEEE.std_logic_1164.all; +use work.cpu_package.all; + +Entity data_buffer is + Port( in_out_en : std_logic; + in_data_in : data_word; + out_data_out : out data_word); +End Entity; + +architecture rtl of data_buffer is +begin + process(in_out_en, in_data_in) + begin + if in_out_en = '1' then + out_data_out <= in_data_in; + else + out_data_out <= (others => 'Z'); + end if; + end process; +end architecture; diff --git a/AR4003/multiplexer.vhd b/AR4003/multiplexer.vhd new file mode 100644 index 0000000..7f18ef2 --- /dev/null +++ b/AR4003/multiplexer.vhd @@ -0,0 +1,21 @@ +Library IEEE; +Use IEEE.std_logic_1164.all; +Use IEEE.numeric_std.all; +use work.cpu_package.all; + +Entity multiplexer is + Port( in_sel : std_logic_vector(1 downto 0); + in_data_in_2 : data_word; + in_data_in_1 : data_word; + in_data_in_0 : data_word; + out_data_out : out data_word); +End Entity; + +Architecture rtl of multiplexer is +Begin + with in_sel select + out_data_out <= in_data_in_0 when "00", + in_data_in_1 when "01", + in_data_in_2 when "10", + (others=>'U') when others; +End Architecture; diff --git a/register_file.vhd b/AR4003/register_file.vhd similarity index 100% rename from register_file.vhd rename to AR4003/register_file.vhd diff --git a/tb_register_file.vhd b/AR4003/tb_register_file.vhd similarity index 100% rename from tb_register_file.vhd rename to AR4003/tb_register_file.vhd diff --git a/README.md b/README.md index 636e147..9afbf79 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # 1331IL-VHDL-Design -Microprocessor AR 4003 +MicroAR4003 AR 4003 diff --git a/processor/enchip.vhd b/processor/enchip.vhd index 992c34e..1fdcf0a 100644 --- a/processor/enchip.vhd +++ b/processor/enchip.vhd @@ -12,7 +12,7 @@ Entity enchip is End Entity; Architecture structure of enchip is - Component processor + Component AR4003 Port( out_adr : out address_bus; in_data : instruction_bus; in_stop : std_logic; @@ -45,7 +45,7 @@ Architecture structure of enchip is signal sig_RWM_en, sig_ROM_en, sig_rw_RWM : std_logic; Begin - PR : processor port map ( + PR : AR4003 port map ( out_adr => sig_adr, in_data => sig_ROM_data, in_stop => in_stop, diff --git a/processor/processor.vhd b/processor/processor.vhd index 4699911..52c3afe 100644 --- a/processor/processor.vhd +++ b/processor/processor.vhd @@ -3,7 +3,7 @@ Use IEEE.std_logic_1164.all; Use IEEE.numeric_std.all; Use work.cpu_package.all; -Entity processor is +Entity AR4003 is Port( out_adr : out address_bus; in_data : instruction_bus; in_stop : std_logic; @@ -15,7 +15,7 @@ Entity processor is in_reset : std_logic); end Entity; -Architecture Structure of processor is +Architecture Structure of AR4003 is Component ALU Port ( in_Op : in std_logic_vector(2 downto 0); in_A : in data_word; diff --git a/processor/tb_processor.vhd b/processor/tb_processor.vhd index 8e6a736..e3e9c47 100644 --- a/processor/tb_processor.vhd +++ b/processor/tb_processor.vhd @@ -3,11 +3,11 @@ Use IEEE.std_logic_1164.all; Use IEEE.numeric_std.all; Use work.cpu_package.all; -Entity tb_processor is +Entity tb_AR4003 is end Entity; -Architecture test of tb_processor is - Component processor +Architecture test of tb_AR4003 is + Component AR4003 Port( out_adr : out address_bus; in_data : instruction_bus; in_stop : std_logic; @@ -50,7 +50,7 @@ Architecture test of tb_processor is ); begin - Pocesor_inst : processor port map( + Pocesor_inst : AR4003 port map( out_adr => sig_adr, in_data => sig_ROM_data, in_stop => sig_stop,