Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
Conv TTL Blocking
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
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
Conv TTL Blocking
Commits
3f50efec
Commit
3f50efec
authored
Nov 11, 2012
by
Carlos Gil Soriano
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement whole read and writes cycles.
parent
c1e58f09
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
906 additions
and
335 deletions
+906
-335
gc_clk_divider.vhd
hdl/ctdah_lib/rtl/gc_clk_divider.vhd
+1
-0
wishbone_driver.vhd
hdl/ctdah_lib/test/wishbone_driver.vhd
+90
-0
wishbone_driver_pkg.vhd
hdl/ctdah_lib/test/wishbone_driver_pkg.vhd
+38
-0
i2c_bit.vhd
hdl/i2c_slave_wb_master/rtl/i2c_bit.vhd
+10
-0
i2c_regs.vhd
hdl/i2c_slave_wb_master/rtl/i2c_regs.vhd
+94
-61
i2c_slave_core.vhd
hdl/i2c_slave_wb_master/rtl/i2c_slave_core.vhd
+322
-183
i2c_slave_pkg.vhd
hdl/i2c_slave_wb_master/rtl/i2c_slave_pkg.vhd
+68
-11
i2c_slave_top.vhd
hdl/i2c_slave_wb_master/rtl/i2c_slave_top.vhd
+15
-17
i2c_master_driver.vhd
hdl/i2c_slave_wb_master/test/i2c_master_driver.vhd
+123
-11
i2c_slave_top_tb.vhd
hdl/i2c_slave_wb_master/test/i2c_slave_top_tb.vhd
+145
-52
No files found.
hdl/ctdah_lib/rtl/gc_clk_divider.vhd
View file @
3f50efec
...
...
@@ -61,6 +61,7 @@ signal s_clk_o : STD_LOGIC;
signal
clk_i_count
:
UNSIGNED
(
g_clk_division_logSize
-
1
downto
0
);
begin
clk_o
<=
s_clk_o
;
p_div
:
process
(
clk_i
)
...
...
hdl/ctdah_lib/test/wishbone_driver.vhd
0 → 100644
View file @
3f50efec
library
IEEE
;
use
IEEE
.
STD_LOGIC_1164
.
ALL
;
use
IEEE
.
NUMERIC_STD
.
ALL
;
--! Code intended for simulation only.
entity
wishbone_driver
is
generic
(
g_WB_DATA_O_LENGTH
:
NATURAL
:
=
32
;
g_WB_DATA_I_LENGTH
:
NATURAL
:
=
32
;
g_WB_ADDR_LENGTH
:
NATURAL
:
=
6
;
g_WB_CLK_PERIOD
:
TIME
:
=
50
ns
);
port
(
wb_clk_i
:
in
STD_LOGIC
;
wb_rst_i
:
in
STD_LOGIC
;
wb_stb_o
:
out
STD_LOGIC
;
wb_cyc_o
:
out
STD_LOGIC
;
wb_sel_o
:
out
STD_LOGIC_VECTOR
(
3
downto
0
);
wb_we_o
:
out
STD_LOGIC
;
wb_data_i
:
in
STD_LOGIC_VECTOR
(
g_WB_DATA_I_LENGTH
-
1
downto
0
);
wb_data_o
:
out
STD_LOGIC_VECTOR
(
g_WB_DATA_O_LENGTH
-
1
downto
0
);
wb_addr_o
:
out
STD_LOGIC_VECTOR
(
g_WB_ADDR_LENGTH
-
1
downto
0
);
wb_ack_i
:
in
STD_LOGIC
;
wb_rty_i
:
in
STD_LOGIC
;
wb_err_i
:
in
STD_LOGIC
;
data_i
:
in
STD_LOGIC_VECTOR
(
g_WB_DATA_O_LENGTH
-
1
downto
0
);
data_o
:
out
STD_LOGIC_VECTOR
(
g_WB_DATA_I_LENGTH
-
1
downto
0
);
addr_i
:
in
STD_LOGIC_VECTOR
(
g_WB_ADDR_LENGTH
-
1
downto
0
);
write_i
:
in
STD_LOGIC
;
write_done_o
:
out
STD_LOGIC
;
read_i
:
in
STD_LOGIC
;
read_done_o
:
out
STD_LOGIC
);
end
wishbone_driver
;
architecture
Behavioral
of
wishbone_driver
is
begin
p_read_write
:
process
begin
if
read_i
=
'1'
then
wait
until
rising_edge
(
wb_clk_i
);
wb_we_o
<=
'0'
;
wb_stb_o
<=
'1'
;
wb_cyc_o
<=
'1'
;
wb_sel_o
<=
(
others
=>
'1'
);
wb_addr_o
<=
addr_i
;
wait
until
rising_edge
(
wb_clk_i
);
wait
until
wb_ack_i
'event
;
--! Here we wait for the ack and keep till operation is finished
data_o
<=
wb_data_i
;
wait
until
rising_edge
(
wb_clk_i
);
wb_stb_o
<=
'0'
;
wb_cyc_o
<=
'0'
;
wb_sel_o
<=
(
others
=>
'0'
);
read_done_o
<=
'1'
;
elsif
write_i
=
'1'
then
wait
until
rising_edge
(
wb_clk_i
);
wb_we_o
<=
'1'
;
wb_stb_o
<=
'1'
;
wb_cyc_o
<=
'1'
;
wb_sel_o
<=
(
others
=>
'1'
);
wb_data_o
<=
data_i
;
wb_addr_o
<=
addr_i
;
wait
until
rising_edge
(
wb_clk_i
);
--! Here we wait for the ack and keep till operation is finished
wait
until
rising_edge
(
wb_clk_i
);
wb_we_o
<=
'0'
;
wb_stb_o
<=
'0'
;
wb_cyc_o
<=
'0'
;
wb_sel_o
<=
(
others
=>
'0'
);
write_done_o
<=
'1'
;
else
wb_stb_o
<=
'0'
;
wb_cyc_o
<=
'0'
;
wb_sel_o
<=
(
others
=>
'0'
);
wb_we_o
<=
'0'
;
wb_data_o
<=
(
others
=>
'0'
);
wb_addr_o
<=
(
others
=>
'0'
);
data_o
<=
(
others
=>
'0'
);
write_done_o
<=
'0'
;
read_done_o
<=
'0'
;
end
if
;
wait
until
rising_edge
(
wb_clk_i
);
end
process
;
end
;
hdl/ctdah_lib/test/wishbone_driver_pkg.vhd
0 → 100644
View file @
3f50efec
library
IEEE
;
use
IEEE
.
STD_LOGIC_1164
.
all
;
use
IEEE
.
NUMERIC_STD
.
ALL
;
package
wishbone_driver_pkg
is
component
wishbone_driver
is
generic
(
g_WB_DATA_O_LENGTH
:
NATURAL
:
=
32
;
g_WB_DATA_I_LENGTH
:
NATURAL
:
=
32
;
g_WB_ADDR_LENGTH
:
NATURAL
:
=
6
;
g_WB_CLK_PERIOD
:
TIME
:
=
50
ns
);
port
(
wb_clk_i
:
in
STD_LOGIC
;
wb_rst_i
:
in
STD_LOGIC
;
wb_stb_o
:
out
STD_LOGIC
;
wb_cyc_o
:
out
STD_LOGIC
;
wb_sel_o
:
out
STD_LOGIC_VECTOR
(
3
downto
0
);
wb_we_o
:
out
STD_LOGIC
;
wb_data_i
:
in
STD_LOGIC_VECTOR
(
g_WB_DATA_I_LENGTH
-
1
downto
0
);
wb_data_o
:
out
STD_LOGIC_VECTOR
(
g_WB_DATA_O_LENGTH
-
1
downto
0
);
wb_addr_o
:
out
STD_LOGIC_VECTOR
(
g_WB_ADDR_LENGTH
-
1
downto
0
);
wb_ack_i
:
in
STD_LOGIC
;
wb_rty_i
:
in
STD_LOGIC
;
wb_err_i
:
in
STD_LOGIC
;
data_i
:
in
STD_LOGIC_VECTOR
(
g_WB_DATA_O_LENGTH
-
1
downto
0
);
data_o
:
out
STD_LOGIC_VECTOR
(
g_WB_DATA_I_LENGTH
-
1
downto
0
);
addr_i
:
in
STD_LOGIC_VECTOR
(
g_WB_ADDR_LENGTH
-
1
downto
0
);
write_i
:
in
STD_LOGIC
;
write_done_o
:
out
STD_LOGIC
;
read_i
:
in
STD_LOGIC
;
read_done_o
:
out
STD_LOGIC
);
end
component
;
end
wishbone_driver_pkg
;
package
body
wishbone_driver_pkg
is
end
wishbone_driver_pkg
;
hdl/i2c_slave_wb_master/rtl/i2c_bit.vhd
View file @
3f50efec
...
...
@@ -75,6 +75,7 @@ architecture Behavioral of i2c_bit is
begin
debouncer_scl_i
:
i2c_debouncer
generic
map
(
g_LENGTH
=>
6
)
port
map
(
rst
=>
rst_i
,
...
...
@@ -83,12 +84,21 @@ begin
output
=>
s_scl_deglitched
,
glitch_mask
=>
c_GLITCH_MASK
);
--! Probably safer operation if we add one extra delay to the scl line.
--! However, we increase the glitch time while placing an ACK.
--! We have not implemented a counter to foresee the glitch due to the
--! strange behaviour in Renesas I2C which rescales dinamically (that
--! means in the middle of an I2C transaction) the scl line.
--! Due to the variability of the scl period when an I2C transaction is
--! in progress, it is better not to add a "guesser" of the scl period.
ff1_scl
:
gc_ff
port
map
(
Q
=>
s_scl_deglitched_d1
,
C
=>
wb_clk_i
,
CLR
=>
rst_i
,
D
=>
s_scl_deglitched
);
debouncer_sda_i
:
i2c_debouncer
generic
map
(
g_LENGTH
=>
6
)
port
map
(
rst
=>
rst_i
,
...
...
hdl/i2c_slave_wb_master/rtl/i2c_regs.vhd
View file @
3f50efec
This diff is collapsed.
Click to expand it.
hdl/i2c_slave_wb_master/rtl/i2c_slave_core.vhd
View file @
3f50efec
This diff is collapsed.
Click to expand it.
hdl/i2c_slave_wb_master/rtl/i2c_slave_pkg.vhd
View file @
3f50efec
...
...
@@ -26,7 +26,7 @@ use IEEE.NUMERIC_STD.ALL;
package
i2c_slave_pkg
is
--! Default clock divider
constant
c_
CLK_DIV
:
UNSIGNED
(
31
downto
28
)
:
=
to_unsigned
(
2
,
4
)
;
constant
c_
RST_EXTENSOR
:
NATURAL
:
=
4
;
constant
c_DEBOUNCE_LENGTH
:
NATURAL
:
=
6
;
--! Broadcast address as specified in I2C standard
constant
c_I2C_GENERAL_ADDR
:
UNSIGNED
(
6
downto
0
)
:
=
to_unsigned
(
0
,
7
);
...
...
@@ -48,13 +48,17 @@ package i2c_slave_pkg is
constant
c_RX_STACK_DEPTH
:
NATURAL
:
=
6
;
constant
c_TX_STACK_DEPTH
:
NATURAL
:
=
4
;
constant
c_WB_CLK_PERIOD
:
TIME
:
=
50
ns
;
constant
c_WATCHDOG_WIDTH
:
NATURAL
:
=
32
;
constant
c_WATCHDOG_DEADLINE
:
TIME
:
=
10
**
9
*
60
ns
;
constant
c_WATCHDOG_ENABLE
:
STD_LOGIC
:
=
'1'
;
attribute
a_length
:
NATURAL
;
-------------------------------------
-- CTR0 register
-------------------------------------
--
16
bits
--
32
bits
-- Wishbone access: Write-read
------------------------------------
-- BIT NAME Description
...
...
@@ -63,7 +67,7 @@ package i2c_slave_pkg is
-- 11-8 BIA Bytes of Indirect Addressing
-- 19-12 BRD Bytes to be ReaD from FPGA
-- 27-20 BWR Bytes to be WRitten to FPGA
-- 31-28
CLK_DIV Clock Divider for prescaling
-- 31-28
x Reserved
-------------------------------------
-- I2C_OP Operations
-- 0 Read from I2C
...
...
@@ -76,11 +80,32 @@ package i2c_slave_pkg is
BIA
:
UNSIGNED
(
11
downto
8
);
BRD
:
UNSIGNED
(
19
downto
12
);
BWR
:
UNSIGNED
(
27
downto
20
);
CLK_DIV
:
UNSIGNED
(
31
downto
28
);
x
:
STD_LOGIC_VECTOR
(
31
downto
28
);
end
record
;
attribute
a_length
of
r_CTR0
:
type
is
32
;
-------------------------------------
-- LT register
-------------------------------------
-- 32 bits
-- Wishbone access: Read-only
------------------------------------
-- BIT NAME Description
-- 7-0 WBCP WishBone Clock Period
-- 31-8 SCLP SCL Period
-------------------------------------
-- Both period are given with nanosecond
-- precision.
-------------------------------------
type
r_LT
is
record
WBCP
:
UNSIGNED
(
7
downto
0
);
SCLP
:
UNSIGNED
(
31
downto
8
);
end
record
;
attribute
a_length
of
r_LT
:
type
is
32
;
-------------------------------------
-- DRX register
-------------------------------------
...
...
@@ -115,18 +140,24 @@ package i2c_slave_pkg is
constant
c_CTR0_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"0"
;
constant
c_DTX_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"1"
;
constant
c_DRXA_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"2"
;
constant
c_DRXB_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"3"
;
constant
c_LT_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"1"
;
constant
c_DTX_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"2"
;
constant
c_DRXA_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"3"
;
constant
c_DRXB_addr
:
UNSIGNED
(
3
downto
0
)
:
=
X"4"
;
constant
c_CTR0_default
:
r_CTR0
:
=
(
I2C_OP
=>
'0'
,
I2C_ADDR
=>
c_I2C_GENERAL_ADDR
,
BIA
=>
to_unsigned
(
2
,
4
),
BRD
=>
to_unsigned
(
4
,
8
),
BWR
=>
to_unsigned
(
4
,
8
),
CLK_DIV
=>
c_CLK_DIV
);
x
=>
(
others
=>
'0'
));
constant
c_LT_default
:
r_LT
:
=
(
WBCP
=>
to_unsigned
(
c_WB_CLK_PERIOD
/
(
1
ns
),
8
),
SCLP
=>
to_unsigned
(
0
,
24
));
component
i2c_slave_core
generic
(
g_WB_CLK_PERIOD
:
TIME
:
=
50
ns
);
port
(
clk
:
in
STD_LOGIC
;
rst_i
:
in
STD_LOGIC
;
...
...
@@ -139,12 +170,14 @@ package i2c_slave_pkg is
scl_o
:
out
STD_LOGIC
;
CTR0_i
:
in
STD_LOGIC_VECTOR
(
r_CTR0
'a_length
-
1
downto
0
);
LT_o
:
out
STD_LOGIC_VECTOR
(
r_LT
'a_length
-
1
downto
0
);
DRXA_o
:
out
STD_LOGIC_VECTOR
(
r_DRX
'a_length
-
1
downto
0
);
DRXB_o
:
out
STD_LOGIC_VECTOR
(
r_DRX
'a_length
-
1
downto
0
);
DTX_i
:
in
STD_LOGIC_VECTOR
(
r_DTX
'a_length
-
1
downto
0
);
load_TX
:
in
STD_LOGIC
;
pf_wb_addr_o
:
out
STD_LOGIC
;
pf_wb_data_i
:
in
STD_LOGIC_VECTOR
(
31
downto
0
);
rd_done_o
:
out
STD_LOGIC
;
wr_done_o
:
out
STD_LOGIC
);
end
component
;
...
...
@@ -176,12 +209,14 @@ package i2c_slave_pkg is
wb_slave_err_o
:
out
STD_LOGIC
;
CTR0_o
:
out
STD_LOGIC_VECTOR
(
r_CTR0
'a_length
-
1
downto
0
);
LT_i
:
in
STD_LOGIC_VECTOR
(
r_LT
'a_length
-
1
downto
0
);
DRXA_i
:
in
STD_LOGIC_VECTOR
(
r_DRX
'a_length
-
1
downto
0
);
DRXB_i
:
in
STD_LOGIC_VECTOR
(
r_DRX
'a_length
-
1
downto
0
);
DTX_o
:
out
STD_LOGIC_VECTOR
(
r_DTX
'a_length
-
1
downto
0
);
load_TX
:
out
STD_LOGIC
;
pf_wb_addr_i
:
in
STD_LOGIC
;
pf_wb_data_o
:
out
STD_LOGIC_VECTOR
(
31
downto
0
);
rd_done_i
:
in
STD_LOGIC
;
wr_done_i
:
in
STD_LOGIC
;
i2c_addr_i
:
in
STD_LOGIC_VECTOR
(
6
downto
0
));
...
...
@@ -199,7 +234,6 @@ package i2c_slave_pkg is
component
i2c_bit
port
(
rst_i
:
in
STD_LOGIC
;
wb_clk_i
:
in
STD_LOGIC
;
sda_i
:
in
STD_LOGIC
;
scl_i
:
in
STD_LOGIC
;
start_o
:
out
STD_LOGIC
;
...
...
@@ -210,8 +244,12 @@ package i2c_slave_pkg is
function
f_CTR0
(
signal
r_register
:
in
STD_LOGIC_VECTOR
(
31
downto
0
))
return
r_CTR0
;
function
f_LT
(
signal
r_register
:
in
STD_LOGIC_VECTOR
(
31
downto
0
))
return
r_LT
;
function
f_STD_LOGIC_VECTOR
(
r_register
:
in
r_CTR0
)
return
STD_LOGIC_VECTOR
;
function
f_STD_LOGIC_VECTOR
(
r_register
:
in
r_LT
)
return
STD_LOGIC_VECTOR
;
end
i2c_slave_pkg
;
...
...
@@ -226,7 +264,25 @@ package body i2c_slave_pkg is
v_return
.
BIA
:
=
UNSIGNED
(
r_register
(
11
downto
8
));
v_return
.
BRD
:
=
UNSIGNED
(
r_register
(
19
downto
12
));
v_return
.
BWR
:
=
UNSIGNED
(
r_register
(
27
downto
20
));
v_return
.
CLK_DIV
:
=
UNSIGNED
(
r_register
(
31
downto
28
));
v_return
.
x
:
=
(
others
=>
'0'
);
return
v_return
;
end
function
;
function
f_LT
(
signal
r_register
:
in
STD_LOGIC_VECTOR
(
31
downto
0
))
return
r_LT
is
variable
v_return
:
r_LT
;
begin
v_return
.
WBCP
:
=
UNSIGNED
(
r_register
(
7
downto
0
));
v_return
.
SCLP
:
=
UNSIGNED
(
r_register
(
31
downto
8
));
return
v_return
;
end
function
;
function
f_STD_LOGIC_VECTOR
(
r_register
:
in
r_LT
)
return
STD_LOGIC_VECTOR
is
variable
v_return
:
STD_LOGIC_VECTOR
(
31
downto
0
);
begin
v_return
(
7
downto
0
)
:
=
STD_LOGIC_VECTOR
(
r_register
.
WBCP
);
v_return
(
31
downto
8
)
:
=
STD_LOGIC_VECTOR
(
r_register
.
SCLP
);
return
v_return
;
end
function
;
...
...
@@ -239,8 +295,9 @@ package body i2c_slave_pkg is
v_return
(
11
downto
8
)
:
=
STD_LOGIC_VECTOR
(
r_register
.
BIA
);
v_return
(
19
downto
12
)
:
=
STD_LOGIC_VECTOR
(
r_register
.
BRD
);
v_return
(
27
downto
20
)
:
=
STD_LOGIC_VECTOR
(
r_register
.
BWR
);
v_return
(
31
downto
28
)
:
=
STD_LOGIC_VECTOR
(
r_register
.
CLK_DIV
);
v_return
(
31
downto
28
)
:
=
(
others
=>
'0'
);
return
v_return
;
end
function
;
end
i2c_slave_pkg
;
hdl/i2c_slave_wb_master/rtl/i2c_slave_top.vhd
View file @
3f50efec
...
...
@@ -26,6 +26,7 @@ use work.i2c_slave_pkg.ALL;
use
work
.
ctdah_pkg
.
ALL
;
entity
i2c_slave_top
is
generic
(
g_WB_CLK_PERIOD
:
TIME
:
=
c_WB_CLK_PERIOD
);
-- Specify in ns
port
(
sda_oen
:
out
STD_LOGIC
;
sda_i
:
in
STD_LOGIC
;
...
...
@@ -69,6 +70,7 @@ architecture Behavioral of i2c_slave_top is
signal
s_CTR0_slv
:
STD_LOGIC_VECTOR
(
r_CTR0
'a_length
-
1
downto
0
);
signal
s_CTR0
:
r_CTR0
;
signal
s_LT_slv
:
STD_LOGIC_VECTOR
(
r_LT
'a_length
-
1
downto
0
);
signal
s_DRXA
:
STD_LOGIC_VECTOR
(
r_DRX
'a_length
-
1
downto
0
);
signal
s_DRXB
:
STD_LOGIC_VECTOR
(
r_DRX
'a_length
-
1
downto
0
);
...
...
@@ -76,12 +78,13 @@ architecture Behavioral of i2c_slave_top is
signal
s_load_TX
:
STD_LOGIC
;
signal
s_pf_wb_addr
:
STD_LOGIC
;
signal
s_pf_wb_data
:
STD_LOGIC_VECTOR
(
31
downto
0
);
signal
s_rd_done
:
STD_LOGIC
;
signal
s_wr_done
:
STD_LOGIC
;
signal
s_clk_i2c
:
STD_LOGIC
;
signal
s_rst_i2c
:
STD_LOGIC
;
signal
s_reset_extensor
:
STD_LOGIC_VECTOR
(
2
**
c_
CLK_DIV
'length
-
1
signal
s_clk_i2c
:
STD_LOGIC
;
signal
s_rst_i2c
:
STD_LOGIC
;
signal
s_reset_extensor
:
STD_LOGIC_VECTOR
(
2
**
c_
RST_EXTENSOR
-
1
downto
0
)
:
=
(
others
=>
'1'
);
begin
...
...
@@ -91,8 +94,8 @@ begin
s_CTR0
<=
f_CTR0
(
s_CTR0_slv
);
inst_i2c_slave_core
:
i2c_slave_core
port
map
(
clk
=>
wb_clk
,
--s_clk_i2c,
rst_i
=>
wb_rst_i
,
--s_rst_i2c,
port
map
(
clk
=>
wb_clk
,
rst_i
=>
wb_rst_i
,
sda_oen
=>
sda_oen
,
sda_i
=>
sda_i
,
...
...
@@ -102,17 +105,20 @@ begin
scl_o
=>
scl_o
,
CTR0_i
=>
s_CTR0_slv
,
LT_o
=>
s_LT_slv
,
DRXA_o
=>
s_DRXA
,
DRXB_o
=>
s_DRXB
,
DTX_i
=>
s_DTX
,
load_tx
=>
s_load_tx
,
pf_wb_addr_o
=>
s_pf_wb_addr
,
pf_wb_data_i
=>
s_pf_wb_data
,
rd_done_o
=>
s_rd_done
,
wr_done_o
=>
s_wr_done
);
inst_i2c_regs
:
i2c_regs
port
map
(
pf_wb_addr_i
=>
s_pf_wb_addr
,
pf_wb_data_o
=>
s_pf_wb_data
,
rd_done_i
=>
s_rd_done
,
wr_done_i
=>
s_wr_done
,
...
...
@@ -141,7 +147,8 @@ begin
wb_slave_rty_o
=>
wb_slave_rty_o
,
wb_slave_err_o
=>
wb_slave_err_o
,
CTR0_o
=>
s_CTR0_slv
,
CTR0_o
=>
s_CTR0_slv
,
LT_i
=>
s_LT_slv
,
DRXA_i
=>
s_DRXA
,
DRXB_i
=>
s_DRXB
,
DTX_o
=>
s_DTX
,
...
...
@@ -149,16 +156,7 @@ begin
i2c_addr_i
=>
i2c_addr_i
);
inst_clk_divider
:
gc_clk_divider
generic
map
(
g_clk_division_logSize
=>
4
)
port
map
(
clk_i
=>
wb_clk
,
rst_i
=>
wb_rst_i
,
oe_n_i
=>
'0'
,
clk_o
=>
s_clk_i2c
,
--Divides by twice the value specified
divider_i
=>
STD_LOGIC_VECTOR
(
s_CTR0
.
CLK_DIV
));
s_rst_i2c
<=
s_reset_extensor
(
2
**
c_CLK_DIV
'length
-
1
);
s_rst_i2c
<=
s_reset_extensor
(
2
**
c_RST_EXTENSOR
-
1
);
--! A shift with reset, consumes just a few SLICEX in Spartan6.
p_rst_extender
:
process
(
wb_clk
)
...
...
@@ -168,7 +166,7 @@ begin
s_reset_extensor
<=
(
others
=>
'1'
);
else
s_reset_extensor
(
0
)
<=
'0'
;
for
i
in
1
to
2
**
c_
CLK_DIV
'length
-1
loop
for
i
in
1
to
2
**
c_
RST_EXTENSOR
-1
loop
s_reset_extensor
(
i
)
<=
s_reset_extensor
(
i
-1
);
end
loop
;
end
if
;
...
...
hdl/i2c_slave_wb_master/test/i2c_master_driver.vhd
View file @
3f50efec
...
...
@@ -62,6 +62,10 @@ architecture Behavioral of i2c_master_driver is
signal
s_active_link
:
STD_LOGIC
:
=
'0'
;
signal
s_i2c_addr_op
:
STD_LOGIC_VECTOR
(
7
downto
0
);
signal
s_DTX
:
STD_LOGIC_VECTOR
(
31
downto
0
)
:
=
(
others
=>
'0'
);
begin
file_open
(
s_file_handler
,
c_LOG_PATH
,
WRITE_MODE
);
...
...
@@ -83,7 +87,7 @@ begin
p_sda
:
process
variable
v_bit_number
:
NATURAL
:
=
0
;
variable
v_write_data
:
STD_LOGIC_VECTOR
(
g_RD_DATA_LENGTH
-
1
downto
0
);
variable
v_i2c_addr_op
:
STD_LOGIC_VECTOR
(
7
downto
0
);
--! @brief Function that returns strings for the acked field to be
--! logged.
...
...
@@ -114,6 +118,17 @@ begin
return
v_return
;
end
function
;
function
order_i2c_addr_op
(
i2c_addr_op
:
STD_LOGIC_VECTOR
(
7
downto
0
))
return
STD_LOGIC_VECTOR
is
variable
v_return
:
STD_LOGIC_VECTOR
(
7
downto
0
);
begin
for
i
in
0
to
7
loop
v_return
(
7
-
i
)
:
=
i2c_addr_op
(
i
);
end
loop
;
return
v_return
;
end
function
;
--! @brief Function to reorder data before being sent by driver
--! through SDA
--! @param data Data to be reordered before being sent
...
...
@@ -184,6 +199,21 @@ begin
wait
until
falling_edge
(
s_scl_clk
);
end
procedure
;
--! @brieg Procedure to start/restart I2C communication
procedure
start_restart_I2c
is
begin
wait
until
rising_edge
(
s_scl_clk
);
wait
for
g_SCL_PERIOD
/
4
;
s_sda_master_o
<=
'0'
;
s_active_link
<=
'1'
;
wait
until
falling_edge
(
s_scl_clk
);
wait
until
rising_edge
(
tb_clk
);
s_start_done
<=
'1'
;
wait
until
rising_edge
(
tb_clk
);
s_start_done
<=
'0'
;
end
procedure
;
--! @brief Procedure to pause I2c communication
procedure
pause_I2C
is
begin
wait
for
g_SCL_PERIOD
/
4
;
...
...
@@ -192,32 +222,75 @@ begin
wait
for
g_SCL_PERIOD
/
4
;
s_sda_master_o
<=
'1'
;
s_active_link
<=
'1'
;
wait
until
falling_edge
(
s_scl_clk
);
--! We allow one clock to let i2c_slave_core.vhd to react
wait
until
rising_edge
(
tb_clk
);
s_pause_done
<=
'1'
;
wait
until
rising_edge
(
tb_clk
);
s_pause_done
<=
'0'
;
s_active_link
<=
'0'
;
end
procedure
;
begin
if
start_i
=
'1'
the
n
procedure
read_bit
is
variable
v_bit_rcv
:
STD_LOGIC
;
begi
n
wait
until
rising_edge
(
s_scl_clk
);
v_bit_rcv
:
=
sda_master_i
;
for
i
in
0
to
(
g_SCL_PERIOD
/
2
)
/
(
1
ns
)
-
1
loop
if
v_bit_rcv
/=
sda_master_i
then
--! Here we report an error
end
if
;
wait
for
1
ns
;
end
loop
;
wait
until
falling_edge
(
s_scl_clk
);
s_DTX
(
s_DTX
'length
-
1
)
<=
v_bit_rcv
;
end
procedure
;
procedure
shift_bit
is
begin
for
i
in
1
to
s_DTX
'length
-
1
loop
s_DTX
(
i
-1
)
<=
s_DTX
(
i
);
end
loop
;
end
procedure
;
procedure
read_byte
is
begin
for
i
in
0
to
7
loop
read_bit
;
shift_bit
;
end
loop
;
--! At the end we are just in the falling edge of scl
end
procedure
;
procedure
place_ack
is
begin
wait
for
g_SCL_PERIOD
/
4
;
s_sda_master_o
<=
'0'
;
s_active_link
<=
'1'
;
wait
until
falling_edge
(
s_scl_clk
);
wait
until
rising_edge
(
tb_clk
);
s_start_done
<=
'1'
;
wait
until
rising_edge
(
tb_clk
);
s_start_done
<=
'0'
;
s_sda_master_o
<=
'1'
;
end
procedure
;
procedure
place_nack
is
begin
wait
for
g_SCL_PERIOD
/
4
;
s_sda_master_o
<=
'1'
;
wait
until
falling_edge
(
s_scl_clk
);
s_sda_master_o
<=
'0'
;
end
procedure
;
begin
if
start_i
=
'1'
then
start_restart_I2c
;
elsif
pause_i
=
'1'
then
pause_I2C
;
elsif
write_i
=
'1'
then
s_test_id
<=
s_test_id
+
1
;
v_write_data
:
=
order_write_data
(
wr_data_i
);
--! 1.- Send [ADDRESS|0]
send_byte
(
i2c_addr_op_i
);
v_i2c_addr_op
:
=
i2c_addr_op_i
;
v_i2c_addr_op
(
0
)
:
=
'0'
;
send_byte
(
order_i2c_addr_op
(
v_i2c_addr_op
));
check_ack
(
s_test_id
,
"WRITE"
,
ADDRESS_0
);
--! 2.- Send wishbone address high
send_byte
(
wishbone_addr_i
(
15
downto
8
));
...
...
@@ -238,7 +311,46 @@ begin
send_byte
(
wr_data_i
(
31
downto
24
));
check_ack
(
s_test_id
,
"WRITE"
,
DATA3
);
pause_I2C
;
s_write_done
<=
'1'
;
wait
until
rising_edge
(
tb_clk
);
s_write_done
<=
'0'
;
elsif
read_i
=
'1'
then
s_test_id
<=
s_test_id
+
1
;
v_write_data
:
=
order_write_data
(
wr_data_i
);
--! 1.- Send [ADDRESS|0]
v_i2c_addr_op
:
=
i2c_addr_op_i
;
v_i2c_addr_op
(
0
)
:
=
'0'
;
send_byte
(
order_i2c_addr_op
(
v_i2c_addr_op
));
check_ack
(
s_test_id
,
" READ"
,
ADDRESS_0
);
--! 2.- Send wishbone address high
send_byte
(
wishbone_addr_i
(
15
downto
8
));
check_ack
(
s_test_id
,
" READ"
,
WISHBONE_HIGH
);
--! 3.- Send wishbone address low
send_byte
(
wishbone_addr_i
(
7
downto
0
));
check_ack
(
s_test_id
,
" READ"
,
WISHBONE_LOW
);
--! 4.- We have to place a start condition
start_restart_I2c
;
--! 5.- Send [ADDRESS|1]
v_i2c_addr_op
(
7
downto
1
)
:
=
i2c_addr_op_i
(
7
downto
1
);
v_i2c_addr_op
(
0
)
:
=
'1'
;
send_byte
(
order_i2c_addr_op
(
v_i2c_addr_op
));
check_ack
(
s_test_id
,
" READ"
,
ADDRESS_0
);
--! 6.- Read DATA0
read_byte
;
place_ack
;
--! 7.- Read DATA1
read_byte
;
place_ack
;
--! 8.- Read DATA2
read_byte
;
place_ack
;
--! 9.- Read DATA3
read_byte
;
place_ack
;
pause_I2C
;
s_read_done
<=
'1'
;
wait
until
rising_edge
(
tb_clk
);
s_read_done
<=
'0'
;
end
if
;
wait
until
rising_edge
(
tb_clk
);
end
process
;
...
...
hdl/i2c_slave_wb_master/test/i2c_slave_top_tb.vhd
View file @
3f50efec
This diff is collapsed.
Click to expand it.
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