diff --git a/vhdl/clock_gen.vhd b/vhdl/clock_gen.vhd index b763178..4c4ab6e 100755 --- a/vhdl/clock_gen.vhd +++ b/vhdl/clock_gen.vhd @@ -21,70 +21,75 @@ end; architecture my_clock_gen of clock_gen is - type state is (s_idle, s_read, s_alu, s_write, s_wait, s_next); + type state_type is (s_idle, s_read, s_alu, s_write, s_wait, s_next); - signal current_state : state := s_idle; - signal next_state : state := s_idle; + signal state : state_type := s_idle; +begin + clock_gen : process(clk, reset, state, ram_busy, alu_ins) begin - clock_gen : process(current_state, ram_busy, alu_ins) - begin + if reset = '1' then + phi_read <= '0'; phi_alu <= '0'; phi_write <= '0'; phi_next <= '0'; + state <= s_idle; - case current_state is - - when s_idle => - next_state <= s_read; - - when s_read => - phi_read <= '1'; - if alu_ins = '0' then - next_state <= s_write; - else - next_state <= s_alu; - end if; - - when s_alu => - phi_alu <= '1'; - next_state <= s_write; - - when s_write => - phi_write <= '1'; - next_state <= s_next; - - when s_next => - phi_next <= '1'; - if ram_busy = '1' then - next_state <= s_wait; - else - next_state <= s_read; - end if; - - when s_wait => - if ram_busy = '0' then - next_state <= s_read; - else - next_state <= s_wait; - end if; - end case; - end process; - - set_next_state : process(clk, next_state, reset) - begin - if reset = '1' then - current_state <= s_idle; - elsif rising_edge(clk) then - if stop = '1' then - stopped <= '1'; - current_state <= current_state; - else - stopped <= '0'; - current_state <= next_state; - end if; - end if; - end process; + elsif rising_edge(clk) then + + if stop = '1' then + + stopped <= '1'; + + else + + stopped <= '0'; + + phi_read <= '0'; + phi_alu <= '0'; + phi_write <= '0'; + phi_next <= '0'; + + case state is - end; + when s_idle => + state <= s_read; + + when s_read => + phi_read <= '1'; + if ram_busy = '0' then + if alu_ins = '0' then + state <= s_write; + else + state <= s_alu; + end if; + end if; + + when s_alu => + phi_alu <= '1'; + state <= s_write; + + when s_write => + phi_write <= '1'; + state <= s_next; + + when s_next => + phi_next <= '1'; + if ram_busy = '1' then + state <= s_wait; + else + state <= s_read; + end if; + + when s_wait => + if ram_busy = '0' then + state <= s_read; + else + state <= s_wait; + end if; + end case; + end if; + end if; + end process; +end; diff --git a/vhdl/clock_gen_TB.vhd b/vhdl/clock_gen_TB.vhd new file mode 100755 index 0000000..3210429 --- /dev/null +++ b/vhdl/clock_gen_TB.vhd @@ -0,0 +1,121 @@ +------------------------------------------------------------------------------- +-- +-- Title : Test Bench for clock_gen +-- Design : secd +-- Author : Hans Hübner +-- Company : . +-- +------------------------------------------------------------------------------- +-- +-- File : H:\fpga\secd\vhdl\clock_gen_TB.vhd +-- Generated : 05.07.2006, 13:59 +-- From : h:\fpga\secd\vhdl\clock_gen.vhd +-- By : Active-HDL Built-in Test Bench Generator ver. 1.2s +-- +------------------------------------------------------------------------------- +-- +-- Description : Automatically generated Test Bench for clock_gen_tb +-- +------------------------------------------------------------------------------- + +library ieee; +use work.secd_defs.all; +use ieee.numeric_std.all; +use ieee.std_logic_1164.all; + +-- Add your library and packages declaration here ... + +entity clock_gen_tb is +end clock_gen_tb; + +architecture TB_ARCHITECTURE of clock_gen_tb is + -- Component declaration of the tested unit + component clock_gen + port( + reset : in std_logic; + clk : in std_logic; + alu_ins : in std_logic; + ram_busy : in std_logic; + phi_read : out std_logic; + phi_alu : out std_logic; + phi_write : out std_logic; + phi_next : out std_logic; + stop : in std_logic; + stopped : out std_logic ); + end component; + + -- Stimulus signals - signals mapped to the input and inout ports of tested entity + signal reset : std_logic; + signal clk : std_logic; + signal alu_ins : std_logic; + signal ram_busy : std_logic; + signal stop : std_logic; + -- Observed signals - signals mapped to the output ports of tested entity + signal phi_read : std_logic; + signal phi_alu : std_logic; + signal phi_write : std_logic; + signal phi_next : std_logic; + signal stopped : std_logic; + + -- Add your code here ... + +begin + + -- Unit Under Test port map + UUT : clock_gen + port map ( + reset => reset, + clk => clk, + alu_ins => alu_ins, + ram_busy => ram_busy, + phi_read => phi_read, + phi_alu => phi_alu, + phi_write => phi_write, + phi_next => phi_next, + stop => stop, + stopped => stopped + ); + + -- Add your stimulus here ... + + clock_stimulus : process + begin + clk <= '1'; + wait for 40 ns; + clk <= '0'; + wait for 40 ns; + end process; + + reset <= '0'; + stop <= '0'; + + ram_is_busy : process + begin + loop + ram_busy <= '0'; + wait for 900 ns; + ram_busy <= '1'; + wait for 420 ns; + end loop; + end process; + + has_alu_instruction : process + begin + loop + alu_ins <= '0'; + wait for 500 ns; + alu_ins <= '1'; + wait for 300 ns; + end loop; + end process; + +end TB_ARCHITECTURE; + +configuration TESTBENCH_FOR_clock_gen of clock_gen_tb is + for TB_ARCHITECTURE + for UUT : clock_gen + use entity work.clock_gen(my_clock_gen); + end for; + end for; +end TESTBENCH_FOR_clock_gen; + diff --git a/vhdl/clock_gen_TB_runtest.do b/vhdl/clock_gen_TB_runtest.do new file mode 100755 index 0000000..e025f46 --- /dev/null +++ b/vhdl/clock_gen_TB_runtest.do @@ -0,0 +1,19 @@ +SetActiveLib -work +comp -include "h:\fpga\secd\vhdl\clock_gen.vhd" +comp -include "H:\fpga\secd\vhdl\clock_gen_TB.vhd" +asim TESTBENCH_FOR_clock_gen +wave +wave -noreg reset +wave -noreg clk +wave -noreg alu_ins +wave -noreg ram_busy +wave -noreg phi_read +wave -noreg phi_alu +wave -noreg phi_write +wave -noreg phi_next +wave -noreg stop +wave -noreg stopped +# The following lines can be used for timing simulation +# acom +# comp -include "H:\fpga\secd\vhdl\clock_gen_TB_tim_cfg.vhd" +# asim TIMING_FOR_clock_gen diff --git a/vhdl/control_unit.vhd b/vhdl/control_unit.vhd index 10dcba9..76249f3 100755 --- a/vhdl/control_unit.vhd +++ b/vhdl/control_unit.vhd @@ -58,16 +58,18 @@ architecture my_control_unit of control_unit is opcode, button, stack, next_mpc, sp) begin if reset = '1' then - mpc <= (others => '0'); - push_stack <= '0'; - pop_stack <= '0'; + mpc <= (others => '0'); + push_stack <= '0'; + pop_stack <= '0'; + stop_instruction <= '0'; elsif rising_edge(phi_next) then - push_stack <= '0'; - pop_stack <= '0'; + push_stack <= '0'; + pop_stack <= '0'; + stop_instruction <= '0'; if mi_test = jump then mpc <= mi_a; elsif mi_test = dispatch then - report "executing instruction " & integer'image(to_integer(unsigned(opcode))) & " " & secd_ins_name(to_integer(unsigned(opcode))); +-- report "executing instruction " & integer'image(to_integer(unsigned(opcode))) & " " & secd_ins_name(to_integer(unsigned(opcode))); mpc <= opcode; elsif mi_test = markp and flags(mark) = '1' then mpc <= mi_a; @@ -75,6 +77,10 @@ architecture my_control_unit of control_unit is mpc <= mi_a; elsif mi_test = eqp and flags(eq) = '1' then mpc <= mi_a; + elsif mi_test = leqp and flags(leq) = '1' then + mpc <= mi_a; + elsif mi_test = zerop and flags(zero) = '1' then + mpc <= mi_a; elsif mi_test = nump and flags(num) = '1' then mpc <= mi_a; elsif mi_test = atomp and flags(atom) = '1' then @@ -85,10 +91,10 @@ architecture my_control_unit of control_unit is mpc <= mi_a; elsif mi_test = call then mpc <= mi_a; - stack(sp + 1) <= next_mpc; + stack(sp) <= next_mpc; push_stack <= '1'; elsif mi_test = returnx then - mpc <= stack(sp); + mpc <= stack(sp - 1); pop_stack <= '1'; elsif mi_test = stop then stop_instruction <= '1'; diff --git a/vhdl/control_unit_TB.vhd b/vhdl/control_unit_TB.vhd new file mode 100755 index 0000000..4ef279a --- /dev/null +++ b/vhdl/control_unit_TB.vhd @@ -0,0 +1,124 @@ +------------------------------------------------------------------------------- +-- +-- Title : Test Bench for control_unit +-- Design : secd +-- Author : Hans Hübner +-- Company : . +-- +------------------------------------------------------------------------------- +-- +-- File : H:\fpga\secd\vhdl\control_unit_TB.vhd +-- Generated : 02.07.2006, 16:06 +-- From : h:\fpga\secd\vhdl\control_unit.vhd +-- By : Active-HDL Built-in Test Bench Generator ver. 1.2s +-- +------------------------------------------------------------------------------- +-- +-- Description : Automatically generated Test Bench for control_unit_tb +-- +------------------------------------------------------------------------------- + +library ieee; +use work.secd_defs.all; +use ieee.numeric_std.all; +use ieee.std_logic_1164.all; + +-- Add your library and packages declaration here ... + +entity control_unit_tb is +end control_unit_tb; + +architecture TB_ARCHITECTURE of control_unit_tb is + -- Component declaration of the tested unit + component control_unit + port( + clk : in std_logic; + reset : in std_logic; + phi_next : in std_logic; + button : in std_logic; + opcode : in std_logic_vector(8 downto 0); + flags : in flagsunit; + read_sel : out std_logic_vector(4 downto 0); + write_sel : out std_logic_vector(4 downto 0); + alu_sel : out std_logic_vector(4 downto 0); + alu_ins : out std_logic; + stop_instruction : out std_logic ); + end component; + + -- Stimulus signals - signals mapped to the input and inout ports of tested entity + signal clk : std_logic; + signal reset : std_logic; + signal phi_next : std_logic; + signal button : std_logic; + signal opcode : std_logic_vector(8 downto 0); + signal flags : flagsunit; + -- Observed signals - signals mapped to the output ports of tested entity + signal read_sel : std_logic_vector(4 downto 0); + signal write_sel : std_logic_vector(4 downto 0); + signal alu_sel : std_logic_vector(4 downto 0); + signal alu_ins : std_logic; + signal stop_instruction : std_logic; + + -- Add your code here ... + +begin + + -- Unit Under Test port map + UUT : control_unit + port map ( + clk => clk, + reset => reset, + phi_next => phi_next, + button => button, + opcode => opcode, + flags => flags, + read_sel => read_sel, + write_sel => write_sel, + alu_sel => alu_sel, + alu_ins => alu_ins, + stop_instruction => stop_instruction + ); + + -- Add your stimulus here ... + + clock_stimulator : process + begin + clk <= '0'; + wait for 40 ns; + clk <= '1'; + wait for 40 ns; + end process; + + phi_next_stimulator : process + begin + wait for 500 ns; + loop + phi_next <= '1'; + wait for 100 ns; + phi_next <= '0'; + wait for 300 ns; + end loop; + end process; + + stimulus: process + begin + button <= '1'; + reset <= '1'; + wait for 200 ns; + reset <= '0'; + wait for 200 ns; + opcode <= "000001101"; + flags <= (others => '0'); + wait; + end process; + +end TB_ARCHITECTURE; + +configuration TESTBENCH_FOR_control_unit of control_unit_tb is + for TB_ARCHITECTURE + for UUT : control_unit + use entity work.control_unit(my_control_unit); + end for; + end for; +end TESTBENCH_FOR_control_unit; + diff --git a/vhdl/control_unit_TB_runtest.do b/vhdl/control_unit_TB_runtest.do new file mode 100755 index 0000000..206c63e --- /dev/null +++ b/vhdl/control_unit_TB_runtest.do @@ -0,0 +1,22 @@ +SetActiveLib -work +comp -include "h:\fpga\secd\vhdl\secd_defs.vhd" +comp -include "h:\fpga\secd\secd-microcode.vhd" +comp -include "h:\fpga\secd\vhdl\control_unit.vhd" +comp -include "H:\fpga\secd\vhdl\control_unit_TB.vhd" +asim TESTBENCH_FOR_control_unit +wave +wave -noreg clk +wave -noreg reset +wave -noreg phi_next +wave -noreg button +wave -noreg opcode +wave -noreg flags +wave -noreg read_sel +wave -noreg write_sel +wave -noreg alu_sel +wave -noreg alu_ins +wave -noreg stop_instruction +# The following lines can be used for timing simulation +# acom +# comp -include "H:\fpga\secd\vhdl\control_unit_TB_tim_cfg.vhd" +# asim TIMING_FOR_control_unit diff --git a/vhdl/datapath.vhd b/vhdl/datapath.vhd index 1462d4b..b202866 100755 --- a/vhdl/datapath.vhd +++ b/vhdl/datapath.vhd @@ -8,7 +8,6 @@ use work.secd_ram_defs.all; entity datapath is port( clk : in std_logic; - reset : in std_logic; -- phase selection signals from top-level fsm phi_read : in std_logic; phi_alu : in std_logic; @@ -190,16 +189,16 @@ architecture datapath_arch of datapath is root <= arg(27 downto 14); parent <= y2; - -- accept status register pseudo ops + -- status register pseudo ops when running => - null; + state_reg <= "00"; when halted => - null; + state_reg <= "01"; when gc => - null; - + state_reg <= "10"; + when others => report "Warning, unsupported ALU operation"; end case; @@ -289,41 +288,22 @@ architecture datapath_arch of datapath is opcode <= arg(8 downto 0); end process; - status_register_gen : process(phi_read, clk) - begin - if falling_edge(phi_read) - then - case alu_sel is - when running => - state_reg <= "00"; - - when halted => - state_reg <= "01"; - - when gc => - state_reg <= "10"; - - when others => - null; - end case; - end if; - end process; - ram_rw_gen : process(clk, phi_write, read_sel, write_sel) begin if rising_edge(clk) then if phi_write = '1' then -- RAM access - if write_sel = wmar then - ram_read <= '1'; - ram_write <= '0'; - elsif write_sel = bidir then - ram_write <= '1'; - ram_read <= '0'; - else - ram_read <= '0'; - ram_write <= '0'; - end if; + case write_sel is + when wmar => + ram_read <= '1'; + ram_write <= '0'; + when bidir => + ram_write <= '1'; + ram_read <= '0'; + when others => + ram_read <= '0'; + ram_write <= '0'; + end case; else ram_read <= '0'; ram_write <= '0'; diff --git a/vhdl/secd_defs.vhd b/vhdl/secd_defs.vhd index 6d92fb6..259c1ca 100755 --- a/vhdl/secd_defs.vhd +++ b/vhdl/secd_defs.vhd @@ -105,15 +105,16 @@ package secd_defs is constant dispatch : std_logic_vector := "0010"; constant markp : std_logic_vector := "0011"; constant fieldp : std_logic_vector := "0100"; - constant eqp : std_logic_vector := "0101"; - constant leqp : std_logic_vector := "0110"; - constant nump : std_logic_vector := "0111"; - constant atomp : std_logic_vector := "1000"; - constant nilp : std_logic_vector := "1001"; - constant buttonp : std_logic_vector := "1010"; - constant call : std_logic_vector := "1011"; - constant returnx : std_logic_vector := "1100"; - constant stop : std_logic_vector := "1101"; + constant zerop : std_logic_vector := "0101"; + constant eqp : std_logic_vector := "0110"; + constant leqp : std_logic_vector := "0111"; + constant nump : std_logic_vector := "1000"; + constant atomp : std_logic_vector := "1001"; + constant nilp : std_logic_vector := "1010"; + constant buttonp : std_logic_vector := "1011"; + constant call : std_logic_vector := "1100"; + constant returnx : std_logic_vector := "1101"; + constant stop : std_logic_vector := "1110"; -- Cell types constant cell_symbol : std_logic_vector := "10"; diff --git a/vhdl/secd_toplevel.vhd b/vhdl/secd_toplevel.vhd index 5cc62f5..d2f99ec 100755 --- a/vhdl/secd_toplevel.vhd +++ b/vhdl/secd_toplevel.vhd @@ -35,6 +35,9 @@ architecture my_secd_system of secd_system is signal phi_write : std_logic; signal phi_next : std_logic; + attribute buffer_type : string; + attribute buffer_type of phi_next : signal is "BUFG"; + signal alu_ins : std_logic; signal opcode : std_logic_vector(8 downto 0); @@ -47,7 +50,6 @@ architecture my_secd_system of secd_system is begin my_datapath : entity datapath port map ( clk => clk, - reset => reset, phi_read => phi_read, phi_alu => phi_alu, phi_write => phi_write,