From c372ae2eb08e67ace32ace1131249cc4220e0f17 Mon Sep 17 00:00:00 2001
From: JobvanWee <wee@astron.nl>
Date: Wed, 6 Apr 2022 08:08:27 +0200
Subject: [PATCH] Initial commit

---
 .../ddrctrl/src/vhdl/ddrctrl_output.vhd       | 101 +++++++++++
 .../src/vhdl/ddrctrl_output_repack.vhd        |  58 +++++++
 .../src/vhdl/ddrctrl_output_unpack.vhd        | 162 ++++++++++++++++++
 3 files changed, 321 insertions(+)
 create mode 100644 applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd
 create mode 100644 applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd
 create mode 100644 applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd

diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd
new file mode 100644
index 0000000000..2ac12ede36
--- /dev/null
+++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output.vhd
@@ -0,0 +1,101 @@
+-------------------------------------------------------------------------------
+--
+-- 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: Folding a stream of data into a mm data configuration so it can be
+-- stored in a DDR RAM-stick.
+--
+-- Description:
+--  First the data from the sosi array gets collected into one data vector.
+--  After that this data vector gets resized to the right size data vector in 
+--  order to make it storable in a DDR RAM-stick.
+--  After that a address gets assigned to the data so the data can be found back.
+--
+-- 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_output IS
+  GENERIC (
+    g_tech_ddr        : t_c_tech_ddr;                                   -- type of memory
+    g_sim_model       : BOOLEAN       := TRUE;                          -- determens if this is a simulation
+    g_in_data_w       : NATURAL       := 576;                           
+    g_nof_streams     : NATURAL       := 12;                            -- number of input streams
+    g_data_w          : NATURAL       := 14                             -- data with of input data vectors
+  );
+  PORT (
+    clk               : IN  STD_LOGIC := '0';
+    rst               : IN  STD_LOGIC;
+    in_data           : IN  STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0);   -- input data
+    in_of             : IN  NATURAL;                                    -- amount of internal overflow this output
+    in_bsn            : IN  STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- bsn corresponding to the data at in_data[in_of]
+    out_sosi_arr      : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init) -- output data
+  );
+END ddrctrl_output;
+
+
+ARCHITECTURE str OF ddrctrl_output IS
+
+  -- constant for readability
+  CONSTANT  c_out_data_w : NATURAL    := g_nof_streams*g_data_w;        -- the input data with for ddrctrl_repack 168
+
+  -- signals for connecting the components
+  SIGNAL    sosi                   : t_dp_sosi  := c_dp_sosi_init;
+
+BEGIN
+
+  -- makes one data vector out of all the data from the t_dp_sosi_arr
+  u_ddrctrl_output_pack : ENTITY work.ddrctrl_output_unpack
+  GENERIC MAP(
+    g_tech_ddr        => g_tech_ddr,
+    g_in_data_w       => g_in_data_w,
+    g_out_data_w      => c_out_data_w
+  )
+  PORT MAP(
+    clk               => clk,
+    rst               => rst,
+    in_data           => in_data,                                       -- input data
+    in_of             => in_of,
+    in_bsn            => in_bsn,
+    out_sosi          => sosi                                           -- output data
+  );
+
+  -- resizes the input data vector so that the output data vector can be stored into the ddr memory
+  u_ddrctrl_output_repack : ENTITY work.ddrctrl_output_repack
+  GENERIC MAP(
+  g_nof_streams       => g_nof_streams,
+  g_data_w            => g_data_w
+  )
+  PORT MAP(
+    in_sosi           => sosi,
+    out_sosi_arr      => out_sosi_arr
+  );
+
+END str;
diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd
new file mode 100644
index 0000000000..772264b590
--- /dev/null
+++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_repack.vhd
@@ -0,0 +1,58 @@
+-------------------------------------------------------------------------------
+--
+-- 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: Resize the input data vector so that the output data vector can be
+--  stored into the ddr memory.
+--
+-- Description:
+--  The input data gets resized and put into the output data vector.
+--
+-- Remark:
+--  Use VHDL coding template from:
+--  https://support.astron.nl/confluence/display/SBe/VHDL+design+patterns+for+RTL+coding
+--  The output vector must be larger than the input vector.
+
+LIBRARY IEEE, dp_lib, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE common_lib.common_pkg.ALL;
+
+ENTITY ddrctrl_output_repack IS
+  GENERIC (
+    g_nof_streams   : POSITIVE := 12;
+    g_data_w        : NATURAL  := 14
+  );
+  PORT (
+    in_sosi         : IN  t_dp_sosi     := c_dp_sosi_init;
+    out_sosi_arr    : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init)
+  );
+END ddrctrl_output_repack;
+
+ARCHITECTURE rtl OF ddrctrl_output_repack IS
+
+BEGIN
+
+  -- putting the data from the stream into different streams.
+  gen_repack_data : FOR I IN 0 TO g_nof_streams-1 GENERATE
+    out_sosi_arr(I).data <= in_sosi.data(g_data_w*(I+1)-1 DOWNTO g_data_w*I);
+    out_sosi_arr(I).bsn  <= in_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0);
+  END GENERATE;
+
+END rtl;
diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd
new file mode 100644
index 0000000000..3224d63d98
--- /dev/null
+++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_output_unpack.vhd
@@ -0,0 +1,162 @@
+-------------------------------------------------------------------------------
+--
+-- 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: Resize the input data vector so that the output data vector can be
+--  stored into the ddr memory.
+--
+-- Description:
+--  The input data gets resized and put into the output data vector.
+--
+-- Remark:
+--  Use VHDL coding template from:
+--  https://support.astron.nl/confluence/display/SBe/VHDL+design+patterns+for+RTL+coding
+--  The output vector must be larger than the input vector.
+
+LIBRARY IEEE, dp_lib, tech_ddr_lib, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE tech_ddr_lib.tech_ddr_pkg.ALL;
+USE common_lib.common_pkg.ALL;
+
+ENTITY ddrctrl_output_unpack IS
+  GENERIC (
+    g_tech_ddr      : t_c_tech_ddr;
+    g_in_data_w     : NATURAL;
+    g_out_data_w    : NATURAL
+  );
+  PORT (
+    clk             : IN  STD_LOGIC;
+    rst             : IN  STD_LOGIC;
+    start           : IN  STD_LOGIC;
+    in_data         : IN  STD_LOGIC_VECTOR(g_in_data_w-1 DOWNTO 0);
+    in_of           : IN  NATURAL;
+    in_bsn          : IN  STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
+    out_sosi        : OUT t_dp_sosi   := c_dp_sosi_init
+  );
+END ddrctrl_output_unpack;
+
+
+ARCHITECTURE rtl OF ddrctrl_output_unpack IS
+
+  -- type for statemachine
+  TYPE t_state IS ( READING, FH_READ, SH_READ, RESET, IDLE);
+
+  -- record for readability
+  TYPE t_reg IS RECORD
+  state           : t_state;
+  a_of            : NATURAL;
+  op_data_cnt     : NATURAL;
+  out_sosi        : t_dp_sosi;
+  END RECORD;
+
+  CONSTANT c_t_reg_init   : t_reg     := (RESET, 0, 0, c_dp_sosi_init);
+
+
+  -- 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);
+
+  -- put the input data into c_v and fill the output vector from c_v
+  p_state : PROCESS(q_reg, rst, in_data, in_of, in_bsn, start)
+
+    VARIABLE v            : t_reg;
+
+  BEGIN
+
+    v := q_reg;
+
+    CASE q_reg.state IS
+    WHEN READING =>
+      v.out_sosi.data(g_out_data_w-1 DOWNTO 0) := in_data((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of);
+      v.out_sosi.valid := '1';
+      v.out_sosi.bsn   := ADD_UVEC(q_reg.out_sosi.bsn, "0001", c_dp_stream_bsn_w);
+      v.op_data_cnt := q_reg.op_data_cnt+1;
+
+      IF rst = '1' THEN
+        v.state := RESET;
+      ELSIF (g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of > g_in_data_w THEN
+        v.state := FH_READ;
+      ELSE
+        v.state := READING;
+      END IF;
+
+    WHEN FH_READ =>
+      v.a_of  := (g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-g_in_data_w;
+      v.out_sosi.data(g_out_data_w-v.a_of-1 DOWNTO 0) := in_data(g_in_data_w-1 DOWNTO (g_out_data_w*q_reg.op_data_cnt)+q_reg.a_of);
+      v.out_sosi.valid   := '0';
+      v.op_data_cnt := 0;
+
+      IF rst = '1' THEN
+        v.state := RESET;
+      ELSE
+        v.state := SH_READ;
+      END IF;
+
+    WHEN SH_READ =>
+      v.out_sosi.data(g_out_data_w-1 DOWNTO g_out_data_w-q_reg.a_of) := in_data((g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of-1 DOWNTO 0);
+      v.out_sosi.valid   := '1';
+      v.out_sosi.bsn   := ADD_UVEC(q_reg.out_sosi.bsn, "0001", c_dp_stream_bsn_w);
+      v.op_data_cnt := 0;
+
+      IF rst = '1' THEN
+        v.state := RESET;
+      ELSIF (g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of > g_in_data_w THEN
+        v.state := FH_read;
+      ELSE
+        v.state := READING;
+      END IF;
+
+    WHEN RESET =>
+      v := c_t_reg_init;
+
+      IF rst = '1' THEN
+        v.state := RESET;
+      ELSIF (g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of > g_in_data_w THEN
+        v.state := FH_read;
+      ELSE
+        v.state := READING;
+      END IF;
+
+    WHEN IDLE =>
+      IF rst = '1' THEN
+        v.state := RESET;
+      ELSIF start = '1' AND (g_out_data_w*(q_reg.op_data_cnt+1))+q_reg.a_of > g_in_data_w THEN
+        v.state := FH_read;
+      ELSIF start = '1' THEN
+        v.state := READING;
+        v.a_of  := in_of;
+      ELSE
+        v.state := IDLE;
+      END IF;
+
+    END CASE;
+
+    d_reg <= v;
+  END PROCESS;
+
+  -- fill outputs
+  out_sosi <= q_reg.out_sosi;
+
+
+END rtl;
-- 
GitLab