Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC DIO 5ch TTL a
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
6
Issues
6
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FMC DIO 5ch TTL a
Commits
1da5cbfa
Commit
1da5cbfa
authored
Jul 09, 2012
by
Javier Díaz
Committed by
Miguel Jimenez Lopez
Apr 03, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new register for controlling pulse_length and trigger ready interrupts
parent
6c4814e0
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
3993 additions
and
1247 deletions
+3993
-1247
Manifest.py
modules/wrsw_dio/Manifest.py
+5
-2
immed_pulse_counter.vhd
modules/wrsw_dio/immed_pulse_counter.vhd
+111
-0
pulse_gen_pl.vhd
modules/wrsw_dio/pulse_gen_pl.vhd
+224
-0
wrsw_dio.vhd
modules/wrsw_dio/wrsw_dio.vhd
+154
-91
wrsw_dio.wb
modules/wrsw_dio/wrsw_dio.wb
+137
-12
wrsw_dio_wb.htm
modules/wrsw_dio/wrsw_dio_wb.htm
+3147
-1012
wrsw_dio_wb.vhd
modules/wrsw_dio/wrsw_dio_wb.vhd
+215
-130
No files found.
modules/wrsw_dio/Manifest.py
View file @
1da5cbfa
files
=
[
"wrsw_dio_wb.vhd"
,
"wrsw_dio.vhd"
,
"dummy_time.vhd"
]
"wrsw_dio.vhd"
,
"pulse_gen_pl.vhd"
,
"immed_pulse_counter.vhd"
,
"dummy_time.vhd"
]
modules/wrsw_dio/immed_pulse_counter.vhd
0 → 100644
View file @
1da5cbfa
-------------------------------------------------------------------------------
-- Entity: immed_pulse counter
-- File: immed_pulse counter.vhd
-- Description: a simple synchronous output based on strobe inputs that produces a N-ticks
-- length pulse.
-- Author: Javier Díaz (jdiaz@atc.ugr.es)
-- Date: 9 July 2012
-- Version: 0.01
-- Properties:
-- TBD
-- Todo:
-- TBD
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- -----------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-- for more details. You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
entity
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
immed_pulse_counter
;
architecture
rtl
of
immed_pulse_counter
is
-- Internal registers to hold pulse duration
signal
counter
:
unsigned
(
pulse_length_width
-1
downto
0
);
-- Signals for states
type
counter_state
is
(
WAIT_ST
,
COUNTING
);
signal
state
:
counter_state
;
-- Aux
constant
zeros
:
std_logic_vector
(
pulse_length_width
-1
downto
0
)
:
=
(
others
=>
'0'
);
begin
-- architecture rtl
state_process
:
process
(
clk_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
counter
<=
(
others
=>
'0'
);
state
<=
WAIT_ST
;
elsif
rising_edge
(
clk_i
)
then
case
state
is
when
WAIT_ST
=>
if
pulse_start_i
=
'1'
and
pulse_length_i
/=
zeros
then
state
<=
COUNTING
;
counter
<=
unsigned
(
pulse_length_i
)
-1
;
else
state
<=
WAIT_ST
;
end
if
;
when
COUNTING
=>
if
(
counter
=
0
)
then
state
<=
WAIT_ST
;
else
state
<=
COUNTING
;
counter
<=
counter
-1
;
end
if
;
when
others
=>
state
<=
WAIT_ST
;
end
case
;
end
if
;
end
process
;
output_process
:
process
(
counter
,
state
)
begin
if
(
rst_n_i
=
'0'
)
then
pulse_output_o
<=
'0'
;
else
case
state
is
when
WAIT_ST
=>
pulse_output_o
<=
'0'
;
when
COUNTING
=>
pulse_output_o
<=
'1'
;
when
others
=>
pulse_output_o
<=
'0'
;
end
case
;
end
if
;
end
process
;
end
architecture
rtl
;
modules/wrsw_dio/pulse_gen_pl.vhd
0 → 100644
View file @
1da5cbfa
-------------------------------------------------------------------------------
-- Entity: pulse_gen_pl
-- File: pulse_gen_pl.vhd
-- Description: a pulse generator which produces a N-ticks length pulse in its
-- output when the time passed to it through a vector equals a
-- pre-programmed time.
-- Author: Javier Díaz (jdiaz@atc.ugr.es)
-- Based on the pulse_gen code of Javier Serrano (Javier.Serrano@cern.ch)
-- Date: 6 July 2012
-- Version: 0.02
-- Properties:
-- 1) After arming the trigger, new trigger values are not possible during for 13 clk_sys
-- ticks (208 ns for a 62,5 MHz clock, trig_ready_o<='0') --> not MESURABLE BY PC-SOFTWARE.
-- 2) Minimum of 7 clk_refs ticks are needed between trigger_time and its activation
-- (trig_valid_p1 = 1)
-- Trigger values can be overwritten when trig_ready_o without generate current assigment output
-- Todo: Substitute ready_for_trig process by a state machine.
-- Factor out synchronizer in a separate reusable block.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- -----------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-- for more details. You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
entity
pulse_gen_pl
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_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
pulse_gen_pl
;
architecture
rtl
of
pulse_gen_pl
is
-- Internal registers to hold trigger time and pulse duration
signal
trig_utc
,
trig_utc_ref
:
std_logic_vector
(
39
downto
0
);
signal
trig_cycles
,
trig_cycles_ref
:
std_logic_vector
(
27
downto
0
);
signal
pulse_length
,
pulse_length_ref
:
std_logic_vector
(
27
downto
0
);
-- Signals for the synchronizer
signal
trig_valid_sys_d1
,
trig_valid_sys_d2
:
std_logic
;
signal
rst_from_sync
,
rst_from_sync_d1
:
std_logic
;
signal
trig_valid_ref
:
std_logic_vector
(
2
downto
0
);
signal
trig_valid_back
:
std_logic_vector
(
2
downto
0
);
signal
trig_valid_ref_p1
:
std_logic
;
-- Aux
constant
zeros
:
std_logic_vector
(
27
downto
0
)
:
=
(
others
=>
'0'
);
signal
counter
:
unsigned
(
27
downto
0
);
begin
-- architecture rtl
-- Get trigger time into internal registers
trig_regs
:
process
(
clk_sys_i
)
is
begin
-- process trig_regs
if
clk_sys_i
'event
and
clk_sys_i
=
'1'
then
if
rst_n_i
=
'0'
then
trig_utc
<=
(
others
=>
'0'
);
trig_cycles
<=
(
others
=>
'0'
);
pulse_length
<=
(
others
=>
'0'
);
elsif
trig_valid_p1_i
=
'1'
then
if
trig_cycles_i
=
zeros
then
-- Delay 1 sys_ref tick time trigger to match pulse generation at exact time
-- (otherwise 1 clock cycle delay is presented)
trig_utc
<=
std_logic_vector
(
unsigned
(
trig_utc_i
)
-
to_unsigned
(
1
,
trig_utc
'length
));
trig_cycles
<=
(
others
=>
'1'
);
else
trig_utc
<=
trig_utc_i
;
trig_cycles
<=
std_logic_vector
(
unsigned
(
trig_cycles_i
)
-
to_unsigned
(
1
,
trig_cycles
'length
));
end
if
;
pulse_length
<=
pulse_length_i
;
end
if
;
end
if
;
end
process
trig_regs
;
-- Synchronizer to pass UTC register data to the reference clock domain
-- This synchronizer is made with the following four processes
-- First one FF with async reset, still in the clk_sys_i domain
sync_first_ff
:
process
(
clk_sys_i
,
rst_n_i
,
rst_from_sync
)
begin
if
rst_n_i
=
'0'
or
rst_from_sync
=
'1'
then
trig_valid_sys_d1
<=
'0'
;
elsif
clk_sys_i
'event
and
clk_sys_i
=
'1'
then
if
trig_valid_p1_i
=
'1'
then
trig_valid_sys_d1
<=
'1'
;
end
if
;
end
if
;
end
process
sync_first_ff
;
-- OK this is just for the UTC and cycle registers to have time to settle
-- in the pathological case of a very fast ref clock and very long
-- combinational delays in the UTC and cycle registers
delay_sys
:
process
(
clk_sys_i
)
begin
if
clk_sys_i
'event
and
clk_sys_i
=
'1'
then
trig_valid_sys_d2
<=
trig_valid_sys_d1
;
end
if
;
end
process
delay_sys
;
-- Then three FFs to take the strobe safely into the clk_ref_i domain
sync_ref
:
process
(
clk_ref_i
)
begin
if
clk_ref_i
'event
and
clk_ref_i
=
'1'
then
trig_valid_ref
<=
trig_valid_ref
(
1
downto
0
)
&
trig_valid_sys_d2
;
trig_valid_ref_p1
<=
trig_valid_ref
(
1
)
and
not
trig_valid_ref
(
2
);
end
if
;
end
process
sync_ref
;
-- And then back into the clk_sys_i domain
sync_sys
:
process
(
clk_sys_i
)
begin
if
clk_sys_i
'event
and
clk_sys_i
=
'1'
then
trig_valid_back
<=
trig_valid_back
(
1
downto
0
)
&
trig_valid_ref
(
2
);
rst_from_sync
<=
trig_valid_back
(
2
);
rst_from_sync_d1
<=
rst_from_sync
;
end
if
;
end
process
sync_sys
;
-- Now get the trig registers into the clk_ref_i domain
trig_regs_ref
:
process
(
clk_ref_i
)
begin
if
clk_ref_i
'event
and
clk_ref_i
=
'1'
then
if
trig_valid_ref_p1
=
'1'
then
trig_utc_ref
<=
trig_utc
;
trig_cycles_ref
<=
trig_cycles
;
pulse_length_ref
<=
pulse_length
;
end
if
;
end
if
;
end
process
trig_regs_ref
;
-- Notify we're ready to receive another trigger time write
-- Having the reset set trig_ready_o to '1' is a kludge.
-- A proper state machine would be better.
ready_for_trig
:
process
(
rst_n_i
,
clk_sys_i
)
begin
if
rst_n_i
=
'0'
then
trig_ready_o
<=
'1'
;
elsif
clk_sys_i
'event
and
clk_sys_i
=
'1'
then
if
trig_valid_p1_i
=
'1'
then
trig_ready_o
<=
'0'
;
elsif
rst_from_sync_d1
=
'1'
and
rst_from_sync
=
'0'
then
-- falling edge of reset_from_sync
trig_ready_o
<=
'1'
;
end
if
;
end
if
;
end
process
ready_for_trig
;
-- Produce output
-- Note rst_n_i is used as an async reset because it comes from the
-- clk_sys_i domain. Not the most elegant but it ensures no glitches
-- in the output after startup.
-- This block actually creates a pulse pulse_length ticks when the programmed
-- time matches the current time.
gen_out
:
process
(
rst_n_i
,
clk_ref_i
)
begin
if
rst_n_i
=
'0'
then
pulse_o
<=
'0'
;
elsif
clk_ref_i
'event
and
clk_ref_i
=
'1'
then
if
tm_time_valid_i
=
'0'
then
pulse_o
<=
'0'
;
elsif
tm_utc_i
=
trig_utc_ref
and
tm_cycles_i
=
trig_cycles_ref
and
pulse_length_ref
/=
zeros
then
pulse_o
<=
'1'
;
counter
<=
unsigned
(
pulse_length_ref
)
-1
;
elsif
counter
/=
0
then
counter
<=
counter
-1
;
else
pulse_o
<=
'0'
;
end
if
;
end
if
;
end
process
gen_out
;
end
architecture
rtl
;
modules/wrsw_dio/wrsw_dio.vhd
View file @
1da5cbfa
This diff is collapsed.
Click to expand it.
modules/wrsw_dio/wrsw_dio.wb
View file @
1da5cbfa
...
...
@@ -6,9 +6,9 @@ peripheral {
hdl_entity="wrsw_dio_wb";
---------------------------------------
-- FIFOS FOR INPUT EVENT TIME STAMPING
---------------------------------------
---------------------------------------
-------------
-- FIFOS
& INTERRUPTS
FOR INPUT EVENT TIME STAMPING
---------------------------------------
-------------
-- CHANNEL 0 INPUT FIFO
...
...
@@ -499,11 +499,14 @@ peripheral {
};
};
-----------------------------------------
-- OUTPUT CONFIGURATION/CONTROL REGISTERS
-----------------------------------------
--
Monostable/
Programmable output or GPIO selection
-- Programmable output or GPIO selection
reg {
name = "FMC-DIO output configuration register. ";
description = "It allows to choose a
Monostable/
programmable output or a standard GPIO output.";
description = "It allows to choose a programmable output or a standard GPIO output.";
prefix = "out";
field {
...
...
@@ -557,7 +560,7 @@ peripheral {
-- seconds trigger ready value. Readable-writable the bus, writable from the device.
reg {
name = "FMC-DIO
seconds-based
trigger is ready to accept a new trigger generation request";
name = "FMC-DIO
time
trigger is ready to accept a new trigger generation request";
description = "ready state, waiting new trigger commands for dio output.";
prefix = "trig";
...
...
@@ -572,45 +575,167 @@ peripheral {
};
};
-- DIO CHANNEL 0 trigger ready interrupt
irq {
name = "Channel 0 trigger ready interrupt";
description = "Interrupt active when time-programmable output channels accept new time trigger command.";
prefix = "trigger_ready_0";
trigger = LEVEL_1;
};
-- DIO CHANNEL 1 trigger ready interrupt
irq {
name = "Channel 1 trigger ready interrupt";
description = "Interrupt active when time-programmable output channels accept new time trigger command.";
prefix = "trigger_ready_1";
trigger = LEVEL_1;
};
-- DIO CHANNEL 2 trigger ready interrupt
irq {
name = "Channel 2 trigger ready interrupt";
description = "Interrupt active when time-programmable output channels accept new time trigger command.";
prefix = "trigger_ready_2";
trigger = LEVEL_1;
};
-- DIO CHANNEL 3 trigger ready interrupt
irq {
name = "Channel 3 trigger ready interrupt";
description = "Interrupt active when time-programmable output channels accept new time trigger command.";
prefix = "trigger_ready_3";
trigger = LEVEL_1;
};
-- DIO CHANNEL 4 trigger ready interrupt
irq {
name = "Channel 4 trigger ready interrupt";
description = "Interrupt active when time-programmable output channels accept new time trigger command.";
prefix = "trigger_ready_4";
trigger = LEVEL_1;
};
-- DIO CHANNEL 0: Programmable/immediate output pulse length . Readable-writable the bus, readble from the device.
reg {
name = "fmc-dio channel 0 Programmable/immediate output pulse length";
description = "Number of clk_ref clock ticks that output will be active";
prefix = "prog0_pulse";
field {
name = "number of ticks field for channel 0";
description = "ticks number";
prefix = "length";
type = SLV;
size = 28;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
-- DIO CHANNEL 1: Programmable/immediate output pulse length . Readable-writable the bus, readble from the device.
reg {
name = "fmc-dio channel 1 Programmable/immediate output pulse length";
description = "Number of clk_ref clock ticks that output will be active";
prefix = "prog1_pulse";
field {
name = "number of ticks field for channel 1";
description = "ticks number";
prefix = "length";
type = SLV;
size = 28;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
-- DIO CHANNEL 2: Programmable/immediate output pulse length . Readable-writable the bus, readble from the device.
reg {
name = "fmc-dio channel 2 Programmable/immediate output pulse length";
description = "Number of clk_ref clock ticks that output will be active";
prefix = "prog2_pulse";
field {
name = "number of ticks field for channel 2";
description = "ticks number";
prefix = "length";
type = SLV;
size = 28;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
-- DIO CHANNEL 3: Programmable/immediate output pulse length . Readable-writable the bus, readble from the device.
reg {
name = "fmc-dio channel 3 Programmable/immediate output pulse length";
description = "Number of clk_ref clock ticks that output will be active";
prefix = "prog3_pulse";
field {
name = "number of ticks field for channel 3";
description = "ticks number";
prefix = "length";
type = SLV;
size = 28;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
-- DIO CHANNEL 4: Programmable/immediate output pulse length . Readable-writable the bus, readble from the device.
reg {
name = "fmc-dio channel 4 Programmable/immediate output pulse length";
description = "Number of clk_ref clock ticks that output will be active";
prefix = "prog4_pulse";
field {
name = "number of ticks field for channel 4";
description = "ticks number";
prefix = "length";
type = SLV;
size = 28;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
-----------------------------------------
-- IMMEDIATE OUTPUT REGISTERS
-----------------------------------------
-- Pulse generator.
reg {
name = "Pulse generate immediately";
description = "It is used to generate a pulse immediately";
prefix = "puls
_inmed
";
prefix = "puls
e
";
field {
name = "pulse_gen_now_0";
description = "It generates a pulse";
prefix = "
pul_in
m_0";
prefix = "
im
m_0";
type = MONOSTABLE;
clock = "clk_asyn_i";
};
field {
name = "pulse_gen_now_1";
description = "It generates a pulse";
prefix = "
pul_in
m_1";
prefix = "
im
m_1";
type = MONOSTABLE;
clock = "clk_asyn_i";
};
field {
name = "pulse_gen_now_2";
description = "It generates a pulse";
prefix = "
pul_in
m_2";
prefix = "
im
m_2";
type = MONOSTABLE;
clock = "clk_asyn_i";
};
field {
name = "pulse_gen_now_3";
description = "It generates a pulse";
prefix = "
pul_in
m_3";
prefix = "
im
m_3";
type = MONOSTABLE;
clock = "clk_asyn_i";
};
field {
name = "pulse_gen_now_4";
description = "It generates a pulse";
prefix = "
pul_in
m_4";
prefix = "
im
m_4";
type = MONOSTABLE;
clock = "clk_asyn_i";
};
...
...
modules/wrsw_dio/wrsw_dio_wb.htm
View file @
1da5cbfa
This diff is collapsed.
Click to expand it.
modules/wrsw_dio/wrsw_dio_wb.vhd
View file @
1da5cbfa
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment