Commit 1fbf7c8b authored by Tristan Gingold's avatar Tristan Gingold

Merge remote-tracking branch 'origin/tom-wrpc-riscv-for-adam-feb19' into wrpc-v5

parents d7453e86 37c92c65
Pipeline #3430 failed with stage
......@@ -10,3 +10,6 @@
[submodule "ip_cores/vme64x-core"]
path = ip_cores/vme64x-core
url = https://ohwr.org/project/vme64x-core.git
[submodule "ip_cores/urv-core"]
path = ip_cores/urv-core
url = https://ohwr.org/project/urv-core.git
Subproject commit f4a94d1bc3fa885d082b88cc9bc9e51976dd6310
......@@ -6,4 +6,4 @@ files = ["dmtd_phase_meas.vhd",
"pulse_gen.vhd",
"pulse_stamper.vhd",
"pulse_stamper_sync.vhd",
"dmtd_sampler.vhd" ]
]
......@@ -37,5 +37,11 @@ files = [ "endpoint_private_pkg.vhd",
"ep_tx_inject_ctrl.vhd",
"endpoint_pkg.vhd",
"wr_endpoint.vhd",
"xwr_endpoint.vhd"
"xwr_endpoint.vhd",
"prbs/lfsr_crc.v",
"prbs/lfsr_descramble.v",
"prbs/lfsr_prbs_check.v",
"prbs/lfsr_prbs_gen.v",
"prbs/lfsr_scramble.v",
"prbs/lfsr.v"
];
......@@ -6,7 +6,7 @@
-- Author : Tomasz Włostowski
-- Company : CERN BE-CO-HT
-- Created : 2010-11-18
-- Last update: 2017-02-20
-- Last update: 2021-04-09
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -206,6 +206,7 @@ package endpoint_private_pkg is
mdio_mcr_reset_i : in std_logic;
mdio_mcr_pdown_i : in std_logic;
mdio_wr_spec_tx_cal_i : in std_logic;
mdio_dbg_prbs_en_i : in std_logic;
an_tx_en_i : in std_logic;
an_tx_val_i : in std_logic_vector(15 downto 0);
timestamp_trigger_p_a_o : out std_logic;
......@@ -277,6 +278,10 @@ package endpoint_private_pkg is
mdio_mcr_pdown_i : in std_logic;
mdio_wr_spec_cal_crst_i : in std_logic;
mdio_wr_spec_rx_cal_stat_o : out std_logic;
mdio_dbg_prbs_check_i : in std_logic;
mdio_dbg_prbs_latch_count_i : in std_logic;
mdio_dbg_prbs_word_sel_i : in std_logic;
mdio_dbg_prbs_errors_o : out std_logic_vector(15 downto 0);
synced_o : out std_logic;
sync_lost_o : out std_logic;
an_rx_en_i : in std_logic;
......@@ -360,7 +365,10 @@ package endpoint_private_pkg is
mdio_ectrl_sfp_tx_disable_o : out std_logic;
mdio_ectrl_tx_prbs_sel_o : out std_logic_vector(2 downto 0);
mdio_lpc_phy_stat_i : in std_logic_vector(15 downto 0);
mdio_lpc_phy_ctrl_o : out std_logic_vector(15 downto 0));
mdio_lpc_phy_ctrl_o : out std_logic_vector(15 downto 0);
mdio_dbg_prbs_control_o : out std_logic_vector(15 downto 0);
mdio_dbg_prbs_status_i : in std_logic_vector(15 downto 0)
);
end component ep_pcs_tbi_mdio_wb;
component ep_tx_header_processor
......@@ -456,24 +464,24 @@ package endpoint_private_pkg is
rmon_sent_pause_o : out std_logic);
end component;
component ep_wishbone_controller
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(4 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;
tx_clk_i : in std_logic;
rx_clk_i : in std_logic;
regs_o : out t_ep_out_registers;
regs_i : in t_ep_in_registers);
end component;
-- component ep_wishbone_controller
-- port (
-- rst_n_i : in std_logic;
-- clk_sys_i : in std_logic;
-- wb_adr_i : in std_logic_vector(4 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;
-- tx_clk_i : in std_logic;
-- rx_clk_i : in std_logic;
-- regs_o : out t_ep_out_registers;
-- regs_i : in t_ep_in_registers);
-- end component;
component ep_leds_controller
generic (
......
......@@ -6,7 +6,7 @@
-- Author : Tomasz Włostowski
-- Company : CERN BE-CO-HT
-- Created : 2010-11-18
-- Last update: 2019-04-18
-- Last update: 2021-04-09
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -264,7 +264,10 @@ architecture rtl of ep_1000basex_pcs is
signal rmon_rx_overrun : std_logic;
signal rmon_rx_inv_code : std_logic;
signal rmon_rx_sync_lost: std_logic;
signal dbg_prbs_control : std_logic_vector(15 downto 0);
signal dbg_prbs_status : std_logic_vector(15 downto 0);
begin -- rtl
pcs_reset_n <= '0' when (mdio_mcr_reset = '1' or rst_n_i = '0') else '1';
......@@ -285,6 +288,7 @@ begin -- rtl
mdio_mcr_reset_i => mdio_mcr_reset,
mdio_mcr_pdown_i => mdio_mcr_pdown,
mdio_wr_spec_tx_cal_i => mdio_wr_spec_tx_cal,
mdio_dbg_prbs_en_i => dbg_prbs_control(0),
an_tx_en_i => an_tx_en,
an_tx_val_i => an_tx_val,
......@@ -323,6 +327,10 @@ begin -- rtl
mdio_mcr_pdown_i => mdio_mcr_pdown,
mdio_wr_spec_cal_crst_i => mdio_wr_spec_cal_crst,
mdio_wr_spec_rx_cal_stat_o => mdio_wr_spec_rx_cal_stat,
mdio_dbg_prbs_check_i => dbg_prbs_control(1),
mdio_dbg_prbs_word_sel_i => dbg_prbs_control(2),
mdio_dbg_prbs_latch_count_i => dbg_prbs_control(3),
mdio_dbg_prbs_errors_o => dbg_prbs_status,
synced_o => synced,
sync_lost_o => sync_lost,
......@@ -364,7 +372,7 @@ begin -- rtl
mdio_mcr_reset_i => mdio_mcr_reset,
mdio_mcr_pdown_i => mdio_mcr_pdown,
mdio_wr_spec_tx_cal_i => mdio_wr_spec_tx_cal,
an_tx_en_i => an_tx_en,
an_tx_val_i => an_tx_val,
timestamp_trigger_p_a_o => txpcs_timestamp_trigger_p_a_o,
......@@ -481,7 +489,8 @@ begin -- rtl
mdio_ectrl_tx_prbs_sel_o => serdes_tx_prbs_sel_o,
mdio_lpc_phy_stat_i => serdes_stat_i,
mdio_lpc_phy_ctrl_o => serdes_ctrl_o,
mdio_dbg_prbs_status_i => dbg_prbs_status,
mdio_dbg_prbs_control_o => dbg_prbs_control,
lstat_read_notify_o => lstat_read_notify
);
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : ep_pcs_tbi_mdio_wb.vhd
-- Author : auto-generated by wbgen2 from pcs_regs.wb
-- Created : Fri Jul 12 10:34:39 2019
-- Created : Fri Apr 9 15:52:50 2021
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE pcs_regs.wb
......@@ -26,6 +26,8 @@ entity ep_pcs_tbi_mdio_wb is
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
tx_clk_i : in std_logic;
rx_clk_i : in std_logic;
......@@ -85,7 +87,11 @@ entity ep_pcs_tbi_mdio_wb is
-- Port for std_logic_vector field: 'Control word 0' in reg: 'Low phase drift calibration status register'
mdio_lpc_phy_stat_i : in std_logic_vector(15 downto 0);
-- Port for std_logic_vector field: 'Control word 0' in reg: 'Low phase drift calibration control register'
mdio_lpc_phy_ctrl_o : out std_logic_vector(15 downto 0)
mdio_lpc_phy_ctrl_o : out std_logic_vector(15 downto 0);
-- Port for std_logic_vector field: 'Control word 0' in reg: 'DBG PRBS Control'
mdio_dbg_prbs_control_o : out std_logic_vector(15 downto 0);
-- Port for std_logic_vector field: 'Status word 0' in reg: 'DBG PRBS Status'
mdio_dbg_prbs_status_i : in std_logic_vector(15 downto 0)
);
end ep_pcs_tbi_mdio_wb;
......@@ -122,6 +128,7 @@ signal mdio_ectrl_lpbck_vec_int : std_logic_vector(2 downto 0);
signal mdio_ectrl_sfp_tx_disable_int : std_logic ;
signal mdio_ectrl_tx_prbs_sel_int : std_logic_vector(2 downto 0);
signal mdio_lpc_phy_ctrl_int : std_logic_vector(15 downto 0);
signal mdio_dbg_prbs_control_int : std_logic_vector(15 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);
......@@ -134,13 +141,8 @@ 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.
-- Some internal signals assignments
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)
......@@ -168,6 +170,7 @@ begin
mdio_ectrl_sfp_tx_disable_int <= '0';
mdio_ectrl_tx_prbs_sel_int <= "000";
mdio_lpc_phy_ctrl_int <= "0000000000000000";
mdio_dbg_prbs_control_int <= "0000000000000000";
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
......@@ -546,6 +549,51 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10100" =>
if (wb_we_i = '1') then
mdio_dbg_prbs_control_int <= wrdata_reg(15 downto 0);
end if;
rddata_reg(15 downto 0) <= mdio_dbg_prbs_control_int;
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 "10101" =>
if (wb_we_i = '1') then
end if;
rddata_reg(15 downto 0) <= mdio_dbg_prbs_status_i;
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 others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
......@@ -684,8 +732,13 @@ begin
-- Control word 0
-- Control word 0
mdio_lpc_phy_ctrl_o <= mdio_lpc_phy_ctrl_int;
-- Control word 0
mdio_dbg_prbs_control_o <= mdio_dbg_prbs_control_int;
-- Status word 0
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
This diff is collapsed.
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2009-06-16
-- Last update: 2017-02-20
-- Last update: 2021-04-09
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -96,6 +96,10 @@ entity ep_rx_pcs_16bit is
mdio_mcr_pdown_i : in std_logic;
mdio_wr_spec_cal_crst_i : in std_logic;
mdio_wr_spec_rx_cal_stat_o : out std_logic;
mdio_dbg_prbs_check_i : in std_logic;
mdio_dbg_prbs_errors_o : out std_logic_vector(15 downto 0);
mdio_dbg_prbs_latch_count_i : in std_logic;
mdio_dbg_prbs_word_sel_i : in std_logic;
synced_o : out std_logic;
sync_lost_o : out std_logic;
......@@ -218,6 +222,34 @@ architecture behavioral of ep_rx_pcs_16bit is
signal pcs_fab_out : t_ep_internal_fabric;
signal pcs_valid_int : std_logic;
signal timestamp_pending : std_logic_vector(2 downto 0) := "000";
signal mdio_dbg_prbs_check_synced: std_logic;
signal mdio_dbg_prbs_word_sel_synced: std_logic;
signal mdio_dbg_prbs_latch_count_synced_p: std_logic;
signal lfsr_rst : std_logic;
component lfsr_prbs_check is
generic
(
DATA_WIDTH : integer := 16
);
port (
clk : in std_logic;
rst : in std_logic;
data_in : in std_logic_vector(DATA_WIDTH-1 downto 0);
data_in_valid : in std_logic;
data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
signal prbs_error_count : unsigned(31 downto 0);
signal prbs_error_count_latched : unsigned(31 downto 0);
signal prbs_data_in : std_logic_vector(15 downto 0);
signal prbs_data_in_valid : std_logic;
signal prbs_data_out : std_logic_vector(15 downto 0);
begin
-------------------------------------------------------------------------------
......@@ -257,6 +289,40 @@ begin
npulse_o => open,
ppulse_o => open);
U_sync_check_en : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => phy_rx_clk_i,
rst_n_i => '1',
data_i => mdio_dbg_prbs_check_i,
synced_o => mdio_dbg_prbs_check_synced,
npulse_o => open,
ppulse_o => open);
U_sync_check_word_sel : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => phy_rx_clk_i,
rst_n_i => '1',
data_i => mdio_dbg_prbs_word_sel_i,
synced_o => mdio_dbg_prbs_word_sel_synced,
npulse_o => open,
ppulse_o => open);
U_sync_check_latch : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => phy_rx_clk_i,
rst_n_i => '1',
data_i => mdio_dbg_prbs_latch_count_i,
npulse_o => open,
ppulse_o => mdio_dbg_prbs_latch_count_synced_p);
U_sync_power_down : gc_sync_ffs
generic map (
g_sync_edge => "positive")
......@@ -341,6 +407,63 @@ begin
end process;
U_lfsr_prbs_check: lfsr_prbs_check
generic map (
DATA_WIDTH => 16)
port map (
clk => phy_rx_clk_i,
rst => lfsr_rst,
data_in => prbs_data_in,
data_in_valid => prbs_data_in_valid,
data_out => prbs_data_out);
lfsr_rst <= '1' when rst_n_rx = '0' or mdio_dbg_prbs_check_synced = '0' else '0';
p_prbs_check: process(phy_rx_clk_i)
begin
if rising_edge(phy_rx_clk_i) then
if rst_n_rx = '0' then
prbs_error_count <= (others => '0');
prbs_data_in_valid <= '0';
else
if mdio_dbg_prbs_check_synced = '1' then
if phy_rx_data_i = (c_K28_5 & c_d16_2) and phy_rx_k_i = "10" then
prbs_data_in_valid <= '0';
else
prbs_data_in_valid <= '1';
prbs_data_in <= phy_rx_data_i;
end if;
if prbs_data_out /= x"0000" then
prbs_error_count <= prbs_error_count + 1;
end if;
else
prbs_error_count <= (others => '0');
end if;
if mdio_dbg_prbs_latch_count_synced_p = '1' then
prbs_error_count_latched <= prbs_error_count;
end if;
if mdio_dbg_prbs_word_sel_i = '0' then
mdio_dbg_prbs_errors_o <= std_logic_vector(prbs_error_count_latched(15 downto 0));
else
mdio_dbg_prbs_errors_o <= std_logic_vector(prbs_error_count_latched(31 downto 16));
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------
-- Clock adjustment FIFO
-------------------------------------------------------------------------------
......
......@@ -6,7 +6,7 @@
-- Author : Tomasz Włostowski
-- Company : CERN BE-CO-HT section
-- Created : 2009-06-16
-- Last update: 2017-02-20
-- Last update: 2021-04-09
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
......@@ -94,6 +94,9 @@ entity ep_tx_pcs_16bit is
-- Transmit Control Register, TX_CAL field
mdio_wr_spec_tx_cal_i : in std_logic;
mdio_dbg_prbs_en_i : in std_logic;
-- autonegotiation control
an_tx_en_i : in std_logic;
an_tx_val_i : in std_logic_vector(15 downto 0);
......@@ -152,6 +155,9 @@ architecture behavioral of ep_tx_pcs_16bit is
signal tx_error : std_logic;
signal rst_n_tx : std_logic;
signal prbs_tx_reg : std_logic_vector(15 downto 0);
signal prbs_tx_is_k : std_logic_vector(1 downto 0);
signal mdio_mcr_reset_synced : std_logic;
signal mdio_mcr_pdown_synced : std_logic;
......@@ -170,6 +176,27 @@ architecture behavioral of ep_tx_pcs_16bit is
-- -----------------------------------------
-- just now we send Preamble
--
component lfsr_prbs_gen is
generic (
DATA_WIDTH : integer := 16
);
port (
clk : in std_logic;
rst : in std_logic;
enable : in std_logic;
data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end component;
signal prbs_count : unsigned(10 downto 0);
signal rst_tx : std_logic;
signal lfsr_enable : std_logic;
signal lfsr_out : std_logic_vector(15 downto 0);
signal mdio_dbg_prbs_en_synced : std_logic;
begin
U_sync_pcs_busy_o : gc_sync_ffs
......@@ -210,6 +237,17 @@ begin
npulse_o => open,
ppulse_o => open);
U_sync_mdio_prbs_en : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => phy_tx_clk_i,
rst_n_i => '1',
data_i => mdio_dbg_prbs_en_i,
synced_o => mdio_dbg_prbs_en_synced,
npulse_o => open,
ppulse_o => open);
U_sync_power_down : gc_sync_ffs
generic map (
g_sync_edge => "positive")
......@@ -219,11 +257,55 @@ begin
data_i => mdio_mcr_pdown_i,
synced_o => mdio_mcr_pdown_synced);
phy_tx_data_o <= tx_odata_reg;
phy_tx_k_o <= tx_is_k;
phy_tx_data_o <= tx_odata_reg when mdio_dbg_prbs_en_synced = '0' else prbs_tx_reg;
phy_tx_k_o <= tx_is_k when mdio_dbg_prbs_en_synced = '0' else prbs_tx_is_k;
rst_n_tx <= rst_txclk_n_i and not mdio_mcr_reset_synced;
rst_tx <= not rst_n_tx;
U_lfsr_prbs_gen : lfsr_prbs_gen
generic map (
DATA_WIDTH => 16)
port map (
clk => phy_tx_clk_i,
rst => rst_tx,
enable => lfsr_enable,
data_out => lfsr_out);
p_prbs_generator : process(phy_tx_clk_i)
begin
if rising_edge(phy_tx_clk_i) then
if(rst_n_tx = '0' or mdio_mcr_pdown_synced = '1') then
prbs_count <= (others => '0');
else
if mdio_dbg_prbs_en_synced = '1' then
prbs_count <= prbs_count + 1;
if prbs_count = 0 then
lfsr_enable <= '0';
else
lfsr_enable <= '1';
end if;
if prbs_count = 2 then
prbs_tx_is_k <= "10";
prbs_tx_reg(15 downto 8) <= c_K28_5;
prbs_tx_reg(7 downto 0) <= c_d16_2;
else
prbs_tx_is_k <= "00";
prbs_tx_reg <= lfsr_out;
end if;
else
lfsr_enable <= '0';
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------
-- Clock alignment FIFO
-------------------------------------------------------------------------------
......
......@@ -815,5 +815,29 @@ peripheral {
};
};
reg {
name = "DBG PRBS Control";
prefix = "DBG_PRBS_CONTROL";
field {
name = "Control word 0";
size = 16;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DBG PRBS Status";
prefix = "DBG_PRBS_STATUS";
field {
name = "Status word 0";
size = 16;
type = SLV;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
};
This diff is collapsed.
/*
Copyright (c) 2016 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* LFSR CRC generator
*/
module lfsr_crc #
(
// width of LFSR
parameter LFSR_WIDTH = 32,
// LFSR polynomial
parameter LFSR_POLY = 32'h04c11db7,
// Initial state
parameter LFSR_INIT = {LFSR_WIDTH{1'b1}},
// LFSR configuration: "GALOIS", "FIBONACCI"
parameter LFSR_CONFIG = "GALOIS",
// bit-reverse input and output
parameter REVERSE = 1,
// invert output
parameter INVERT = 1,
// width of data input and output
parameter DATA_WIDTH = 8,
// implementation style: "AUTO", "LOOP", "REDUCTION"
parameter STYLE = "AUTO"
)
(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] data_in,
input wire data_in_valid,
output wire [LFSR_WIDTH-1:0] crc_out
);
/*
Fully parametrizable combinatorial parallel LFSR CRC module. Implements an unrolled LFSR
next state computation.
Ports:
clk
Clock input
rst
Reset module, set state to LFSR_INIT
data_in
CRC data input
data_in_valid
Shift input data through CRC when asserted
data_out
LFSR output (OUTPUT_WIDTH bits)
Parameters:
LFSR_WIDTH
Specify width of LFSR/CRC register
LFSR_POLY
Specify the LFSR/CRC polynomial in hex format. For example, the polynomial
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
would be represented as
32'h04c11db7
Note that the largest term (x^32) is suppressed. This term is generated automatically based
on LFSR_WIDTH.
LFSR_INIT
Initial state of LFSR. Defaults to all 1s.
LFSR_CONFIG
Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used
for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators,
scramblers, and descrambers, while Galois is generally used for cyclic redundancy check
generators and checkers.
Fibonacci style (example for 64b66b scrambler, 0x8000000001)
DIN (LSB first)
|
V
(+)<---------------------------(+)<-----------------------------.
| ^ |
| .----. .----. .----. | .----. .----. .----. |
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--'
| '----' '----' '----' '----' '----' '----'
V
DOUT
Galois style (example for CRC16, 0x8005)
,-------------------+-------------------------+----------(+)<-- DIN (MSB first)
| | | ^
| .----. .----. V .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT
'----' '----' '----' '----' '----'
REVERSE
Bit-reverse LFSR input and output. Shifts MSB first by default, set REVERSE for LSB first.
INVERT
Bitwise invert CRC output.
DATA_WIDTH
Specify width of input data bus. The module will perform one shift per input data bit,
so if the input data bus is not required tie data_in to zero and set DATA_WIDTH to the
required number of shifts per clock cycle.
STYLE
Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO"
is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate
directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate
and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog
reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction
operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in
Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing
problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO"
will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey
synthesis translate directives.
Settings for common LFSR/CRC implementations:
Name Configuration Length Polynomial Initial value Notes
CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output
PRBS6 Fibonacci 6 6'h21 any
PRBS7 Fibonacci 7 7'h41 any
PRBS9 Fibonacci 9 9'h021 any ITU V.52
PRBS10 Fibonacci 10 10'h081 any ITU
PRBS11 Fibonacci 11 11'h201 any ITU O.152
PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152
PRBS17 Fibonacci 17 17'h04001 any
PRBS20 Fibonacci 20 20'h00009 any ITU V.57
PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151
PRBS29 Fibonacci, inverted 29 29'h08000001 any
PRBS31 Fibonacci, inverted 31 31'h10000001 any
64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet
128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3
*/
reg [LFSR_WIDTH-1:0] state_reg = LFSR_INIT;
reg [LFSR_WIDTH-1:0] output_reg = 0;
wire [LFSR_WIDTH-1:0] lfsr_state;
assign crc_out = output_reg;
lfsr #(
.LFSR_WIDTH(LFSR_WIDTH),
.LFSR_POLY(LFSR_POLY),
.LFSR_CONFIG(LFSR_CONFIG),
.LFSR_FEED_FORWARD(0),
.REVERSE(REVERSE),
.DATA_WIDTH(DATA_WIDTH),
.STYLE(STYLE)
)
lfsr_inst (
.data_in(data_in),
.state_in(state_reg),
.data_out(),
.state_out(lfsr_state)
);
always @(posedge clk) begin
if (rst) begin
state_reg <= LFSR_INIT;
output_reg <= 0;
end else begin
if (data_in_valid) begin
state_reg <= lfsr_state;
if (INVERT) begin
output_reg <= ~lfsr_state;
end else begin
output_reg <= lfsr_state;
end
end
end
end
endmodule
/*
Copyright (c) 2016 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* LFSR descrambler
*/
module lfsr_descramble #
(
// width of LFSR
parameter LFSR_WIDTH = 58,
// LFSR polynomial
parameter LFSR_POLY = 58'h8000000001,
// Initial state
parameter LFSR_INIT = {LFSR_WIDTH{1'b1}},
// LFSR configuration: "GALOIS", "FIBONACCI"
parameter LFSR_CONFIG = "FIBONACCI",
// bit-reverse input and output
parameter REVERSE = 1,
// width of data bus
parameter DATA_WIDTH = 64,
// implementation style: "AUTO", "LOOP", "REDUCTION"
parameter STYLE = "AUTO"
)
(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] data_in,
input wire data_in_valid,
output wire [DATA_WIDTH-1:0] data_out
);
/*
Fully parametrizable combinatorial parallel LFSR CRC module. Implements an unrolled LFSR
next state computation.
Ports:
clk
Clock input
rst
Reset module, set state to LFSR_INIT
data_in
Scrambled data input (DATA_WIDTH bits)
data_in_valid
Shift input data through CRC when asserted
data_out
Descrambled data output (DATA_WIDTH bits)
Parameters:
LFSR_WIDTH
Specify width of LFSR/CRC register
LFSR_POLY
Specify the LFSR/CRC polynomial in hex format. For example, the polynomial
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
would be represented as
32'h04c11db7
Note that the largest term (x^32) is suppressed. This term is generated automatically based
on LFSR_WIDTH.
LFSR_INIT
Initial state of LFSR. Defaults to all 1s.
LFSR_CONFIG
Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used
for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators,
scramblers, and descrambers, while Galois is generally used for cyclic redundancy check
generators and checkers.
Fibonacci style (example for 64b66b scrambler, 0x8000000001)
DIN (LSB first)
|
V
(+)<---------------------------(+)<-----------------------------.
| ^ |
| .----. .----. .----. | .----. .----. .----. |
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--'
| '----' '----' '----' '----' '----' '----'
V
DOUT
Galois style (example for CRC16, 0x8005)
,-------------------+-------------------------+----------(+)<-- DIN (MSB first)
| | | ^
| .----. .----. V .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT
'----' '----' '----' '----' '----'
REVERSE
Bit-reverse LFSR input and output.
DATA_WIDTH
Specify width of the data bus. The module will perform one shift per input data bit.
STYLE
Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO"
is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate
directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate
and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog
reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction
operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in
Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing
problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO"
will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey
synthesis translate directives.
Settings for common LFSR/CRC implementations:
Name Configuration Length Polynomial Initial value Notes
CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output
PRBS6 Fibonacci 6 6'h21 any
PRBS7 Fibonacci 7 7'h41 any
PRBS9 Fibonacci 9 9'h021 any ITU V.52
PRBS10 Fibonacci 10 10'h081 any ITU
PRBS11 Fibonacci 11 11'h201 any ITU O.152
PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152
PRBS17 Fibonacci 17 17'h04001 any
PRBS20 Fibonacci 20 20'h00009 any ITU V.57
PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151
PRBS29 Fibonacci, inverted 29 29'h08000001 any
PRBS31 Fibonacci, inverted 31 31'h10000001 any
64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet
128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3
*/
reg [LFSR_WIDTH-1:0] state_reg = LFSR_INIT;
reg [DATA_WIDTH-1:0] output_reg = 0;
wire [DATA_WIDTH-1:0] lfsr_data;
wire [LFSR_WIDTH-1:0] lfsr_state;
assign data_out = output_reg;
lfsr #(
.LFSR_WIDTH(LFSR_WIDTH),
.LFSR_POLY(LFSR_POLY),
.LFSR_CONFIG(LFSR_CONFIG),
.LFSR_FEED_FORWARD(1),
.REVERSE(REVERSE),
.DATA_WIDTH(DATA_WIDTH),
.STYLE(STYLE)
)
lfsr_inst (
.data_in(data_in),
.state_in(state_reg),
.data_out(lfsr_data),
.state_out(lfsr_state)
);
always @(posedge clk) begin
if (rst) begin
state_reg <= LFSR_INIT;
output_reg <= 0;
end else begin
if (data_in_valid) begin
state_reg <= lfsr_state;
output_reg <= lfsr_data;
end
end
end
endmodule
/*
Copyright (c) 2016 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* LFSR PRBS checker
*/
module lfsr_prbs_check #
(
// width of LFSR
parameter LFSR_WIDTH = 31,
// LFSR polynomial
parameter LFSR_POLY = 31'h10000001,
// Initial state
parameter LFSR_INIT = {LFSR_WIDTH{1'b1}},
// LFSR configuration: "GALOIS", "FIBONACCI"
parameter LFSR_CONFIG = "FIBONACCI",
// bit-reverse input and output
parameter REVERSE = 0,
// invert input
parameter INVERT = 1,
// width of data input and output
parameter DATA_WIDTH = 8,
// implementation style: "AUTO", "LOOP", "REDUCTION"
parameter STYLE = "AUTO"
)
(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] data_in,
input wire data_in_valid,
output wire [DATA_WIDTH-1:0] data_out
);
/*
Fully parametrizable combinatorial parallel LFSR PRBS checker. Implements an unrolled LFSR
PRBS checker.
Ports:
clk
Clock input
rst
Reset input, set state to LFSR_INIT
data_in
PRBS data input (DATA_WIDTH bits)
data_in_valid
Shift input data through LFSR when asserted
data_out
Error output (DATA_WIDTH bits)
Parameters:
LFSR_WIDTH
Specify width of LFSR/CRC register
LFSR_POLY
Specify the LFSR/CRC polynomial in hex format. For example, the polynomial
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
would be represented as
32'h04c11db7
Note that the largest term (x^32) is suppressed. This term is generated automatically based
on LFSR_WIDTH.
LFSR_INIT
Initial state of LFSR. Defaults to all 1s.
LFSR_CONFIG
Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used
for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators,
scramblers, and descrambers, while Galois is generally used for cyclic redundancy check
generators and checkers.
Fibonacci style (example for 64b66b scrambler, 0x8000000001)
DIN (LSB first)
|
V
(+)<---------------------------(+)<-----------------------------.
| ^ |
| .----. .----. .----. | .----. .----. .----. |
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--'
| '----' '----' '----' '----' '----' '----'
V
DOUT
Galois style (example for CRC16, 0x8005)
,-------------------+-------------------------+----------(+)<-- DIN (MSB first)
| | | ^
| .----. .----. V .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT
'----' '----' '----' '----' '----'
REVERSE
Bit-reverse LFSR output. Shifts MSB first by default, set REVERSE for LSB first.
INVERT
Bitwise invert PRBS input.
DATA_WIDTH
Specify width of output data bus.
STYLE
Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO"
is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate
directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate
and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog
reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction
operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in
Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing
problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO"
will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey
synthesis translate directives.
Settings for common LFSR/CRC implementations:
Name Configuration Length Polynomial Initial value Notes
CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output
PRBS6 Fibonacci 6 6'h21 any
PRBS7 Fibonacci 7 7'h41 any
PRBS9 Fibonacci 9 9'h021 any ITU V.52
PRBS10 Fibonacci 10 10'h081 any ITU
PRBS11 Fibonacci 11 11'h201 any ITU O.152
PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152
PRBS17 Fibonacci 17 17'h04001 any
PRBS20 Fibonacci 20 20'h00009 any ITU V.57
PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151
PRBS29 Fibonacci, inverted 29 29'h08000001 any
PRBS31 Fibonacci, inverted 31 31'h10000001 any
64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet
128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3
*/
reg [LFSR_WIDTH-1:0] state_reg = LFSR_INIT;
reg [DATA_WIDTH-1:0] output_reg = 0;
wire [DATA_WIDTH-1:0] lfsr_data;
wire [LFSR_WIDTH-1:0] lfsr_state;
assign data_out = output_reg;
lfsr #(
.LFSR_WIDTH(LFSR_WIDTH),
.LFSR_POLY(LFSR_POLY),
.LFSR_CONFIG(LFSR_CONFIG),
.LFSR_FEED_FORWARD(1),
.REVERSE(REVERSE),
.DATA_WIDTH(DATA_WIDTH),
.STYLE(STYLE)
)
lfsr_inst (
.data_in(INVERT ? ~data_in : data_in),
.state_in(state_reg),
.data_out(lfsr_data),
.state_out(lfsr_state)
);
always @(posedge clk) begin
if (rst) begin
state_reg <= LFSR_INIT;
output_reg <= 0;
end else begin
if (data_in_valid) begin
state_reg <= lfsr_state;
output_reg <= lfsr_data;
end
end
end
endmodule
/*
Copyright (c) 2016 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* LFSR PRBS generator
*/
module lfsr_prbs_gen #
(
// width of LFSR
parameter LFSR_WIDTH = 31,
// LFSR polynomial
parameter LFSR_POLY = 31'h10000001,
// Initial state
parameter LFSR_INIT = {LFSR_WIDTH{1'b1}},
// LFSR configuration: "GALOIS", "FIBONACCI"
parameter LFSR_CONFIG = "FIBONACCI",
// bit-reverse input and output
parameter REVERSE = 0,
// invert output
parameter INVERT = 1,
// width of data output
parameter DATA_WIDTH = 8,
// implementation style: "AUTO", "LOOP", "REDUCTION"
parameter STYLE = "AUTO"
)
(
input wire clk,
input wire rst,
input wire enable,
output wire [DATA_WIDTH-1:0] data_out
);
/*
Fully parametrizable combinatorial parallel LFSR PRBS module. Implements an unrolled LFSR
next state computation.
Ports:
clk
Clock input
rst
Reset input, set state to LFSR_INIT
enable
Generate new output data
data_out
LFSR output (DATA_WIDTH bits)
Parameters:
LFSR_WIDTH
Specify width of LFSR/CRC register
LFSR_POLY
Specify the LFSR/CRC polynomial in hex format. For example, the polynomial
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
would be represented as
32'h04c11db7
Note that the largest term (x^32) is suppressed. This term is generated automatically based
on LFSR_WIDTH.
LFSR_INIT
Initial state of LFSR. Defaults to all 1s.
LFSR_CONFIG
Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used
for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators,
scramblers, and descrambers, while Galois is generally used for cyclic redundancy check
generators and checkers.
Fibonacci style (example for 64b66b scrambler, 0x8000000001)
DIN (LSB first)
|
V
(+)<---------------------------(+)<-----------------------------.
| ^ |
| .----. .----. .----. | .----. .----. .----. |
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--'
| '----' '----' '----' '----' '----' '----'
V
DOUT
Galois style (example for CRC16, 0x8005)
,-------------------+-------------------------+----------(+)<-- DIN (MSB first)
| | | ^
| .----. .----. V .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT
'----' '----' '----' '----' '----'
REVERSE
Bit-reverse LFSR output. Shifts MSB first by default, set REVERSE for LSB first.
INVERT
Bitwise invert PRBS output.
DATA_WIDTH
Specify width of output data bus.
STYLE
Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO"
is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate
directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate
and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog
reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction
operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in
Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing
problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO"
will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey
synthesis translate directives.
Settings for common LFSR/CRC implementations:
Name Configuration Length Polynomial Initial value Notes
CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output
PRBS6 Fibonacci 6 6'h21 any
PRBS7 Fibonacci 7 7'h41 any
PRBS9 Fibonacci 9 9'h021 any ITU V.52
PRBS10 Fibonacci 10 10'h081 any ITU
PRBS11 Fibonacci 11 11'h201 any ITU O.152
PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152
PRBS17 Fibonacci 17 17'h04001 any
PRBS20 Fibonacci 20 20'h00009 any ITU V.57
PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151
PRBS29 Fibonacci, inverted 29 29'h08000001 any
PRBS31 Fibonacci, inverted 31 31'h10000001 any
64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet
128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3
*/
reg [LFSR_WIDTH-1:0] state_reg = LFSR_INIT;
reg [DATA_WIDTH-1:0] output_reg = 0;
wire [DATA_WIDTH-1:0] lfsr_data;
wire [LFSR_WIDTH-1:0] lfsr_state;
assign data_out = output_reg;
lfsr #(
.LFSR_WIDTH(LFSR_WIDTH),
.LFSR_POLY(LFSR_POLY),
.LFSR_CONFIG(LFSR_CONFIG),
.LFSR_FEED_FORWARD(0),
.REVERSE(REVERSE),
.DATA_WIDTH(DATA_WIDTH),
.STYLE(STYLE)
)
lfsr_inst (
.data_in({DATA_WIDTH{1'b0}}),
.state_in(state_reg),
.data_out(lfsr_data),
.state_out(lfsr_state)
);
always @* begin
if (INVERT) begin
output_reg <= ~lfsr_data;
end else begin
output_reg <= lfsr_data;
end
end
always @(posedge clk) begin
if (rst) begin
state_reg <= LFSR_INIT;
end else begin
if (enable) begin
state_reg <= lfsr_state;
end
end
end
endmodule
/*
Copyright (c) 2016 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* LFSR scrambler
*/
module lfsr_scramble #
(
// width of LFSR
parameter LFSR_WIDTH = 58,
// LFSR polynomial
parameter LFSR_POLY = 58'h8000000001,
// Initial state
parameter LFSR_INIT = {LFSR_WIDTH{1'b1}},
// LFSR configuration: "GALOIS", "FIBONACCI"
parameter LFSR_CONFIG = "FIBONACCI",
// bit-reverse input and output
parameter REVERSE = 1,
// width of data bus
parameter DATA_WIDTH = 64,
// implementation style: "AUTO", "LOOP", "REDUCTION"
parameter STYLE = "AUTO"
)
(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] data_in,
input wire data_in_valid,
output wire [DATA_WIDTH-1:0] data_out
);
/*
Fully parametrizable combinatorial parallel LFSR CRC module. Implements an unrolled LFSR
next state computation.
Ports:
clk
Clock input
rst
Reset module, set state to LFSR_INIT
data_in
Unscrambled data input (DATA_WIDTH bits)
data_in_valid
Shift input data through CRC when asserted
data_out
Scrambled data output (DATA_WIDTH bits)
Parameters:
LFSR_WIDTH
Specify width of LFSR/CRC register
LFSR_POLY
Specify the LFSR/CRC polynomial in hex format. For example, the polynomial
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
would be represented as
32'h04c11db7
Note that the largest term (x^32) is suppressed. This term is generated automatically based
on LFSR_WIDTH.
LFSR_INIT
Initial state of LFSR. Defaults to all 1s.
LFSR_CONFIG
Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used
for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators,
scramblers, and descrambers, while Galois is generally used for cyclic redundancy check
generators and checkers.
Fibonacci style (example for 64b66b scrambler, 0x8000000001)
DIN (LSB first)
|
V
(+)<---------------------------(+)<-----------------------------.
| ^ |
| .----. .----. .----. | .----. .----. .----. |
+->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--'
| '----' '----' '----' '----' '----' '----'
V
DOUT
Galois style (example for CRC16, 0x8005)
,-------------------+-------------------------+----------(+)<-- DIN (MSB first)
| | | ^
| .----. .----. V .----. .----. V .----. |
`->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT
'----' '----' '----' '----' '----'
REVERSE
Bit-reverse LFSR input and output.
DATA_WIDTH
Specify width of the data bus. The module will perform one shift per input data bit.
STYLE
Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO"
is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate
directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate
and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog
reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction
operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in
Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing
problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO"
will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey
synthesis translate directives.
Settings for common LFSR/CRC implementations:
Name Configuration Length Polynomial Initial value Notes
CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output
PRBS6 Fibonacci 6 6'h21 any
PRBS7 Fibonacci 7 7'h41 any
PRBS9 Fibonacci 9 9'h021 any ITU V.52
PRBS10 Fibonacci 10 10'h081 any ITU
PRBS11 Fibonacci 11 11'h201 any ITU O.152
PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152
PRBS17 Fibonacci 17 17'h04001 any
PRBS20 Fibonacci 20 20'h00009 any ITU V.57
PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151
PRBS29 Fibonacci, inverted 29 29'h08000001 any
PRBS31 Fibonacci, inverted 31 31'h10000001 any
64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet
128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3
*/
reg [LFSR_WIDTH-1:0] state_reg = LFSR_INIT;
reg [DATA_WIDTH-1:0] output_reg = 0;
wire [DATA_WIDTH-1:0] lfsr_data;
wire [LFSR_WIDTH-1:0] lfsr_state;
assign data_out = output_reg;
lfsr #(
.LFSR_WIDTH(LFSR_WIDTH),
.LFSR_POLY(LFSR_POLY),
.LFSR_CONFIG(LFSR_CONFIG),
.LFSR_FEED_FORWARD(0),
.REVERSE(REVERSE),
.DATA_WIDTH(DATA_WIDTH),
.STYLE(STYLE)
)
lfsr_inst (
.data_in(data_in),
.state_in(state_reg),
.data_out(lfsr_data),
.state_out(lfsr_state)
);
always @(posedge clk) begin
if (rst) begin
state_reg <= LFSR_INIT;
output_reg <= 0;
end else begin
if (data_in_valid) begin
state_reg <= lfsr_state;
output_reg <= lfsr_data;
end
end
end
endmodule
......@@ -4,5 +4,8 @@ files = [ "xwr_core.vhd",
"wrc_periph.vhd",
"wrc_syscon_wb.vhd",
"wrc_syscon_pkg.vhd",
"wrc_diags_dpram.vhd"];
"wrc_diags_dpram.vhd",
"wrc_urv_wrapper.vhd",
"wrc_cpu_csr_wbgen2_pkg.vhd",
"wrc_cpu_csr_wb.vhd"
];
......@@ -2,4 +2,5 @@
mkdir -p doc
wbgen2 -D ./doc/wrc_syscon.html -p wrc_syscon_pkg.vhd -H record -V wrc_syscon_wb.vhd -C wrc_syscon_regs.h --cstyle defines --lang vhdl -K ../../sim/wrc_syscon_regs.vh wrc_syscon_wb.wb
wbgen2 -D ./doc/wrc_diags.html -p wrc_diags_pkg.vhd -H record -V wrc_diags_wb.vhd -C wrc_diags_regs.h --cstyle defines --lang vhdl -K ../../sim/wrc_diags_regs.vh wrc_diags_wb.wb
wbgen2 -V wrc_cpu_csr_wb.vhd -p wrc_cpu_csr_wbgen2_pkg.vhd --hstyle record_full -Z --lang vhdl -K ../../testbench/wrc_core/wrc_cpu_csr_regs.vh wrc_cpu_csr.wb
This diff is collapsed.
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- Mock Turtle
-- https://gitlab.cern.ch/coht/mockturtle
--------------------------------------------------------------------------------
--
-- unit name: mt_cpu_csr
--
-- description: MT CPU Control/Status Registers block layout (wbgen2)
--
--------------------------------------------------------------------------------
-- Copyright (c) 2014-2019 CERN (home.cern)
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- 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://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this 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.
--------------------------------------------------------------------------------
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "Mock Turtle CPU Control/Status registers block";
prefix = "wrc_cpu_csr";
hdl_entity = "wrc_cpu_csr_wb_slave";
reg {
name = "Core Reset Register";
prefix = "RESET";
field {
name = "Core reset lines";
size = 8;
type = SLV;
reset_value = 0x0;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Core Upload Address Register";
prefix = "UADDR";
field {
name = "Address to access in selected core's local memory.";
prefix = "ADDR";
size = 20;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Core Upload Data Register";
prefix = "UDATA";
field {
name = "Read/Write data from/to selected core's local memory.";
description = "The address to read/write from/to is specified in the UADDR register.";
size = 32;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
align = 32;
name = "Debug Interface Status Register";
prefix = "DBG_STATUS";
field {
name = "Per Core debug mode bit";
type = SLV;
size = 8;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Debug Interface Force Register";
prefix = "DBG_FORCE";
field {
name = "Core debug force";
size = 8;
type = SLV;
reset_value = 0x00;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Debug Interface Instruction Ready Register";
prefix = "DBG_INSN_READY";
field {
name = "Core instruction ready";
size = 8;
type = SLV;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Debug Interface Core[0] Instruction Register";
prefix = "DBG_CORE0_INSN";
field {
name = "Instruction to be executed";
size = 32;
type = PASS_THROUGH;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Debug Interface Core[0] Mailbox Data Register";
prefix = "DBG_CORE0_MBX";
field {
name = "Mailbox data";
size = 32;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3,7 +3,7 @@
* File : wrc_syscon_regs.h
* Author : auto-generated by wbgen2 from wrc_syscon_wb.wb
* Created : Sat Jun 19 00:30:19 2021
* Created : Mon Mar 28 09:12:03 2022
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrc_syscon_wb.wb
......@@ -133,6 +133,12 @@
#define SYSC_HWFR_STORAGE_TYPE_W(value) WBGEN2_GEN_WRITE(value, 8, 2)
#define SYSC_HWFR_STORAGE_TYPE_R(reg) WBGEN2_GEN_READ(reg, 8, 2)
/* definitions for field: Map version in reg: Hardware Feature Register */
#define SYSC_HWFR_MAPVER_MASK WBGEN2_GEN_MASK(12, 4)
#define SYSC_HWFR_MAPVER_SHIFT 12
#define SYSC_HWFR_MAPVER_W(value) WBGEN2_GEN_WRITE(value, 12, 4)
#define SYSC_HWFR_MAPVER_R(reg) WBGEN2_GEN_READ(reg, 12, 4)
/* definitions for field: Storage sector size in reg: Hardware Feature Register */
#define SYSC_HWFR_STORAGE_SEC_MASK WBGEN2_GEN_MASK(16, 16)
#define SYSC_HWFR_STORAGE_SEC_SHIFT 16
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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