Commit 50af1a20 authored by Tristan Gingold's avatar Tristan Gingold Committed by Federico Vaga

Working sata link (still WIP)

parent 995f8b9f
# SPDX-FileCopyrightText: 2020 CERN (home.cern)
#
# SPDX-License-Identifier: CC-BY-SA-4.0 OR CERN-OHL-W-2.0+ OR GPL-2.0-or-later
memory-map:
bus: wb-32-be
name: sata_regs
description: Registers for the SATA link
x-hdl:
busgroup: True
reg-prefix: False
children:
- reg:
name: status
description: Status register
access: ro
width: 32
children:
- field:
name: rdy0
description: Transceiver 0 is locked and aligned
range: 0
- field:
name: rdy1
description: Transceiver 1 is locked and aligned
range: 1
- field:
name: rx0
description: Byte received from transceiver 0
range: 16
- field:
name: rx1
description: Byte received from transceiver 1
range: 17
- reg:
name: control
description: Control register
width: 32
access: rw
children:
- field:
name: rst0
description: Reset transceiver 0
range: 0
- field:
name: rst1
description: Reset transceiver 1
range: 1
- reg:
name: rx_data_0
description: Last data byte received from rx 0
width: 32
access: ro
x-hdl:
read-strobe: True
- reg:
name: rx_data_1
description: Last data byte received from rx 1
width: 32
access: ro
x-hdl:
read-strobe: True
- reg:
name: tx_data_0
description: Byte to be send on tx 0
width: 32
access: wo
x-hdl:
write-strobe: True
- reg:
name: tx_data_1
description: Byte to be send on tx 1
width: 32
access: wo
x-hdl:
write-strobe: True
-- Do not edit. Generated on Thu Jul 22 08:41:43 2021 by tgingold
-- With Cheby 1.5.dev0 and these options:
-- -i fmc_adc_sata_regs.cheby --gen-hdl=fmc_adc_sata_regs.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity sata_regs is
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Status register
-- Transceiver 0 is locked and aligned
rdy0_i : in std_logic;
-- Transceiver 1 is locked and aligned
rdy1_i : in std_logic;
-- Byte received from transceiver 0
rx0_i : in std_logic;
-- Byte received from transceiver 1
rx1_i : in std_logic;
-- Control register
-- Reset transceiver 0
rst0_o : out std_logic;
-- Reset transceiver 1
rst1_o : out std_logic;
-- Last data byte received from rx 0
rx_data_0_i : in std_logic_vector(31 downto 0);
rx_data_0_rd_o : out std_logic;
-- Last data byte received from rx 1
rx_data_1_i : in std_logic_vector(31 downto 0);
rx_data_1_rd_o : out std_logic;
-- Byte to be send on tx 0
tx_data_0_o : out std_logic_vector(31 downto 0);
tx_data_0_wr_o : out std_logic;
-- Byte to be send on tx 1
tx_data_1_o : out std_logic_vector(31 downto 0);
tx_data_1_wr_o : out std_logic
);
end sata_regs;
architecture syn of sata_regs is
signal adr_int : std_logic_vector(4 downto 2);
signal rd_req_int : std_logic;
signal wr_req_int : std_logic;
signal rd_ack_int : std_logic;
signal wr_ack_int : std_logic;
signal wb_en : std_logic;
signal ack_int : std_logic;
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal rst0_reg : std_logic;
signal rst1_reg : std_logic;
signal control_wreq : std_logic;
signal control_wack : std_logic;
signal tx_data_0_reg : std_logic_vector(31 downto 0);
signal tx_data_0_wreq : std_logic;
signal tx_data_0_wack : std_logic;
signal tx_data_1_reg : std_logic_vector(31 downto 0);
signal tx_data_1_wreq : std_logic;
signal tx_data_1_wack : std_logic;
signal rd_ack_d0 : std_logic;
signal rd_dat_d0 : std_logic_vector(31 downto 0);
signal wr_req_d0 : std_logic;
signal wr_adr_d0 : std_logic_vector(4 downto 2);
signal wr_dat_d0 : std_logic_vector(31 downto 0);
signal wr_sel_d0 : std_logic_vector(3 downto 0);
begin
-- WB decode signals
adr_int <= wb_i.adr(4 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wb_rip <= '0';
else
wb_rip <= (wb_rip or (wb_en and not wb_i.we)) and not rd_ack_int;
end if;
end if;
end process;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wb_wip <= '0';
else
wb_wip <= (wb_wip or (wb_en and wb_i.we)) and not wr_ack_int;
end if;
end if;
end process;
wr_req_int <= (wb_en and wb_i.we) and not wb_wip;
ack_int <= rd_ack_int or wr_ack_int;
wb_o.ack <= ack_int;
wb_o.stall <= not ack_int and wb_en;
wb_o.rty <= '0';
wb_o.err <= '0';
-- pipelining for wr-in+rd-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack_int <= '0';
wr_req_d0 <= '0';
else
rd_ack_int <= rd_ack_d0;
wb_o.dat <= rd_dat_d0;
wr_req_d0 <= wr_req_int;
wr_adr_d0 <= adr_int;
wr_dat_d0 <= wb_i.dat;
wr_sel_d0 <= wb_i.sel;
end if;
end if;
end process;
-- Register status
-- Register control
rst0_o <= rst0_reg;
rst1_o <= rst1_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rst0_reg <= '0';
rst1_reg <= '0';
control_wack <= '0';
else
if control_wreq = '1' then
rst0_reg <= wr_dat_d0(0);
rst1_reg <= wr_dat_d0(1);
end if;
control_wack <= control_wreq;
end if;
end if;
end process;
-- Register rx_data_0
-- Register rx_data_1
-- Register tx_data_0
tx_data_0_o <= tx_data_0_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
tx_data_0_reg <= "00000000000000000000000000000000";
tx_data_0_wack <= '0';
else
if tx_data_0_wreq = '1' then
tx_data_0_reg <= wr_dat_d0;
end if;
tx_data_0_wack <= tx_data_0_wreq;
end if;
end if;
end process;
tx_data_0_wr_o <= tx_data_0_wack;
-- Register tx_data_1
tx_data_1_o <= tx_data_1_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
tx_data_1_reg <= "00000000000000000000000000000000";
tx_data_1_wack <= '0';
else
if tx_data_1_wreq = '1' then
tx_data_1_reg <= wr_dat_d0;
end if;
tx_data_1_wack <= tx_data_1_wreq;
end if;
end if;
end process;
tx_data_1_wr_o <= tx_data_1_wack;
-- Process for write requests.
process (wr_adr_d0, wr_req_d0, control_wack, tx_data_0_wack, tx_data_1_wack) begin
control_wreq <= '0';
tx_data_0_wreq <= '0';
tx_data_1_wreq <= '0';
case wr_adr_d0(4 downto 2) is
when "000" =>
-- Reg status
wr_ack_int <= wr_req_d0;
when "001" =>
-- Reg control
control_wreq <= wr_req_d0;
wr_ack_int <= control_wack;
when "010" =>
-- Reg rx_data_0
wr_ack_int <= wr_req_d0;
when "011" =>
-- Reg rx_data_1
wr_ack_int <= wr_req_d0;
when "100" =>
-- Reg tx_data_0
tx_data_0_wreq <= wr_req_d0;
wr_ack_int <= tx_data_0_wack;
when "101" =>
-- Reg tx_data_1
tx_data_1_wreq <= wr_req_d0;
wr_ack_int <= tx_data_1_wack;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (adr_int, rd_req_int, rdy0_i, rdy1_i, rx0_i, rx1_i, rst0_reg, rst1_reg, rx_data_0_i, rx_data_1_i) begin
-- By default ack read requests
rd_dat_d0 <= (others => 'X');
rx_data_0_rd_o <= '0';
rx_data_1_rd_o <= '0';
case adr_int(4 downto 2) is
when "000" =>
-- Reg status
rd_ack_d0 <= rd_req_int;
rd_dat_d0(0) <= rdy0_i;
rd_dat_d0(1) <= rdy1_i;
rd_dat_d0(15 downto 2) <= (others => '0');
rd_dat_d0(16) <= rx0_i;
rd_dat_d0(17) <= rx1_i;
rd_dat_d0(31 downto 18) <= (others => '0');
when "001" =>
-- Reg control
rd_ack_d0 <= rd_req_int;
rd_dat_d0(0) <= rst0_reg;
rd_dat_d0(1) <= rst1_reg;
rd_dat_d0(31 downto 2) <= (others => '0');
when "010" =>
-- Reg rx_data_0
rx_data_0_rd_o <= rd_req_int;
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= rx_data_0_i;
when "011" =>
-- Reg rx_data_1
rx_data_1_rd_o <= rd_req_int;
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= rx_data_1_i;
when "100" =>
-- Reg tx_data_0
rd_ack_d0 <= rd_req_int;
when "101" =>
-- Reg tx_data_1
rd_ack_d0 <= rd_req_int;
when others =>
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
......@@ -40,8 +40,8 @@ NET "clk_125m_clk1_101_p_i" TNM_NET = "clk_125m_clk1_101";
NET "clk_125m_clk1_101_n_i" TNM_NET = "clk_125m_clk1_101";
TIMESPEC TS_clk_125m_clk1_101 = PERIOD "clk_125m_clk1_101" 8 ns HIGH 50%;
NET "gen_sata.inst_gt_101/ch1_gtp_clkout_int[1]" TNM_NET = wrc_gtp_101_clk;
NET "gen_sata.inst_sata/inst_gt_101/ch1_gtp_clkout_int[1]" TNM_NET = wrc_gtp_101_clk;
TIMESPEC TS_wrc_gtp_101_clk = PERIOD "wrc_gtp_101_clk" 8 ns HIGH 50%;
NET "gen_sata.inst_gt_123/ch0_gtp_clkout_int[1]" TNM_NET = wrc_gtp_123_clk;
NET "gen_sata.inst_sata/inst_gt_123/ch0_gtp_clkout_int[1]" TNM_NET = wrc_gtp_123_clk;
TIMESPEC TS_wrc_gtp_123_clk = PERIOD "wrc_gtp_123_clk" 8 ns HIGH 50%;
......@@ -91,10 +91,14 @@
`define ADDR_FMC_ADC_100MS_CSR_POST_SAMPLES 'h34
`define ADDR_FMC_ADC_100MS_CSR_SAMPLES_CNT 'h38
`define ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH1 'h80
`define ADDR_MASK_FMC_ADC_100MS_CSR_FMC_ADC_CH1 'h1e0
`define FMC_ADC_100MS_CSR_FMC_ADC_CH1_SIZE 32
`define ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH2 'hc0
`define ADDR_MASK_FMC_ADC_100MS_CSR_FMC_ADC_CH2 'h1e0
`define FMC_ADC_100MS_CSR_FMC_ADC_CH2_SIZE 32
`define ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH3 'h100
`define ADDR_MASK_FMC_ADC_100MS_CSR_FMC_ADC_CH3 'h1e0
`define FMC_ADC_100MS_CSR_FMC_ADC_CH3_SIZE 32
`define ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH4 'h140
`define ADDR_MASK_FMC_ADC_100MS_CSR_FMC_ADC_CH4 'h1e0
`define FMC_ADC_100MS_CSR_FMC_ADC_CH4_SIZE 32
......@@ -4,8 +4,11 @@
`define SVEC_REF_FMC_ADC_100M_MMAP_SIZE 65536
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_METADATA 'h4000
`define ADDR_MASK_SVEC_REF_FMC_ADC_100M_MMAP_METADATA 'hffc0
`define SVEC_REF_FMC_ADC_100M_MMAP_METADATA_SIZE 64
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE 'h6000
`define ADDR_MASK_SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE 'he000
`define SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE_SIZE 8192
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE 'h8000
`define ADDR_MASK_SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE 'he000
`define SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE_SIZE 8192
......@@ -4,6 +4,7 @@
files = [
"spec_sata_fmc_adc_100Ms.vhd",
"spec_sata.vhd",
"sata_controller.vhd",
"../../cheby/fmc_adc_sata_regs.vhd",
"../../cheby/spec_ref_fmc_adc_100Ms_mmap.vhd",
......@@ -22,4 +23,5 @@ modules = {
"https://ohwr.org/project/gn4124-core.git",
"https://ohwr.org/project/spec.git",
],
"system" : [ "xilinx" ],
}
This diff is collapsed.
......@@ -551,219 +551,28 @@ begin -- architecture arch
-- SATA
gen_sata: if True generate
signal sata_rdy, sata_rx, sata_rst : std_logic_vector(1 downto 0);
signal sata_rx_data_rd, sata_tx_data_wr : std_logic_vector (1 downto 0);
signal sata_rx_data0, sata_rx_data1 : std_logic_vector(31 downto 0);
signal sata_tx_data0, sata_tx_data1 : std_logic_vector(31 downto 0);
signal gtp_rx_data0, gtp_tx_data0 : std_logic_vector(7 downto 0);
signal gtp_rx_k0, gtp_tx_k0, gtp_rx_clk0 : std_logic;
signal gtp_rx_data1, gtp_tx_data1 : std_logic_vector(7 downto 0);
signal gtp_rx_k1, gtp_tx_k1, gtp_rx_clk1 : std_logic;
signal clk_125m_gtp123_buf, clk_125m_gtp101_buf : std_logic;
begin
inst_sata_regs: entity work.sata_regs
port map (
rst_n_i => rst_sys_62m5_n,
clk_i => clk_sys_62m5,
wb_i => cnx_slave_in(c_WB_SLAVE_SATA),
wb_o => cnx_slave_out(c_WB_SLAVE_SATA),
rdy0_i => sata_rdy(0),
rdy1_i => sata_rdy(1),
rx0_i => sata_rx(0),
rx1_i => sata_rx(1),
rst0_o => sata_rst(0),
rst1_o => sata_rst(1),
rx_data_0_i => sata_rx_data0,
rx_data_0_rd_o => sata_rx_data_rd(0),
rx_data_1_i => sata_rx_data1,
rx_data_1_rd_o => sata_rx_data_rd(1),
tx_data_0_o => sata_tx_data0,
tx_data_0_wr_o => sata_tx_data_wr(0),
tx_data_1_o => sata_tx_data1,
tx_data_1_wr_o => sata_tx_data_wr(1)
);
cmp_ibufgds_gtp_123 : IBUFGDS
inst_sata: entity work.spec_sata
generic map (
DIFF_TERM => TRUE,
IBUF_LOW_PWR => TRUE,
IOSTANDARD => "DEFAULT")
port map (
O => clk_125m_gtp123_buf,
I => clk_125m_clk0_123_p_i,
IB => clk_125m_clk0_123_n_i);
cmp_ibufgds_gtp_101 : IBUFGDS
generic map (
DIFF_TERM => TRUE,
IBUF_LOW_PWR => TRUE,
IOSTANDARD => "DEFAULT")
port map (
O => clk_125m_gtp101_buf,
I => clk_125m_clk1_101_p_i,
IB => clk_125m_clk1_101_n_i);
inst_gt_101: entity work.wr_gtp_phy_spartan6
generic map (
g_simulation => g_simulation,
g_force_disparity => 0,
g_enable_ch0 => 0, -- For FMC
g_enable_ch1 => 1 -- For SATA
g_simulation => g_simulation
)
port map (
-- Channel 0 is not used.
gtp0_clk_i => '0',
ch0_ref_clk_i => '0',
ch0_tx_data_i => (others => '0'),
ch0_tx_k_i => '0',
ch0_tx_disparity_o => open,
ch0_tx_enc_err_o => open,
ch0_rx_rbclk_o => open,
ch0_rx_data_o => open,
ch0_rx_k_o => open,
ch0_rx_enc_err_o => open,
ch0_rx_bitslide_o => open,
ch0_rst_i => '1',
ch0_loopen_i => '0',
ch0_loopen_vec_i => (others => '0'),
ch0_tx_prbs_sel_i => "000",
ch0_rdy_o => open,
-- Channel 1 is SATA!
gtp1_clk_i => clk_125m_gtp101_buf,
ch1_ref_clk_i => clk_ref_125m,
ch1_tx_data_i => gtp_tx_data0,
ch1_tx_k_i => gtp_tx_k0,
ch1_tx_disparity_o => open,
ch1_tx_enc_err_o => open,
ch1_rx_data_o => gtp_rx_data0,
ch1_rx_rbclk_o => gtp_rx_clk0,
ch1_rx_k_o => gtp_rx_k0,
ch1_rx_enc_err_o => open,
ch1_rx_bitslide_o => open,
ch1_rst_i => sata_rst(0),
ch1_loopen_i => '0',
ch1_loopen_vec_i => (others => '0'),
ch1_tx_prbs_sel_i => (others => '0'),
ch1_rdy_o => sata_rdy(0),
ch0_ref_sel_pll => "100",
ch1_ref_sel_pll => "100",
pad_txn0_o => open,
pad_txp0_o => open,
pad_rxn0_i => '0',
pad_rxp0_i => '0',
pad_txn1_o => sata0_txn_o,
pad_txp1_o => sata0_txp_o,
pad_rxn1_i => sata0_rxn_i,
pad_rxp1_i => sata0_rxp_i
);
inst_sata_ctrl0: entity work.sata_controller
port map (
clk_62m5_i => clk_sys_62m5,
rst_62m5_n_i => rst_sys_62m5_n,
tx_clk_i => clk_ref_125m,
rx_clk_i => gtp_rx_clk0,
reg_tx_data_i => sata_tx_data0(7 downto 0),
reg_tx_wr_i => sata_tx_data_wr(0),
tx_data_o => gtp_tx_data0,
tx_k_o => gtp_tx_k0,
reg_rx_data_o => sata_rx_data0(7 downto 0),
reg_rx_rd_i => sata_rx_data_rd(0),
reg_rx_o => sata_rx(0),
rx_data_i => gtp_rx_data0,
rx_k_i => gtp_rx_k0
);
sata_rx_data0 (31 downto 8) <= (others => '0');
inst_gt_123: entity work.wr_gtp_phy_spartan6
generic map (
g_simulation => g_simulation,
g_force_disparity => 0,
g_enable_ch0 => 1, -- For SATA1
g_enable_ch1 => 0 -- For SFP
)
port map (
-- Channel 0 is SATA!
gtp0_clk_i => clk_125m_gtp123_buf,
ch0_ref_clk_i => clk_ref_125m,
ch0_tx_data_i => gtp_tx_data1,
ch0_tx_k_i => gtp_tx_k1,
ch0_tx_disparity_o => open,
ch0_tx_enc_err_o => open,
ch0_rx_data_o => gtp_rx_data1,
ch0_rx_rbclk_o => gtp_rx_clk1,
ch0_rx_k_o => gtp_rx_k1,
ch0_rx_enc_err_o => open,
ch0_rx_bitslide_o => open,
ch0_rst_i => sata_rst(1),
ch0_loopen_i => '0',
ch0_loopen_vec_i => (others => '0'),
ch0_tx_prbs_sel_i => (others => '0'),
ch0_rdy_o => sata_rdy(1),
-- Channel 0 is not used.
gtp1_clk_i => '0',
ch1_ref_clk_i => '0',
ch1_tx_data_i => (others => '0'),
ch1_tx_k_i => '0',
ch1_tx_disparity_o => open,
ch1_tx_enc_err_o => open,
ch1_rx_rbclk_o => open,
ch1_rx_data_o => open,
ch1_rx_k_o => open,
ch1_rx_enc_err_o => open,
ch1_rx_bitslide_o => open,
ch1_rst_i => '1',
ch1_loopen_i => '0',
ch1_loopen_vec_i => (others => '0'),
ch1_tx_prbs_sel_i => "000",
ch1_rdy_o => open,
ch0_ref_sel_pll => "100",
ch1_ref_sel_pll => "100",
pad_txn1_o => open,
pad_txp1_o => open,
pad_rxn1_i => '0',
pad_rxp1_i => '0',
pad_txn0_o => sata1_txn_o,
pad_txp0_o => sata1_txp_o,
pad_rxn0_i => sata1_rxn_i,
pad_rxp0_i => sata1_rxp_i
clk_sys_62m5_i => clk_sys_62m5,
rst_sys_62m5_n_i => rst_sys_62m5_n,
clk_ref_125m_i => clk_ref_125m,
clk_125m_clk0_123_n_i => clk_125m_clk0_123_n_i,
clk_125m_clk0_123_p_i => clk_125m_clk0_123_p_i,
clk_125m_clk1_101_n_i => clk_125m_clk1_101_n_i,
clk_125m_clk1_101_p_i => clk_125m_clk1_101_p_i,
sata0_txp_o => sata0_txp_o,
sata0_txn_o => sata0_txn_o,
sata0_rxp_i => sata0_rxp_i,
sata0_rxn_i => sata0_rxn_i,
sata1_txp_o => sata1_txp_o,
sata1_txn_o => sata1_txn_o,
sata1_rxp_i => sata1_rxp_i,
sata1_rxn_i => sata1_rxn_i,
wb_i => cnx_slave_in(c_WB_SLAVE_SATA),
wb_o => cnx_slave_out(c_WB_SLAVE_SATA)
);
gen_chipscope: if True generate
component chipscope_icon_sata
PORT (
CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);
CONTROL1 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0));
end component;
component chipscope_ila_sata
PORT (
CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0);
CLK : IN STD_LOGIC;
TRIG0 : IN STD_LOGIC_VECTOR(9 DOWNTO 0));
end component;
signal control0, control1: std_logic_vector(35 downto 0);
begin
inst_ila_icon : chipscope_icon_sata
port map (
CONTROL0 => CONTROL0,
CONTROL1 => CONTROL1);
inst_ila_gtp0_rx : chipscope_ila_sata
port map (
CONTROL => CONTROL0,
CLK => gtp_rx_clk0,
TRIG0 (7 downto 0)=> gtp_rx_data0,
TRIG0 (8) => gtp_rx_k0,
TRIG0 (9) => sata_rdy(0));
inst_ila_gtp0_tx : chipscope_ila_sata
port map (
CONTROL => CONTROL1,
CLK => clk_ref_125m,
TRIG0 (7 downto 0)=> gtp_tx_data0,
TRIG0 (8) => gtp_tx_k0,
TRIG0 (9) => sata_rst(0));
end generate;
end generate;
end architecture arch;
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