Commit a3a2724b authored by Federico Vaga's avatar Federico Vaga

Merge branch 'release/v5.0.0' into master

parents 7cc993f1 c0a9675b
......@@ -6,7 +6,7 @@
Changelog
=========
5.0.0 - 2020-01-01
5.0.0 - 2021-02-11
==================
Changes
-------
......@@ -26,9 +26,9 @@ Added
- add tool to get/set run-time calibration data
- periodically update gain calibration for DAC and ADC
- trigger time
- MBLT support for SVEC
Removed
-------
- library is not supported anymore, use adc-lib (https://www.ohwr.org/projects/adc-lib)
- fald-acq tool is not supported anymore, use adc-acq from adc-lib (https://www.ohwr.org/projects/adc-lib)
......@@ -22,7 +22,7 @@
# -- Project information -----------------------------------------------------
project = 'FMC-ADC-100M-14B-4CHA'
copyright = u'2013-2020, CERN, documentation released under CC-BY-SA-4.0'
copyright = u'2013-2021, CERN, documentation released under CC-BY-SA-4.0'
author = 'Matthieu Cattin, Dimitris Lampridis <dimitrios.lampridis@cern.ch>, Federico Vaga <federico.vaga@cern.ch>'
# The suffix(es) of source filenames.
......
......@@ -9,7 +9,7 @@ PDF=$(SVG:.svg=.pdf)
all: $(PDF)
%.pdf : %.svg
inkscape --without-gui $< -A $@
inkscape $< -o $@ || inkscape --without-gui $< -A $@
clean:
rm -f $(PDF)
......
......@@ -103,12 +103,21 @@ There are two different Wishbone bus interconnects in the design.
Mapped WB bus (blue)
This bus connects all the peripherals to the GN4142 core.
Data: 32-bit, address: 32-bit (word aligned), clock: system clock (125MHz).
Data: 32-bit, address: 32-bit (word aligned),
Clock: system clock (125MHz) and system clock / 2 (62.5MHz), see note below.
ADC core to memory controller (orange)
This bus is used to write samples from the ADC core to the DDR memory.
Data: 64-bit, address: 32-bit (word aligned), clock: system clock (125MHz).
.. note::
The SPEC-base core works internally at 62.5MHz, especially for the WR PTP
core. On the other hand, the ADC core needs to work at 125MHz in order to
be able to retrieve and process the incoming ADC samples at 100MHz (from
the ``fs_clk`` domain). Therefore, a Wishbone clock crossing component is
inserted between the SPEC-base core and the ADC core. With this topology,
only the SPEC-base core runs at a lower frequency.
Note that some of the cores from the `General Cores`_ library are
based on cores from `OpenCores`_. Therefore, the documentation for
those cores is hosted on the OpenCores website.
......@@ -116,28 +125,31 @@ those cores is hosted on the OpenCores website.
Clock Domains
~~~~~~~~~~~~~
The SPEC version of the fmc-adc design has five different clock domains.
The SPEC version of the fmc-adc design has six different clock domains.
They are listed in the following table.
+-----------------+-----------------+-----------------+-----------------+
| Name | Description | Frequency | Source |
+=================+=================+=================+=================+
| ``sys_clk_125`` | Main system | 125.00 MHz | 20MHz TCXO |
| | clock | | (carrier) |
+-----------------+-----------------+-----------------+-----------------+
| ``ddr_clk`` | DDR interface | 333.33 MHz | 20MHz TCXO |
| | clock | | (carrier) |
+-----------------+-----------------+-----------------+-----------------+
| ``fs_clk`` | Sampling clock | 100.00 MHz | 400MHz LTC2174 |
| | | | (mezzanine) |
+-----------------+-----------------+-----------------+-----------------+
| ``serdes_clk`` | ADC data | 800.00 MHz | 400MHz LTC2174 |
| | de-serialiser | | (mezzanine) |
| | clock | | |
+-----------------+-----------------+-----------------+-----------------+
| ``p2l_clk`` | Local bus clock | 200.00 MHz | 200MHz GN4124 |
| | | | (carrier) |
+-----------------+-----------------+-----------------+-----------------+
+------------------+-----------------+-----------------+-----------------+
| Name | Description | Frequency | Source |
+==================+=================+=================+=================+
| ``clk_ref_125m`` | Main system | 125.00 MHz | 125MHz VCXO |
| | clock | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
| ``clk_sys_62m5`` | System clock | 62.50 MHz | 125MHz VCXO |
| | for spec-base | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
| ``clk_333m_ddr`` | DDR interface | 333.33 MHz | 125MHz VCXO |
| | clock | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
| ``fs_clk`` | Sampling clock | 100.00 MHz | 400MHz LTC2174 |
| | | | (mezzanine) |
+------------------+-----------------+-----------------+-----------------+
| ``adc_dco`` | ADC data | 800.00 MHz | 400MHz LTC2174 |
| | de-serialiser | | (mezzanine) |
| | clock | | |
+------------------+-----------------+-----------------+-----------------+
| ``p2l_clk`` | PCI to Local | 200.00 MHz | 200MHz GN4124 |
| | bus clock | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
SVEC (VME64x carrier)
---------------------
......@@ -167,39 +179,49 @@ ADC cores to memory controllers (2x, orange)
Data: 64-bit, address: 32-bit (word aligned), clock: system clock (125MHz).
.. note::
The VME64x core cannot work with a clock frequency as high as
125MHz, therefore it is clocked with half the system clock
frequency. As the fmc-adc core needs 125MHz to work properly, a
Wishbone clock crossing component is inserted between the VME64x core
and the first Wishbone crossbar component. With this topology, only
the VME64x core runs at a lower frequency.
The SVEC-base core works internally at 62.5MHz, especially for the WR PTP
core. On the other hand, the ADC core needs to work at 125MHz in order to
be able to retrieve and process the incoming ADC samples at 100MHz (from
the ``fs_clk`` domain). Therefore, a Wishbone clock crossing component is
inserted between the SVEC-base core and the ADC core. With this topology,
only the SVEC-base core runs at a lower frequency.
Note that some of the cores from the `General Cores`_ library are
based on cores from `OpenCores`_. Therefore, the documentation for
those cores is hosted on the OpenCores website.
Clock Domains
~~~~~~~~~~~~~
The SVEC version of the fmc-adc design has five different clock domains.
The SVEC version of the fmc-adc design has seven different clock domains.
They are listed in the following table.
+-----------------+-----------------+-----------------+-----------------+
| Name | Description | Frequency | Source |
+=================+=================+=================+=================+
| sys_clk_125 | Main system | 125.00 MHz | 20MHz TCXO |
| | clock | | (carrier) |
+-----------------+-----------------+-----------------+-----------------+
| sys_clk_62_5 | System clock / | 62.50 MHz | 20MHz TCXO |
| | 2 | | (carrier) |
+-----------------+-----------------+-----------------+-----------------+
| ddr_clk | DDR interface | 333.33 MHz | 20MHz TCXO |
| | clock | | (carrier) |
+-----------------+-----------------+-----------------+-----------------+
| fs_clk | Sampling clock | 100.00 MHz | 400MHz LTC2174 |
| | | | (mezzanine) |
+-----------------+-----------------+-----------------+-----------------+
| serdes_clk | ADC data | 800.00 MHz | 400MHz LTC2174 |
| | de-serialiser | | (mezzanine) |
| | clock | | |
+-----------------+-----------------+-----------------+-----------------+
+------------------+-----------------+-----------------+-----------------+
| Name | Description | Frequency | Source |
+==================+=================+=================+=================+
| ``clk_ref_125m`` | Main system | 125.00 MHz | 125MHz VCXO |
| | clock | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
| ``clk_sys_62m5`` | System clock | 62.50 MHz | 125MHz VCXO |
| | for spec-base | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
| ``clk_ddr_333m`` | DDR interface | 333.33 MHz | 125MHz VCXO |
| | clock | | (carrier) |
+------------------+-----------------+-----------------+-----------------+
| ``fs_clk1`` | Sampling clock | 100.00 MHz | 400MHz LTC2174 |
| | | | (mezzanine #1) |
+------------------+-----------------+-----------------+-----------------+
| ``adc_dco1`` | ADC data | 800.00 MHz | 400MHz LTC2174 |
| | de-serialiser | | (mezzanine #1) |
| | clock | | |
+------------------+-----------------+-----------------+-----------------+
| ``fs_clk2`` | Sampling clock | 100.00 MHz | 400MHz LTC2174 |
| | | | (mezzanine #2) |
+------------------+-----------------+-----------------+-----------------+
| ``adc_dco2`` | ADC data | 800.00 MHz | 400MHz LTC2174 |
| | de-serialiser | | (mezzanine #2) |
| | clock | | |
+------------------+-----------------+-----------------+-----------------+
Common Cores
------------
......
......@@ -3,7 +3,6 @@
# SPDX-License-Identifier: CC0-1.0
SIM =../testbench/include
SW =../../software/include/hw
SOURCES = $(wildcard *.cheby)
TARGETS = $(SOURCES:.cheby=.vhd)
......@@ -13,8 +12,7 @@ all: $(TARGETS)
.PHONY: $(TARGETS)
$(TARGETS): %.vhd : %.cheby
@echo "\n\033[34m\033[1m-> Processing file $<\033[0m"
@cheby -i $< --gen-hdl=$@
@cheby -i $< \
--gen-consts=$(SIM)/$(@:.vhd=.v) \
--gen-c=$(SW)/$(@:.vhd=.h)
@echo -e "\n\033[34m\033[1m-> Processing file $<\033[0m"
cheby -i $< --gen-hdl=$@
cheby -i $< --gen-consts=$(SIM)/$(@:.vhd=.v)
cheby -i $< --gen-c=../../software/include/hw/$(<:.cheby=.h)
......@@ -40,7 +40,6 @@ entity fmc_adc_100ms_channel_regs is
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Wires and registers
fmc_adc_100ms_ch_i : in t_fmc_adc_100ms_ch_master_in;
fmc_adc_100ms_ch_o : out t_fmc_adc_100ms_ch_master_out
......@@ -48,8 +47,9 @@ entity fmc_adc_100ms_channel_regs is
end fmc_adc_100ms_channel_regs;
architecture syn of fmc_adc_100ms_channel_regs is
signal rd_int : std_logic;
signal wr_int : std_logic;
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;
......@@ -57,17 +57,32 @@ architecture syn of fmc_adc_100ms_channel_regs is
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal ctl_ssr_reg : std_logic_vector(6 downto 0);
signal ctl_wreq : std_logic;
signal ctl_wack : std_logic;
signal calib_gain_reg : std_logic_vector(15 downto 0);
signal calib_offset_reg : std_logic_vector(15 downto 0);
signal calib_wreq : std_logic;
signal calib_wack : std_logic;
signal sat_val_reg : std_logic_vector(14 downto 0);
signal sat_wreq : std_logic;
signal sat_wack : std_logic;
signal trig_thres_val_reg : std_logic_vector(15 downto 0);
signal trig_thres_hyst_reg : std_logic_vector(15 downto 0);
signal trig_thres_wreq : std_logic;
signal trig_thres_wack : std_logic;
signal trig_dly_reg : std_logic_vector(31 downto 0);
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal trig_dly_wreq : std_logic;
signal trig_dly_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
......@@ -79,7 +94,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -90,7 +105,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -98,144 +113,183 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- 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 ctl
fmc_adc_100ms_ch_o.ctl_ssr <= ctl_ssr_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
ctl_ssr_reg <= "0000000";
ctl_wack <= '0';
else
if ctl_wreq = '1' then
ctl_ssr_reg <= wr_dat_d0(6 downto 0);
end if;
ctl_wack <= ctl_wreq;
end if;
end if;
end process;
-- Register sta
-- Register calib
fmc_adc_100ms_ch_o.calib_gain <= calib_gain_reg;
fmc_adc_100ms_ch_o.calib_offset <= calib_offset_reg;
fmc_adc_100ms_ch_o.sat_val <= sat_val_reg;
fmc_adc_100ms_ch_o.trig_thres_val <= trig_thres_val_reg;
fmc_adc_100ms_ch_o.trig_thres_hyst <= trig_thres_hyst_reg;
fmc_adc_100ms_ch_o.trig_dly <= trig_dly_reg;
-- Process for write requests.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
ctl_ssr_reg <= "0000000";
calib_gain_reg <= "0000000000000000";
calib_offset_reg <= "0000000000000000";
calib_wack <= '0';
else
if calib_wreq = '1' then
calib_gain_reg <= wr_dat_d0(15 downto 0);
calib_offset_reg <= wr_dat_d0(31 downto 16);
end if;
calib_wack <= calib_wreq;
end if;
end if;
end process;
-- Register sat
fmc_adc_100ms_ch_o.sat_val <= sat_val_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
sat_val_reg <= "000000000000000";
sat_wack <= '0';
else
if sat_wreq = '1' then
sat_val_reg <= wr_dat_d0(14 downto 0);
end if;
sat_wack <= sat_wreq;
end if;
end if;
end process;
-- Register trig_thres
fmc_adc_100ms_ch_o.trig_thres_val <= trig_thres_val_reg;
fmc_adc_100ms_ch_o.trig_thres_hyst <= trig_thres_hyst_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
trig_thres_val_reg <= "0000000000000000";
trig_thres_hyst_reg <= "0000000000000000";
trig_dly_reg <= "00000000000000000000000000000000";
trig_thres_wack <= '0';
else
wr_ack_int <= '0';
case wb_i.adr(4 downto 2) is
when "000" =>
-- Register ctl
if wr_int = '1' then
ctl_ssr_reg <= wb_i.dat(6 downto 0);
end if;
wr_ack_int <= wr_int;
when "001" =>
-- Register sta
when "010" =>
-- Register calib
if wr_int = '1' then
calib_gain_reg <= wb_i.dat(15 downto 0);
calib_offset_reg <= wb_i.dat(31 downto 16);
end if;
wr_ack_int <= wr_int;
when "011" =>
-- Register sat
if wr_int = '1' then
sat_val_reg <= wb_i.dat(14 downto 0);
end if;
wr_ack_int <= wr_int;
when "100" =>
-- Register trig_thres
if wr_int = '1' then
trig_thres_val_reg <= wb_i.dat(15 downto 0);
trig_thres_hyst_reg <= wb_i.dat(31 downto 16);
end if;
wr_ack_int <= wr_int;
when "101" =>
-- Register trig_dly
if wr_int = '1' then
trig_dly_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when others =>
wr_ack_int <= wr_int;
end case;
if trig_thres_wreq = '1' then
trig_thres_val_reg <= wr_dat_d0(15 downto 0);
trig_thres_hyst_reg <= wr_dat_d0(31 downto 16);
end if;
trig_thres_wack <= trig_thres_wreq;
end if;
end if;
end process;
-- Process for registers read.
-- Register trig_dly
fmc_adc_100ms_ch_o.trig_dly <= trig_dly_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
trig_dly_reg <= "00000000000000000000000000000000";
trig_dly_wack <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(4 downto 2) is
when "000" =>
-- ctl
reg_rdat_int(6 downto 0) <= ctl_ssr_reg;
rd_ack1_int <= rd_int;
when "001" =>
-- sta
reg_rdat_int(15 downto 0) <= fmc_adc_100ms_ch_i.sta_val;
rd_ack1_int <= rd_int;
when "010" =>
-- calib
reg_rdat_int(15 downto 0) <= calib_gain_reg;
reg_rdat_int(31 downto 16) <= calib_offset_reg;
rd_ack1_int <= rd_int;
when "011" =>
-- sat
reg_rdat_int(14 downto 0) <= sat_val_reg;
rd_ack1_int <= rd_int;
when "100" =>
-- trig_thres
reg_rdat_int(15 downto 0) <= trig_thres_val_reg;
reg_rdat_int(31 downto 16) <= trig_thres_hyst_reg;
rd_ack1_int <= rd_int;
when "101" =>
-- trig_dly
reg_rdat_int <= trig_dly_reg;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
if trig_dly_wreq = '1' then
trig_dly_reg <= wr_dat_d0;
end if;
trig_dly_wack <= trig_dly_wreq;
end if;
end if;
end process;
-- Process for write requests.
process (wr_adr_d0, wr_req_d0, ctl_wack, calib_wack, sat_wack, trig_thres_wack, trig_dly_wack) begin
ctl_wreq <= '0';
calib_wreq <= '0';
sat_wreq <= '0';
trig_thres_wreq <= '0';
trig_dly_wreq <= '0';
case wr_adr_d0(4 downto 2) is
when "000" =>
-- Reg ctl
ctl_wreq <= wr_req_d0;
wr_ack_int <= ctl_wack;
when "001" =>
-- Reg sta
wr_ack_int <= wr_req_d0;
when "010" =>
-- Reg calib
calib_wreq <= wr_req_d0;
wr_ack_int <= calib_wack;
when "011" =>
-- Reg sat
sat_wreq <= wr_req_d0;
wr_ack_int <= sat_wack;
when "100" =>
-- Reg trig_thres
trig_thres_wreq <= wr_req_d0;
wr_ack_int <= trig_thres_wack;
when "101" =>
-- Reg trig_dly
trig_dly_wreq <= wr_req_d0;
wr_ack_int <= trig_dly_wack;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
process (adr_int, rd_req_int, ctl_ssr_reg, fmc_adc_100ms_ch_i.sta_val, calib_gain_reg, calib_offset_reg, sat_val_reg, trig_thres_val_reg, trig_thres_hyst_reg, trig_dly_reg) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
case wb_i.adr(4 downto 2) is
when "000" =>
-- ctl
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "001" =>
-- sta
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "010" =>
-- calib
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "011" =>
-- sat
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "100" =>
-- trig_thres
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "101" =>
-- trig_dly
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
rd_dat_d0 <= (others => 'X');
case adr_int(4 downto 2) is
when "000" =>
-- Reg ctl
rd_ack_d0 <= rd_req_int;
rd_dat_d0(6 downto 0) <= ctl_ssr_reg;
rd_dat_d0(31 downto 7) <= (others => '0');
when "001" =>
-- Reg sta
rd_ack_d0 <= rd_req_int;
rd_dat_d0(15 downto 0) <= fmc_adc_100ms_ch_i.sta_val;
rd_dat_d0(31 downto 16) <= (others => '0');
when "010" =>
-- Reg calib
rd_ack_d0 <= rd_req_int;
rd_dat_d0(15 downto 0) <= calib_gain_reg;
rd_dat_d0(31 downto 16) <= calib_offset_reg;
when "011" =>
-- Reg sat
rd_ack_d0 <= rd_req_int;
rd_dat_d0(14 downto 0) <= sat_val_reg;
rd_dat_d0(31 downto 15) <= (others => '0');
when "100" =>
-- Reg trig_thres
rd_ack_d0 <= rd_req_int;
rd_dat_d0(15 downto 0) <= trig_thres_val_reg;
rd_dat_d0(31 downto 16) <= trig_thres_hyst_reg;
when "101" =>
-- Reg trig_dly
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= trig_dly_reg;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
......@@ -12,6 +12,7 @@ memory-map:
x-hdl:
busgroup: True
iogroup: fmc_adc_100ms_csr
pipeline: wr,rd
children:
- reg:
name: ctl
......
......@@ -86,7 +86,6 @@ entity fmc_adc_100ms_csr is
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Wires and registers
fmc_adc_100ms_csr_i : in t_fmc_adc_100ms_csr_master_in;
fmc_adc_100ms_csr_o : out t_fmc_adc_100ms_csr_master_out;
......@@ -110,8 +109,9 @@ entity fmc_adc_100ms_csr is
end fmc_adc_100ms_csr;
architecture syn of fmc_adc_100ms_csr is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal adr_int : std_logic_vector(8 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;
......@@ -122,51 +122,79 @@ architecture syn of fmc_adc_100ms_csr is
signal ctl_offset_dac_clr_n_reg : std_logic;
signal ctl_trig_led_reg : std_logic;
signal ctl_acq_led_reg : std_logic;
signal ctl_wreq : std_logic;
signal ctl_wack : std_logic;
signal trig_en_ext_reg : std_logic;
signal trig_en_time_reg : std_logic;
signal trig_en_ch1_reg : std_logic;
signal trig_en_ch2_reg : std_logic;
signal trig_en_ch3_reg : std_logic;
signal trig_en_ch4_reg : std_logic;
signal trig_en_wreq : std_logic;
signal trig_en_wack : std_logic;
signal trig_pol_ext_reg : std_logic;
signal trig_pol_ch1_reg : std_logic;
signal trig_pol_ch2_reg : std_logic;
signal trig_pol_ch3_reg : std_logic;
signal trig_pol_ch4_reg : std_logic;
signal trig_pol_wreq : std_logic;
signal trig_pol_wack : std_logic;
signal ext_trig_dly_reg : std_logic_vector(31 downto 0);
signal ext_trig_dly_wreq : std_logic;
signal ext_trig_dly_wack : std_logic;
signal sw_trig_wreq : std_logic;
signal shots_nbr_reg : std_logic_vector(15 downto 0);
signal shots_wreq : std_logic;
signal shots_wack : std_logic;
signal downsample_reg : std_logic_vector(31 downto 0);
signal downsample_wreq : std_logic;
signal downsample_wack : std_logic;
signal pre_samples_reg : std_logic_vector(31 downto 0);
signal pre_samples_wreq : std_logic;
signal pre_samples_wack : std_logic;
signal post_samples_reg : std_logic_vector(31 downto 0);
signal post_samples_wreq : std_logic;
signal post_samples_wack : std_logic;
signal fmc_adc_ch1_re : std_logic;
signal fmc_adc_ch1_we : std_logic;
signal fmc_adc_ch1_wt : std_logic;
signal fmc_adc_ch1_rt : std_logic;
signal fmc_adc_ch1_tr : std_logic;
signal fmc_adc_ch1_wack : std_logic;
signal fmc_adc_ch1_rack : std_logic;
signal fmc_adc_ch2_re : std_logic;
signal fmc_adc_ch2_we : std_logic;
signal fmc_adc_ch2_wt : std_logic;
signal fmc_adc_ch2_rt : std_logic;
signal fmc_adc_ch2_tr : std_logic;
signal fmc_adc_ch2_wack : std_logic;
signal fmc_adc_ch2_rack : std_logic;
signal fmc_adc_ch3_re : std_logic;
signal fmc_adc_ch3_we : std_logic;
signal fmc_adc_ch3_wt : std_logic;
signal fmc_adc_ch3_rt : std_logic;
signal fmc_adc_ch3_tr : std_logic;
signal fmc_adc_ch3_wack : std_logic;
signal fmc_adc_ch3_rack : std_logic;
signal fmc_adc_ch4_re : std_logic;
signal fmc_adc_ch4_we : std_logic;
signal fmc_adc_ch4_wt : std_logic;
signal fmc_adc_ch4_rt : std_logic;
signal fmc_adc_ch4_tr : std_logic;
signal fmc_adc_ch4_wack : std_logic;
signal fmc_adc_ch4_rack : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal rd_req_d0 : std_logic;
signal rd_adr_d0 : std_logic_vector(8 downto 2);
signal rd_ack_d0 : std_logic;
signal rd_dat_d0 : std_logic_vector(31 downto 0);
signal wr_req_d0 : std_logic;
signal wr_dat_d0 : std_logic_vector(31 downto 0);
signal wr_sel_d0 : std_logic_vector(3 downto 0);
signal wr_ack_d0 : std_logic;
begin
-- WB decode signals
adr_int <= wb_i.adr(8 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
......@@ -178,7 +206,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -189,7 +217,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -197,36 +225,225 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- pipelining for rd-in+rd-out+wr-in+wr-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_req_d0 <= '0';
rd_ack_int <= '0';
wr_req_d0 <= '0';
wr_ack_int <= '0';
else
rd_req_d0 <= rd_req_int;
rd_adr_d0 <= adr_int;
rd_ack_int <= rd_ack_d0;
wb_o.dat <= rd_dat_d0;
wr_req_d0 <= wr_req_int;
wr_dat_d0 <= wb_i.dat;
wr_sel_d0 <= wb_i.sel;
wr_ack_int <= wr_ack_d0;
end if;
end if;
end process;
-- Register ctl
fmc_adc_100ms_csr_o.ctl_fsm_cmd <= wr_dat_d0(1 downto 0);
fmc_adc_100ms_csr_o.ctl_fmc_clk_oe <= ctl_fmc_clk_oe_reg;
fmc_adc_100ms_csr_o.ctl_offset_dac_clr_n <= ctl_offset_dac_clr_n_reg;
fmc_adc_100ms_csr_o.ctl_man_bitslip <= wr_dat_d0(4);
fmc_adc_100ms_csr_o.ctl_trig_led <= ctl_trig_led_reg;
fmc_adc_100ms_csr_o.ctl_acq_led <= ctl_acq_led_reg;
fmc_adc_100ms_csr_o.ctl_clear_trig_stat <= wr_dat_d0(8);
fmc_adc_100ms_csr_o.ctl_calib_apply <= wr_dat_d0(15);
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
ctl_fmc_clk_oe_reg <= '0';
ctl_offset_dac_clr_n_reg <= '0';
ctl_trig_led_reg <= '0';
ctl_acq_led_reg <= '0';
ctl_wack <= '0';
else
if ctl_wreq = '1' then
ctl_fmc_clk_oe_reg <= wr_dat_d0(2);
ctl_offset_dac_clr_n_reg <= wr_dat_d0(3);
ctl_trig_led_reg <= wr_dat_d0(6);
ctl_acq_led_reg <= wr_dat_d0(7);
end if;
ctl_wack <= ctl_wreq;
end if;
end if;
end process;
fmc_adc_100ms_csr_o.ctl_wr <= ctl_wack;
-- Register sta
-- Register trig_stat
-- Register trig_en
fmc_adc_100ms_csr_o.trig_en_ext <= trig_en_ext_reg;
fmc_adc_100ms_csr_o.trig_en_sw <= wr_dat_d0(1);
fmc_adc_100ms_csr_o.trig_en_time <= trig_en_time_reg;
fmc_adc_100ms_csr_o.trig_en_aux_time <= wr_dat_d0(5);
fmc_adc_100ms_csr_o.trig_en_ch1 <= trig_en_ch1_reg;
fmc_adc_100ms_csr_o.trig_en_ch2 <= trig_en_ch2_reg;
fmc_adc_100ms_csr_o.trig_en_ch3 <= trig_en_ch3_reg;
fmc_adc_100ms_csr_o.trig_en_ch4 <= trig_en_ch4_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
trig_en_ext_reg <= '0';
trig_en_time_reg <= '0';
trig_en_ch1_reg <= '0';
trig_en_ch2_reg <= '0';
trig_en_ch3_reg <= '0';
trig_en_ch4_reg <= '0';
trig_en_wack <= '0';
else
if trig_en_wreq = '1' then
trig_en_ext_reg <= wr_dat_d0(0);
trig_en_time_reg <= wr_dat_d0(4);
trig_en_ch1_reg <= wr_dat_d0(8);
trig_en_ch2_reg <= wr_dat_d0(9);
trig_en_ch3_reg <= wr_dat_d0(10);
trig_en_ch4_reg <= wr_dat_d0(11);
end if;
trig_en_wack <= trig_en_wreq;
end if;
end if;
end process;
-- Register trig_pol
fmc_adc_100ms_csr_o.trig_pol_ext <= trig_pol_ext_reg;
fmc_adc_100ms_csr_o.trig_pol_ch1 <= trig_pol_ch1_reg;
fmc_adc_100ms_csr_o.trig_pol_ch2 <= trig_pol_ch2_reg;
fmc_adc_100ms_csr_o.trig_pol_ch3 <= trig_pol_ch3_reg;
fmc_adc_100ms_csr_o.trig_pol_ch4 <= trig_pol_ch4_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
trig_pol_ext_reg <= '0';
trig_pol_ch1_reg <= '0';
trig_pol_ch2_reg <= '0';
trig_pol_ch3_reg <= '0';
trig_pol_ch4_reg <= '0';
trig_pol_wack <= '0';
else
if trig_pol_wreq = '1' then
trig_pol_ext_reg <= wr_dat_d0(0);
trig_pol_ch1_reg <= wr_dat_d0(8);
trig_pol_ch2_reg <= wr_dat_d0(9);
trig_pol_ch3_reg <= wr_dat_d0(10);
trig_pol_ch4_reg <= wr_dat_d0(11);
end if;
trig_pol_wack <= trig_pol_wreq;
end if;
end if;
end process;
-- Register ext_trig_dly
fmc_adc_100ms_csr_o.ext_trig_dly <= ext_trig_dly_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
ext_trig_dly_reg <= "00000000000000000000000000000000";
ext_trig_dly_wack <= '0';
else
if ext_trig_dly_wreq = '1' then
ext_trig_dly_reg <= wr_dat_d0;
end if;
ext_trig_dly_wack <= ext_trig_dly_wreq;
end if;
end if;
end process;
-- Register sw_trig
fmc_adc_100ms_csr_o.sw_trig <= wr_dat_d0;
fmc_adc_100ms_csr_o.sw_trig_wr <= sw_trig_wreq;
-- Register shots
fmc_adc_100ms_csr_o.shots_nbr <= shots_nbr_reg;
fmc_adc_100ms_csr_o.shots_remain <= wr_dat_d0(31 downto 16);
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
shots_nbr_reg <= "0000000000000000";
shots_wack <= '0';
else
if shots_wreq = '1' then
shots_nbr_reg <= wr_dat_d0(15 downto 0);
end if;
shots_wack <= shots_wreq;
end if;
end if;
end process;
-- Register multi_depth
-- Register trig_pos
-- Register fs_freq
-- Register downsample
fmc_adc_100ms_csr_o.downsample <= downsample_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
downsample_reg <= "00000000000000000000000000000000";
downsample_wack <= '0';
else
if downsample_wreq = '1' then
downsample_reg <= wr_dat_d0;
end if;
downsample_wack <= downsample_wreq;
end if;
end if;
end process;
-- Register pre_samples
fmc_adc_100ms_csr_o.pre_samples <= pre_samples_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pre_samples_reg <= "00000000000000000000000000000000";
pre_samples_wack <= '0';
else
if pre_samples_wreq = '1' then
pre_samples_reg <= wr_dat_d0;
end if;
pre_samples_wack <= pre_samples_wreq;
end if;
end if;
end process;
-- Register post_samples
fmc_adc_100ms_csr_o.post_samples <= post_samples_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
post_samples_reg <= "00000000000000000000000000000000";
post_samples_wack <= '0';
else
if post_samples_wreq = '1' then
post_samples_reg <= wr_dat_d0;
end if;
post_samples_wack <= post_samples_wreq;
end if;
end if;
end process;
-- Assignments for submap fmc_adc_ch1
-- Register samples_cnt
-- Interface fmc_adc_ch1
fmc_adc_ch1_tr <= fmc_adc_ch1_wt or fmc_adc_ch1_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_ch1_rt <= '0';
fmc_adc_ch1_wt <= '0';
else
fmc_adc_ch1_rt <= (fmc_adc_ch1_rt or fmc_adc_ch1_re) and not fmc_adc_ch1_rack;
fmc_adc_ch1_wt <= (fmc_adc_ch1_wt or fmc_adc_ch1_we) and not fmc_adc_ch1_wack;
end if;
end if;
end process;
......@@ -234,19 +451,21 @@ begin
fmc_adc_ch1_o.stb <= fmc_adc_ch1_tr;
fmc_adc_ch1_wack <= fmc_adc_ch1_i.ack and fmc_adc_ch1_wt;
fmc_adc_ch1_rack <= fmc_adc_ch1_i.ack and fmc_adc_ch1_rt;
fmc_adc_ch1_o.adr <= ((26 downto 0 => '0') & wb_i.adr(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch1_o.sel <= (others => '1');
fmc_adc_ch1_o.adr <= ((26 downto 0 => '0') & rd_adr_d0(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch1_o.sel <= wr_sel_d0;
fmc_adc_ch1_o.we <= fmc_adc_ch1_wt;
fmc_adc_ch1_o.dat <= wb_i.dat;
fmc_adc_ch1_o.dat <= wr_dat_d0;
-- Assignments for submap fmc_adc_ch2
-- Interface fmc_adc_ch2
fmc_adc_ch2_tr <= fmc_adc_ch2_wt or fmc_adc_ch2_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_ch2_rt <= '0';
fmc_adc_ch2_wt <= '0';
else
fmc_adc_ch2_rt <= (fmc_adc_ch2_rt or fmc_adc_ch2_re) and not fmc_adc_ch2_rack;
fmc_adc_ch2_wt <= (fmc_adc_ch2_wt or fmc_adc_ch2_we) and not fmc_adc_ch2_wack;
end if;
end if;
end process;
......@@ -254,19 +473,21 @@ begin
fmc_adc_ch2_o.stb <= fmc_adc_ch2_tr;
fmc_adc_ch2_wack <= fmc_adc_ch2_i.ack and fmc_adc_ch2_wt;
fmc_adc_ch2_rack <= fmc_adc_ch2_i.ack and fmc_adc_ch2_rt;
fmc_adc_ch2_o.adr <= ((26 downto 0 => '0') & wb_i.adr(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch2_o.sel <= (others => '1');
fmc_adc_ch2_o.adr <= ((26 downto 0 => '0') & rd_adr_d0(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch2_o.sel <= wr_sel_d0;
fmc_adc_ch2_o.we <= fmc_adc_ch2_wt;
fmc_adc_ch2_o.dat <= wb_i.dat;
fmc_adc_ch2_o.dat <= wr_dat_d0;
-- Assignments for submap fmc_adc_ch3
-- Interface fmc_adc_ch3
fmc_adc_ch3_tr <= fmc_adc_ch3_wt or fmc_adc_ch3_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_ch3_rt <= '0';
fmc_adc_ch3_wt <= '0';
else
fmc_adc_ch3_rt <= (fmc_adc_ch3_rt or fmc_adc_ch3_re) and not fmc_adc_ch3_rack;
fmc_adc_ch3_wt <= (fmc_adc_ch3_wt or fmc_adc_ch3_we) and not fmc_adc_ch3_wack;
end if;
end if;
end process;
......@@ -274,19 +495,21 @@ begin
fmc_adc_ch3_o.stb <= fmc_adc_ch3_tr;
fmc_adc_ch3_wack <= fmc_adc_ch3_i.ack and fmc_adc_ch3_wt;
fmc_adc_ch3_rack <= fmc_adc_ch3_i.ack and fmc_adc_ch3_rt;
fmc_adc_ch3_o.adr <= ((26 downto 0 => '0') & wb_i.adr(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch3_o.sel <= (others => '1');
fmc_adc_ch3_o.adr <= ((26 downto 0 => '0') & rd_adr_d0(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch3_o.sel <= wr_sel_d0;
fmc_adc_ch3_o.we <= fmc_adc_ch3_wt;
fmc_adc_ch3_o.dat <= wb_i.dat;
fmc_adc_ch3_o.dat <= wr_dat_d0;
-- Assignments for submap fmc_adc_ch4
-- Interface fmc_adc_ch4
fmc_adc_ch4_tr <= fmc_adc_ch4_wt or fmc_adc_ch4_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_ch4_rt <= '0';
fmc_adc_ch4_wt <= '0';
else
fmc_adc_ch4_rt <= (fmc_adc_ch4_rt or fmc_adc_ch4_re) and not fmc_adc_ch4_rack;
fmc_adc_ch4_wt <= (fmc_adc_ch4_wt or fmc_adc_ch4_we) and not fmc_adc_ch4_wack;
end if;
end if;
end process;
......@@ -294,393 +517,255 @@ begin
fmc_adc_ch4_o.stb <= fmc_adc_ch4_tr;
fmc_adc_ch4_wack <= fmc_adc_ch4_i.ack and fmc_adc_ch4_wt;
fmc_adc_ch4_rack <= fmc_adc_ch4_i.ack and fmc_adc_ch4_rt;
fmc_adc_ch4_o.adr <= ((26 downto 0 => '0') & wb_i.adr(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch4_o.sel <= (others => '1');
fmc_adc_ch4_o.adr <= ((26 downto 0 => '0') & rd_adr_d0(4 downto 2)) & (1 downto 0 => '0');
fmc_adc_ch4_o.sel <= wr_sel_d0;
fmc_adc_ch4_o.we <= fmc_adc_ch4_wt;
fmc_adc_ch4_o.dat <= wb_i.dat;
fmc_adc_ch4_o.dat <= wr_dat_d0;
-- Process for write requests.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
fmc_adc_100ms_csr_o.ctl_wr <= '0';
ctl_fmc_clk_oe_reg <= '0';
ctl_offset_dac_clr_n_reg <= '0';
ctl_trig_led_reg <= '0';
ctl_acq_led_reg <= '0';
trig_en_ext_reg <= '0';
trig_en_time_reg <= '0';
trig_en_ch1_reg <= '0';
trig_en_ch2_reg <= '0';
trig_en_ch3_reg <= '0';
trig_en_ch4_reg <= '0';
trig_pol_ext_reg <= '0';
trig_pol_ch1_reg <= '0';
trig_pol_ch2_reg <= '0';
trig_pol_ch3_reg <= '0';
trig_pol_ch4_reg <= '0';
ext_trig_dly_reg <= "00000000000000000000000000000000";
fmc_adc_100ms_csr_o.sw_trig_wr <= '0';
shots_nbr_reg <= "0000000000000000";
downsample_reg <= "00000000000000000000000000000000";
pre_samples_reg <= "00000000000000000000000000000000";
post_samples_reg <= "00000000000000000000000000000000";
fmc_adc_ch1_wt <= '0';
fmc_adc_ch2_wt <= '0';
fmc_adc_ch3_wt <= '0';
fmc_adc_ch4_wt <= '0';
else
wr_ack_int <= '0';
fmc_adc_100ms_csr_o.ctl_wr <= '0';
fmc_adc_100ms_csr_o.sw_trig_wr <= '0';
fmc_adc_ch1_wt <= '0';
fmc_adc_ch2_wt <= '0';
fmc_adc_ch3_wt <= '0';
fmc_adc_ch4_wt <= '0';
case wb_i.adr(8 downto 5) is
when "0000" =>
case wb_i.adr(4 downto 2) is
when "000" =>
-- Register ctl
fmc_adc_100ms_csr_o.ctl_wr <= wr_int;
if wr_int = '1' then
fmc_adc_100ms_csr_o.ctl_fsm_cmd <= wb_i.dat(1 downto 0);
ctl_fmc_clk_oe_reg <= wb_i.dat(2);
ctl_offset_dac_clr_n_reg <= wb_i.dat(3);
fmc_adc_100ms_csr_o.ctl_man_bitslip <= wb_i.dat(4);
ctl_trig_led_reg <= wb_i.dat(6);
ctl_acq_led_reg <= wb_i.dat(7);
fmc_adc_100ms_csr_o.ctl_clear_trig_stat <= wb_i.dat(8);
fmc_adc_100ms_csr_o.ctl_calib_apply <= wb_i.dat(15);
end if;
wr_ack_int <= wr_int;
when "001" =>
-- Register sta
when "010" =>
-- Register trig_stat
when "011" =>
-- Register trig_en
if wr_int = '1' then
trig_en_ext_reg <= wb_i.dat(0);
fmc_adc_100ms_csr_o.trig_en_sw <= wb_i.dat(1);
trig_en_time_reg <= wb_i.dat(4);
fmc_adc_100ms_csr_o.trig_en_aux_time <= wb_i.dat(5);
trig_en_ch1_reg <= wb_i.dat(8);
trig_en_ch2_reg <= wb_i.dat(9);
trig_en_ch3_reg <= wb_i.dat(10);
trig_en_ch4_reg <= wb_i.dat(11);
end if;
wr_ack_int <= wr_int;
when "100" =>
-- Register trig_pol
if wr_int = '1' then
trig_pol_ext_reg <= wb_i.dat(0);
trig_pol_ch1_reg <= wb_i.dat(8);
trig_pol_ch2_reg <= wb_i.dat(9);
trig_pol_ch3_reg <= wb_i.dat(10);
trig_pol_ch4_reg <= wb_i.dat(11);
end if;
wr_ack_int <= wr_int;
when "101" =>
-- Register ext_trig_dly
if wr_int = '1' then
ext_trig_dly_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "110" =>
-- Register sw_trig
fmc_adc_100ms_csr_o.sw_trig_wr <= wr_int;
if wr_int = '1' then
fmc_adc_100ms_csr_o.sw_trig <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "111" =>
-- Register shots
if wr_int = '1' then
shots_nbr_reg <= wb_i.dat(15 downto 0);
fmc_adc_100ms_csr_o.shots_remain <= wb_i.dat(31 downto 16);
end if;
wr_ack_int <= wr_int;
when others =>
wr_ack_int <= wr_int;
end case;
when "0001" =>
case wb_i.adr(4 downto 2) is
when "000" =>
-- Register multi_depth
when "001" =>
-- Register trig_pos
when "010" =>
-- Register fs_freq
when "011" =>
-- Register downsample
if wr_int = '1' then
downsample_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "100" =>
-- Register pre_samples
if wr_int = '1' then
pre_samples_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "101" =>
-- Register post_samples
if wr_int = '1' then
post_samples_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "110" =>
-- Register samples_cnt
when others =>
wr_ack_int <= wr_int;
end case;
when "0100" =>
-- Submap fmc_adc_ch1
fmc_adc_ch1_wt <= (fmc_adc_ch1_wt or wr_int) and not fmc_adc_ch1_wack;
wr_ack_int <= fmc_adc_ch1_wack;
when "0110" =>
-- Submap fmc_adc_ch2
fmc_adc_ch2_wt <= (fmc_adc_ch2_wt or wr_int) and not fmc_adc_ch2_wack;
wr_ack_int <= fmc_adc_ch2_wack;
when "1000" =>
-- Submap fmc_adc_ch3
fmc_adc_ch3_wt <= (fmc_adc_ch3_wt or wr_int) and not fmc_adc_ch3_wack;
wr_ack_int <= fmc_adc_ch3_wack;
when "1010" =>
-- Submap fmc_adc_ch4
fmc_adc_ch4_wt <= (fmc_adc_ch4_wt or wr_int) and not fmc_adc_ch4_wack;
wr_ack_int <= fmc_adc_ch4_wack;
when others =>
wr_ack_int <= wr_int;
end case;
end if;
end if;
end process;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(8 downto 5) is
when "0000" =>
case wb_i.adr(4 downto 2) is
when "000" =>
-- ctl
reg_rdat_int(1 downto 0) <= fmc_adc_100ms_csr_i.ctl_fsm_cmd;
reg_rdat_int(2) <= ctl_fmc_clk_oe_reg;
reg_rdat_int(3) <= ctl_offset_dac_clr_n_reg;
reg_rdat_int(4) <= fmc_adc_100ms_csr_i.ctl_man_bitslip;
reg_rdat_int(6) <= ctl_trig_led_reg;
reg_rdat_int(7) <= ctl_acq_led_reg;
reg_rdat_int(8) <= fmc_adc_100ms_csr_i.ctl_clear_trig_stat;
reg_rdat_int(15) <= fmc_adc_100ms_csr_i.ctl_calib_apply;
rd_ack1_int <= rd_int;
when "001" =>
-- sta
reg_rdat_int(2 downto 0) <= fmc_adc_100ms_csr_i.sta_fsm;
reg_rdat_int(3) <= fmc_adc_100ms_csr_i.sta_serdes_pll;
reg_rdat_int(4) <= fmc_adc_100ms_csr_i.sta_serdes_synced;
reg_rdat_int(5) <= fmc_adc_100ms_csr_i.sta_acq_cfg;
reg_rdat_int(7 downto 6) <= fmc_adc_100ms_csr_i.sta_fmc_nr;
reg_rdat_int(15) <= fmc_adc_100ms_csr_i.sta_calib_busy;
rd_ack1_int <= rd_int;
when "010" =>
-- trig_stat
reg_rdat_int(0) <= fmc_adc_100ms_csr_i.trig_stat_ext;
reg_rdat_int(1) <= fmc_adc_100ms_csr_i.trig_stat_sw;
reg_rdat_int(4) <= fmc_adc_100ms_csr_i.trig_stat_time;
reg_rdat_int(8) <= fmc_adc_100ms_csr_i.trig_stat_ch1;
reg_rdat_int(9) <= fmc_adc_100ms_csr_i.trig_stat_ch2;
reg_rdat_int(10) <= fmc_adc_100ms_csr_i.trig_stat_ch3;
reg_rdat_int(11) <= fmc_adc_100ms_csr_i.trig_stat_ch4;
rd_ack1_int <= rd_int;
when "011" =>
-- trig_en
reg_rdat_int(0) <= trig_en_ext_reg;
reg_rdat_int(1) <= fmc_adc_100ms_csr_i.trig_en_sw;
reg_rdat_int(4) <= trig_en_time_reg;
reg_rdat_int(5) <= fmc_adc_100ms_csr_i.trig_en_aux_time;
reg_rdat_int(8) <= trig_en_ch1_reg;
reg_rdat_int(9) <= trig_en_ch2_reg;
reg_rdat_int(10) <= trig_en_ch3_reg;
reg_rdat_int(11) <= trig_en_ch4_reg;
rd_ack1_int <= rd_int;
when "100" =>
-- trig_pol
reg_rdat_int(0) <= trig_pol_ext_reg;
reg_rdat_int(8) <= trig_pol_ch1_reg;
reg_rdat_int(9) <= trig_pol_ch2_reg;
reg_rdat_int(10) <= trig_pol_ch3_reg;
reg_rdat_int(11) <= trig_pol_ch4_reg;
rd_ack1_int <= rd_int;
when "101" =>
-- ext_trig_dly
reg_rdat_int <= ext_trig_dly_reg;
rd_ack1_int <= rd_int;
when "110" =>
-- sw_trig
rd_ack1_int <= rd_int;
when "111" =>
-- shots
reg_rdat_int(15 downto 0) <= shots_nbr_reg;
reg_rdat_int(31 downto 16) <= fmc_adc_100ms_csr_i.shots_remain;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "0001" =>
case wb_i.adr(4 downto 2) is
when "000" =>
-- multi_depth
reg_rdat_int <= fmc_adc_100ms_csr_i.multi_depth;
rd_ack1_int <= rd_int;
when "001" =>
-- trig_pos
reg_rdat_int <= fmc_adc_100ms_csr_i.trig_pos;
rd_ack1_int <= rd_int;
when "010" =>
-- fs_freq
reg_rdat_int <= fmc_adc_100ms_csr_i.fs_freq;
rd_ack1_int <= rd_int;
when "011" =>
-- downsample
reg_rdat_int <= downsample_reg;
rd_ack1_int <= rd_int;
when "100" =>
-- pre_samples
reg_rdat_int <= pre_samples_reg;
rd_ack1_int <= rd_int;
when "101" =>
-- post_samples
reg_rdat_int <= post_samples_reg;
rd_ack1_int <= rd_int;
when "110" =>
-- samples_cnt
reg_rdat_int <= fmc_adc_100ms_csr_i.samples_cnt;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "0100" =>
when "0110" =>
when "1000" =>
when "1010" =>
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
process (rd_adr_d0, wr_req_d0, ctl_wack, trig_en_wack, trig_pol_wack, ext_trig_dly_wack, shots_wack, downsample_wack, pre_samples_wack, post_samples_wack, fmc_adc_ch1_wack, fmc_adc_ch2_wack, fmc_adc_ch3_wack, fmc_adc_ch4_wack) begin
ctl_wreq <= '0';
trig_en_wreq <= '0';
trig_pol_wreq <= '0';
ext_trig_dly_wreq <= '0';
sw_trig_wreq <= '0';
shots_wreq <= '0';
downsample_wreq <= '0';
pre_samples_wreq <= '0';
post_samples_wreq <= '0';
fmc_adc_ch1_we <= '0';
fmc_adc_ch2_we <= '0';
fmc_adc_ch3_we <= '0';
fmc_adc_ch4_we <= '0';
case rd_adr_d0(8 downto 5) is
when "0000" =>
case rd_adr_d0(4 downto 2) is
when "000" =>
-- Reg ctl
ctl_wreq <= wr_req_d0;
wr_ack_d0 <= ctl_wack;
when "001" =>
-- Reg sta
wr_ack_d0 <= wr_req_d0;
when "010" =>
-- Reg trig_stat
wr_ack_d0 <= wr_req_d0;
when "011" =>
-- Reg trig_en
trig_en_wreq <= wr_req_d0;
wr_ack_d0 <= trig_en_wack;
when "100" =>
-- Reg trig_pol
trig_pol_wreq <= wr_req_d0;
wr_ack_d0 <= trig_pol_wack;
when "101" =>
-- Reg ext_trig_dly
ext_trig_dly_wreq <= wr_req_d0;
wr_ack_d0 <= ext_trig_dly_wack;
when "110" =>
-- Reg sw_trig
sw_trig_wreq <= wr_req_d0;
wr_ack_d0 <= wr_req_d0;
when "111" =>
-- Reg shots
shots_wreq <= wr_req_d0;
wr_ack_d0 <= shots_wack;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
when "0001" =>
case rd_adr_d0(4 downto 2) is
when "000" =>
-- Reg multi_depth
wr_ack_d0 <= wr_req_d0;
when "001" =>
-- Reg trig_pos
wr_ack_d0 <= wr_req_d0;
when "010" =>
-- Reg fs_freq
wr_ack_d0 <= wr_req_d0;
when "011" =>
-- Reg downsample
downsample_wreq <= wr_req_d0;
wr_ack_d0 <= downsample_wack;
when "100" =>
-- Reg pre_samples
pre_samples_wreq <= wr_req_d0;
wr_ack_d0 <= pre_samples_wack;
when "101" =>
-- Reg post_samples
post_samples_wreq <= wr_req_d0;
wr_ack_d0 <= post_samples_wack;
when "110" =>
-- Reg samples_cnt
wr_ack_d0 <= wr_req_d0;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
when "0100" =>
-- Submap fmc_adc_ch1
fmc_adc_ch1_we <= wr_req_d0;
wr_ack_d0 <= fmc_adc_ch1_wack;
when "0110" =>
-- Submap fmc_adc_ch2
fmc_adc_ch2_we <= wr_req_d0;
wr_ack_d0 <= fmc_adc_ch2_wack;
when "1000" =>
-- Submap fmc_adc_ch3
fmc_adc_ch3_we <= wr_req_d0;
wr_ack_d0 <= fmc_adc_ch3_wack;
when "1010" =>
-- Submap fmc_adc_ch4
fmc_adc_ch4_we <= wr_req_d0;
wr_ack_d0 <= fmc_adc_ch4_wack;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int, rd_int, fmc_adc_ch1_i.dat, fmc_adc_ch1_rack, fmc_adc_ch1_rt, rd_int, fmc_adc_ch2_i.dat, fmc_adc_ch2_rack, fmc_adc_ch2_rt, rd_int, fmc_adc_ch3_i.dat, fmc_adc_ch3_rack, fmc_adc_ch3_rt, rd_int, fmc_adc_ch4_i.dat, fmc_adc_ch4_rack, fmc_adc_ch4_rt) begin
process (rd_adr_d0, rd_req_d0, fmc_adc_100ms_csr_i.ctl_fsm_cmd, ctl_fmc_clk_oe_reg, ctl_offset_dac_clr_n_reg, fmc_adc_100ms_csr_i.ctl_man_bitslip, ctl_trig_led_reg, ctl_acq_led_reg, fmc_adc_100ms_csr_i.ctl_clear_trig_stat, fmc_adc_100ms_csr_i.ctl_calib_apply, fmc_adc_100ms_csr_i.sta_fsm, fmc_adc_100ms_csr_i.sta_serdes_pll, fmc_adc_100ms_csr_i.sta_serdes_synced, fmc_adc_100ms_csr_i.sta_acq_cfg, fmc_adc_100ms_csr_i.sta_fmc_nr, fmc_adc_100ms_csr_i.sta_calib_busy, fmc_adc_100ms_csr_i.trig_stat_ext, fmc_adc_100ms_csr_i.trig_stat_sw, fmc_adc_100ms_csr_i.trig_stat_time, fmc_adc_100ms_csr_i.trig_stat_ch1, fmc_adc_100ms_csr_i.trig_stat_ch2, fmc_adc_100ms_csr_i.trig_stat_ch3, fmc_adc_100ms_csr_i.trig_stat_ch4, trig_en_ext_reg, fmc_adc_100ms_csr_i.trig_en_sw, trig_en_time_reg, fmc_adc_100ms_csr_i.trig_en_aux_time, trig_en_ch1_reg, trig_en_ch2_reg, trig_en_ch3_reg, trig_en_ch4_reg, trig_pol_ext_reg, trig_pol_ch1_reg, trig_pol_ch2_reg, trig_pol_ch3_reg, trig_pol_ch4_reg, ext_trig_dly_reg, shots_nbr_reg, fmc_adc_100ms_csr_i.shots_remain, fmc_adc_100ms_csr_i.multi_depth, fmc_adc_100ms_csr_i.trig_pos, fmc_adc_100ms_csr_i.fs_freq, downsample_reg, pre_samples_reg, post_samples_reg, fmc_adc_100ms_csr_i.samples_cnt, fmc_adc_ch1_i.dat, fmc_adc_ch1_rack, fmc_adc_ch2_i.dat, fmc_adc_ch2_rack, fmc_adc_ch3_i.dat, fmc_adc_ch3_rack, fmc_adc_ch4_i.dat, fmc_adc_ch4_rack) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
rd_dat_d0 <= (others => 'X');
fmc_adc_ch1_re <= '0';
fmc_adc_ch2_re <= '0';
fmc_adc_ch3_re <= '0';
fmc_adc_ch4_re <= '0';
case wb_i.adr(8 downto 5) is
when "0000" =>
case wb_i.adr(4 downto 2) is
when "000" =>
-- ctl
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "001" =>
-- sta
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "010" =>
-- trig_stat
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "011" =>
-- trig_en
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "100" =>
-- trig_pol
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "101" =>
-- ext_trig_dly
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "110" =>
-- sw_trig
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "111" =>
-- shots
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
case rd_adr_d0(8 downto 5) is
when "0000" =>
case rd_adr_d0(4 downto 2) is
when "000" =>
-- Reg ctl
rd_ack_d0 <= rd_req_d0;
rd_dat_d0(1 downto 0) <= fmc_adc_100ms_csr_i.ctl_fsm_cmd;
rd_dat_d0(2) <= ctl_fmc_clk_oe_reg;
rd_dat_d0(3) <= ctl_offset_dac_clr_n_reg;
rd_dat_d0(4) <= fmc_adc_100ms_csr_i.ctl_man_bitslip;
rd_dat_d0(5) <= '0';
rd_dat_d0(6) <= ctl_trig_led_reg;
rd_dat_d0(7) <= ctl_acq_led_reg;
rd_dat_d0(8) <= fmc_adc_100ms_csr_i.ctl_clear_trig_stat;
rd_dat_d0(14 downto 9) <= (others => '0');
rd_dat_d0(15) <= fmc_adc_100ms_csr_i.ctl_calib_apply;
rd_dat_d0(31 downto 16) <= (others => '0');
when "001" =>
-- Reg sta
rd_ack_d0 <= rd_req_d0;
rd_dat_d0(2 downto 0) <= fmc_adc_100ms_csr_i.sta_fsm;
rd_dat_d0(3) <= fmc_adc_100ms_csr_i.sta_serdes_pll;
rd_dat_d0(4) <= fmc_adc_100ms_csr_i.sta_serdes_synced;
rd_dat_d0(5) <= fmc_adc_100ms_csr_i.sta_acq_cfg;
rd_dat_d0(7 downto 6) <= fmc_adc_100ms_csr_i.sta_fmc_nr;
rd_dat_d0(14 downto 8) <= (others => '0');
rd_dat_d0(15) <= fmc_adc_100ms_csr_i.sta_calib_busy;
rd_dat_d0(31 downto 16) <= (others => '0');
when "010" =>
-- Reg trig_stat
rd_ack_d0 <= rd_req_d0;
rd_dat_d0(0) <= fmc_adc_100ms_csr_i.trig_stat_ext;
rd_dat_d0(1) <= fmc_adc_100ms_csr_i.trig_stat_sw;
rd_dat_d0(3 downto 2) <= (others => '0');
rd_dat_d0(4) <= fmc_adc_100ms_csr_i.trig_stat_time;
rd_dat_d0(7 downto 5) <= (others => '0');
rd_dat_d0(8) <= fmc_adc_100ms_csr_i.trig_stat_ch1;
rd_dat_d0(9) <= fmc_adc_100ms_csr_i.trig_stat_ch2;
rd_dat_d0(10) <= fmc_adc_100ms_csr_i.trig_stat_ch3;
rd_dat_d0(11) <= fmc_adc_100ms_csr_i.trig_stat_ch4;
rd_dat_d0(31 downto 12) <= (others => '0');
when "011" =>
-- Reg trig_en
rd_ack_d0 <= rd_req_d0;
rd_dat_d0(0) <= trig_en_ext_reg;
rd_dat_d0(1) <= fmc_adc_100ms_csr_i.trig_en_sw;
rd_dat_d0(3 downto 2) <= (others => '0');
rd_dat_d0(4) <= trig_en_time_reg;
rd_dat_d0(5) <= fmc_adc_100ms_csr_i.trig_en_aux_time;
rd_dat_d0(7 downto 6) <= (others => '0');
rd_dat_d0(8) <= trig_en_ch1_reg;
rd_dat_d0(9) <= trig_en_ch2_reg;
rd_dat_d0(10) <= trig_en_ch3_reg;
rd_dat_d0(11) <= trig_en_ch4_reg;
rd_dat_d0(31 downto 12) <= (others => '0');
when "100" =>
-- Reg trig_pol
rd_ack_d0 <= rd_req_d0;
rd_dat_d0(0) <= trig_pol_ext_reg;
rd_dat_d0(7 downto 1) <= (others => '0');
rd_dat_d0(8) <= trig_pol_ch1_reg;
rd_dat_d0(9) <= trig_pol_ch2_reg;
rd_dat_d0(10) <= trig_pol_ch3_reg;
rd_dat_d0(11) <= trig_pol_ch4_reg;
rd_dat_d0(31 downto 12) <= (others => '0');
when "101" =>
-- Reg ext_trig_dly
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= ext_trig_dly_reg;
when "110" =>
-- Reg sw_trig
rd_ack_d0 <= rd_req_d0;
when "111" =>
-- Reg shots
rd_ack_d0 <= rd_req_d0;
rd_dat_d0(15 downto 0) <= shots_nbr_reg;
rd_dat_d0(31 downto 16) <= fmc_adc_100ms_csr_i.shots_remain;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
when "0001" =>
case wb_i.adr(4 downto 2) is
when "000" =>
-- multi_depth
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "001" =>
-- trig_pos
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "010" =>
-- fs_freq
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "011" =>
-- downsample
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "100" =>
-- pre_samples
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "101" =>
-- post_samples
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "110" =>
-- samples_cnt
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "0001" =>
case rd_adr_d0(4 downto 2) is
when "000" =>
-- Reg multi_depth
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= fmc_adc_100ms_csr_i.multi_depth;
when "001" =>
-- Reg trig_pos
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= fmc_adc_100ms_csr_i.trig_pos;
when "010" =>
-- Reg fs_freq
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= fmc_adc_100ms_csr_i.fs_freq;
when "011" =>
-- Reg downsample
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= downsample_reg;
when "100" =>
-- Reg pre_samples
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= pre_samples_reg;
when "101" =>
-- Reg post_samples
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= post_samples_reg;
when "110" =>
-- Reg samples_cnt
rd_ack_d0 <= rd_req_d0;
rd_dat_d0 <= fmc_adc_100ms_csr_i.samples_cnt;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
when "0100" =>
when "0100" =>
-- Submap fmc_adc_ch1
fmc_adc_ch1_re <= rd_int;
wb_o.dat <= fmc_adc_ch1_i.dat;
rd_ack_int <= fmc_adc_ch1_rack;
when "0110" =>
fmc_adc_ch1_re <= rd_req_d0;
rd_dat_d0 <= fmc_adc_ch1_i.dat;
rd_ack_d0 <= fmc_adc_ch1_rack;
when "0110" =>
-- Submap fmc_adc_ch2
fmc_adc_ch2_re <= rd_int;
wb_o.dat <= fmc_adc_ch2_i.dat;
rd_ack_int <= fmc_adc_ch2_rack;
when "1000" =>
fmc_adc_ch2_re <= rd_req_d0;
rd_dat_d0 <= fmc_adc_ch2_i.dat;
rd_ack_d0 <= fmc_adc_ch2_rack;
when "1000" =>
-- Submap fmc_adc_ch3
fmc_adc_ch3_re <= rd_int;
wb_o.dat <= fmc_adc_ch3_i.dat;
rd_ack_int <= fmc_adc_ch3_rack;
when "1010" =>
fmc_adc_ch3_re <= rd_req_d0;
rd_dat_d0 <= fmc_adc_ch3_i.dat;
rd_ack_d0 <= fmc_adc_ch3_rack;
when "1010" =>
-- Submap fmc_adc_ch4
fmc_adc_ch4_re <= rd_int;
wb_o.dat <= fmc_adc_ch4_i.dat;
rd_ack_int <= fmc_adc_ch4_rack;
fmc_adc_ch4_re <= rd_req_d0;
rd_dat_d0 <= fmc_adc_ch4_i.dat;
rd_ack_d0 <= fmc_adc_ch4_rack;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
end process;
end syn;
......@@ -17,6 +17,7 @@ entity aux_trigin is
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Control register
-- Enable trigger, cleared when triggered
ctrl_enable_i : in std_logic;
ctrl_enable_o : out std_logic;
......@@ -31,21 +32,32 @@ entity aux_trigin is
end aux_trigin;
architecture syn of aux_trigin is
signal rd_int : std_logic;
signal wr_int : std_logic;
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 ctrl_wreq : std_logic;
signal seconds_reg : std_logic_vector(63 downto 0);
signal seconds_wreq : std_logic_vector(1 downto 0);
signal seconds_wack : std_logic_vector(1 downto 0);
signal cycles_reg : std_logic_vector(31 downto 0);
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal cycles_wreq : std_logic;
signal cycles_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
......@@ -57,7 +69,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -68,7 +80,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -76,167 +88,152 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
seconds_o <= seconds_reg;
cycles_o <= cycles_reg;
-- 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;
-- Process for write requests.
-- Register version
-- Register ctrl
ctrl_enable_o <= wr_dat_d0(0);
ctrl_wr_o <= ctrl_wreq;
-- Register seconds
seconds_o <= seconds_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
ctrl_wr_o <= '0';
seconds_reg <= "0000000000000000000000000000000000000000000000000000000000000000";
cycles_reg <= "00000000000000000000000000000000";
seconds_wack <= (others => '0');
else
wr_ack_int <= '0';
ctrl_wr_o <= '0';
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register version
when "1" =>
-- Register ctrl
ctrl_wr_o <= wr_int;
if wr_int = '1' then
ctrl_enable_o <= wb_i.dat(0);
end if;
wr_ack_int <= wr_int;
when others =>
wr_ack_int <= wr_int;
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register seconds
if wr_int = '1' then
seconds_reg(63 downto 32) <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "1" =>
-- Register seconds
if wr_int = '1' then
seconds_reg(31 downto 0) <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when others =>
wr_ack_int <= wr_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register cycles
if wr_int = '1' then
cycles_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when others =>
wr_ack_int <= wr_int;
end case;
when others =>
wr_ack_int <= wr_int;
end case;
if seconds_wreq(0) = '1' then
seconds_reg(31 downto 0) <= wr_dat_d0;
end if;
if seconds_wreq(1) = '1' then
seconds_reg(63 downto 32) <= wr_dat_d0;
end if;
seconds_wack <= seconds_wreq;
end if;
end if;
end process;
-- Process for registers read.
-- Register cycles
cycles_o <= cycles_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
cycles_reg <= "00000000000000000000000000000000";
cycles_wack <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- version
reg_rdat_int <= "10101101110000010000000000000001";
rd_ack1_int <= rd_int;
when "1" =>
-- ctrl
reg_rdat_int(0) <= ctrl_enable_i;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- seconds
reg_rdat_int <= seconds_reg(63 downto 32);
rd_ack1_int <= rd_int;
when "1" =>
-- seconds
reg_rdat_int <= seconds_reg(31 downto 0);
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- cycles
reg_rdat_int <= cycles_reg;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
if cycles_wreq = '1' then
cycles_reg <= wr_dat_d0;
end if;
cycles_wack <= cycles_wreq;
end if;
end if;
end process;
-- Process for write requests.
process (wr_adr_d0, wr_req_d0, seconds_wack, cycles_wack) begin
ctrl_wreq <= '0';
seconds_wreq <= (others => '0');
cycles_wreq <= '0';
case wr_adr_d0(4 downto 3) is
when "00" =>
case wr_adr_d0(2 downto 2) is
when "0" =>
-- Reg version
wr_ack_int <= wr_req_d0;
when "1" =>
-- Reg ctrl
ctrl_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when others =>
wr_ack_int <= wr_req_d0;
end case;
when "01" =>
case wr_adr_d0(2 downto 2) is
when "0" =>
-- Reg seconds
seconds_wreq(1) <= wr_req_d0;
wr_ack_int <= seconds_wack(1);
when "1" =>
-- Reg seconds
seconds_wreq(0) <= wr_req_d0;
wr_ack_int <= seconds_wack(0);
when others =>
wr_ack_int <= wr_req_d0;
end case;
when "10" =>
case wr_adr_d0(2 downto 2) is
when "0" =>
-- Reg cycles
cycles_wreq <= wr_req_d0;
wr_ack_int <= cycles_wack;
when others =>
wr_ack_int <= wr_req_d0;
end case;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
process (adr_int, rd_req_int, ctrl_enable_i, seconds_reg, cycles_reg) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- version
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- ctrl
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
rd_dat_d0 <= (others => 'X');
case adr_int(4 downto 3) is
when "00" =>
case adr_int(2 downto 2) is
when "0" =>
-- Reg version
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= "10101101110000010000000000000001";
when "1" =>
-- Reg ctrl
rd_ack_d0 <= rd_req_int;
rd_dat_d0(0) <= ctrl_enable_i;
rd_dat_d0(31 downto 1) <= (others => '0');
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- seconds
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- seconds
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01" =>
case adr_int(2 downto 2) is
when "0" =>
-- Reg seconds
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= seconds_reg(63 downto 32);
when "1" =>
-- Reg seconds
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= seconds_reg(31 downto 0);
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- cycles
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10" =>
case adr_int(2 downto 2) is
when "0" =>
-- Reg cycles
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= cycles_reg;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
......@@ -8,7 +8,7 @@ memory-map:
description: FMC ADC aux trigger out registers
x-hdl:
busgroup: True
reg_prefix: False
reg-prefix: False
children:
- reg:
name: status
......
-- 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
-- Do not edit; this file was generated by Cheby using these options:
-- Do not edit. Generated on Wed Dec 02 17:51:00 2020 by tgingold
-- With Cheby 1.4.dev0 and these options:
-- -i fmc_adc_aux_trigout.cheby --gen-hdl=fmc_adc_aux_trigout.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
......@@ -17,36 +15,31 @@ entity aux_trigout is
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Status register
-- Set when WR is enabled
wr_enable_i : in std_logic;
-- WR link status
wr_link_i : in std_logic;
-- Set when WR time is valid
wr_valid_i : in std_logic;
-- Set when the timestamp fifo is not empty
ts_present_i : in std_logic;
-- Time (seconds) of the last event
-- Seconds part of the timestamp
ts_sec_i : in std_logic_vector(39 downto 0);
-- Set if channel 1 triggered
ch1_mask_i : in std_logic;
-- Set if channel 2 triggered
ch2_mask_i : in std_logic;
-- Set if channel 3 triggered
ch3_mask_i : in std_logic;
-- Set if channel 4 triggered
ch4_mask_i : in std_logic;
-- Set if external trigger
ext_mask_i : in std_logic;
-- Reading this register discards the entry
-- Cycles
cycles_i : in std_logic_vector(27 downto 0);
ts_cycles_rd_o : out std_logic
......@@ -54,19 +47,25 @@ entity aux_trigout is
end aux_trigout;
architecture syn of aux_trigout is
signal rd_int : std_logic;
signal wr_int : std_logic;
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 reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : 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
......@@ -78,7 +77,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -89,7 +88,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -97,145 +96,118 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- Process for write requests.
-- pipelining for wr-in+rd-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
rd_ack_int <= '0';
wr_req_d0 <= '0';
else
wr_ack_int <= '0';
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register status
when others =>
wr_ack_int <= wr_int;
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register ts_mask_sec
when "1" =>
-- Register ts_mask_sec
when others =>
wr_ack_int <= wr_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- Register ts_cycles
when others =>
wr_ack_int <= wr_int;
end case;
when others =>
wr_ack_int <= wr_int;
end case;
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;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
ts_cycles_rd_o <= '0';
else
ts_cycles_rd_o <= '0';
reg_rdat_int <= (others => 'X');
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- status
reg_rdat_int(0) <= wr_enable_i;
reg_rdat_int(1) <= wr_link_i;
reg_rdat_int(2) <= wr_valid_i;
reg_rdat_int(8) <= ts_present_i;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_mask_sec
reg_rdat_int(7 downto 0) <= ts_sec_i(39 downto 32);
reg_rdat_int(16) <= ch1_mask_i;
reg_rdat_int(17) <= ch2_mask_i;
reg_rdat_int(18) <= ch3_mask_i;
reg_rdat_int(19) <= ch4_mask_i;
reg_rdat_int(24) <= ext_mask_i;
rd_ack1_int <= rd_int;
when "1" =>
-- ts_mask_sec
reg_rdat_int <= ts_sec_i(31 downto 0);
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_cycles
reg_rdat_int(27 downto 0) <= cycles_i;
ts_cycles_rd_o <= rd_int;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
-- Register status
-- Register ts_mask_sec
-- Register ts_cycles
-- Process for write requests.
process (wr_adr_d0, wr_req_d0) begin
case wr_adr_d0(4 downto 3) is
when "00" =>
case wr_adr_d0(2 downto 2) is
when "0" =>
-- Reg status
wr_ack_int <= wr_req_d0;
when others =>
wr_ack_int <= wr_req_d0;
end case;
when "01" =>
case wr_adr_d0(2 downto 2) is
when "0" =>
-- Reg ts_mask_sec
wr_ack_int <= wr_req_d0;
when "1" =>
-- Reg ts_mask_sec
wr_ack_int <= wr_req_d0;
when others =>
wr_ack_int <= wr_req_d0;
end case;
when "10" =>
case wr_adr_d0(2 downto 2) is
when "0" =>
-- Reg ts_cycles
wr_ack_int <= wr_req_d0;
when others =>
wr_ack_int <= wr_req_d0;
end case;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
process (adr_int, rd_req_int, wr_enable_i, wr_link_i, wr_valid_i, ts_present_i, ts_sec_i, ch1_mask_i, ch2_mask_i, ch3_mask_i, ch4_mask_i, ext_mask_i, cycles_i) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
case wb_i.adr(4 downto 3) is
when "00" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- status
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
rd_dat_d0 <= (others => 'X');
ts_cycles_rd_o <= '0';
case adr_int(4 downto 3) is
when "00" =>
case adr_int(2 downto 2) is
when "0" =>
-- Reg status
rd_ack_d0 <= rd_req_int;
rd_dat_d0(0) <= wr_enable_i;
rd_dat_d0(1) <= wr_link_i;
rd_dat_d0(2) <= wr_valid_i;
rd_dat_d0(7 downto 3) <= (others => '0');
rd_dat_d0(8) <= ts_present_i;
rd_dat_d0(31 downto 9) <= (others => '0');
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
when "01" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_mask_sec
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "1" =>
-- ts_mask_sec
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01" =>
case adr_int(2 downto 2) is
when "0" =>
-- Reg ts_mask_sec
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= ts_sec_i(39 downto 32);
rd_dat_d0(15 downto 8) <= (others => '0');
rd_dat_d0(16) <= ch1_mask_i;
rd_dat_d0(17) <= ch2_mask_i;
rd_dat_d0(18) <= ch3_mask_i;
rd_dat_d0(19) <= ch4_mask_i;
rd_dat_d0(23 downto 20) <= (others => '0');
rd_dat_d0(24) <= ext_mask_i;
rd_dat_d0(31 downto 25) <= (others => '0');
when "1" =>
-- Reg ts_mask_sec
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= ts_sec_i(31 downto 0);
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
when "10" =>
case wb_i.adr(2 downto 2) is
when "0" =>
-- ts_cycles
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10" =>
case adr_int(2 downto 2) is
when "0" =>
-- Reg ts_cycles
ts_cycles_rd_o <= rd_req_int;
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= cycles_i;
rd_dat_d0(31 downto 28) <= (others => '0');
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
......@@ -40,7 +40,6 @@ entity fmc_adc_eic_regs is
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Wires and registers
fmc_adc_eic_regs_i : in t_fmc_adc_eic_regs_master_in;
fmc_adc_eic_regs_o : out t_fmc_adc_eic_regs_master_out
......@@ -48,19 +47,28 @@ entity fmc_adc_eic_regs is
end fmc_adc_eic_regs;
architecture syn of fmc_adc_eic_regs is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal adr_int : std_logic_vector(3 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 reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal idr_wreq : std_logic;
signal ier_wreq : std_logic;
signal isr_wreq : 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(3 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(3 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
......@@ -72,7 +80,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -83,7 +91,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -91,105 +99,84 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- Process for write requests.
-- pipelining for wr-in+rd-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
fmc_adc_eic_regs_o.idr_wr <= '0';
fmc_adc_eic_regs_o.ier_wr <= '0';
fmc_adc_eic_regs_o.isr_wr <= '0';
rd_ack_int <= '0';
wr_req_d0 <= '0';
else
wr_ack_int <= '0';
fmc_adc_eic_regs_o.idr_wr <= '0';
fmc_adc_eic_regs_o.ier_wr <= '0';
fmc_adc_eic_regs_o.isr_wr <= '0';
case wb_i.adr(3 downto 2) is
when "00" =>
-- Register idr
fmc_adc_eic_regs_o.idr_wr <= wr_int;
if wr_int = '1' then
fmc_adc_eic_regs_o.idr <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "01" =>
-- Register ier
fmc_adc_eic_regs_o.ier_wr <= wr_int;
if wr_int = '1' then
fmc_adc_eic_regs_o.ier <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "10" =>
-- Register imr
when "11" =>
-- Register isr
fmc_adc_eic_regs_o.isr_wr <= wr_int;
if wr_int = '1' then
fmc_adc_eic_regs_o.isr <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when others =>
wr_ack_int <= wr_int;
end case;
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;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(3 downto 2) is
when "00" =>
-- idr
rd_ack1_int <= rd_int;
when "01" =>
-- ier
rd_ack1_int <= rd_int;
when "10" =>
-- imr
reg_rdat_int <= fmc_adc_eic_regs_i.imr;
rd_ack1_int <= rd_int;
when "11" =>
-- isr
reg_rdat_int <= fmc_adc_eic_regs_i.isr;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
-- Register idr
fmc_adc_eic_regs_o.idr <= wr_dat_d0;
fmc_adc_eic_regs_o.idr_wr <= idr_wreq;
-- Register ier
fmc_adc_eic_regs_o.ier <= wr_dat_d0;
fmc_adc_eic_regs_o.ier_wr <= ier_wreq;
-- Register imr
-- Register isr
fmc_adc_eic_regs_o.isr <= wr_dat_d0;
fmc_adc_eic_regs_o.isr_wr <= isr_wreq;
-- Process for write requests.
process (wr_adr_d0, wr_req_d0) begin
idr_wreq <= '0';
ier_wreq <= '0';
isr_wreq <= '0';
case wr_adr_d0(3 downto 2) is
when "00" =>
-- Reg idr
idr_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when "01" =>
-- Reg ier
ier_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when "10" =>
-- Reg imr
wr_ack_int <= wr_req_d0;
when "11" =>
-- Reg isr
isr_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
process (adr_int, rd_req_int, fmc_adc_eic_regs_i.imr, fmc_adc_eic_regs_i.isr) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
case wb_i.adr(3 downto 2) is
when "00" =>
-- idr
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01" =>
-- ier
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10" =>
-- imr
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "11" =>
-- isr
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
rd_dat_d0 <= (others => 'X');
case adr_int(3 downto 2) is
when "00" =>
-- Reg idr
rd_ack_d0 <= rd_req_int;
when "01" =>
-- Reg ier
rd_ack_d0 <= rd_req_int;
when "10" =>
-- Reg imr
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= fmc_adc_eic_regs_i.imr;
when "11" =>
-- Reg isr
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= fmc_adc_eic_regs_i.isr;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
......@@ -9,6 +9,7 @@ memory-map:
size: 0x2000
x-hdl:
busgroup: True
pipeline: wr,rd
children:
- submap:
name: fmc_adc_100m_csr
......
......@@ -44,8 +44,9 @@ entity fmc_adc_mezzanine_mmap is
end fmc_adc_mezzanine_mmap;
architecture syn of fmc_adc_mezzanine_mmap is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal adr_int : std_logic_vector(12 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;
......@@ -53,46 +54,59 @@ architecture syn of fmc_adc_mezzanine_mmap is
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal fmc_adc_100m_csr_re : std_logic;
signal fmc_adc_100m_csr_we : std_logic;
signal fmc_adc_100m_csr_wt : std_logic;
signal fmc_adc_100m_csr_rt : std_logic;
signal fmc_adc_100m_csr_tr : std_logic;
signal fmc_adc_100m_csr_wack : std_logic;
signal fmc_adc_100m_csr_rack : std_logic;
signal fmc_adc_eic_re : std_logic;
signal fmc_adc_eic_we : std_logic;
signal fmc_adc_eic_wt : std_logic;
signal fmc_adc_eic_rt : std_logic;
signal fmc_adc_eic_tr : std_logic;
signal fmc_adc_eic_wack : std_logic;
signal fmc_adc_eic_rack : std_logic;
signal si570_i2c_master_re : std_logic;
signal si570_i2c_master_we : std_logic;
signal si570_i2c_master_wt : std_logic;
signal si570_i2c_master_rt : std_logic;
signal si570_i2c_master_tr : std_logic;
signal si570_i2c_master_wack : std_logic;
signal si570_i2c_master_rack : std_logic;
signal ds18b20_onewire_master_re : std_logic;
signal ds18b20_onewire_master_we : std_logic;
signal ds18b20_onewire_master_wt : std_logic;
signal ds18b20_onewire_master_rt : std_logic;
signal ds18b20_onewire_master_tr : std_logic;
signal ds18b20_onewire_master_wack : std_logic;
signal ds18b20_onewire_master_rack : std_logic;
signal fmc_spi_master_re : std_logic;
signal fmc_spi_master_we : std_logic;
signal fmc_spi_master_wt : std_logic;
signal fmc_spi_master_rt : std_logic;
signal fmc_spi_master_tr : std_logic;
signal fmc_spi_master_wack : std_logic;
signal fmc_spi_master_rack : std_logic;
signal timetag_core_re : std_logic;
signal timetag_core_we : std_logic;
signal timetag_core_wt : std_logic;
signal timetag_core_rt : std_logic;
signal timetag_core_tr : std_logic;
signal timetag_core_wack : std_logic;
signal timetag_core_rack : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal rd_req_d0 : std_logic;
signal rd_adr_d0 : std_logic_vector(12 downto 2);
signal rd_ack_d0 : std_logic;
signal rd_dat_d0 : std_logic_vector(31 downto 0);
signal wr_req_d0 : std_logic;
signal wr_dat_d0 : std_logic_vector(31 downto 0);
signal wr_sel_d0 : std_logic_vector(3 downto 0);
signal wr_ack_d0 : std_logic;
begin
-- WB decode signals
adr_int <= wb_i.adr(12 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
......@@ -104,7 +118,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -115,7 +129,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -123,16 +137,37 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- pipelining for rd-in+rd-out+wr-in+wr-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_req_d0 <= '0';
rd_ack_int <= '0';
wr_req_d0 <= '0';
wr_ack_int <= '0';
else
rd_req_d0 <= rd_req_int;
rd_adr_d0 <= adr_int;
rd_ack_int <= rd_ack_d0;
wb_o.dat <= rd_dat_d0;
wr_req_d0 <= wr_req_int;
wr_dat_d0 <= wb_i.dat;
wr_sel_d0 <= wb_i.sel;
wr_ack_int <= wr_ack_d0;
end if;
end if;
end process;
-- Assignments for submap fmc_adc_100m_csr
-- Interface fmc_adc_100m_csr
fmc_adc_100m_csr_tr <= fmc_adc_100m_csr_wt or fmc_adc_100m_csr_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_100m_csr_rt <= '0';
fmc_adc_100m_csr_wt <= '0';
else
fmc_adc_100m_csr_rt <= (fmc_adc_100m_csr_rt or fmc_adc_100m_csr_re) and not fmc_adc_100m_csr_rack;
fmc_adc_100m_csr_wt <= (fmc_adc_100m_csr_wt or fmc_adc_100m_csr_we) and not fmc_adc_100m_csr_wack;
end if;
end if;
end process;
......@@ -140,19 +175,21 @@ begin
fmc_adc_100m_csr_o.stb <= fmc_adc_100m_csr_tr;
fmc_adc_100m_csr_wack <= fmc_adc_100m_csr_i.ack and fmc_adc_100m_csr_wt;
fmc_adc_100m_csr_rack <= fmc_adc_100m_csr_i.ack and fmc_adc_100m_csr_rt;
fmc_adc_100m_csr_o.adr <= ((22 downto 0 => '0') & wb_i.adr(8 downto 2)) & (1 downto 0 => '0');
fmc_adc_100m_csr_o.sel <= (others => '1');
fmc_adc_100m_csr_o.adr <= ((22 downto 0 => '0') & rd_adr_d0(8 downto 2)) & (1 downto 0 => '0');
fmc_adc_100m_csr_o.sel <= wr_sel_d0;
fmc_adc_100m_csr_o.we <= fmc_adc_100m_csr_wt;
fmc_adc_100m_csr_o.dat <= wb_i.dat;
fmc_adc_100m_csr_o.dat <= wr_dat_d0;
-- Assignments for submap fmc_adc_eic
-- Interface fmc_adc_eic
fmc_adc_eic_tr <= fmc_adc_eic_wt or fmc_adc_eic_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_eic_rt <= '0';
fmc_adc_eic_wt <= '0';
else
fmc_adc_eic_rt <= (fmc_adc_eic_rt or fmc_adc_eic_re) and not fmc_adc_eic_rack;
fmc_adc_eic_wt <= (fmc_adc_eic_wt or fmc_adc_eic_we) and not fmc_adc_eic_wack;
end if;
end if;
end process;
......@@ -160,19 +197,21 @@ begin
fmc_adc_eic_o.stb <= fmc_adc_eic_tr;
fmc_adc_eic_wack <= fmc_adc_eic_i.ack and fmc_adc_eic_wt;
fmc_adc_eic_rack <= fmc_adc_eic_i.ack and fmc_adc_eic_rt;
fmc_adc_eic_o.adr <= ((27 downto 0 => '0') & wb_i.adr(3 downto 2)) & (1 downto 0 => '0');
fmc_adc_eic_o.sel <= (others => '1');
fmc_adc_eic_o.adr <= ((27 downto 0 => '0') & rd_adr_d0(3 downto 2)) & (1 downto 0 => '0');
fmc_adc_eic_o.sel <= wr_sel_d0;
fmc_adc_eic_o.we <= fmc_adc_eic_wt;
fmc_adc_eic_o.dat <= wb_i.dat;
fmc_adc_eic_o.dat <= wr_dat_d0;
-- Assignments for submap si570_i2c_master
-- Interface si570_i2c_master
si570_i2c_master_tr <= si570_i2c_master_wt or si570_i2c_master_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
si570_i2c_master_rt <= '0';
si570_i2c_master_wt <= '0';
else
si570_i2c_master_rt <= (si570_i2c_master_rt or si570_i2c_master_re) and not si570_i2c_master_rack;
si570_i2c_master_wt <= (si570_i2c_master_wt or si570_i2c_master_we) and not si570_i2c_master_wack;
end if;
end if;
end process;
......@@ -180,19 +219,21 @@ begin
si570_i2c_master_o.stb <= si570_i2c_master_tr;
si570_i2c_master_wack <= si570_i2c_master_i.ack and si570_i2c_master_wt;
si570_i2c_master_rack <= si570_i2c_master_i.ack and si570_i2c_master_rt;
si570_i2c_master_o.adr <= ((23 downto 0 => '0') & wb_i.adr(7 downto 2)) & (1 downto 0 => '0');
si570_i2c_master_o.sel <= (others => '1');
si570_i2c_master_o.adr <= ((23 downto 0 => '0') & rd_adr_d0(7 downto 2)) & (1 downto 0 => '0');
si570_i2c_master_o.sel <= wr_sel_d0;
si570_i2c_master_o.we <= si570_i2c_master_wt;
si570_i2c_master_o.dat <= wb_i.dat;
si570_i2c_master_o.dat <= wr_dat_d0;
-- Assignments for submap ds18b20_onewire_master
-- Interface ds18b20_onewire_master
ds18b20_onewire_master_tr <= ds18b20_onewire_master_wt or ds18b20_onewire_master_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
ds18b20_onewire_master_rt <= '0';
ds18b20_onewire_master_wt <= '0';
else
ds18b20_onewire_master_rt <= (ds18b20_onewire_master_rt or ds18b20_onewire_master_re) and not ds18b20_onewire_master_rack;
ds18b20_onewire_master_wt <= (ds18b20_onewire_master_wt or ds18b20_onewire_master_we) and not ds18b20_onewire_master_wack;
end if;
end if;
end process;
......@@ -200,19 +241,21 @@ begin
ds18b20_onewire_master_o.stb <= ds18b20_onewire_master_tr;
ds18b20_onewire_master_wack <= ds18b20_onewire_master_i.ack and ds18b20_onewire_master_wt;
ds18b20_onewire_master_rack <= ds18b20_onewire_master_i.ack and ds18b20_onewire_master_rt;
ds18b20_onewire_master_o.adr <= ((27 downto 0 => '0') & wb_i.adr(3 downto 2)) & (1 downto 0 => '0');
ds18b20_onewire_master_o.sel <= (others => '1');
ds18b20_onewire_master_o.adr <= ((27 downto 0 => '0') & rd_adr_d0(3 downto 2)) & (1 downto 0 => '0');
ds18b20_onewire_master_o.sel <= wr_sel_d0;
ds18b20_onewire_master_o.we <= ds18b20_onewire_master_wt;
ds18b20_onewire_master_o.dat <= wb_i.dat;
ds18b20_onewire_master_o.dat <= wr_dat_d0;
-- Assignments for submap fmc_spi_master
-- Interface fmc_spi_master
fmc_spi_master_tr <= fmc_spi_master_wt or fmc_spi_master_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_spi_master_rt <= '0';
fmc_spi_master_wt <= '0';
else
fmc_spi_master_rt <= (fmc_spi_master_rt or fmc_spi_master_re) and not fmc_spi_master_rack;
fmc_spi_master_wt <= (fmc_spi_master_wt or fmc_spi_master_we) and not fmc_spi_master_wack;
end if;
end if;
end process;
......@@ -220,19 +263,21 @@ begin
fmc_spi_master_o.stb <= fmc_spi_master_tr;
fmc_spi_master_wack <= fmc_spi_master_i.ack and fmc_spi_master_wt;
fmc_spi_master_rack <= fmc_spi_master_i.ack and fmc_spi_master_rt;
fmc_spi_master_o.adr <= ((26 downto 0 => '0') & wb_i.adr(4 downto 2)) & (1 downto 0 => '0');
fmc_spi_master_o.sel <= (others => '1');
fmc_spi_master_o.adr <= ((26 downto 0 => '0') & rd_adr_d0(4 downto 2)) & (1 downto 0 => '0');
fmc_spi_master_o.sel <= wr_sel_d0;
fmc_spi_master_o.we <= fmc_spi_master_wt;
fmc_spi_master_o.dat <= wb_i.dat;
fmc_spi_master_o.dat <= wr_dat_d0;
-- Assignments for submap timetag_core
-- Interface timetag_core
timetag_core_tr <= timetag_core_wt or timetag_core_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
timetag_core_rt <= '0';
timetag_core_wt <= '0';
else
timetag_core_rt <= (timetag_core_rt or timetag_core_re) and not timetag_core_rack;
timetag_core_wt <= (timetag_core_wt or timetag_core_we) and not timetag_core_wack;
end if;
end if;
end process;
......@@ -240,159 +285,112 @@ begin
timetag_core_o.stb <= timetag_core_tr;
timetag_core_wack <= timetag_core_i.ack and timetag_core_wt;
timetag_core_rack <= timetag_core_i.ack and timetag_core_rt;
timetag_core_o.adr <= ((24 downto 0 => '0') & wb_i.adr(6 downto 2)) & (1 downto 0 => '0');
timetag_core_o.sel <= (others => '1');
timetag_core_o.adr <= ((24 downto 0 => '0') & rd_adr_d0(6 downto 2)) & (1 downto 0 => '0');
timetag_core_o.sel <= wr_sel_d0;
timetag_core_o.we <= timetag_core_wt;
timetag_core_o.dat <= wb_i.dat;
timetag_core_o.dat <= wr_dat_d0;
-- Process for write requests.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
fmc_adc_100m_csr_wt <= '0';
fmc_adc_eic_wt <= '0';
si570_i2c_master_wt <= '0';
ds18b20_onewire_master_wt <= '0';
fmc_spi_master_wt <= '0';
timetag_core_wt <= '0';
else
wr_ack_int <= '0';
fmc_adc_100m_csr_wt <= '0';
fmc_adc_eic_wt <= '0';
si570_i2c_master_wt <= '0';
ds18b20_onewire_master_wt <= '0';
fmc_spi_master_wt <= '0';
timetag_core_wt <= '0';
case wb_i.adr(12 downto 9) is
when "1000" =>
-- Submap fmc_adc_100m_csr
fmc_adc_100m_csr_wt <= (fmc_adc_100m_csr_wt or wr_int) and not fmc_adc_100m_csr_wack;
wr_ack_int <= fmc_adc_100m_csr_wack;
when "1010" =>
-- Submap fmc_adc_eic
fmc_adc_eic_wt <= (fmc_adc_eic_wt or wr_int) and not fmc_adc_eic_wack;
wr_ack_int <= fmc_adc_eic_wack;
when "1011" =>
case wb_i.adr(8 downto 8) is
when "0" =>
-- Submap si570_i2c_master
si570_i2c_master_wt <= (si570_i2c_master_wt or wr_int) and not si570_i2c_master_wack;
wr_ack_int <= si570_i2c_master_wack;
when "1" =>
-- Submap ds18b20_onewire_master
ds18b20_onewire_master_wt <= (ds18b20_onewire_master_wt or wr_int) and not ds18b20_onewire_master_wack;
wr_ack_int <= ds18b20_onewire_master_wack;
when others =>
wr_ack_int <= wr_int;
end case;
when "1100" =>
case wb_i.adr(8 downto 7) is
when "00" =>
-- Submap fmc_spi_master
fmc_spi_master_wt <= (fmc_spi_master_wt or wr_int) and not fmc_spi_master_wack;
wr_ack_int <= fmc_spi_master_wack;
when "10" =>
-- Submap timetag_core
timetag_core_wt <= (timetag_core_wt or wr_int) and not timetag_core_wack;
wr_ack_int <= timetag_core_wack;
when others =>
wr_ack_int <= wr_int;
end case;
when others =>
wr_ack_int <= wr_int;
end case;
end if;
end if;
end process;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(12 downto 9) is
when "1000" =>
when "1010" =>
when "1011" =>
case wb_i.adr(8 downto 8) is
when "0" =>
when "1" =>
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when "1100" =>
case wb_i.adr(8 downto 7) is
when "00" =>
when "10" =>
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
process (rd_adr_d0, wr_req_d0, fmc_adc_100m_csr_wack, fmc_adc_eic_wack, si570_i2c_master_wack, ds18b20_onewire_master_wack, fmc_spi_master_wack, timetag_core_wack) begin
fmc_adc_100m_csr_we <= '0';
fmc_adc_eic_we <= '0';
si570_i2c_master_we <= '0';
ds18b20_onewire_master_we <= '0';
fmc_spi_master_we <= '0';
timetag_core_we <= '0';
case rd_adr_d0(12 downto 9) is
when "1000" =>
-- Submap fmc_adc_100m_csr
fmc_adc_100m_csr_we <= wr_req_d0;
wr_ack_d0 <= fmc_adc_100m_csr_wack;
when "1010" =>
-- Submap fmc_adc_eic
fmc_adc_eic_we <= wr_req_d0;
wr_ack_d0 <= fmc_adc_eic_wack;
when "1011" =>
case rd_adr_d0(8 downto 8) is
when "0" =>
-- Submap si570_i2c_master
si570_i2c_master_we <= wr_req_d0;
wr_ack_d0 <= si570_i2c_master_wack;
when "1" =>
-- Submap ds18b20_onewire_master
ds18b20_onewire_master_we <= wr_req_d0;
wr_ack_d0 <= ds18b20_onewire_master_wack;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
when "1100" =>
case rd_adr_d0(8 downto 7) is
when "00" =>
-- Submap fmc_spi_master
fmc_spi_master_we <= wr_req_d0;
wr_ack_d0 <= fmc_spi_master_wack;
when "10" =>
-- Submap timetag_core
timetag_core_we <= wr_req_d0;
wr_ack_d0 <= timetag_core_wack;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int, rd_int, fmc_adc_100m_csr_i.dat, fmc_adc_100m_csr_rack, fmc_adc_100m_csr_rt, rd_int, fmc_adc_eic_i.dat, fmc_adc_eic_rack, fmc_adc_eic_rt, rd_int, si570_i2c_master_i.dat, si570_i2c_master_rack, si570_i2c_master_rt, rd_int, ds18b20_onewire_master_i.dat, ds18b20_onewire_master_rack, ds18b20_onewire_master_rt, rd_int, fmc_spi_master_i.dat, fmc_spi_master_rack, fmc_spi_master_rt, rd_int, timetag_core_i.dat, timetag_core_rack, timetag_core_rt) begin
process (rd_adr_d0, rd_req_d0, fmc_adc_100m_csr_i.dat, fmc_adc_100m_csr_rack, fmc_adc_eic_i.dat, fmc_adc_eic_rack, si570_i2c_master_i.dat, si570_i2c_master_rack, ds18b20_onewire_master_i.dat, ds18b20_onewire_master_rack, fmc_spi_master_i.dat, fmc_spi_master_rack, timetag_core_i.dat, timetag_core_rack) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
rd_dat_d0 <= (others => 'X');
fmc_adc_100m_csr_re <= '0';
fmc_adc_eic_re <= '0';
si570_i2c_master_re <= '0';
ds18b20_onewire_master_re <= '0';
fmc_spi_master_re <= '0';
timetag_core_re <= '0';
case wb_i.adr(12 downto 9) is
when "1000" =>
case rd_adr_d0(12 downto 9) is
when "1000" =>
-- Submap fmc_adc_100m_csr
fmc_adc_100m_csr_re <= rd_int;
wb_o.dat <= fmc_adc_100m_csr_i.dat;
rd_ack_int <= fmc_adc_100m_csr_rack;
when "1010" =>
fmc_adc_100m_csr_re <= rd_req_d0;
rd_dat_d0 <= fmc_adc_100m_csr_i.dat;
rd_ack_d0 <= fmc_adc_100m_csr_rack;
when "1010" =>
-- Submap fmc_adc_eic
fmc_adc_eic_re <= rd_int;
wb_o.dat <= fmc_adc_eic_i.dat;
rd_ack_int <= fmc_adc_eic_rack;
when "1011" =>
case wb_i.adr(8 downto 8) is
when "0" =>
fmc_adc_eic_re <= rd_req_d0;
rd_dat_d0 <= fmc_adc_eic_i.dat;
rd_ack_d0 <= fmc_adc_eic_rack;
when "1011" =>
case rd_adr_d0(8 downto 8) is
when "0" =>
-- Submap si570_i2c_master
si570_i2c_master_re <= rd_int;
wb_o.dat <= si570_i2c_master_i.dat;
rd_ack_int <= si570_i2c_master_rack;
when "1" =>
si570_i2c_master_re <= rd_req_d0;
rd_dat_d0 <= si570_i2c_master_i.dat;
rd_ack_d0 <= si570_i2c_master_rack;
when "1" =>
-- Submap ds18b20_onewire_master
ds18b20_onewire_master_re <= rd_int;
wb_o.dat <= ds18b20_onewire_master_i.dat;
rd_ack_int <= ds18b20_onewire_master_rack;
ds18b20_onewire_master_re <= rd_req_d0;
rd_dat_d0 <= ds18b20_onewire_master_i.dat;
rd_ack_d0 <= ds18b20_onewire_master_rack;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
when "1100" =>
case wb_i.adr(8 downto 7) is
when "00" =>
when "1100" =>
case rd_adr_d0(8 downto 7) is
when "00" =>
-- Submap fmc_spi_master
fmc_spi_master_re <= rd_int;
wb_o.dat <= fmc_spi_master_i.dat;
rd_ack_int <= fmc_spi_master_rack;
when "10" =>
fmc_spi_master_re <= rd_req_d0;
rd_dat_d0 <= fmc_spi_master_i.dat;
rd_ack_d0 <= fmc_spi_master_rack;
when "10" =>
-- Submap timetag_core
timetag_core_re <= rd_int;
wb_o.dat <= timetag_core_i.dat;
rd_ack_int <= timetag_core_rack;
timetag_core_re <= rd_req_d0;
rd_dat_d0 <= timetag_core_i.dat;
rd_ack_d0 <= timetag_core_rack;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
end process;
end syn;
......@@ -28,8 +28,9 @@ entity spec_ref_fmc_adc_100m_mmap is
end spec_ref_fmc_adc_100m_mmap;
architecture syn of spec_ref_fmc_adc_100m_mmap is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal adr_int : std_logic_vector(14 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;
......@@ -37,22 +38,29 @@ architecture syn of spec_ref_fmc_adc_100m_mmap is
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal metadata_re : std_logic;
signal metadata_we : std_logic;
signal metadata_wt : std_logic;
signal metadata_rt : std_logic;
signal metadata_tr : std_logic;
signal metadata_wack : std_logic;
signal metadata_rack : std_logic;
signal fmc_adc_mezzanine_re : std_logic;
signal fmc_adc_mezzanine_we : std_logic;
signal fmc_adc_mezzanine_wt : std_logic;
signal fmc_adc_mezzanine_rt : std_logic;
signal fmc_adc_mezzanine_tr : std_logic;
signal fmc_adc_mezzanine_wack : std_logic;
signal fmc_adc_mezzanine_rack : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : 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(14 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(14 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
......@@ -64,7 +72,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -75,7 +83,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -83,16 +91,33 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- 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;
-- Assignments for submap metadata
-- Interface metadata
metadata_tr <= metadata_wt or metadata_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
metadata_rt <= '0';
metadata_wt <= '0';
else
metadata_rt <= (metadata_rt or metadata_re) and not metadata_rack;
metadata_wt <= (metadata_wt or metadata_we) and not metadata_wack;
end if;
end if;
end process;
......@@ -100,19 +125,21 @@ begin
metadata_o.stb <= metadata_tr;
metadata_wack <= metadata_i.ack and metadata_wt;
metadata_rack <= metadata_i.ack and metadata_rt;
metadata_o.adr <= ((25 downto 0 => '0') & wb_i.adr(5 downto 2)) & (1 downto 0 => '0');
metadata_o.sel <= (others => '1');
metadata_o.adr <= ((25 downto 0 => '0') & adr_int(5 downto 2)) & (1 downto 0 => '0');
metadata_o.sel <= wr_sel_d0;
metadata_o.we <= metadata_wt;
metadata_o.dat <= wb_i.dat;
metadata_o.dat <= wr_dat_d0;
-- Assignments for submap fmc_adc_mezzanine
-- Interface fmc_adc_mezzanine
fmc_adc_mezzanine_tr <= fmc_adc_mezzanine_wt or fmc_adc_mezzanine_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc_adc_mezzanine_rt <= '0';
fmc_adc_mezzanine_wt <= '0';
else
fmc_adc_mezzanine_rt <= (fmc_adc_mezzanine_rt or fmc_adc_mezzanine_re) and not fmc_adc_mezzanine_rack;
fmc_adc_mezzanine_wt <= (fmc_adc_mezzanine_wt or fmc_adc_mezzanine_we) and not fmc_adc_mezzanine_wack;
end if;
end if;
end process;
......@@ -120,75 +147,48 @@ begin
fmc_adc_mezzanine_o.stb <= fmc_adc_mezzanine_tr;
fmc_adc_mezzanine_wack <= fmc_adc_mezzanine_i.ack and fmc_adc_mezzanine_wt;
fmc_adc_mezzanine_rack <= fmc_adc_mezzanine_i.ack and fmc_adc_mezzanine_rt;
fmc_adc_mezzanine_o.adr <= ((18 downto 0 => '0') & wb_i.adr(12 downto 2)) & (1 downto 0 => '0');
fmc_adc_mezzanine_o.sel <= (others => '1');
fmc_adc_mezzanine_o.adr <= ((18 downto 0 => '0') & adr_int(12 downto 2)) & (1 downto 0 => '0');
fmc_adc_mezzanine_o.sel <= wr_sel_d0;
fmc_adc_mezzanine_o.we <= fmc_adc_mezzanine_wt;
fmc_adc_mezzanine_o.dat <= wb_i.dat;
fmc_adc_mezzanine_o.dat <= wr_dat_d0;
-- Process for write requests.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
metadata_wt <= '0';
fmc_adc_mezzanine_wt <= '0';
else
wr_ack_int <= '0';
metadata_wt <= '0';
fmc_adc_mezzanine_wt <= '0';
case wb_i.adr(14 downto 13) is
when "01" =>
-- Submap metadata
metadata_wt <= (metadata_wt or wr_int) and not metadata_wack;
wr_ack_int <= metadata_wack;
when "10" =>
-- Submap fmc_adc_mezzanine
fmc_adc_mezzanine_wt <= (fmc_adc_mezzanine_wt or wr_int) and not fmc_adc_mezzanine_wack;
wr_ack_int <= fmc_adc_mezzanine_wack;
when others =>
wr_ack_int <= wr_int;
end case;
end if;
end if;
end process;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(14 downto 13) is
when "01" =>
when "10" =>
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
process (wr_adr_d0, wr_req_d0, metadata_wack, fmc_adc_mezzanine_wack) begin
metadata_we <= '0';
fmc_adc_mezzanine_we <= '0';
case wr_adr_d0(14 downto 13) is
when "01" =>
-- Submap metadata
metadata_we <= wr_req_d0;
wr_ack_int <= metadata_wack;
when "10" =>
-- Submap fmc_adc_mezzanine
fmc_adc_mezzanine_we <= wr_req_d0;
wr_ack_int <= fmc_adc_mezzanine_wack;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int, rd_int, metadata_i.dat, metadata_rack, metadata_rt, rd_int, fmc_adc_mezzanine_i.dat, fmc_adc_mezzanine_rack, fmc_adc_mezzanine_rt) begin
process (adr_int, rd_req_int, metadata_i.dat, metadata_rack, fmc_adc_mezzanine_i.dat, fmc_adc_mezzanine_rack) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
rd_dat_d0 <= (others => 'X');
metadata_re <= '0';
fmc_adc_mezzanine_re <= '0';
case wb_i.adr(14 downto 13) is
when "01" =>
case adr_int(14 downto 13) is
when "01" =>
-- Submap metadata
metadata_re <= rd_int;
wb_o.dat <= metadata_i.dat;
rd_ack_int <= metadata_rack;
when "10" =>
metadata_re <= rd_req_int;
rd_dat_d0 <= metadata_i.dat;
rd_ack_d0 <= metadata_rack;
when "10" =>
-- Submap fmc_adc_mezzanine
fmc_adc_mezzanine_re <= rd_int;
wb_o.dat <= fmc_adc_mezzanine_i.dat;
rd_ack_int <= fmc_adc_mezzanine_rack;
fmc_adc_mezzanine_re <= rd_req_int;
rd_dat_d0 <= fmc_adc_mezzanine_i.dat;
rd_ack_d0 <= fmc_adc_mezzanine_rack;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
......@@ -6,13 +6,14 @@ memory-map:
name: svec_ref_fmc_adc_100m_mmap
bus: wb-32-be
description: SPEC FMC-ADC-100M memory map
size: 0x8000
size: 0x10000
x-hdl:
busgroup: True
pipeline: wr,rd
children:
- submap:
name: metadata
address: 0x2000
address: 0x4000
size: 0x40
interface: wb-32-be
x-hdl:
......@@ -20,11 +21,11 @@ memory-map:
description: a ROM containing the application metadata
- submap:
name: fmc1_adc_mezzanine
address: 0x4000
address: 0x6000
description: FMC ADC Mezzanine slot 1
filename: fmc_adc_mezzanine_mmap.cheby
- submap:
name: fmc2_adc_mezzanine
address: 0x6000
address: 0x8000
description: FMC ADC Mezzanine slot 2
filename: fmc_adc_mezzanine_mmap.cheby
......@@ -32,8 +32,9 @@ entity svec_ref_fmc_adc_100m_mmap is
end svec_ref_fmc_adc_100m_mmap;
architecture syn of svec_ref_fmc_adc_100m_mmap is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal adr_int : std_logic_vector(15 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;
......@@ -41,28 +42,38 @@ architecture syn of svec_ref_fmc_adc_100m_mmap is
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal metadata_re : std_logic;
signal metadata_we : std_logic;
signal metadata_wt : std_logic;
signal metadata_rt : std_logic;
signal metadata_tr : std_logic;
signal metadata_wack : std_logic;
signal metadata_rack : std_logic;
signal fmc1_adc_mezzanine_re : std_logic;
signal fmc1_adc_mezzanine_we : std_logic;
signal fmc1_adc_mezzanine_wt : std_logic;
signal fmc1_adc_mezzanine_rt : std_logic;
signal fmc1_adc_mezzanine_tr : std_logic;
signal fmc1_adc_mezzanine_wack : std_logic;
signal fmc1_adc_mezzanine_rack : std_logic;
signal fmc2_adc_mezzanine_re : std_logic;
signal fmc2_adc_mezzanine_we : std_logic;
signal fmc2_adc_mezzanine_wt : std_logic;
signal fmc2_adc_mezzanine_rt : std_logic;
signal fmc2_adc_mezzanine_tr : std_logic;
signal fmc2_adc_mezzanine_wack : std_logic;
signal fmc2_adc_mezzanine_rack : std_logic;
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal rd_req_d0 : std_logic;
signal rd_adr_d0 : std_logic_vector(15 downto 2);
signal rd_ack_d0 : std_logic;
signal rd_dat_d0 : std_logic_vector(31 downto 0);
signal wr_req_d0 : std_logic;
signal wr_dat_d0 : std_logic_vector(31 downto 0);
signal wr_sel_d0 : std_logic_vector(3 downto 0);
signal wr_ack_d0 : std_logic;
begin
-- WB decode signals
adr_int <= wb_i.adr(15 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
......@@ -74,7 +85,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -85,7 +96,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -93,16 +104,37 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
-- pipelining for rd-in+rd-out+wr-in+wr-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_req_d0 <= '0';
rd_ack_int <= '0';
wr_req_d0 <= '0';
wr_ack_int <= '0';
else
rd_req_d0 <= rd_req_int;
rd_adr_d0 <= adr_int;
rd_ack_int <= rd_ack_d0;
wb_o.dat <= rd_dat_d0;
wr_req_d0 <= wr_req_int;
wr_dat_d0 <= wb_i.dat;
wr_sel_d0 <= wb_i.sel;
wr_ack_int <= wr_ack_d0;
end if;
end if;
end process;
-- Assignments for submap metadata
-- Interface metadata
metadata_tr <= metadata_wt or metadata_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
metadata_rt <= '0';
metadata_wt <= '0';
else
metadata_rt <= (metadata_rt or metadata_re) and not metadata_rack;
metadata_wt <= (metadata_wt or metadata_we) and not metadata_wack;
end if;
end if;
end process;
......@@ -110,19 +142,21 @@ begin
metadata_o.stb <= metadata_tr;
metadata_wack <= metadata_i.ack and metadata_wt;
metadata_rack <= metadata_i.ack and metadata_rt;
metadata_o.adr <= ((25 downto 0 => '0') & wb_i.adr(5 downto 2)) & (1 downto 0 => '0');
metadata_o.sel <= (others => '1');
metadata_o.adr <= ((25 downto 0 => '0') & rd_adr_d0(5 downto 2)) & (1 downto 0 => '0');
metadata_o.sel <= wr_sel_d0;
metadata_o.we <= metadata_wt;
metadata_o.dat <= wb_i.dat;
metadata_o.dat <= wr_dat_d0;
-- Assignments for submap fmc1_adc_mezzanine
-- Interface fmc1_adc_mezzanine
fmc1_adc_mezzanine_tr <= fmc1_adc_mezzanine_wt or fmc1_adc_mezzanine_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc1_adc_mezzanine_rt <= '0';
fmc1_adc_mezzanine_wt <= '0';
else
fmc1_adc_mezzanine_rt <= (fmc1_adc_mezzanine_rt or fmc1_adc_mezzanine_re) and not fmc1_adc_mezzanine_rack;
fmc1_adc_mezzanine_wt <= (fmc1_adc_mezzanine_wt or fmc1_adc_mezzanine_we) and not fmc1_adc_mezzanine_wack;
end if;
end if;
end process;
......@@ -130,19 +164,21 @@ begin
fmc1_adc_mezzanine_o.stb <= fmc1_adc_mezzanine_tr;
fmc1_adc_mezzanine_wack <= fmc1_adc_mezzanine_i.ack and fmc1_adc_mezzanine_wt;
fmc1_adc_mezzanine_rack <= fmc1_adc_mezzanine_i.ack and fmc1_adc_mezzanine_rt;
fmc1_adc_mezzanine_o.adr <= ((18 downto 0 => '0') & wb_i.adr(12 downto 2)) & (1 downto 0 => '0');
fmc1_adc_mezzanine_o.sel <= (others => '1');
fmc1_adc_mezzanine_o.adr <= ((18 downto 0 => '0') & rd_adr_d0(12 downto 2)) & (1 downto 0 => '0');
fmc1_adc_mezzanine_o.sel <= wr_sel_d0;
fmc1_adc_mezzanine_o.we <= fmc1_adc_mezzanine_wt;
fmc1_adc_mezzanine_o.dat <= wb_i.dat;
fmc1_adc_mezzanine_o.dat <= wr_dat_d0;
-- Assignments for submap fmc2_adc_mezzanine
-- Interface fmc2_adc_mezzanine
fmc2_adc_mezzanine_tr <= fmc2_adc_mezzanine_wt or fmc2_adc_mezzanine_rt;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
fmc2_adc_mezzanine_rt <= '0';
fmc2_adc_mezzanine_wt <= '0';
else
fmc2_adc_mezzanine_rt <= (fmc2_adc_mezzanine_rt or fmc2_adc_mezzanine_re) and not fmc2_adc_mezzanine_rack;
fmc2_adc_mezzanine_wt <= (fmc2_adc_mezzanine_wt or fmc2_adc_mezzanine_we) and not fmc2_adc_mezzanine_wack;
end if;
end if;
end process;
......@@ -150,88 +186,59 @@ begin
fmc2_adc_mezzanine_o.stb <= fmc2_adc_mezzanine_tr;
fmc2_adc_mezzanine_wack <= fmc2_adc_mezzanine_i.ack and fmc2_adc_mezzanine_wt;
fmc2_adc_mezzanine_rack <= fmc2_adc_mezzanine_i.ack and fmc2_adc_mezzanine_rt;
fmc2_adc_mezzanine_o.adr <= ((18 downto 0 => '0') & wb_i.adr(12 downto 2)) & (1 downto 0 => '0');
fmc2_adc_mezzanine_o.sel <= (others => '1');
fmc2_adc_mezzanine_o.adr <= ((18 downto 0 => '0') & rd_adr_d0(12 downto 2)) & (1 downto 0 => '0');
fmc2_adc_mezzanine_o.sel <= wr_sel_d0;
fmc2_adc_mezzanine_o.we <= fmc2_adc_mezzanine_wt;
fmc2_adc_mezzanine_o.dat <= wb_i.dat;
fmc2_adc_mezzanine_o.dat <= wr_dat_d0;
-- Process for write requests.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
metadata_wt <= '0';
fmc1_adc_mezzanine_wt <= '0';
fmc2_adc_mezzanine_wt <= '0';
else
wr_ack_int <= '0';
metadata_wt <= '0';
fmc1_adc_mezzanine_wt <= '0';
fmc2_adc_mezzanine_wt <= '0';
case wb_i.adr(14 downto 13) is
when "01" =>
-- Submap metadata
metadata_wt <= (metadata_wt or wr_int) and not metadata_wack;
wr_ack_int <= metadata_wack;
when "10" =>
-- Submap fmc1_adc_mezzanine
fmc1_adc_mezzanine_wt <= (fmc1_adc_mezzanine_wt or wr_int) and not fmc1_adc_mezzanine_wack;
wr_ack_int <= fmc1_adc_mezzanine_wack;
when "11" =>
-- Submap fmc2_adc_mezzanine
fmc2_adc_mezzanine_wt <= (fmc2_adc_mezzanine_wt or wr_int) and not fmc2_adc_mezzanine_wack;
wr_ack_int <= fmc2_adc_mezzanine_wack;
when others =>
wr_ack_int <= wr_int;
end case;
end if;
end if;
end process;
-- Process for registers read.
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(14 downto 13) is
when "01" =>
when "10" =>
when "11" =>
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
end if;
end if;
process (rd_adr_d0, wr_req_d0, metadata_wack, fmc1_adc_mezzanine_wack, fmc2_adc_mezzanine_wack) begin
metadata_we <= '0';
fmc1_adc_mezzanine_we <= '0';
fmc2_adc_mezzanine_we <= '0';
case rd_adr_d0(15 downto 13) is
when "010" =>
-- Submap metadata
metadata_we <= wr_req_d0;
wr_ack_d0 <= metadata_wack;
when "011" =>
-- Submap fmc1_adc_mezzanine
fmc1_adc_mezzanine_we <= wr_req_d0;
wr_ack_d0 <= fmc1_adc_mezzanine_wack;
when "100" =>
-- Submap fmc2_adc_mezzanine
fmc2_adc_mezzanine_we <= wr_req_d0;
wr_ack_d0 <= fmc2_adc_mezzanine_wack;
when others =>
wr_ack_d0 <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int, rd_int, metadata_i.dat, metadata_rack, metadata_rt, rd_int, fmc1_adc_mezzanine_i.dat, fmc1_adc_mezzanine_rack, fmc1_adc_mezzanine_rt, rd_int, fmc2_adc_mezzanine_i.dat, fmc2_adc_mezzanine_rack, fmc2_adc_mezzanine_rt) begin
process (rd_adr_d0, rd_req_d0, metadata_i.dat, metadata_rack, fmc1_adc_mezzanine_i.dat, fmc1_adc_mezzanine_rack, fmc2_adc_mezzanine_i.dat, fmc2_adc_mezzanine_rack) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
rd_dat_d0 <= (others => 'X');
metadata_re <= '0';
fmc1_adc_mezzanine_re <= '0';
fmc2_adc_mezzanine_re <= '0';
case wb_i.adr(14 downto 13) is
when "01" =>
case rd_adr_d0(15 downto 13) is
when "010" =>
-- Submap metadata
metadata_re <= rd_int;
wb_o.dat <= metadata_i.dat;
rd_ack_int <= metadata_rack;
when "10" =>
metadata_re <= rd_req_d0;
rd_dat_d0 <= metadata_i.dat;
rd_ack_d0 <= metadata_rack;
when "011" =>
-- Submap fmc1_adc_mezzanine
fmc1_adc_mezzanine_re <= rd_int;
wb_o.dat <= fmc1_adc_mezzanine_i.dat;
rd_ack_int <= fmc1_adc_mezzanine_rack;
when "11" =>
fmc1_adc_mezzanine_re <= rd_req_d0;
rd_dat_d0 <= fmc1_adc_mezzanine_i.dat;
rd_ack_d0 <= fmc1_adc_mezzanine_rack;
when "100" =>
-- Submap fmc2_adc_mezzanine
fmc2_adc_mezzanine_re <= rd_int;
wb_o.dat <= fmc2_adc_mezzanine_i.dat;
rd_ack_int <= fmc2_adc_mezzanine_rack;
fmc2_adc_mezzanine_re <= rd_req_d0;
rd_dat_d0 <= fmc2_adc_mezzanine_i.dat;
rd_ack_d0 <= fmc2_adc_mezzanine_rack;
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_d0;
end case;
end process;
end syn;
......@@ -56,7 +56,6 @@ entity timetag_core_regs is
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Wires and registers
timetag_core_i : in t_timetag_core_master_in;
timetag_core_o : out t_timetag_core_master_out
......@@ -64,22 +63,37 @@ entity timetag_core_regs is
end timetag_core_regs;
architecture syn of timetag_core_regs is
signal rd_int : std_logic;
signal wr_int : std_logic;
signal adr_int : std_logic_vector(6 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 seconds_upper_wreq : std_logic;
signal seconds_lower_wreq : std_logic;
signal coarse_wreq : std_logic;
signal time_trig_seconds_upper_reg : std_logic_vector(7 downto 0);
signal time_trig_seconds_upper_wreq : std_logic;
signal time_trig_seconds_upper_wack : std_logic;
signal time_trig_seconds_lower_reg : std_logic_vector(31 downto 0);
signal time_trig_seconds_lower_wreq : std_logic;
signal time_trig_seconds_lower_wack : std_logic;
signal time_trig_coarse_reg : std_logic_vector(27 downto 0);
signal reg_rdat_int : std_logic_vector(31 downto 0);
signal rd_ack1_int : std_logic;
signal time_trig_coarse_wreq : std_logic;
signal time_trig_coarse_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(6 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(6 downto 2);
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
......@@ -91,7 +105,7 @@ begin
end if;
end if;
end process;
rd_int <= (wb_en and not wb_i.we) and not wb_rip;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
......@@ -102,7 +116,7 @@ begin
end if;
end if;
end process;
wr_int <= (wb_en and wb_i.we) and not wb_wip;
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;
......@@ -110,265 +124,272 @@ begin
wb_o.rty <= '0';
wb_o.err <= '0';
-- Assign outputs
timetag_core_o.time_trig_seconds_upper <= time_trig_seconds_upper_reg;
timetag_core_o.time_trig_seconds_lower <= time_trig_seconds_lower_reg;
timetag_core_o.time_trig_coarse <= time_trig_coarse_reg;
-- 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;
-- Process for write requests.
-- Register seconds_upper
timetag_core_o.seconds_upper <= wr_dat_d0(7 downto 0);
timetag_core_o.seconds_upper_wr <= seconds_upper_wreq;
-- Register seconds_lower
timetag_core_o.seconds_lower <= wr_dat_d0;
timetag_core_o.seconds_lower_wr <= seconds_lower_wreq;
-- Register coarse
timetag_core_o.coarse <= wr_dat_d0(27 downto 0);
timetag_core_o.coarse_wr <= coarse_wreq;
-- Register time_trig_seconds_upper
timetag_core_o.time_trig_seconds_upper <= time_trig_seconds_upper_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ack_int <= '0';
timetag_core_o.seconds_upper_wr <= '0';
timetag_core_o.seconds_lower_wr <= '0';
timetag_core_o.coarse_wr <= '0';
time_trig_seconds_upper_reg <= "00000000";
time_trig_seconds_upper_wack <= '0';
else
if time_trig_seconds_upper_wreq = '1' then
time_trig_seconds_upper_reg <= wr_dat_d0(7 downto 0);
end if;
time_trig_seconds_upper_wack <= time_trig_seconds_upper_wreq;
end if;
end if;
end process;
-- Register time_trig_seconds_lower
timetag_core_o.time_trig_seconds_lower <= time_trig_seconds_lower_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
time_trig_seconds_lower_reg <= "00000000000000000000000000000000";
time_trig_coarse_reg <= "0000000000000000000000000000";
time_trig_seconds_lower_wack <= '0';
else
wr_ack_int <= '0';
timetag_core_o.seconds_upper_wr <= '0';
timetag_core_o.seconds_lower_wr <= '0';
timetag_core_o.coarse_wr <= '0';
case wb_i.adr(6 downto 2) is
when "00000" =>
-- Register seconds_upper
timetag_core_o.seconds_upper_wr <= wr_int;
if wr_int = '1' then
timetag_core_o.seconds_upper <= wb_i.dat(7 downto 0);
end if;
wr_ack_int <= wr_int;
when "00001" =>
-- Register seconds_lower
timetag_core_o.seconds_lower_wr <= wr_int;
if wr_int = '1' then
timetag_core_o.seconds_lower <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "00010" =>
-- Register coarse
timetag_core_o.coarse_wr <= wr_int;
if wr_int = '1' then
timetag_core_o.coarse <= wb_i.dat(27 downto 0);
end if;
wr_ack_int <= wr_int;
when "00011" =>
-- Register time_trig_seconds_upper
if wr_int = '1' then
time_trig_seconds_upper_reg <= wb_i.dat(7 downto 0);
end if;
wr_ack_int <= wr_int;
when "00100" =>
-- Register time_trig_seconds_lower
if wr_int = '1' then
time_trig_seconds_lower_reg <= wb_i.dat;
end if;
wr_ack_int <= wr_int;
when "00101" =>
-- Register time_trig_coarse
if wr_int = '1' then
time_trig_coarse_reg <= wb_i.dat(27 downto 0);
end if;
wr_ack_int <= wr_int;
when "00110" =>
-- Register trig_tag_seconds_upper
when "00111" =>
-- Register trig_tag_seconds_lower
when "01000" =>
-- Register trig_tag_coarse
when "01001" =>
-- Register acq_start_tag_seconds_upper
when "01010" =>
-- Register acq_start_tag_seconds_lower
when "01011" =>
-- Register acq_start_tag_coarse
when "01100" =>
-- Register acq_stop_tag_seconds_upper
when "01101" =>
-- Register acq_stop_tag_seconds_lower
when "01110" =>
-- Register acq_stop_tag_coarse
when "01111" =>
-- Register acq_end_tag_seconds_upper
when "10000" =>
-- Register acq_end_tag_seconds_lower
when "10001" =>
-- Register acq_end_tag_coarse
when others =>
wr_ack_int <= wr_int;
end case;
if time_trig_seconds_lower_wreq = '1' then
time_trig_seconds_lower_reg <= wr_dat_d0;
end if;
time_trig_seconds_lower_wack <= time_trig_seconds_lower_wreq;
end if;
end if;
end process;
-- Process for registers read.
-- Register time_trig_coarse
timetag_core_o.time_trig_coarse <= time_trig_coarse_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack1_int <= '0';
time_trig_coarse_reg <= "0000000000000000000000000000";
time_trig_coarse_wack <= '0';
else
reg_rdat_int <= (others => 'X');
case wb_i.adr(6 downto 2) is
when "00000" =>
-- seconds_upper
reg_rdat_int(7 downto 0) <= timetag_core_i.seconds_upper;
rd_ack1_int <= rd_int;
when "00001" =>
-- seconds_lower
reg_rdat_int <= timetag_core_i.seconds_lower;
rd_ack1_int <= rd_int;
when "00010" =>
-- coarse
reg_rdat_int(27 downto 0) <= timetag_core_i.coarse;
rd_ack1_int <= rd_int;
when "00011" =>
-- time_trig_seconds_upper
reg_rdat_int(7 downto 0) <= time_trig_seconds_upper_reg;
rd_ack1_int <= rd_int;
when "00100" =>
-- time_trig_seconds_lower
reg_rdat_int <= time_trig_seconds_lower_reg;
rd_ack1_int <= rd_int;
when "00101" =>
-- time_trig_coarse
reg_rdat_int(27 downto 0) <= time_trig_coarse_reg;
rd_ack1_int <= rd_int;
when "00110" =>
-- trig_tag_seconds_upper
reg_rdat_int(7 downto 0) <= timetag_core_i.trig_tag_seconds_upper;
rd_ack1_int <= rd_int;
when "00111" =>
-- trig_tag_seconds_lower
reg_rdat_int <= timetag_core_i.trig_tag_seconds_lower;
rd_ack1_int <= rd_int;
when "01000" =>
-- trig_tag_coarse
reg_rdat_int(27 downto 0) <= timetag_core_i.trig_tag_coarse;
rd_ack1_int <= rd_int;
when "01001" =>
-- acq_start_tag_seconds_upper
reg_rdat_int(7 downto 0) <= timetag_core_i.acq_start_tag_seconds_upper;
rd_ack1_int <= rd_int;
when "01010" =>
-- acq_start_tag_seconds_lower
reg_rdat_int <= timetag_core_i.acq_start_tag_seconds_lower;
rd_ack1_int <= rd_int;
when "01011" =>
-- acq_start_tag_coarse
reg_rdat_int(27 downto 0) <= timetag_core_i.acq_start_tag_coarse;
rd_ack1_int <= rd_int;
when "01100" =>
-- acq_stop_tag_seconds_upper
reg_rdat_int(7 downto 0) <= timetag_core_i.acq_stop_tag_seconds_upper;
rd_ack1_int <= rd_int;
when "01101" =>
-- acq_stop_tag_seconds_lower
reg_rdat_int <= timetag_core_i.acq_stop_tag_seconds_lower;
rd_ack1_int <= rd_int;
when "01110" =>
-- acq_stop_tag_coarse
reg_rdat_int(27 downto 0) <= timetag_core_i.acq_stop_tag_coarse;
rd_ack1_int <= rd_int;
when "01111" =>
-- acq_end_tag_seconds_upper
reg_rdat_int(7 downto 0) <= timetag_core_i.acq_end_tag_seconds_upper;
rd_ack1_int <= rd_int;
when "10000" =>
-- acq_end_tag_seconds_lower
reg_rdat_int <= timetag_core_i.acq_end_tag_seconds_lower;
rd_ack1_int <= rd_int;
when "10001" =>
-- acq_end_tag_coarse
reg_rdat_int(27 downto 0) <= timetag_core_i.acq_end_tag_coarse;
rd_ack1_int <= rd_int;
when others =>
reg_rdat_int <= (others => 'X');
rd_ack1_int <= rd_int;
end case;
if time_trig_coarse_wreq = '1' then
time_trig_coarse_reg <= wr_dat_d0(27 downto 0);
end if;
time_trig_coarse_wack <= time_trig_coarse_wreq;
end if;
end if;
end process;
-- Register trig_tag_seconds_upper
-- Register trig_tag_seconds_lower
-- Register trig_tag_coarse
-- Register acq_start_tag_seconds_upper
-- Register acq_start_tag_seconds_lower
-- Register acq_start_tag_coarse
-- Register acq_stop_tag_seconds_upper
-- Register acq_stop_tag_seconds_lower
-- Register acq_stop_tag_coarse
-- Register acq_end_tag_seconds_upper
-- Register acq_end_tag_seconds_lower
-- Register acq_end_tag_coarse
-- Process for write requests.
process (wr_adr_d0, wr_req_d0, time_trig_seconds_upper_wack, time_trig_seconds_lower_wack, time_trig_coarse_wack) begin
seconds_upper_wreq <= '0';
seconds_lower_wreq <= '0';
coarse_wreq <= '0';
time_trig_seconds_upper_wreq <= '0';
time_trig_seconds_lower_wreq <= '0';
time_trig_coarse_wreq <= '0';
case wr_adr_d0(6 downto 2) is
when "00000" =>
-- Reg seconds_upper
seconds_upper_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when "00001" =>
-- Reg seconds_lower
seconds_lower_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when "00010" =>
-- Reg coarse
coarse_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when "00011" =>
-- Reg time_trig_seconds_upper
time_trig_seconds_upper_wreq <= wr_req_d0;
wr_ack_int <= time_trig_seconds_upper_wack;
when "00100" =>
-- Reg time_trig_seconds_lower
time_trig_seconds_lower_wreq <= wr_req_d0;
wr_ack_int <= time_trig_seconds_lower_wack;
when "00101" =>
-- Reg time_trig_coarse
time_trig_coarse_wreq <= wr_req_d0;
wr_ack_int <= time_trig_coarse_wack;
when "00110" =>
-- Reg trig_tag_seconds_upper
wr_ack_int <= wr_req_d0;
when "00111" =>
-- Reg trig_tag_seconds_lower
wr_ack_int <= wr_req_d0;
when "01000" =>
-- Reg trig_tag_coarse
wr_ack_int <= wr_req_d0;
when "01001" =>
-- Reg acq_start_tag_seconds_upper
wr_ack_int <= wr_req_d0;
when "01010" =>
-- Reg acq_start_tag_seconds_lower
wr_ack_int <= wr_req_d0;
when "01011" =>
-- Reg acq_start_tag_coarse
wr_ack_int <= wr_req_d0;
when "01100" =>
-- Reg acq_stop_tag_seconds_upper
wr_ack_int <= wr_req_d0;
when "01101" =>
-- Reg acq_stop_tag_seconds_lower
wr_ack_int <= wr_req_d0;
when "01110" =>
-- Reg acq_stop_tag_coarse
wr_ack_int <= wr_req_d0;
when "01111" =>
-- Reg acq_end_tag_seconds_upper
wr_ack_int <= wr_req_d0;
when "10000" =>
-- Reg acq_end_tag_seconds_lower
wr_ack_int <= wr_req_d0;
when "10001" =>
-- Reg acq_end_tag_coarse
wr_ack_int <= wr_req_d0;
when others =>
wr_ack_int <= wr_req_d0;
end case;
end process;
-- Process for read requests.
process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
process (adr_int, rd_req_int, timetag_core_i.seconds_upper, timetag_core_i.seconds_lower, timetag_core_i.coarse, time_trig_seconds_upper_reg, time_trig_seconds_lower_reg, time_trig_coarse_reg, timetag_core_i.trig_tag_seconds_upper, timetag_core_i.trig_tag_seconds_lower, timetag_core_i.trig_tag_coarse, timetag_core_i.acq_start_tag_seconds_upper, timetag_core_i.acq_start_tag_seconds_lower, timetag_core_i.acq_start_tag_coarse, timetag_core_i.acq_stop_tag_seconds_upper, timetag_core_i.acq_stop_tag_seconds_lower, timetag_core_i.acq_stop_tag_coarse, timetag_core_i.acq_end_tag_seconds_upper, timetag_core_i.acq_end_tag_seconds_lower, timetag_core_i.acq_end_tag_coarse) begin
-- By default ack read requests
wb_o.dat <= (others => '0');
case wb_i.adr(6 downto 2) is
when "00000" =>
-- seconds_upper
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00001" =>
-- seconds_lower
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00010" =>
-- coarse
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00011" =>
-- time_trig_seconds_upper
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00100" =>
-- time_trig_seconds_lower
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00101" =>
-- time_trig_coarse
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00110" =>
-- trig_tag_seconds_upper
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "00111" =>
-- trig_tag_seconds_lower
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01000" =>
-- trig_tag_coarse
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01001" =>
-- acq_start_tag_seconds_upper
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01010" =>
-- acq_start_tag_seconds_lower
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01011" =>
-- acq_start_tag_coarse
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01100" =>
-- acq_stop_tag_seconds_upper
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01101" =>
-- acq_stop_tag_seconds_lower
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01110" =>
-- acq_stop_tag_coarse
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "01111" =>
-- acq_end_tag_seconds_upper
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10000" =>
-- acq_end_tag_seconds_lower
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
when "10001" =>
-- acq_end_tag_coarse
wb_o.dat <= reg_rdat_int;
rd_ack_int <= rd_ack1_int;
rd_dat_d0 <= (others => 'X');
case adr_int(6 downto 2) is
when "00000" =>
-- Reg seconds_upper
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= timetag_core_i.seconds_upper;
rd_dat_d0(31 downto 8) <= (others => '0');
when "00001" =>
-- Reg seconds_lower
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= timetag_core_i.seconds_lower;
when "00010" =>
-- Reg coarse
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= timetag_core_i.coarse;
rd_dat_d0(31 downto 28) <= (others => '0');
when "00011" =>
-- Reg time_trig_seconds_upper
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= time_trig_seconds_upper_reg;
rd_dat_d0(31 downto 8) <= (others => '0');
when "00100" =>
-- Reg time_trig_seconds_lower
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= time_trig_seconds_lower_reg;
when "00101" =>
-- Reg time_trig_coarse
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= time_trig_coarse_reg;
rd_dat_d0(31 downto 28) <= (others => '0');
when "00110" =>
-- Reg trig_tag_seconds_upper
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= timetag_core_i.trig_tag_seconds_upper;
rd_dat_d0(31 downto 8) <= (others => '0');
when "00111" =>
-- Reg trig_tag_seconds_lower
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= timetag_core_i.trig_tag_seconds_lower;
when "01000" =>
-- Reg trig_tag_coarse
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= timetag_core_i.trig_tag_coarse;
rd_dat_d0(31 downto 28) <= (others => '0');
when "01001" =>
-- Reg acq_start_tag_seconds_upper
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= timetag_core_i.acq_start_tag_seconds_upper;
rd_dat_d0(31 downto 8) <= (others => '0');
when "01010" =>
-- Reg acq_start_tag_seconds_lower
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= timetag_core_i.acq_start_tag_seconds_lower;
when "01011" =>
-- Reg acq_start_tag_coarse
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= timetag_core_i.acq_start_tag_coarse;
rd_dat_d0(31 downto 28) <= (others => '0');
when "01100" =>
-- Reg acq_stop_tag_seconds_upper
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= timetag_core_i.acq_stop_tag_seconds_upper;
rd_dat_d0(31 downto 8) <= (others => '0');
when "01101" =>
-- Reg acq_stop_tag_seconds_lower
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= timetag_core_i.acq_stop_tag_seconds_lower;
when "01110" =>
-- Reg acq_stop_tag_coarse
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= timetag_core_i.acq_stop_tag_coarse;
rd_dat_d0(31 downto 28) <= (others => '0');
when "01111" =>
-- Reg acq_end_tag_seconds_upper
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= timetag_core_i.acq_end_tag_seconds_upper;
rd_dat_d0(31 downto 8) <= (others => '0');
when "10000" =>
-- Reg acq_end_tag_seconds_lower
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= timetag_core_i.acq_end_tag_seconds_lower;
when "10001" =>
-- Reg acq_end_tag_coarse
rd_ack_d0 <= rd_req_int;
rd_dat_d0(27 downto 0) <= timetag_core_i.acq_end_tag_coarse;
rd_dat_d0(31 downto 28) <= (others => '0');
when others =>
rd_ack_int <= rd_int;
rd_ack_d0 <= rd_req_int;
end case;
end process;
end syn;
Subproject commit 70f9de318f155764fdd4b7e1ae7f9c5b77131930
Subproject commit b84d0335dcda7b55352a3aabd38f65cf2169cac2
Subproject commit 258eb8e00f99f795fe9b98840b01ac4a8b92ec94
Subproject commit 67100ef69d1d65cbb33f80475f860de996bdf619
Subproject commit 06414d93d446a4e851f8aecd7512eec1b6d1fc4c
Subproject commit 461b30fe1f5e4e0c99f2265cdbf5843d31e31a4b
Subproject commit 26b16bd3b1217d447034437eb83c1c56b75c8bd3
Subproject commit fd485c8b31b50a681f1a72504f6969384cfb1d4f
Subproject commit 7d85d3b7bcb88186cd49a8646053f67d3aceab41
Subproject commit 577b31c8b1dc530aa145a8a49ab10dff7e9483b1
Subproject commit f85c29dbca768bedd709b3f43448706c7d27b76d
Subproject commit b25fbe11de7efc6c9a22b5646de852f0d27f2d15
......@@ -140,12 +140,7 @@ architecture rtl of fmc_adc_100Ms_core is
signal serdes_arst : std_logic;
-- Clocks and PLL
signal clk_fb : std_logic;
signal clk_fb_buf : std_logic;
signal locked_in : std_logic;
signal serdes_clk : std_logic;
signal fs_clk : std_logic;
signal fs_clk_buf : std_logic;
signal fs_freq : std_logic_vector(31 downto 0);
signal fs_freq_t : std_logic_vector(31 downto 0);
signal fs_freq_valid : std_logic;
......@@ -279,6 +274,8 @@ architecture rtl of fmc_adc_100Ms_core is
signal dpram_addrb_cnt : unsigned(c_DPRAM_DEPTH-1 downto 0);
signal dpram_dout : std_logic_vector(63 downto 0);
signal dpram_valid : std_logic;
signal dpram_valid_d1 : std_logic;
signal dpram_valid_d2 : std_logic;
signal dpram_valid_t : std_logic;
signal dpram0_dina : std_logic_vector(63 downto 0);
......@@ -302,10 +299,15 @@ architecture rtl of fmc_adc_100Ms_core is
signal wb_ddr_fifo_rd : std_logic;
signal wb_ddr_fifo_wr_en : std_logic;
signal wb_ddr_skidpad_stb_in : std_logic;
signal wb_ddr_skidpad_stb_out : std_logic;
signal wb_ddr_skidpad_stall : std_logic;
signal wb_ddr_skidpad_adr_in : std_logic_vector(28 downto 0);
signal wb_ddr_skidpad_adr_out : std_logic_vector(28 downto 0);
-- RAM address counter
signal ram_addr_cnt : unsigned(28 downto 0);
signal trig_addr : std_logic_vector(31 downto 0);
signal mem_ovr : std_logic;
-- LEDs
signal trig_led : std_logic;
......@@ -546,10 +548,10 @@ begin
if rising_edge(sys_clk_i) then
gpio_si570_oe_o <= csr_regout.ctl_fmc_clk_oe;
gpio_dac_clr_n_o <= csr_regout.ctl_offset_dac_clr_n;
gpio_ssr_ch1_o <= channel_regout(1).ctl_ssr;
gpio_ssr_ch2_o <= channel_regout(2).ctl_ssr;
gpio_ssr_ch3_o <= channel_regout(3).ctl_ssr;
gpio_ssr_ch4_o <= channel_regout(4).ctl_ssr;
gpio_ssr_ch1_o <= channel_regout(1).ctl_ssr;
gpio_ssr_ch2_o <= channel_regout(2).ctl_ssr;
gpio_ssr_ch3_o <= channel_regout(3).ctl_ssr;
gpio_ssr_ch4_o <= channel_regout(4).ctl_ssr;
end if;
end process p_delay_gpio_ssr;
......@@ -794,12 +796,14 @@ begin
ext_trig_delay_bsy <= '0';
else
if ext_trig = '1' and ext_trig_delay_bsy = '0' then
-- Start counter
ext_trig_delay_cnt <= unsigned(ext_trig_delay);
ext_trig_delay_bsy <= '1';
elsif ext_trig_delay_cnt /= 0 then
-- Count
ext_trig_delay_cnt <= ext_trig_delay_cnt - 1;
else
-- when counter reaches zero
-- When counter reaches zero
ext_trig_delay_bsy <= '0';
end if;
end if;
......@@ -989,7 +993,7 @@ begin
downsample_cnt <= to_unsigned(1, downsample_cnt'length);
downsample_en <= '0';
else
if downsample_cnt = to_unsigned(0, downsample_cnt'length) then
if downsample_cnt = 0 then
if downsample_factor /= X"00000000" then
downsample_cnt <= unsigned(downsample_factor) - 1;
end if;
......@@ -1401,23 +1405,37 @@ begin
dpram_addra_trig <= dpram_addra_cnt;
end if;
if post_trig_done = '1' then
dpram_addra_post_done <= dpram_addra_cnt;
-- reads 2 extra addresses -> trigger time-tag
dpram_addra_post_done <= dpram_addra_cnt + 2;
end if;
end if;
end if;
end process p_dpram_addra_cnt;
-- DPRAM inputs
dpram0_addra <= std_logic_vector(dpram_addra_cnt);
dpram1_addra <= std_logic_vector(dpram_addra_cnt);
dpram0_dina <= sync_fifo_dout(63 downto 0)
when acq_in_trig_tag = '0' else trig_tag_data;
dpram1_dina <= sync_fifo_dout(63 downto 0)
when acq_in_trig_tag = '0' else trig_tag_data;
dpram0_wea <= not single_shot and ((samples_wr_en and sync_fifo_valid) or acq_in_trig_tag)
when multishot_buffer_sel = '0' else '0';
dpram1_wea <= not single_shot and ((samples_wr_en and sync_fifo_valid) or acq_in_trig_tag)
when multishot_buffer_sel = '1' else '0';
p_dpram_inputs: process (sys_clk_i)
begin
if rising_edge(sys_clk_i) then
if sys_rst_n_i = '0' then
dpram0_wea <= '0';
dpram1_wea <= '1';
else
dpram0_addra <= std_logic_vector(dpram_addra_cnt);
dpram1_addra <= std_logic_vector(dpram_addra_cnt);
if acq_in_trig_tag = '0' then
dpram0_dina <= sync_fifo_dout(63 downto 0);
dpram1_dina <= sync_fifo_dout(63 downto 0);
else
dpram0_dina <= trig_tag_data;
dpram1_dina <= trig_tag_data;
end if;
dpram0_wea <= not single_shot and ((samples_wr_en and sync_fifo_valid) or acq_in_trig_tag)
and not multishot_buffer_sel;
dpram1_wea <= not single_shot and ((samples_wr_en and sync_fifo_valid) or acq_in_trig_tag)
and multishot_buffer_sel;
end if;
end if;
end process;
-- DPRAMs
cmp_multishot_dpram0 : generic_dpram
......@@ -1480,25 +1498,44 @@ begin
if rising_edge(sys_clk_i) then
if sys_rst_n_i = '0' or single_shot = '1' then
dpram_valid_t <= '0';
dpram_valid <= '0';
else
if trig_tag_done = '1' then
dpram_addrb_cnt <= dpram_addra_trig - unsigned(pre_trig_value(c_DPRAM_DEPTH-1 downto 0));
dpram_valid_t <= '1';
elsif (dpram_addrb_cnt = dpram_addra_post_done + 2) then -- reads 2 extra addresses -> trigger time-tag
elsif dpram_addrb_cnt = dpram_addra_post_done then
dpram_valid_t <= '0';
else
dpram_addrb_cnt <= dpram_addrb_cnt + 1;
end if;
dpram_valid <= dpram_valid_t;
end if;
end if;
end process p_dpram_addrb_cnt;
-- DPRAM output mux
dpram_dout <= dpram0_doutb when multishot_buffer_sel = '1' else dpram1_doutb;
dpram0_addrb <= std_logic_vector(dpram_addrb_cnt);
dpram1_addrb <= std_logic_vector(dpram_addrb_cnt);
p_dpram_valid : process (sys_clk_i)
begin
if rising_edge(sys_clk_i) then
if sys_rst_n_i = '0' or single_shot = '1' then
dpram_valid <= '0';
dpram_valid_d1 <= '0';
dpram_valid_d2 <= '0';
else
dpram0_addrb <= std_logic_vector(dpram_addrb_cnt);
dpram1_addrb <= std_logic_vector(dpram_addrb_cnt);
-- dpram_valid is delayed by 2 cycles from dpram_valid_t.
-- 1 for the dpram access, the second for the pipeline here.
dpram_valid_d1 <= dpram_valid_t;
dpram_valid_d2 <= dpram_valid_d1;
dpram_valid <= dpram_valid_d2;
if multishot_buffer_sel = '1' then
dpram_dout <= dpram0_doutb;
else
dpram_dout <= dpram1_doutb;
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------
-- Flow control FIFO for data to DDR
......@@ -1568,7 +1605,7 @@ begin
wb_ddr_fifo_wr <= wb_ddr_fifo_wr_en and not(wb_ddr_fifo_full);
wb_ddr_fifo_rd <= not(wb_ddr_fifo_empty or wb_ddr_master_i.stall);
wb_ddr_fifo_rd <= not(wb_ddr_fifo_empty or wb_ddr_skidpad_stall);
------------------------------------------------------------------------------
-- Wishbone master (to DDR)
......@@ -1583,24 +1620,45 @@ begin
else
if acq_start = '1' then
ram_addr_cnt <= (others => '0');
elsif wb_ddr_fifo_empty = '0' and wb_ddr_master_i.stall = '0' then
elsif wb_ddr_fifo_empty = '0' and wb_ddr_skidpad_stall = '0' then
ram_addr_cnt <= ram_addr_cnt + 1;
end if;
end if;
end if;
end process p_ram_addr_cnt;
with acq_fsm_state select
wb_ddr_master_o.cyc <=
dpram_valid or not wb_ddr_fifo_empty when "001",
'1' when others;
wb_ddr_master_o.stb <= not wb_ddr_fifo_empty;
wb_ddr_skidpad_stb_in <= not wb_ddr_fifo_empty;
-- Convert to 32-bit word addressing for Wishbone
wb_ddr_master_o.adr <= "00" & std_logic_vector(ram_addr_cnt) & "0";
wb_ddr_skidpad_adr_in <= std_logic_vector(ram_addr_cnt);
inst_skidpad: entity work.wb_skidpad2
generic map (
g_adrbits => ram_addr_cnt'length,
g_datbits => 64
)
port map (
clk_i => wb_ddr_clk_i,
rst_n_i => wb_ddr_rst_n_i,
stb_i => wb_ddr_skidpad_stb_in,
adr_i => wb_ddr_skidpad_adr_in,
dat_i => wb_ddr_fifo_dout(63 downto 0),
sel_i => (others => '1'),
we_i => '1',
stall_o => wb_ddr_skidpad_stall,
stb_o => wb_ddr_skidpad_stb_out,
adr_o => wb_ddr_skidpad_adr_out,
dat_o => wb_ddr_master_o.dat,
sel_o => open,
we_o => open,
stall_i => wb_ddr_master_i.stall
);
wb_ddr_master_o.we <= '1';
wb_ddr_master_o.sel <= X"FF";
wb_ddr_master_o.dat <= wb_ddr_fifo_dout(63 downto 0);
wb_ddr_master_o.cyc <= dpram_valid or wb_ddr_skidpad_stb_out when acq_fsm_state = "001" else '1';
wb_ddr_master_o.stb <= wb_ddr_skidpad_stb_out;
wb_ddr_master_o.adr <= "00" & wb_ddr_skidpad_adr_out & "0";
-- Store trigger DDR address (byte address)
p_trig_addr : process (wb_ddr_clk_i)
......@@ -1708,12 +1766,12 @@ begin
trigout_trig <= f_reduce_or (trigout_triggers);
-- Acquisition trigger delayed pulse
p_acq_end : process (sys_clk_i)
p_acq_trig : process (sys_clk_i)
begin
if rising_edge(sys_clk_i) then
acq_trig_d <= acq_trig;
end if;
end process p_acq_end;
end process p_acq_trig;
trigout_fifo_wr <= trigout_trig and not trigout_fifo_full and acq_trig_d;
......
......@@ -139,14 +139,11 @@ architecture rtl of fmc_adc_mezzanine is
-- Signals declaration
------------------------------------------------------------------------------
-- Wishbone buse(s) from master(s) to crossbar slave port(s)
signal cnx_master_out : t_wishbone_master_out;
signal cnx_master_in : t_wishbone_master_in;
-- Wishbone buse(s) from crossbar master port(s) to slave(s)
signal cnx_slave_out : t_wishbone_slave_out_array(c_NUM_WB_SLAVES-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array(c_NUM_WB_SLAVES-1 downto 0);
-- Wishbone buse(s) from master(s) to crossbar slave port(s)
signal wb_csr_out : t_wishbone_slave_in;
signal wb_csr_in : t_wishbone_slave_out;
......@@ -205,24 +202,12 @@ begin
master_i => wb_csr_in,
master_o => wb_csr_out);
-- Additional register to help timing
cmp_xwb_register : xwb_register
generic map (
g_WB_MODE => PIPELINED)
port map (
rst_n_i => sys_rst_n_i,
clk_i => sys_clk_i,
slave_i => wb_csr_out,
slave_o => wb_csr_in,
master_i => cnx_master_in,
master_o => cnx_master_out);
cmp_crossbar : entity work.fmc_adc_mezzanine_mmap
port map (
rst_n_i => sys_rst_n_i,
clk_i => sys_clk_i,
wb_i => cnx_master_out,
wb_o => cnx_master_in,
wb_i => wb_csr_out,
wb_o => wb_csr_in,
fmc_adc_100m_csr_i => cnx_slave_out(c_WB_SLAVE_FMC_ADC),
fmc_adc_100m_csr_o => cnx_slave_in(c_WB_SLAVE_FMC_ADC),
fmc_adc_eic_i => cnx_slave_out(c_WB_SLAVE_FMC_EIC),
......@@ -317,7 +302,7 @@ begin
-- ADC core control and status
------------------------------------------------------------------------------
cmp_fmc_adc_100Ms_core : fmc_adc_100Ms_core
cmp_fmc_adc_100Ms_core : entity work.fmc_adc_100Ms_core
generic map (
g_MULTISHOT_RAM_SIZE => g_MULTISHOT_RAM_SIZE,
g_SPARTAN6_USE_PLL => g_SPARTAN6_USE_PLL,
......
......@@ -203,14 +203,14 @@ NET "gen_fmc_mezzanine[1].*/cmp_fmc_adc_100Ms_core/fs_clk" TNM_NET = fs1_clk;
TIMEGRP "adc0_sync_ffs" = "sync_ffs" EXCEPT "fs0_clk";
TIMEGRP "adc1_sync_ffs" = "sync_ffs" EXCEPT "fs1_clk";
TIMESPEC TS_adc0_sync_ffs = FROM fs0_clk TO "adc0_sync_ffs" TIG;
TIMESPEC TS_adc1_sync_ffs = FROM fs1_clk TO "adc1_sync_ffs" TIG;
#TIMESPEC TS_adc0_sync_ffs = FROM fs0_clk TO "adc0_sync_ffs" TIG;
#TIMESPEC TS_adc1_sync_ffs = FROM fs1_clk TO "adc1_sync_ffs" TIG;
TIMEGRP "adc0_sync_reg" = "sync_reg" EXCEPT "fs0_clk";
TIMEGRP "adc1_sync_reg" = "sync_reg" EXCEPT "fs1_clk";
TIMESPEC TS_adc0_sync_reg = FROM fs0_clk TO "adc0_sync_reg" 10ns DATAPATHONLY;
TIMESPEC TS_adc1_sync_reg = FROM fs1_clk TO "adc1_sync_reg" 10ns DATAPATHONLY;
TIMESPEC TS_adc0_sync_reg = FROM fs0_clk TO "adc0_sync_reg" 8ns DATAPATHONLY;
TIMESPEC TS_adc1_sync_reg = FROM fs1_clk TO "adc1_sync_reg" 8ns DATAPATHONLY;
# No sync words used in FMC-ADC
#TIMESPEC TS_adc0_sync_word = FROM sync_word TO fs0_clk 30ns DATAPATHONLY;
......
......@@ -5,14 +5,15 @@
`timescale 1ns/1ps
`include "vhd_wishbone_master.svh"
`include "fmc_adc_mezzanine_mmap.v"
`include "fmc_adc_100Ms_csr.v"
`include "timetag_core_regs.v"
`include "fmc_adc_aux_trigin.v"
`include "fmc_adc_aux_trigout.v"
`define SDB_ADDR 'h0000
`define CSR_BASE 'h1000
`define TAG_BASE 'h1900
`define CSR_BASE `ADDR_FMC_ADC_MEZZANINE_MMAP_FMC_ADC_100M_CSR
`define TAG_BASE `ADDR_FMC_ADC_MEZZANINE_MMAP_TIMETAG_CORE
module main;
......
......@@ -2,10 +2,10 @@
//
// SPDX-License-Identifier: CC0-1.0
`define SVEC_REF_FMC_ADC_100M_MMAP_SIZE 32768
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_METADATA 'h2000
`define SVEC_REF_FMC_ADC_100M_MMAP_SIZE 65536
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_METADATA 'h4000
`define SVEC_REF_FMC_ADC_100M_MMAP_METADATA_SIZE 64
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE 'h4000
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE 'h6000
`define SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE_SIZE 8192
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE 'h6000
`define ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE 'h8000
`define SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE_SIZE 8192
......@@ -6,14 +6,24 @@
`include "vme64x_bfm.svh"
`include "svec_vme_buffers.svh"
`include "svec_ref_fmc_adc_100Ms_mmap.v"
`include "fmc_adc_mezzanine_mmap.v"
`include "fmc_adc_100Ms_csr.v"
`include "fmc_adc_100Ms_channel_regs.v"
`include "fmc_adc_eic_regs.v"
`include "timetag_core_regs.v"
`define VME_OFFSET 'h80000000
`define ADC_OFFSET 'h4000
`define ADC1_OFFSET `VME_OFFSET + `ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE
`define ADC2_OFFSET `VME_OFFSET + `ADDR_SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE
`define CSR_BASE `VME_OFFSET + `ADC_OFFSET + 'h1000
`define OWC_BASE `VME_OFFSET + `ADC_OFFSET + 'h1700
`define TAG_BASE `VME_OFFSET + `ADC_OFFSET + 'h1900
`define CSR_BASE `ADC1_OFFSET + `ADDR_FMC_ADC_MEZZANINE_MMAP_FMC_ADC_100M_CSR
`define CH1_BASE `CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH1
`define CH2_BASE `CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH2
`define CH3_BASE `CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH3
`define CH4_BASE `CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_FMC_ADC_CH4
`define EIC_BASE `ADC1_OFFSET + `ADDR_FMC_ADC_MEZZANINE_MMAP_FMC_ADC_EIC
`define TAG_BASE `ADC1_OFFSET + `ADDR_FMC_ADC_MEZZANINE_MMAP_TIMETAG_CORE
module main;
......@@ -255,14 +265,13 @@ module main;
/* map func0 to 0x80000000, A32 */
acc.write('h7ff63, 'h80, A32|CR_CSR|D08Byte3);
acc.write('h7ff67, 0, CR_CSR|A32|D08Byte3);
acc.write('h7ff6b, 0, CR_CSR|A32|D08Byte3);
acc.write('h7ff6f, 36, CR_CSR|A32|D08Byte3);
acc.write('h7ff33, 1, CR_CSR|A32|D08Byte3);
acc.write('h7ff63, 'h80, CR_CSR|A32|D08Byte3);
acc.write('h7ff67, 0, CR_CSR|A32|D08Byte3);
acc.write('h7ff6b, 0, CR_CSR|A32|D08Byte3);
acc.write('h7ff6f, 36, CR_CSR|A32|D08Byte3);
acc.write('h7ff33, 1, CR_CSR|A32|D08Byte3);
acc.write('h7fffb, 'h10, CR_CSR|A32|D08Byte3); /* enable module (BIT_SET = 0x10) */
acc.set_default_modifiers(A32 | D32 | SINGLE);
endtask // init_vme64x_core
......@@ -309,22 +318,23 @@ module main;
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_SHOTS, 'h00000001);
// FMC-ADC core channel configuration
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_CALIB, 'h00008000);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_CALIB, 'h00008000);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_CALIB, 'h00008000);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_CALIB, 'h00008000);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_SAT, 'h00007fff);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_SAT, 'h00007fff);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_SAT, 'h00007fff);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_SAT, 'h00007fff);
acc.write(`CH1_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_CALIB, 'h00008000);
acc.write(`CH2_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_CALIB, 'h00008000);
acc.write(`CH3_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_CALIB, 'h00008000);
acc.write(`CH4_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_CALIB, 'h00008000);
acc.write(`CH1_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_SAT, 'h00007fff);
acc.write(`CH2_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_SAT, 'h00007fff);
acc.write(`CH3_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_SAT, 'h00007fff);
acc.write(`CH4_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_SAT, 'h00007fff);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CTL, `FMC_ADC_100MS_CSR_CTL_CALIB_APPLY);
// FMC-ADC core trigger configuration
val = (16'h100 << `FMC_ADC_100MS_CSR_CH1_TRIG_THRES_HYST_OFFSET) |
(16'h300 << `FMC_ADC_100MS_CSR_CH1_TRIG_THRES_VAL_OFFSET);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_TRIG_THRES, val);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_TRIG_THRES, val);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_TRIG_THRES, val);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_TRIG_THRES, val);
val = (16'h100 << `FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES_HYST_OFFSET) |
(16'h300 << `FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES_VAL_OFFSET);
acc.write(`CH1_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES, val);
acc.write(`CH2_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES, val);
acc.write(`CH3_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES, val);
acc.write(`CH4_BASE + `ADDR_FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES, val);
val = (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_SW_OFFSET);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_EN, val);
......@@ -353,6 +363,33 @@ module main;
wait (acq_fsm_state == 1);
$display("<%t> END ACQ 1/4", $realtime);
#100ns;
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_PRE_SAMPLES, 'h00000004);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_POST_SAMPLES, 'h00000008);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_SHOTS, 'h00000001);
val = (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_CH1_OFFSET);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_EN, val);
$display("<%t> START ACQ 1b/4", $realtime);
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CTL, 'h00000001); // FSM sta
#1us;
wait (acq_fsm_state == 1);
$display("<%t> END ACQ 1b/4", $realtime);
// TODO: check results (they are only displayed)
acc.read(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_POS, val);
$display("trig pos: %x", val);
acc.write(`VME_OFFSET + 16'h58, val);
for(i = 0; i < 8*2 + 4; i+=1) begin
acc.read(`VME_OFFSET + 16'h2000, val);
$display("%d: %08x", i, val);
end
$stop;
#200ns;
acc.write(`CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_SHOTS, 'h00000003); // #nshots: 3x multi-shot acq
......
......@@ -240,7 +240,7 @@ architecture arch of svec_ref_fmc_adc_100Ms is
constant c_WB_SLAVE_FMC1_ADC : integer := 2; -- FMC slot 2 ADC mezzanine
-- Convention metadata base address
constant c_METADATA_ADDR : t_wishbone_address := x"0000_2000";
constant c_METADATA_ADDR : t_wishbone_address := x"0000_4000";
------------------------------------------------------------------------------
-- Signals declaration
......@@ -309,6 +309,7 @@ begin -- architecture arch
inst_svec_base : entity work.svec_base_wr
generic map (
g_DECODE_AM => FALSE,
g_WITH_VIC => TRUE,
g_WITH_ONEWIRE => FALSE,
g_WITH_SPI => FALSE,
......@@ -475,7 +476,7 @@ begin -- architecture arch
generic map (
g_VENDOR_ID => x"0000_10DC",
g_DEVICE_ID => x"4144_4302", -- "ADC2"
g_VERSION => x"0500_0000",
g_VERSION => x"0500_0002",
g_CAPABILITIES => x"0000_0000",
g_COMMIT_ID => (others => '0'))
port map (
......@@ -503,9 +504,9 @@ begin -- architecture arch
gen_fmc_mezzanine : for I in 0 to g_NB_FMC_SLOTS - 1 generate
cmp_xwb_clock_bridge : xwb_clock_bridge
generic map (
g_SLAVE_PORT_WB_MODE => CLASSIC,
g_MASTER_PORT_WB_MODE => PIPELINED)
generic map (
g_SLAVE_PORT_WB_MODE => CLASSIC,
g_MASTER_PORT_WB_MODE => PIPELINED)
port map (
slave_clk_i => clk_sys_62m5,
slave_rst_n_i => rst_sys_62m5_n,
......@@ -641,7 +642,7 @@ begin -- architecture arch
d_i => fmc_acq_trig(I),
q_o => fmc_acq_trig_sync(I));
p_fmc_acq_led: process (fmc_acq_cfg_ok_sync) is
p_fmc_acq_led: process (fmc_acq_cfg_ok_sync, fmc_acq_trig_sync) is
begin
if fmc_acq_cfg_ok_sync(I) = '0' then
fmc_acq_led(I) <= c_LED_RED;
......
#ifndef __CHEBY__FMC_ADC_100MS_CHANNEL_REGS__H__
#define __CHEBY__FMC_ADC_100MS_CHANNEL_REGS__H__
#define FMC_ADC_100MS_CHANNEL_REGS_SIZE 24 /* 0x18 */
/* Channel control register */
#define FMC_ADC_100MS_CHANNEL_REGS_CTL 0x0UL
#define FMC_ADC_100MS_CHANNEL_REGS_CTL_SSR_MASK 0x7fUL
#define FMC_ADC_100MS_CHANNEL_REGS_CTL_SSR_SHIFT 0
/* Channel status register */
#define FMC_ADC_100MS_CHANNEL_REGS_STA 0x4UL
#define FMC_ADC_100MS_CHANNEL_REGS_STA_VAL_MASK 0xffffUL
#define FMC_ADC_100MS_CHANNEL_REGS_STA_VAL_SHIFT 0
/* Channel calibration register */
#define FMC_ADC_100MS_CHANNEL_REGS_CALIB 0x8UL
#define FMC_ADC_100MS_CHANNEL_REGS_CALIB_GAIN_MASK 0xffffUL
#define FMC_ADC_100MS_CHANNEL_REGS_CALIB_GAIN_SHIFT 0
#define FMC_ADC_100MS_CHANNEL_REGS_CALIB_OFFSET_MASK 0xffff0000UL
#define FMC_ADC_100MS_CHANNEL_REGS_CALIB_OFFSET_SHIFT 16
/* Channel saturation register */
#define FMC_ADC_100MS_CHANNEL_REGS_SAT 0xcUL
#define FMC_ADC_100MS_CHANNEL_REGS_SAT_VAL_MASK 0x7fffUL
#define FMC_ADC_100MS_CHANNEL_REGS_SAT_VAL_SHIFT 0
/* Channel trigger threshold configuration register */
#define FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES 0x10UL
#define FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES_VAL_MASK 0xffffUL
#define FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES_VAL_SHIFT 0
#define FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES_HYST_MASK 0xffff0000UL
#define FMC_ADC_100MS_CHANNEL_REGS_TRIG_THRES_HYST_SHIFT 16
/* Channel trigger delay */
#define FMC_ADC_100MS_CHANNEL_REGS_TRIG_DLY 0x14UL
struct fmc_adc_100ms_channel_regs {
/* [0x0]: REG (rw) Channel control register */
uint32_t ctl;
/* [0x4]: REG (ro) Channel status register */
uint32_t sta;
/* [0x8]: REG (rw) Channel calibration register */
uint32_t calib;
/* [0xc]: REG (rw) Channel saturation register */
uint32_t sat;
/* [0x10]: REG (rw) Channel trigger threshold configuration register */
uint32_t trig_thres;
/* [0x14]: REG (rw) Channel trigger delay */
uint32_t trig_dly;
};
#endif /* __CHEBY__FMC_ADC_100MS_CHANNEL_REGS__H__ */
#ifndef __CHEBY__FMC_ADC_100MS_CSR__H__
#define __CHEBY__FMC_ADC_100MS_CSR__H__
#include "fmc_adc_100ms_channel_regs.h"
#define FMC_ADC_100MS_CSR_SIZE 512 /* 0x200 */
/* Control register */
#define FMC_ADC_100MS_CSR_CTL 0x0UL
#define FMC_ADC_100MS_CSR_CTL_FSM_CMD_MASK 0x3UL
#define FMC_ADC_100MS_CSR_CTL_FSM_CMD_SHIFT 0
#define FMC_ADC_100MS_CSR_CTL_FMC_CLK_OE 0x4UL
#define FMC_ADC_100MS_CSR_CTL_OFFSET_DAC_CLR_N 0x8UL
#define FMC_ADC_100MS_CSR_CTL_MAN_BITSLIP 0x10UL
#define FMC_ADC_100MS_CSR_CTL_TRIG_LED 0x40UL
#define FMC_ADC_100MS_CSR_CTL_ACQ_LED 0x80UL
#define FMC_ADC_100MS_CSR_CTL_CLEAR_TRIG_STAT 0x100UL
#define FMC_ADC_100MS_CSR_CTL_CALIB_APPLY 0x8000UL
/* Status register */
#define FMC_ADC_100MS_CSR_STA 0x4UL
#define FMC_ADC_100MS_CSR_STA_FSM_MASK 0x7UL
#define FMC_ADC_100MS_CSR_STA_FSM_SHIFT 0
#define FMC_ADC_100MS_CSR_STA_SERDES_PLL 0x8UL
#define FMC_ADC_100MS_CSR_STA_SERDES_SYNCED 0x10UL
#define FMC_ADC_100MS_CSR_STA_ACQ_CFG 0x20UL
#define FMC_ADC_100MS_CSR_STA_FMC_NR_MASK 0xc0UL
#define FMC_ADC_100MS_CSR_STA_FMC_NR_SHIFT 6
#define FMC_ADC_100MS_CSR_STA_CALIB_BUSY 0x8000UL
/* Trigger status */
#define FMC_ADC_100MS_CSR_TRIG_STAT 0x8UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_EXT 0x1UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_SW 0x2UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_TIME 0x10UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_CH1 0x100UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_CH2 0x200UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_CH3 0x400UL
#define FMC_ADC_100MS_CSR_TRIG_STAT_CH4 0x800UL
/* Trigger enable */
#define FMC_ADC_100MS_CSR_TRIG_EN 0xcUL
#define FMC_ADC_100MS_CSR_TRIG_EN_EXT 0x1UL
#define FMC_ADC_100MS_CSR_TRIG_EN_SW 0x2UL
#define FMC_ADC_100MS_CSR_TRIG_EN_TIME 0x10UL
#define FMC_ADC_100MS_CSR_TRIG_EN_AUX_TIME 0x20UL
#define FMC_ADC_100MS_CSR_TRIG_EN_CH1 0x100UL
#define FMC_ADC_100MS_CSR_TRIG_EN_CH2 0x200UL
#define FMC_ADC_100MS_CSR_TRIG_EN_CH3 0x400UL
#define FMC_ADC_100MS_CSR_TRIG_EN_CH4 0x800UL
/* Trigger polarity */
#define FMC_ADC_100MS_CSR_TRIG_POL 0x10UL
#define FMC_ADC_100MS_CSR_TRIG_POL_EXT 0x1UL
#define FMC_ADC_100MS_CSR_TRIG_POL_CH1 0x100UL
#define FMC_ADC_100MS_CSR_TRIG_POL_CH2 0x200UL
#define FMC_ADC_100MS_CSR_TRIG_POL_CH3 0x400UL
#define FMC_ADC_100MS_CSR_TRIG_POL_CH4 0x800UL
/* External trigger delay */
#define FMC_ADC_100MS_CSR_EXT_TRIG_DLY 0x14UL
/* Software trigger */
#define FMC_ADC_100MS_CSR_SW_TRIG 0x18UL
/* Number of shots */
#define FMC_ADC_100MS_CSR_SHOTS 0x1cUL
#define FMC_ADC_100MS_CSR_SHOTS_NBR_MASK 0xffffUL
#define FMC_ADC_100MS_CSR_SHOTS_NBR_SHIFT 0
#define FMC_ADC_100MS_CSR_SHOTS_REMAIN_MASK 0xffff0000UL
#define FMC_ADC_100MS_CSR_SHOTS_REMAIN_SHIFT 16
/* Multi-shot sample depth register */
#define FMC_ADC_100MS_CSR_MULTI_DEPTH 0x20UL
/* Trigger address register */
#define FMC_ADC_100MS_CSR_TRIG_POS 0x24UL
/* Sampling clock frequency */
#define FMC_ADC_100MS_CSR_FS_FREQ 0x28UL
/* Downsampling ratio */
#define FMC_ADC_100MS_CSR_DOWNSAMPLE 0x2cUL
/* Pre-trigger samples */
#define FMC_ADC_100MS_CSR_PRE_SAMPLES 0x30UL
/* Post-trigger samples */
#define FMC_ADC_100MS_CSR_POST_SAMPLES 0x34UL
/* Samples counter */
#define FMC_ADC_100MS_CSR_SAMPLES_CNT 0x38UL
/* Channel 1 registers */
#define FMC_ADC_100MS_CSR_FMC_ADC_CH1 0x80UL
#define FMC_ADC_100MS_CSR_FMC_ADC_CH1_SIZE 32 /* 0x20 */
/* Channel 2 registers */
#define FMC_ADC_100MS_CSR_FMC_ADC_CH2 0xc0UL
#define FMC_ADC_100MS_CSR_FMC_ADC_CH2_SIZE 32 /* 0x20 */
/* Channel 3 registers */
#define FMC_ADC_100MS_CSR_FMC_ADC_CH3 0x100UL
#define FMC_ADC_100MS_CSR_FMC_ADC_CH3_SIZE 32 /* 0x20 */
/* Channel 4 registers */
#define FMC_ADC_100MS_CSR_FMC_ADC_CH4 0x140UL
#define FMC_ADC_100MS_CSR_FMC_ADC_CH4_SIZE 32 /* 0x20 */
struct fmc_adc_100ms_csr {
/* [0x0]: REG (rw) Control register */
uint32_t ctl;
/* [0x4]: REG (ro) Status register */
uint32_t sta;
/* [0x8]: REG (ro) Trigger status */
uint32_t trig_stat;
/* [0xc]: REG (rw) Trigger enable */
uint32_t trig_en;
/* [0x10]: REG (rw) Trigger polarity */
uint32_t trig_pol;
/* [0x14]: REG (rw) External trigger delay */
uint32_t ext_trig_dly;
/* [0x18]: REG (wo) Software trigger */
uint32_t sw_trig;
/* [0x1c]: REG (rw) Number of shots */
uint32_t shots;
/* [0x20]: REG (ro) Multi-shot sample depth register */
uint32_t multi_depth;
/* [0x24]: REG (ro) Trigger address register */
uint32_t trig_pos;
/* [0x28]: REG (ro) Sampling clock frequency */
uint32_t fs_freq;
/* [0x2c]: REG (rw) Downsampling ratio */
uint32_t downsample;
/* [0x30]: REG (rw) Pre-trigger samples */
uint32_t pre_samples;
/* [0x34]: REG (rw) Post-trigger samples */
uint32_t post_samples;
/* [0x38]: REG (ro) Samples counter */
uint32_t samples_cnt;
/* padding to: 32 words */
uint32_t __padding_0[17];
/* [0x80]: SUBMAP Channel 1 registers */
struct fmc_adc_100ms_channel_regs fmc_adc_ch1;
/* padding to: 48 words */
uint32_t __padding_1[10];
/* [0xc0]: SUBMAP Channel 2 registers */
struct fmc_adc_100ms_channel_regs fmc_adc_ch2;
/* padding to: 64 words */
uint32_t __padding_2[10];
/* [0x100]: SUBMAP Channel 3 registers */
struct fmc_adc_100ms_channel_regs fmc_adc_ch3;
/* padding to: 80 words */
uint32_t __padding_3[10];
/* [0x140]: SUBMAP Channel 4 registers */
struct fmc_adc_100ms_channel_regs fmc_adc_ch4;
/* padding to: 80 words */
uint32_t __padding_4[42];
};
#endif /* __CHEBY__FMC_ADC_100MS_CSR__H__ */
#ifndef __CHEBY__AUX_TRIGIN__H__
#define __CHEBY__AUX_TRIGIN__H__
#define AUX_TRIGIN_SIZE 20 /* 0x14 */
/* Core version */
#define AUX_TRIGIN_VERSION 0x0UL
#define AUX_TRIGIN_VERSION_PRESET 0xadc10001UL
/* Control register */
#define AUX_TRIGIN_CTRL 0x4UL
#define AUX_TRIGIN_CTRL_ENABLE 0x1UL
/* Time (seconds) to trigger */
#define AUX_TRIGIN_SECONDS 0x8UL
/* Time (cycles) to trigger */
#define AUX_TRIGIN_CYCLES 0x10UL
struct aux_trigin {
/* [0x0]: REG (ro) Core version */
uint32_t version;
/* [0x4]: REG (rw) Control register */
uint32_t ctrl;
/* [0x8]: REG (rw) Time (seconds) to trigger */
uint64_t seconds;
/* [0x10]: REG (rw) Time (cycles) to trigger */
uint32_t cycles;
};
#endif /* __CHEBY__AUX_TRIGIN__H__ */
#ifndef __CHEBY__AUX_TRIGOUT__H__
#define __CHEBY__AUX_TRIGOUT__H__
#define AUX_TRIGOUT_SIZE 20 /* 0x14 */
/* Status register */
#define AUX_TRIGOUT_STATUS 0x0UL
#define AUX_TRIGOUT_WR_ENABLE 0x1UL
#define AUX_TRIGOUT_WR_LINK 0x2UL
#define AUX_TRIGOUT_WR_VALID 0x4UL
#define AUX_TRIGOUT_TS_PRESENT 0x100UL
/* Time (seconds) of the last event */
#define AUX_TRIGOUT_TS_MASK_SEC 0x8UL
#define AUX_TRIGOUT_TS_SEC_MASK 0xffffffffffULL
#define AUX_TRIGOUT_TS_SEC_SHIFT 0
#define AUX_TRIGOUT_CH1_MASK 0x1000000000000ULL
#define AUX_TRIGOUT_CH2_MASK 0x2000000000000ULL
#define AUX_TRIGOUT_CH3_MASK 0x4000000000000ULL
#define AUX_TRIGOUT_CH4_MASK 0x8000000000000ULL
#define AUX_TRIGOUT_EXT_MASK 0x100000000000000ULL
/* Cycles part of timestamp fifo. */
#define AUX_TRIGOUT_TS_CYCLES 0x10UL
#define AUX_TRIGOUT_CYCLES_MASK 0xfffffffUL
#define AUX_TRIGOUT_CYCLES_SHIFT 0
struct aux_trigout {
/* [0x0]: REG (ro) Status register */
uint32_t status;
/* padding to: 2 words */
uint32_t __padding_0[1];
/* [0x8]: REG (ro) Time (seconds) of the last event */
uint64_t ts_mask_sec;
/* [0x10]: REG (ro) Cycles part of timestamp fifo. */
uint32_t ts_cycles;
};
#endif /* __CHEBY__AUX_TRIGOUT__H__ */
#ifndef __CHEBY__FMC_ADC_EIC_REGS__H__
#define __CHEBY__FMC_ADC_EIC_REGS__H__
#define FMC_ADC_EIC_REGS_SIZE 16 /* 0x10 */
/* Interrupt Disable Register */
#define FMC_ADC_EIC_REGS_IDR 0x0UL
/* Interrupt Enable Register */
#define FMC_ADC_EIC_REGS_IER 0x4UL
/* Interrupt Mask Register */
#define FMC_ADC_EIC_REGS_IMR 0x8UL
/* Interrupt Status Register */
#define FMC_ADC_EIC_REGS_ISR 0xcUL
struct fmc_adc_eic_regs {
/* [0x0]: REG (wo) Interrupt Disable Register */
uint32_t idr;
/* [0x4]: REG (wo) Interrupt Enable Register */
uint32_t ier;
/* [0x8]: REG (ro) Interrupt Mask Register */
uint32_t imr;
/* [0xc]: REG (rw) Interrupt Status Register */
uint32_t isr;
};
#endif /* __CHEBY__FMC_ADC_EIC_REGS__H__ */
#ifndef __CHEBY__FMC_ADC_MEZZANINE_MMAP__H__
#define __CHEBY__FMC_ADC_MEZZANINE_MMAP__H__
#include "fmc_adc_eic_regs.h"
#include "fmc_adc_100ms_csr.h"
#include "timetag_core_regs.h"
#include "wb_ds182x_regs.h"
#define FMC_ADC_MEZZANINE_MMAP_SIZE 8192 /* 0x2000 = 8KB */
/* FMC ADC 100M CSR */
#define FMC_ADC_MEZZANINE_MMAP_FMC_ADC_100M_CSR 0x1000UL
#define FMC_ADC_MEZZANINE_MMAP_FMC_ADC_100M_CSR_SIZE 512 /* 0x200 */
/* FMC ADC Embedded Interrupt Controller */
#define FMC_ADC_MEZZANINE_MMAP_FMC_ADC_EIC 0x1500UL
#define FMC_ADC_MEZZANINE_MMAP_FMC_ADC_EIC_SIZE 16 /* 0x10 */
/* Si570 control I2C master */
#define FMC_ADC_MEZZANINE_MMAP_SI570_I2C_MASTER 0x1600UL
#define FMC_ADC_MEZZANINE_MMAP_SI570_I2C_MASTER_SIZE 256 /* 0x100 */
/* DS18B20 OneWire master */
#define FMC_ADC_MEZZANINE_MMAP_DS18B20_ONEWIRE_MASTER 0x1700UL
#define FMC_ADC_MEZZANINE_MMAP_DS18B20_ONEWIRE_MASTER_SIZE 16 /* 0x10 */
/* Mezzanine SPI master (ADC control + DAC offsets) */
#define FMC_ADC_MEZZANINE_MMAP_FMC_SPI_MASTER 0x1800UL
#define FMC_ADC_MEZZANINE_MMAP_FMC_SPI_MASTER_SIZE 32 /* 0x20 */
/* Timetag Core */
#define FMC_ADC_MEZZANINE_MMAP_TIMETAG_CORE 0x1900UL
#define FMC_ADC_MEZZANINE_MMAP_TIMETAG_CORE_SIZE 128 /* 0x80 */
struct fmc_adc_mezzanine_mmap {
/* padding to: 1024 words */
uint32_t __padding_0[1024];
/* [0x1000]: SUBMAP FMC ADC 100M CSR */
struct fmc_adc_100ms_csr fmc_adc_100m_csr;
/* padding to: 1344 words */
uint32_t __padding_1[192];
/* [0x1500]: SUBMAP FMC ADC Embedded Interrupt Controller */
struct fmc_adc_eic_regs fmc_adc_eic;
/* padding to: 1408 words */
uint32_t __padding_2[60];
/* [0x1600]: SUBMAP Si570 control I2C master */
uint32_t si570_i2c_master[64];
/* [0x1700]: SUBMAP DS18B20 OneWire master */
struct wb_ds182x_regs ds18b20_onewire_master;
/* padding to: 1536 words */
uint32_t __padding_3[60];
/* [0x1800]: SUBMAP Mezzanine SPI master (ADC control + DAC offsets) */
uint32_t fmc_spi_master[8];
/* padding to: 1600 words */
uint32_t __padding_4[56];
/* [0x1900]: SUBMAP Timetag Core */
struct timetag_core_regs timetag_core;
/* padding to: 1600 words */
uint32_t __padding_5[416];
};
#endif /* __CHEBY__FMC_ADC_MEZZANINE_MMAP__H__ */
#ifndef __CHEBY__SPEC_REF_FMC_ADC_100M_MMAP__H__
#define __CHEBY__SPEC_REF_FMC_ADC_100M_MMAP__H__
#include "fmc_adc_mezzanine_mmap.h"
#define SPEC_REF_FMC_ADC_100M_MMAP_SIZE 24576 /* 0x6000 = 24KB */
/* a ROM containing the application metadata */
#define SPEC_REF_FMC_ADC_100M_MMAP_METADATA 0x2000UL
#define SPEC_REF_FMC_ADC_100M_MMAP_METADATA_SIZE 64 /* 0x40 */
/* FMC ADC Mezzanine */
#define SPEC_REF_FMC_ADC_100M_MMAP_FMC_ADC_MEZZANINE 0x4000UL
#define SPEC_REF_FMC_ADC_100M_MMAP_FMC_ADC_MEZZANINE_SIZE 8192 /* 0x2000 = 8KB */
struct spec_ref_fmc_adc_100m_mmap {
/* padding to: 2048 words */
uint32_t __padding_0[2048];
/* [0x2000]: SUBMAP a ROM containing the application metadata */
uint32_t metadata[16];
/* padding to: 4096 words */
uint32_t __padding_1[2032];
/* [0x4000]: SUBMAP FMC ADC Mezzanine */
struct fmc_adc_mezzanine_mmap fmc_adc_mezzanine;
};
#endif /* __CHEBY__SPEC_REF_FMC_ADC_100M_MMAP__H__ */
#ifndef __CHEBY__SVEC_REF_FMC_ADC_100M_MMAP__H__
#define __CHEBY__SVEC_REF_FMC_ADC_100M_MMAP__H__
#include "fmc_adc_mezzanine_mmap.h"
#define SVEC_REF_FMC_ADC_100M_MMAP_SIZE 65536 /* 0x10000 = 64KB */
/* a ROM containing the application metadata */
#define SVEC_REF_FMC_ADC_100M_MMAP_METADATA 0x4000UL
#define SVEC_REF_FMC_ADC_100M_MMAP_METADATA_SIZE 64 /* 0x40 */
/* FMC ADC Mezzanine slot 1 */
#define SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE 0x6000UL
#define SVEC_REF_FMC_ADC_100M_MMAP_FMC1_ADC_MEZZANINE_SIZE 8192 /* 0x2000 = 8KB */
/* FMC ADC Mezzanine slot 2 */
#define SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE 0x8000UL
#define SVEC_REF_FMC_ADC_100M_MMAP_FMC2_ADC_MEZZANINE_SIZE 8192 /* 0x2000 = 8KB */
struct svec_ref_fmc_adc_100m_mmap {
/* padding to: 4096 words */
uint32_t __padding_0[4096];
/* [0x4000]: SUBMAP a ROM containing the application metadata */
uint32_t metadata[16];
/* padding to: 6144 words */
uint32_t __padding_1[2032];
/* [0x6000]: SUBMAP FMC ADC Mezzanine slot 1 */
struct fmc_adc_mezzanine_mmap fmc1_adc_mezzanine;
/* [0x8000]: SUBMAP FMC ADC Mezzanine slot 2 */
struct fmc_adc_mezzanine_mmap fmc2_adc_mezzanine;
/* padding to: 8192 words */
uint32_t __padding_2[6144];
};
#endif /* __CHEBY__SVEC_REF_FMC_ADC_100M_MMAP__H__ */
#ifndef __CHEBY__TIMETAG_CORE_REGS__H__
#define __CHEBY__TIMETAG_CORE_REGS__H__
#define TIMETAG_CORE_REGS_SIZE 128 /* 0x80 */
/* Timetag seconds register (upper) */
#define TIMETAG_CORE_REGS_SECONDS_UPPER 0x0UL
#define TIMETAG_CORE_REGS_SECONDS_UPPER_MASK 0xffUL
#define TIMETAG_CORE_REGS_SECONDS_UPPER_SHIFT 0
/* Timetag seconds register (lower) */
#define TIMETAG_CORE_REGS_SECONDS_LOWER 0x4UL
/* Timetag coarse time register, system clock ticks (125MHz) */
#define TIMETAG_CORE_REGS_COARSE 0x8UL
#define TIMETAG_CORE_REGS_COARSE_MASK 0xfffffffUL
#define TIMETAG_CORE_REGS_COARSE_SHIFT 0
/* Time trigger seconds register (upper) */
#define TIMETAG_CORE_REGS_TIME_TRIG_SECONDS_UPPER 0xcUL
#define TIMETAG_CORE_REGS_TIME_TRIG_SECONDS_UPPER_MASK 0xffUL
#define TIMETAG_CORE_REGS_TIME_TRIG_SECONDS_UPPER_SHIFT 0
/* Time trigger seconds register (lower) */
#define TIMETAG_CORE_REGS_TIME_TRIG_SECONDS_LOWER 0x10UL
/* Time trigger coarse time register, system clock ticks (125MHz) */
#define TIMETAG_CORE_REGS_TIME_TRIG_COARSE 0x14UL
#define TIMETAG_CORE_REGS_TIME_TRIG_COARSE_MASK 0xfffffffUL
#define TIMETAG_CORE_REGS_TIME_TRIG_COARSE_SHIFT 0
/* Trigger time-tag seconds register (upper) */
#define TIMETAG_CORE_REGS_TRIG_TAG_SECONDS_UPPER 0x18UL
#define TIMETAG_CORE_REGS_TRIG_TAG_SECONDS_UPPER_MASK 0xffUL
#define TIMETAG_CORE_REGS_TRIG_TAG_SECONDS_UPPER_SHIFT 0
/* Trigger time-tag seconds register (lower) */
#define TIMETAG_CORE_REGS_TRIG_TAG_SECONDS_LOWER 0x1cUL
/* Trigger time-tag coarse time (system clock ticks 125MHz) register */
#define TIMETAG_CORE_REGS_TRIG_TAG_COARSE 0x20UL
#define TIMETAG_CORE_REGS_TRIG_TAG_COARSE_MASK 0xfffffffUL
#define TIMETAG_CORE_REGS_TRIG_TAG_COARSE_SHIFT 0
/* Acquisition start time-tag seconds register (upper) */
#define TIMETAG_CORE_REGS_ACQ_START_TAG_SECONDS_UPPER 0x24UL
#define TIMETAG_CORE_REGS_ACQ_START_TAG_SECONDS_UPPER_MASK 0xffUL
#define TIMETAG_CORE_REGS_ACQ_START_TAG_SECONDS_UPPER_SHIFT 0
/* Acquisition start time-tag seconds register (lower) */
#define TIMETAG_CORE_REGS_ACQ_START_TAG_SECONDS_LOWER 0x28UL
/* Acquisition start time-tag coarse time (system clock ticks 125MHz) register */
#define TIMETAG_CORE_REGS_ACQ_START_TAG_COARSE 0x2cUL
#define TIMETAG_CORE_REGS_ACQ_START_TAG_COARSE_MASK 0xfffffffUL
#define TIMETAG_CORE_REGS_ACQ_START_TAG_COARSE_SHIFT 0
/* Acquisition stop time-tag seconds register (upper) */
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_SECONDS_UPPER 0x30UL
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_SECONDS_UPPER_MASK 0xffUL
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_SECONDS_UPPER_SHIFT 0
/* Acquisition stop time-tag seconds register (lower) */
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_SECONDS_LOWER 0x34UL
/* Acquisition stop time-tag coarse time (system clock ticks 125MHz) register */
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_COARSE 0x38UL
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_COARSE_MASK 0xfffffffUL
#define TIMETAG_CORE_REGS_ACQ_STOP_TAG_COARSE_SHIFT 0
/* Acquisition end time-tag seconds register (upper) */
#define TIMETAG_CORE_REGS_ACQ_END_TAG_SECONDS_UPPER 0x3cUL
#define TIMETAG_CORE_REGS_ACQ_END_TAG_SECONDS_UPPER_MASK 0xffUL
#define TIMETAG_CORE_REGS_ACQ_END_TAG_SECONDS_UPPER_SHIFT 0
/* Acquisition end time-tag seconds register (lower) */
#define TIMETAG_CORE_REGS_ACQ_END_TAG_SECONDS_LOWER 0x40UL
/* Acquisition end time-tag coarse time (system clock ticks 125MHz) register */
#define TIMETAG_CORE_REGS_ACQ_END_TAG_COARSE 0x44UL
#define TIMETAG_CORE_REGS_ACQ_END_TAG_COARSE_MASK 0xfffffffUL
#define TIMETAG_CORE_REGS_ACQ_END_TAG_COARSE_SHIFT 0
struct timetag_core_regs {
/* [0x0]: REG (rw) Timetag seconds register (upper) */
uint32_t seconds_upper;
/* [0x4]: REG (rw) Timetag seconds register (lower) */
uint32_t seconds_lower;
/* [0x8]: REG (rw) Timetag coarse time register, system clock ticks (125MHz) */
uint32_t coarse;
/* [0xc]: REG (rw) Time trigger seconds register (upper) */
uint32_t time_trig_seconds_upper;
/* [0x10]: REG (rw) Time trigger seconds register (lower) */
uint32_t time_trig_seconds_lower;
/* [0x14]: REG (rw) Time trigger coarse time register, system clock ticks (125MHz) */
uint32_t time_trig_coarse;
/* [0x18]: REG (ro) Trigger time-tag seconds register (upper) */
uint32_t trig_tag_seconds_upper;
/* [0x1c]: REG (ro) Trigger time-tag seconds register (lower) */
uint32_t trig_tag_seconds_lower;
/* [0x20]: REG (ro) Trigger time-tag coarse time (system clock ticks 125MHz) register */
uint32_t trig_tag_coarse;
/* [0x24]: REG (ro) Acquisition start time-tag seconds register (upper) */
uint32_t acq_start_tag_seconds_upper;
/* [0x28]: REG (ro) Acquisition start time-tag seconds register (lower) */
uint32_t acq_start_tag_seconds_lower;
/* [0x2c]: REG (ro) Acquisition start time-tag coarse time (system clock ticks 125MHz) register */
uint32_t acq_start_tag_coarse;
/* [0x30]: REG (ro) Acquisition stop time-tag seconds register (upper) */
uint32_t acq_stop_tag_seconds_upper;
/* [0x34]: REG (ro) Acquisition stop time-tag seconds register (lower) */
uint32_t acq_stop_tag_seconds_lower;
/* [0x38]: REG (ro) Acquisition stop time-tag coarse time (system clock ticks 125MHz) register */
uint32_t acq_stop_tag_coarse;
/* [0x3c]: REG (ro) Acquisition end time-tag seconds register (upper) */
uint32_t acq_end_tag_seconds_upper;
/* [0x40]: REG (ro) Acquisition end time-tag seconds register (lower) */
uint32_t acq_end_tag_seconds_lower;
/* [0x44]: REG (ro) Acquisition end time-tag coarse time (system clock ticks 125MHz) register */
uint32_t acq_end_tag_coarse;
/* padding to: 17 words */
uint32_t __padding_0[14];
};
#endif /* __CHEBY__TIMETAG_CORE_REGS__H__ */
......@@ -171,7 +171,7 @@ static int sg_alloc_table_from_pages_no_squash(struct sg_table *sgt,
unsigned long chunk_size;
chunk_size = PAGE_SIZE - offset;
sg_set_page(sg, pages[i], min(size, chunk_size), offset);
sg_set_page(sg, pages[i], min_t(unsigned long, size, chunk_size), offset);
offset = 0;
size -= chunk_size;
}
......@@ -656,7 +656,8 @@ static void fa_sg_alloc_table_init(struct fa_dev *fa)
static struct fmc_adc_platform_data fmc_adc_pdata_default = {
.flags = 0,
.vme_ddr_offset = 0,
.vme_reg_offset = 0,
.vme_dma_offset = 0,
.calib_trig_time = 0,
.calib_trig_threshold = 0,
.calib_trig_internal = 0,
......
......@@ -233,10 +233,10 @@ static ssize_t fa_data_pattern_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct fa_dev *fa = file->private_data;
char buf_l[CMD_SIZE];
char buf_l[CMD_SIZE + 1];
int err;
memset(buf_l, 0, CMD_SIZE);
memset(buf_l, 0, sizeof(buf_l));
err = copy_from_user(buf_l, buf, min(count, CMD_SIZE));
if (err)
return err;
......@@ -248,7 +248,7 @@ static ssize_t fa_data_pattern_write(struct file *file, const char __user *buf,
return err ? err : count;
} else {
dev_err(&fa->pdev->dev, "Unknown command \"%s\"\n", buf);
dev_err(&fa->pdev->dev, "Unknown command \"%s\"\n", buf_l);
return -EINVAL;
}
}
......
......@@ -214,8 +214,6 @@ static unsigned int zfad_block_n_pages(struct zio_block *block)
#ifdef CONFIG_FMC_ADC_SVEC
#define ADC_VME_DDR_ADDR 0x00
#define ADC_VME_DDR_DATA 0x04
#define SVEC_FUNC_NR 1 /* HARD coded in SVEC */
static inline struct vme_dev *fa_to_vme_dev(struct fa_dev *fa)
......@@ -233,9 +231,9 @@ static unsigned long fa_ddr_data_vme_addr(struct fa_dev *fa)
"Invalid VME function\n"))
return ~0; /* invalid address, we will see VME errors */
WARN(data->vme_ddr_offset == 0, "Invalid DDR DATA offset");
WARN(data->vme_dma_offset == 0, "Invalid DDR DMA offset");
addr = vdev->map[SVEC_FUNC_NR].vme_addrl;
addr += data->vme_ddr_offset + ADC_VME_DDR_DATA;
addr += data->vme_dma_offset;
return addr;
}
......@@ -251,7 +249,7 @@ static void *fa_ddr_addr_reg_off(struct fa_dev *fa)
return NULL; /* invalid address, we will see VME errors */
addr = vdev->map[SVEC_FUNC_NR].kernel_va;
addr += data->vme_ddr_offset + ADC_VME_DDR_ADDR;
addr += data->vme_reg_offset;
return addr;
}
......@@ -284,8 +282,7 @@ static void build_dma_desc(struct vme_dma *desc, unsigned long vme_addr,
desc->ctrl.vme_backoff_time = VME_DMA_BACKOFF_0;
vme->data_width = VME_D32;
vme->am = VME_A24_USER_DATA_SCT;
/*vme->am = VME_A24_USER_MBLT;*/
vme->am = VME_A24_USER_MBLT;
vme->addru = upper_32_bits(vme_addr);
vme->addrl = lower_32_bits(vme_addr);
......@@ -338,42 +335,19 @@ static int zfad_dma_context_init_svec(struct zio_cset *cset,
#ifdef CONFIG_FMC_ADC_SVEC
struct fa_dev *fa = cset->zdev->priv_d;
struct vme_dma *desc;
int err;
dev_dbg(&fa->pdev->dev, "SVEC build DMA context\n");
zfad_block->dma_ctx = NULL;
desc = kmalloc(sizeof(struct vme_dma), GFP_ATOMIC);
if (!desc)
return -ENOMEM;
if (zfad_block == cset->interleave->priv_d) {
void *addr = fa_ddr_addr_reg_off(fa);
if (!addr) {
err = -ENODEV;
goto err_reg_addr;
}
/*
* Only for the first block:
* write the data address in the ddr_addr register: this
* address has been computed after ACQ_END by looking to the
* trigger position see fa-irq.c::irq_acq_end.
* Be careful: the SVEC HW version expects an address of 32bits word
* therefore mem-offset in byte is translated into 32bit word
*/
fa_iowrite(fa, zfad_block->sconfig.src_addr / 4, addr);
}
zfad_block->dma_ctx = desc;
build_dma_desc(desc, fa_ddr_data_vme_addr(fa),
zfad_block->block->data,
zfad_block->block->datalen);
return 0;
err_reg_addr:
kfree(desc);
zfad_block->dma_ctx = NULL;
return err;
#else
return 0;
#endif
......@@ -443,6 +417,8 @@ static void fa_dma_complete(void *arg,
fa_dma_release_channel_svec(fa);
zfad_dma_done(cset);
}
complete(&zfad_block->shot_done);
}
......@@ -551,60 +527,82 @@ err_alloc_pages:
return err;
}
/**
* Configure the DDR window offset
*/
static int fa_svec_ddr_window_set(struct fa_dev *fa, unsigned int offset)
{
void *addr = fa_ddr_addr_reg_off(fa);
if (!addr)
return -ENODEV;
fa_iowrite(fa, offset, addr);
return 0;
}
static int fa_dmaengine_slave_config(struct fa_dev *fa,
struct dma_slave_config *sconfig)
{
/*
* For SVEC we must set the DMA context, there is not slave config
*/
if (fa_is_flag_set(fa, FMC_ADC_SVEC))
return 0;
if (fa_is_flag_set(fa, FMC_ADC_SVEC)) {
/*
* For SVEC we must set the DMA context, there is not a real
* slave config. The SVEC HDL implementation requires some
* cooridination between the DMA engine (the VME bridge),
* and the SVEC card. This coordination happens here by
* setting the DDR window for the next acquisition.
*
* This is necessary becasue the SVEC can't map the entire DDR.
*/
return fa_svec_ddr_window_set(fa, sconfig->src_addr);
}
return dmaengine_slave_config(fa->dchan, sconfig);
}
/**
* It maps the ZIO blocks with an sg table, then it starts the DMA transfer
* from the ADC to the host memory.
*
* @param cset
/*
* In multishot mode we must wait for the previous
* transfer to complete because:
* - of the MBLT prefetch, so we need to do separate DMA
* transfers;
* - of the SVEC DMA DDR offset register that can't be
* overwritten while running a DMA transfer
*/
static int zfad_dma_start(struct zio_cset *cset)
static int fa_dma_shot_wait_svec(struct fa_dev *fa,
struct zfad_block *zfad_block,
unsigned int timeout_ms)
{
int err;
if (fa->n_shots == 1)
return 0;
err = wait_for_completion_interruptible_timeout(&zfad_block->shot_done,
msecs_to_jiffies(timeout_ms));
/* Check the status of our transfer */
if (err <= 0) {
/* timeout elapsed or signal interruption */
dev_err(&fa->pdev->dev, "%s\n", (err == 0) ? "DMA timeout elapsed" :
"DMA interrupted by a signal");
return -EINVAL;
}
return 0;
}
static int fa_dma_start_svec(struct zio_cset *cset)
{
struct fa_dev *fa = cset->zdev->priv_d;
struct zfad_block *zfad_block = cset->interleave->priv_d;
int err, i;
err = fa_fsm_wait_state(fa, FA100M14B4C_STATE_IDLE, 10);
if (err) {
dev_warn(fa->msgdev,
"Can't start DMA on the last acquisition, "
"State Machine is not IDLE\n");
return err;
}
dev_dbg(fa->msgdev, "Start DMA transfer for %i shots of %i samples\n",
fa->n_shots, cset->ti->nsamples);
err = fa_dma_request_channel_svec(fa);
if (err)
return err;
/*
* Disable all triggers to prevent fires between
* different DMA transfers required for multi-shots
*/
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_CFG_SRC], 0);
fa->transfers_left = fa->n_shots;
for (i = 0; i < fa->n_shots; ++i) {
/*
* TODO
* Let's see what to do with SVEC. SVEC need to set
* the DMA_DDR_ADDR in hardware before starting the DMA
* (it configures the DMA window).
* In single shot is not a big deal, in multishot we may have
* to issue_pending many time since we can't update the
* DMA_DDR_ADDR for each block submitted to the dma engine.
* But sice the blocks are contigous, perhaps there is no need
* because the address of shot 2 is exactly after shot 1
*/
zfad_block[i].sconfig.direction = DMA_DEV_TO_MEM;
zfad_block[i].sconfig.src_addr_width = 8; /* 2 bytes for each channel (4) */
zfad_block[i].sconfig.src_addr = fa_ddr_offset(fa, i);
......@@ -614,8 +612,51 @@ static int zfad_dma_start(struct zio_cset *cset)
err = zfad_dma_prep_slave_sg(fa->dchan, cset, &zfad_block[i]);
if (err)
goto err_prep;
init_completion(&zfad_block[i].shot_done);
dma_async_issue_pending(fa->dchan);
err = fa_dma_shot_wait_svec(fa, &zfad_block[i], 60000);
if (err)
goto err_wait;
}
return 0;
err_wait:
dmaengine_terminate_all(fa->dchan);
dma_unmap_sg(&fa->pdev->dev,
zfad_block[i].sgt.sgl,
zfad_block[i].sgt.nents,
DMA_DEV_TO_MEM);
sg_free_table(&zfad_block[i].sgt);
/* Clean/fix the context */
zfad_dma_context_exit(cset, &zfad_block[i]);
err_prep:
err_config:
fa_dma_release_channel_svec(fa);
return err;
}
static int fa_dma_start_spec(struct zio_cset *cset)
{
struct fa_dev *fa = cset->zdev->priv_d;
struct zfad_block *zfad_block = cset->interleave->priv_d;
int err, i;
for (i = 0; i < fa->n_shots; ++i) {
zfad_block[i].sconfig.direction = DMA_DEV_TO_MEM;
zfad_block[i].sconfig.src_addr_width = 8; /* 2 bytes for each channel (4) */
zfad_block[i].sconfig.src_addr = fa_ddr_offset(fa, i);
err = fa_dmaengine_slave_config(fa, &zfad_block[i].sconfig);
if (err)
goto err_config;
err = zfad_dma_prep_slave_sg(fa->dchan, cset, &zfad_block[i]);
if (err)
goto err_prep;
init_completion(&zfad_block[i].shot_done);
}
fa->transfers_left = fa->n_shots;
dma_async_issue_pending(fa->dchan);
......@@ -624,7 +665,6 @@ static int zfad_dma_start(struct zio_cset *cset)
err_prep:
err_config:
dmaengine_terminate_all(fa->dchan);
fa_dma_release_channel_svec(fa);
while (--i >= 0) {
dma_unmap_sg(&fa->pdev->dev,
zfad_block[i].sgt.sgl,
......@@ -632,9 +672,51 @@ err_config:
DMA_DEV_TO_MEM);
sg_free_table(&zfad_block[i].sgt);
}
return err;
}
/**
* It maps the ZIO blocks with an sg table, then it starts the DMA transfer
* from the ADC to the host memory.
*
* @param cset
*/
static int zfad_dma_start(struct zio_cset *cset)
{
struct fa_dev *fa = cset->zdev->priv_d;
int err;
err = fa_fsm_wait_state(fa, FA100M14B4C_STATE_IDLE, 10);
if (err) {
dev_warn(&fa->pdev->dev,
"Can't start DMA on the last acquisition, "
"State Machine is not IDLE\n");
return err;
}
dev_dbg(&fa->pdev->dev,
"Start DMA transfer for %i shots of %i samples\n",
fa->n_shots, cset->ti->nsamples);
/*
* Disable all triggers to prevent fires between
* different DMA transfers required for multi-shots
*/
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_CFG_SRC], 0);
if (fa_is_flag_set(fa, FMC_ADC_SVEC))
err = fa_dma_start_svec(cset);
else
err = fa_dma_start_spec(cset);
if (err)
goto err_start;
return 0;
err_start:
fa_writel(fa, fa->fa_adc_csr_base, &zfad_regs[ZFAT_CFG_SRC],
cset->ti->zattr_set.ext_zattr[FA100M14B4C_TATTR_SRC].value);
dev_err(fa->msgdev, "Failed to run a DMA transfer (%d)\n", err);
dev_err(&fa->pdev->dev, "Failed to run a DMA transfer (%d)\n", err);
return err;
}
......@@ -659,10 +741,9 @@ static int zfad_block_timetag_extract(struct zio_block *block,
tg = block->data + block->datalen - FA_TRIG_TIMETAG_BYTES;
/* resize the datalen, by removing the trigger tstamp */
block->datalen = block->datalen - FA_TRIG_TIMETAG_BYTES;
memcpy(timetag, tg, sizeof(*timetag));
if (unlikely((tg->sec_high >> 8) != 0xACCE55))
return -EINVAL;
memcpy(timetag, tg, sizeof(*timetag));
return 0;
}
......@@ -756,7 +837,8 @@ static void zfad_dma_done(struct zio_cset *cset)
err = zfad_block_timetag_extract(block, &timetag);
if (err) {
dev_err(&fa->pdev->dev,
"Failed to extract Timetag from acquisition :0x%x 0x%x 0x%x 0x%x\n",
"Failed to extract Timetag from acquisition from shot %i :0x%x 0x%x 0x%x 0x%x\n",
i + 1,
timetag.sec_high, timetag.sec_low,
timetag.ticks, timetag.status);
......
......@@ -4,6 +4,8 @@
* Author: Federico Vaga <federico.vaga@cern.ch>
*/
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
......@@ -12,6 +14,8 @@
#include "platform_data/fmc-adc-100m14b4cha.h"
#define SVEC_FMC_SLOTS 2
/*
* From SVEC but we do not want to add a dependency for these 4 registers
* which should never change by design. If they do, and you end up here:
......@@ -19,39 +23,57 @@
*/
#define SVEC_BASE_REGS_CSR 0x40UL
#define SVEC_FPGA_CSR_DDR4_ADDR (SVEC_BASE_REGS_CSR + 0x18)
#define SVEC_FPGA_CSR_DDR4_DATA (SVEC_BASE_REGS_CSR + 0x1C)
#define SVEC_FPGA_CSR_DDR5_ADDR (SVEC_BASE_REGS_CSR + 0x20)
#define SVEC_FPGA_CSR_DDR5_DATA (SVEC_BASE_REGS_CSR + 0x24)
#define SVEC_FPGA_DDR4_DMA (0x2000)
#define SVEC_FPGA_CSR_DDR5_ADDR (SVEC_BASE_REGS_CSR + 0x1C)
#define SVEC_FPGA_DDR5_DMA (0x3000)
enum fa_svec_dev_offsets {
FA_SVEC_ADC1_MEM_START = 0x000002000,
FA_SVEC_ADC1_MEM_END = 0x00003FFF,
FA_SVEC_ADC2_MEM_START = 0x00004000,
FA_SVEC_ADC2_MEM_END = 0x000005FFF,
};
static struct fmc_adc_platform_data fmc_adc_pdata1 = {
.flags = FMC_ADC_BIG_ENDIAN | FMC_ADC_SVEC,
.vme_ddr_offset = SVEC_FPGA_CSR_DDR4_ADDR,
.calib_trig_time = 0,
.calib_trig_threshold = 0,
.calib_trig_internal = 0,
FA_SVEC_ADC1_MEM_START = 0x00002000,
FA_SVEC_ADC1_MEM_END = 0x00003FFF,
FA_SVEC_ADC2_MEM_START = 0x00004000,
FA_SVEC_ADC2_MEM_END = 0x00005FFF,
};
static struct fmc_adc_platform_data fmc_adc_pdata2 = {
.flags = FMC_ADC_BIG_ENDIAN | FMC_ADC_SVEC,
.vme_ddr_offset = SVEC_FPGA_CSR_DDR5_ADDR,
.calib_trig_time = 0,
.calib_trig_threshold = 0,
.calib_trig_internal = 0,
static inline struct platform_device *platform_device_register_resndata_mask(
struct device *parent, const char *name, int id,
const struct resource *res, unsigned int num,
const void *data, size_t size, u64 dma_mask) {
struct platform_device_info pdevinfo = {
.parent = parent,
.name = name,
.id = id,
.res = res,
.num_res = num,
.data = data,
.size_data = size,
.dma_mask = dma_mask,
};
return platform_device_register_full(&pdevinfo);
}
};
/* MFD devices */
enum svec_fpga_mfd_devs_enum {
FA_SVEC_MFD_FA1 = 0,
FA_SVEC_MFD_FA2,
static struct fmc_adc_platform_data fa_svec_adc_pdata[] = {
{
.flags = FMC_ADC_BIG_ENDIAN |
FMC_ADC_SVEC |
FMC_ADC_NOSQUASH_SCATTERLIST,
.vme_reg_offset = SVEC_FPGA_CSR_DDR4_ADDR,
.vme_dma_offset = SVEC_FPGA_DDR4_DMA,
.calib_trig_time = 0,
.calib_trig_threshold = 0,
.calib_trig_internal = 0,
}, {
.flags = FMC_ADC_BIG_ENDIAN |
FMC_ADC_SVEC |
FMC_ADC_NOSQUASH_SCATTERLIST,
.vme_reg_offset = SVEC_FPGA_CSR_DDR5_ADDR,
.vme_dma_offset = SVEC_FPGA_DDR5_DMA,
.calib_trig_time = 0,
.calib_trig_threshold = 0,
.calib_trig_internal = 0,
}
};
static struct resource fa_svec_res1[] = {
......@@ -72,6 +94,7 @@ static struct resource fa_svec_res1[] = {
.end = 0,
},
};
static struct resource fa_svec_res2[] = {
{
.name = "fmc-adc-100m-mem.2",
......@@ -91,42 +114,24 @@ static struct resource fa_svec_res2[] = {
},
};
#define MFD_ADC(_n) \
{ \
.name = "fmc-adc-100m", \
.platform_data = &fmc_adc_pdata##_n, \
.pdata_size = sizeof(fmc_adc_pdata##_n), \
.num_resources = ARRAY_SIZE(fa_svec_res##_n), \
.resources = fa_svec_res##_n, \
}
static const struct mfd_cell fa_svec_mfd_devs1[] = {
MFD_ADC(1),
};
static const struct mfd_cell fa_svec_mfd_devs2[] = {
MFD_ADC(2),
};
static const struct mfd_cell fa_svec_mfd_devs3[] = {
MFD_ADC(1),
MFD_ADC(2),
static struct resource *fa_svec_res[] = {
fa_svec_res1,
fa_svec_res2,
};
static const struct mfd_cell *fa_svec_mfd_devs[] = {
fa_svec_mfd_devs1,
fa_svec_mfd_devs2,
fa_svec_mfd_devs3,
struct fa_svec_data {
struct platform_device *adc[2];
};
static int fa_svec_probe(struct platform_device *pdev)
{
struct fa_svec_data *pdev_data;
struct resource *rmem;
int idev = 0;
int ndev;
int irq;
int i;
rmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!rmem) {
dev_err(&pdev->dev, "Missing memory resource\n");
return -EINVAL;
......@@ -138,46 +143,70 @@ static int fa_svec_probe(struct platform_device *pdev)
return -EINVAL;
}
for (i = 1; i <= 2; ++i) {
struct fmc_slot *slot = fmc_slot_get(pdev->dev.parent, i);
pdev_data = kmalloc(sizeof(*pdev_data), GFP_KERNEL);
if (!pdev_data)
return -ENOMEM;
for (i = 0; i < SVEC_FMC_SLOTS; ++i) {
unsigned int res_n = ARRAY_SIZE(fa_svec_res1);
struct resource res[res_n];
struct fmc_slot *slot = fmc_slot_get(pdev->dev.parent, i + 1);
int present;
if (IS_ERR(slot)) {
dev_err(&pdev->dev,
"Can't find FMC slot %d err: %ld\n",
i, PTR_ERR(slot));
return PTR_ERR(slot);
i + 1, PTR_ERR(slot));
continue;
}
present = fmc_slot_present(slot);
fmc_slot_put(slot);
dev_dbg(&pdev->dev, "FMC slot: %d, present: %d\n",
i, present);
if (present)
idev |= BIT(i - 1);
i + 1, present);
if (!present)
continue;
memcpy(res, fa_svec_res[i], sizeof(res));
res[0].parent = rmem;
res[0].start += rmem->start;
res[0].end += rmem->start;
res[2].start += irq;
pdev_data->adc[i] = platform_device_register_resndata_mask(&pdev->dev,
"fmc-adc-100m",
PLATFORM_DEVID_AUTO,
res,
res_n,
&fa_svec_adc_pdata[i],
sizeof(fa_svec_adc_pdata[i]),
DMA_BIT_MASK(32));
if (IS_ERR(pdev_data->adc[i])) {
dev_err(&pdev->dev,
"Faild to register ADC instance %d\n",
i);
pdev_data->adc[i] = NULL;
}
}
if (idev == 0)
return -ENODEV;
idev--;
/*
* We know that this design uses the HTVIC IRQ controller.
* This IRQ controller has a linear mapping, so it is enough
* to give the first one as input
*/
ndev = 1 + !!(idev & 0x2);
dev_dbg(&pdev->dev, "Found %d, point to mfd_cell %d\n", ndev, idev);
return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
fa_svec_mfd_devs[idev], ndev,
rmem, irq, NULL);
platform_set_drvdata(pdev, pdev_data);
return 0;
}
static int fa_svec_remove(struct platform_device *pdev)
{
mfd_remove_devices(&pdev->dev);
struct fa_svec_data *pdev_data = platform_get_drvdata(pdev);
int i;
if (!pdev_data)
return 0;
for (i = 0; i < SVEC_FMC_SLOTS; ++i)
if (pdev_data->adc[i])
platform_device_unregister(pdev_data->adc[i]);
kfree(pdev_data);
return 0;
return 0;
}
/**
......
......@@ -15,6 +15,7 @@
#include <linux/debugfs.h>
#include <linux/platform_device.h>
#include <linux/fmc.h>
#include <linux/completion.h>
#include <linux/zio.h>
#include <linux/zio-dma.h>
......@@ -367,6 +368,7 @@ struct zfad_block {
void *dma_ctx;
unsigned int shot_n;
struct dma_slave_config sconfig;
struct completion shot_done;
};
/*
......
......@@ -19,7 +19,8 @@
struct fmc_adc_platform_data {
unsigned long flags;
unsigned long vme_ddr_offset;
unsigned long vme_reg_offset;
unsigned long vme_dma_offset;
uint8_t calib_trig_time;
uint8_t calib_trig_threshold;
uint8_t calib_trig_internal;
......
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