Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
30
Issues
30
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Schedules
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
White Rabbit core collection
Commits
bf48dc31
Commit
bf48dc31
authored
Jul 21, 2023
by
Tristan Gingold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add serial_dac856x (and a testbench)
parent
7cd9b30f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
241 additions
and
1 deletion
+241
-1
Manifest.py
modules/wr_dacs/Manifest.py
+2
-1
serial_dac856x.vhd
modules/wr_dacs/serial_dac856x.vhd
+147
-0
serial_dac856x_tb.vhd
testbench/dac/serial_dac856x_tb.vhd
+92
-0
No files found.
modules/wr_dacs/Manifest.py
View file @
bf48dc31
...
...
@@ -2,5 +2,6 @@ files = [
"spec_serial_dac_arb.vhd"
,
"spec_serial_dac.vhd"
,
"cute_serial_dac_arb.vhd"
,
"cute_serial_dac.vhd"
"cute_serial_dac.vhd"
,
"serial_dac856x.vhd"
,
]
modules/wr_dacs/serial_dac856x.vhd
0 → 100644
View file @
bf48dc31
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
entity
serial_dac856x
is
generic
(
-- SCLK is CLK / (g_sclk_div + 1)
g_sclk_div
:
positive
:
=
1
);
port
(
clk_i
:
std_logic
;
rst_n_i
:
std_logic
;
-- Value to be sent for output A.
value_a_i
:
std_logic_vector
(
15
downto
0
);
wr_a_i
:
std_logic
;
value_b_i
:
std_logic_vector
(
15
downto
0
);
wr_b_i
:
std_logic
;
-- If true, values for a and b will be sent.
en_a_i
:
std_logic
;
en_b_i
:
std_logic
;
-- Extra config. When BUSY is set, the data are not yet sent.
data_i
:
std_logic_vector
(
23
downto
0
);
wr_i
:
std_logic
;
busy_o
:
out
std_logic
;
-- SPI interface
sclk_o
:
out
std_logic
;
d_o
:
out
std_logic
;
sync_n_o
:
out
std_logic
);
end
serial_dac856x
;
architecture
behav
of
serial_dac856x
is
signal
sclk_p
:
std_logic
;
signal
sclk_cnt
:
natural
range
g_sclk_div
-
1
downto
0
;
signal
set_a
,
set_b
,
set_d
:
std_logic
;
signal
val_a
,
val_b
:
std_logic_vector
(
15
downto
0
);
signal
val_d
:
std_logic_vector
(
23
downto
0
);
subtype
t_clk_count
is
natural
range
(
24
+
4
)
-
1
downto
0
;
signal
edge
:
std_logic
;
signal
clk_count
:
t_clk_count
;
signal
buf
:
std_logic_vector
(
23
downto
0
);
signal
busy
:
std_logic
;
begin
-- Clock divider.
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
sclk_p
<=
'0'
;
if
rst_n_i
=
'0'
or
busy
=
'0'
then
sclk_cnt
<=
g_sclk_div
-
1
;
else
if
sclk_cnt
=
0
then
sclk_p
<=
'1'
;
sclk_cnt
<=
g_sclk_div
-
1
;
else
sclk_cnt
<=
sclk_cnt
-
1
;
end
if
;
end
if
;
end
if
;
end
process
;
-- General state machine
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
busy
<=
'0'
;
sclk_o
<=
'1'
;
sync_n_o
<=
'1'
;
d_o
<=
'0'
;
set_a
<=
'0'
;
set_b
<=
'0'
;
set_d
<=
'0'
;
else
-- Accept values. Will overwrite but not corrupt current values.
if
wr_a_i
=
'1'
then
val_a
<=
value_a_i
;
set_a
<=
'1'
;
end
if
;
if
wr_b_i
=
'1'
then
val_b
<=
value_b_i
;
set_b
<=
'1'
;
end
if
;
if
wr_i
=
'1'
then
val_d
<=
data_i
;
set_d
<=
'1'
;
end
if
;
if
busy
=
'1'
then
-- Transmit, but only on clock divider pulses.
if
sclk_p
=
'1'
then
if
clk_count
>
3
then
sclk_o
<=
edge
;
else
sclk_o
<=
'1'
;
end
if
;
if
edge
=
'1'
then
if
clk_count
>
3
then
sync_n_o
<=
'0'
;
d_o
<=
buf
(
buf
'high
);
buf
<=
buf
(
buf
'high
-
1
downto
buf
'low
)
&
'0'
;
else
sync_n_o
<=
'1'
;
d_o
<=
'0'
;
end
if
;
else
if
clk_count
=
0
then
busy
<=
'0'
;
else
clk_count
<=
clk_count
-
1
;
end
if
;
end
if
;
edge
<=
not
edge
;
end
if
;
else
-- Choose (with implicit priority the new data to be transmitted).
if
set_d
=
'1'
then
buf
<=
val_d
;
busy
<=
'1'
;
set_d
<=
'0'
;
elsif
set_a
=
'1'
and
en_a_i
=
'1'
then
buf
<=
b"00_011_000"
&
val_a
;
busy
<=
'1'
;
set_a
<=
'0'
;
elsif
set_b
=
'1'
and
en_b_i
=
'1'
then
buf
<=
b"00_011_001"
&
val_b
;
busy
<=
'1'
;
set_b
<=
'0'
;
end
if
;
clk_count
<=
t_clk_count
'high
;
edge
<=
'1'
;
end
if
;
end
if
;
end
if
;
end
process
;
busy_o
<=
set_d
;
end
behav
;
testbench/dac/serial_dac856x_tb.vhd
0 → 100644
View file @
bf48dc31
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
entity
serial_dac856x_tb
is
end
;
architecture
arch
of
serial_dac856x_tb
is
signal
clk
,
rst_n
:
std_logic
;
signal
din
,
sync_n
,
sclk
:
std_logic
;
signal
value_a
,
value_b
:
std_logic_vector
(
15
downto
0
);
signal
en_a
,
en_b
:
std_logic
;
signal
data
:
std_logic_vector
(
23
downto
0
);
signal
wr_a
,
wr_b
,
wr
:
std_logic
;
signal
busy
:
std_logic
;
begin
inst_dut
:
entity
work
.
serial_dac856x
generic
map
(
g_sclk_div
=>
1
)
port
map
(
clk_i
=>
clk
,
rst_n_i
=>
rst_n
,
value_a_i
=>
value_a
,
wr_a_i
=>
wr_a
,
value_b_i
=>
value_b
,
wr_b_i
=>
wr_b
,
en_a_i
=>
en_a
,
en_b_i
=>
en_b
,
data_i
=>
data
,
wr_i
=>
wr
,
busy_o
=>
busy
,
sclk_o
=>
sclk
,
d_o
=>
din
,
sync_n_o
=>
sync_n
);
process
begin
clk
<=
'0'
;
wait
for
4
ns
;
clk
<=
'1'
;
wait
for
4
ns
;
end
process
;
rst_n
<=
'0'
,
'1'
after
8
ns
;
process
begin
wr_a
<=
'0'
;
wr_b
<=
'0'
;
wr
<=
'0'
;
en_a
<=
'0'
;
en_b
<=
'0'
;
wait
until
rising_edge
(
clk
)
and
rst_n
=
'1'
;
assert
busy
=
'0'
;
value_a
<=
x"f549"
;
wr_a
<=
'1'
;
wait
until
rising_edge
(
clk
);
value_a
<=
(
others
=>
'X'
);
wr_a
<=
'0'
;
assert
busy
=
'0'
;
wait
until
rising_edge
(
clk
);
en_a
<=
'1'
;
wait
until
rising_edge
(
clk
);
data
<=
x"800001"
;
wr
<=
'1'
;
wait
until
rising_edge
(
clk
);
wr
<=
'0'
;
-- TODO: real test
wait
;
end
process
;
process
(
sclk
,
sync_n
)
variable
buf
:
std_logic_vector
(
23
downto
0
);
variable
cnt
:
natural
;
begin
if
sync_n
=
'1'
then
cnt
:
=
0
;
elsif
falling_edge
(
sclk
)
then
buf
:
=
buf
(
22
downto
0
)
&
din
;
cnt
:
=
cnt
+
1
;
if
cnt
=
24
then
report
"received:"
&
to_string
(
buf
)
&
" "
&
to_hstring
(
buf
);
end
if
;
end
if
;
end
process
;
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