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
9ce986ab
Commit
9ce986ab
authored
Oct 15, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adding code for top of the hispi decoder
parent
1b4f3f2c
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
186 additions
and
33 deletions
+186
-33
sens_hispi12l4.v
sensor/sens_hispi12l4.v
+144
-1
sens_hispi_lane.v
sensor/sens_hispi_lane.v
+36
-27
fifo_cross_clocks.v
util_modules/fifo_cross_clocks.v
+6
-5
No files found.
sensor/sens_hispi12l4.v
View file @
9ce986ab
...
@@ -43,6 +43,7 @@ module sens_hispi12l4#(
...
@@ -43,6 +43,7 @@ module sens_hispi12l4#(
parameter
SENS_SS_MODE
=
"CENTER_HIGH"
,
//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter
SENS_SS_MODE
=
"CENTER_HIGH"
,
//"CENTER_HIGH","CENTER_LOW","DOWN_HIGH","DOWN_LOW"
parameter
SENS_SS_MOD_PERIOD
=
10000
,
// integer 4000-40000 - SS modulation period in ns
parameter
SENS_SS_MOD_PERIOD
=
10000
,
// integer 4000-40000 - SS modulation period in ns
parameter
HISPI_MSB_FIRST
=
0
,
parameter
HISPI_NUMLANES
=
4
,
parameter
HISPI_NUMLANES
=
4
,
parameter
HISPI_CAPACITANCE
=
"DONT_CARE"
,
parameter
HISPI_CAPACITANCE
=
"DONT_CARE"
,
parameter
HISPI_DIFF_TERM
=
"TRUE"
,
parameter
HISPI_DIFF_TERM
=
"TRUE"
,
...
@@ -76,6 +77,7 @@ module sens_hispi12l4#(
...
@@ -76,6 +77,7 @@ module sens_hispi12l4#(
input
ld_idelay
,
// mclk synchronous set idealy value
input
ld_idelay
,
// mclk synchronous set idealy value
input
set_clk_phase
,
// mclk synchronous set idealy value
input
set_clk_phase
,
// mclk synchronous set idealy value
input
rst_mmcm
,
input
rst_mmcm
,
// input wait_all_lanes, // when 0 allow some lanes missing sync (for easier phase adjustment)
// MMCP output status
// MMCP output status
output
ps_rdy
,
// output
output
ps_rdy
,
// output
output
[
7
:
0
]
ps_out
,
// output[7:0] reg
output
[
7
:
0
]
ps_out
,
// output[7:0] reg
...
@@ -154,7 +156,148 @@ module sens_hispi12l4#(
...
@@ -154,7 +156,148 @@ module sens_hispi12l4#(
.
dout
(
sns_d
)
// output[15:0]
.
dout
(
sns_d
)
// output[15:0]
)
;
)
;
localparam
WAIT_ALL_LANES
=
8
;
// number of output pixel cycles to wait after the earliest lane
localparam
FIFO_DEPTH
=
4
;
wire
[
HISPI_NUMLANES
*
12
-
1
:
0
]
hispi_aligned
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
hispi_dv
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
hispi_embed
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
hispi_sof
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
hispi_eof
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
hispi_sol
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
hispi_eol
;
// TODO - try to make that something will be recorded even if some lanes are bad (to simplify phase adjust
// possibly - extra control bit (wait_all_lanes)
// use earliest SOF
reg
vact_ipclk
;
reg
[
1
:
0
]
vact_pclk_strt
;
wire
[
HISPI_NUMLANES
-
1
:
0
]
rd_run
;
reg
rd_line
;
// combine all lanes
reg
rd_line_r
;
wire
sol_all_dly
;
reg
[
HISPI_NUMLANES
-
1
:
0
]
rd_run_d
;
reg
sof_pclk
;
// wire [HISPI_NUMLANES-1:0] sol_pclk = rd_run & ~rd_run_d;
wire
sol_pclk
=
|
(
rd_run
&
~
rd_run_d
)
;
// possibly multi-cycle
reg
[
HISPI_NUMLANES
-
1
:
0
]
good_lanes
;
// lanes that started active line OK
reg
[
HISPI_NUMLANES
-
1
:
0
]
fifo_re
;
reg
[
HISPI_NUMLANES
-
1
:
0
]
fifo_re_r
;
reg
hact_r
;
wire
[
HISPI_NUMLANES
*
12
-
1
:
0
]
fifo_out
;
wire
hact_on
;
wire
hact_off
;
assign
hact_out
=
hact_r
;
always
@
(
posedge
ipclk
)
begin
if
(
irst
||
(
|
hispi_eof
[
i
]))
vact_ipclk
<=
0
;
// extend output if hact active
else
if
(
|
hispi_sof
)
vact_ipclk
<=
1
;
end
always
@
(
posedge
pclk
)
begin
vact_pclk_strt
<=
{
vact_pclk_strt
[
0
]
,
vact_ipclk
};
rd_run_d
<=
rd_run
;
sof_pclk
<=
vact_pclk_strt
[
0
]
&&
!
vact_pclk_strt
[
1
]
;
if
(
prst
||
sof_pclk
)
rd_line
<=
0
;
else
if
(
sol_pclk
)
rd_line
<=
1
;
else
rd_line
<=
rd_line
&
(
&
(
~
good_lanes
|
rd_run
))
;
// Off when first of the good lanes goes off
rd_line_r
<=
rd_line
;
if
(
sol_pclk
&&
!
rd_line
)
good_lanes
<=
~
rd_run
;
// should be off before start
else
if
(
sol_all_dly
)
good_lanes
<=
good_lanes
&
rd_run
;
// and now they should be on
fifo_re_r
<=
fifo_re
&
rd_run
;
// when data out is ready, mask if not running
// not using HISPI_NUMLANES here - fix? Will be 0 (not possible in hispi) when no data
pxd_out
<=
(
{
12
{
fifo_re_r
[
0
]
}}
&
fifo_out
[
0
*
12
+:
12
])
|
(
{
12
{
fifo_re_r
[
1
]
}}
&
fifo_out
[
1
*
12
+:
12
])
|
(
{
12
{
fifo_re_r
[
2
]
}}
&
fifo_out
[
2
*
12
+:
12
])
|
(
{
12
{
fifo_re_r
[
3
]
}}
&
fifo_out
[
3
*
12
+:
12
])
;
if
(
prst
)
fifo_re
<=
0
;
else
if
(
sol_pclk
||
(
rd_line
&&
fifo_re
[
HISPI_NUMLANES
-
1
]))
fifo_re
<=
1
;
else
fifo_re
<=
fifo_re
<<
1
;
if
(
prst
||
hact_off
)
hact_r
<=
0
;
else
if
(
hact_on
)
hact_r
<=
1
;
vact_out
<=
vact_pclk_strt
[
0
]
||
hact_r
;
end
dly_16
#(
.
WIDTH
(
1
)
)
dly_16_start_line_i
(
.
clk
(
pclk
)
,
// input
.
rst
(
1'b0
)
,
// input
.
dly
(
WAIT_ALL_LANES
)
,
// input[3:0]
.
din
(
rd_line
&&
!
rd_line_r
)
,
// input[0:0]
.
dout
(
sol_all_dly
)
// output[0:0]
)
;
dly_16
#(
.
WIDTH
(
1
)
)
dly_16_hact_on_i
(
.
clk
(
pclk
)
,
// input
.
rst
(
1'b0
)
,
// input
.
dly
(
2
)
,
// input[3:0]
.
din
(
sol_pclk
)
,
// input[0:0]
.
dout
(
hact_on
)
// output[0:0]
)
;
dly_16
#(
.
WIDTH
(
1
)
)
dly_16_hact_off_i
(
.
clk
(
pclk
)
,
// input
.
rst
(
1'b0
)
,
// input
.
dly
(
2
)
,
// input[3:0]
.
din
(
fifo_re
[
HISPI_NUMLANES
-
1
])
,
// input[0:0]
.
dout
(
hact_off
)
// output[0:0]
)
;
generate
genvar
i
;
for
(
i
=
0
;
i
<
4
;
i
=
i
+
1
)
begin
:
hispi_lane
sens_hispi_lane
#(
.
HISPI_MSB_FIRST
(
HISPI_MSB_FIRST
)
)
sens_hispi_lane_i
(
.
ipclk
(
ipclk
)
,
// input
.
irst
(
irst
)
,
// input
.
din
(
sns_d
[
4
*
i
+:
4
])
,
// input[3:0]
.
dout
(
hispi_aligned
[
12
*
i
+:
12
])
,
// output[3:0] reg
.
dv
(
hispi_dv
[
i
])
,
// output reg
.
embed
(
hispi_embed
[
i
])
,
// output reg
.
sof
(
hispi_sof
[
i
])
,
// output reg
.
eof
(
hispi_eof
[
i
])
,
// output reg
.
sol
(
hispi_sol
[
i
])
,
// output reg
.
eol
(
hispi_eol
[
i
])
// output reg
)
;
sens_hispi_fifo
#(
.
COUNT_START
(
7
)
,
.
DATA_WIDTH
(
12
)
,
.
DATA_DEPTH
(
FIFO_DEPTH
)
)
sens_hispi_fifo_i
(
.
ipclk
(
ipclk
)
,
// input
.
irst
(
irst
)
,
// input
.
we
(
hispi_dv
[
i
])
,
// input
.
sol
(
hispi_sol
[
i
])
,
// input
.
eol
(
hispi_eol
[
i
])
,
// input
.
din
(
hispi_aligned
[
12
*
i
+:
12
])
,
// input[11:0]
.
pclk
(
pclk
)
,
// input
.
prst
(
prst
)
,
// input
.
re
(
fifo_re
[
i
])
,
// input
.
dout
(
fifo_out
[
12
*
i
+:
12
])
,
// output[11:0] reg
.
run
(
rd_run
[
i
])
// output
)
;
end
endgenerate
endmodule
endmodule
sensor/sens_hispi_lane.v
View file @
9ce986ab
...
@@ -26,7 +26,7 @@ module sens_hispi_lane#(
...
@@ -26,7 +26,7 @@ module sens_hispi_lane#(
input
ipclk
,
// half HiSPi recovered clock (165 MHz for 660 bps of MT9F002)
input
ipclk
,
// half HiSPi recovered clock (165 MHz for 660 bps of MT9F002)
input
irst
,
// reset sync to ipclk
input
irst
,
// reset sync to ipclk
input
[
3
:
0
]
din
,
// @posedge ipclk, din[3] came first
input
[
3
:
0
]
din
,
// @posedge ipclk, din[3] came first
output
reg
[
3
:
0
]
dout
,
// data output, aligned (decide about bit order)
output
reg
[
11
:
0
]
dout
,
// 12-bit data output
output
reg
dv
,
// data valid - continuous marks line
output
reg
dv
,
// data valid - continuous marks line
output
reg
embed
,
// valid @sol and up through all dv
output
reg
embed
,
// valid @sol and up through all dv
output
reg
sof
,
// always before first sol - not instead of
output
reg
sof
,
// always before first sol - not instead of
...
@@ -40,7 +40,10 @@ module sens_hispi_lane#(
...
@@ -40,7 +40,10 @@ module sens_hispi_lane#(
// localparam [3:0] SYNC_EOL = 6;
// localparam [3:0] SYNC_EOL = 6;
localparam
[
3
:
0
]
SYNC_EMBED
=
HISPI_MSB_FIRST
?
4'h1
:
4'h8
;
// other nibble (bit 4)
localparam
[
3
:
0
]
SYNC_EMBED
=
HISPI_MSB_FIRST
?
4'h1
:
4'h8
;
// other nibble (bit 4)
localparam
SYNC_NIBBLE
=
HISPI_MSB_FIRST
?
2
:
0
;
// decode which nibble of the last sync word
localparam
LSB_INDEX
=
HISPI_MSB_FIRST
?
2
:
0
;
// nibble number in 12-bit word
localparam
MSB_INDEX
=
HISPI_MSB_FIRST
?
0
:
2
;
// nibble number in 12-bit word
reg
[
3
:
0
]
d_r
;
// rehistered input data
reg
[
3
:
0
]
d_r
;
// rehistered input data
wire
[
2
:
0
]
num_trail_0_w
;
// number of trailing 0-s in the last nibble
wire
[
2
:
0
]
num_trail_0_w
;
// number of trailing 0-s in the last nibble
...
@@ -64,7 +67,7 @@ module sens_hispi_lane#(
...
@@ -64,7 +67,7 @@ module sens_hispi_lane#(
// reg got_eol;
// reg got_eol;
reg
got_embed
;
reg
got_embed
;
reg
pre_dv
;
reg
[
2
:
0
]
pre_dv
;
wire
[
3
:
0
]
dout_w
;
wire
[
3
:
0
]
dout_w
;
wire
[
4
:
0
]
num_running_zeros_w
=
num_running_zeros
+
{
1'b0
,
num_lead_0_w
};
wire
[
4
:
0
]
num_running_zeros_w
=
num_running_zeros
+
{
1'b0
,
num_lead_0_w
};
wire
start_line
=
sync_decode
[
3
]
&&
(
got_sol
||
got_sof
)
;
wire
start_line
=
sync_decode
[
3
]
&&
(
got_sol
||
got_sof
)
;
...
@@ -120,34 +123,41 @@ module sens_hispi_lane#(
...
@@ -120,34 +123,41 @@ module sens_hispi_lane#(
else
sync_decode
<=
sync_decode
<<
1
;
else
sync_decode
<=
sync_decode
<<
1
;
if
(
got_sync
)
got_sof
<=
0
;
if
(
got_sync
)
got_sof
<=
0
;
else
if
(
sync_decode
[
SYNC_NIBBLE
]
&&
(
barrel
==
SYNC_SOF
))
got_sof
<=
1
;
else
if
(
sync_decode
[
LSB_INDEX
]
&&
(
barrel
==
SYNC_SOF
))
got_sof
<=
1
;
if
(
got_sync
)
got_eof
<=
0
;
if
(
got_sync
)
got_eof
<=
0
;
else
if
(
sync_decode
[
SYNC_NIBBLE
]
&&
(
barrel
==
SYNC_EOF
))
got_eof
<=
1
;
else
if
(
sync_decode
[
LSB_INDEX
]
&&
(
barrel
==
SYNC_EOF
))
got_eof
<=
1
;
if
(
got_sync
)
got_sol
<=
0
;
if
(
got_sync
)
got_sol
<=
0
;
else
if
(
sync_decode
[
SYNC_NIBBLE
]
&&
(
barrel
==
SYNC_SOL
))
got_sol
<=
1
;
else
if
(
sync_decode
[
LSB_INDEX
]
&&
(
barrel
==
SYNC_SOL
))
got_sol
<=
1
;
// if (got_sync) got_eol <= 0;
// if (got_sync) got_eol <= 0;
// else if (sync_decode[
SYNC_NIBBLE
] && (barrel == SYNC_EOL)) got_eol <= 1;
// else if (sync_decode[
LSB_INDEX
] && (barrel == SYNC_EOL)) got_eol <= 1;
if
(
got_sync
)
got_embed
<=
0
;
if
(
got_sync
)
got_embed
<=
0
;
else
if
(
sync_decode
[
1
]
&&
(
barrel
==
SYNC_EMBED
))
got_embed
<=
1
;
else
if
(
sync_decode
[
1
]
&&
(
barrel
==
SYNC_EMBED
))
got_embed
<=
1
;
if
(
irst
)
dout
<=
0
;
if
(
irst
)
dout
[
3
:
0
]
<=
0
;
else
dout
<=
dout_w
;
else
if
(
pre_dv
[
LSB_INDEX
])
dout
[
3
:
0
]
<=
dout_w
;
if
(
irst
)
dout
[
7
:
4
]
<=
0
;
else
if
(
pre_dv
[
1
])
dout
[
7
:
4
]
<=
dout_w
;
if
(
irst
)
dout
[
11
:
8
]
<=
0
;
else
if
(
pre_dv
[
MSB_INDEX
])
dout
[
11
:
8
]
<=
dout_w
;
if
(
irst
||
got_sync
)
pre_dv
<=
0
;
if
(
irst
||
got_sync
)
pre_dv
<=
0
;
else
if
(
start_line_d
)
pre_dv
<=
1
;
else
if
(
start_line_d
)
pre_dv
<=
1
;
else
pre_dv
<=
{
pre_dv
[
1
:
0
]
,
pre_dv
[
2
]
};
if
(
irst
)
dv
<=
0
;
if
(
irst
)
dv
<=
0
;
else
dv
<=
pre_dv
;
else
dv
<=
pre_dv
[
2
]
;
if
(
irst
)
sol
<=
0
;
if
(
irst
)
sol
<=
0
;
else
sol
<=
start_line_d
;
else
sol
<=
start_line_d
;
if
(
irst
)
eol
<=
0
;
if
(
irst
)
eol
<=
0
;
else
eol
<=
got_sync
&&
pre_dv
;
else
eol
<=
got_sync
&&
(
|
pre_dv
)
;
if
(
irst
)
sof
<=
0
;
if
(
irst
)
sof
<=
0
;
else
sof
<=
sync_decode
[
3
]
&&
got_sof
;
else
sof
<=
sync_decode
[
3
]
&&
got_sof
;
...
@@ -180,4 +190,3 @@ module sens_hispi_lane#(
...
@@ -180,4 +190,3 @@ module sens_hispi_lane#(
endmodule
endmodule
util_modules/fifo_cross_clocks.v
View file @
9ce986ab
...
@@ -82,12 +82,13 @@ module fifo_cross_clocks
...
@@ -82,12 +82,13 @@ module fifo_cross_clocks
end
end
always
@
(
posedge
rclk
or
posedge
rst
)
begin
always
@
(
posedge
rclk
or
posedge
rst
)
begin
if
(
rst
)
raddr
<=
0
;
// making rrst set FIFO to empty regardless of current waddr (write should be stopped)
else
if
(
rrst
)
raddr
<=
0
;
if
(
rst
)
raddr
<=
waddr
;
// 0;
else
if
(
rrst
)
raddr
<=
waddr
;
// 0;
else
if
(
re
)
raddr
<=
raddr_plus1
;
else
if
(
re
)
raddr
<=
raddr_plus1
;
if
(
rst
)
raddr_gray_top3
<=
0
;
if
(
rst
)
raddr_gray_top3
<=
waddr
[
DATA_DEPTH
-
1
-:
3
]
^
{
1'b0
,
waddr
[
DATA_DEPTH
-
1
-:
2
]
};
//
0;
else
if
(
rrst
)
raddr_gray_top3
<=
0
;
else
if
(
rrst
)
raddr_gray_top3
<=
waddr
[
DATA_DEPTH
-
1
-:
3
]
^
{
1'b0
,
waddr
[
DATA_DEPTH
-
1
-:
2
]
};
//
0;
else
if
(
re
)
raddr_gray_top3
<=
raddr_plus1_gray_top3
;
else
if
(
re
)
raddr_gray_top3
<=
raddr_plus1_gray_top3
;
end
end
...
...
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