]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - hw/bus_irc.vhd
IRC input: simplify and remove dependency on ieee.std_logic_arith.all and work.mbl_pk...
[fpga/lx-cpu1/lx-rocon.git] / hw / bus_irc.vhd
index 722f6fafb3ba9f948c7d42b1603b13005f51bd41..828d7dba27b587c0d24ab658617777e739103ccd 100644 (file)
 library ieee;
 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.lx_rocon_pkg.all;
 
--- IRC bus interconnect: memory region for IRC
-
+-- IRC bus interconnect
 entity bus_irc is
        port
        (
-               clk         : in std_logic;
-               reset       : in std_logic;
-
-               -- Address (needs just last 4 bits, rest is wired to CE)
-               address     : in std_logic_vector(3 downto 0);
-               ce          : in std_logic;
-
+               clk_i        : in std_logic;
+               reset_i      : in std_logic;
                -- Data bus
-               data_in     : in std_logic; -- 1 bit input
-               data_out    : out std_logic_vector(31 downto 0);
-
-               -- Bus signals
-               rd          : in std_logic;
-               ta          : out std_logic;
-               wr          : in std_logic;
-
+               address_i    : in std_logic_vector(4 downto 0);
+               ce_i         : in std_logic;
+               data_i       : in std_logic_vector(31 downto 0);
+               data_o       : out std_logic_vector(31 downto 0);
+               --
+               bls_i        : in std_logic_vector(3 downto 0);
                -- Signals for IRC
-               irc1_a      : in std_logic;
-               irc1_b      : in std_logic;
-               irc1_index  : in std_logic;
-               irc1_mark   : in std_logic;
-
-               irc2_a      : in std_logic;
-               irc2_b      : in std_logic;
-               irc2_index  : in std_logic;
-               irc2_mark   : in std_logic;
-
-               irc3_a      : in std_logic;
-               irc3_b      : in std_logic;
-               irc3_index  : in std_logic;
-               irc3_mark   : in std_logic;
-
-               irc4_a      : in std_logic;
-               irc4_b      : in std_logic;
-               irc4_index  : in std_logic;
-               irc4_mark   : in std_logic
-
+               irc_i        : in IRC_INPUT_Array_Type(7 downto 0)
        );
 end bus_irc;
 
 architecture Behavioral of bus_irc is
 
-       -- Multiplexer signals
-       signal irc1_out : std_logic_vector(31 downto 0);
-       signal irc1_ta : std_logic;
-       signal irc1_ce : std_logic_vector(1 downto 0);
-
-       signal irc2_out : std_logic_vector(31 downto 0);
-       signal irc2_ta : std_logic;
-       signal irc2_ce : std_logic_vector(1 downto 0);
-
-       signal irc3_out : std_logic_vector(31 downto 0);
-       signal irc3_ta : std_logic;
-       signal irc3_ce : std_logic_vector(1 downto 0);
-
-       signal irc4_out : std_logic_vector(31 downto 0);
-       signal irc4_ta : std_logic;
-       signal irc4_ce : std_logic_vector(1 downto 0);
-
-       -- IRC register
-       component irc_register
-       port
-       (
-               clk      : in std_logic;
-               reset    : in std_logic;
-               a0, b0   : in std_logic;
-               index0   : in std_logic;
-               mark0    : in std_logic;
-               data_in  : in std_logic;
-               data_out : out std_logic_vector(31 downto 0);
-               ce       : in std_logic_vector(1 downto 0);
-               rd       : in std_logic;
-               ta       : out std_logic;
-               wr       : in std_logic
-       );
-       end component;
+       constant num_irc_c          : positive := 8;
+
+       signal irc_o_s              : IRC_OUTPUT_Array_Type(num_irc_c-1 downto 0);
+       signal irc_count_s          : IRC_COUNT_OUTPUT_Array_Type((num_irc_c-1) downto 0);
+
+       signal reset_index_event_s  : std_logic_vector(num_irc_c-1 downto 0);
+       signal reset_index_event2_s : std_logic_vector(num_irc_c-1 downto 0);
+       signal reset_ab_error_s     : std_logic_vector(num_irc_c-1 downto 0);
+       signal state_o_s            : std_logic_vector(3 downto 0);
+       signal state_o_r            : std_logic_vector(3 downto 0);
+       --
+       signal irc_en_s             : std_logic;
+       signal irc_bls_s            : std_logic_vector(3 downto 0);
+       signal irc_addr_s           : std_logic_vector(3 downto 0);
+       signal irc_data_s           : std_logic_vector(31 downto 0);
+       signal irc_out_s            : std_logic;
+       signal irc_out_r            : std_logic;
+       --
+       signal reset_reg_s          : std_logic;
+       signal reset_reg_r          : std_logic;
+       signal reset_reg_wr_s       : std_logic;
+       --
+       signal reset_s              : std_logic;
+       signal ce_r                 : std_logic;
 
 begin
 
-       -- IRC for first axis
-       irc1: irc_register
-       port map
+irc_generate: for i in 0 to num_irc_c-1 generate
+       irc : irc_reader
+               port map
+               (
+                       clk_i                => clk_i,
+                       reset_i              => reset_s,
+                       irc_i                => irc_i(i),
+                       reset_index_event_i  => reset_index_event_s(i),
+                       reset_index_event2_i => reset_index_event2_s(i),
+                       reset_ab_error_i     => reset_ab_error_s(i),
+                       irc_o                => irc_o_s(i)
+               );
+
+               irc_count_s(i) <= irc_o_s(i).count;
+       end generate;
+
+irc_proc : irc_proc_main
+       generic map
        (
-               clk => clk,
-               reset => reset,
-               a0 => irc1_a,
-               b0 => irc1_b,
-               index0 => irc1_index,
-               mark0 => irc1_mark,
-               data_in => data_in,
-               data_out => irc1_out,
-               ce => irc1_ce,
-               rd => rd,
-               ta => irc1_ta,
-               wr => wr
-       );
-
-       -- IRC for second axis
-       irc2: irc_register
+               num_irc_g            => num_irc_c
+       )
        port map
        (
-               clk => clk,
-               reset => reset,
-               a0 => irc2_a,
-               b0 => irc2_b,
-               index0 => irc2_index,
-               mark0 => irc2_mark,
-               data_in => data_in,
-               data_out => irc2_out,
-               ce => irc2_ce,
-               rd => rd,
-               ta => irc2_ta,
-               wr => wr
+               clk_i                => clk_i,
+               reset_i              => reset_s,
+               -- IRC
+               irc_i                => irc_count_s,
+               irc_index_reset_o    => reset_index_event_s,
+               -- BRAM
+               mem_clk_i            => clk_i,
+               mem_en_i             => irc_en_s,
+               mem_we_i             => irc_bls_s,
+               mem_addr_i           => irc_addr_s,
+               mem_data_i           => data_i,
+               mem_data_o           => irc_data_s
        );
 
-       -- IRC for thrid axis
-       irc3: irc_register
-       port map
-       (
-               clk => clk,
-               reset => reset,
-               a0 => irc3_a,
-               b0 => irc3_b,
-               index0 => irc3_index,
-               mark0 => irc3_mark,
-               data_in => data_in,
-               data_out => irc3_out,
-               ce => irc3_ce,
-               rd => rd,
-               ta => irc3_ta,
-               wr => wr
-       );
-
-       -- IRC for fourth axis
-       irc4: irc_register
-       port map
-       (
-               clk => clk,
-               reset => reset,
-               a0 => irc4_a,
-               b0 => irc4_b,
-               index0 => irc4_index,
-               mark0 => irc4_mark,
-               data_in => data_in,
-               data_out => irc4_out,
-               ce => irc4_ce,
-               rd => rd,
-               ta => irc4_ta,
-               wr => wr
-       );
+       reset_s <= reset_reg_r or reset_i;
 
-       -- Bus update
-       memory_bus_update: process(ce, address, irc1_out, irc1_ta, irc2_out, irc2_ta,
-                                  irc3_out, irc3_ta, irc4_out, irc4_ta)
+wire_in:
+       process(ce_i, ce_r, reset_reg_r, bls_i, address_i, irc_data_s, data_i, irc_o_s)
        begin
 
-               -- Reset signals
-               irc1_ce <= "11";
-               irc2_ce <= "11";
-               irc3_ce <= "11";
-               irc4_ce <= "11";
-
-               ta <= '1';
-               data_out <= (others => 'X');
+               -- init values
+               irc_en_s             <= '0';
+               irc_out_s            <= '0';
+               irc_bls_s            <= (others => '0');
+               irc_addr_s           <= (others => '0');
+               reset_ab_error_s     <= (others => '0');
+               reset_index_event2_s <= (others => '0');
+               state_o_s            <= (others => '0');
+               reset_reg_s          <= '0';
+               reset_reg_wr_s       <= '0';
+
+               -- Incoming bus request
+               if ce_i = '1' then
+                       -- Mapping:
+                       -- 0 & axis & irc / index - (all read from bram) (R/W)
+                       -- 1 & axis & 0           - status register (R/W)
+                       -- 1 & 000  & 1           - reset
+                       if address_i(4) = '0' then
+
+                               irc_addr_s    <= address_i(3 downto 0);
+                               irc_en_s      <= '1';
+                               irc_bls_s     <= bls_i;
+                               irc_out_s     <= '1';
+
+                       -- Maybe these would be better to latch in ce_i cycle,
+                       -- and then just pass them
+                       elsif address_i(0) = '0' then
+
+                               state_o_s(0) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.mark;
+                               state_o_s(1) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.ab_error;
+                               state_o_s(2) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.index_event;
+                               state_o_s(3) <= irc_o_s(to_integer(unsigned(address_i(3 downto 1)))).state.index;
+
+                               if bls_i(0) = '1' then
+                                       if data_i(1) = '1' then
+                                               reset_ab_error_s(to_integer(unsigned(address_i(3 downto 1))))     <= '1';
+                                       end if;
+                                       if data_i(2) = '1' then
+                                               reset_index_event2_s(to_integer(unsigned(address_i(3 downto 1)))) <= '1';
+                                       end if;
+                               end if;
+                       elsif address_i = "10001" then
+
+                               if bls_i(0) = '1' then
+                                       reset_reg_s    <= data_i(0);
+                                       reset_reg_wr_s <= '1';
+                               else
+                                       -- Ugh, hack :-)
+                                       state_o_s(0)          <= reset_reg_r;
+                                       state_o_s(3 downto 1) <= (others => '0');
+                               end if;
+
+                       end if;
 
-               if ce = '0' then
-
-                       -- We have 4-bit address, and IRC module has 3 registers
-                       -- Higher bits choose which IRC module, lower bits are for registers of the module
-                       case address(3 downto 2) is
-                               when "00" =>
-                                       irc1_ce <= address(1 downto 0);
-                                       data_out <= irc1_out;
-                                       ta <= irc1_ta;
+               end if;
+       end process;
 
-                               when "01" =>
-                                       irc2_ce <= address(1 downto 0);
-                                       data_out <= irc2_out;
-                                       ta <= irc2_ta;
+wire_out:
+       process(ce_r, irc_data_s, irc_out_r, state_o_r)
+       begin
 
-                               when "10" =>
-                                       irc3_ce <= address(1 downto 0);
-                                       data_out <= irc3_out;
-                                       ta <= irc3_ta;
+               data_o <= (others => '0');
 
-                               when "11" =>
-                                       irc4_ce <= address(1 downto 0);
-                                       data_out <= irc4_out;
-                                       ta <= irc4_ta;
+               if ce_r = '1' then
 
-                               when others =>
-                                       data_out <= (others => 'X');
+                       if irc_out_r = '1' then
+                               data_o <= irc_data_s;
+                       else
+                               data_o(3 downto 0) <= state_o_r;
+                       end if;
 
-                       end case;
+               end if;
+       end process;
 
+update:
+       process
+       begin
+               wait until clk_i'event and clk_i= '1';
+               ce_r      <= ce_i;
+               irc_out_r <= irc_out_s;
+               state_o_r <= state_o_s;
+
+               if reset_i = '1' then
+                       reset_reg_r <= '1';
+               elsif reset_reg_wr_s = '1' then
+                       reset_reg_r <= reset_reg_s;
                end if;
 
        end process;