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

IT works!!

parent efc7da9e
No related branches found
No related tags found
1 merge request!236Resolve L2SDP-704
Pipeline #28102 failed
...@@ -9,6 +9,9 @@ synth_files = ...@@ -9,6 +9,9 @@ synth_files =
src/vhdl/ddrctrl_input_pack.vhd src/vhdl/ddrctrl_input_pack.vhd
src/vhdl/ddrctrl_input_repack.vhd src/vhdl/ddrctrl_input_repack.vhd
src/vhdl/ddrctrl_input.vhd src/vhdl/ddrctrl_input.vhd
src/vhdl/ddrctrl_output_unpack.vhd
src/vhdl/ddrctrl_output_repack.vhd
src/vhdl/ddrctrl_output.vhd
src/vhdl/ddrctrl_controller.vhd src/vhdl/ddrctrl_controller.vhd
src/vhdl/ddrctrl.vhd src/vhdl/ddrctrl.vhd
......
...@@ -62,6 +62,7 @@ ENTITY ddrctrl IS ...@@ -62,6 +62,7 @@ ENTITY ddrctrl IS
wr_not_rd : IN STD_LOGIC := '0'; wr_not_rd : IN STD_LOGIC := '0';
stop_in : IN STD_LOGIC := '0'; stop_in : IN STD_LOGIC := '0';
out_sosi_arr : OUT t_dp_sosi_arr;
term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol; term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol;
term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst; term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst;
...@@ -93,13 +94,24 @@ ARCHITECTURE str OF ddrctrl IS ...@@ -93,13 +94,24 @@ ARCHITECTURE str OF ddrctrl IS
SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init; SIGNAL out_sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL out_adr : NATURAL := 0; SIGNAL out_adr : NATURAL := 0;
SIGNAL dvr_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst; SIGNAL dvr_mosi : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst;
SIGNAL dvr_miso : t_mem_ctlr_miso := c_mem_ctlr_miso_rst;
SIGNAL wr_sosi : t_dp_sosi := c_dp_sosi_init; SIGNAL wr_sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL rd_siso : t_dp_siso := c_dp_siso_rst; SIGNAL rd_siso : t_dp_siso := c_dp_siso_rst;
SIGNAL rd_sosi : t_dp_sosi := c_dp_sosi_init;
SIGNAL stop : STD_LOGIC; SIGNAL stop : STD_LOGIC;
SIGNAL rd_fifo_usedw: STD_LOGIC_VECTOR(ceil_log2(c_rd_fifo_depth*(func_tech_ddr_ctlr_data_w(g_tech_ddr)/c_io_ddr_data_w) )-1 DOWNTO 0);
SIGNAL rd_ready : STD_LOGIC;
SIGNAL inp_ds : NATURAL;
SIGNAL inp_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
SIGNAL inp_bsn_adr : NATURAL;
SIGNAL outp_ds : NATURAL;
SIGNAL outp_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
BEGIN BEGIN
rd_siso.ready <= rd_ready;
rd_siso.xon <= '1';
-- input to io_ddr -- input to io_ddr
u_ddrctrl_input : ENTITY work.ddrctrl_input u_ddrctrl_input : ENTITY work.ddrctrl_input
...@@ -116,7 +128,10 @@ BEGIN ...@@ -116,7 +128,10 @@ BEGIN
in_stop => stop, in_stop => stop,
out_of => out_of, out_of => out_of,
out_sosi => out_sosi, out_sosi => out_sosi,
out_adr => out_adr out_adr => out_adr,
out_bsn_ds => inp_ds,
out_bsn => inp_bsn,
out_bsn_adr => inp_bsn_adr
); );
-- functions as a fifo buffer for input data into the sdram stick. also manages input to sdram stick. -- functions as a fifo buffer for input data into the sdram stick. also manages input to sdram stick.
...@@ -160,7 +175,7 @@ BEGIN ...@@ -160,7 +175,7 @@ BEGIN
dvr_clk => clk, dvr_clk => clk,
dvr_rst => rst, dvr_rst => rst,
dvr_miso => open, dvr_miso => dvr_miso,
dvr_mosi => dvr_mosi, dvr_mosi => dvr_mosi,
-- Write FIFO clock domain -- Write FIFO clock domain
...@@ -175,8 +190,8 @@ BEGIN ...@@ -175,8 +190,8 @@ BEGIN
rd_clk => clk, rd_clk => clk,
rd_rst => rst, rd_rst => rst,
rd_fifo_usedw => open, rd_fifo_usedw => rd_fifo_usedw,
rd_sosi => open, rd_sosi => rd_sosi,
rd_siso => rd_siso, rd_siso => rd_siso,
term_ctrl_out => term_ctrl_out, term_ctrl_out => term_ctrl_out,
...@@ -193,24 +208,60 @@ BEGIN ...@@ -193,24 +208,60 @@ BEGIN
phy4_ou => phy4_ou phy4_ou => phy4_ou
); );
-- reading ddr memory
u_ddrctrl_output : ENTITY work.ddrctrl_output
GENERIC MAP(
g_tech_ddr => g_tech_ddr,
g_sim_model => g_sim_model,
g_nof_streams => g_nof_streams,
g_data_w => g_data_w
)
PORT MAP(
clk => clk,
rst => rst,
in_sosi => rd_sosi,
in_ds => outp_ds,
in_bsn => outp_bsn,
out_sosi_arr => out_sosi_arr,
out_ready => rd_ready
);
-- controller of ddrctrl -- controller of ddrctrl
u_ddrctrl_controller : ENTITY work.ddrctrl_controller u_ddrctrl_controller : ENTITY work.ddrctrl_controller
GENERIC MAP( GENERIC MAP(
g_tech_ddr => g_tech_ddr, g_tech_ddr => g_tech_ddr,
g_stop_percentage => g_stop_percentage g_stop_percentage => g_stop_percentage,
g_nof_streams => g_nof_streams,
g_out_data_w => g_data_w,
g_wr_data_w => c_io_ddr_data_w,
g_rd_fifo_depth => c_rd_fifo_depth,
g_rd_data_w => c_io_ddr_data_w
) )
PORT MAP( PORT MAP(
clk => clk, clk => clk,
rst => rst, rst => rst,
-- ddrctrl_input
out_of => out_of, out_of => out_of,
out_sosi => out_sosi, out_sosi => out_sosi,
out_adr => out_adr, out_adr => out_adr,
inp_ds => inp_ds,
inp_bsn => inp_bsn,
inp_bsn_adr => inp_bsn_adr,
-- io_ddr
dvr_mosi => dvr_mosi, dvr_mosi => dvr_mosi,
dvr_miso => dvr_miso,
wr_sosi => wr_sosi, wr_sosi => wr_sosi,
rd_siso => rd_siso, rd_fifo_usedw => rd_fifo_usedw,
-- ddrctrl_output
outp_ds => outp_ds,
outp_bsn => outp_bsn,
-- ddrctrl_controller
stop_in => stop_in, stop_in => stop_in,
stop_out => stop stop_out => stop
); );
......
...@@ -39,7 +39,12 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL; ...@@ -39,7 +39,12 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL;
ENTITY ddrctrl_controller IS ENTITY ddrctrl_controller IS
GENERIC ( GENERIC (
g_tech_ddr : t_c_tech_ddr; g_tech_ddr : t_c_tech_ddr;
g_stop_percentage : NATURAL := 50 g_stop_percentage : NATURAL := 50;
g_nof_streams : NATURAL;
g_out_data_w : NATURAL;
g_wr_data_w : NATURAL;
g_rd_fifo_depth : NATURAL;
g_rd_data_w : NATURAL
); );
PORT ( PORT (
clk : IN STD_LOGIC; clk : IN STD_LOGIC;
...@@ -49,13 +54,21 @@ ENTITY ddrctrl_controller IS ...@@ -49,13 +54,21 @@ ENTITY ddrctrl_controller IS
out_of : IN NATURAL; out_of : IN NATURAL;
out_sosi : IN t_dp_sosi; out_sosi : IN t_dp_sosi;
out_adr : IN NATURAL; out_adr : IN NATURAL;
inp_ds : IN NATURAL;
inp_bsn : IN STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
inp_bsn_adr : IN NATURAL;
-- io_ddr -- io_ddr
dvr_mosi : OUT t_mem_ctlr_mosi; dvr_mosi : OUT t_mem_ctlr_mosi;
dvr_miso : IN t_mem_ctlr_miso;
wr_sosi : OUT t_dp_sosi; wr_sosi : OUT t_dp_sosi;
rd_siso : OUT t_dp_siso; rd_fifo_usedw : IN STD_LOGIC_VECTOR(ceil_log2(g_rd_fifo_depth * (func_tech_ddr_ctlr_data_w(g_tech_ddr)/g_rd_data_w) )-1 DOWNTO 0);
-- ddrctrl -- ddrctrl_output
outp_ds : OUT NATURAL;
outp_bsn : OUT STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0');
-- ddrctrl_controller
stop_in : IN STD_LOGIC; stop_in : IN STD_LOGIC;
stop_out : OUT STD_LOGIC stop_out : OUT STD_LOGIC
); );
...@@ -70,25 +83,39 @@ ARCHITECTURE rtl OF ddrctrl_controller IS ...@@ -70,25 +83,39 @@ ARCHITECTURE rtl OF ddrctrl_controller IS
CONSTANT c_pof_ma : NATURAL := (c_max_adr*(100-g_stop_percentage))/100; CONSTANT c_pof_ma : NATURAL := (c_max_adr*(100-g_stop_percentage))/100;
CONSTANT c_zeros : STD_LOGIC_VECTOR(c_bitshift_adr-1 DOWNTO 0) := (OTHERS => '0'); CONSTANT c_zeros : STD_LOGIC_VECTOR(c_bitshift_adr-1 DOWNTO 0) := (OTHERS => '0');
-- constant for reading
CONSTANT c_rd_data_w : NATURAL := g_nof_streams*g_out_data_w; -- 168
CONSTANT c_rest : NATURAL := c_rd_data_w-(g_wr_data_w mod c_rd_data_w); -- 96
CONSTANT c_max_read_cnt : NATURAL := (c_max_adr+1)/c_burstsize; -- 256
-- not needed hopefully
--CONSTANT c_gcd : NATURAL := GCD(c_rd_data_w, g_wr_data_w); -- 24
--CONSTANT c_ofset_repeat : NATURAL := c_rd_data_wc/c_gcd; -- 7
-- type for statemachine -- type for statemachine
TYPE t_state IS (RESET, WRITING, SET_STOP, STOP_WRITING, READING, STOP_READING, IDLE); TYPE t_state IS (RESET, WRITING, SET_STOP, STOP_WRITING, START_READING, READING, STOP_READING, IDLE);
-- record for readability -- record for readability
TYPE t_reg IS RECORD TYPE t_reg IS RECORD
-- state of program -- state of program
state : t_state; state : t_state;
-- signals -- stoppping signals
stop_adr : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0); stop_adr : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);
stopped : STD_LOGIC; stopped : STD_LOGIC;
-- reading signals
outp_ds : NATURAL;
outp_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
read_cnt : NATURAL;
rd_burst_en : STD_LOGIC;
-- output -- output
dvr_mosi : t_mem_ctlr_mosi; dvr_mosi : t_mem_ctlr_mosi;
wr_sosi : t_dp_sosi; wr_sosi : t_dp_sosi;
rd_siso : t_dp_siso;
END RECORD; END RECORD;
CONSTANT c_t_reg_init : t_reg := (RESET, TO_UVEC(c_max_adr, c_adr_w), '0', c_mem_ctlr_mosi_rst, c_dp_sosi_init, c_dp_siso_rst); CONSTANT c_t_reg_init : t_reg := (RESET, TO_UVEC(c_max_adr, c_adr_w), '0', 0, (OTHERS => '0'), 0, '0', c_mem_ctlr_mosi_rst, c_dp_sosi_init);
-- signals for readability -- signals for readability
...@@ -100,20 +127,30 @@ BEGIN ...@@ -100,20 +127,30 @@ BEGIN
q_reg <= d_reg WHEN rising_edge(clk); q_reg <= d_reg WHEN rising_edge(clk);
-- put the input data into c_v and fill the output vector from c_v -- put the input data into c_v and fill the output vector from c_v
p_state : PROCESS(q_reg, rst, out_of, out_sosi, out_adr) p_state : PROCESS(q_reg, rst, out_of, out_sosi, out_adr, dvr_miso, rd_fifo_usedw)
VARIABLE v : t_reg := c_t_reg_init; VARIABLE v : t_reg := c_t_reg_init;
BEGIN BEGIN
v := q_reg; v := q_reg;
CASE q_reg.state IS
CASE q_reg.state IS
WHEN RESET => WHEN RESET =>
v := c_t_reg_init; v := c_t_reg_init;
IF rst = '1' THEN
v.state := RESET;
ELSIF stop_in = '1' THEN
v.state := SET_STOP;
ELSIF v.stop_adr = TO_UVEC(out_adr, c_adr_w) AND v.stop_adr(c_bitshift_adr-1 DOWNTO 0) = c_zeros(c_bitshift_adr-1 DOWNTO 0) AND q_reg.stopped = '0' THEN
v.state := STOP_WRITING;
ELSIF v.stopped = '1' THEN
v.state := IDLE;
ELSE
v.state := WRITING;
END IF;
WHEN WRITING => WHEN WRITING =>
IF TO_UVEC(out_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros THEN -- if adr mod c_burstsize = 0 IF TO_UVEC(out_adr, c_adr_w)(c_bitshift_adr-1 DOWNTO 0) = c_zeros THEN -- if adr mod c_burstsize = 0
...@@ -133,6 +170,19 @@ BEGIN ...@@ -133,6 +170,19 @@ BEGIN
IF rst = '1' THEN
v.state := RESET;
ELSIF stop_in = '1' THEN
v.state := SET_STOP;
ELSIF v.stop_adr = TO_UVEC(out_adr, c_adr_w) AND v.stop_adr(c_bitshift_adr-1 DOWNTO 0) = c_zeros(c_bitshift_adr-1 DOWNTO 0) AND q_reg.stopped = '0' THEN
v.state := STOP_WRITING;
ELSIF v.stopped = '1' THEN
v.state := IDLE;
ELSE
v.state := WRITING;
END IF;
WHEN SET_STOP => WHEN SET_STOP =>
--setting a stop address dependend on the g_stop_percentage --setting a stop address dependend on the g_stop_percentage
IF out_adr+c_pof_ma >= c_max_adr THEN IF out_adr+c_pof_ma >= c_max_adr THEN
...@@ -160,22 +210,112 @@ BEGIN ...@@ -160,22 +210,112 @@ BEGIN
IF rst = '1' THEN
v.state := RESET;
ELSIF stop_in = '1' THEN
v.state := SET_STOP;
ELSIF v.stop_adr = TO_UVEC(out_adr, c_adr_w) AND v.stop_adr(c_bitshift_adr-1 DOWNTO 0) = c_zeros(c_bitshift_adr-1 DOWNTO 0) AND q_reg.stopped = '0' THEN
v.state := STOP_WRITING;
ELSIF v.stopped = '1' THEN
v.state := IDLE;
ELSE
v.state := WRITING;
END IF;
WHEN STOP_WRITING => WHEN STOP_WRITING =>
v.dvr_mosi.burstbegin := '0';
IF dvr_miso.done = '1' THEN -- wait until the write burst is finished
v.stopped := '1'; v.stopped := '1';
v.wr_sosi.valid := '0'; v.wr_sosi.valid := '0';
v.dvr_mosi.flush := '1'; v.dvr_mosi.flush := '1';
v.state := START_READING;
ELSE
v.state := STOP_WRITING;
END IF;
IF rst = '1' THEN
v.state := RESET;
END IF;
WHEN START_READING =>
v.rd_burst_en := '1';
v.dvr_mosi.wr := '0';
v.dvr_mosi.rd := '1';
v.outp_ds := inp_ds;
FOR I IN 0 TO inp_bsn_adr+(c_max_adr-TO_UINT(q_reg.stop_adr)) LOOP -- takes a while
IF v.outp_ds-c_rest <= 0 THEN
v.outp_ds := v.outp_ds+c_rd_data_w-c_rest;
ELSE
v.outp_ds := v.outp_ds-c_rest;
END IF;
END LOOP;
v.outp_bsn := TO_UVEC(TO_UINT(inp_bsn)-((inp_bsn_adr+(c_max_adr-TO_UINT(q_reg.stop_adr)))*g_wr_data_w+v.outp_ds-inp_ds)/c_rd_data_w, c_dp_stream_bsn_w); -- maths
IF rst = '1' THEN
v.state := RESET;
ELSE
v.state := READING;
END IF;
WHEN READING =>
IF TO_UINT(rd_fifo_usedw) = 0 AND dvr_miso.done = '1' AND q_reg.rd_burst_en = '1' THEN
IF TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt >= c_max_adr THEN
v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := TO_UVEC((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt)-c_max_adr, c_adr_w);
--assert false report "1. address: " & natural'image((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt)-c_max_adr) severity note;
ELSE
v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := TO_UVEC(TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt, c_adr_w);
--assert false report "2. address: " & natural'image((TO_UINT(q_reg.stop_adr(c_adr_w-1 DOWNTO 0))+c_burstsize*q_reg.read_cnt)) severity note;
END IF;
v.dvr_mosi.burstbegin := '1';
v.read_cnt := v.read_cnt+1;
v.rd_burst_en := '0';
ELSE
v.dvr_mosi.burstbegin := '0';
END IF;
IF TO_UINT(rd_fifo_usedw) >= 1 THEN
v.rd_burst_en := '1';
END IF;
IF rst = '1' THEN
v.state := RESET;
ELSIF q_reg.read_cnt >= c_max_read_cnt THEN
v.state := IDLE;
ELSE
v.state := READING;
END IF;
WHEN IDLE => WHEN IDLE =>
IF rst = '1' THEN
v.state := RESET;
ELSIF stop_in = '1' THEN
v.state := SET_STOP;
ELSIF v.stop_adr = TO_UVEC(out_adr, c_adr_w) AND v.stop_adr(c_bitshift_adr-1 DOWNTO 0) = c_zeros(c_bitshift_adr-1 DOWNTO 0) AND q_reg.stopped = '0' THEN
v.state := STOP_WRITING;
ELSIF v.stopped = '1' THEN
v.state := IDLE;
ELSE
v.state := WRITING;
END IF;
WHEN OTHERS => WHEN OTHERS =>
v := c_t_reg_init; v := c_t_reg_init;
END CASE;
IF rst = '1' THEN IF rst = '1' THEN
v.state := RESET; v.state := RESET;
ELSIF stop_in = '1' THEN ELSIF stop_in = '1' THEN
...@@ -187,13 +327,21 @@ BEGIN ...@@ -187,13 +327,21 @@ BEGIN
ELSE ELSE
v.state := WRITING; v.state := WRITING;
END IF; END IF;
END CASE;
d_reg <= v; d_reg <= v;
END PROCESS; END PROCESS;
-- fill outputs -- fill outputs
dvr_mosi <= q_reg.dvr_mosi; dvr_mosi <= q_reg.dvr_mosi;
wr_sosi <= q_reg.wr_sosi; wr_sosi <= q_reg.wr_sosi;
rd_siso <= q_reg.rd_siso;
stop_out <= q_reg.stopped; stop_out <= q_reg.stopped;
outp_bsn <= q_reg.outp_bsn;
outp_ds <= q_reg.outp_ds;
END rtl; END rtl;
-------------------------------------------------------------------------------
--
-- 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_sosi : IN t_dp_sosi := c_dp_sosi_init; -- input data
in_ds : 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
out_ready : OUT STD_LOGIC
);
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_unpack : 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_sosi => in_sosi, -- input data
in_ds => in_ds,
in_bsn => in_bsn,
out_sosi => sosi, -- output data
out_ready => out_ready
);
-- 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;
-------------------------------------------------------------------------------
--
-- 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(g_data_w-1 DOWNTO 0) <= in_sosi.data(g_data_w*(I+1)-1 DOWNTO g_data_w*I);
out_sosi_arr(I).bsn(c_dp_stream_bsn_w-1 DOWNTO 0) <= in_sosi.bsn(c_dp_stream_bsn_w-1 DOWNTO 0);
END GENERATE;
END rtl;
-------------------------------------------------------------------------------
--
-- 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;
in_sosi : IN t_dp_sosi := c_dp_sosi_init;
in_ds : 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;
out_ready : OUT STD_LOGIC := '0'
);
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;
out_ready : STD_LOGIC;
END RECORD;
CONSTANT c_t_reg_init : t_reg := (RESET, 0, 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);
-- put the input data into c_v and fill the output vector from c_v
p_state : PROCESS(q_reg, rst, in_sosi, in_ds, in_bsn)
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_sosi.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 in_sosi.valid = '1' AND (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of > g_in_data_w THEN
v.state := FH_READ;
ELSIF in_sosi.valid = '1' THEN
v.state := READING;
ELSE
v.state := IDLE;
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_sosi.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;
v.out_ready := '1';
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_sosi.data((g_out_data_w*q_reg.op_data_cnt)+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;
v.out_ready := '0';
IF rst = '1' THEN
v.state := RESET;
ELSIF in_sosi.valid = '1' AND (g_out_data_w*(v.op_data_cnt+1))+q_reg.a_of > g_in_data_w THEN
v.state := FH_read;
ELSIF in_sosi.valid = '1' THEN
v.state := READING;
ELSE
v.state := IDLE;
END IF;
WHEN RESET =>
v := c_t_reg_init;
IF rst = '1' THEN
v.state := RESET;
ELSIF in_sosi.valid = '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 in_sosi.valid = '1' THEN
v.state := READING;
ELSE
v.state := IDLE;
END IF;
WHEN IDLE =>
v.out_ready := '1';
IF rst = '1' THEN
v.state := RESET;
ELSIF in_sosi.valid = '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 in_sosi.valid = '1' THEN
v.state := READING;
v.a_of := in_ds;
ELSE
v.state := IDLE;
END IF;
END CASE;
d_reg <= v;
END PROCESS;
-- fill outputs
out_sosi <= q_reg.out_sosi;
out_ready <= q_reg.out_ready;
END rtl;
...@@ -96,6 +96,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS ...@@ -96,6 +96,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS
SIGNAL wr_not_rd : STD_LOGIC; SIGNAL wr_not_rd : STD_LOGIC;
SIGNAL stop_in : STD_LOGIC := '0'; SIGNAL stop_in : STD_LOGIC := '0';
SIGNAL bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_init);
-- testbench signal -- testbench signal
SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off SIGNAL tb_end : STD_LOGIC := '0'; -- signal to turn the testbench off
...@@ -201,6 +202,7 @@ BEGIN ...@@ -201,6 +202,7 @@ BEGIN
in_sosi_arr => in_sosi_arr, in_sosi_arr => in_sosi_arr,
wr_not_rd => wr_not_rd, wr_not_rd => wr_not_rd,
stop_in => stop_in, stop_in => stop_in,
out_sosi_arr => out_sosi_arr,
--PHY --PHY
phy3_io => phy3_io, phy3_io => phy3_io,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment