Skip to content
Snippets Groups Projects
Select Git revision
  • 7a5501e181cb00fe0283870b5094ad879bc6f2d1
  • master default protected
  • L2SDP-LIFT
  • L2SDP-1137
  • L2SDP-1113
  • HPR-158
6 results

ddrctrl_address_counter.vhd

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ddrctrl_address_counter.vhd 5.40 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright 2022
    -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
    --
    -- Licensed under the Apache License, Version 2.0 (the "License");
    -- you may not use this file except in compliance with the License.
    -- You may obtain a copy of the License at
    --
    --     http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    --
    -------------------------------------------------------------------------------
    -- Author: Job van Wee
    -- Purpose: Creates address by counting input valids
    --
    -- Description:
    --  The counter starts on the first valid = '1' clockcylce, the counter stops 
    --  when valid = '0'.
    --
    -- Remark:
    --  Use VHDL coding template from:
    --  https://support.astron.nl/confluence/display/SBe/VHDL+design+patterns+for+RTL+coding
    --  The maximum value of the address is determend by g_tech_ddr.
    
    LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib;
    USE IEEE.std_logic_1164.ALL;
    USE IEEE.numeric_std.ALL;
    USE technology_lib.technology_pkg.ALL;
    USE tech_ddr_lib.tech_ddr_pkg.ALL;
    USE common_lib.common_pkg.ALL;
    USE common_lib.common_mem_pkg.ALL;
    USE dp_lib.dp_stream_pkg.ALL;
    
    
    ENTITY ddrctrl_address_counter IS
      GENERIC (
        g_tech_ddr            : t_c_tech_ddr;                                                                                                 -- type of memory
        g_sim_model           : BOOLEAN                               := TRUE                                                                 -- determens if this is a simulation
      );
      PORT (
        clk                   : IN  STD_LOGIC;
        rst                   : IN  STD_LOGIC;
        in_sosi               : IN  t_dp_sosi;                                                                                                -- input data
        in_of                 : IN  NATURAL;
        out_mosi              : OUT t_mem_ctlr_mosi                   := c_mem_ctlr_mosi_rst;                                                 -- output data
        out_of                : OUT NATURAL
      );
    END ddrctrl_address_counter;
    
    
    ARCHITECTURE rtl OF ddrctrl_address_counter IS
    
      -- constants for readability
      CONSTANT c_data_w       : NATURAL                               := func_tech_ddr_ctlr_data_w( g_tech_ddr );                             -- the with of the input data and output data, 576
      CONSTANT c_adr_w        : NATURAL                               := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27
      CONSTANT c_max_adr      : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0)  := STD_LOGIC_VECTOR(TO_UVEC(2**(c_adr_w)-1, c_adr_w));                  -- the maximal address that is possible within the vector length of the address
    
      -- type for statemachine
      TYPE t_state IS (RESET, COUNTING, MAX, IDLE);
    
      -- record for readability
      TYPE t_reg IS RECORD
      state                   : t_state;
      out_mosi                : t_mem_ctlr_mosi;
      out_of                  : NATURAL;
      s_in_sosi               : t_dp_sosi;
      s_in_of                 : NATURAL;
      END RECORD;
    
      CONSTANT  c_t_reg_init  : t_reg                                 := (RESET, c_mem_ctlr_mosi_rst, 0, c_dp_sosi_init, 0);
    
    
      -- signals for readability
      SIGNAL d_reg            : t_reg                                 := c_t_reg_init;
      SIGNAL q_reg            : t_reg                                 := c_t_reg_init;
    
    BEGIN
    
      q_reg <= d_reg WHEN rising_edge(clk);
    
      -- Increments the address each time in_sosi.valid = '1', if address = c_max_adr the address is reset to 0.
      p_adr : PROCESS(rst, in_sosi, in_of, q_reg)
    
      VARIABLE v              : t_reg;
    
      BEGIN
        v                                                             := q_reg;
        v.out_mosi.wrdata(c_data_w-1 DOWNTO 0)                        := q_reg.s_in_sosi.data(c_data_w - 1 DOWNTO 0);
        v.out_mosi.wr                                                 := q_reg.s_in_sosi.valid;
        v.out_of                                                      := q_reg.s_in_of;
        v.s_in_sosi                                                   := in_sosi;
        v.s_in_of                                                     := in_of;
    
    
        CASE q_reg.state IS
        WHEN RESET =>
          v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0');
    
        WHEN COUNTING =>
          v.out_mosi.address(c_adr_w-1 DOWNTO 0) := STD_LOGIC_VECTOR(TO_UVEC(TO_UINT(q_reg.out_mosi.address)+1, c_adr_w));
    
        WHEN MAX =>
          v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0');
    
        WHEN IDLE =>
    
        END CASE;
    
        IF rst = '1' THEN
          v.state := RESET;
        ELSIF q_reg.out_mosi.address(c_adr_w-1 DOWNTO 0) = c_max_adr(c_adr_w-1 DOWNTO 0) AND in_sosi.valid = '1' THEN
          v.state := MAX;
        ELSIF in_sosi.valid = '1' THEN
          v.state := COUNTING;
        ELSE
          v.state := IDLE;
        END IF;
    
        d_reg <= v;
      END PROCESS;
    
      -- fill outputs
      out_mosi <= q_reg.out_mosi;
      out_of   <= q_reg.out_of;
    
    END rtl;