Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
SPEC7
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
5
Issues
5
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Projects
SPEC7
Commits
b6b7d9c2
Commit
b6b7d9c2
authored
Mar 27, 2024
by
Pascal Bos
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed issue with hours > 15, added an extra bit.
parent
77ad7376
Pipeline
#5219
failed with stage
in 3 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
80 deletions
+80
-80
wr_irigb_conv.vhd
hdl/top/spec7_ref_design/wr_irigb_conv.vhd
+80
-80
No files found.
hdl/top/spec7_ref_design/wr_irigb_conv.vhd
View file @
b6b7d9c2
...
...
@@ -12,9 +12,9 @@
-- Last update: 2021-05-04
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: A module that takes the TAI signal from white rabbit and
-- Description: A module that takes the TAI signal from white rabbit and
-- converts it into IRIG_B data. The PR signal is in sync with the PPS.
--
--
-------------------------------------------------------------------------------
-- Copyright (c) 2021 Nikhef
-------------------------------------------------------------------------------
...
...
@@ -46,12 +46,12 @@ entity wr_irigb_conv is
generic
(
clk_freq
:
natural
:
=
125000000
);
Port
(
Port
(
clk_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
pps_i
:
in
std_logic
;
irig_b_o
:
out
std_logic
;
irig_b_ctrl_i
:
in
std_logic_vector
(
17
downto
0
)
:
=
(
others
=>
'0'
);
irig_b_ctrl_i
:
in
std_logic_vector
(
17
downto
0
)
:
=
(
others
=>
'0'
);
tm_time_valid_i
:
in
std_logic
;
tm_tai_i
:
in
std_logic_vector
(
39
downto
0
)
);
...
...
@@ -64,42 +64,42 @@ architecture Behavioral of wr_irigb_conv is
signal
pps_trigger
:
std_logic
;
type
state_type_irig
is
(
IDLE
,
PR
,
SEC
,
P1
,
MIN
,
P2
,
HOUR
,
P3
,
DAY_L
,
P4
,
DAY_H
,
P5
,
YEAR
,
P6
,
CTRL_1
,
P7
,
CTRL_2
,
P8
,
SBS_L
,
P9
,
SBS_H
,
P0
,
WAIT_FOR_PPS
);
signal
prs
,
nxt
:
state_type_irig
;
type
divisors_type
is
array
(
0
to
4
)
of
std_logic_vector
(
23
downto
0
);
type
divideds_type
is
array
(
0
to
4
)
of
std_logic_vector
(
39
downto
0
);
type
quotients_type
is
array
(
0
to
4
)
of
std_logic_vector
(
39
downto
0
);
type
quotients_type
is
array
(
0
to
4
)
of
std_logic_vector
(
39
downto
0
);
type
remainders_type
is
array
(
0
to
4
)
of
std_logic_vector
(
19
downto
0
);
constant
divisors
:
divisors_type
:
=
(
x"00003c"
,
--60 seconds in minute
x"00003c"
,
--60 minutes in hour
x"000018"
,
--24 hours in day
x"0005b5"
,
--365.25*4 days in 4 years
x"015180"
);
--seconds in a day
signal
divideds
:
divideds_type
;
signal
quotients
:
quotients_type
;
signal
remainders
:
remainders_type
;
signal
divideds
:
divideds_type
;
signal
quotients
:
quotients_type
;
signal
remainders
:
remainders_type
;
--signal divider_pipe_valids : std_logic_vector(0 to 5);
signal
divider_input_valids
:
std_logic_vector
(
0
to
5
);
signal
divider_output_valids
:
std_logic_vector
(
0
to
5
);
signal
start_dividers
:
std_logic
;
signal
seconds
:
std_logic_vector
(
5
downto
0
);
signal
minutes
:
std_logic_vector
(
5
downto
0
);
signal
hours
:
std_logic_vector
(
3
downto
0
);
signal
hours
:
std_logic_vector
(
4
downto
0
);
signal
days
:
std_logic_vector
(
8
downto
0
);
signal
years
:
std_logic_vector
(
39
downto
0
);
--should outlast the sun
signal
sbs
:
std_logic_vector
(
17
downto
0
);
signal
enable_bcd_conv
:
std_logic
;
--all bcd signals are 4bits * amount * of digits + 1 index marker
signal
seconds_bcd
:
std_logic_vector
(
7
downto
0
);
signal
minutes_bcd
:
std_logic_vector
(
8
downto
0
);
signal
hours_bcd
:
std_logic_vector
(
8
downto
0
);
signal
days_bcd
:
std_logic_vector
(
17
downto
0
);
signal
years_bcd
:
std_logic_vector
(
8
downto
0
);
signal
years_bcd
:
std_logic_vector
(
8
downto
0
);
signal
days_bcd_tdata_2
:
std_logic_vector
(
23
downto
0
);
signal
years_bcd_tdata
:
std_logic_vector
(
23
DOWNTO
0
);
...
...
@@ -108,24 +108,24 @@ architecture Behavioral of wr_irigb_conv is
signal
seconds_bcd_tdata
:
std_logic_vector
(
23
DOWNTO
0
);
signal
minutes_bcd_tdata
:
std_logic_vector
(
23
DOWNTO
0
);
signal
days_bcd_valid_1
:
std_logic
;
signal
bcd_ready
:
std_logic
;
type
irig_signal_type
is
(
ONE
,
ZERO
,
MARK
);
signal
irig_sig
:
irig_signal_type
;
signal
irig_counter_enable
:
std_logic
;
signal
irig_bit_comp
:
std_logic
;
signal
irig_bit_comp
:
std_logic
;
signal
irig_word_cnt
:
integer
range
0
to
8
;
constant
bit_time
:
integer
:
=
clk_freq
/
100
;
constant
bit_time
:
integer
:
=
clk_freq
/
100
;
constant
zero_time
:
natural
:
=
bit_time
/
5
;
constant
one_time
:
natural
:
=
bit_time
/
2
;
constant
mark_time
:
natural
:
=
bit_time
-
zero_time
;
signal
irig_cnt
:
integer
range
0
to
bit_time
;
signal
total_days
:
unsigned
(
39
downto
0
);
signal
total_days_valid
:
std_logic
;
COMPONENT
tai_divider
PORT
(
aclk
:
IN
STD_LOGIC
;
...
...
@@ -197,24 +197,24 @@ pps_trigger <= '1' when pps_i = '1' and pps_reg = '0' else '0';
-- this statement generates the 4 dividers for: Seconds&Minutes, Hours, Years and SBS, days is a bit more complicated --
-- it utilizes both the dividers "Answer/Quotient" and "Remainder", as can be seen below --
--
-- ___________ ___________ ___________ ___________
-- ___________ ___________ ___________ ___________
-- --------->| |-------------->| |-------------->| |--------------->| |-------->[current year since 1970]
-- Tai_Time | DIVIDE BY |(Answer) | DIVIDE BY |(Answer) | DIVIDE BY |(Answer) |Day in the |
-- Tai_Time | DIVIDE BY |(Answer) | DIVIDE BY |(Answer) | DIVIDE BY |(Answer) |Day in the |
-- (seconds) | 60 | | 60 | | 24 | |year engine|
-- | |------------ | |------------ | |------------ | see |------------
-- | |(Remainder) | | |(Remainder) | | |(Remainder) | | below | |
-- |___________| | |___________| | |___________| | |___________| |
-- V V V V
-- | |------------ | |------------ | |------------ | see |------------
-- | |(Remainder) | | |(Remainder) | | |(Remainder) | | below | |
-- |___________| | |___________| | |___________| | |___________| |
-- V V V V
-- [seconds in the current minute] [minutes in the current hour] [Hour in the current day] [Day in the current year - 1]
--
--
-- Day in the year Engine
-- ______ ___________ _________________
-- --------->| |---------------->| |-------------->| Multiply by 4 |------------------------------------------
-- Days | +365 | | DIVIDE BY |(Answer) | (bit shift 2) | _|_ _|_ _|_ _|_
-- Days | +365 | | DIVIDE BY |(Answer) | (bit shift 2) | _|_ _|_ _|_ _|_
-- | | | 1461 | |_________________| |+ 0|-->year|+ 1|-->year|+ 2|-->year|+ 3|-->year (+29 years) (to start in 2000 instead of 1969)
-- |______| | |------------ ________ |___| |___| |___| |___|
-- | |(Remainder) | / <365 |-----------0 | | |
-- |______| | |------------ ________ |___| |___| |___| |___|
-- | |(Remainder) | / <365 |-----------0 | | |
-- |___________| | / | | | | |
-- | | <730 |-----------|-----------0 | |
-- ->| | | | | |
...
...
@@ -225,7 +225,7 @@ pps_trigger <= '1' when pps_i = '1' and pps_reg = '0' else '0';
-- | | | |
-- _|__ _|__ _|__ _|___
-- |-0 |->days|-365|->days|-730|->days|-1095|->days (+1 for zero-day)
-- |____| |____| |____| |_____|
-- |____| |____| |____| |_____|
...
...
@@ -256,10 +256,10 @@ divider_input_valids(1) <= divider_output_valids(0);
divideds
(
1
)
<=
quotients
(
0
);
--#2 divde by 24 (hours)
divider_input_valids
(
2
)
<=
divider_output_valids
(
1
);
divideds
(
2
)
<=
quotients
(
1
);
divideds
(
2
)
<=
quotients
(
1
);
--#3 divde by 1461 (4 years)
divider_input_valids
(
3
)
<=
total_days_valid
;
divideds
(
3
)
<=
std_logic_vector
(
total_days
);
divideds
(
3
)
<=
std_logic_vector
(
total_days
);
--#4 divide by 15180 (seconds in day)
divider_input_valids
(
4
)
<=
start_dividers
;
divideds
(
4
)
<=
tai_time_s
;
...
...
@@ -291,7 +291,7 @@ begin
hours
<=
(
others
=>
'0'
);
days
<=
(
others
=>
'0'
);
years
<=
(
others
=>
'0'
);
sbs
<=
(
others
=>
'0'
);
sbs
<=
(
others
=>
'0'
);
enable_bcd_conv
<=
'0'
;
remaining_days
:
=
(
others
=>
'0'
);
block_4_years
:
=
(
others
=>
'0'
);
...
...
@@ -307,7 +307,7 @@ begin
all_rdy
(
1
)
:
=
'1'
;
end
if
;
if
divider_output_valids
(
2
)
=
'1'
then
--latch hours
hours
<=
remainders
(
2
)(
3
downto
0
);
hours
<=
remainders
(
2
)(
4
downto
0
);
all_rdy
(
2
)
:
=
'1'
;
end
if
;
if
divider_output_valids
(
3
)
=
'1'
then
--calculate days and years.
...
...
@@ -326,7 +326,7 @@ begin
years_buffer
:
=
(
block_4_years
(
37
downto
0
)
&
"00"
)
+
2
;
days
<=
std_logic_vector
(
remaining_days
(
8
downto
0
)
-1095
+
1
);
end
if
;
if
years_buffer
>=
30
then
--Check if is before the year 2000 or after.
if
years_buffer
>=
30
then
--Check if is before the year 2000 or after.
years_buffer
:
=
years_buffer
-
30
;
else
years_buffer
:
=
years_buffer
+
70
;
...
...
@@ -363,18 +363,18 @@ begin
end
if
;
end
if
;
end
process
irig_counter
;
irig_bit_comp
<=
'1'
when
irig_cnt
=
bit_time
-1
else
'0'
;
irig_bit_comp
<=
'1'
when
irig_cnt
=
bit_time
-1
else
'0'
;
--the driver of the irig_b outbut signal
--this is combinatoric to ensure a same-clock cycle start with the pps.
irig_b_o
<=
pps_i
when
(
prs
=
IDLE
or
prs
=
WAIT_FOR_PPS
)
else
'0'
when
(
rst_n_i
=
'0'
)
or
(
irig_cnt
>
mark_time
)
irig_b_o
<=
pps_i
when
(
prs
=
IDLE
or
prs
=
WAIT_FOR_PPS
)
else
'0'
when
(
rst_n_i
=
'0'
)
or
(
irig_cnt
>
mark_time
)
or
(
irig_cnt
>
one_time
and
irig_sig
=
ONE
)
or
(
irig_cnt
>
zero_time
and
irig_sig
=
ZERO
)
or
(
irig_cnt
>
zero_time
and
irig_sig
=
ZERO
)
else
'1'
;
--counts its position within the current irig_b word ( f.e.: 1,2,4,8,10,20,40)
--counts its position within the current irig_b word ( f.e.: 1,2,4,8,10,20,40)
word_counter
:
process
(
clk_i
,
rst_n_i
)
is
begin
if
rst_n_i
=
'0'
then
...
...
@@ -399,7 +399,7 @@ begin
end
if
;
end
process
state_register
;
next_state_decoder
:
process
(
prs
,
rst_n_i
,
pps_trigger
,
irig_word_cnt
,
irig_bit_comp
,
irig_cnt
)
is
next_state_decoder
:
process
(
prs
,
rst_n_i
,
pps_trigger
,
irig_word_cnt
,
irig_bit_comp
,
irig_cnt
)
is
begin
if
rst_n_i
=
'0'
then
nxt
<=
IDLE
;
...
...
@@ -407,7 +407,7 @@ begin
nxt
<=
PR
;
else
case
prs
is
when
IDLE
=>
when
IDLE
=>
nxt
<=
IDLE
;
-- stay here until pps_trigger jumps to PR.
when
PR
=>
if
irig_bit_comp
=
'1'
then
...
...
@@ -415,7 +415,7 @@ begin
else
nxt
<=
PR
;
end
if
;
when
SEC
=>
when
SEC
=>
if
irig_word_cnt
>=
7
and
irig_bit_comp
=
'1'
then
--checks if the last bit has been send
nxt
<=
P1
;
else
...
...
@@ -427,13 +427,13 @@ begin
else
nxt
<=
P1
;
end
if
;
when
MIN
=>
when
MIN
=>
if
irig_word_cnt
>=
8
and
irig_bit_comp
=
'1'
then
nxt
<=
P2
;
else
nxt
<=
MIN
;
end
if
;
when
P2
=>
end
if
;
when
P2
=>
if
irig_bit_comp
=
'1'
then
nxt
<=
HOUR
;
else
...
...
@@ -444,8 +444,8 @@ begin
nxt
<=
P3
;
else
nxt
<=
HOUR
;
end
if
;
when
P3
=>
end
if
;
when
P3
=>
if
irig_bit_comp
=
'1'
then
nxt
<=
DAY_L
;
else
...
...
@@ -487,7 +487,7 @@ begin
else
nxt
<=
P6
;
end
if
;
when
CTRL_1
=>
when
CTRL_1
=>
if
irig_word_cnt
>=
8
and
irig_bit_comp
=
'1'
then
nxt
<=
P7
;
else
...
...
@@ -541,18 +541,18 @@ begin
end
if
;
end
process
next_state_decoder
;
output_decoder
:
process
(
prs
,
irig_word_cnt
,
seconds_bcd
,
minutes_bcd
,
hours_bcd
,
days_bcd
,
years_bcd
,
irig_b_ctrl_s
,
sbs
)
is
output_decoder
:
process
(
prs
,
irig_word_cnt
,
seconds_bcd
,
minutes_bcd
,
hours_bcd
,
days_bcd
,
years_bcd
,
irig_b_ctrl_s
,
sbs
)
is
variable
irig_bit
:
std_logic
;
variable
irig_mark
:
std_logic
;
begin
irig_mark
:
=
'0'
;
irig_bit
:
=
'0'
;
case
prs
is
when
IDLE
|
PR
|
P1
|
P2
|
P3
|
P4
|
P5
|
P6
|
P7
|
P8
|
P9
|
P0
|
WAIT_FOR_PPS
=>
case
prs
is
when
IDLE
|
PR
|
P1
|
P2
|
P3
|
P4
|
P5
|
P6
|
P7
|
P8
|
P9
|
P0
|
WAIT_FOR_PPS
=>
irig_mark
:
=
'1'
;
-- All these states are MARK signals.
when
SEC
=>
when
SEC
=>
irig_bit
:
=
seconds_bcd
(
irig_word_cnt
);
when
MIN
=>
irig_bit
:
=
minutes_bcd
(
irig_word_cnt
);
...
...
@@ -571,9 +571,9 @@ begin
when
SBS_L
=>
irig_bit
:
=
sbs
(
irig_word_cnt
);
when
SBS_H
=>
irig_bit
:
=
sbs
(
irig_word_cnt
+
9
);
irig_bit
:
=
sbs
(
irig_word_cnt
+
9
);
end
case
;
if
irig_mark
=
'1'
then
irig_sig
<=
MARK
;
elsif
irig_bit
=
'1'
then
...
...
@@ -584,14 +584,14 @@ begin
end
process
output_decoder
;
--The divide-by-ten dividers to convert binary values into bcd values
-- ___________
-- ___________
-- --------->| |---------> 4
-- Value | DIVIDE BY | (Answer)
-- (binary) | 10 |
-- [f.e: 42] | |---------> 2
-- | | (Remainder)
-- |___________|
--
-- Value | DIVIDE BY | (Answer)
-- (binary) | 10 |
-- [f.e: 42] | |---------> 2
-- | | (Remainder)
-- |___________|
--
--The diveder for "days" has an additional divide-by-100 divider because there are more then 99 days in a year.
seconds_bcd_divider
:
bcd_divider
PORT
MAP
(
...
...
@@ -608,7 +608,7 @@ seconds_bcd_divider : bcd_divider
);
--all the bcd data has some '0' inserted between then to separate decimal and unit, as is requierd by IRIG
seconds_bcd
<=
seconds_bcd_tdata
(
10
downto
8
)
&
'0'
&
seconds_bcd_tdata
(
3
downto
0
);
minutes_bcd_divider
:
bcd_divider
PORT
MAP
(
aclk
=>
clk_i
,
...
...
@@ -623,8 +623,8 @@ minutes_bcd_divider : bcd_divider
m_axis_dout_tdata
=>
minutes_bcd_tdata
);
minutes_bcd
<=
'0'
&
minutes_bcd_tdata
(
10
downto
8
)
&
'0'
&
minutes_bcd_tdata
(
3
downto
0
);
hours_bcd_divider
:
bcd_divider
PORT
MAP
(
aclk
=>
clk_i
,
...
...
@@ -633,14 +633,14 @@ hours_bcd_divider : bcd_divider
s_axis_divisor_tdata
=>
x"0A"
,
s_axis_dividend_tvalid
=>
enable_bcd_conv
,
s_axis_dividend_tready
=>
open
,
s_axis_dividend_tdata
(
15
downto
4
)
=>
(
others
=>
'0'
),
s_axis_dividend_tdata
(
3
downto
0
)
=>
hours
,
s_axis_dividend_tdata
(
15
downto
5
)
=>
(
others
=>
'0'
),
s_axis_dividend_tdata
(
4
downto
0
)
=>
hours
,
m_axis_dout_tvalid
=>
open
,
m_axis_dout_tdata
=>
hours_bcd_tdata
);
hours_bcd
<=
"00"
&
hours_bcd_tdata
(
9
downto
8
)
&
'0'
&
hours_bcd_tdata
(
3
downto
0
);
years_bcd_divider
:
bcd_divider
PORT
MAP
(
aclk
=>
clk_i
,
...
...
@@ -668,21 +668,21 @@ days_bcd_divider_1 : bcd_divider
m_axis_dout_tvalid
=>
days_bcd_valid_1
,
m_axis_dout_tdata
=>
days_bcd_tdata_2
);
days_bcd_divider_2
:
bcd_divider
PORT
MAP
(
aclk
=>
clk_i
,
s_axis_divisor_tvalid
=>
days_bcd_valid_1
,
s_axis_divisor_tready
=>
open
,
s_axis_divisor_tdata
=>
x"0A"
,
s_axis_divisor_tdata
=>
x"0A"
,
s_axis_dividend_tvalid
=>
days_bcd_valid_1
,
s_axis_dividend_tready
=>
open
,
s_axis_dividend_tdata
(
15
downto
8
)
=>
(
others
=>
'0'
),
s_axis_dividend_tdata
(
7
downto
0
)
=>
days_bcd_tdata_2
(
7
downto
0
),
m_axis_dout_tvalid
=>
bcd_ready
,
m_axis_dout_tdata
=>
days_bcd_tdata_1
);
);
days_bcd
<=
"0000000"
&
days_bcd_tdata_2
(
9
downto
8
)
&
days_bcd_tdata_1
(
11
downto
8
)
&
'0'
&
days_bcd_tdata_1
(
3
downto
0
);
end
Behavioral
;
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