Skip to content
Snippets Groups Projects
Commit 2c60dd71 authored by Job van Wee's avatar Job van Wee
Browse files

initial commit WIP (Work In Progress)

parent b986ce34
No related branches found
No related tags found
1 merge request!215Resolve L2SDP-660
Pipeline #25616 failed
hdl_lib_name = lofar2_ddrctrl
hdl_library_clause_name = lofar2_ddrctrl_lib
hdl_lib_uses_synth = technology common tech_ddr dp
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
src/vhdl/address_counter.vhd
src/vhdl/pack.vhd
src/vhdl/repack.vhd
test_bench_files =
tb/vhdl/tb_address_counter.vhd
regression_test_vhdl =
[modelsim_project_file]
[quartus_project_file]
LIBRARY IEEE, technology_lib, tech_ddr_lib, common_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;
ENTITY address_counter IS
GENERIC (
g_tech_ddr : t_c_tech_ddr;
g_sim_model : BOOLEAN := TRUE
);
PORT (
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
in_data : IN STD_LOGIC_VECTOR(func_tech_ddr_ctlr_data_w( g_tech_ddr )-1 DOWNTO 0);
in_data_enable : IN STD_LOGIC;
out_data : OUT STD_LOGIC_VECTOR(func_tech_ddr_ctlr_data_w( g_tech_ddr )-1 DOWNTO 0);
out_data_enable : OUT STD_LOGIC;
adr : OUT NATURAL range 0 to 2**(sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )))-1
);
END address_counter;
ARCHITECTURE rtl OF address_counter IS
CONSTANT c_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); --576
CONSTANT c_adr_w : NATURAL := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); --27;
SIGNAL s_adr : NATURAL range 0 to 2**(c_adr_w)-1;
BEGIN
out_data(c_data_w - 1 DOWNTO 0) <= in_data(c_data_w - 1 DOWNTO 0);
out_data_enable <= in_data_enable;
adr <= s_adr;
p_clk : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF rst = '1' THEN
s_adr <= 0; -- https://stackoverflow.com/questions/9989913/vhdl-how-to-use-clk-and-reset-in-process
ELSIF in_data_enable = '1' THEN
IF (s_adr = 2**(c_adr_w) - 1) THEN
s_adr <= 0;
ELSE
s_adr <= s_adr + 1;
END IF;
END IF;
END IF;
END PROCESS;
END rtl;
LIBRARY IEEE, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE dp_lib.dp_stream_pkg.ALL;
ENTITY pack IS
GENERIC (
g_nof_streams : POSITIVE := 12;
g_data_w : NATURAL := 14
);
PORT (
clk : IN STD_LOGIC;
in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
out_data : OUT STD_LOGIC_VECTOR((g_nof_streams*g_data_w)-1 DOWNTO 0)
);
END pack;
ARCHITECTURE rtl OF pack IS
BEGIN
gen_extract_and_pack_data : FOR I IN 0 TO g_nof_streams-1 GENERATE
out_data(g_data_w*(I+1)-1 DOWNTO g_data_w*I) <= in_sosi_arr(I).data(g_data_w-1 DOWNTO 0);
END GENERATE;
END rtl;
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY repack IS
GENERIC (
g_in_data_w : NATURAL := 168;
g_out_data_w : NATURAL := 576
);
PORT (
clk : IN STD_LOGIC;
out_o_f : OUT NATURAL;
in_data : IN STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0);
out_data : OUT STD_LOGIC_VECTOR(g_out_data_w-1 DOWNTO 0);
data_enable : OUT STD_LOGIC
);
END repack;
ARCHITECTURE rtl OF repack IS
CONSTANT k_c_v_w : NATURAL := g_out_data_w*2;
SIGNAL c_v_count : NATURAL := 0;
SIGNAL out_data_count : NATURAL := 0;
SIGNAL a_o_f : NATURAL := 0;
SIGNAL c_v : STD_LOGIC_VECTOR (k_c_v_w-1 DOWNTO 0);
BEGIN
p_clk : PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF (g_in_data_w*(c_v_count+1) >= g_out_data_w*(out_data_count+1)) THEN -- if the input data exceeds the output data vector width
IF (out_data_count = 1) THEN -- if the input data exceeds c_v vector widt
out_o_f <= a_o_f; -- set the output overflow to the overflow that maches the out_data vector
a_o_f <= a_o_f + g_in_data_w * c_v_count - g_out_data_w * (out_data_count + 1); -- check how much overflow there is and safe it in a_o_f
c_v(k_c_v_w - 1 DOWNTO k_c_v_w - (g_in_data_w - a_o_f)) <= in_data(g_in_data_w - a_o_f - 1 DOWNTO 0); -- fill the rest of c_v untill the end
c_v(a_o_f - 1 DOWNTO 0) <= in_data(g_in_data_w - 1 DOWNTO g_in_data_w - a_o_f); -- fill the start of c_v untill the a_o_f
out_data(g_out_data_w - 1 DOWNTO 0) <= c_v(k_c_v_w - 1 DOWNTO g_out_data_w); -- fill out_data with 2nd part of c_v
data_enable <= '1'; -- data_enable 1
c_v_count <= 0; -- reset counter
out_data_count <= 0; -- reset counter
Else -- if the input data exceeds output data vector width but not the c_v vector widt
c_v(g_in_data_w * (c_v_count + 1) + a_o_f - 1 DOWNTO g_in_data_w * c_v_count + a_o_f) <= in_data(g_in_data_w - 1 DOWNTO 0); -- fill c_v
c_v_count <= c_v_count + 1; -- increase the counter of c_v with 1
out_data(g_out_data_w - 1 DOWNTO 0) <= c_v(g_out_data_w - 1 DOWNTO 0); -- fill out_data with 1st part of c_v
out_data_count <= out_data_count + 1; -- increase the counter of out_data with 1
data_enable <= '1'; -- data_enable 1
END IF;
ELSE -- if the input data doesn't exceeds the output data vector width
c_v(g_in_data_w * (c_v_count + 1) + a_o_f - 1 DOWNTO g_in_data_w * c_v_count + a_o_f) <= in_data(g_in_data_w - 1 DOWNTO 0); -- fill c_v
c_v_count <= c_v_count + 1; -- increase the counter of c_v with 1
data_enable <= '0'; -- data_enable 0
END IF;
END IF;
END PROCESS;
END rtl;
--------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, technology_lib, tech_ddr_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.MATH_REAL.ALL;
USE technology_lib.technology_pkg.ALL;
USE tech_ddr_lib.tech_ddr_pkg.ALL;
ENTITY tb_address_counter IS
GENERIC (
g_tech_ddr : t_c_tech_ddr := c_tech_ddr4_8g_1600m;
g_sim_model : BOOLEAN := TRUE
);
END tb_address_counter;
ARCHITECTURE tb OF tb_address_counter IS
CONSTANT c_clk_freq : NATURAL := 200; -- MHz
CONSTANT c_clk_period : TIME := (10**6 / c_clk_freq) * 1 ps;
CONSTANT c_data_w : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr ); -- 576
CONSTANT c_adr_w : NATURAL := 4;
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC;
SIGNAL in_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
SIGNAL in_data_enable : STD_LOGIC;
SIGNAL out_data : STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0);
SIGNAL out_data_enable : STD_LOGIC;
SIGNAL adr : NATURAL range 0 to 2**(c_adr_w)-1;
BEGIN
clk <= NOT clk OR tb_end AFTER c_clk_period/2;
p_mm : PROCESS
BEGIN
rst <= '1', '0' AFTER c_clk_period/10;
tb_end <= '0';
in_data <= (OTHERS => '0');
in_data_enable <= '0';
WAIT UNTIL rising_edge(clk); -- align to rising edge
WAIT FOR c_clk_period*10;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
rst <= '1'; -- reset
in_data_enable <= '0';
WAIT FOR c_clk_period*1;
rst <= '0';
WAIT FOR c_clk_period*1;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
WHILE (adr /= 1) LOOP
in_data_enable <= '1';
in_data <= NOT in_data;
WAIT FOR c_clk_period*1;
in_data_enable <= '0';
WAIT FOR c_clk_period*2;
END LOOP;
WAIT FOR c_clk_period*20;
tb_end <= '1';
WAIT;
END PROCESS;
u_address_counter : ENTITY work.address_counter
GENERIC MAP (
g_tech_ddr => g_tech_ddr,
g_sim_model => g_sim_model
)
PORT MAP (
clk => clk,
rst => rst,
in_data => in_data,
in_data_enable => in_data_enable,
out_data => out_data,
out_data_enable => out_data_enable,
adr => adr
);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment