Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393_sata
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_sata
Commits
cb2fc48f
Commit
cb2fc48f
authored
Mar 13, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eliminating use of PLL with GTX
parent
36c295d8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
295 additions
and
405 deletions
+295
-405
.project
.project
+17
-17
gtx_wrap.v
host/gtx_wrap.v
+114
-312
sata_phy.v
host/sata_phy.v
+83
-69
system_defines.vh
system_defines.vh
+1
-1
top.v
top.v
+27
-6
select_clk_buf.v
x393/wrap/select_clk_buf.v
+53
-0
No files found.
.project
View file @
cb2fc48f
...
...
@@ -52,87 +52,87 @@
<link>
<name>
vivado_logs/VivadoBitstream.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoBitstream-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoOpt.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOpt-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoOptPhys.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPhys-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoOptPower.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoOptPower-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoPlace.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoPlace-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoRoute.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoRoute-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoSynthesis.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoSynthesis-20160312
231356578
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimimgSummaryReportImplemented.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportImplemented-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimimgSummaryReportSynthesis.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimimgSummaryReportSynthesis-20160312
231356578
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimingReportImplemented.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportImplemented-20160312
231527798
.log
</location>
</link>
<link>
<name>
vivado_logs/VivadoTimingReportSynthesis.log
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160312
151407716
.log
</location>
<location>
/home/andrey/git/x393_sata/vivado_logs/VivadoTimingReportSynthesis-20160312
231356578
.log
</location>
</link>
<link>
<name>
vivado_state/x393_sata-opt-phys.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160312
151407716
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-phys-20160312
231527798
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-opt-power.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160312
151407716
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-power-20160312
231527798
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-opt.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160312
151407716
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-opt-20160312
231527798
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-place.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160312
151407716
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-place-20160312
231527798
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-route.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160312
151407716
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-route-20160312
231527798
.dcp
</location>
</link>
<link>
<name>
vivado_state/x393_sata-synth.dcp
</name>
<type>
1
</type>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160312
151407716
.dcp
</location>
<location>
/home/andrey/git/x393_sata/vivado_state/x393_sata-synth-20160312
231356578
.dcp
</location>
</link>
</linkedResources>
</projectDescription>
host/gtx_wrap.v
View file @
cb2fc48f
...
...
@@ -84,7 +84,7 @@ module gtx_wrap #(
input
wire
txelecidle
,
output
wire
txp
,
output
wire
txn
,
output
wire
txoutclk
,
output
wire
txoutclk
,
// global clock
input
wire
txpcsreset
,
output
wire
txresetdone
,
input
wire
txcominit
,
...
...
@@ -108,7 +108,7 @@ module gtx_wrap #(
output
wire
[
1
:
0
]
txbufstatus
,
output
xclk
// just to measure frequency to set the local clock
output
xclk
// just to measure frequency to set the local clock
(global clock)
`ifdef
USE_DATASCOPE
// Datascope interface (write to memory that can be software-read)
...
...
@@ -144,17 +144,9 @@ wire rxresetdone_gtx;
wire
txresetdone_gtx
;
reg
wrap_rxreset_
;
reg
wrap_txreset_
;
`ifdef
OLD_ELASTIC
reg
rxresetdone_gtx_r
;
reg
txresetdone_gtx_r
;
// resets while PCS resets, active low
always
@
(
posedge
rxusrclk2
)
wrap_rxreset_
<=
rxuserrdy
&
rxresetdone_gtx_r
;
always
@
(
posedge
txusrclk2
)
wrap_txreset_
<=
txuserrdy
&
txresetdone_gtx_r
;
`else
// OLD_ELASTIC
// resets while PCS resets, active low
always
@
(
posedge
rxusrclk2
)
wrap_rxreset_
<=
rxuserrdy
&
rxresetdone_gtx
;
always
@
(
posedge
txusrclk2
)
wrap_txreset_
<=
txuserrdy
&
txresetdone_gtx
;
`endif
// OLD_ELASTIC
// resets while PCS resets, active low
always
@
(
posedge
rxusrclk2
)
wrap_rxreset_
<=
rxuserrdy
&
rxresetdone_gtx
;
always
@
(
posedge
txusrclk2
)
wrap_txreset_
<=
txuserrdy
&
txresetdone_gtx
;
wire
[
63
:
0
]
rxdata_gtx
;
wire
[
7
:
0
]
rxcharisk_gtx
;
wire
[
7
:
0
]
rxdisperr_gtx
;
...
...
@@ -561,220 +553,69 @@ gtx_10x8dec gtx_10x8dec(
wire
rxcomwakedet_gtx
;
wire
rxcominitdet_gtx
;
`ifdef
OLD_ELASTIC
// elastic buffer: transition from xclk to rxusrclk
wire
[
15
:
0
]
rxdata_els_out
;
wire
[
1
:
0
]
rxcharisk_els_out
;
wire
[
1
:
0
]
rxnotintable_els_out
;
wire
[
1
:
0
]
rxdisperr_els_out
;
wire
lword_strobe
;
wire
isaligned
;
wire
elastic_full
;
wire
elastic_empty
;
gtx_elastic
#(
.
DEPTH_LOG2
(
3
)
,
.
OFFSET
(
4
)
)
gtx_elastic
(
// .rst (~rx_clocks_aligned), // ~wrap_rxreset_),
.
rst
(
~
wrap_rxreset_
)
,
.
wclk
(
xclk
)
,
.
rclk
(
rxusrclk
)
,
/// .isaligned_in (state_aligned),
elastic1632
#(
.
DEPTH_LOG2
(
ELASTIC_DEPTH
)
,
// 16 //4),
.
OFFSET
(
ELASTIC_OFFSET
)
// 10 //5)
)
elastic1632_i
(
.
wclk
(
xclk
)
,
// input 150MHz, recovered
.
rclk
(
rxusrclk2
)
,
// input 75 MHz, system
// .isaligned_in (state_aligned && rxdlysresetdone_r), // input
.
isaligned_in
(
state_aligned
)
,
// input Moved clock phase reset/align to OOB module to handle
.
charisk_in
(
rxcharisk_dec_out
)
,
.
notintable_in
(
rxnotintable_dec_out
)
,
.
disperror_in
(
rxdisperr_dec_out
)
,
.
data_in
(
rxdata_dec_out
)
,
.
isaligned_out
(
isaligned
)
,
.
charisk_out
(
rxcharisk_els_out
)
,
.
notintable_out
(
rxnotintable_els_out
)
,
.
disperror_out
(
rxdisperr_els_out
)
,
.
data_out
(
rxdata_els_out
)
,
.
lword_strobe
(
lword_strobe
)
,
.
full
(
elastic_full
)
,
.
empty
(
elastic_empty
)
)
;
// iface resync
reg
rxcomwakedet_gtx_r
;
reg
rxcominitdet_gtx_r
;
// insert resync if it's necessary
generate
if
(
DATA_BYTE_WIDTH
==
4
)
begin
// resync to rxusrclk
// Fin = 2*Fout => 2*WIDTHin = WIDTHout
// first data word arrived = last word of a primitive, second arrived - first one
// lword_strobe indicates that second data word is arrived
wire
rxdata_resync_nempty
;
reg
rxdata_resync_nempty_r
;
wire
rxdata_resync_strobe
;
wire
[
50
:
0
]
rxdata_resync_in
;
wire
[
50
:
0
]
rxdata_resync_out
;
reg
[
25
:
0
]
rxdata_resync_buf
;
.
isaligned_in
(
state_aligned
)
,
// input Moved clock phase reset/align to OOB module to handle
.
charisk_in
(
rxcharisk_dec_out
)
,
// input[1:0]
.
notintable_in
(
rxnotintable_dec_out
)
,
// input[1:0]
.
disperror_in
(
rxdisperr_dec_out
)
,
// input[1:0]
.
data_in
(
rxdata_dec_out
)
,
// input[15:0]
.
isaligned_out
(
rxbyteisaligned
)
,
// output
.
charisk_out
(
rxcharisk
)
,
// output[3:0] reg
.
notintable_out
(
rxnotintable
)
,
// output[3:0] reg
.
disperror_out
(
rxdisperr
)
,
// output[3:0] reg
.
data_out
(
rxdata
)
,
// output[31:0] reg
.
full
(
rxelsfull
)
,
// output
.
empty
(
rxelsempty
)
// output
)
;
`ifdef
DEBUG_ELASTIC
localparam
ALIGN_PRIM
=
32'h7B4A4ABC
;
localparam
SOF_PRIM
=
32'h3737b57c
;
localparam
EOF_PRIM
=
32'hd5d5b57c
;
localparam
CONT_PRIM
=
32'h9999aa7c
;
localparam
HOLD_PRIM
=
32'hd5d5aa7c
;
localparam
HOLDA_PRIM
=
32'h9595aa7c
;
localparam
WTRM_PRIM
=
32'h5858b57c
;
assign
rxdata_resync_strobe
=
lword_strobe
;
assign
rxdata_resync_in
=
{
isaligned
,
// 1
rxcomwakedet_gtx_r
|
rxdata_resync_buf
[
25
]
,
// 1
rxcominitdet_gtx_r
|
rxdata_resync_buf
[
24
]
,
// 1
rxresetdone_gtx_r
,
// 1
txresetdone_gtx_r
,
// 1
elastic_full
|
rxdata_resync_buf
[
23
]
,
// 1
elastic_empty
|
rxdata_resync_buf
[
22
]
,
// 1
rxdisperr_els_out
,
// 2
rxnotintable_els_out
,
// 2
rxcharisk_els_out
,
// 2
rxdata_els_out
,
// 16
rxdata_resync_buf
[
21
:
0
]
};
// 22 / 51 total
always
@
(
posedge
rxusrclk
)
begin
/// rxdata_resync_buf <= ~wrap_rxreset_ ? 26'h0 : ~rxdata_resync_strobe ? {rxcomwakedet_gtx_r, rxcominitdet_gtx_r, elastic_full, elastic_empty, rxdisperr_els_out, rxnotintable_els_out, rxcharisk_els_out, rxdata_els_out} : rxdata_resync_buf;
if
(
!
wrap_rxreset_
)
rxdata_resync_buf
<=
26'b0
;
else
if
(
!
rxdata_resync_strobe
)
rxdata_resync_buf
<=
{
rxcomwakedet_gtx_r
,
rxcominitdet_gtx_r
,
elastic_full
,
elastic_empty
,
rxdisperr_els_out
,
rxnotintable_els_out
,
rxcharisk_els_out
,
rxdata_els_out
};
end
always
@
(
posedge
rxusrclk2
)
rxdata_resync_nempty_r
<=
rxdata_resync_nempty
;
reg
[
15
:
0
]
dbg_data_in_r
;
reg
[
1
:
0
]
dbg_charisk_in_r
;
// reg [1:0] dbg_notintable_in_r;
// reg [1:0] dbg_disperror_in_r;
reg
dbg_aligned32_in_r
;
// input data is word-aligned and got ALIGNp
reg
dbg_msb_in_r
;
// input contains MSB
// reg dbg_inc_waddr;
reg
[
11
:
0
]
dbg_data_cntr_r
;
reg
[
3
:
0
]
got_prims_r
;
reg
dbg_frun
;
reg
dbg_is_alignp_r
;
reg
dbg_is_sof_r
;
reg
dbg_is_eof_r
;
reg
dbg_is_data_r
;
fifo_cross_clocks
#(
.
DATA_WIDTH
(
51
)
,
.
DATA_DEPTH
(
4
)
)
rxdata_resynchro
(
// .rst (~wrap_rxreset_),
.
rst
(
1'b0
)
,
.
rrst
(
~
wrap_rxreset_
)
,
.
wrst
(
~
wrap_rxreset_
)
,
.
rclk
(
rxusrclk2
)
,
.
wclk
(
rxusrclk
)
,
.
we
(
rxdata_resync_strobe
)
,
.
re
(
rxdata_resync_nempty
&
rxdata_resync_nempty_r
)
,
.
data_in
(
rxdata_resync_in
)
,
.
data_out
(
rxdata_resync_out
)
,
.
nempty
(
rxdata_resync_nempty
)
,
.
half_empty
()
)
;
assign
rxbyteisaligned
=
rxdata_resync_out
[
50
]
;
assign
rxcomwakedet
=
rxdata_resync_out
[
49
]
;
assign
rxcominitdet
=
rxdata_resync_out
[
48
]
;
assign
rxresetdone
=
rxdata_resync_out
[
47
]
;
assign
txresetdone
=
rxdata_resync_out
[
46
]
;
assign
rxelsfull
=
rxdata_resync_out
[
45
]
;
assign
rxelsempty
=
rxdata_resync_out
[
44
]
;
assign
rxdisperr
[
3
:
0
]
=
{
rxdata_resync_out
[
43
:
42
]
,
rxdata_resync_out
[
21
:
20
]
};
assign
rxnotintable
[
3
:
0
]
=
{
rxdata_resync_out
[
41
:
40
]
,
rxdata_resync_out
[
19
:
18
]
};
assign
rxcharisk
[
3
:
0
]
=
{
rxdata_resync_out
[
39
:
38
]
,
rxdata_resync_out
[
17
:
16
]
};
assign
rxdata
[
31
:
0
]
=
{
rxdata_resync_out
[
37
:
22
]
,
rxdata_resync_out
[
15
:
0
]
};
end
else
if
(
DATA_BYTE_WIDTH
==
2
)
begin
// no resync is needed => straightforward assignments
assign
rxbyteisaligned
=
isaligned
;
assign
rxcomwakedet
=
rxcomwakedet_gtx_r
;
assign
rxcominitdet
=
rxcominitdet_gtx_r
;
assign
rxresetdone
=
rxresetdone_gtx_r
;
assign
txresetdone
=
txresetdone_gtx_r
;
assign
rxelsfull
=
elastic_full
;
assign
rxelsempty
=
elastic_empty
;
assign
rxdisperr
[
1
:
0
]
=
rxdisperr_els_out
;
assign
rxnotintable
[
1
:
0
]
=
rxnotintable_els_out
;
assign
rxcharisk
[
1
:
0
]
=
rxcharisk_els_out
;
assign
rxdata
[
15
:
0
]
=
rxdata_els_out
;
end
else
begin
// unconsidered case
always
@
(
posedge
txusrclk
)
begin
$
display
(
"Wrong width set in %m, value is %d"
,
DATA_BYTE_WIDTH
)
;
end
end
endgenerate
wire
dbg_is_alignp_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
ALIGN_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_sof_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
SOF_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_eof_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
EOF_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
// latching gtx outputs, synchronous to RXUSRCLK2 = rxusrclk
always
@
(
posedge
rxusrclk
)
begin
rxcomwakedet_gtx_r
<=
rxcomwakedet_gtx
;
rxcominitdet_gtx_r
<=
rxcominitdet_gtx
;
rxresetdone_gtx_r
<=
rxresetdone_gtx
;
txresetdone_gtx_r
<=
txresetdone_gtx
;
end
wire
dbg_is_cont_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
CONT_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_hold_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
HOLD_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_holda_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
HOLDA_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_wrtm_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
WTRM_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
`else
// OLD_ELASTIC
elastic1632
#(
.
DEPTH_LOG2
(
ELASTIC_DEPTH
)
,
// 16 //4),
.
OFFSET
(
ELASTIC_OFFSET
)
// 10 //5)
)
elastic1632_i
(
.
wclk
(
xclk
)
,
// input 150MHz, recovered
.
rclk
(
rxusrclk2
)
,
// input 75 MHz, system
// .isaligned_in (state_aligned && rxdlysresetdone_r), // input
.
isaligned_in
(
state_aligned
)
,
// input Moved clock phase reset/align to OOB module to handle
.
charisk_in
(
rxcharisk_dec_out
)
,
// input[1:0]
.
notintable_in
(
rxnotintable_dec_out
)
,
// input[1:0]
.
disperror_in
(
rxdisperr_dec_out
)
,
// input[1:0]
.
data_in
(
rxdata_dec_out
)
,
// input[15:0]
.
isaligned_out
(
rxbyteisaligned
)
,
// output
.
charisk_out
(
rxcharisk
)
,
// output[3:0] reg
.
notintable_out
(
rxnotintable
)
,
// output[3:0] reg
.
disperror_out
(
rxdisperr
)
,
// output[3:0] reg
.
data_out
(
rxdata
)
,
// output[31:0] reg
.
full
(
rxelsfull
)
,
// output
.
empty
(
rxelsempty
)
// output
)
;
`ifdef
DEBUG_ELASTIC
localparam
ALIGN_PRIM
=
32'h7B4A4ABC
;
localparam
SOF_PRIM
=
32'h3737b57c
;
localparam
EOF_PRIM
=
32'hd5d5b57c
;
localparam
CONT_PRIM
=
32'h9999aa7c
;
localparam
HOLD_PRIM
=
32'hd5d5aa7c
;
localparam
HOLDA_PRIM
=
32'h9595aa7c
;
localparam
WTRM_PRIM
=
32'h5858b57c
;
wire
dbg_is_data_w
=
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h0
)
;
reg
[
15
:
0
]
dbg_data_in_r
;
reg
[
1
:
0
]
dbg_charisk_in_r
;
// reg [1:0] dbg_notintable_in_r;
// reg [1:0] dbg_disperror_in_r;
reg
dbg_aligned32_in_r
;
// input data is word-aligned and got ALIGNp
reg
dbg_msb_in_r
;
// input contains MSB
// reg dbg_inc_waddr;
reg
[
11
:
0
]
dbg_data_cntr_r
;
reg
[
3
:
0
]
got_prims_r
;
reg
dbg_frun
;
reg
dbg_is_alignp_r
;
reg
dbg_is_sof_r
;
reg
dbg_is_eof_r
;
reg
dbg_is_data_r
;
wire
dbg_is_alignp_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
ALIGN_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_sof_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
SOF_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_eof_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
EOF_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_cont_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
CONT_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_hold_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
HOLD_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_holda_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
HOLDA_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_wrtm_w
=
(
{
rxdata_dec_out
,
dbg_data_in_r
}
==
WTRM_PRIM
)
&&
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h1
)
;
wire
dbg_is_data_w
=
(
{
rxcharisk_dec_out
,
dbg_charisk_in_r
}
==
4'h0
)
;
always
@
(
posedge
xclk
)
begin
dbg_data_in_r
<=
rxdata_dec_out
;
dbg_charisk_in_r
<=
rxcharisk_dec_out
;
always
@
(
posedge
xclk
)
begin
dbg_data_in_r
<=
rxdata_dec_out
;
dbg_charisk_in_r
<=
rxcharisk_dec_out
;
// dbg_notintable_in_r <= rxnotintable_dec_out;
// dbg_disperror_in_r <= rxdisperr_dec_out;
...
...
@@ -794,111 +635,72 @@ wire rxcominitdet_gtx;
// dbg_inc_waddr <= !dbg_msb_in_r || (dbg_is_alignp_w && !dbg_aligned32_in_r);
// if (!dbg_aligned32_in_r || dbg_is_eof_w) dbg_frun <= 0;
// else if (dbg_is_sof_w) dbg_frun <= 1;
if
(
!
dbg_aligned32_in_r
||
dbg_is_eof_r
)
dbg_frun
<=
0
;
else
if
(
dbg_is_sof_r
)
dbg_frun
<=
1
;
if
(
!
dbg_aligned32_in_r
||
dbg_is_eof_r
)
dbg_frun
<=
0
;
else
if
(
dbg_is_sof_r
)
dbg_frun
<=
1
;
// if (!dbg_aligned32_in_r || dbg_is_sof_w) dbg_data_cntr_r <= 0;
// else if (dbg_frun && dbg_is_data_w &&dbg_msb_in_r) dbg_data_cntr_r <= dbg_data_cntr_r + 1;
if
(
!
dbg_aligned32_in_r
||
dbg_is_sof_r
)
dbg_data_cntr_r
<=
0
;
else
if
(
dbg_frun
&&
dbg_is_data_r
)
dbg_data_cntr_r
<=
dbg_data_cntr_r
+
1
;
// if (!dbg_aligned32_in_r || dbg_is_sof_w) dbg_data_cntr <= dbg_data_cntr_r; // copy previous value
if
(
!
dbg_aligned32_in_r
||
dbg_is_sof_r
)
dbg_data_cntr
<=
{
got_prims_r
,
dbg_data_cntr_r
};
// copy previous value
if
(
!
dbg_aligned32_in_r
||
dbg_is_sof_r
)
dbg_data_cntr_r
<=
0
;
else
if
(
dbg_frun
&&
dbg_is_data_r
)
dbg_data_cntr_r
<=
dbg_data_cntr_r
+
1
;
end
`endif
// DEBUG_ELASATIC
reg
rxresetdone_r
;
reg
txresetdone_r
;
always
@
(
posedge
rxusrclk2
)
rxresetdone_r
<=
rxresetdone_gtx
;
always
@
(
posedge
txusrclk2
)
txresetdone_r
<=
txresetdone_gtx
;
assign
rxresetdone
=
rxresetdone_r
;
assign
txresetdone
=
txresetdone_r
;
pulse_cross_clock
#(
.
EXTRA_DLY
(
0
)
)
pulse_cross_clock_rxcominitdet_i
(
.
rst
(
~
wrap_rxreset_
)
,
// input
.
src_clk
(
xclk
)
,
// input
.
dst_clk
(
rxusrclk2
)
,
// input
.
in_pulse
(
rxcominitdet_gtx
)
,
// input
.
out_pulse
(
rxcominitdet
)
,
// output
.
busy
()
// output
)
;
pulse_cross_clock
#(
.
EXTRA_DLY
(
0
)
)
pulse_cross_clock_rxcomwakedet_i
(
.
rst
(
~
wrap_rxreset_
)
,
// input
.
src_clk
(
xclk
)
,
// input
.
dst_clk
(
rxusrclk2
)
,
// input
.
in_pulse
(
rxcomwakedet_gtx
)
,
// input
.
out_pulse
(
rxcomwakedet
)
,
// output
.
busy
()
// output
)
;
// if (!dbg_aligned32_in_r || dbg_is_sof_w) dbg_data_cntr <= dbg_data_cntr_r; // copy previous value
if
(
!
dbg_aligned32_in_r
||
dbg_is_sof_r
)
dbg_data_cntr
<=
{
got_prims_r
,
dbg_data_cntr_r
};
// copy previous value
end
//rxusrclk2
`endif
// DEBUG_ELASATIC
reg
rxresetdone_r
;
reg
txresetdone_r
;
always
@
(
posedge
rxusrclk2
)
rxresetdone_r
<=
rxresetdone_gtx
;
always
@
(
posedge
txusrclk2
)
txresetdone_r
<=
txresetdone_gtx
;
assign
rxresetdone
=
rxresetdone_r
;
assign
txresetdone
=
txresetdone_r
;
pulse_cross_clock
#(
.
EXTRA_DLY
(
0
)
)
pulse_cross_clock_rxcominitdet_i
(
.
rst
(
~
wrap_rxreset_
)
,
// input
.
src_clk
(
xclk
)
,
// input
.
dst_clk
(
rxusrclk2
)
,
// input
.
in_pulse
(
rxcominitdet_gtx
)
,
// input
.
out_pulse
(
rxcominitdet
)
,
// output
.
busy
()
// output
)
;
`endif
//OLD_ELASTIC
wire
txoutclk_gtx
;
pulse_cross_clock
#(
.
EXTRA_DLY
(
0
)
)
pulse_cross_clock_rxcomwakedet_i
(
.
rst
(
~
wrap_rxreset_
)
,
// input
.
src_clk
(
xclk
)
,
// input
.
dst_clk
(
rxusrclk2
)
,
// input
.
in_pulse
(
rxcomwakedet_gtx
)
,
// input
.
out_pulse
(
rxcomwakedet
)
,
// output
.
busy
()
// output
)
;
wire
txoutclk_gtx
;
wire
xclk_gtx
;
//wire xclk_mr;
BUFG
bufg_txoutclk
(
.
O
(
txoutclk
)
,.
I
(
txoutclk_gtx
))
;
//BUFR bufr_xclk (.O(xclk),.I(xclk_mr),.CE(1'b1),.CLR(1'b0));
//BUFMR bufmr_xclk (.O(xclk_mr),.I(xclk_gtx));
`ifdef
USE_DRP
wire
xclk_gtx_g
;
`ifdef
STRAIGHT_XCLK
BUFH
BUFH_i
(
.
O
()
,
// output
.
I
()
// input
)
;
/* Instance template for module clock_inverter */
clock_inverter
clock_inverter_i
(
.
rst
()
,
.
clk_in
()
,
// input
.
invert
()
,
// input
.
clk_out
()
// output
)
;
BUFG
bug_xclk
(
.
O
(
xclk
)
,.
I
(
xclk_gtx
))
;
`else
BUFH
bufr_xclk
(
.
O
(
xclk_gtx_g
)
,
.
I
(
xclk_gtx
))
;
clock_inverter
bug_xclk
(
.
rst
(
rxreset
)
,
.
clk_in
(
xclk_gtx_g
)
,
// input
.
invert
(
other_control
[
15
])
,
// input other_control[15] inverts xclk phase
.
clk_out
(
xclk
))
;
// output
`endif
`else
// VDT bug - incorrectly processes defines when calculating closure
BUFH
BUFH_i
(
.
O
()
,
// output
.
I
()
// input
)
;
/* Instance template for module clock_inverter */
clock_inverter
clock_inverter_i
(
.
rst
()
,
.
clk_in
()
,
// input
.
invert
()
,
// input
.
clk_out
()
// output
)
;
BUFG
bug_xclk
(
.
O
(
xclk
)
,.
I
(
xclk_gtx
))
;
`endif
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bufg_txoutclk
(
.
o
(
txoutclk
)
,
// output
.
i
(
txoutclk_gtx
)
,
// input
.
clr
(
1'b0
)
// input
)
;
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bug_xclk
(
.
o
(
xclk
)
,
// output
.
i
(
xclk_gtx
)
,
// input
.
clr
(
1'b0
)
// input
)
;
gtxe2_channel_wrapper
#(
.
SIM_RECEIVER_DETECT_PASS
(
"TRUE"
)
,
...
...
host/sata_phy.v
View file @
cb2fc48f
...
...
@@ -227,7 +227,7 @@ wire txp;
wire
txn
;
wire
rxp
;
wire
rxn
;
wire
txoutclk
;
wire
txoutclk
;
// comes out global from gtx_wrap
wire
txpmareset_done
;
wire
rxeyereset_done
;
...
...
@@ -377,7 +377,7 @@ always @ (posedge clk or posedge extrst)
`endif
// OLD_TXPCSRESET
// issue rx reset to restore functionality after oob sequence. Let it last
s 8 clock l
ycles
// issue rx reset to restore functionality after oob sequence. Let it last
8 clock c
ycles
reg
[
3
:
0
]
rxreset_oob_cnt
;
wire
rxreset_oob_stop
;
...
...
@@ -395,73 +395,89 @@ always @ (posedge clk or posedge extrst)
* USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk
* It's recommended to use MMCM instead of PLL, whatever
*/
wire
usrpll_fb_clk
;
wire
usrclk
;
wire
usrclk2
;
wire
usrclk_global
;
BUFG
bufg_usrclk
(
.
O
(
usrclk_global
)
,.
I
(
usrclk
))
;
wire
usrclk2
;
//`define GTX_USE_PLL
`ifdef
GTX_USE_PLL
wire
usrpll_fb_clk
;
wire
usrclk
;
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bufg_usrclk
(
.
o
(
usrclk_global
)
,
// output
.
i
(
usrclk
)
,
// input
.
clr
(
1'b0
)
// input
)
;
PLLE2_ADV
#(
.
BANDWIDTH
(
"OPTIMIZED"
)
,
.
CLKFBOUT_MULT
(
8
)
,
.
CLKFBOUT_PHASE
(
0.000
)
,
.
CLKIN1_PERIOD
(
6.666
)
,
.
CLKIN2_PERIOD
(
0.000
)
,
.
CLKOUT0_DIVIDE
(
8
)
,
.
CLKOUT0_DUTY_CYCLE
(
0.500
)
,
.
CLKOUT0_PHASE
(
0.000
)
,
.
CLKOUT1_DIVIDE
(
16
)
,
.
CLKOUT1_DUTY_CYCLE
(
0.500
)
,
.
CLKOUT1_PHASE
(
0.000
)
,
.
COMPENSATION
(
"ZHOLD"
)
,
.
DIVCLK_DIVIDE
(
1
)
,
.
IS_CLKINSEL_INVERTED
(
1'b0
)
,
.
IS_PWRDWN_INVERTED
(
1'b0
)
,
.
IS_RST_INVERTED
(
1'b0
)
,
.
REF_JITTER1
(
0.010
)
,
.
REF_JITTER2
(
0.010
)
,
.
STARTUP_WAIT
(
"FALSE"
)
)
usrclk_pll
(
.
CLKFBOUT
(
usrpll_fb_clk
)
,
.
CLKOUT0
(
usrclk
)
,
//150Mhz
.
CLKOUT1
(
usrclk2
)
,
// 75MHz
.
CLKOUT2
()
,
.
CLKOUT3
()
,
.
CLKOUT4
()
,
.
CLKOUT5
()
,
.
DO
()
,
.
DRDY
()
,
.
LOCKED
(
usrpll_locked
)
,
.
CLKFBIN
(
usrpll_fb_clk
)
,
.
CLKIN1
(
txoutclk
)
,
.
CLKIN2
(
1'b0
)
,
.
CLKINSEL
(
1'b1
)
,
.
DADDR
(
7'h0
)
,
.
DCLK
(
drpclk
)
,
.
DEN
(
1'b0
)
,
.
DI
(
16'h0
)
,
.
DWE
(
1'b0
)
,
.
PWRDWN
(
1'b0
)
,
.
RST
(
~
cplllock
)
)
;
`else
// GTX_USE_PLL
// divide txoutclk (global) by 2, then make global. Does not need to be phase-aligned - will use FIFO
reg
usrclk2_r
;
always
@
(
posedge
txoutclk
)
begin
if
(
~
cplllock
)
usrclk2_r
<=
0
;
else
usrclk2_r
<=
~
usrclk2
;
end
assign
txusrclk
=
txoutclk
;
// 150MHz, was already global
assign
usrclk_global
=
txoutclk
;
// 150MHz, was already global
assign
usrclk2
=
usrclk2_r
;
assign
usrpll_locked
=
cplllock
;
`endif
// else // GTX_USE_PLL
assign
txusrclk
=
usrclk_global
;
// 150MHz
assign
txusrclk2
=
clk
;
// usrclk2; // should not use non-buffered clock!
assign
txusrclk2
=
clk
;
// usrclk2;
assign
rxusrclk
=
usrclk_global
;
// 150MHz
assign
rxusrclk2
=
clk
;
// usrclk2; // should not use non-buffered clock!
PLLE2_ADV
#(
.
BANDWIDTH
(
"OPTIMIZED"
)
,
.
CLKFBOUT_MULT
(
8
)
,
.
CLKFBOUT_PHASE
(
0.000
)
,
.
CLKIN1_PERIOD
(
6.666
)
,
.
CLKIN2_PERIOD
(
0.000
)
,
.
CLKOUT0_DIVIDE
(
8
)
,
.
CLKOUT0_DUTY_CYCLE
(
0.500
)
,
.
CLKOUT0_PHASE
(
0.000
)
,
.
CLKOUT1_DIVIDE
(
16
)
,
.
CLKOUT1_DUTY_CYCLE
(
0.500
)
,
.
CLKOUT1_PHASE
(
0.000
)
,
/* .CLKOUT2_DIVIDE = 1,
.CLKOUT2_DUTY_CYCLE = 0.500,
.CLKOUT2_PHASE = 0.000,
.CLKOUT3_DIVIDE = 1,
.CLKOUT3_DUTY_CYCLE = 0.500,
.CLKOUT3_PHASE = 0.000,
.CLKOUT4_DIVIDE = 1,
.CLKOUT4_DUTY_CYCLE = 0.500,
.CLKOUT4_PHASE = 0.000,
.CLKOUT5_DIVIDE = 1,
.CLKOUT5_DUTY_CYCLE = 0.500,
.CLKOUT5_PHASE = 0.000,*/
.
COMPENSATION
(
"ZHOLD"
)
,
.
DIVCLK_DIVIDE
(
1
)
,
.
IS_CLKINSEL_INVERTED
(
1'b0
)
,
.
IS_PWRDWN_INVERTED
(
1'b0
)
,
.
IS_RST_INVERTED
(
1'b0
)
,
.
REF_JITTER1
(
0.010
)
,
.
REF_JITTER2
(
0.010
)
,
.
STARTUP_WAIT
(
"FALSE"
)
)
usrclk_pll
(
.
CLKFBOUT
(
usrpll_fb_clk
)
,
.
CLKOUT0
(
usrclk
)
,
//150Mhz
.
CLKOUT1
(
usrclk2
)
,
// 75MHz
.
CLKOUT2
()
,
.
CLKOUT3
()
,
.
CLKOUT4
()
,
.
CLKOUT5
()
,
.
DO
()
,
.
DRDY
()
,
.
LOCKED
(
usrpll_locked
)
,
.
CLKFBIN
(
usrpll_fb_clk
)
,
.
CLKIN1
(
txoutclk
)
,
.
CLKIN2
(
1'b0
)
,
.
CLKINSEL
(
1'b1
)
,
.
DADDR
(
7'h0
)
,
.
DCLK
(
drpclk
)
,
.
DEN
(
1'b0
)
,
.
DI
(
16'h0
)
,
.
DWE
(
1'b0
)
,
.
PWRDWN
(
1'b0
)
,
.
RST
(
~
cplllock
)
assign
rxusrclk2
=
clk
;
// usrclk2;
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bufg_sclk
(
.
o
(
clk
)
,
// output
.
i
(
usrclk2
)
,
// input
.
clr
(
1'b0
)
// input
)
;
/*
...
...
@@ -528,7 +544,7 @@ gtx_wrap
.
txelecidle
(
txelecidle
)
,
// input wire
.
txp
(
txp
)
,
// output wire
.
txn
(
txn
)
,
// output wire
.
txoutclk
(
txoutclk
)
,
// output wire
.
txoutclk
(
txoutclk
)
,
// output wire
// made global inside
.
txpcsreset
(
txpcsreset
)
,
// input wire
.
txresetdone
(
txresetdone
)
,
// output wire
.
txcominit
(
txcominit
)
,
// input wire
...
...
@@ -547,7 +563,7 @@ gtx_wrap
.
dbg_rxcdrlock
(
dbg_rxcdrlock
)
,
.
dbg_rxdlysresetdone
(
dbg_rxdlysresetdone
)
,
.
txbufstatus
(
txbufstatus
[
1
:
0
])
,
.
xclk
(
xclk
)
// output receive clock, just to measure frequency
.
xclk
(
xclk
)
// output receive clock, just to measure frequency
// global
`ifdef
USE_DATASCOPE
,.
datascope_clk
(
datascope_clk
)
,
// output
.
datascope_waddr
(
datascope_waddr
)
,
// output[9:0]
...
...
@@ -580,8 +596,6 @@ gtx_wrap
assign
cplllockdetclk
=
reliable_clk
;
//gtrefclk;
assign
drpclk
=
reliable_clk
;
//gtrefclk;
//assign clk = usrclk2;
BUFG
bufg_sclk
(
.
O
(
clk
)
,.
I
(
usrclk2
))
;
assign
rxn
=
rxn_in
;
assign
rxp
=
rxp_in
;
assign
txn_out
=
txn
;
...
...
system_defines.vh
View file @
cb2fc48f
...
...
@@ -3,7 +3,7 @@
`define SYSTEM_DEFINES
`define USE_DRP
`define ALIGN_CLOCKS
`define STRAIGHT_XCLK
//
`define STRAIGHT_XCLK
`define USE_DATASCOPE
// `define DATASCOPE_INCOMING_RAW
`define PRELOAD_BRAMS
...
...
top.v
View file @
cb2fc48f
...
...
@@ -40,7 +40,7 @@
`include
"system_defines.vh"
module
top
#(
//
`include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - partially used
`include
"includes/x393_parameters.vh"
// SuppressThisWarning VEditor - partially used
)
(
// sata serial data iface
...
...
@@ -149,11 +149,31 @@ always @(posedge comb_rst or posedge axi_aclk0) begin
else
axi_rst_pre
<=
1'b0
;
end
//BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(/*fclk[0]*/ sclk));
//assign axi_aclk = sclk;
BUFG
bufg_axi_aclk0_i
(
.
O
(
axi_aclk0
)
,.
I
(
fclk
[
0
]))
;
BUFG
bufg_axi_rst_i
(
.
O
(
axi_rst
)
,.
I
(
axi_rst_pre
))
;
BUFG
bufg_extrst_i
(
.
O
(
extrst
)
,.
I
(
axi_rst_pre
))
;
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bufg_axi_aclk0_i
(
.
o
(
axi_aclk0
)
,
// output
.
i
(
fclk
[
0
])
,
// input
.
clr
(
1'b0
)
// input
)
;
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bufg_axi_rst_i
(
.
o
(
axi_rst
)
,
// output
.
i
(
axi_rst_pre
)
,
// input
.
clr
(
1'b0
)
// input
)
;
select_clk_buf
#(
.
BUFFER_TYPE
(
"BUFG"
)
)
bufg_extrst_i
(
.
o
(
extrst
)
,
// output
.
i
(
axi_rst_pre
)
,
// input
.
clr
(
1'b0
)
// input
)
;
axi_hp_clk
#(
.
CLKIN_PERIOD
(
20.000
)
,
.
CLKFBOUT_MULT_AXIHP
(
18
)
,
...
...
@@ -164,6 +184,7 @@ axi_hp_clk #(
.
clk_axihp
(
hclk
)
,
// output
.
locked_axihp
()
// output // not controlled?
)
;
sata_ahci_top
sata_top
(
.
sata_clk
(
sclk
)
,
// reliable clock to source drp and cpll lock det circuits
...
...
x393/wrap/select_clk_buf.v
0 → 100644
View file @
cb2fc48f
/*******************************************************************************
* Module: select_clk_buf
* Date:2015-11-07
* Author: andrey
* Description: Select one of the clock buffers primitives by parameter
*
* Copyright (c) 2015 Elphel, Inc .
* select_clk_buf.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* select_clk_buf.v 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify this Program, or any covered work, by linking or combining it
* with independent modules provided by the FPGA vendor only (this permission
* does not extend to any 3-rd party modules, "soft cores" or macros) under
* different license terms solely for the purpose of generating binary "bitstream"
* files and/or simulating the code, the copyright holders of this Program give
* you the right to distribute the covered work without those independent modules
* as long as the source code for them is available from the FPGA vendor free of
* charge, and there is no dependence on any encrypted modules for simulating of
* the combined code. This permission applies to you if the distributed code
* contains all the components and scripts required to completely simulate it
* with at least one of the Free Software programs.
*******************************************************************************/
`timescale
1
ns
/
1
ps
module
select_clk_buf
#(
parameter
BUFFER_TYPE
=
"BUFR"
// to use clr
)(
output
o
,
input
i
,
input
clr
// for BUFR_only
)
;
generate
if
(
BUFFER_TYPE
==
"BUFG"
)
BUFG
clk1x_i
(
.
O
(
o
)
,
.
I
(
i
))
;
else
if
(
BUFFER_TYPE
==
"BUFH"
)
BUFH
clk1x_i
(
.
O
(
o
)
,
.
I
(
i
))
;
else
if
(
BUFFER_TYPE
==
"BUFR"
)
BUFR
clk1x_i
(
.
O
(
o
)
,
.
I
(
i
)
,
.
CE
(
1'b1
)
,
.
CLR
(
clr
))
;
else
if
(
BUFFER_TYPE
==
"BUFMR"
)
BUFMR
clk1x_i
(
.
O
(
o
)
,
.
I
(
i
))
;
else
if
(
BUFFER_TYPE
==
"BUFIO"
)
BUFIO
clk1x_i
(
.
O
(
o
)
,
.
I
(
i
))
;
else
assign
o
=
i
;
endgenerate
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