Commit 7a337d4c authored by Javier Díaz's avatar Javier Díaz

vic-eic interrupts tested, debugged with python scripts

parent 00ce30b6
......@@ -8,3 +8,5 @@ modules = {"local" :
"git" : "git://ohwr.org/hdl-core-lib/wr-cores.git::wishbonized",
"svn" : "http://svn.ohwr.org/gn4124-core/trunk/hdl/gn4124core/rtl"
}
......@@ -22,7 +22,7 @@ The main block modules of the architecture are described on next figure.
![Main HDL blocks of the wr-nic gateware](./img/wr_nic_blocks2.png)
Here`s a quick description of each block:
Here is a quick description of each block:
* The `DIO core` allows configuration of each one of the 5 channels of the DIO mezzanine as input or output. For inputs, it provides an accurate time stamp (using time information from the WRPC, not shown in the diagram) and optionally a host (PCIe) interrupt via the IRQ Gen block. For outputs, it allows the user to schedule the generation of a pulse at a given future time, or to generate it immediately.
* The `IRQ Gen` block receives one-tick-long pulses from other blocks and generates interrupt requests to the GN4124 core. It also includes interrupt source and mask registers.
......@@ -30,7 +30,7 @@ Here`s a quick description of each block:
The `GN4124 core` is a bridge between the GN4124 PCIe interface chip and the internal Wishbone bus, allowing communication with the host and interrupts --> pipelined version!
* The `WRPC (White Rabbit PTP Core)` communicates with the outside world through the SFP socket in the SPEC, typically using fiber optics. It deals with the WR PTP using an internal LM32 CPU running a portable PTP stack. It forwards/receives non-PTP frames to/from the NIC block, using two pipelined Wishbone interfaces (master and slave for forwarding and receiving respectively). It also provides time information to other cores (not represented in the diagram), and time-tags for transmitted and received frames that can be read through Wishbone for diagnostics purposes. Future versions will include the PPSi library instead of the current PTP stack.
* The `NIC core` ensures communication between the host and the WRPC. More precisely, it interrupts the host and provides a descriptor that the host can use to fetch incoming frames. For outgoing frames, it receives a descriptor from the host, fetches the frame using PCIe DMA via the GN4124 core and sends it to the WRPC using a pipelined Wishbone interface.
* The `TxTSU module` collect tiemstamps with associated frame identifiers and puts them in a shared FIFO (port identifier is also included although not required for the SPEC card because only one Ethernet port is available). A IRQ is triggered when FIFO is not empty so drivers could read TX timestamps and frame/port identifiers.
* The `TxTSU module` collect timestamps with associated frame identifiers and puts them in a shared FIFO (port identifier is also included although not required for the SPEC card because only one Ethernet port is available). A IRQ is triggered when FIFO is not empty so drivers could read TX timestamps and frame/port identifiers.
DIO core
......@@ -70,27 +70,30 @@ Any address within this memory space may be addressed by the PC to configure cor
DIO core utilization
--------------------
The DIO core, according to its architecture already shown, it allows to read input data of each of the 5 channel with precise time-tag information provided by the WRPTP core. It is also possible to program output at a precise time or we could just generate an monostable output inmediately. In addition, it is also possible to configure different boards elements as terminator resistors or reference voltage Level using the DAC. All this elements could be controlled independently for each of the 5 channels. More information about the different board configuration elements is available at: http://www.ohwr.org/projects/fmc-dio-5chttla
The DIO core, according to its architecture already shown, it allows to read input data of each of the 5 channel with precise time-tag information provided by the WRPTP core. It is also possible to program output at a precise time or we could just generate an output signals immediately. In addition, it is also possible to configure different boards elements as terminator resistors or reference voltage Level using the DAC. All this elements could be controlled independently for each of the 5 channels. More information about the different board configuration elements is available at: http://www.ohwr.org/projects/fmc-dio-5chttla
Note that dio channels time base work wth 8 ns accuracy for inputs time-tagging. Outputs need to be generated align on 8 ns time-slices but their time-stamps values have subnanosecond accuracy thanks to the White-Rabbit timing properties.
In order to use input/output channels as previously described, the following actions are required:
* Standard GPIO output generation is selected by defautl. In order to use monostable output (time-programmed or immediate), each channel should be properly configured written to the `di_out_mode register`. A value of 1 indicates that channel will be used for monostable output, otherwise (0 by default), channel will use the values assigned by the GPIO logic block.
* Standard GPIO output generation is selected by default. In order to use monostable output (time-programmed or immediate), each channel should be properly configured written to the `dio_out_mode register`. A value of 1 indicates that channel will be used for programmable output, otherwise (0 by default), channel will use the values assigned by the GPIO logic block.
* Programmed pulse generation: Generate a programmed input at any time at channel X (X between 0 and 4 identifies the required card channel). For this purpose you need to perform the following actions:
* Set the required time. This means to provide the 40 bits for the time value and the number of cycles (28 bits). This requires to write the registers `dio_trigX_seconds, dio_trighX_seconds` (high part of the time value) and `dio_cyc0_cyc`.
* Checking if the the board is ready for accepting new triggers. A `1` will be found at each bit of `dio_trig_rdy` register only when required channel is ready to accepts new request.
* Checking if the the board is ready for accepting new triggers. This can be done by reading a `1` found at each bit of `dio_trig_rdy` register. The EIC bits 9 to 5 have associated interrupts (active means system is ready to accept new trigger values (but please check you have properly configure EIC interrupt mask). Both methods are possible to check the status. Nevertheless note that the non-ready periods are very shorts (13 cycles of a 62.5 MHz clock, 208 ns) so systems is almost always ready for new trigger values.
* Arming the trigger. You need to write a `1` a the corresponding bit of the `dio_latch_time_chX` bit field.
After these operations, a monostable output will be presented on the desired channel at the requested time.
After these operations, a monostable output will be presented on the desired channel at the requested time. It is not necessary to do software reset to the register.
* Immediate pulse generation: A immediate pulse is generated a the output of each of the card channels just by writing a corresponding `1` at the bit field dio_puls_inmed when output mode is set to monostable outputs. No erase is required.
* Immediate pulse generation: A immediate pulse is generated a the output of each of the card channels just by writing a corresponding `1` at the bit field dio_pulse_imm_X when output mode is set to programmable outputs. No reset is required.
* Input time-tagging: for each of the 5 inputs, if a `1` is detected at this channel, a precise time information is stored on logic FIFOs including the 40 bits time counters and 28 bits more for the cycles. For accessing this information you need to read `dio_tsfX_tag_tai` (32 low bits), `dio_tsfX_tag_taih` (high bits), `dio_tsfX_tag_cycles`. Each time the time tag of any channel is stored, the `fifo not empty` flag generates an interruption to the PC. In the next section we will describe this mechanisms.
* Variable pulse length: by writing the value of the registers dio_progX_pulse_length the width of the output pulse could be controlled. The register use the 28 low significant bits and allow a length equal to register_value x 8 ns.
* Input time-tagging: for each of the 5 inputs, if a `1` is detected at this channel, a precise time information is stored on logic FIFOs including the 40 bits time counters and 28 bits more for the cycles (fifo depth is 256 each one). Currently this information is collected even for pins configured in output mode, GPIO, immediate or time-programmable configurations but it is straightforward to change this at the HDL code. For accessing this information you need to read `dio_tsfX_tag_seconds` (32 low bits), `dio_tsfX_tag_secondsh` (high bits), `dio_tsfX_tag_cycles`. Each time the time tag of any channel is stored, the `fifo not empty` flag generates an interruption to the PC. In the next section we will describe these mechanisms.
A detailed information about the memory maps and related registers names are available by generating html documentation of http://www.ohwr.org/projects/wr-nic/repository/revisions/master/changes/modules/wrsw_nic/wr_nic.wb file. Download the file and generate the HTML documentation using wbgen2 tool (for instance wbgen2 -D diocore.htm wr_nic.wb).
Interrupt handling
------------------
The VIC module block is in charge of handling the different interrupts and provide proper registers to inform of the source of each interruption. The main interrupt signal is communicated to the PC using the gn4124 core and the irq_req_p1_i signal and proper GPIO pins needs to be assigned at the hardware level.
The VIC module block is in charge of handling the different interrupts and provide proper registers to inform of the source of each interruption. The main interrupt signal is communicated to the PC using the gn4124 chip and gn4124 and GPIO-8. A proper core in the FPGA uses the irq_req_p1_i signal to activate this external GPIO pin which needs to be assigned at the low-level hardware.
The base address, as shown on the memory map figure is 0x00060000. It handles the following interrupts sources:
......@@ -122,7 +125,7 @@ This project could be used as starting demo with White-Rabbit technology. Betwee
* The user supplies a ~100Hz square wave on one of the inputs of the master card. The master host reads the time value of the rising edge of the external pulse upon IRQ. Then it adds a constant time (something like 1 ms) and sends a frame with that value to the slave.
* The slave schedules a pulse to be produced at that time. On the scope we should see a constant time offset between the two pulses.
* Network latency measurements. This is interesting if we connect a switch between the SPEC cards. By using th timestamps on Ethernet frames we could get the measurement of the network latency, verify it it is constant or how traffic affect this parameter.
* Network latency measurements. This is interesting if we connect a switch between the SPEC cards. By using the timestamps on Ethernet frames we could get the measurement of the network latency, verify it it is constant or how traffic affect this parameter.
* Many other options are possible. For instance, the measurement of the DIO card latency (we know when we generate a pulse and we could measure when it is received). Please fell free to propose new experiments!
......
files = ["wrsw_dio_wb.vhd",
"wrsw_dio.vhd",
"pulse_gen_pl.vhd",
"immed_pulse_counter.vhd",
"dummy_time.vhd" ]
"xwrsw_dio.vhd",
"pulse_gen_pl.vhd",
"immed_pulse_counter.vhd",
"dummy_time.vhd" ]
......@@ -25,7 +25,11 @@
-- 2012-03-08 0.2 Javier.d Added wrsw_dio_wb
-- 2012-07-05 0.3 Javier.d Midified wrsw_dio_wb, modified interface
-------------------------------------------------------------------------------
-- Memory map:
-- 0x000: DIO-ONEWIRE
-- 0x100: DIO-I2C
-- 0x200: DIO-GPIO
-- 0x300: DIO-REGISTERS
-- WARNING: only pipelined mode is supported (Intercon is pipelined only) - T.W.
library ieee;
......@@ -83,13 +87,13 @@ architecture rtl of wrsw_dio is
-------------------------------------------------------------------------------
-- Component only for debugging (in order to generate seconds time)
-------------------------------------------------------------------------------
-- component dummy_time is
-- port(
-- clk_sys : in std_logic;
-- rst_n : in std_logic;
-- tm_utc : out std_logic_vector(39 downto 0);
-- tm_cycles : out std_logic_vector(27 downto 0));
-- end component;
component dummy_time is
port(
clk_sys : in std_logic;
rst_n : in std_logic;
tm_utc : out std_logic_vector(39 downto 0);
tm_cycles : out std_logic_vector(27 downto 0));
end component;
-------------------------------------------------------------------------------
-- PULSE GENERATOR which produces a 1-tick-long pulse in its
......@@ -345,7 +349,7 @@ architecture rtl of wrsw_dio is
type t_cycles_array is array (4 downto 0) of std_logic_vector (27 downto 0);
type t_pulselength_array is array (4 downto 0) of std_logic_vector (27 downto 0);
signal trig_seconds : t_seconds_array;
signal trig_seconds : t_seconds_array;
signal trig_cycles : t_cycles_array;
signal trig_valid_p1 : std_logic_vector (4 downto 0);
......@@ -368,7 +372,7 @@ architecture rtl of wrsw_dio is
-- DEBUG SIGNALS FOR USING seconds time values from dummy_time instead WRPC
signal tm_seconds : std_logic_vector (39 downto 0);
signal tm_seconds : std_logic_vector (39 downto 0);
signal tm_cycles : std_logic_vector (27 downto 0);
-- WB Crossbar
......@@ -387,12 +391,16 @@ architecture rtl of wrsw_dio is
signal cbar_master_in : t_wishbone_master_in_array(c_WB_SLAVES_DIO-1 downto 0);
signal cbar_master_out : t_wishbone_master_out_array(c_WB_SLAVES_DIO-1 downto 0);
signal slave_bypass_i : t_wishbone_slave_in;
signal slave_bypass_o : t_wishbone_slave_out;
-- DIO related signals
signal dio_pulse : std_logic_vector(4 downto 0);
signal dio_pulse_prog : std_logic_vector(4 downto 0);
signal dio_pulse_immed : std_logic_vector(4 downto 0);
signal dio_pulse_immed_stb : std_logic_vector(4 downto 0);
signal dio_out_mode : std_logic_vector(4 downto 0);
signal wb_dio_irq : std_logic;
-------------------------------------------------------------------------------
-- rtl
......@@ -400,13 +408,13 @@ architecture rtl of wrsw_dio is
begin
-- Dummy counter for simulationg WRPC seconds time
-- U_dummy: dummy_time
-- port map(
-- clk_sys => clk_ref_i,
-- rst_n => rst_n_i,
-- tm_utc => tm_utc,
-- tm_cycles => tm_cycles
-- );
U_dummy: dummy_time
port map(
clk_sys => clk_ref_i,
rst_n => rst_n_i,
tm_utc => tm_seconds,
tm_cycles => tm_cycles
);
------------------------------------------------------------------------------
-- GEN AND STAMPER
......@@ -420,12 +428,12 @@ begin
pulse_o => dio_pulse_prog(i),
-- DEBUG
-- tm_time_valid_i => '1',--tm_time_valid_i,
-- tm_utc_i => tm_utc,--tm_utc_i,
-- tm_cycles_i => tm_cycles, --tm_cycles_i,
tm_time_valid_i => tm_time_valid_i,
tm_utc_i => tm_seconds_i,
tm_cycles_i => tm_cycles_i,
tm_time_valid_i => '1',--tm_time_valid_i,
tm_utc_i => tm_seconds,--tm_utc_i,
tm_cycles_i => tm_cycles, --tm_cycles_i,
-- tm_time_valid_i => tm_time_valid_i,
-- tm_utc_i => tm_seconds_i,
-- tm_cycles_i => tm_cycles_i,
trig_ready_o => trig_ready(i),
......@@ -443,13 +451,14 @@ begin
rst_n_i => rst_n_i,
pulse_a_i => dio_in_i(i),
-- tm_time_valid_i => '1',--tm_time_valid_i,
-- tm_utc_i => tm_utc, --tm_utc_i,
-- tm_cycles_i => tm_cycles, --tm_cycles_i,
tm_time_valid_i => tm_time_valid_i,
tm_utc_i => tm_seconds_i,
tm_cycles_i => tm_cycles_i,
-- DEBUG
tm_time_valid_i => '1',--tm_time_valid_i,
tm_utc_i => tm_seconds, --tm_utc_i,
tm_cycles_i => tm_cycles, --tm_cycles_i,
-- tm_time_valid_i => tm_time_valid_i,
-- tm_utc_i => tm_seconds_i,
-- tm_cycles_i => tm_cycles_i,
tag_utc_o => tag_seconds(i),
tag_cycles_o => tag_cycles(i),
......@@ -543,12 +552,27 @@ begin
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
-- Master connections
slave_i(0) => slave_i,
slave_o(0) => slave_o,
slave_i(0) => slave_bypass_i,
slave_o(0) => slave_bypass_o,
-- Slave conenctions
master_i => cbar_master_in,
master_o => cbar_master_out
);
-- Irq form one slave is bypassed to the Master connection
slave_bypass_i.cyc <= slave_i.cyc;
slave_bypass_i.stb <= slave_i.stb;
slave_bypass_i.adr <= slave_i.adr;
slave_bypass_i.sel <= slave_i.sel;
slave_bypass_i.dat <= slave_i.dat;
slave_bypass_i.we <= slave_i.we;
slave_o.ack <= slave_bypass_o.ack;
--slave_o.err <= slave_bypass_o.err;
--slave_o.rty <= slave_bypass_o.rty;
slave_o.stall <= slave_bypass_o.stall;
slave_o.int <= wb_dio_irq;
slave_o.dat <= slave_bypass_o.dat;
immediate_output_with_pulse_length: for i in 0 to 4 generate
immediate_output_component: immed_pulse_counter
......@@ -595,76 +619,77 @@ begin
wb_we_i => cbar_master_out(3).we,
wb_ack_o => cbar_master_in(3).ack,
wb_stall_o => cbar_master_in(3).stall,
wb_int_o => cbar_master_in(3).int,--wb_irq_data_fifo_o, --slave_o.int,
-- Crossbar could not propagate interrupt lines of several slaves => signal bypass
wb_int_o => wb_dio_irq,
clk_asyn_i => clk_ref_i,
dio_tsf0_wr_req_i => dio_tsf_wr_req(0),
dio_tsf0_wr_full_o => dio_tsf_wr_full(0),
dio_tsf0_wr_empty_o => dio_tsf_wr_empty(0),
dio_tsf0_tag_seconds_i => dio_tsf_tag_seconds(0)(31 downto 0),
dio_tsf0_tag_secondsh_i => dio_tsf_tag_seconds(0)(39 downto 32),
dio_tsf0_tag_cycles_i => dio_tsf_tag_cycles(0),
irq_nempty_0_i => irq_nempty(0),
dio_tsf1_wr_req_i => dio_tsf_wr_req(1),
dio_tsf1_wr_full_o => dio_tsf_wr_full(1),
dio_tsf1_wr_empty_o => dio_tsf_wr_empty(1),
dio_tsf1_tag_seconds_i => dio_tsf_tag_seconds(1)(31 downto 0),
dio_tsf1_tag_secondsh_i => dio_tsf_tag_seconds(1)(39 downto 32),
dio_tsf1_tag_cycles_i => dio_tsf_tag_cycles(1),
irq_nempty_1_i => irq_nempty(1),
dio_tsf2_wr_req_i => dio_tsf_wr_req(2),
dio_tsf2_wr_full_o => dio_tsf_wr_full(2),
dio_tsf2_wr_empty_o => dio_tsf_wr_empty(2),
dio_tsf2_tag_seconds_i => dio_tsf_tag_seconds(2)(31 downto 0),
dio_tsf2_tag_secondsh_i => dio_tsf_tag_seconds(2)(39 downto 32),
dio_tsf2_tag_cycles_i => dio_tsf_tag_cycles(2),
irq_nempty_2_i => irq_nempty(2),
dio_tsf3_wr_req_i => dio_tsf_wr_req(3),
dio_tsf3_wr_full_o => dio_tsf_wr_full(3),
dio_tsf3_wr_empty_o => dio_tsf_wr_empty(3),
dio_tsf3_tag_seconds_i => dio_tsf_tag_seconds(3)(31 downto 0),
dio_tsf3_tag_secondsh_i => dio_tsf_tag_seconds(3)(39 downto 32),
dio_tsf3_tag_cycles_i => dio_tsf_tag_cycles(3),
irq_nempty_3_i => irq_nempty(3),
dio_tsf4_wr_req_i => dio_tsf_wr_req(4),
dio_tsf4_wr_full_o => dio_tsf_wr_full(4),
dio_tsf4_wr_empty_o => dio_tsf_wr_empty(4),
dio_tsf4_tag_seconds_i => dio_tsf_tag_seconds(4)(31 downto 0),
dio_tsf4_tag_secondsh_i => dio_tsf_tag_seconds(4)(39 downto 32),
dio_tsf4_tag_cycles_i => dio_tsf_tag_cycles(4),
irq_nempty_4_i => irq_nempty(4),
dio_trig0_seconds_o => trig_seconds(0)(31 downto 0),
dio_trigh0_seconds_o => trig_seconds(0)(39 downto 32),
dio_cyc0_cyc_o => trig_cycles(0),
dio_trig1_seconds_o => trig_seconds(1)(31 downto 0),
dio_trigh1_seconds_o => trig_seconds(1)(39 downto 32),
dio_cyc1_cyc_o => trig_cycles(1),
dio_trig2_seconds_o => trig_seconds(2)(31 downto 0),
dio_trigh2_seconds_o => trig_seconds(2)(39 downto 32),
dio_cyc2_cyc_o => trig_cycles(2),
dio_trig3_seconds_o => trig_seconds(3)(31 downto 0),
dio_trigh3_seconds_o => trig_seconds(3)(39 downto 32),
dio_cyc3_cyc_o => trig_cycles(3),
dio_trig4_seconds_o => trig_seconds(4)(31 downto 0),
dio_trigh4_seconds_o => trig_seconds(4)(39 downto 32),
dio_cyc4_cyc_o => trig_cycles(4),
dio_out_mode_o => dio_out_mode,
dio_latch_time_ch0_o => trig_valid_p1(0),
dio_latch_time_ch1_o => trig_valid_p1(1),
dio_latch_time_ch2_o => trig_valid_p1(2),
dio_latch_time_ch3_o => trig_valid_p1(3),
dio_latch_time_ch4_o => trig_valid_p1(4),
dio_tsf0_wr_req_i => dio_tsf_wr_req(0),
dio_tsf0_wr_full_o => dio_tsf_wr_full(0),
dio_tsf0_wr_empty_o => dio_tsf_wr_empty(0),
dio_tsf0_tag_seconds_i => dio_tsf_tag_seconds(0)(31 downto 0),
dio_tsf0_tag_secondsh_i => dio_tsf_tag_seconds(0)(39 downto 32),
dio_tsf0_tag_cycles_i => dio_tsf_tag_cycles(0),
irq_nempty_0_i => irq_nempty(0),
dio_tsf1_wr_req_i => dio_tsf_wr_req(1),
dio_tsf1_wr_full_o => dio_tsf_wr_full(1),
dio_tsf1_wr_empty_o => dio_tsf_wr_empty(1),
dio_tsf1_tag_seconds_i => dio_tsf_tag_seconds(1)(31 downto 0),
dio_tsf1_tag_secondsh_i => dio_tsf_tag_seconds(1)(39 downto 32),
dio_tsf1_tag_cycles_i => dio_tsf_tag_cycles(1),
irq_nempty_1_i => irq_nempty(1),
dio_tsf2_wr_req_i => dio_tsf_wr_req(2),
dio_tsf2_wr_full_o => dio_tsf_wr_full(2),
dio_tsf2_wr_empty_o => dio_tsf_wr_empty(2),
dio_tsf2_tag_seconds_i => dio_tsf_tag_seconds(2)(31 downto 0),
dio_tsf2_tag_secondsh_i => dio_tsf_tag_seconds(2)(39 downto 32),
dio_tsf2_tag_cycles_i => dio_tsf_tag_cycles(2),
irq_nempty_2_i => irq_nempty(2),
dio_tsf3_wr_req_i => dio_tsf_wr_req(3),
dio_tsf3_wr_full_o => dio_tsf_wr_full(3),
dio_tsf3_wr_empty_o => dio_tsf_wr_empty(3),
dio_tsf3_tag_seconds_i => dio_tsf_tag_seconds(3)(31 downto 0),
dio_tsf3_tag_secondsh_i => dio_tsf_tag_seconds(3)(39 downto 32),
dio_tsf3_tag_cycles_i => dio_tsf_tag_cycles(3),
irq_nempty_3_i => irq_nempty(3),
dio_tsf4_wr_req_i => dio_tsf_wr_req(4),
dio_tsf4_wr_full_o => dio_tsf_wr_full(4),
dio_tsf4_wr_empty_o => dio_tsf_wr_empty(4),
dio_tsf4_tag_seconds_i => dio_tsf_tag_seconds(4)(31 downto 0),
dio_tsf4_tag_secondsh_i => dio_tsf_tag_seconds(4)(39 downto 32),
dio_tsf4_tag_cycles_i => dio_tsf_tag_cycles(4),
irq_nempty_4_i => irq_nempty(4),
dio_trig0_seconds_o => trig_seconds(0)(31 downto 0),
dio_trigh0_seconds_o => trig_seconds(0)(39 downto 32),
dio_cyc0_cyc_o => trig_cycles(0),
dio_trig1_seconds_o => trig_seconds(1)(31 downto 0),
dio_trigh1_seconds_o => trig_seconds(1)(39 downto 32),
dio_cyc1_cyc_o => trig_cycles(1),
dio_trig2_seconds_o => trig_seconds(2)(31 downto 0),
dio_trigh2_seconds_o => trig_seconds(2)(39 downto 32),
dio_cyc2_cyc_o => trig_cycles(2),
dio_trig3_seconds_o => trig_seconds(3)(31 downto 0),
dio_trigh3_seconds_o => trig_seconds(3)(39 downto 32),
dio_cyc3_cyc_o => trig_cycles(3),
dio_trig4_seconds_o => trig_seconds(4)(31 downto 0),
dio_trigh4_seconds_o => trig_seconds(4)(39 downto 32),
dio_cyc4_cyc_o => trig_cycles(4),
dio_out_mode_o => dio_out_mode,
dio_latch_time_ch0_o => trig_valid_p1(0),
dio_latch_time_ch1_o => trig_valid_p1(1),
dio_latch_time_ch2_o => trig_valid_p1(2),
dio_latch_time_ch3_o => trig_valid_p1(3),
dio_latch_time_ch4_o => trig_valid_p1(4),
dio_trig_rdy_i => trig_ready,
......@@ -680,11 +705,11 @@ begin
dio_prog3_pulse_length_o=> pulse_length(3),
dio_prog4_pulse_length_o=> pulse_length(4),
dio_pulse_imm_0_o => dio_pulse_immed_stb(0),
dio_pulse_imm_1_o => dio_pulse_immed_stb(1),
dio_pulse_imm_2_o => dio_pulse_immed_stb(2),
dio_pulse_imm_3_o => dio_pulse_immed_stb(3),
dio_pulse_imm_4_o => dio_pulse_immed_stb(4)
dio_pulse_imm_0_o => dio_pulse_immed_stb(0),
dio_pulse_imm_1_o => dio_pulse_immed_stb(1),
dio_pulse_imm_2_o => dio_pulse_immed_stb(2),
dio_pulse_imm_3_o => dio_pulse_immed_stb(3),
dio_pulse_imm_4_o => dio_pulse_immed_stb(4)
);
-- seconds timestamped FIFO-no-empty interrupts
......
-------------------------------------------------------------------------------
-- Title : DIO Core
-- Project : White Rabbit Network Interface
-------------------------------------------------------------------------------
-- File : wrsw_dio.vhd
-- Author : Rafael Rodriguez, Javier Díaz
-- Company : Seven Solutions
-- Created : 2012-03-03
-- Last update: 2012-03-20
-- Platform : FPGA-generic
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description: The DIO core allows configuration of each one of the 5 channels of
-- the DIO mezzanine as input or output. For inputs, it provides an accurate seconds
-- time stamp (using seconds from the WRPC, not shown in the diagram) and
-- a host (PCIe) interrupt via the IRQ Gen block. For outputs, it allows the user
-- to schedule the generation of a pulse at a given future seconds time, or to generate
-- it immediately.
-------------------------------------------------------------------------------
-- TODO:
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-03-03 0.1 Rafa.r Created
-- 2012-03-08 0.2 Javier.d Added wrsw_dio_wb
-- 2012-07-05 0.3 Javier.d Midified wrsw_dio_wb, modified interface
-------------------------------------------------------------------------------
-- Memory map:
-- 0x000: DIO-ONEWIRE
-- 0x100: DIO-I2C
-- 0x200: DIO-GPIO
-- 0x300: DIO-REGISTERS
-- WARNING: only pipelined mode is supported (Intercon is pipelined only) - T.W.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
entity xwrsw_dio is
generic (
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD
);
port (
clk_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
dio_clk_i : in std_logic;
dio_in_i : in std_logic_vector(4 downto 0);
dio_out_o : out std_logic_vector(4 downto 0);
dio_oe_n_o : out std_logic_vector(4 downto 0);
dio_term_en_o : out std_logic_vector(4 downto 0);
dio_onewire_b : inout std_logic;
dio_sdn_n_o : out std_logic;
dio_sdn_ck_n_o : out std_logic;
dio_led_top_o : out std_logic;
dio_led_bot_o : out std_logic;
dio_scl_b : inout std_logic;
dio_sda_b : inout std_logic;
dio_ga_o : out std_logic_vector(1 downto 0);
tm_time_valid_i : in std_logic;
tm_seconds_i : in std_logic_vector(39 downto 0);
tm_cycles_i : in std_logic_vector(27 downto 0);
-- Debug signals for chipscope
TRIG0 : out std_logic_vector(31 downto 0);
TRIG1 : out std_logic_vector(31 downto 0);
TRIG2 : out std_logic_vector(31 downto 0);
TRIG3 : out std_logic_vector(31 downto 0);
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out
-- wb_irq_data_fifo_o : out std_logic -- T.B.DELETED
);
end xwrsw_dio;
architecture rtl of xwrsw_dio is
-------------------------------------------------------------------------------
-- Component only for debugging (in order to generate seconds time)
-------------------------------------------------------------------------------
component dummy_time is
port(
clk_sys : in std_logic;
rst_n : in std_logic;
tm_utc : out std_logic_vector(39 downto 0);
tm_cycles : out std_logic_vector(27 downto 0));
end component;
-------------------------------------------------------------------------------
-- PULSE GENERATOR which produces a 1-tick-long pulse in its
-- output when the seconds time passed to it through a vector equals a
-- pre-programmed seconds time.
-------------------------------------------------------------------------------
component pulse_gen_pl is
generic (
g_ref_clk_rate : integer := 125000000
);
port (
clk_ref_i : in std_logic; -- timing reference clock
clk_sys_i : in std_logic; -- data output reference clock
rst_n_i : in std_logic; -- system reset
pulse_o : out std_logic; -- pulse output
-------------------------------------------------------------------------------
-- Timing input (from WRPC), clk_ref_i domain
------------------------------------------------------------------------------
-- 1: time given on tm_utc_i and tm_cycles_i is valid (otherwise, don't
-- produce pulses and keep trig_ready_o line permamaently active)
tm_time_valid_i : in std_logic;
-- number of seconds
tm_utc_i : in std_logic_vector(39 downto 0);
-- number of clk_ref_i cycles
tm_cycles_i : in std_logic_vector(27 downto 0);
---------------------------------------------------------------------------
-- Time tag output (clk_sys_i domain)
---------------------------------------------------------------------------
-- 1: input is ready to accept next trigger time tag
trig_ready_o : out std_logic;
-- time at which the pulse will be produced + a single-cycle strobe to
-- latch it in
trig_utc_i : in std_logic_vector(39 downto 0);
trig_cycles_i : in std_logic_vector(27 downto 0);
trig_valid_p1_i : in std_logic;
pulse_length_i : in std_logic_vector(27 downto 0)
);
end component;
-------------------------------------------------------------------------------
-- PULSE STAMPER which associates a time-tag with an asyncrhonous
-- input pulse.
-------------------------------------------------------------------------------
component pulse_stamper is
generic (
-- reference clock frequency
g_ref_clk_rate : integer := 125000000
);
port(
clk_ref_i : in std_logic; -- timing reference clock
clk_sys_i : in std_logic; -- data output reference clock
rst_n_i : in std_logic; -- system reset
pulse_a_i : in std_logic; -- pulses to be stamped
-------------------------------------------------------------------------------
-- Timing input (from WRPC), clk_ref_i domain
------------------------------------------------------------------------------
-- 1: time given on tm_seconds_i and tm_cycles_i is valid (otherwise, don't timestamp)
tm_time_valid_i : in std_logic;
-- number of seconds
tm_utc_i : in std_logic_vector(39 downto 0);
-- number of clk_ref_i cycles
tm_cycles_i : in std_logic_vector(27 downto 0);
---------------------------------------------------------------------------
-- Time tag output (clk_sys_i domain)
---------------------------------------------------------------------------
tag_utc_o : out std_logic_vector(39 downto 0);
tag_cycles_o : out std_logic_vector(27 downto 0);
-- single-cycle pulse: strobe tag on tag_seconds_o and tag_cycles_o
tag_valid_p1_o : out std_logic
);
end component;
component immed_pulse_counter is
generic (
-- reference clock frequency
pulse_length_width : integer := 28
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic; -- asynchronous system reset
pulse_start_i : in std_logic; -- strobe for pulse generation
pulse_length_i : in std_logic_vector(pulse_length_width-1 downto 0);
pulse_output_o : out std_logic
);
end component;
component wrsw_dio_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(5 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
clk_asyn_i : in std_logic;
-- FIFO write request
dio_tsf0_wr_req_i : in std_logic;
-- FIFO full flag
dio_tsf0_wr_full_o : out std_logic;
-- FIFO empty flag
dio_tsf0_wr_empty_o : out std_logic;
dio_tsf0_tag_seconds_i : in std_logic_vector(31 downto 0);
dio_tsf0_tag_secondsh_i : in std_logic_vector(7 downto 0);
dio_tsf0_tag_cycles_i : in std_logic_vector(27 downto 0);
irq_nempty_0_i : in std_logic;
-- FIFO write request
dio_tsf1_wr_req_i : in std_logic;
-- FIFO full flag
dio_tsf1_wr_full_o : out std_logic;
-- FIFO empty flag
dio_tsf1_wr_empty_o : out std_logic;
dio_tsf1_tag_seconds_i : in std_logic_vector(31 downto 0);
dio_tsf1_tag_secondsh_i : in std_logic_vector(7 downto 0);
dio_tsf1_tag_cycles_i : in std_logic_vector(27 downto 0);
irq_nempty_1_i : in std_logic;
-- FIFO write request
dio_tsf2_wr_req_i : in std_logic;
-- FIFO full flag
dio_tsf2_wr_full_o : out std_logic;
-- FIFO empty flag
dio_tsf2_wr_empty_o : out std_logic;
dio_tsf2_tag_seconds_i : in std_logic_vector(31 downto 0);
dio_tsf2_tag_secondsh_i : in std_logic_vector(7 downto 0);
dio_tsf2_tag_cycles_i : in std_logic_vector(27 downto 0);
irq_nempty_2_i : in std_logic;
-- FIFO write request
dio_tsf3_wr_req_i : in std_logic;
-- FIFO full flag
dio_tsf3_wr_full_o : out std_logic;
-- FIFO empty flag
dio_tsf3_wr_empty_o : out std_logic;
dio_tsf3_tag_seconds_i : in std_logic_vector(31 downto 0);
dio_tsf3_tag_secondsh_i : in std_logic_vector(7 downto 0);
dio_tsf3_tag_cycles_i : in std_logic_vector(27 downto 0);
irq_nempty_3_i : in std_logic;
-- FIFO write request
dio_tsf4_wr_req_i : in std_logic;
-- FIFO full flag
dio_tsf4_wr_full_o : out std_logic;
-- FIFO empty flag
dio_tsf4_wr_empty_o : out std_logic;
dio_tsf4_tag_seconds_i : in std_logic_vector(31 downto 0);
dio_tsf4_tag_secondsh_i : in std_logic_vector(7 downto 0);
dio_tsf4_tag_cycles_i : in std_logic_vector(27 downto 0);
irq_nempty_4_i : in std_logic;
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 0 seconds-based trigger for pulse generation'
dio_trig0_seconds_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 0 seconds-based trigger for pulse generation'
dio_trigh0_seconds_o : out std_logic_vector(7 downto 0);
-- Port for std_logic_vector field: 'cycles field' in reg: 'fmc-dio 0 cycles to trigger a pulse generation'
dio_cyc0_cyc_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 1 seconds-based trigger for pulse generation'
dio_trig1_seconds_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 1 seconds-based trigger for pulse generation'
dio_trigh1_seconds_o : out std_logic_vector(7 downto 0);
-- Port for std_logic_vector field: 'cycles field' in reg: 'fmc-dio 1 cycles to trigger a pulse generation'
dio_cyc1_cyc_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 2 seconds-based trigger for pulse generation'
dio_trig2_seconds_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 2 seconds-based trigger for pulse generation'
dio_trigh2_seconds_o : out std_logic_vector(7 downto 0);
-- Port for std_logic_vector field: 'cycles field' in reg: 'fmc-dio 2 cycles to trigger a pulse generation'
dio_cyc2_cyc_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 3 seconds-based trigger for pulse generation'
dio_trig3_seconds_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 3 seconds-based trigger for pulse generation'
dio_trigh3_seconds_o : out std_logic_vector(7 downto 0);
-- Port for std_logic_vector field: 'cycles field' in reg: 'fmc-dio 3 cycles to trigger a pulse generation'
dio_cyc3_cyc_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 4 seconds-based trigger for pulse generation'
dio_trig4_seconds_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'seconds field' in reg: 'fmc-dio 4 seconds-based trigger for pulse generation'
dio_trigh4_seconds_o : out std_logic_vector(7 downto 0);
-- Port for std_logic_vector field: 'cycles field' in reg: 'fmc-dio 4 cycles to trigger a pulse generation'
dio_cyc4_cyc_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'outmode' in reg: 'FMC-DIO output configuration register. '
dio_out_mode_o : out std_logic_vector(4 downto 0);
-- Port for MONOSTABLE field: 'Sincle-cycle strobe' in reg: 'Time-programmable output strobe signal'
dio_latch_time_ch0_o : out std_logic;
-- Port for MONOSTABLE field: 'Sincle-cycle strobe' in reg: 'Time-programmable output strobe signal'
dio_latch_time_ch1_o : out std_logic;
-- Port for MONOSTABLE field: 'Sincle-cycle strobe' in reg: 'Time-programmable output strobe signal'
dio_latch_time_ch2_o : out std_logic;
-- Port for MONOSTABLE field: 'Sincle-cycle strobe' in reg: 'Time-programmable output strobe signal'
dio_latch_time_ch3_o : out std_logic;
-- Port for MONOSTABLE field: 'Sincle-cycle strobe' in reg: 'Time-programmable output strobe signal'
dio_latch_time_ch4_o : out std_logic;
-- Port for std_logic_vector field: 'trig_rdy field' in reg: 'FMC-DIO time trigger is ready to accept a new trigger generation request'
dio_trig_rdy_i : in std_logic_vector(4 downto 0);
irq_trigger_ready_0_i : in std_logic;
irq_trigger_ready_1_i : in std_logic;
irq_trigger_ready_2_i : in std_logic;
irq_trigger_ready_3_i : in std_logic;
irq_trigger_ready_4_i : in std_logic;
-- Port for std_logic_vector field: 'number of ticks field for channel 0' in reg: 'fmc-dio channel 0 Programmable/immediate output pulse length'
dio_prog0_pulse_length_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'number of ticks field for channel 1' in reg: 'fmc-dio channel 1 Programmable/immediate output pulse length'
dio_prog1_pulse_length_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'number of ticks field for channel 2' in reg: 'fmc-dio channel 2 Programmable/immediate output pulse length'
dio_prog2_pulse_length_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'number of ticks field for channel 3' in reg: 'fmc-dio channel 3 Programmable/immediate output pulse length'
dio_prog3_pulse_length_o : out std_logic_vector(27 downto 0);
-- Port for std_logic_vector field: 'number of ticks field for channel 4' in reg: 'fmc-dio channel 4 Programmable/immediate output pulse length'
dio_prog4_pulse_length_o : out std_logic_vector(27 downto 0);
-- Port for asynchronous (clock: clk_asyn_i) MONOSTABLE field: 'pulse_gen_now_0' in reg: 'Pulse generate immediately'
dio_pulse_imm_0_o : out std_logic;
-- Port for asynchronous (clock: clk_asyn_i) MONOSTABLE field: 'pulse_gen_now_1' in reg: 'Pulse generate immediately'
dio_pulse_imm_1_o : out std_logic;
-- Port for asynchronous (clock: clk_asyn_i) MONOSTABLE field: 'pulse_gen_now_2' in reg: 'Pulse generate immediately'
dio_pulse_imm_2_o : out std_logic;
-- Port for asynchronous (clock: clk_asyn_i) MONOSTABLE field: 'pulse_gen_now_3' in reg: 'Pulse generate immediately'
dio_pulse_imm_3_o : out std_logic;
-- Port for asynchronous (clock: clk_asyn_i) MONOSTABLE field: 'pulse_gen_now_4' in reg: 'Pulse generate immediately'
dio_pulse_imm_4_o : out std_logic
);
end component;
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
constant c_WB_SLAVES_DIO : integer := 4;
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
signal gpio_out : std_logic_vector(31 downto 0);
signal gpio_in : std_logic_vector(31 downto 0);
signal gpio_oen : std_logic_vector(31 downto 0);
signal onewire_en : std_logic;
signal onewire_pwren : std_logic;
signal scl_pad_in, scl_pad_out, scl_pad_oen : std_logic;
signal sda_pad_in, sda_pad_out, sda_pad_oen : std_logic;
-- Pulse generator trigger registers signals
type t_seconds_array is array (4 downto 0) of std_logic_vector (39 downto 0);
type t_cycles_array is array (4 downto 0) of std_logic_vector (27 downto 0);
type t_pulselength_array is array (4 downto 0) of std_logic_vector (27 downto 0);
signal trig_seconds : t_seconds_array;
signal trig_cycles : t_cycles_array;
signal trig_valid_p1 : std_logic_vector (4 downto 0);
signal trig_ready : std_logic_vector (4 downto 0);
signal tag_seconds : t_seconds_array;
signal tag_cycles : t_cycles_array;
signal tag_valid_p1 : std_logic_vector (4 downto 0);
signal pulse_length : t_pulselength_array;
-- FIFO signals
signal dio_tsf_wr_req : std_logic_vector (4 downto 0);
signal dio_tsf_wr_full : std_logic_vector (4 downto 0);
signal dio_tsf_wr_empty : std_logic_vector (4 downto 0);
signal dio_tsf_tag_seconds : t_seconds_array;
signal dio_tsf_tag_cycles : t_cycles_array;
-- Fifos no-empty interrupts
signal irq_nempty : std_logic_vector (4 downto 0);
-- DEBUG SIGNALS FOR USING seconds time values from dummy_time instead WRPC
signal tm_seconds : std_logic_vector (39 downto 0);
signal tm_cycles : std_logic_vector (27 downto 0);
-- WB Crossbar
constant c_cfg_base_addr : t_wishbone_address_array(3 downto 0) :=
(0 => x"00000000", -- ONEWIRE
1 => x"00000100", -- I2C
2 => x"00000200", -- GPIO
3 => x"00000300"); -- PULSE GEN & STAMPER
constant c_cfg_base_mask : t_wishbone_address_array(3 downto 0) :=
(0 => x"00000f00",
1 => x"00000f00",
2 => x"00000f00",
3 => x"00000f00");
signal cbar_master_in : t_wishbone_master_in_array(c_WB_SLAVES_DIO-1 downto 0);
signal cbar_master_out : t_wishbone_master_out_array(c_WB_SLAVES_DIO-1 downto 0);
signal slave_bypass_i : t_wishbone_slave_in;
signal slave_bypass_o : t_wishbone_slave_out;
-- DIO related signals
signal dio_pulse : std_logic_vector(4 downto 0);
signal dio_pulse_prog : std_logic_vector(4 downto 0);
signal dio_pulse_immed : std_logic_vector(4 downto 0);
signal dio_pulse_immed_stb : std_logic_vector(4 downto 0);
signal dio_out_mode : std_logic_vector(4 downto 0);
signal wb_dio_irq : std_logic;
-------------------------------------------------------------------------------
-- rtl
-------------------------------------------------------------------------------
begin
-- Dummy counter for simulationg WRPC seconds time
-- U_dummy: dummy_time
-- port map(
-- clk_sys => clk_ref_i,
-- rst_n => rst_n_i,
-- tm_utc => tm_seconds,
-- tm_cycles => tm_cycles
-- );
------------------------------------------------------------------------------
-- GEN AND STAMPER
------------------------------------------------------------------------------
gen_pulse_modules : for i in 0 to 4 generate
U_pulse_gen : pulse_gen_pl
port map(
clk_ref_i => clk_ref_i,
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
pulse_o => dio_pulse_prog(i),
-- DEBUG
-- tm_time_valid_i => '1',--tm_time_valid_i,
-- tm_utc_i => tm_seconds,--tm_utc_i,
-- tm_cycles_i => tm_cycles, --tm_cycles_i,
tm_time_valid_i => tm_time_valid_i,
tm_utc_i => tm_seconds_i,
tm_cycles_i => tm_cycles_i,
trig_ready_o => trig_ready(i),
trig_utc_i => trig_seconds(i),
trig_cycles_i => trig_cycles(i),
trig_valid_p1_i => trig_valid_p1(i),
pulse_length_i => pulse_length(i)
);
U_pulse_stamper : pulse_stamper
port map(
clk_ref_i => clk_ref_i,
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
pulse_a_i => dio_in_i(i),
-- DEBUG
-- tm_time_valid_i => '1',
-- tm_utc_i => tm_seconds,
-- tm_cycles_i => tm_cycles,
tm_time_valid_i => tm_time_valid_i,
tm_utc_i => tm_seconds_i,
tm_cycles_i => tm_cycles_i,
tag_utc_o => tag_seconds(i),
tag_cycles_o => tag_cycles(i),
tag_valid_p1_o => tag_valid_p1(i));
end generate gen_pulse_modules;
------------------------------------------------------------------------------
-- WB ONEWIRE MASTER
------------------------------------------------------------------------------
U_Onewire : xwb_onewire_master
generic map (
g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_num_ports => 1)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
slave_i => cbar_master_out(0),
slave_o => cbar_master_in(0),
desc_o => open,
owr_pwren_o(0) => onewire_pwren,
owr_en_o(0) => onewire_en,
owr_i(0) => dio_onewire_b);
dio_onewire_b <= '0' when onewire_en = '1' else 'Z';
------------------------------------------------------------------------------
-- WB I2C MASTER
------------------------------------------------------------------------------
U_I2C : xwb_i2c_master
generic map (
g_interface_mode => PIPELINED,
g_address_granularity => BYTE
)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
slave_i => cbar_master_out(1),
slave_o => cbar_master_in(1),
desc_o => open,
scl_pad_i => scl_pad_in,
scl_pad_o => scl_pad_out,
scl_padoen_o => scl_pad_oen,
sda_pad_i => sda_pad_in,
sda_pad_o => sda_pad_out,
sda_padoen_o => sda_pad_oen);
dio_scl_b <= scl_pad_out when scl_pad_oen = '0' else 'Z';
dio_sda_b <= sda_pad_out when sda_pad_oen = '0' else 'Z';
scl_pad_in <= dio_scl_b;
sda_pad_in <= dio_sda_b;
dio_ga_o<="00"; -- Innused because SPEC boards have these fmc signals to ground
------------------------------------------------------------------------------
-- WB GPIO PORT
------------------------------------------------------------------------------
U_GPIO : xwb_gpio_port
generic map (
g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_num_pins => 32,
g_with_builtin_tristates => false)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
slave_i => cbar_master_out(2),
slave_o => cbar_master_in(2),
desc_o => open,
gpio_b => open,
gpio_out_o => gpio_out,
gpio_in_i => gpio_in,
gpio_oen_o => gpio_oen);
------------------------------------------------------------------------------
-- WB Crossbar
------------------------------------------------------------------------------
WB_INTERCON : xwb_crossbar
generic map(
g_num_masters => 1,
g_num_slaves => 4,
g_registered => true,
-- Address of the slaves connected
g_address => c_cfg_base_addr,
g_mask => c_cfg_base_mask
)
port map(
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
-- Master connections
slave_i(0) => slave_bypass_i,
slave_o(0) => slave_bypass_o,
-- Slave conenctions
master_i => cbar_master_in,
master_o => cbar_master_out
);
-- Irq form one slave is bypassed to the Master connection
slave_bypass_i.cyc <= slave_i.cyc;
slave_bypass_i.stb <= slave_i.stb;
slave_bypass_i.adr <= slave_i.adr;
slave_bypass_i.sel <= slave_i.sel;
slave_bypass_i.dat <= slave_i.dat;
slave_bypass_i.we <= slave_i.we;
slave_o.ack <= slave_bypass_o.ack;
slave_o.stall <= slave_bypass_o.stall;
slave_o.int <= wb_dio_irq;
slave_o.dat <= slave_bypass_o.dat;
--slave_o.err <= slave_bypass_o.err;
--slave_o.rty <= slave_bypass_o.rty;
immediate_output_with_pulse_length: for i in 0 to 4 generate
immediate_output_component: immed_pulse_counter
generic map (
pulse_length_width => 28
)
port map(
clk_i => clk_ref_i,
rst_n_i => rst_n_i,
pulse_start_i => dio_pulse_immed_stb(i),
pulse_length_i => pulse_length(i),
pulse_output_o => dio_pulse_immed(i)
);
end generate immediate_output_with_pulse_length;
gen_pio_assignment: for i in 0 to 4 generate
gpio_in(4*i) <= dio_in_i(i);
dio_pulse(i) <= '1' when dio_pulse_immed(i) = '1' else dio_pulse_prog(i);
dio_out_o(i) <= dio_pulse(i) when dio_out_mode(i) ='1' else gpio_out(4*i);
dio_oe_n_o(i) <= gpio_out(4*i+1);
dio_term_en_o(i) <= gpio_out(4*i+2);
end generate gen_pio_assignment;
dio_led_bot_o <= gpio_out(28);
dio_led_top_o <= gpio_out(27);
gpio_in(29) <= dio_clk_i;
dio_sdn_ck_n_o <= gpio_out(30);
dio_sdn_n_o <= gpio_out(31);
------------------------------------------------------------------------------
-- WB seconds-BASED PULSE GENERATION & INPUT STAMPING
------------------------------------------------------------------------------
U_seconds_wbslave : wrsw_dio_wb
port map(
rst_n_i => rst_n_i,
clk_sys_i => clk_sys_i,
wb_adr_i => cbar_master_out(3).adr(7 downto 2), -- only word acesses are available
wb_dat_i => cbar_master_out(3).dat,
wb_dat_o => cbar_master_in(3).dat,
wb_cyc_i => cbar_master_out(3).cyc,
wb_sel_i => cbar_master_out(3).sel,
wb_stb_i => cbar_master_out(3).stb,
wb_we_i => cbar_master_out(3).we,
wb_ack_o => cbar_master_in(3).ack,
wb_stall_o => cbar_master_in(3).stall,
-- Crossbar could not propagate interrupt lines of several slaves => signal bypass
wb_int_o => wb_dio_irq,
clk_asyn_i => clk_ref_i,
dio_tsf0_wr_req_i => dio_tsf_wr_req(0),
dio_tsf0_wr_full_o => dio_tsf_wr_full(0),
dio_tsf0_wr_empty_o => dio_tsf_wr_empty(0),
dio_tsf0_tag_seconds_i => dio_tsf_tag_seconds(0)(31 downto 0),
dio_tsf0_tag_secondsh_i => dio_tsf_tag_seconds(0)(39 downto 32),
dio_tsf0_tag_cycles_i => dio_tsf_tag_cycles(0),
irq_nempty_0_i => irq_nempty(0),
dio_tsf1_wr_req_i => dio_tsf_wr_req(1),
dio_tsf1_wr_full_o => dio_tsf_wr_full(1),
dio_tsf1_wr_empty_o => dio_tsf_wr_empty(1),
dio_tsf1_tag_seconds_i => dio_tsf_tag_seconds(1)(31 downto 0),
dio_tsf1_tag_secondsh_i => dio_tsf_tag_seconds(1)(39 downto 32),
dio_tsf1_tag_cycles_i => dio_tsf_tag_cycles(1),
irq_nempty_1_i => irq_nempty(1),
dio_tsf2_wr_req_i => dio_tsf_wr_req(2),
dio_tsf2_wr_full_o => dio_tsf_wr_full(2),
dio_tsf2_wr_empty_o => dio_tsf_wr_empty(2),
dio_tsf2_tag_seconds_i => dio_tsf_tag_seconds(2)(31 downto 0),
dio_tsf2_tag_secondsh_i => dio_tsf_tag_seconds(2)(39 downto 32),
dio_tsf2_tag_cycles_i => dio_tsf_tag_cycles(2),
irq_nempty_2_i => irq_nempty(2),
dio_tsf3_wr_req_i => dio_tsf_wr_req(3),
dio_tsf3_wr_full_o => dio_tsf_wr_full(3),
dio_tsf3_wr_empty_o => dio_tsf_wr_empty(3),
dio_tsf3_tag_seconds_i => dio_tsf_tag_seconds(3)(31 downto 0),
dio_tsf3_tag_secondsh_i => dio_tsf_tag_seconds(3)(39 downto 32),
dio_tsf3_tag_cycles_i => dio_tsf_tag_cycles(3),
irq_nempty_3_i => irq_nempty(3),
dio_tsf4_wr_req_i => dio_tsf_wr_req(4),
dio_tsf4_wr_full_o => dio_tsf_wr_full(4),
dio_tsf4_wr_empty_o => dio_tsf_wr_empty(4),
dio_tsf4_tag_seconds_i => dio_tsf_tag_seconds(4)(31 downto 0),
dio_tsf4_tag_secondsh_i => dio_tsf_tag_seconds(4)(39 downto 32),
dio_tsf4_tag_cycles_i => dio_tsf_tag_cycles(4),
irq_nempty_4_i => irq_nempty(4),
dio_trig0_seconds_o => trig_seconds(0)(31 downto 0),
dio_trigh0_seconds_o => trig_seconds(0)(39 downto 32),
dio_cyc0_cyc_o => trig_cycles(0),
dio_trig1_seconds_o => trig_seconds(1)(31 downto 0),
dio_trigh1_seconds_o => trig_seconds(1)(39 downto 32),
dio_cyc1_cyc_o => trig_cycles(1),
dio_trig2_seconds_o => trig_seconds(2)(31 downto 0),
dio_trigh2_seconds_o => trig_seconds(2)(39 downto 32),
dio_cyc2_cyc_o => trig_cycles(2),
dio_trig3_seconds_o => trig_seconds(3)(31 downto 0),
dio_trigh3_seconds_o => trig_seconds(3)(39 downto 32),
dio_cyc3_cyc_o => trig_cycles(3),
dio_trig4_seconds_o => trig_seconds(4)(31 downto 0),
dio_trigh4_seconds_o => trig_seconds(4)(39 downto 32),
dio_cyc4_cyc_o => trig_cycles(4),
dio_out_mode_o => dio_out_mode,
dio_latch_time_ch0_o => trig_valid_p1(0),
dio_latch_time_ch1_o => trig_valid_p1(1),
dio_latch_time_ch2_o => trig_valid_p1(2),
dio_latch_time_ch3_o => trig_valid_p1(3),
dio_latch_time_ch4_o => trig_valid_p1(4),
dio_trig_rdy_i => trig_ready,
irq_trigger_ready_0_i => trig_ready(0),
irq_trigger_ready_1_i => trig_ready(1),
irq_trigger_ready_2_i => trig_ready(2),
irq_trigger_ready_3_i => trig_ready(3),
irq_trigger_ready_4_i => trig_ready(4),
dio_prog0_pulse_length_o=> pulse_length(0),
dio_prog1_pulse_length_o=> pulse_length(1),
dio_prog2_pulse_length_o=> pulse_length(2),
dio_prog3_pulse_length_o=> pulse_length(3),
dio_prog4_pulse_length_o=> pulse_length(4),
dio_pulse_imm_0_o => dio_pulse_immed_stb(0),
dio_pulse_imm_1_o => dio_pulse_immed_stb(1),
dio_pulse_imm_2_o => dio_pulse_immed_stb(2),
dio_pulse_imm_3_o => dio_pulse_immed_stb(3),
dio_pulse_imm_4_o => dio_pulse_immed_stb(4)
);
-- seconds timestamped FIFO-no-empty interrupts
irq_fifos : for i in 0 to 4 generate
irq_nempty(i) <= not dio_tsf_wr_empty(i);
process(clk_sys_i, rst_n_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
dio_tsf_wr_req(i) <= '0';
dio_tsf_tag_seconds(i) <= (others => '0');
dio_tsf_tag_cycles(i) <= (others => '0');
else
if ((tag_valid_p1(i) = '1') AND (dio_tsf_wr_full(i)='0')) then
dio_tsf_wr_req(i) <='1';
dio_tsf_tag_seconds(i) <=tag_seconds(i);
dio_tsf_tag_cycles(i) <=tag_cycles(i);
else
dio_tsf_wr_req(i) <='0';
end if;
end if;
end if;
end process;
end generate irq_fifos;
-----------------------------------------------------------------------------------
------ signals for debugging
-----------------------------------------------------------------------------------
-- TRIG0 <= tag_utc(0)(31 downto 0);
-- TRIG1(27 downto 0) <= tag_cycles(0)(27 downto 0);
-- TRIG1(0) <= cbar_master_in(3).int;
-- TRIG2 <= tm_utc(31 downto 0);
-- TRIG3(2 downto 0) <= dio_in_i(0) & dio_out(0) & dio_pulse_immed(0);
--TRIG3(4 downto 0) <= dio_tsf_wr_req(0) & tag_valid_p1(0) & gpio_out(1) & dio_in_i(0) & dio_out(0);
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
end rtl;
......@@ -23,6 +23,17 @@ class VIC_irq:
def get_reg(self, adr):
return self.bus.iread(0, self.base + adr, 4)
class wrcore_time:
def __init__(self, bus, base):
self.bus = bus;
self.base = base;
def set_reg(self, adr, value):
self.bus.iwrite(0, self.base + adr, 4, value)
def get_reg(self, adr):
return self.bus.iread(0, self.base + adr, 4)
class CDAC5578:
......@@ -63,10 +74,10 @@ class CDAC5578:
class CFmcDio:
BASE_REGS = 0x300
BASE_GPIO = 0x200
BASE_I2C = 0x100
BASE_ONEWIRE = 0x0
BASE_I2C = 0x100
BASE_GPIO = 0x200
BASE_REGS = 0x300
I2C_ADDR_DAC = 0x48
I2C_ADDR_EEPROM = 0x50
......@@ -132,13 +143,13 @@ class CFmcDio:
return self.ds1820.read_temp(serial_number)
def set_reg(self, adr, value):
self.bus.iwrite(0, 0x60000 + self.BASE_REGS + adr, 4, value)
self.bus.iwrite(0, 0x62000 + self.BASE_REGS + adr, 4, value)
def get_reg(self, adr):
return self.bus.iread(0, 0x60000 + self.BASE_REGS + adr, 4)
return self.bus.iread(0, 0x62000 + self.BASE_REGS + adr, 4)
def get_reg_long(self, adr):
return self.bus.iread(0, 0x60000 + self.BASE_REGS + adr, 8)
return self.bus.iread(0, 0x62000 + self.BASE_REGS + adr, 8)
def wait_irq_spec(self):
return self.bus.irqwait()
......
#!/bin/bash
insmod ~/pts/gnurabbit/kernel/rawrabbit.ko vendor=0x10dc device=0x18d
insmod ~/OHWR/wr-nic/software_test_dio_core/rawrabbit.ko vendor=0x10dc device=0x18d
......@@ -21,30 +21,42 @@ GN4124_CSR = 0x0
def main(default_directory="."):
print "(-------------STARTING TEST-----------------)"
# Configure the FPGA using the program fpga_loader
path_fpga_loader = './fpga_loader'
path_firmware = '../syn/spec/wr_nic_top.bin'
firmware_loader = os.path.join(default_directory, path_fpga_loader)
bitstream = os.path.join(default_directory, path_firmware)
print "Loading firmware: %s" % (firmware_loader + ' ' + bitstream)
os.system( firmware_loader + ' ' + bitstream )
# Load board library and open the corresponding device
spec = rr.Gennum()
gennum = gn4124.CGN4124(spec, GN4124_CSR)
dio = CFmcDio(spec, 0x60000)
dio = CFmcDio(spec, 0x62000)
print "(3 devices expected)"
print
print ("FMC temperature: %3.3f°C" % dio.get_temp())
print "(expected room or computer temperature)"
print
# Lemo output configuration
print "(------------CONFIGURING DIO CHANNELS--------------)"
print "Value of LEMOs with all drivers enabled and terminations disabled"
for lemon in range(5):
dio.set_term(lemon, 0)
dio.set_dir(lemon, 1)
dio.set_dir(lemon, 1) # enable output
dio.set_in_threshold(lemon,15)
print "Input threshold set to an intermediate level ({}).".format(dio.get_in_threshold(0))
print
print "(------------CONFIGURING INTERRUPTS--------------)"
print "(DIO Interrupts)"
# DIO Interrupts
dio.set_reg(0x64, 0x1f) # Interrupts when the fifos have datas (UTC time from the pulse stamper)
print "(DIO Interrupts)"
#dio.set_reg(0x64, 0x1f) # Interrupts when the fifos have datas (UTC time from the pulse stamper)
dio.set_reg(0x64, 0x3ff) # fifos and pulse gen rdy interrupts
mask_irq = dio.get_reg(0x68)
print "MASK IRQ DIO =>", mask_irq
status_irq = dio.get_reg(0x6c)
......@@ -52,81 +64,130 @@ def main(default_directory="."):
# VIC Interrupts
print "(VIC Interrupts)"
VIC = VIC_irq(spec, 0x40000)
VIC = VIC_irq(spec, 0x60000)
VIC.set_reg(0x0, 0x3) # control register
control_irq_vic = VIC.get_reg(0x0)
print "CONTROL IRQ VIC =>", control_irq_vic
VIC.set_reg(0x8, 0x7) # enable register
mask_irq_vic = VIC.get_reg(0x10)
print "MASK IRQ VIC =>", mask_irq_vic
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
# Simulate interrupts
#VIC.set_reg(0x18, 0x7) # generate soft irq
print
print "(------------CONFIGURING TRIG UTC TIME FOR EACH LEMO--------------)"
print "Note: The dummy time core is already running after configuring the fpga, therefore you should run this program"
print "before the configured trigger time below."
dio_rdy = dio.get_reg(0x40)
if dio_rdy != 0x1f:
print "Some pulse_gen module isn't ready to accept next trigger time tag, dio_rdy:", dio_rdy
exit()
#TIME TRIGGERS
dio.set_reg(0x0, 20) #trig0 UTC_low
dio.set_reg(0x4, 0) #trig0 UTC_high
dio.set_reg(0x8, 0) #trig0 cycles
dio.set_reg(0xc, 25) #trig1 UTC_low
dio.set_reg(0x10, 0) #trig1 UTC_high
dio.set_reg(0x14, 67) #trig1 cycles
dio.set_reg(0x18, 31) #trig2 UTC_low
dio.set_reg(0x1c, 0) #trig2 UTC_high
dio.set_reg(0x20, 430) #trig2 cycles
dio.set_reg(0x24, 40) #trig3 UTC_low
dio.set_reg(0x28, 0) #trig3 UTC_high
dio.set_reg(0x2c, 94) #trig3 cycles
dio.set_reg(0x30, 42) #trig4 UTC_low
dio.set_reg(0x34, 0) #trig4 UTC_high
dio.set_reg(0x38, 98) #trig4 cycles
dio.set_reg(0x3c, 0x1f) #all trigX Enabled
#status_irq_vic = VIC.get_reg(0x4)
#print "STATUS VIC IRQ =>", status_irq_vic
# Checking interrupts at pc level
#print "Waiting irq ..."
#spec.irqena()
#gennum.set_interrupt_config()
#a=gennum.wait_irq()
#b=spec.irqwait()
#print "Is this working?", a,b
# Read WRCORE time --> HANG UP THE PC!!!!!!!
#WR_CORE_AD =0x0
#PRI_CROSSBAR_AD=0x00020000 # Second bridge
#SEC_CROSSBAR_AD=0x00000300 # PPS
#time = wrcore_time(spec, (WR_CORE_AD + PRI_CROSSBAR_AD+SEC_CROSSBAR_AD))
#print "eso", time
#seconds= time.get_reg(0x8) NNOOOOOOO!!!!!! 0x00020308
#cycles = time.get_reg(0x4)
#seconds=10
#cycles=0
#print "Time is: ", seconds, "and", cycles*8, "(cycles", cycles, ")"
###################################################################################
# START LEMO OUTPUT DANCING ...
print
print "(------------START LEMO CONFIGURATION--------------)"
#print "Note: The dummy time core is already running after configuring the fpga, therefore you should run this program"
#print "before the configured trigger time below."
# BASIC GPIO FUNCTIONALITY TEST
dio.set_reg(0x3C, 0x00) # channels as GPIOs
for lemon in range(5):
dio.set_dir(lemon, 1) # enable output
dio.set_out(lemon,0)
val=dio.get_in (lemon)
print "Set value for channel", lemon, " to 0, read: ", val
dio.set_out(lemon,1)
val=dio.get_in (lemon)
print "Set value for channel", lemon, " to 1, read: ", val
# Please connect channel 0 and 1 with a lemo wire for this test
dio.set_dir(0, 0) # enable channel 1 output and dissble channel 0
dio.set_dir(1,1)
dio.set_out(1,0)
val=dio.get_in (0)
print "Channel 1 write 0, channel 0 read", val
dio.set_out(1,1)
val=dio.get_in (0)
print "Channel 1 write 1, channel 0 read", val
# Osciloscope test
#dio.set_out(4,1)
#pause()
#dio.set_out(4,0)
#pause()
#dio.set_out(4,1)
#pause()
#dio.set_out(4,0)
#pause()
# TIME-LENGTH PROGRAMMABLE PULSES TESTS
dio.set_reg(0x3C, 0x1f) #Generate a programmable/immediate pulse of different length
# Setting pulse length
dio.set_reg(0x48, 0x1)
dio.set_reg(0x4C, 0x8)
dio.set_reg(0x50, 0x10)
dio.set_reg(0x54, 0x20)
dio.set_reg(0x58, 0x40)
# Time-stamps FIFOs registers address
adr_status_fifo = [0x7c, 0x8c, 0x9c, 0xac, 0xbc]
adr_time = [0x70, 0x80, 0x90, 0xa0, 0xb0]
adr_cycles = [0x78, 0x88, 0x98, 0xa8, 0xb8]
for dio_pulse in range(5):
print "Waiting pulse stamper from DIO ", dio_pulse," ...."
adr_time = [0x70, 0x80, 0x90, 0xa0, 0xb0] # we just take the lowest 32 bits for the seconds
adr_cycles = [0x78, 0x88, 0x98, 0xa8, 0xb8]
# Flushng fifos from previous game
print
for dio_pulse in range(5): # reading of pulses
print "------Flushing fifos ", dio_pulse, ":"
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
while((status_fifo_reg & 0xff) != 0x1): #counter = 0x1
cont = 0
while((status_fifo_reg & 0xff) != 0x0):
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "Pulse ", cont
print "Seconds DIO dio_pulse =>", time
print "cycles DIO dio_pulse =>", cycles
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "UTC DIO dio_pulse =>", time
print "cycles DIO dio_pulse =>", cycles
cont = cont + 1
print
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
print
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq
###################################################################################################
# Inmmediate output test
print
print "(-----------IMMEDIATE PULSE GENERATION (5 pulses for each DIO)---------------)"
#pause()
for num_pulses in range(5):
dio.set_reg(0x44, 0x1f) # To generate 5 pulses for each DIO
dio.set_reg(0x5C, 0x1f) #Generate a pulse of different length
#status_irq = dio.get_reg(0x6c)
##print "STATUS IRQ DIO =>", status_irq
print "5 Immediate pulse of different length has been generated for each channel"
print
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq
print "STATUS IRQ DIO =>", status_irq # 31 means the 5 fifos has data
print
......@@ -134,11 +195,12 @@ def main(default_directory="."):
print "------Pulses from DIO ", dio_pulse, ":"
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
cont = 0
while((status_fifo_reg & 0xff) != 0x0):
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "Pulse ", cont
print "UTC DIO dio_pulse =>", time
print "Seconds DIO dio_pulse =>", time
print "cycles DIO dio_pulse =>", cycles
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
cont = cont + 1
......@@ -150,17 +212,65 @@ def main(default_directory="."):
print "STATUS VIC IRQ =>", status_irq_vic
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq
print "STATUS IRQ DIO =>", status_irq # we have read the fifo, no data to read => 0
# print "Waiting irq ..."
# gennum.wait_irq()
############################################################################
print
print "Starting time-programmable test"
print
print "(------------CONFIGURING TRIGGER TIME FOR EACH LEMO--------------)"
# Programmable output test
dio_rdy = dio.get_reg(0x44)
if dio_rdy != 0x1f:
print "Some pulse_gen module isn't ready to accept next trigger time tag, dio_rdy:", dio_rdy
exit()
#TIME TRIGGERS VALUES FOR EACH CHANNEL
dio.set_reg(0x0, 3) #trig0 seconds_low
dio.set_reg(0x4, 0) #trig0 seconds_high
dio.set_reg(0x8, 0) #trig0 cycles
dio.set_reg(0xc, 10) #trig1 seconds_low
dio.set_reg(0x10, 0) #trig1 seconds_high
dio.set_reg(0x14, 67) #trig1 cycles
exit()
dio.set_reg(0x18, 15) #trig2 seconds_low
dio.set_reg(0x1c, 0) #trig2 seconds_high
dio.set_reg(0x20, 430) #trig2 cycles
dio.set_reg(0x24, 20) #trig3 seconds_low
dio.set_reg(0x28, 0) #trig3 seconds_high
dio.set_reg(0x2c, 94) #trig3 cycles
dio.set_reg(0x30, 25) #trig4 seconds_low
dio.set_reg(0x34, 0) #trig4 seconds_high
dio.set_reg(0x38, 98) #trig4 cycles
dio.set_reg(0x40, 0x1f) # channell x trigger strobe
print
for dio_pulse in range(5):
print "Waiting pulse stamper from DIO ", dio_pulse," ...."
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
while((status_fifo_reg & 0xff) != 0x1): #counter = 0x1
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "DIO dio_pulse seconds =>", time
print "DIO dio_pulse cycles =>", cycles
print
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
print
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq
exit()
if __name__ == "__main__":
main(".")
......
#!/usr/bin/python
#coding: utf8
from ptsexcept import *
from dio_fmc import *
import rr
import os
import sys
import gn4124
import kbhit
"""
Tests DIO core (GEN AND STAMPER PULSE)
"""
def pause():
raw_input("press key\n")
GN4124_CSR = 0x0
def main(default_directory="."):
print "(-------------STARTING TEST-----------------)"
# Configure the FPGA using the program fpga_loader
path_fpga_loader = './fpga_loader'
path_firmware = '../syn/spec/wr_nic_top.bin'
firmware_loader = os.path.join(default_directory, path_fpga_loader)
bitstream = os.path.join(default_directory, path_firmware)
print "Loading firmware: %s" % (firmware_loader + ' ' + bitstream)
os.system( firmware_loader + ' ' + bitstream )
# Load board library and open the corresponding device
spec = rr.Gennum()
gennum = gn4124.CGN4124(spec, GN4124_CSR)
dio = CFmcDio(spec, 0x62000)
print "(3 devices expected)"
print
print ("FMC temperature: %3.3f°C" % dio.get_temp())
print "(expected room or computer temperature)"
print
# Lemo output configuration
print "(------------CONFIGURING DIO CHANNELS--------------)"
print "Value of LEMOs with all drivers enabled and terminations disabled"
for lemon in range(5):
dio.set_term(lemon, 0)
dio.set_dir(lemon, 1) # enable output
dio.set_in_threshold(lemon,15)
print "Input threshold set to an intermediate level ({}).".format(dio.get_in_threshold(0))
print
print "(------------CONFIGURING INTERRUPTS--------------)"
# DIO Interrupts
print "(DIO Interrupts)"
dio.set_reg(0x64, 0x1f) # Interrupts when the fifos have datas (UTC time from the pulse stamper)
#dio.set_reg(0x64, 0x3ff) # fifos and pulse gen rdy interrupts
mask_irq = dio.get_reg(0x68)
print "MASK IRQ DIO =>", mask_irq
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq
# VIC Interrupts
print "(VIC Interrupts)"
VIC = VIC_irq(spec, 0x60000)
VIC.set_reg(0x0, 0x3) # control register
control_irq_vic = VIC.get_reg(0x0)
print "CONTROL IRQ VIC =>", control_irq_vic
VIC.set_reg(0x8, 0x7) # enable register
mask_irq_vic = VIC.get_reg(0x10)
print "MASK IRQ VIC =>", mask_irq_vic
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
# Simulate interrupts
#VIC.set_reg(0x18, 0x7) # generate soft irq
#status_irq_vic = VIC.get_reg(0x4)
#print "STATUS VIC IRQ AFTER SOFTWARE INTERRUPTS =>", status_irq_vic
# Checking interrupts at pc level
#print "Waiting irq ..."
#spec.irqena()
#gennum.set_interrupt_config()
#a=gennum.wait_irq()
#b=spec.irqwait()
#print "Is this working?", a,b
# Read WRCORE time --> HANG UP THE PC!!!!!!!
#WR_CORE_AD =0x0
#PRI_CROSSBAR_AD=0x00020000 # Second bridge
#SEC_CROSSBAR_AD=0x00000300 # PPS
#time = wrcore_time(spec, (WR_CORE_AD + PRI_CROSSBAR_AD+SEC_CROSSBAR_AD))
#print "eso", time
#seconds= time.get_reg(0x8) NNOOOOOOO!!!!!! 0x00020308
#cycles = time.get_reg(0x4)
#seconds=10
#cycles=0
#print "Time is: ", seconds, "and", cycles*8, "(cycles", cycles, ")"
###################################################################################
# START LEMO OUTPUT DANCING ...
print
print "(------------START LEMO CONFIGURATION--------------)"
#print "Note: The dummy time core is already running after configuring the fpga, therefore you should run this program"
#print "before the configured trigger time below."
# BASIC GPIO FUNCTIONALITY TEST
dio.set_reg(0x3C, 0x00) # channels as GPIOs
for lemon in range(5):
dio.set_dir(lemon, 1) # enable output
dio.set_out(lemon,0)
val=dio.get_in (lemon)
print "Set value for channel", lemon, " to 0, read: ", val
dio.set_out(lemon,1)
val=dio.get_in (lemon)
print "Set value for channel", lemon, " to 1, read: ", val
# Please connect channel 0 and 1 with a lemo wire for this test
dio.set_dir(0, 0) # enable channel 1 output and dissble channel 0
dio.set_dir(1,1)
dio.set_out(1,0)
val=dio.get_in (0)
print "Channel 1 write 0, channel 0 read", val
dio.set_out(1,1)
val=dio.get_in (0)
print "Channel 1 write 1, channel 0 read", val
# Osciloscope test
#dio.set_out(4,1)
#pause()
#dio.set_out(4,0)
#pause()
#dio.set_out(4,1)
#pause()
#dio.set_out(4,0)
#pause()
# TIME-LENGTH PROGRAMMABLE PULSES TESTS
dio.set_reg(0x3C, 0x1f) #Generate a programmable/immediate pulse of different length
# Setting pulse length
dio.set_reg(0x48, 0x1)
dio.set_reg(0x4C, 0x8)
dio.set_reg(0x50, 0x10)
dio.set_reg(0x54, 0x1)
dio.set_reg(0x58, 0x40)
# Time-stamps FIFOs registers address
adr_status_fifo = [0x7c, 0x8c, 0x9c, 0xac, 0xbc]
adr_time = [0x70, 0x80, 0x90, 0xa0, 0xb0] # we just take the lowest 32 bits for the seconds
adr_cycles = [0x78, 0x88, 0x98, 0xa8, 0xb8]
# Flushng fifos from previous game
print
for dio_pulse in range(5): # reading of pulses
print "------Flushing fifos ", dio_pulse, ":"
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
cont = 0
while((status_fifo_reg & 0xff) != 0x0):
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "Pulse ", cont
print "Seconds DIO dio_pulse =>", time
print "cycles DIO dio_pulse =>", cycles
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
cont = cont + 1
print
###################################################################################################
# Inmmediate output test
print
print "(-----------IMMEDIATE PULSE GENERATION (5 pulses for each DIO)---------------)"
#pause()
for num_pulses in range(5):
dio.set_reg(0x5C, 0x1f) #Generate a pulse of different length
#status_irq = dio.get_reg(0x6c)
##print "STATUS IRQ DIO =>", status_irq
print "5 Immediate pulse of different length has been generated for each channel"
print
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq # 31 means the 5 fifos has data
print
for dio_pulse in range(5): # reading of pulses
print "------Pulses from DIO ", dio_pulse, ":"
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
cont = 0
while((status_fifo_reg & 0xff) != 0x0):
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "Pulse ", cont
print "Seconds DIO dio_pulse =>", time
print "cycles DIO dio_pulse =>", cycles
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
cont = cont + 1
print
print
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq # we have read the fifo, no data to read => 0
############################################################################
print
print "Starting time-programmable test"
print
print "(------------TIME-TRIGGER BASED OUTPUTS--------------)"
# Programmable output test
dio_rdy = dio.get_reg(0x44)
if dio_rdy != 0x1f:
print "Some pulse_gen module isn't ready to accept next trigger time tag, dio_rdy:", dio_rdy
exit()
#TIME TRIGGERS VALUES FOR EACH CHANNEL
dio.set_reg(0x0, 3) #trig0 seconds_low
dio.set_reg(0x4, 0) #trig0 seconds_high
dio.set_reg(0x8, 0) #trig0 cycles
dio.set_reg(0xc, 5) #trig1 seconds_low
dio.set_reg(0x10, 0) #trig1 seconds_high
dio.set_reg(0x14, 67) #trig1 cycles
dio.set_reg(0x18, 10) #trig2 seconds_low
dio.set_reg(0x1c, 0) #trig2 seconds_high
dio.set_reg(0x20, 430) #trig2 cycles
dio.set_reg(0x24, 12) #trig3 seconds_low
dio.set_reg(0x28, 0) #trig3 seconds_high
dio.set_reg(0x2c, 94) #trig3 cycles
dio.set_reg(0x30, 15) #trig4 seconds_low
dio.set_reg(0x34, 0) #trig4 seconds_high
dio.set_reg(0x38, 98) #trig4 cycles
dio.set_reg(0x40, 0x1f) # channell x trigger strobe
print
for dio_pulse in range(5):
print "Waiting pulse stamper from DIO ", dio_pulse," ...."
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
while((status_fifo_reg & 0xff) != 0x1): #counter = 0x1
status_fifo_reg = dio.get_reg(adr_status_fifo[dio_pulse])
time = dio.get_reg_long(adr_time[dio_pulse])
cycles = dio.get_reg(adr_cycles[dio_pulse])
print "DIO dio_pulse seconds =>", time
print "DIO dio_pulse cycles =>", cycles
print
status_irq_vic = VIC.get_reg(0x4)
print "STATUS VIC IRQ =>", status_irq_vic
print
status_irq = dio.get_reg(0x6c)
print "STATUS IRQ DIO =>", status_irq
exit()
if __name__ == "__main__":
main(".")
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -40,6 +40,11 @@
-- 0x00060000: VIC
-- 0x00061000: TxTSU
-- 0x00062000: DIO
-- 0x000: DIO-ONEWIRE
-- 0x100: DIO-I2C
-- 0x200: DIO-GPIO
-- 0x300: DIO-REGISTERS
library IEEE;
use IEEE.STD_LOGIC_1164.all;
......@@ -80,8 +85,8 @@ entity wr_nic_top is
L_RST_N : in std_logic; -- Reset from GN4124 (RSTOUT18_N)
-- General Purpose Interface
GPIO : inout std_logic_vector(1 downto 0); -- GPIO[0] -> GN4124 GPIO8
-- GPIO[1] -> GN4124 GPIO9
GPIO : inout std_logic_vector(1 downto 0); -- GPIO[0] -> GN4124 GPIO8 -- T.B.V. datasheet write 9
-- GPIO[1] -> GN4124 GPIO9 -- T.B.V. datasheet write 9
-- PCIe to Local [Inbound Data] - RX
P2L_RDY : out std_logic; -- Rx Buffer Full Flag
P2L_CLKn : in std_logic; -- Receiver Source Synchronous Clock-
......@@ -475,7 +480,7 @@ architecture rtl of wr_nic_top is
end component;
-- DIO core
component wrsw_dio
component xwrsw_dio
generic (
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD
......@@ -866,9 +871,9 @@ begin
p_rd_d_rdy_i => P_RD_D_RDY,
tx_error_i => TX_ERROR,
dma_irq_o => open, -- T.B.D. Check it is ok
dma_irq_o => open,
irq_p_i => vic_irq,
irq_p_o => GPIO(0),
irq_p_o => GPIO(1), -- T.B.D. Check if GPIO is 1 or 0
dma_reg_clk_i => clk_sys, -- Look, many signals just take default values if not used
......@@ -1153,7 +1158,7 @@ begin
-----------------------------------
-- DIO core
-----------------------------------
U_dio_core : wrsw_dio
U_dio_core : xwrsw_dio
generic map (
g_interface_mode => PIPELINED,
g_address_granularity => BYTE)
......
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