Commit 5c8532a5 authored by Maciej Lipinski's avatar Maciej Lipinski

Adding WR transmission module

it contains streamers as well as a WB-accessible registers for:
- reading/controling statistics (module to be added)
- debugging
- controlling streamers, e.g. reset sequence
parent 56e6762e
files = ["wr_transmission_wbgen2_pkg.vhd",
"xwr_transmission.vhd",
"wr_transmission_pkg.vhd",
"wr_transmission_wb.vhd"]
\ No newline at end of file
#!/bin/bash
wbgen2 -D ./wb_doc.html -p wr_transmission_wbgen2_pkg.vhd -H record -V wr_transmission_wb.vhd --cstyle defines --lang vhdl -K ../../testbench/include/regs/wr_transmission_wb.vh wr_transmission_wb.wb
\ No newline at end of file
-------------------------------------------------------------------------------
-- Title : Btrain over White Rabbit
-- Project : Btrain
-------------------------------------------------------------------------------
-- File : BtrainFMC_pkg.vhd
-- Author : Maciej Lipinski
-- Company : CERN
-- Created : 2016-05-31
-- Last update: 2016-05-31
-- Platform : FPGA-generics
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2016 CERN/BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source 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 Lesser General Public License for more
-- details
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2016-05-30 1.0 mlipinsk Created
library ieee;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all; -- needed for t_wishbone_slave_in, etc
use work.streamers_pkg.all; -- needed for streamers
use work.wr_fabric_pkg.all; -- neede for :t_wrf_source_in, etc
use work.wr_transmission_wbgen2_pkg.all;
package wr_transmission_pkg is
component xwr_transmission is
generic (
g_data_width : integer := 32
);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
src_i : in t_wrf_source_in;
src_o : out t_wrf_source_out;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
tx_data_i : in std_logic_vector(g_data_width-1 downto 0);
tx_valid_i : in std_logic;
tx_dreq_o : out std_logic;
tx_last_i : in std_logic := '1';
tx_flush_i : in std_logic := '0';
rx_first_o : out std_logic;
rx_last_o : out std_logic;
rx_data_o : out std_logic_vector(g_data_width-1 downto 0);
rx_valid_o : out std_logic;
rx_dreq_i : in std_logic;
clk_ref_i : in std_logic := '0';
tm_time_valid_i : in std_logic := '0';
tm_tai_i : in std_logic_vector(39 downto 0) := x"0000000000";
tm_cycles_i : in std_logic_vector(27 downto 0) := x"0000000";
wb_slave_i : in t_wishbone_slave_in := cc_dummy_slave_in;
wb_slave_o : out t_wishbone_slave_out
);
end component;
end package;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Transmission control and debug
---------------------------------------------------------------------------------------
-- File : wr_transmission_wb.vhd
-- Author : auto-generated by wbgen2 from wr_transmission_wb.wb
-- Created : Tue May 31 08:48:29 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_transmission_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wr_transmission_wbgen2_pkg.all;
entity wr_transmission_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
regs_i : in t_wr_transmission_in_registers;
regs_o : out t_wr_transmission_out_registers
);
end wr_transmission_wb;
architecture syn of wr_transmission_wb is
signal wr_transmission_rxctrl_rst_cnt_dly0 : std_logic ;
signal wr_transmission_rxctrl_rst_cnt_int : std_logic ;
signal wr_transmission_rxctrl_rx_rst_latency_stats_dly0 : std_logic ;
signal wr_transmission_rxctrl_rx_rst_latency_stats_int : std_logic ;
signal wr_transmission_dbg_ctrl_mux_int : std_logic ;
signal wr_transmission_dbg_ctrl_start_byte_int : std_logic_vector(7 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
wr_transmission_rxctrl_rst_cnt_int <= '0';
wr_transmission_rxctrl_rx_rst_latency_stats_int <= '0';
wr_transmission_dbg_ctrl_mux_int <= '0';
wr_transmission_dbg_ctrl_start_byte_int <= "00000000";
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
wr_transmission_rxctrl_rst_cnt_int <= '0';
wr_transmission_rxctrl_rx_rst_latency_stats_int <= '0';
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
wr_transmission_rxctrl_rst_cnt_int <= wrdata_reg(0);
wr_transmission_rxctrl_rx_rst_latency_stats_int <= wrdata_reg(1);
end if;
rddata_reg(0) <= '0';
rddata_reg(1) <= '0';
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.rx_stat_rx_loss_cnt_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
wr_transmission_dbg_ctrl_mux_int <= wrdata_reg(0);
wr_transmission_dbg_ctrl_start_byte_int <= wrdata_reg(15 downto 8);
end if;
rddata_reg(0) <= wr_transmission_dbg_ctrl_mux_int;
rddata_reg(15 downto 8) <= wr_transmission_dbg_ctrl_start_byte_int;
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.dbg_data_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- Reset loss count
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
wr_transmission_rxctrl_rst_cnt_dly0 <= '0';
regs_o.rxctrl_rst_cnt_o <= '0';
elsif rising_edge(clk_sys_i) then
wr_transmission_rxctrl_rst_cnt_dly0 <= wr_transmission_rxctrl_rst_cnt_int;
regs_o.rxctrl_rst_cnt_o <= wr_transmission_rxctrl_rst_cnt_int and (not wr_transmission_rxctrl_rst_cnt_dly0);
end if;
end process;
-- Reset latency statistics
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
wr_transmission_rxctrl_rx_rst_latency_stats_dly0 <= '0';
regs_o.rxctrl_rx_rst_latency_stats_o <= '0';
elsif rising_edge(clk_sys_i) then
wr_transmission_rxctrl_rx_rst_latency_stats_dly0 <= wr_transmission_rxctrl_rx_rst_latency_stats_int;
regs_o.rxctrl_rx_rst_latency_stats_o <= wr_transmission_rxctrl_rx_rst_latency_stats_int and (not wr_transmission_rxctrl_rx_rst_latency_stats_dly0);
end if;
end process;
-- WR Streamer frame loss count
-- Debug Tx or Rx
regs_o.dbg_ctrl_mux_o <= wr_transmission_dbg_ctrl_mux_int;
-- Debug Start byte
regs_o.dbg_ctrl_start_byte_o <= wr_transmission_dbg_ctrl_start_byte_int;
-- Debug content
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "WR Transmission control and debug";
description ="dd";
prefix = "wr_transmission";
hdl_entity = "wr_transmission_wb";
reg {
name = "Rx statistics ctrl";
prefix = "RxCTRL";
field {
name = "Reset loss count";
prefix = "RST_CNT";
description = "Resets count of lost frames to zero";
type = MONOSTABLE;
};
field {
name = "Reset latency statistics";
prefix = "RX_RST_LATENCY_STATS";
description = "Resets to zero staticstis of latency measurement, i.e. max, min, avg";
type = MONOSTABLE;
};
};
reg {
name = "Rx statistics: loss count";
prefix = "RX_STAT";
field {
name = "WR Streamer frame loss count";
description = "Number of lost wr streamer frames since reset";
prefix = "RX_LOSS_CNT";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DBG Control register";
prefix = "DBG_CTRL";
field {
name = "Debug Tx or Rx";
prefix = "MUX";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Debug Start byte";
prefix = "START_BYTE";
type = SLV;
align =8;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DBG Data";
prefix = "DBG_DATA";
field {
name = "Debug content";
size = 32;
type =SLV;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
};
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Transmission control and debug
---------------------------------------------------------------------------------------
-- File : wr_transmission_wb_pkg.vhd
-- Author : auto-generated by wbgen2 from wr_transmission_wb.wb
-- Created : Tue May 31 08:42:37 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_transmission_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package wr_transmission_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_wr_transmission_in_registers is record
rx_stat_rx_loss_cnt_i : std_logic_vector(31 downto 0);
dbg_data_i : std_logic_vector(31 downto 0);
end record;
constant c_wr_transmission_in_registers_init_value: t_wr_transmission_in_registers := (
rx_stat_rx_loss_cnt_i => (others => '0'),
dbg_data_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_wr_transmission_out_registers is record
rxctrl_rst_cnt_o : std_logic;
rxctrl_rx_rst_latency_stats_o : std_logic;
dbg_ctrl_mux_o : std_logic;
end record;
constant c_wr_transmission_out_registers_init_value: t_wr_transmission_out_registers := (
rxctrl_rst_cnt_o => '0',
rxctrl_rx_rst_latency_stats_o => '0',
dbg_ctrl_mux_o => '0'
);
function "or" (left, right: t_wr_transmission_in_registers) return t_wr_transmission_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
end package;
package body wr_transmission_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_wr_transmission_in_registers) return t_wr_transmission_in_registers is
variable tmp: t_wr_transmission_in_registers;
begin
tmp.rx_stat_rx_loss_cnt_i := f_x_to_zero(left.rx_stat_rx_loss_cnt_i) or f_x_to_zero(right.rx_stat_rx_loss_cnt_i);
tmp.dbg_data_i := f_x_to_zero(left.dbg_data_i) or f_x_to_zero(right.dbg_data_i);
return tmp;
end function;
end package body;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Transmission control and debug
---------------------------------------------------------------------------------------
-- File : wr_transmission_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wr_transmission_wb.wb
-- Created : Tue May 31 08:48:29 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_transmission_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package wr_transmission_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_wr_transmission_in_registers is record
rx_stat_rx_loss_cnt_i : std_logic_vector(31 downto 0);
dbg_data_i : std_logic_vector(31 downto 0);
end record;
constant c_wr_transmission_in_registers_init_value: t_wr_transmission_in_registers := (
rx_stat_rx_loss_cnt_i => (others => '0'),
dbg_data_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_wr_transmission_out_registers is record
rxctrl_rst_cnt_o : std_logic;
rxctrl_rx_rst_latency_stats_o : std_logic;
dbg_ctrl_mux_o : std_logic;
dbg_ctrl_start_byte_o : std_logic_vector(7 downto 0);
end record;
constant c_wr_transmission_out_registers_init_value: t_wr_transmission_out_registers := (
rxctrl_rst_cnt_o => '0',
rxctrl_rx_rst_latency_stats_o => '0',
dbg_ctrl_mux_o => '0',
dbg_ctrl_start_byte_o => (others => '0')
);
function "or" (left, right: t_wr_transmission_in_registers) return t_wr_transmission_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
end package;
package body wr_transmission_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_wr_transmission_in_registers) return t_wr_transmission_in_registers is
variable tmp: t_wr_transmission_in_registers;
begin
tmp.rx_stat_rx_loss_cnt_i := f_x_to_zero(left.rx_stat_rx_loss_cnt_i) or f_x_to_zero(right.rx_stat_rx_loss_cnt_i);
tmp.dbg_data_i := f_x_to_zero(left.dbg_data_i) or f_x_to_zero(right.dbg_data_i);
return tmp;
end function;
end package body;
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment