]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - hw/bus_tumbl.vhd
RoCoN: USB CDC ACM use maximal packet length - 64 bytes.
[fpga/lx-cpu1/lx-rocon.git] / hw / bus_tumbl.vhd
index c4405022b2d3269184efef34bdfa26cde975517e..9e09ef9681d5977a8b92be0d6e4d2fe502e26777 100644 (file)
@@ -4,7 +4,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
-use work.mbl_Pkg.all;
+use work.mbl_pkg.all;
 use work.lx_rocon_pkg.all;
 
 -- Connects tumbl to the Master CPU
@@ -13,58 +13,60 @@ entity bus_tumbl is
        port
        (
                -- Clock
-               clk_100m : in std_logic;
-               clk_50m  : in std_logic;
-
+               clk_i        : in std_logic;
                -- Chip enable
-               ce       : in std_logic;
-
+               ce_i         : in std_logic;
                -- Global Reset
-               reset    : in std_logic;
-
+               reset_i      : in std_logic;
                -- Master CPU bus for the memory
-    rd       : in std_logic;
-    bls      : in std_logic_vector(3 downto 0);
-    address  : in std_logic_vector(11 downto 0);
-    data_in  : in std_logic_vector(31 downto 0);
-    data_out : out std_logic_vector(31 downto 0);
-               ta       : out std_logic;
-
+    bls_i        : in std_logic_vector(3 downto 0);
+    address_i    : in std_logic_vector(11 downto 0);
+    data_i       : in std_logic_vector(31 downto 0);
+    data_o       : out std_logic_vector(31 downto 0);
                -- Tumbl extrenal memory bus
-               XMEMB_sel_o :  out std_logic;
-               XMEMB_i     :  in DMEMB2CORE_Type;
-               XMEMB_o     :  out CORE2DMEMB_Type
+               xmemb_sel_o  : out std_logic;
+               xmemb_i      : in DMEMB2CORE_Type;
+               xmemb_o      : out CORE2DMEMB_Type
   );
 end bus_tumbl;
 
 architecture Behavioral of bus_tumbl is
-
-       -- Internal state
-       signal tumbl_reset : std_logic;
-       signal tumbl_halt : std_logic;
-       signal tumbl_int : std_logic;
-       signal tumbl_trace : std_logic;
-       signal tumbl_trace_kick : std_logic; -- driven by 50M clock
-       signal tumbl_trace_kick_ack : std_logic; -- driven by 50M clock
-       signal tumbl_trace_kick_req : std_logic; -- driven by 100M clock
-       signal tumbl_bad_op : std_logic; -- driven by 50M clock
-
-       -- Tumbl PC (copy it with cpu clock and then wire further)
-       signal tumbl_pc : std_logic_vector(31 downto 0); -- driven by 50M clock
-
-       -- Halting using halt instruction
-       signal tumbl_halted : std_logic;
-       signal tumbl_halt_code : std_logic_vector(4 downto 0);
+       -- Types
+       type TUMBL_Input_Type is record
+               halt       : std_logic;
+               int        : std_logic;
+               trace      : std_logic;
+               trace_kick : std_logic;
+       end record;
+
+       type TUMBL_State_Type is record
+               pc         : std_logic_vector(31 downto 0);
+               halted     : std_logic;
+               halt_code  : std_logic_vector(4 downto 0);
+       end record;
+
+       -- Reset
+       signal tumbl_reset_s : std_logic;
+       -- Internals
+       signal tumbl_input_s : TUMBL_Input_Type;
+       signal tumbl_state_s : TUMBL_State_Type;
 
        -- Internal memory signals
-       signal imem_en : std_logic;
-       signal dmem_en : std_logic;
+       signal imem_en_s     : std_logic;
+       signal imem_en_r     : std_logic;
+       signal dmem_en_s     : std_logic;
+       signal dmem_en_r     : std_logic;
 
-       signal imem_we : std_logic_vector(3 downto 0);
-       signal dmem_we : std_logic_vector(3 downto 0);
+       signal imem_we_s     : std_logic_vector(3 downto 0);
+       signal dmem_we_s     : std_logic_vector(3 downto 0);
 
-       signal imem_dout : std_logic_vector(31 downto 0);
-       signal dmem_dout : std_logic_vector(31 downto 0);
+       signal imem_data_o_s : std_logic_vector(31 downto 0);
+       signal dmem_data_o_s : std_logic_vector(31 downto 0);
+
+       -- Control registers read access
+       signal tumbl_reg_en_control_r   : std_logic;
+       signal tumbl_reg_en_pc_r        : std_logic;
+       signal tumbl_reg_en_halt_code_r : std_logic;
 
        -- Internal bus structure
        -- 12 address bits: 2 bits for selection, 10 bits for address
@@ -78,16 +80,14 @@ architecture Behavioral of bus_tumbl is
        -- Registers
        -- 0x000
        --
-       -- Bit 0: R/W - Reset
-       -- Bit 1: R/W - Interrupt
-       -- Bit 2: R/W - Halt
-       -- Bit 3: R/W - Trace
-       -- Bit 4: R - Halted
-       -- Bit 5: R - Done
-       -- Bit 6: R - Bad Op (halts the core until reset)
+       -- Bit 0: RW - Reset
+       -- Bit 1: RW - Interrupt
+       -- Bit 2: RW - Halt
+       -- Bit 3: RW - Trace
+       -- Bit 4: R  - Halted
 
        -- 0x001
-       -- Bit 0: W - Write 1 for trace kick, R - Read internal signals
+       -- Bit 0: W - Write 1 for trace kick
 
        -- 0x002
        -- Tumbl program counter (R)
@@ -101,187 +101,158 @@ begin
        I_TUMBL: lx_rocon_tumbl
        generic map
        (
-               IMEM_ABITS_g => 11,
-               DMEM_ABITS_g => 12,
+               IMEM_ABITS_g         => 9,
+               DMEM_ABITS_g         => 10,
                --
-               USE_HW_MUL_g => true,
-               USE_BARREL_g => true,
+               USE_HW_MUL_g         => true,
+               USE_BARREL_g         => true,
                COMPATIBILITY_MODE_g => false
        )
        port map
        (
-               clk_i => clk_50m,
-               rst_i => tumbl_reset,
-               halt_i => tumbl_halt,
-               int_i => tumbl_int,
-               trace_i => tumbl_trace,
-               trace_kick_i => tumbl_trace_kick,
+               clk_i        => clk_i,
+               rst_i        => tumbl_reset_s,
+               halt_i       => tumbl_input_s.halt,
+               int_i        => tumbl_input_s.int,
+               trace_i      => tumbl_input_s.trace,
+               trace_kick_i => tumbl_input_s.trace_kick,
 
-               pc_o => tumbl_pc,
-               halted_o => tumbl_halted,
-               halt_code_o => tumbl_halt_code,
+               pc_o         => tumbl_state_s.pc,
+               halted_o     => tumbl_state_s.halted,
+               halt_code_o  => tumbl_state_s.halt_code,
 
                -- Internal memory (instruction)
-               imem_clk => clk_100m,
-    imem_en => imem_en,
-    imem_we => imem_we,
-    imem_addr => address(8 downto 0),
-    imem_din => data_in,
-    imem_dout => imem_dout,
+               imem_clk_i   => clk_i,
+    imem_en_i    => imem_en_s,
+    imem_we_i    => imem_we_s,
+    imem_addr_i  => address_i(8 downto 0),
+    imem_data_i  => data_i,
+    imem_data_o  => imem_data_o_s,
 
                -- Internal memory (data)
-               dmem_clk => clk_100m,
-    dmem_en => dmem_en,
-    dmem_we => dmem_we,
-    dmem_addr => address(9 downto 0),
-    dmem_din => data_in,
-    dmem_dout => dmem_dout,
+               dmem_clk_i   => clk_i,
+    dmem_en_i    => dmem_en_s,
+    dmem_we_i    => dmem_we_s,
+    dmem_addr_i  => address_i(9 downto 0),
+    dmem_data_i  => data_i,
+    dmem_data_o  => dmem_data_o_s,
 
                -- External memory bus
-               XMEMB_sel_o => XMEMB_sel_o,
-               XMEMB_i => XMEMB_i,
-               XMEMB_o => XMEMB_o,
-               --
-               bad_op_o => tumbl_bad_op
+               xmemb_sel_o  => xmemb_sel_o,
+               xmemb_i      => xmemb_i,
+               xmemb_o      => xmemb_o
        );
 
-       -- Enabling
-       enabling: process(ce, address)
+-- Enabling
+enabling: process(ce_i, address_i)
        begin
 
-               if ce = '0' and address(11 downto 10) = "00" then
-                       imem_en <= '1';
+               if ce_i = '1' and address_i(11 downto 10) = "00" then
+                       imem_en_s <= '1';
                else
-                       imem_en <= '0';
+                       imem_en_s <= '0';
                end if;
 
-               if ce = '0' and address(11 downto 10) = "01" then
-                       dmem_en <= '1';
+               if ce_i = '1' and address_i(11 downto 10) = "01" then
+                       dmem_en_s <= '1';
                else
-                       dmem_en <= '0';
+                       dmem_en_s <= '0';
                end if;
 
        end process;
 
-       -- Wiring
-       wiring: process(ce, rd, bls, address, imem_en, imem_dout, dmem_en, dmem_dout,
-                       tumbl_reset, tumbl_int, tumbl_halt, tumbl_trace,
-                                                                       tumbl_halted, tumbl_halt_code, tumbl_bad_op, tumbl_pc)
+-- Wiring
+wiring:
+       process(ce_i, bls_i, address_i, imem_en_s, imem_data_o_s, dmem_en_s,
+               dmem_data_o_s, tumbl_reset_s, tumbl_input_s, tumbl_state_s,
+               imem_en_r, dmem_en_r, tumbl_reg_en_control_r, tumbl_reg_en_pc_r,
+               tumbl_reg_en_halt_code_r)
        begin
 
-               if imem_en = '1' and tumbl_reset = '1' then
-                       imem_we <= not bls;
+               if imem_en_s = '1' then
+                       imem_we_s <= bls_i;
                else
-                       imem_we <= "0000";
+                       imem_we_s <= "0000";
                end if;
 
-               if dmem_en = '1' and tumbl_reset = '1' then
-                       dmem_we <= not bls;
+               if dmem_en_s = '1' then
+                       dmem_we_s <= bls_i;
                else
-                       dmem_we <= "0000";
+                       dmem_we_s <= "0000";
                end if;
 
-               if imem_en = '1' then
-                       data_out <= imem_dout;
-               elsif dmem_en = '1' then
-                       data_out <= dmem_dout;
-               elsif ce = '0' and rd = '0' and address(11 downto 10) = "11" then
-                       if address(9 downto 0) = "0000000000" then
-                               data_out(0) <= tumbl_reset;
-                               data_out(1) <= tumbl_int;
-                               data_out(2) <= tumbl_halt;
-                               data_out(3) <= tumbl_trace;
-                               data_out(4) <= tumbl_halted;
-                               data_out(5) <= tumbl_bad_op;
-                               data_out(31 downto 6) <= (others => '0');
-                       elsif address(9 downto 0) = "0000000010" then
-                               data_out <= tumbl_pc;
-                       elsif address(9 downto 0) = "0000000011" then
-                               data_out(4 downto 0) <= tumbl_halt_code;
-                               data_out(31 downto 5) <= (others => '0');
-                       else
-                               data_out <= (others => 'X');
-                       end if;
+               if imem_en_r = '1' then
+                       data_o <= imem_data_o_s;
+               elsif dmem_en_r = '1' then
+                       data_o <= dmem_data_o_s;
+               elsif tumbl_reg_en_control_r = '1' then
+                       data_o(0) <= tumbl_reset_s;
+                       data_o(1) <= tumbl_input_s.int;
+                       data_o(2) <= tumbl_input_s.halt;
+                       data_o(3) <= tumbl_input_s.trace;
+                       data_o(4) <= tumbl_state_s.halted;
+                       data_o(31 downto 5) <= (others => '0');
+               elsif tumbl_reg_en_pc_r = '1' then
+                       data_o <= tumbl_state_s.pc;
+               elsif tumbl_reg_en_halt_code_r = '1' then
+                       data_o(4 downto 0)  <= tumbl_state_s.halt_code;
+                       data_o(31 downto 5) <= (others => '0');
                else
-                       data_out <= (others => 'X');
+                       data_o <= (others => 'X');
                end if;
 
        end process;
 
-       -- Transaction acknowledge and writing to registers
-       -- The clock are synchronous!
-       update: process(clk_100m)
+-- Transaction acknowledge and writing to registers
+update:
+       process
        begin
 
-               -- Update on the 100 MHz clock
-               if clk_100m = '1' and clk_100m'event then
-                       ta <= '1';
+               -- Update
+               wait until clk_i'event and clk_i = '1';
 
-                       if imem_en = '1' or dmem_en = '1' then
-                               ta <= '0';
-                       end if;
+               imem_en_r <= imem_en_s;
+               dmem_en_r <= dmem_en_s;
 
-                       if reset = '1' then
-                               tumbl_reset <= '1';
-                               tumbl_int <= '0';
-                               tumbl_halt <= '0';
-                               tumbl_trace <= '0';
-                               tumbl_trace_kick_req <= '0';
-                       else
+               tumbl_reg_en_control_r   <= '0';
+               tumbl_reg_en_pc_r        <= '0';
+               tumbl_reg_en_halt_code_r <= '0';
 
-                               if tumbl_trace_kick_ack = '1' then
-                                       tumbl_trace_kick_req <= '0';
-                               end if;
+               tumbl_input_s.trace_kick <= '0';
 
-                               if ce = '0' and address(11 downto 10) = "11" then
-                                       if bls(0) = '0' then
-                                               if address(9 downto 0) = "0000000000" then
-                                                       tumbl_reset <= data_in(0);
-                                                       tumbl_int <= data_in(1);
-                                                       tumbl_halt <= data_in(2);
-                                                       tumbl_trace <= data_in(3);
-                                               elsif address(9 downto 0) = "0000000001" then
-                                                       if data_in(0) = '1' and tumbl_trace_kick = '0' then
-                                                               tumbl_trace_kick_req <= '1';
-                                                       end if;
-                                               end if;
-                                       end if;
+               if reset_i = '1' then
+                       tumbl_reset_s            <= '1';
+                       tumbl_input_s.int        <= '0';
+                       tumbl_input_s.halt       <= '0';
+                       tumbl_input_s.trace      <= '0';
+
+               else
 
-                                       if rd = '0' then
-                                               ta <= '0';
+                       if ce_i = '1' and address_i(11 downto 10) = "11" then
+                               if bls_i(0) = '1' then
+                                       if address_i(9 downto 0) = "0000000000" then
+                                               tumbl_reset_s              <= data_i(0);
+                                               tumbl_input_s.int          <= data_i(1);
+                                               tumbl_input_s.halt         <= data_i(2);
+                                               tumbl_input_s.trace        <= data_i(3);
+                                       elsif address_i(9 downto 0) = "0000000001" then
+                                               if data_i(0) = '1' then
+                                                       tumbl_input_s.trace_kick <= '1';
+                                               end if;
                                        end if;
                                end if;
-                       end if;
 
-               end if;
-       end process;
 
-       -- Update tracing
-       tumbl: process(clk_50m)
-       begin
-
-               -- Update on the 50 MHz clock
-               if clk_50m = '1' and clk_50m'event then
-
-                       if reset = '1' then
-                               tumbl_trace_kick <= '0';
-                               tumbl_trace_kick_ack <= '0';
-                       else
-                               if tumbl_trace_kick = '0' and tumbl_trace_kick_req = '1' then
-                                       tumbl_trace_kick <= '1';
-                                       tumbl_trace_kick_ack <= '1';
-                               else
-                                       tumbl_trace_kick <= '0';
+                               if address_i(9 downto 0) = "0000000000" then
+                                       tumbl_reg_en_control_r   <= '1';
+                               elsif address_i(9 downto 0) = "0000000010" then
+                                       tumbl_reg_en_pc_r        <= '1';
+                               elsif address_i(9 downto 0) = "0000000011" then
+                                       tumbl_reg_en_halt_code_r <= '1';
                                end if;
                        end if;
-
-                       if tumbl_trace_kick_req <= '0' then
-                               tumbl_trace_kick_ack <= '0';
-                       end if;
-
                end if;
 
        end process;
 
 end Behavioral;
-