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

Ported diag_block_gen.vhd to RadioHDL.

parent 651ac102
Branches
No related tags found
No related merge requests found
...@@ -26,7 +26,7 @@ synth_files = ...@@ -26,7 +26,7 @@ synth_files =
$UNB/Firmware/modules/Lofar/diag/src/vhdl/mms_diag_wg_wideband.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/mms_diag_wg_wideband.vhd
$UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_data_buffer.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_data_buffer.vhd
$UNB/Firmware/modules/Lofar/diag/src/vhdl/mms_diag_data_buffer.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/mms_diag_data_buffer.vhd
$UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_block_gen.vhd src/vhdl/diag_block_gen.vhd
$UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_block_gen_reg.vhd $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_block_gen_reg.vhd
src/vhdl/mms_diag_block_gen.vhd src/vhdl/mms_diag_block_gen.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- 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/>.
--
-------------------------------------------------------------------------------
library IEEE, common_lib, dp_lib;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use common_lib.common_pkg.ALL;
use work.diag_pkg.ALL;
use dp_lib.dp_stream_pkg.ALL;
entity diag_block_gen is
generic (
g_blk_sync : boolean := false; -- when true use active sync during entire block, else use single clock cycle sync pulse
g_buf_dat_w : natural := 32;
g_buf_addr_w : natural := 7
);
port (
rst : in std_logic;
clk : in std_logic;
buf_addr : out std_logic_vector(g_buf_addr_w-1 downto 0);
buf_rden : out std_logic;
buf_rddat : in std_logic_vector(g_buf_dat_w-1 downto 0);
buf_rdval : in std_logic;
ctrl : in t_diag_block_gen;
en_sync : in std_logic := '1';
out_siso : in t_dp_siso := c_dp_siso_rdy;
out_sosi : out t_dp_sosi
);
end diag_block_gen;
architecture rtl of diag_block_gen is
type state_type is (s_idle, s_block, s_gap);
type reg_type is record
blk_en : std_logic; -- enable at block level
blk_xon : std_logic; -- siso.xon at block level, the BG continues but the sosi control depend on xon (the BG does not support siso.ready)
blk_sync : std_logic; -- block sync alternative of the pulse sync
pls_sync : std_logic; -- pulse sync
valid : std_logic;
sop : std_logic;
eop : std_logic;
rd_ena : std_logic;
samples_cnt : natural range 0 to 2**c_diag_bg_samples_per_packet_w-1;
blocks_cnt : natural range 0 to 2**c_diag_bg_blocks_per_sync_w-1;
bsn_cnt : std_logic_vector(c_diag_bg_bsn_init_w-1 downto 0); -- = c_dp_stream_bsn_w
mem_cnt : natural range 0 to 2**g_buf_addr_w-1;
state : state_type; -- The state machine.
end record;
signal r, rin : reg_type;
signal out_sosi_i : t_dp_sosi := c_dp_sosi_rst; -- Signal used to assign reset values to output
begin
p_comb : process(r, rst, ctrl, en_sync, out_siso)
variable v : reg_type;
variable v_samples_per_packet : natural;
variable v_gapsize : natural;
variable v_blocks_per_sync : natural;
variable v_mem_low_adrs : natural;
variable v_mem_high_adrs : natural;
begin
v_samples_per_packet := TO_UINT(ctrl.samples_per_packet);
v_gapsize := TO_UINT(ctrl.gapsize);
v_blocks_per_sync := TO_UINT(ctrl.blocks_per_sync);
v_mem_low_adrs := TO_UINT(ctrl.mem_low_adrs);
v_mem_high_adrs := TO_UINT(ctrl.mem_high_adrs);
v := r; -- default hold all r fields
v.pls_sync := '0';
v.valid := '0';
v.sop := '0';
v.eop := '0';
v.rd_ena := '0';
-- Control block generator enable
if ctrl.enable='0' then
v.blk_en := '0'; -- disable immediately
elsif ctrl.enable_sync='0' then
v.blk_en := '1'; -- enable immediately or keep enabled
elsif en_sync='1' then
v.blk_en := '1'; -- enable at input sync pulse or keep enabled
end if;
-- The pulse sync is high at the sop of the first block, the block sync is high during the entire block until the eop
if r.eop='1' then
v.blk_sync := '0';
end if;
-- Increment the block sequence number counter after each block
if r.eop='1' then
v.bsn_cnt := incr_uvec(r.bsn_cnt, 1);
end if;
case r.state is
when s_idle =>
v.blk_xon := out_siso.xon;
v.blk_sync := '0';
v.samples_cnt := 0;
v.blocks_cnt := 0;
v.bsn_cnt := ctrl.bsn_init;
v.mem_cnt := v_mem_low_adrs;
if(r.blk_en = '1') then -- Wait until enabled
v.rd_ena := '1';
v.state := s_block;
end if;
when s_block =>
v.rd_ena := '1';
if(r.samples_cnt = 0 and r.blocks_cnt = 0) then
v.pls_sync := '1'; -- Always start with a pulse sync
v.blk_sync := '1';
v.sop := '1';
v.samples_cnt := v.samples_cnt + 1;
elsif(r.samples_cnt = 0) then
v.sop := '1';
v.samples_cnt := v.samples_cnt + 1;
elsif(r.samples_cnt >= v_samples_per_packet-1 and v_gapsize = 0 and r.blocks_cnt >= v_blocks_per_sync-1) then
v.eop := '1';
v.samples_cnt := 0;
v.blocks_cnt := 0;
elsif(r.samples_cnt >= v_samples_per_packet-1 and v_gapsize = 0) then
v.eop := '1';
v.samples_cnt := 0;
v.blocks_cnt := r.blocks_cnt + 1;
elsif(r.samples_cnt >= v_samples_per_packet-1) then
v.eop := '1';
v.samples_cnt := 0;
v.rd_ena := '0';
v.state := s_gap;
else
v.samples_cnt := r.samples_cnt + 1;
end if;
v.valid := '1';
if(r.mem_cnt >= v_mem_high_adrs) then
v.mem_cnt := v_mem_low_adrs;
else
v.mem_cnt := r.mem_cnt + 1;
end if;
if(v.eop = '1' and r.blk_en = '0') then
v.state := s_idle; -- accept disable after eop, not during block
end if;
if(r.eop = '1') then
v.blk_xon := out_siso.xon; -- accept XOFF after eop, not during block
end if;
when s_gap =>
if(r.samples_cnt >= v_gapsize-1 and r.blocks_cnt >= v_blocks_per_sync-1) then
v.samples_cnt := 0;
v.blocks_cnt := 0;
v.rd_ena := '1';
v.state := s_block;
elsif(r.samples_cnt >= v_gapsize-1) then
v.samples_cnt := 0;
v.blocks_cnt := r.blocks_cnt + 1;
v.rd_ena := '1';
v.state := s_block;
else
v.samples_cnt := r.samples_cnt + 1;
end if;
if(r.blk_en = '0') then
v.state := s_idle;
end if;
v.blk_xon := out_siso.xon;
when others =>
v.state := s_idle;
end case;
if(rst = '1') then
v.blk_en := '0';
v.blk_xon := '0';
v.blk_sync := '0';
v.pls_sync := '0';
v.valid := '0';
v.sop := '0';
v.eop := '0';
v.rd_ena := '0';
v.samples_cnt := 0;
v.blocks_cnt := 0;
v.bsn_cnt := (others=>'0');
v.mem_cnt := 0;
v.state := s_idle;
end if;
rin <= v;
end process;
p_regs : process(rst, clk)
begin
if rising_edge(clk) then
r <= rin;
end if;
end process;
-- Connect to the outside world
out_sosi_i.sop <= r.sop and r.blk_xon;
out_sosi_i.eop <= r.eop and r.blk_xon;
out_sosi_i.sync <= r.pls_sync and r.blk_xon when g_blk_sync=false else r.blk_sync and r.blk_xon;
out_sosi_i.valid <= r.valid and r.blk_xon;
out_sosi_i.bsn <= r.bsn_cnt;
out_sosi_i.re <= RESIZE_DP_DSP_DATA(buf_rddat(g_buf_dat_w/2-1 downto 0)); -- treat as signed
out_sosi_i.im <= RESIZE_DP_DSP_DATA(buf_rddat(g_buf_dat_w-1 downto g_buf_dat_w/2)); -- treat as signed
out_sosi_i.data <= RESIZE_DP_DATA( buf_rddat(g_buf_dat_w-1 downto 0)); -- treat as unsigned
out_sosi <= out_sosi_i;
buf_addr <= TO_UVEC(r.mem_cnt, g_buf_addr_w);
buf_rden <= r.rd_ena;
end rtl;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment