Select Git revision
ddrctrl_address_counter.vhd
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;