Skip to content
Snippets Groups Projects
Commit 19a7f5c8 authored by Pieter Donker's avatar Pieter Donker
Browse files

backup of working tb

parent 0af24c7a
Branches
No related tags found
3 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!54Resolve L2SDP-49,!49WIP: Resolve L2SDP-49
...@@ -76,6 +76,7 @@ synth_files = ...@@ -76,6 +76,7 @@ synth_files =
src/vhdl/dp_bsn_source.vhd src/vhdl/dp_bsn_source.vhd
src/vhdl/dp_bsn_source_v2.vhd src/vhdl/dp_bsn_source_v2.vhd
src/vhdl/dp_bsn_source_reg.vhd src/vhdl/dp_bsn_source_reg.vhd
src/vhdl/dp_bsn_source_reg_v2.vhd
src/vhdl/mms_dp_bsn_source.vhd src/vhdl/mms_dp_bsn_source.vhd
src/vhdl/mms_dp_bsn_source_v2.vhd src/vhdl/mms_dp_bsn_source_v2.vhd
src/vhdl/dp_bsn_scheduler.vhd src/vhdl/dp_bsn_scheduler.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2012
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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/>.
--
-------------------------------------------------------------------------------
-- RO read only (no VHDL present to access HW in write mode)
-- WO write only (no VHDL present to access HW in read mode)
-- WE write event (=WO)
-- WR write control, read control
-- RW read status, write control
-- RC read, clear on read
-- FR FIFO read
-- FW FIFO write
--
-- wi Bits R/W Name Default Description
-- ====================================================================================
-- 0 [0] RW dp_on 0x0 WR '1' enables DP (on PPS when dp_on_pps=1)
-- RD '0' = DP off; RD '1' = DP on.
-- [1] WR dp_on_pps 0x0
-- 1 [31..0] WR nof_clk_per_sync 0x0
-- 2 [31..0] RW bsn[31..0] 0x0 write init_bsn, read current bsn
-- 3 [31..0] RW bsn[63..32] 0x0 write init_bsn, read current bsn
-- ====================================================================================
LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
ENTITY dp_bsn_source_reg_v2 IS
GENERIC (
g_cross_clock_domain : BOOLEAN := TRUE; -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain
g_nof_clk_per_sync : NATURAL := 200 * 10**6
);
PORT (
-- Clocks and reset
mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk
mm_clk : IN STD_LOGIC; -- memory-mapped bus clock
st_rst : IN STD_LOGIC; -- reset synchronous with st_clk
st_clk : IN STD_LOGIC; -- other clock domain clock
-- Memory Mapped Slave in mm_clk domain
sla_in : IN t_mem_mosi; -- actual ranges defined by c_mm_reg
sla_out : OUT t_mem_miso; -- actual ranges defined by c_mm_reg
-- MM registers in st_clk domain
st_on : OUT STD_LOGIC := '1'; -- level
st_on_pps : OUT STD_LOGIC := '0'; -- level
st_on_status : IN STD_LOGIC;
st_nof_clk_per_sync : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- nof block per sync
st_init_bsn : OUT STD_LOGIC_VECTOR; -- wr init BSN
st_current_bsn : IN STD_LOGIC_VECTOR -- rd current BSN
);
END dp_bsn_source_reg_v2;
ARCHITECTURE rtl OF dp_bsn_source_reg_v2 IS
CONSTANT c_bsn_w : NATURAL := st_init_bsn'LENGTH;
-- Define the actual size of the MM slave register
CONSTANT c_mm_reg : t_c_mem := (latency => 1,
adr_w => 2,
dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers
nof_dat => 2**2,
init_sl => '0');
-- Registers in mm_clk domain
SIGNAL mm_on : STD_LOGIC;
SIGNAL mm_on_pps : STD_LOGIC;
SIGNAL mm_on_ctrl : STD_LOGIC_VECTOR(1 DOWNTO 0); -- = mm_on_pps & mm_on
SIGNAL st_on_ctrl : STD_LOGIC_VECTOR(1 DOWNTO 0); -- = st_on_pps & st_on
SIGNAL mm_on_status : STD_LOGIC;
SIGNAL mm_nof_clk_per_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL mm_init_bsn : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0);
SIGNAL mm_init_bsn_wr : STD_LOGIC;
SIGNAL mm_current_bsn : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL mm_current_bsn_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS=>'0');
-- Registers in st_clk domain
BEGIN
------------------------------------------------------------------------------
-- MM register access in the mm_clk domain
-- . Hardcode the shared MM slave register directly in RTL instead of using
-- the common_reg_r_w instance. Directly using RTL is easier when the large
-- MM register has multiple different fields and with different read and
-- write options per field in one MM register.
------------------------------------------------------------------------------
p_mm_reg : PROCESS (mm_rst, mm_clk)
BEGIN
IF mm_rst = '1' THEN
-- Read access
sla_out <= c_mem_miso_rst;
-- Access event, register values
mm_on <= '0';
mm_on_pps <= '0';
mm_nof_clk_per_sync <= TO_UVEC(g_nof_clk_per_sync, c_word_w);
mm_init_bsn <= (OTHERS=>'0');
mm_init_bsn_wr <= '0';
mm_current_bsn_hi <= (OTHERS=>'0');
ELSIF rising_edge(mm_clk) THEN
-- Read access defaults
sla_out.rdval <= '0';
-- Access event defaults
mm_init_bsn_wr <= '0';
-- Write access: set register value
IF sla_in.wr = '1' THEN
CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS
-- Write Block Sync
WHEN 0 =>
mm_on <= sla_in.wrdata(0);
mm_on_pps <= sla_in.wrdata(1);
WHEN 1 =>
mm_nof_clk_per_sync <= sla_in.wrdata(31 DOWNTO 0);
-- Write init BSN
WHEN 2 =>
mm_init_bsn(31 DOWNTO 0) <= sla_in.wrdata(31 DOWNTO 0);
WHEN 3 =>
mm_init_bsn(63 DOWNTO 32) <= sla_in.wrdata(31 DOWNTO 0);
mm_init_bsn_wr <= '1';
WHEN OTHERS => NULL; -- not used MM addresses
END CASE;
-- Read access: get register value
ELSIF sla_in.rd = '1' THEN
sla_out <= c_mem_miso_rst; -- set unused rddata bits to '0' when read
sla_out.rdval <= '1'; -- c_mm_reg.latency = 1
CASE TO_UINT(sla_in.address(c_mm_reg.adr_w-1 DOWNTO 0)) IS
-- Read Block Sync
WHEN 0 =>
sla_out.rddata(0) <= mm_on_status;
sla_out.rddata(1) <= mm_on_pps;
WHEN 1 =>
sla_out.rddata(31 DOWNTO 0) <= mm_nof_clk_per_sync;
-- Read current BSN
WHEN 2 =>
sla_out.rddata(31 DOWNTO 0) <= mm_current_bsn(31 DOWNTO 0);
mm_current_bsn_hi <= mm_current_bsn(63 DOWNTO 32); -- first read low part and preserve high part
WHEN 3 =>
sla_out.rddata(31 DOWNTO 0) <= mm_current_bsn_hi;
WHEN OTHERS => NULL; -- not used MM addresses
END CASE;
END IF;
END IF;
END PROCESS;
------------------------------------------------------------------------------
-- Transfer register value between mm_clk and st_clk domain.
-- If the function of the register ensures that the value will not be used
-- immediately when it was set, then the transfer between the clock domains
-- can be done by wires only. Otherwise if the change in register value can
-- have an immediate effect then the bit or word value needs to be transfered
-- using:
--
-- . common_async --> for single-bit level signal
-- . common_spulse --> for single-bit pulse signal
-- . common_reg_cross_domain --> for a multi-bit (a word) signal
--
-- Typically always use a crossing component for the single bit signals (to
-- be on the save side) and only use a crossing component for the word
-- signals if it is necessary (to avoid using more logic than necessary).
------------------------------------------------------------------------------
no_cross : IF g_cross_clock_domain = FALSE GENERATE -- so mm_clk = st_clk
st_on <= mm_on;
st_on_pps <= mm_on_pps;
st_nof_clk_per_sync <= mm_nof_clk_per_sync;
st_init_bsn <= mm_init_bsn(c_bsn_w-1 DOWNTO 0);
p_st_clk : PROCESS(st_rst, st_clk)
BEGIN
IF st_rst='1' THEN
st_init_bsn <= TO_UVEC(0, c_bsn_w);
ELSIF rising_edge(st_clk) THEN
IF mm_init_bsn_wr='1' THEN
st_init_bsn <= mm_init_bsn(c_bsn_w-1 DOWNTO 0); -- use wr of mm_init_bsn high part for in_new to ensure proper transfer of double word
END IF;
END IF;
END PROCESS;
mm_current_bsn(c_bsn_w-1 DOWNTO 0) <= st_current_bsn; -- MM user may read current_bsn twice to avoid small chance that the high part of the double word changed (i.e. incremented)
END GENERATE; -- no_cross
gen_cross : IF g_cross_clock_domain = TRUE GENERATE
-- Block sync registers
u_dp_on_ctrl : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => mm_rst,
in_clk => mm_clk,
in_dat => mm_on_ctrl,
in_done => OPEN, -- pulses when no more pending in_new
out_rst => st_rst,
out_clk => st_clk,
out_dat => st_on_ctrl,
out_new => OPEN
);
mm_on_ctrl(0) <= mm_on;
mm_on_ctrl(1) <= mm_on_pps;
st_on <= st_on_ctrl(0);
st_on_pps <= st_on_ctrl(1);
u_mm_on_status : ENTITY common_lib.common_async
GENERIC MAP (
g_rst_level => '0'
)
PORT MAP (
rst => mm_rst,
clk => mm_clk,
din => st_on_status,
dout => mm_on_status
);
-- write occurs with sufficient margin before it is used, still use common_reg_cross_domain nonetheless
u_nof_block_per_sync : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => mm_rst,
in_clk => mm_clk,
in_dat => mm_nof_clk_per_sync,
in_done => OPEN, -- pulses when no more pending in_new
out_rst => st_rst,
out_clk => st_clk,
out_dat => st_nof_clk_per_sync,
out_new => OPEN
);
-- write occurs with sufficient margin before it is used, still use common_reg_cross_domain nonetheless
u_init_bsn : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => mm_rst,
in_clk => mm_clk,
in_new => mm_init_bsn_wr, -- use wr of mm_init_bsn high part for in_new to ensure proper transfer of double word
in_dat => mm_init_bsn(c_bsn_w-1 DOWNTO 0),
in_done => OPEN, -- pulses when no more pending in_new
out_rst => st_rst,
out_clk => st_clk,
out_dat => st_init_bsn,
out_new => OPEN
);
-- thanks to mm_current_bsn_hi the double word can be read reliably
u_current_bsn : ENTITY common_lib.common_reg_cross_domain
PORT MAP (
in_rst => st_rst,
in_clk => st_clk,
in_new => '1', -- could use t_dp_sosi sop here to indicate in_new, but using default '1' is fine too
in_dat => st_current_bsn,
in_done => OPEN, -- pulses when no more pending in_new
out_rst => mm_rst,
out_clk => mm_clk,
out_dat => mm_current_bsn(c_bsn_w-1 DOWNTO 0),
out_new => OPEN
);
END GENERATE; -- gen_cross
END rtl;
...@@ -41,7 +41,7 @@ USE work.dp_stream_pkg.ALL; ...@@ -41,7 +41,7 @@ USE work.dp_stream_pkg.ALL;
ENTITY dp_bsn_source_v2 IS ENTITY dp_bsn_source_v2 IS
GENERIC ( GENERIC (
g_block_size : NATURAL := 256; g_block_size : NATURAL := 256;
g_nof_block_per_sync : NATURAL := 8; g_nof_clk_per_sync : NATURAL := 200 * 10**6;
g_bsn_w : NATURAL := 48; g_bsn_w : NATURAL := 48;
g_offset_w : NATURAL := 4 g_offset_w : NATURAL := 4
); );
...@@ -56,7 +56,7 @@ ENTITY dp_bsn_source_v2 IS ...@@ -56,7 +56,7 @@ ENTITY dp_bsn_source_v2 IS
dp_on_status : OUT STD_LOGIC; dp_on_status : OUT STD_LOGIC;
init_bsn : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); init_bsn : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
nof_block_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_block_per_sync, c_word_w); nof_clk_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_clk_per_sync, c_word_w);
offset_bsn : IN STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0) := (OTHERS=>'0'); offset_bsn : IN STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0) := (OTHERS=>'0');
--offset_bsn : IN STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0) := TO_UVEC(4, g_offset_w); --offset_bsn : IN STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0) := TO_UVEC(4, g_offset_w);
...@@ -79,8 +79,8 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS ...@@ -79,8 +79,8 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS
SIGNAL block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0); SIGNAL block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0);
SIGNAL nxt_block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0); SIGNAL nxt_block_size_cnt : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0);
SIGNAL block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); --SIGNAL block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL nxt_block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); --SIGNAL nxt_block_cnt : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL i_src_out : t_dp_sosi := c_dp_sosi_init; SIGNAL i_src_out : t_dp_sosi := c_dp_sosi_init;
SIGNAL nxt_src_out : t_dp_sosi; SIGNAL nxt_src_out : t_dp_sosi;
...@@ -89,14 +89,19 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS ...@@ -89,14 +89,19 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS
SIGNAL i_dp_on_status : STD_LOGIC; SIGNAL i_dp_on_status : STD_LOGIC;
SIGNAL nxt_offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0); SIGNAL nxt_offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0);
SIGNAL offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0); SIGNAL offset_bsn_cnt : STD_LOGIC_VECTOR(g_offset_w-1 DOWNTO 0);
SIGNAL nxt_clk_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL clk_cnt : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL nxt_sync : STD_LOGIC;
SIGNAL sync : STD_LOGIC;
BEGIN BEGIN
src_out <= i_src_out; src_out <= i_src_out;
dp_on_status <= i_dp_on_status; dp_on_status <= i_dp_on_status;
p_state : PROCESS(state, prev_state, dp_on, dp_on_pps, pps, block_size_cnt, block_cnt, nof_block_per_sync, init_bsn, i_src_out, i_dp_on_status, offset_bsn_cnt) p_state : PROCESS(state, prev_state, dp_on, dp_on_pps, pps, block_size_cnt, clk_cnt, init_bsn, i_src_out, i_dp_on_status, offset_bsn_cnt)
BEGIN BEGIN
nxt_state <= state; nxt_state <= state;
nxt_src_out <= i_src_out; nxt_src_out <= i_src_out;
...@@ -105,8 +110,15 @@ BEGIN ...@@ -105,8 +110,15 @@ BEGIN
nxt_src_out.sop <= '0'; nxt_src_out.sop <= '0';
nxt_src_out.eop <= '0'; nxt_src_out.eop <= '0';
nxt_block_size_cnt <= block_size_cnt; nxt_block_size_cnt <= block_size_cnt;
nxt_block_cnt <= block_cnt; nxt_clk_cnt <= INCR_UVEC(clk_cnt, 1);
nxt_sync <= sync;
nxt_dp_on_status <= i_dp_on_status; nxt_dp_on_status <= i_dp_on_status;
nxt_offset_bsn_cnt <= offset_bsn_cnt;
IF UNSIGNED(clk_cnt) = UNSIGNED(nof_clk_per_sync) - 1 THEN
nxt_clk_cnt <= (OTHERS=>'0');
nxt_sync <= '1'; -- set sync signal on next sop
END IF;
CASE state IS CASE state IS
...@@ -115,11 +127,6 @@ BEGIN ...@@ -115,11 +127,6 @@ BEGIN
nxt_src_out.valid <= '1'; nxt_src_out.valid <= '1';
nxt_state <= s_dp_on_sop; nxt_state <= s_dp_on_sop;
nxt_block_size_cnt <= INCR_UVEC(block_size_cnt, 1); nxt_block_size_cnt <= INCR_UVEC(block_size_cnt, 1);
IF UNSIGNED(block_cnt) = UNSIGNED(nof_block_per_sync) -1 THEN
nxt_block_cnt <= (OTHERS=>'0');
ELSE
nxt_block_cnt <= INCR_UVEC(block_cnt, 1);
END IF;
IF dp_on = '0' THEN IF dp_on = '0' THEN
nxt_state <= s_dp_off; nxt_state <= s_dp_off;
END IF; END IF;
...@@ -140,14 +147,16 @@ BEGIN ...@@ -140,14 +147,16 @@ BEGIN
IF prev_state = s_dp_on_eop THEN IF prev_state = s_dp_on_eop THEN
nxt_src_out.bsn(g_bsn_w-1 DOWNTO 0) <= INCR_UVEC(i_src_out.bsn(g_bsn_w-1 DOWNTO 0), 1); nxt_src_out.bsn(g_bsn_w-1 DOWNTO 0) <= INCR_UVEC(i_src_out.bsn(g_bsn_w-1 DOWNTO 0), 1);
END IF; END IF;
IF UNSIGNED(block_cnt) = UNSIGNED(c_block_cnt_zero) THEN IF sync = '1' THEN
nxt_src_out.sync <= '1'; nxt_src_out.sync <= '1';
nxt_sync <= '0'; -- clear sync if set
END IF; END IF;
WHEN s_dp_off => WHEN s_dp_off =>
nxt_dp_on_status <= '0'; nxt_dp_on_status <= '0';
nxt_block_cnt <= (OTHERS=>'0');
nxt_src_out.bsn <= RESIZE_DP_BSN(init_bsn); nxt_src_out.bsn <= RESIZE_DP_BSN(init_bsn);
nxt_sync <= '0'; -- clear sync if set
nxt_clk_cnt <= (OTHERS=>'0');
IF dp_on = '1' THEN IF dp_on = '1' THEN
IF dp_on_pps = '1' THEN IF dp_on_pps = '1' THEN
IF pps = '1' THEN IF pps = '1' THEN
...@@ -183,7 +192,9 @@ BEGIN ...@@ -183,7 +192,9 @@ BEGIN
prev_state <= s_init; prev_state <= s_init;
state <= s_init; state <= s_init;
i_src_out <= c_dp_sosi_rst; i_src_out <= c_dp_sosi_rst;
block_cnt <= (OTHERS=>'0'); --block_cnt <= (OTHERS=>'0');
clk_cnt <= (OTHERS=>'0');
sync <= '0';
block_size_cnt <= (OTHERS=>'0'); block_size_cnt <= (OTHERS=>'0');
i_dp_on_status <= '0'; i_dp_on_status <= '0';
offset_bsn_cnt <= (OTHERS=>'0'); offset_bsn_cnt <= (OTHERS=>'0');
...@@ -191,7 +202,9 @@ BEGIN ...@@ -191,7 +202,9 @@ BEGIN
prev_state <= state; prev_state <= state;
state <= nxt_state; state <= nxt_state;
i_src_out <= nxt_src_out; i_src_out <= nxt_src_out;
block_cnt <= nxt_block_cnt; --block_cnt <= nxt_block_cnt;
clk_cnt <= nxt_clk_cnt;
sync <= nxt_sync;
block_size_cnt <= nxt_block_size_cnt; block_size_cnt <= nxt_block_size_cnt;
i_dp_on_status <= nxt_dp_on_status; i_dp_on_status <= nxt_dp_on_status;
offset_bsn_cnt <= nxt_offset_bsn_cnt; offset_bsn_cnt <= nxt_offset_bsn_cnt;
......
...@@ -33,7 +33,7 @@ ENTITY mms_dp_bsn_source_v2 IS ...@@ -33,7 +33,7 @@ ENTITY mms_dp_bsn_source_v2 IS
GENERIC ( GENERIC (
g_cross_clock_domain : BOOLEAN := TRUE; -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain g_cross_clock_domain : BOOLEAN := TRUE; -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain
g_block_size : NATURAL := 256; -- 1024 samples @ 800M / 4 = 256 4 sample words @ 200 M g_block_size : NATURAL := 256; -- 1024 samples @ 800M / 4 = 256 4 sample words @ 200 M
g_nof_block_per_sync : NATURAL := 8; -- 800M/1024 = 781250; g_nof_clk_per_sync : NATURAL := 200 * 10**6; -- ;
g_bsn_w : NATURAL := 48 g_bsn_w : NATURAL := 48
); );
PORT ( PORT (
...@@ -58,7 +58,7 @@ ARCHITECTURE str OF mms_dp_bsn_source_v2 IS ...@@ -58,7 +58,7 @@ ARCHITECTURE str OF mms_dp_bsn_source_v2 IS
SIGNAL dp_on : STD_LOGIC; SIGNAL dp_on : STD_LOGIC;
SIGNAL dp_on_pps : STD_LOGIC; SIGNAL dp_on_pps : STD_LOGIC;
SIGNAL nof_block_per_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); SIGNAL nof_clk_per_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL init_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); SIGNAL init_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL i_bs_sosi : t_dp_sosi; SIGNAL i_bs_sosi : t_dp_sosi;
...@@ -71,10 +71,10 @@ BEGIN ...@@ -71,10 +71,10 @@ BEGIN
bs_sosi <= i_bs_sosi; bs_sosi <= i_bs_sosi;
u_mm_reg : ENTITY work.dp_bsn_source_reg u_mm_reg : ENTITY work.dp_bsn_source_reg_v2
GENERIC MAP ( GENERIC MAP (
g_cross_clock_domain => g_cross_clock_domain, g_cross_clock_domain => g_cross_clock_domain,
g_nof_block_per_sync => g_nof_block_per_sync g_nof_clk_per_sync => g_nof_clk_per_sync
) )
PORT MAP ( PORT MAP (
-- Clocks and reset -- Clocks and reset
...@@ -91,7 +91,7 @@ BEGIN ...@@ -91,7 +91,7 @@ BEGIN
st_on => dp_on, st_on => dp_on,
st_on_pps => dp_on_pps, st_on_pps => dp_on_pps,
st_on_status => dp_on_status, st_on_status => dp_on_status,
st_nof_block_per_sync => nof_block_per_sync, st_nof_clk_per_sync => nof_clk_per_sync,
st_init_bsn => init_bsn, st_init_bsn => init_bsn,
st_current_bsn => capture_bsn st_current_bsn => capture_bsn
); );
...@@ -99,7 +99,7 @@ BEGIN ...@@ -99,7 +99,7 @@ BEGIN
u_bsn_source : ENTITY work.dp_bsn_source_v2 u_bsn_source : ENTITY work.dp_bsn_source_v2
GENERIC MAP ( GENERIC MAP (
g_block_size => g_block_size, g_block_size => g_block_size,
g_nof_block_per_sync => g_nof_block_per_sync, g_nof_clk_per_sync => g_nof_clk_per_sync,
g_bsn_w => g_bsn_w g_bsn_w => g_bsn_w
) )
PORT MAP ( PORT MAP (
...@@ -111,7 +111,7 @@ BEGIN ...@@ -111,7 +111,7 @@ BEGIN
dp_on_pps => dp_on_pps, dp_on_pps => dp_on_pps,
dp_on_status => dp_on_status, dp_on_status => dp_on_status,
init_bsn => init_bsn, init_bsn => init_bsn,
nof_block_per_sync => nof_block_per_sync, nof_clk_per_sync => nof_clk_per_sync,
-- Streaming -- Streaming
src_out => i_bs_sosi src_out => i_bs_sosi
); );
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
-- . sop, eop are verified automatically -- . sop, eop are verified automatically
-- . sync and bsn are verified automatically -- . sync and bsn are verified automatically
-- and then manually verify on/off in Wave window -- and then manually verify on/off in Wave window
LIBRARY IEEE, common_lib, dp_lib; LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL; USE IEEE.NUMERIC_STD.ALL;
...@@ -40,13 +40,13 @@ END tb_dp_bsn_source_v2; ...@@ -40,13 +40,13 @@ END tb_dp_bsn_source_v2;
ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS
CONSTANT c_clk_period : TIME := 10 ns; CONSTANT c_clk_period : TIME := 10 ns;
CONSTANT c_block_size : NATURAL := 31; CONSTANT c_block_size : NATURAL := 32; -- 31;
--CONSTANT c_block_size : NATURAL := 32; CONSTANT c_bsn_w : NATURAL := 31; -- 16;
CONSTANT c_bsn_w : NATURAL := 16; CONSTANT c_clk_per_sync : NATURAL := 240; -- 200 * 10**6;
CONSTANT c_sync_period : NATURAL := 7; CONSTANT c_sync_period : NATURAL := 8;
CONSTANT c_sync_offset : NATURAL := 3; -- must be < c_sync_period for proc_dp_verify_sync CONSTANT c_sync_offset : NATURAL := 0; -- 3; -- must be < c_sync_period for proc_dp_verify_sync
-- The state name tells what kind of test is being done -- The state name tells what kind of test is being done
TYPE t_state_enum IS ( TYPE t_state_enum IS (
s_disable, s_disable,
...@@ -55,23 +55,25 @@ ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS ...@@ -55,23 +55,25 @@ ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS
); );
SIGNAL tb_state : t_state_enum; SIGNAL tb_state : t_state_enum;
SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL rst : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '1';
SIGNAL clk : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1';
SIGNAL pps : STD_LOGIC; SIGNAL pps : STD_LOGIC;
-- DUT -- DUT
SIGNAL dp_on : STD_LOGIC := '0'; SIGNAL dp_on : STD_LOGIC := '0';
SIGNAL dp_on_pps : STD_LOGIC := '0'; SIGNAL dp_on_pps : STD_LOGIC := '0';
SIGNAL init_bsn : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); SIGNAL init_bsn : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL bs_sosi : t_dp_sosi; SIGNAL bs_sosi : t_dp_sosi;
-- Verify -- Verify
SIGNAL verify_sync : STD_LOGIC := '1'; SIGNAL verify_sync : STD_LOGIC := '1';
SIGNAL hold_bs_sop : STD_LOGIC; SIGNAL hold_bs_sop : STD_LOGIC;
SIGNAL tb_bsn_cnt : INTEGER := 0;
BEGIN BEGIN
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
...@@ -79,32 +81,32 @@ BEGIN ...@@ -79,32 +81,32 @@ BEGIN
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
rst <= '1', '0' AFTER c_clk_period*7; rst <= '1', '0' AFTER c_clk_period*7;
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2; clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
-- MM control -- MM control
p_mm : PROCESS p_mm : PROCESS
BEGIN BEGIN
tb_end <= '0'; tb_end <= '0';
tb_state <= s_disable; tb_state <= s_disable;
pps <= '0'; pps <= '0';
dp_on <= '0'; dp_on <= '0';
dp_on_pps <= '0'; dp_on_pps <= '0';
init_bsn <= TO_UVEC(c_sync_offset, c_bsn_w); init_bsn <= TO_UVEC(c_sync_offset, c_bsn_w);
-- Get synchronous to clk -- Get synchronous to clk
proc_common_wait_until_low(clk, rst); proc_common_wait_until_low(clk, rst);
proc_common_wait_some_cycles(clk, 500); proc_common_wait_some_cycles(clk, 500);
-- Start by making dp_on high -- Start by making dp_on high
tb_state <= s_start; tb_state <= s_start;
dp_on <= '1'; dp_on <= '1';
proc_common_wait_some_cycles(clk, 2000); proc_common_wait_some_cycles(clk, 2000);
-- Stop by making dp_on low -- Stop by making dp_on low
tb_state <= s_disable; tb_state <= s_disable;
dp_on <= '0'; dp_on <= '0';
proc_common_wait_some_cycles(clk, 1000); proc_common_wait_some_cycles(clk, 1000);
-- Now start on PPS -- Now start on PPS
tb_state <= s_pps_start; tb_state <= s_pps_start;
dp_on_pps <= '1'; dp_on_pps <= '1';
...@@ -114,24 +116,24 @@ BEGIN ...@@ -114,24 +116,24 @@ BEGIN
proc_common_wait_some_cycles(clk, 1); proc_common_wait_some_cycles(clk, 1);
pps <= '0'; pps <= '0';
proc_common_wait_some_cycles(clk, 1000); proc_common_wait_some_cycles(clk, 1000);
-- Stop by making dp_on low -- Stop by making dp_on low
tb_state <= s_disable; tb_state <= s_disable;
dp_on <= '0'; dp_on <= '0';
dp_on_pps <= '0'; --No PPS trigger next time dp_on_pps <= '0'; --No PPS trigger next time
proc_common_wait_some_cycles(clk, 1000); proc_common_wait_some_cycles(clk, 1000);
-- Start by making dp_on high -- Start by making dp_on high
tb_state <= s_start; tb_state <= s_start;
dp_on <= '1'; dp_on <= '1';
proc_common_wait_some_cycles(clk, 2500); proc_common_wait_some_cycles(clk, 2500);
-- Stop by making dp_on low -- Stop by making dp_on low
tb_state <= s_disable; tb_state <= s_disable;
dp_on <= '0'; dp_on <= '0';
dp_on_pps <= '0'; dp_on_pps <= '0';
proc_common_wait_some_cycles(clk, 1000); proc_common_wait_some_cycles(clk, 1000);
-- Now start on next PPS and continue forever -- Now start on next PPS and continue forever
init_bsn <= TO_UVEC(c_sync_offset, c_bsn_w); init_bsn <= TO_UVEC(c_sync_offset, c_bsn_w);
tb_state <= s_pps_start; tb_state <= s_pps_start;
...@@ -141,28 +143,28 @@ BEGIN ...@@ -141,28 +143,28 @@ BEGIN
pps <= '1'; pps <= '1';
proc_common_wait_some_cycles(clk, 1); proc_common_wait_some_cycles(clk, 1);
pps <= '0'; pps <= '0';
proc_common_wait_some_cycles(clk, 10000); proc_common_wait_some_cycles(clk, 10000);
tb_end <= '1'; tb_end <= '1';
WAIT; WAIT;
END PROCESS; END PROCESS;
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Verification -- Verification
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
proc_dp_verify_sop_and_eop(clk, bs_sosi.valid, bs_sosi.sop, bs_sosi.eop, hold_bs_sop); -- Verify that sop and eop come in pairs proc_dp_verify_sop_and_eop(clk, bs_sosi.valid, bs_sosi.sop, bs_sosi.eop, hold_bs_sop); -- Verify that sop and eop come in pairs
proc_dp_verify_sync(c_sync_period, c_sync_offset, clk, verify_sync, bs_sosi.sync, bs_sosi.sop, bs_sosi.bsn); -- Verify sync at sop and at expected BSN proc_dp_verify_sync_v2(c_sync_period, c_sync_offset, clk, verify_sync, bs_sosi.sync, bs_sosi.sop, bs_sosi.bsn, tb_bsn_cnt); -- Verify sync at sop and at expected BSN
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- DUT: dp_bsn_source_v2 -- DUT: dp_bsn_source_v2
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
dut : ENTITY work.dp_bsn_source_v2 dut : ENTITY work.dp_bsn_source_v2
GENERIC MAP ( GENERIC MAP (
g_block_size => c_block_size, g_block_size => c_block_size,
g_nof_block_per_sync => c_sync_period, g_nof_clk_per_sync => c_clk_per_sync,
g_bsn_w => c_bsn_w g_bsn_w => c_bsn_w
) )
PORT MAP ( PORT MAP (
...@@ -176,5 +178,5 @@ BEGIN ...@@ -176,5 +178,5 @@ BEGIN
-- Streaming -- Streaming
src_out => bs_sosi src_out => bs_sosi
); );
END tb; END tb;
This diff is collapsed.
...@@ -161,7 +161,7 @@ BEGIN ...@@ -161,7 +161,7 @@ BEGIN
GENERIC MAP ( GENERIC MAP (
g_cross_clock_domain => TRUE, -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain g_cross_clock_domain => TRUE, -- use FALSE when mm_clk and st_clk are the same, else use TRUE to cross the clock domain
g_block_size => c_block_size, g_block_size => c_block_size,
g_nof_block_per_sync => 1, -- overrule via MM write g_nof_clk_per_sync => 200 * 10**6, -- overrule via MM write
g_bsn_w => c_dp_stream_bsn_w g_bsn_w => c_dp_stream_bsn_w
) )
PORT MAP ( PORT MAP (
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment