]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - hw/lx_rocon_top.vhd
Major refactorization in hw
[fpga/lx-cpu1/lx-rocon.git] / hw / lx_rocon_top.vhd
index 1062e29c2c02e0d82e8cc648615549ad0ca792a2..a4ba836c0d2d30898231f63a696942cf2511a1e6 100644 (file)
@@ -34,15 +34,15 @@ entity lx_rocon_top is
        port
        (
                -- External
-               --clk_cpu   : in std_logic;
-               clk_50m   : in std_logic;
+               --clk_cpu    : in std_logic;
+               clk_50m    : in std_logic;
 
-               cs0_xc   : in std_logic;
+               cs0_xc     : in std_logic;
 
-               rd       : in std_logic;
-               bls      : in std_logic_vector(3 downto 0);
-               address  : in std_logic_vector(15 downto 0);
-               data     : inout std_logic_vector(31 downto 0);
+               rd         : in std_logic;
+               bls        : in std_logic_vector(3 downto 0);
+               address    : in std_logic_vector(15 downto 0);
+               data       : inout std_logic_vector(31 downto 0);
 
                irc1_a     : in std_logic;
                irc1_b     : in std_logic;
@@ -71,35 +71,31 @@ end lx_rocon_top;
 architecture Behavioral of lx_rocon_top is
 
        -- Reset signal
-       signal reset : std_logic;
-       signal neg_init : std_logic;
-
+       signal reset_s           : std_logic;
+       signal neg_init_s        : std_logic;
        -- 100 MHz clock
-       signal clk_100m : std_logic;
-       signal clk_100m_fb : std_logic;
-       signal clk_100m_locked : std_logic;
-
+       signal clk_100m_s        : std_logic;
+       signal clk_100m_fb_s     : std_logic;
+       signal clk_100m_locked_s : std_logic;
        -- Peripherals on the memory bus
-       signal tumbl_out : std_logic_vector(31 downto 0);
-       signal tumbl_ta : std_logic;
-       signal tumbl_ce : std_logic;
-
-       signal irc_reg_out : std_logic_vector(31 downto 0);
-       signal irc_reg_ta : std_logic;
-       signal irc_reg_ce : std_logic;
-
-       signal calib_out : std_logic_vector(31 downto 0);
-       signal calib_ta : std_logic;
-       signal calib_ce : std_logic;
-
+       signal tumbl_out_s       : std_logic_vector(31 downto 0);
+       signal tumbl_ta_s        : std_logic;
+       signal tumbl_ce_s        : std_logic;
+       --
+       signal irc_reg_out_s     : std_logic_vector(31 downto 0);
+       signal irc_reg_ta_s      : std_logic;
+       signal irc_reg_ce_s      : std_logic;
+       --
+       signal calib_out_s       : std_logic_vector(31 downto 0);
+       signal calib_ta_s        : std_logic;
+       signal calib_ce_s        : std_logic;
        -- Signals for external bus transmission
-       signal data_in_bus : std_logic_vector(31 downto 0);
-       signal data_out_bus : std_logic_vector(31 downto 0);
-
+       signal data_i_s          : std_logic_vector(31 downto 0);
+       signal data_o_s          : std_logic_vector(31 downto 0);
        -- Signals for internal transaction
-       signal last_address : std_logic_vector(15 downto 0);
-       signal last_rd : std_logic;
-       signal last_bls : std_logic_vector(3 downto 0);
+       signal last_address_s    : std_logic_vector(15 downto 0);
+       signal last_rd_s         : std_logic;
+       signal last_bls_s        : std_logic_vector(3 downto 0);
 
        -- Reading logic:
        -- Broadcast rd only till ta (transaction acknowledge)
@@ -109,22 +105,21 @@ architecture Behavioral of lx_rocon_top is
        -- Data latching is synchronous - it's purpose is to
        -- provide stable data for CPU on the bus on high rise
        -- of trans. ack signal
-       signal rd_f : std_logic;
-       signal rd_d : std_logic;
-
-       signal data_read : std_logic_vector(31 downto 0);
-
-       signal i_ta : std_logic;
-       signal i_rd : std_logic;
-       signal acked : std_logic;
+       signal rd_f_s            : std_logic; -- Filtered RD
+       signal rd_d_s            : std_logic; -- D over RD
+       signal i_ta_s            : std_logic; -- Internal bus TA (active 1)
+       signal i_rd_s            : std_logic; -- Internal bus RD (active 1)
+       --
+       signal data_read_s       : std_logic_vector(31 downto 0); -- Latched read data
+       --
+       signal acked_s           : std_logic;
 
        -- Writing logic:
-       signal bls_f : std_logic_vector(3 downto 0);
-       signal bls_d : std_logic_vector(3 downto 0);
-
-       signal data_write : std_logic_vector(31 downto 0);
-
-       signal i_bls : std_logic_vector(3 downto 0);
+       signal bls_f_s : std_logic_vector(3 downto 0); -- Filtered BLS
+       signal bls_d_s : std_logic_vector(3 downto 0); -- D over BLS
+       signal i_bls_s : std_logic_vector(3 downto 0); -- Internal BLS (active 1)
+       --
+       signal data_write_s : std_logic_vector(31 downto 0); -- Data broadcasted to write
 
 begin
 
@@ -132,141 +127,146 @@ begin
        clk_100m_dcm_sp : DCM_SP
        generic map
        (
-               clkdv_divide => 2.0,
-               clkfx_divide => 1,
-               clkfx_multiply => 2,
-               clkin_divide_by_2 => false,
-               clkin_period => 20.0, -- 50 MHz
-               clkout_phase_shift => "NONE",
-               clk_feedback => "1X",
-               deskew_adjust => "SYSTEM_SYNCHRONOUS",
-               dfs_frequency_mode => "LOW",
-               dll_frequency_mode => "LOW",
-               dss_mode => "NONE",
+               clkdv_divide          => 2.0,
+               clkfx_divide          => 1,
+               clkfx_multiply        => 2,
+               clkin_divide_by_2     => false,
+               clkin_period          => 20.0, -- 50 MHz
+               clkout_phase_shift    => "NONE",
+               clk_feedback          => "1X",
+               deskew_adjust         => "SYSTEM_SYNCHRONOUS",
+               dfs_frequency_mode    => "LOW",
+               dll_frequency_mode    => "LOW",
+               dss_mode              => "NONE",
                duty_cycle_correction => true,
-               factory_jf => X"c080",
-               phase_shift => 0,
-               startup_wait => false
+               factory_jf            => X"c080",
+               phase_shift           => 0,
+               startup_wait          => false
        )
        port map
        (
-               clk0 => clk_100m_fb,
-               clk180 => open,
-               clk270 => open,
-               clk2x => clk_100m,
-               clk2x180 => open,
-               clk90 => open,
-               clkdv => open,
-               clkfx => open,
-               clkfx180 => open,
-               locked => clk_100m_locked,
-               psdone => open,
-               status => open,
-               clkfb => clk_100m_fb,
-               clkin => clk_50m,
-               dssen => '0',
-               psclk => '0',
-               psen => '0',
-               psincdec => '0',
-               rst => neg_init
+               clk0                  => clk_100m_fb_s,
+               clk180                => open,
+               clk270                => open,
+               clk2x                 => clk_100m_s,
+               clk2x180              => open,
+               clk90                 => open,
+               clkdv                 => open,
+               clkfx                 => open,
+               clkfx180              => open,
+               locked                => clk_100m_locked_s,
+               psdone                => open,
+               status                => open,
+               clkfb                 => clk_100m_fb_s,
+               clkin                 => clk_50m,
+               dssen                 => '0',
+               psclk                 => '0',
+               psen                  => '0',
+               psincdec              => '0',
+               rst                   => neg_init_s
        );
 
        -- IRC interconnect
        memory_bus_irc: bus_irc
        port map
        (
-               clk => clk_100m,
-               reset => reset,
-               address => address(3 downto 0),
-               ce => irc_reg_ce,
-               data_in => data_in_bus(0),
-               data_out => irc_reg_out,
-               rd => i_rd,
-               wr => i_bls(0),
-               ta => irc_reg_ta,
-
-               irc1_a => irc1_a,
-               irc1_b => irc1_b,
-               irc1_index => irc1_index,
-               irc1_mark => irc1_mark,
-
-               irc2_a => irc2_a,
-               irc2_b => irc2_b,
-               irc2_index => irc2_index,
-               irc2_mark => irc2_mark,
-
-               irc3_a => irc3_a,
-               irc3_b => irc3_b,
-               irc3_index => irc3_index,
-               irc3_mark => irc3_mark,
-
-               irc4_a => irc4_a,
-               irc4_b => irc4_b,
-               irc4_index => irc4_index,
-               irc4_mark => irc4_mark
+               clk_i        => clk_100m_s,
+               reset_i      => reset_s,
+               address_i    => address(3 downto 0),
+               ce_i         => irc_reg_ce_s,
+               data_i       => data_i_s(0),
+               data_o       => irc_reg_out_s,
+               rd_i         => i_rd_s,
+               wr_i         => i_bls_s(0),
+               ta_o         => irc_reg_ta_s,
+               --
+               irc1_a_i     => irc1_a,
+               irc1_b_i     => irc1_b,
+               irc1_index_i => irc1_index,
+               irc1_mark_i  => irc1_mark,
+               --
+               irc2_a_i     => irc2_a,
+               irc2_b_i     => irc2_b,
+               irc2_index_i => irc2_index,
+               irc2_mark_i  => irc2_mark,
+               --
+               irc3_a_i     => irc3_a,
+               irc3_b_i     => irc3_b,
+               irc3_index_i => irc3_index,
+               irc3_mark_i  => irc3_mark,
+               --
+               irc4_a_i     => irc4_a,
+               irc4_b_i     => irc4_b,
+               irc4_index_i => irc4_index,
+               irc4_mark_i  => irc4_mark
        );
 
        -- Tumbl coprocessor
        memory_bus_tumbl: bus_tumbl
        port map
        (
-               clk_100m => clk_100m,
-               clk_50m => clk_50m,
-               reset => reset,
-               ce => tumbl_ce,
-               ta => tumbl_ta,
-               rd => i_rd,
-               bls => i_bls,
-               address => address(11 downto 0),
-               data_in => data_in_bus,
-               data_out => tumbl_out,
-
-               XMEMB_o => open,
-               XMEMB_i.clken => '1',
-               XMEMB_i.data => (others => '1'),
-               XMEMB_i.int => '0',
-               XMEMB_sel_o => open
+               clk_100m_i        => clk_100m_s,
+               clk_50m_i         => clk_50m,
+               reset_100m_i      => reset_s,
+               ce_100m_i         => tumbl_ce_s,
+               ta_100m_o         => tumbl_ta_s,
+               rd_100m_i         => i_rd_s,
+               bls_100m_i        => i_bls_s,
+               address_100m_i    => address(11 downto 0),
+               data_100m_i       => data_i_s,
+               data_100m_o       => tumbl_out_s,
+               --
+               XMEMB_50m_o       => open,
+               XMEMB_50m_i.clken => '1',
+               XMEMB_50m_i.data  => (others => '1'),
+               XMEMB_50m_i.int   => '0',
+               XMEMB_sel_50m_o   => open
        );
 
        -- Calibration
        memory_bus_calibration: bus_calibration
        port map
        (
-               clk => clk_100m,
-               reset => reset,
-               ce => calib_ce,
-               address => address(1 downto 0),
-               rd => i_rd,
-               bls => i_bls,
-               ta => calib_ta,
-               data_in => data_in_bus,
-               data_out => calib_out
+               clk_i     => clk_100m_s,
+               reset_i   => reset_s,
+               ce_i      => calib_ce_s,
+               address_i => address(1 downto 0),
+               rd_i      => i_rd_s,
+               bls_i     => i_bls_s,
+               ta_o      => calib_ta_s,
+               data_i    => data_i_s,
+               data_o    => calib_out_s
        );
 
        -- Filters
        --bls_f <= bls when bls = bls_d else "1111";
-       bls_f(0) <= bls(0) when bls(0) = bls_d(0) else '1';
-       bls_f(1) <= bls(2) when bls(2) = bls_d(2) else '1';
-       bls_f(2) <= bls(2) when bls(2) = bls_d(2) else '1';
-       bls_f(3) <= bls(3) when bls(3) = bls_d(3) else '1';
-       rd_f <= rd when rd = rd_d else '1';
+       bls_f_s(0) <= bls(0) when bls(0) = bls_d_s(0) else '1';
+       bls_f_s(1) <= bls(2) when bls(2) = bls_d_s(2) else '1';
+       bls_f_s(2) <= bls(2) when bls(2) = bls_d_s(2) else '1';
+       bls_f_s(3) <= bls(3) when bls(3) = bls_d_s(3) else '1';
+       rd_f_s     <= rd when rd = rd_d_s else '1';
 
        -- Bus update
-       memory_bus_update: process(clk_100m)
+memory_bus_update:
+       process(clk_100m_s)
        begin
 
-               if clk_100m = '1' and clk_100m'event then
+               if clk_100m_s = '1' and clk_100m_s'event then
 
                        -- Set every signal to inactive state here
-                       irc_reg_ce <= '1';
-                       tumbl_ce <= '1';
-                       calib_ce <= '1';
-                       i_rd <= '1';
-                       i_bls <= (others => '1');
-                       data_in_bus <= (others => 'X');
+                       irc_reg_ce_s  <= '0';
+                       tumbl_ce_s    <= '0';
+                       calib_ce_s    <= '0';
+                       i_rd_s        <= '0';
+                       i_bls_s       <= (others => '0');
+                       data_i_s      <= (others => 'X');
 
                        -- Check if we have chip select
-                       if cs0_xc = '0' then
+                       if reset_s = '1' then
+                               acked_s     <= '1';
+                               i_ta_s      <= '0';
+                               data_read_s <= (others => '0');
+                       elsif cs0_xc = '0' then
 
                                -- Memory Map (16-bit address @ 32-bit each)
 
@@ -275,72 +275,72 @@ begin
                                -- 0x8000 - 0x800F: IRC registers
                                -- 0xFFFC - 0xFFFF: Calibration
 
-                               if address < "0001000000000000" then -- Tumbl
-                                       tumbl_ce <= '0';
-                                       i_ta <= tumbl_ta;
-                                       data_out_bus <= tumbl_out;
-                               elsif address(15 downto 4) = "100000000000" then -- IRC
-                                       irc_reg_ce <= '0';
-                                       i_ta <= irc_reg_ta;
-                                       data_out_bus <= irc_reg_out;
+                               if address < "0001000000000000" then               -- Tumbl
+                                       tumbl_ce_s   <= '1';
+                                       i_ta_s       <= tumbl_ta_s;
+                                       data_o_s     <= tumbl_out_s;
+                               elsif address(15 downto 4) = "100000000000" then   -- IRC
+                                       irc_reg_ce_s <= '1';
+                                       i_ta_s       <= irc_reg_ta_s;
+                                       data_o_s     <= irc_reg_out_s;
                                elsif address(15 downto 2) = "11111111111111" then -- Calibration
-                                       calib_ce <= '0';
-                                       i_ta <= calib_ta;
-                                       data_out_bus <= calib_out;
+                                       calib_ce_s   <= '1';
+                                       i_ta_s       <= calib_ta_s;
+                                       data_o_s     <= calib_out_s;
                                end if;
 
                                -- Reading
-                               if rd_f = '0' then
-                                       if last_rd = '1' or last_address /= address then
+                               if rd_f_s = '0' then
+                                       if last_rd_s = '1' or last_address_s /= address then
                                                -- Getting something new
                                                -- Set internal RD to active and reset ack and latched data
-                                               acked <= '0';
-                                               i_rd <= '0';
+                                               acked_s      <= '0';
+                                               i_rd_s       <= '1';
                                                -- Data latching - synchronous
-                                               data_read <= (others => 'X');
-                                       elsif i_rd = '0' and acked = '0' and i_ta = '0' then
+                                               data_read_s  <= (others => 'X');
+                                       elsif i_rd_s = '1' and acked_s = '0' and i_ta_s = '1' then
                                                -- Got acknowledge, latch data
-                                               acked <= '1';
-                                               data_read <= data_out_bus;
-                                       elsif acked = '0' then
-                                               -- Ongoing read, keep the signal low
-                                               i_rd <= '0';
-                                               data_read <= (others => 'X');
+                                               acked_s      <= '1';
+                                               data_read_s  <= data_o_s;
+                                       elsif acked_s = '0' then
+                                               -- Ongoing read, keep the signal active
+                                               i_rd_s       <= '1';
+                                               data_read_s  <= (others => 'X');
                                        end if;
 
-                                       last_address <= address;
+                                       last_address_s <= address;
                                else
                                        -- Not reading, anything goes
-                                       data_read <= (others => 'X');
+                                       data_read_s    <= (others => 'X');
                                end if;
 
-                               last_rd <= rd_f;
+                               last_rd_s        <= rd_f_s;
 
-                               -- Writing (BLS is filtered due to bus error otherwise)
-                               if bls_f /= "1111" then
+                               -- Writing
+                               if bls_f_s /= "1111" then
 
-                                       if last_bls /= bls_f or last_address /= address then
+                                       if last_bls_s /= bls_f_s or last_address_s /= address then
                                                -- Broadcast BLS for once cycle to write the data
-                                               i_bls <= bls_f;
-                                               data_in_bus <= data_write;
+                                               i_bls_s      <= not bls_f_s;
+                                               data_i_s     <= data_write_s;
                                        end if;
 
-                                       last_address <= address;
+                                       last_address_s <= address;
                                end if;
 
-                               last_bls <= bls_f;
+                               last_bls_s       <= bls_f_s;
 
                        else
 
                                -- Set last read / bls to '1' if CS0 is not asserted
-                               last_rd <= '1';
-                               last_bls <= (others => '1');
+                               last_rd_s        <= '1';
+                               last_bls_s       <= (others => '1');
 
                        end if;
 
                        -- Filters
-                       bls_d <= bls;
-                       rd_d <= rd;
+                       bls_d_s <= bls;
+                       rd_d_s  <= rd;
 
                end if;
 
@@ -348,27 +348,30 @@ begin
 
        -- If RD and BLS is not high, we must keep DATA at high impedance
        -- or the FPGA collides with SDRAM (damaging each other)
-       memory_bus_out: process(cs0_xc, rd, data, data_read)
+memory_bus_out:
+       process(cs0_xc, rd, data, data_read_s)
        begin
 
                -- CS0 / RD / BLS are active LOW
                if cs0_xc = '0' and rd = '0' then
-                       data <= data_read;
+                       data <= data_read_s;
                else
                        -- IMPORTANT!!!
                        data <= (others => 'Z');
                end if;
 
-               data_write <= data;
+               data_write_s <= data;
 
        end process;
 
        -- Reset
-       initialization: process(init, clk_100m_locked)
+initialization:
+       process(init, clk_100m_locked_s)
        begin
 
-               neg_init <= not init;
-               reset <= (not init) or (not clk_100m_locked);
+               -- TODO: Proper reset (lacks filter and propagation with ack as we use PLL)
+               neg_init_s <= not init;
+               reset_s <= (not init) or (not clk_100m_locked_s);
 
        end process;