Skip to content
Snippets Groups Projects
Commit 01e2ddf3 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Cosmetic. Updated description.

parent c31ae47d
No related branches found
No related tags found
No related merge requests found
......@@ -25,67 +25,46 @@
-- Block diagram:
--
-- A) Functional
-- g_in_nof_words=4 g_out_nof_words=2
-- The drawing shows g_in_nof_words=4 and g_out_nof_words=2 as example:
--
-- r_in r_out
-- ___ r_out_ready ___ <-- src_in.ready
-- | |<---------------------| |--> src_out.data
-- dp_repack_in dp_repack_out
-- ___ ___
-- | | pack_sosi | |--> src_out
-- | 3 |--------------------->| 1 |
-- | | load | |
-- | 2 | | |
-- | | ^ | | ^
-- | 1 | |valid | 0 | |shift
-- | | |flush | | |
-- | 0 | | | | |
-- snk_in.data -->|___| |___|
-- snk_out.ready <--
-- | | | |
-- | 2 | ^ | | ^
-- | | |valid | | |shift
-- | 1 | |flush | 0 | |
-- | | | | | |
-- | 0 | | |
-- snk_in -->|___| pack_siso |___|
-- snk_out.ready <-- <--------------------- <-- src_in.ready
-- snk_out.xon <------------------------------------- src_in.xon
--
--
-- B) No src_in flow control, but can issue local comb_snk_out flow control
-- B) Flow control
--
-- /----------------------------\
-- | nxt_r r |
-- | /------\ . . |
-- \-->| |----> p_reg -----*--> src_out
-- | | . .
-- snk_in -------->| | . .
-- comb_snk_out <---|p_comb| . .
-- . \------/ . .
-- . . .
-- RL=1 RL=1 RL=2
--
-- C) Add src_in flow control using dp_pipeline
--
-- /----------------------------\
-- | nxt_r r |
-- | /------\ . . |
-- \-->| |----> p_reg -----/ ____
-- | | | |dp |
-- snk_in -------->| | \------------------|pipe|---> src_out
-- /--|p_comb| . |line|
-- | \------/ . | |
-- comb_snk_out | . | |
-- v . | |
-- /-\ . pipe_snk_out | |
-- snk_out <----| |<-----------------------------| |<--- src_in
-- . \-/ . |____| .
-- . . .
-- RL=1 RL=1 RL=1
--
-- Default flow control:
-- snk_out.ready <= comb_snk_out.ready AND pipe_snk_out.ready -- when function maintains or increases the data valid rate
-- snk_out.ready <= '0' WHEN comb_snk_out.ready='0' ELSE pipe_snk_out.ready; -- when function increases the data valid rate (equivalent boolean condition)
--
-- Advanced flow control for maximum throughput:
-- snk_out.ready <= '1' WHEN comb_snk_out.ready='1' ELSE pipe_snk_out.ready; -- when function reduces the data valid rate
--
-- The default flow control condition is that both the local function and
-- the downstream function have to be ready. The default flow control
-- condition works in any case, but if the local function reduces the valid
-- data output rate, then the throughput can be increased by using the
-- advanced flow control condition. The local function can reduce the valid
-- data rate by packing data into larger words or by removing data.
-- . . .
-- . /-----------------------------------------\
-- . | . _____ . |
-- . | /------\ nxt_r | | r |
-- . \-->| |---*-------*----->|p_reg|-----*---> src_out
-- . | | | | |_____|
-- snk_in -------->|p_comb|<--|-------|--------------*-------- src_in
-- | | | | |
-- | | | v |
-- | | | /-------\ |
-- | | | |p_flow | |
-- \------/ | \-------/ |
-- | | |
-- nxt_r.hold_out.valid | | |
-- v | |
-- /| |r_snk_out |
-- |1|------/ |
-- snk_out <------------------| | |
-- |0|---------------------/
-- \|
--
-- Description:
-- The dp_repack_dev repacks g_in_nof_words of width g_in_dat_w into
......@@ -94,80 +73,58 @@
-- . bypass
-- If g_in_nof_words=g_out_nof_words then snk_in is simply passed on directly
-- to src_out via wires.
-- If g_in_nof_words=1 then the dp_repack_in stage is bypassed to safe logic.
-- If g_out_nof_words=1 then the dp_repack_out stage is bypassed to safe logic.
-- Both the dp_repack_in and dp_repack_out stage do work correctly when
-- nof_words=1. They then merely add a transparant pipeline delay. It is
-- important that they also work for nof_words=1 because that gives confidence
-- that their implementation structure is ok.
--
-- . g_in_nof_words and input block size
-- The input block size in words is indicated by snk_in.sop and snk_in.eop.
-- Each subsection of g_in_nof_words is packed into g_out_nof_words. The
-- input block size does not have to be a multiple of g_in_nof_words. When
-- the snk_in.eop
-- occurs the last repack is initiated without need for input data padding.
-- the snk_in.eop occurs the last repack is initiated without need for input
-- data padding. If the block length is an integer multiple of
-- g_in_nof_words then the dp_repack_dev introduces no gaps between blocks.
-- If the block length is a fractional multiple of g_in_nof_words then there
-- will be a gap after the block due to that the dp_repack_in needs to
-- shift up the last subsection for the 'missing' input words.
--
-- . c_out_buf_dat_w >= c_in_buf_dat_w
-- To avoid loss of input data the c_out_buf_dat_w must be >= c_in_buf_dat_w.
-- If c_out_buf_dat_w > c_in_buf_dat_w then there will be unused LSbits in
-- the output data.
--
-- Remark:
-- Remarks:
-- . Originally reused from LOFAR rad_repack.vhd and rad_repack(rtl).vhd. This
-- dp_repack_dev still uses the shift in input register in and the shift out
-- output register, but no longer the intermediate buffer register.
-- Using shift in and shift out probably eases timing closure compared to
-- using a demultiplexer to put the input data in the input register and a
-- multiplexer to get the data directly from the output register. For the
-- demultiplexer / multiplexer it would be possible to only use one internal
-- register.
-- Using shift in and shift out may ease timing closure because the routing
-- is more local compared to using a demultiplexer to put the input data in
-- the input register and a multiplexer to get the data directly from the
-- output register. For the demultiplexer / multiplexer it would be possible
-- to only use one internal register.
-- Using shift up is sufficient, the shift down option is not needed. With
-- shift up the data is input a [0] and output the high index.
-- Instead of requiring an snk_in.valid duty cycle this dp_repack_dev uses
-- snk_out.ready flow control and can handle src_in.ready flow control.
-- . The case of g_in_dat_w*g_in_nof_words /= g_out_dat_w*g_out_nof_words
-- needs to be supported for both < and also > to be able to use a pack and
-- a unpack instance.
--
-- Design steps:
-- * Day 1
-- . Studied original dp_repack with shift in stage, buffer stage and shift
-- out stage. Concluded that:
-- - the buffer stage is not needed
-- - using shift in and shift out stages is better than using one stage
-- with input demux and output mux.
-- - using shift up is sufficient, the shift down optionvis not needed.
-- With shift up the data is input a [0] and output the high index.
-- . Design improvements:
-- - Treat the input stage and output stage as two separate components,
-- each introducing 1 cycle pipeline and each with its own set of
-- registers (r_in and r_out). Describe them using the Gaisler two
-- process method.
-- - Support c_out_buf_dat_w > c_in_buf_dat_w
-- . Started the new dp_repack with streaming interfaces and flow control
-- in a new file dp_repack_dev.vhd. Copied tb_dp_repack.vhd to
-- tb_dp_repack_dev.vhd.
-- . Treat the input stage and output stage as two separate components,
-- each introducing 1 cycle pipeline and each with its own registers
-- (r_in and r_out). Describe them using the Gaisler two process method.
-- . Distinghuised generate cases for g_in_nof_words=1 or >1 and similar
-- for g_out_nof_words=1 or >1. Started with implementing >1 first for
-- r_in and then for r_out.
-- . Defined flow control between r_in and r_out using r_in.load (which acts
-- as sosi.valid) and r_out_ready (which acts as siso.ready with RL=1).
-- * Day 2
-- . Added g_no_unpack to the tb_dp_repack.vhd to be able to verify one DUT
-- instead of DUT and inverse opertion DUT together. Being able to verify
-- a single DUT and using e_active eases the checking that no clock
-- cycles are lost unnecessarily.
-- . Verified that the gap between input blocks can be 0, it does not have
-- to be >= g_out_nof_words.
-- . Added r_out.eos to avoid loosing a clk cycle after loading a new
-- subsection.
-- . Corrected src_out.empty
-- . Corrected src_out.data.
-- . Added block diagram drawing in the description.
-- . Added multi testbench tb_tb_repack_dev.vhd
-- . Committed all.
--
-- * Day 3
-- . Panic and distress : I can not get it to work for blocks with multiple
-- subsections and also not for flow control. Need to rethink.
-- . Split dp_repack_dev into separate dp_repack_in input stage component
-- and dp_repack_out output stage component for more clarity.
--
-- * Day 4
-- * In total the development took 5 days. On day 3 I was in distress because
-- I could not get it to work so I needed to rethink. After changing to the
-- new flow control scheme that uses nxt_r the design was gradually improved
-- by getting the dp_repack_dev instances in tb_tb_dp_repack_dev to work one
-- by one. First only for e_active stimuli and then also for e_random and
-- e_pulse. This step by step approach makes that the bugs appear one by one
-- instead of all together.
-- * The development used the tb_dp_repack_dev testbench that does a pack and
-- an unpack to be able to verify the data. The g_no_unpack and
-- c_enable_repack_in / c_enable_repack_out parameters in the tb were useful
-- to be able to isolate a component for debugging.
-- * First the cases with g_in_nof_words=1 and g_out_nof_words were made to
-- work for different g_pkt_len. Then the empty functionality was added.
-- Then apply external flow control using c_dp_flow_control_enum_arr in
-- the tb_tb_dp_repack_dev was verified resulting in small corrections.
-- Then verified g_in_dat_w*g_in_nof_words /= g_out_dat_w*g_out_nof_words.
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
......@@ -308,9 +265,9 @@ BEGIN
-- pending output
IF src_in.ready='1' THEN
v.src_out.valid := '1';
v.src_out.sync := v.hold_out.sync;
v.src_out.sop := v.hold_out.sop;
v.src_out.eop := v.hold_out.eop;
v.src_out.sync := r.hold_out.sync;
v.src_out.sop := r.hold_out.sop;
v.src_out.eop := r.hold_out.eop;
v.hold_out.valid := '0';
END IF;
END IF;
......@@ -329,7 +286,7 @@ BEGIN
END PROCESS;
--------------------------------------------------------------------------
-- p_in_reg
-- p_reg
r <= nxt_r WHEN rising_edge(clk);
--------------------------------------------------------------------------
......@@ -352,7 +309,7 @@ BEGIN
-- Flow control
-- local function flow control
p_flow_control : PROCESS(nxt_r)
p_flow : PROCESS(nxt_r)
BEGIN
r_snk_out <= c_dp_siso_rdy;
IF nxt_r.flush='1' THEN
......@@ -439,7 +396,6 @@ BEGIN
v.src_out.valid := '0';
v.src_out.sop := '0';
v.src_out.eop := '0';
v.eos := '0';
------------------------------------------------------------------------
-- Function
......@@ -530,10 +486,10 @@ BEGIN
-- pending output
IF src_in.ready='1' THEN
v.src_out.valid := '1';
v.src_out.sync := v.hold_out.sync;
v.src_out.sop := v.hold_out.sop;
IF v.eos='1' THEN
v.src_out.eop := v.hold_out.eop; -- output eop at end of subsection
v.src_out.sync := r.hold_out.sync;
v.src_out.sop := r.hold_out.sop;
IF r.eos='1' THEN
v.src_out.eop := r.hold_out.eop; -- output eop at end of subsection
END IF;
v.hold_out.valid := '0';
END IF;
......@@ -555,7 +511,7 @@ BEGIN
END PROCESS;
--------------------------------------------------------------------------
-- p_out_reg
-- p_reg
r <= nxt_r WHEN rising_edge(clk);
--------------------------------------------------------------------------
......@@ -573,7 +529,7 @@ BEGIN
-- Flow control
-- local function flow control
p_flow_control : PROCESS(nxt_r)
p_flow : PROCESS(nxt_r)
BEGIN
r_snk_out <= c_dp_siso_rdy;
IF nxt_r.shift='1' AND nxt_r.eos='0' THEN
......@@ -694,7 +650,7 @@ BEGIN
END GENERATE;
-- Simulation only: internal stream RL verification
--proc_dp_siso_alert(clk, snk_in, i_snk_out, snk_out_ready_reg);
--proc_dp_siso_alert(clk, pack_sosi, pack_siso, pack_ready_reg);
proc_dp_siso_alert(clk, snk_in, i_snk_out, snk_out_ready_reg);
proc_dp_siso_alert(clk, pack_sosi, pack_siso, pack_ready_reg);
END str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment