Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
0f61407f
Commit
0f61407f
authored
Dec 13, 2017
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added DSP control and signal paths
parent
83f0444a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
179 additions
and
108 deletions
+179
-108
phase_rotator.v
dsp/phase_rotator.v
+179
-108
No files found.
dsp/phase_rotator.v
View file @
0f61407f
...
...
@@ -51,7 +51,7 @@ module phase_rotator#(
input
signed
[
SHIFT_WIDTH
-
1
:
0
]
shift_h
,
//!< subpixel shift horizontal
input
signed
[
SHIFT_WIDTH
-
1
:
0
]
shift_v
,
//!< subpixel shift vertical
// input data CC,CS,SC,SS in column scan order (matching DTT)
input
signed
[
FD_WIDTH
-
1
:
0
]
fd_din
,
//!< frequency domain data in
input
signed
[
FD_WIDTH
-
1
:
0
]
fd_din
,
//!< frequency domain data in
, LATENCY=3 from start
output
reg
signed
[
FD_WIDTH
-
1
:
0
]
fd_out
,
//!< frequency domain data in
output
reg
pre_first_out
,
//!< 1 cycle before output data valid
output
reg
fd_dv
//!< output data valid
...
...
@@ -64,21 +64,16 @@ module phase_rotator#(
// Signed subpixel shifts in the range [-0.5,0.5) are converted to sign and [0,0.5] and both limits are fit to the same slot as
// the shift -0.5 : cos((i+0.5)/16*pi), -sin((i+0.5)/16*pi) for i=0..7 is symmetrical around the center (odd for sine, even - cosine)
// ROM input MSB - 0- cos, 1 - sin, 3 LSB s - index (0..7). Signs for cos and sin are passed to DSPs
// shift i ROM A[8:3] ROM A[2:0] sign cos sign sin
// 1000000 (-0.5) 000 0 000 0 1
// 001 0 001 0 1
// 010 0 010 0 1
// 011 0 011 0 1
// 100 0 011 1 1
// 101 0 010 1 1
// 110 0 001 1 1
// 111 0 000 1 1
// shift i sin ROM[9] ROM A[8:3] ROM A[2:0] sign cos sign sin
// 1000000 (-0.5) nnn 0 1 0 ~nnn 0 1
// nnn 1 1 0 nnn 0 1
//
// 1xxxxxx (<0) nnn
-xxxxxx nnn 0 1
// 1xxxxxx (<0) nnn
s s
-xxxxxx nnn 0 1
//
// 0000000 (==0) nnn 0 100 0 0
// 0000000 (==0) nnn 0 0 0 0 0 0
// nnn 1 0 0 1 0 0
//
// 0xxxxxx (>0) nnn
xxxxxx nnn 0 0
// 0xxxxxx (>0) nnn
s s
xxxxxx nnn 0 0
reg
[
5
:
0
]
start_d
;
// delayed versions of start (TODO: adjust length)
reg
[
7
:
0
]
cntr_h
;
// input sample counter
...
...
@@ -87,7 +82,7 @@ module phase_rotator#(
wire
run_v
;
wire
run_hv
=
run_h
||
run_v
;
reg
[
2
:
0
]
hv_index
;
// horizontal/vertical index
reg
[
1
:
0
]
hv
_phase
;
//
// reg [16:0] dsp
_phase; //
reg
hv_sin
;
// 0 - cos, 1 - sin
reg
[
SHIFT_WIDTH
-
1
:
0
]
shift_hr
;
...
...
@@ -95,13 +90,16 @@ module phase_rotator#(
reg
[
SHIFT_WIDTH
-
1
:
0
]
shift_vr
;
reg
[
SHIFT_WIDTH
-
1
:
0
]
shift_hv
;
// combined horizonta and vertical shifts to match cntr_mux;
reg
sign_cs
;
// sign for cos / sin, feed to DSP
wire
sign_cs_d
;
// sign_cs delayed by 3 clocks
reg
[
1
:
0
]
sign_cs_r
;
// sign_cs delayed by 5 clocks
reg
[
SHIFT_WIDTH
-
2
:
0
]
rom_a_shift
;
// ~shift absolute value
reg
[
2
:
0
]
rom_a_indx
;
// rom index (hor/vert)
reg
rom_a_sin
;
// rom cos =0; sin = 1
wire
[
SHIFT_WIDTH
+
2
:
0
]
rom_a
=
{
rom_a_sin
,
rom_a_shift
,
rom_a_indx
};
wire
shift_ends_0
=
shift_hv
[
SHIFT_WIDTH
-
2
:
0
]
==
0
;
reg
[
1
:
0
]
rom_re_regen
;
reg
[
2
:
0
]
rom_re_regen
;
wire
signed
[
DSP_B_WIDTH
-
1
:
0
]
cos_sin_w
;
wire
mux_v
=
run_v
&&
cntr_v
[
1
]
;
always
@
(
posedge
clk
)
begin
if
(
rst
)
start_d
<=
0
;
...
...
@@ -109,31 +107,35 @@ module phase_rotator#(
if
(
start
)
shift_hr
<=
shift_h
;
if
(
start
)
shift_v0
<=
shift_v
;
if
(
start_d
[
5
])
shift_vr
<=
shift_v0
;
if
(
start_d
[
3
])
shift_vr
<=
shift_v0
;
if
(
rst
)
run_h
<=
0
;
else
if
(
start
_d
[
0
])
run_h
<=
1
;
else
if
(
start
)
run_h
<=
1
;
else
if
(
&
cntr_h
)
run_h
<=
0
;
if
(
!
run_h
)
cntr_h
<=
0
;
else
cntr_h
<=
cntr_h
+
1
;
if
(
!
run_hv
)
hv_phase
<=
0
;
else
hv_phase
<=
hv_phase
+
1
;
//
if (!run_hv) hv_phase <= 0;
//
else hv_phase <= hv_phase + 1;
// combine horizontal and vertical counters and shifts to feed to ROM
hv_index
<=
(
run_v
&&
cntr_v
[
1
])
?
cntr_v
[
4
:
2
]
:
cntr_h
[
7
:
5
]
;
// input data "down first" (transposed)
hv_sin
<=
(
run_v
&&
cntr_v
[
1
])
?
cntr_v
[
0
]
:
cntr_h
[
0
]
;
shift_hv
<=
(
run_v
&&
cntr_v
[
1
])
?
shift_vr
:
shift_hr
;
hv_index
<=
mux_v
?
cntr_v
[
4
:
2
]
:
cntr_h
[
7
:
5
]
;
// input data "down first" (transposed)
hv_sin
<=
mux_v
?
cntr_v
[
0
]
:
cntr_h
[
0
]
;
shift_hv
<=
mux_v
?
shift_vr
:
shift_hr
;
// convert index, shift to ROM address
rom_a_indx
<=
shift_ends_0
?
(
shift_hv
[
SHIFT_WIDTH
-
1
]
?{
1'b0
,
hv_index
[
2
]
?~
hv_index
[
1
:
0
]
:
hv_index
[
1
:
0
]
}:
3'h4
)
:
hv_index
;
rom_a_indx
<=
shift_ends_0
?
(
shift_hv
[
SHIFT_WIDTH
-
1
]
?
(
{
3
{~
hv_sin
}}
^
hv_index
)
:
+{
2'b0
,
hv_sin
}
)
:
hv_index
;
rom_a_shift
<=
shift_hv
[
SHIFT_WIDTH
-
1
]
?
-
shift_hv
[
SHIFT_WIDTH
-
2
:
0
]
:
shift_hv
[
SHIFT_WIDTH
-
2
:
0
]
;
rom_a_sin
<=
hv_sin
;
sign_cs
<=
shift_hv
[
SHIFT_WIDTH
-
1
]
&
(
hv_sin
|
(
shift_ends_0
&
hv_index
[
2
]))
;
rom_a_sin
<=
shift_ends_0
?
shift_hv
[
SHIFT_WIDTH
-
1
]
:
hv_sin
;
// sign_cs <= shift_hv[SHIFT_WIDTH-1] & ( hv_sin | (shift_ends_0 & hv_index[2]));
sign_cs
<=
shift_hv
[
SHIFT_WIDTH
-
1
]
&
hv_sin
;
rom_re_regen
<=
{
rom_re_regen
[
1
:
0
]
,
run_hv
};
rom_re_regen
<=
{
rom_re_regen
[
0
]
,
run_hv
};
sign_cs_r
<=
{
sign_cs_r
[
0
]
,
sign_cs_d
};
end
...
...
@@ -148,6 +150,18 @@ module phase_rotator#(
.
dout
(
{
run_v
,
cntr_v
}
)
// output[0:0]
)
;
dly_var
#(
.
WIDTH
(
1
)
,
.
DLY_WIDTH
(
4
)
)
dly_cntrv_i
(
.
clk
(
clk
)
,
// input
.
rst
(
rst
)
,
// input
.
dly
(
4'h2
)
,
// input[3:0]
.
din
(
sign_cs
)
,
// input[0:0]
.
dout
(
sign_cs_d
)
// output[0:0]
)
;
ram18tp_var_w_var_r
#(
.
REGISTERS_A
(
1
)
,
.
REGISTERS_B
(
1
)
,
...
...
@@ -160,8 +174,8 @@ module phase_rotator#(
.
clk_a
(
clk
)
,
// input
.
addr_a
(
rom_a
)
,
// input[9:0]
.
en_a
(
rom_re_regen
[
0
])
,
// input
.
regen_a
(
rom_re_regen
[
1
])
,
// input
.
en_a
(
rom_re_regen
[
1
])
,
// input
.
regen_a
(
rom_re_regen
[
2
])
,
// input
.
we_a
(
1'b0
)
,
// input
.
data_out_a
(
cos_sin_w
)
,
// output[17:0]
.
data_in_a
(
18'b0
)
,
// input[17:0]
...
...
@@ -174,6 +188,64 @@ module phase_rotator#(
.
data_in_b
(
18'b0
)
// input[17:0]
)
;
// Registers for DSP control
reg
ceb1_1
,
ceb1_2
,
ceb1_3
,
ceb1_4
;
reg
ceb2_1
,
ceb2_2
,
ceb2_3
,
ceb2_4
;
reg
selb_1
,
selb_2
,
selb_3
,
selb_4
;
wire
signed
[
DSP_A_WIDTH
-
1
:
0
]
ain_34
=
pout_1
[
DSP_P_WIDTH
-
1
-:
FD_WIDTH
]
;
// bit select from pout_1
wire
signed
[
DSP_A_WIDTH
-
1
:
0
]
din_34
=
pout_2
[
DSP_P_WIDTH
-
1
-:
FD_WIDTH
]
;
// bit select from pout_1
reg
cea1_1
,
cea1_2
,
cea1_3
,
cea1_4
;
reg
cea2_1
,
cea2_2
,
ced_3
,
ced_4
;
reg
sela_1
,
sela_2
,
end_3
,
end_4
;
reg
cead_1
,
cead_2
,
cead_3
,
cead_4
;
reg
negm_1
,
negm_2
,
negm_3
,
negm_4
;
reg
accum_1
,
accum_2
,
accum_3
,
accum_4
;
wire
signed
[
DSP_P_WIDTH
-
1
:
0
]
pout_1
;
wire
signed
[
DSP_P_WIDTH
-
1
:
0
]
pout_2
;
wire
signed
[
DSP_P_WIDTH
-
1
:
0
]
pout_3
;
wire
signed
[
DSP_P_WIDTH
-
1
:
0
]
pout_4
;
reg
omux_sel
;
wire
pre_dv
=
|
ph
[
16
:
13
]
;
reg
[
16
:
0
]
ph
;
// DSP pre phase,
always
@
(
posedge
clk
)
begin
if
(
rst
)
ph
<=
0
;
else
ph
<=
{
ph
[
15
:
0
]
,
run_h
&
~
cntr_h
[
0
]
&
cntr_h
[
1
]
};
cea1_1
<=
ph
[
0
]
;
cea2_1
<=
ph
[
2
]
;
cea1_2
<=
ph
[
1
]
;
cea2_2
<=
ph
[
3
]
;
ceb1_1
<=
ph
[
3
]
;
ceb2_1
<=
ph
[
2
]
;
ceb1_2
<=
ph
[
2
]
|
ph
[
3
]
;
ceb2_2
<=
ph
[
3
]
;
cead_1
<=
|
ph
[
5
:
2
]
;
cead_2
<=
|
ph
[
6
:
3
]
;
// 1 cycle ahead
sela_1
<=
ph
[
2
]
|
ph
[
4
]
;
sela_2
<=
ph
[
3
]
|
ph
[
5
]
;
selb_1
<=
ph
[
2
]
|
ph
[
5
]
;
selb_2
<=
ph
[
3
]
|
ph
[
6
]
;
// 0 1 0 0
negm_1
<=
(
ph
[
3
]
^
sign_cs_d
)
|
(
~
ph
[
4
]
^
sign_cs_d
)
|
(
ph
[
5
]
^
sign_cs_r
[
1
])
|
(
ph
[
6
]
^
sign_cs_r
[
1
])
;
negm_2
<=
(
ph
[
4
]
^
sign_cs_d
)
|
(
~
ph
[
5
]
^
sign_cs_d
)
|
(
ph
[
6
]
^
sign_cs_r
[
1
])
|
(
ph
[
7
]
^
sign_cs_r
[
1
])
;
accum_1
<=
ph
[
4
]
|
ph
[
6
]
;
accum_2
<=
ph
[
5
]
|
ph
[
7
]
;
// vertical shift DSPs
cea1_3
<=
ph
[
6
]
;
ced_3
<=
ph
[
7
]
;
cea1_4
<=
ph
[
8
]
;
ced_4
<=
ph
[
9
]
;
ceb1_3
<=
ph
[
9
]
;
ceb2_3
<=
ph
[
8
]
;
ceb1_4
<=
ph
[
8
]
|
ph
[
9
]
;
ceb2_4
<=
ph
[
9
]
;
cead_3
<=
|
ph
[
11
:
8
]
;
cead_4
<=
|
ph
[
12
:
9
]
;
// 1 cycle ahead
end_3
<=
ph
[
10
]
|
ph
[
8
]
;
end_4
<=
ph
[
11
]
|
ph
[
9
]
;
selb_3
<=
ph
[
8
]
|
ph
[
11
]
;
selb_4
<=
ph
[
9
]
|
ph
[
12
]
;
negm_4
<=
(
ph
[
9
]
^
sign_cs_d
)
|
(
~
ph
[
10
]
^
sign_cs_d
)
|
(
ph
[
11
]
^
sign_cs_r
[
1
])
|
(
ph
[
12
]
^
sign_cs_r
[
1
])
;
negm_3
<=
(
ph
[
10
]
^
sign_cs_d
)
|
(
~
ph
[
11
]
^
sign_cs_d
)
|
(
ph
[
12
]
^
sign_cs_r
[
1
])
|
(
ph
[
13
]
^
sign_cs_r
[
1
])
;
accum_3
<=
ph
[
10
]
|
ph
[
12
]
;
accum_4
<=
ph
[
11
]
|
ph
[
13
]
;
omux_sel
<=
ph
[
13
]
|
ph
[
15
]
;
fd_dv
<=
pre_dv
;
if
(
pre_dv
)
fd_out
<=
omux_sel
?
pout_4
[
DSP_P_WIDTH
-
1
-:
FD_WIDTH
]
:
pout_3
[
DSP_P_WIDTH
-
1
-:
FD_WIDTH
]
;
pre_first_out
<=
ph
[
12
]
;
end
/*
output reg signed [FD_WIDTH-1:0] fd_out, //!< frequency domain data in
*/
// horizontal shift stage
dsp_ma_preadd
#(
...
...
@@ -183,25 +255,25 @@ module phase_rotator#(
.
A_INPUT
(
"DIRECT"
)
,
.
B_INPUT
(
"DIRECT"
)
)
dsp_1_i
(
.
clk
()
,
// input
.
rst
()
,
// input
.
bin
(
)
,
// input[17:0] signed
.
ceb1
()
,
// input
.
ceb2
()
,
// input
.
selb
()
,
// input
.
ain
()
,
// input[24:0] signed
.
cea1
()
,
// input
.
cea2
()
,
// input
.
din
()
,
// input[24:0] signed
.
ced
()
,
// input
.
cead
()
,
// input
.
sela
()
,
// input
.
en_a
()
,
// input
.
en_d
()
,
// input
.
sub_a
()
,
// input
.
neg_m
()
,
// input
.
accum
()
,
// input
.
pout
()
// output[47:0] signed
.
clk
(
clk
)
,
// input
.
rst
(
rst
)
,
// input
.
bin
(
cos_sin_w
)
,
// input[17:0] signed
.
ceb1
(
ceb1_1
)
,
// input
.
ceb2
(
ceb2_1
)
,
// input
.
selb
(
selb_1
)
,
// input
.
ain
(
fd_din
)
,
// input[24:0] signed
.
cea1
(
cea1_1
)
,
// input
.
cea2
(
cea2_1
)
,
// input
.
din
(
25'b0
)
,
// input[24:0] signed
.
ced
(
1'b0
)
,
// input
.
cead
(
cead_1
)
,
// input
.
sela
(
sela_1
)
,
// input
.
en_a
(
1'b1
)
,
// input
.
en_d
(
1'b0
)
,
// input
.
sub_a
(
1'b0
)
,
// input
.
neg_m
(
negm_1
)
,
// input
.
accum
(
accum_1
)
,
// input
.
pout
(
pout_1
)
// output[47:0] signed
)
;
dsp_ma_preadd
#(
...
...
@@ -211,25 +283,25 @@ module phase_rotator#(
.
A_INPUT
(
"DIRECT"
)
,
.
B_INPUT
(
"CASCADE"
)
)
dsp_2_i
(
.
clk
()
,
// input
.
rst
()
,
// input
.
bin
(
)
,
// input[17:0] signed
.
ceb1
()
,
// input
.
ceb2
()
,
// input
.
selb
()
,
// input
.
ain
()
,
// input[24:0] signed
.
cea1
()
,
// input
.
cea2
()
,
// input
.
din
()
,
// input[24:0] signed
.
ced
()
,
// input
.
cead
()
,
// input
.
sela
()
,
// input
.
en_a
()
,
// input
.
en_d
()
,
// input
.
sub_a
()
,
// input
.
neg_m
()
,
// input
.
accum
()
,
// input
.
pout
()
// output[47:0] signed
.
clk
(
clk
)
,
// input
.
rst
(
rst
)
,
// input
.
bin
(
cos_sin_w
)
,
// input[17:0] signed
.
ceb1
(
ceb1_2
)
,
// input
.
ceb2
(
ceb2_2
)
,
// input
.
selb
(
selb_2
)
,
// input
.
ain
(
fd_din
)
,
// input[24:0] signed
.
cea1
(
cea1_2
)
,
// input
.
cea2
(
cea2_2
)
,
// input
.
din
(
25'b0
)
,
// input[24:0] signed
.
ced
(
1'b0
)
,
// input
.
cead
(
cead_2
)
,
// input
.
sela
(
sela_2
)
,
// input
.
en_a
(
1'b1
)
,
// input
.
en_d
(
1'b0
)
,
// input
.
sub_a
(
1'b0
)
,
// input
.
neg_m
(
negm_2
)
,
// input
.
accum
(
accum_2
)
,
// input
.
pout
(
pout_2
)
// output[47:0] signed
)
;
// vertical shift stage
...
...
@@ -241,25 +313,25 @@ module phase_rotator#(
.
A_INPUT
(
"DIRECT"
)
,
.
B_INPUT
(
"DIRECT"
)
)
dsp_3_i
(
.
clk
()
,
// input
.
rst
()
,
// input
.
bin
(
)
,
// input[17:0] signed
.
ceb1
()
,
// input
.
ceb2
()
,
// input
.
selb
()
,
// input
.
ain
()
,
// input[24:0] signed
.
cea1
()
,
// input
.
cea2
()
,
// input
.
din
()
,
// input[24:0] signed
.
ced
()
,
// input
.
cead
()
,
// input
.
sela
()
,
// input
.
en_a
()
,
// input
.
en_d
()
,
// input
.
sub_a
()
,
// input
.
neg_m
()
,
// input
.
accum
()
,
// input
.
pout
()
// output[47:0] signed
.
clk
(
clk
)
,
// input
.
rst
(
rst
)
,
// input
.
bin
(
cos_sin_w
)
,
// input[17:0] signed
.
ceb1
(
ceb1_3
)
,
// input
.
ceb2
(
ceb2_3
)
,
// input
.
selb
(
selb_3
)
,
// input
.
ain
(
ain_34
)
,
// input[24:0] signed
.
cea1
(
cea1_3
)
,
// input
.
cea2
(
1'b0
)
,
// input
.
din
(
din_34
)
,
// input[24:0] signed
.
ced
(
ced_3
)
,
// input
.
cead
(
cead_3
)
,
// input
.
sela
(
1'b0
)
,
// input
.
en_a
(
~
end_3
)
,
// input
.
en_d
(
end_3
)
,
// input
.
sub_a
(
1'b0
)
,
// input
.
neg_m
(
negm_3
)
,
// input
.
accum
(
accum_3
)
,
// input
.
pout
(
pout_3
)
// output[47:0] signed
)
;
dsp_ma_preadd
#(
...
...
@@ -269,27 +341,26 @@ module phase_rotator#(
.
A_INPUT
(
"DIRECT"
)
,
.
B_INPUT
(
"CASCADE"
)
)
dsp_4_i
(
.
clk
()
,
// input
.
rst
()
,
// input
.
bin
(
)
,
// input[17:0] signed
.
ceb1
()
,
// input
.
ceb2
()
,
// input
.
selb
()
,
// input
.
ain
()
,
// input[24:0] signed
.
cea1
()
,
// input
.
cea2
()
,
// input
.
din
()
,
// input[24:0] signed
.
ced
()
,
// input
.
cead
()
,
// input
.
sela
()
,
// input
.
en_a
()
,
// input
.
en_d
()
,
// input
.
sub_a
()
,
// input
.
neg_m
()
,
// input
.
accum
()
,
// input
.
pout
()
// output[47:0] signed
.
clk
(
clk
)
,
// input
.
rst
(
rst
)
,
// input
.
bin
(
cos_sin_w
)
,
// input[17:0] signed
.
ceb1
(
ceb1_4
)
,
// input
.
ceb2
(
ceb2_4
)
,
// input
.
selb
(
selb_4
)
,
// input
.
ain
(
ain_34
)
,
// input[24:0] signed
.
cea1
(
cea1_4
)
,
// input
.
cea2
(
1'b0
)
,
// input
.
din
(
din_34
)
,
// input[24:0] signed
.
ced
(
ced_4
)
,
// input
.
cead
(
cead_4
)
,
// input
.
sela
(
1'b0
)
,
// input
.
en_a
(
~
end_4
)
,
// input
.
en_d
(
end_4
)
,
// input
.
sub_a
(
1'b0
)
,
// input
.
neg_m
(
negm_4
)
,
// input
.
accum
(
accum_4
)
,
// input
.
pout
(
pout_4
)
// output[47:0] signed
)
;
endmodule
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