Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
E
EtherBone Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
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
EtherBone Core
Commits
7f73d07d
Commit
7f73d07d
authored
Sep 10, 2020
by
Michael Reese
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eb_sim_core: fix a few bugs. saftlib works
parent
67819d32
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
166 additions
and
34 deletions
+166
-34
simbridge.vhd
hdl/eb_sim_core/simbridge.vhd
+20
-8
simbridge_pkg.vhd
hdl/eb_sim_core/simbridge_pkg.vhd
+25
-8
simbridge_pkg_c.cpp
hdl/eb_sim_core/simbridge_pkg_c.cpp
+121
-18
No files found.
hdl/eb_sim_core/simbridge.vhd
View file @
7f73d07d
...
...
@@ -6,13 +6,16 @@ use work.simbridge_pkg.all;
entity
simbridge
is
generic
(
g_sdb_address
:
t_wishbone_address
g_sdb_address
:
t_wishbone_address
;
g_simbridge_msi
:
t_sdb_msi
:
=
c_simbridge_msi
);
port
(
clk_i
:
in
std_logic
;
rstn_i
:
in
std_logic
;
master_o
:
out
t_wishbone_master_out
;
master_i
:
in
t_wishbone_master_in
clk_i
:
in
std_logic
;
rstn_i
:
in
std_logic
;
master_o
:
out
t_wishbone_master_out
;
master_i
:
in
t_wishbone_master_in
;
msi_slave_i
:
in
t_wishbone_slave_in
;
msi_slave_o
:
out
t_wishbone_slave_out
);
end
entity
;
...
...
@@ -23,6 +26,10 @@ begin
variable
master_o_dat
,
master_o_adr
,
master_o_sel
:
integer
;
variable
master_i_ack
,
master_i_err
,
master_i_rty
,
master_i_stall
:
std_logic
;
variable
master_i_dat
:
integer
;
variable
msi_slave_i_cyc
,
msi_slave_i_stb
,
msi_slave_i_we
:
std_logic
;
variable
msi_slave_i_dat
,
msi_slave_i_adr
,
msi_slave_i_sel
:
integer
;
variable
msi_slave_o_ack
,
msi_slave_o_err
,
msi_slave_o_rty
,
msi_slave_o_stall
:
std_logic
;
variable
msi_slave_o_dat
:
integer
;
constant
stop_until_connected
:
integer
:
=
1
;
begin
master_o
.
cyc
<=
'0'
;
...
...
@@ -34,11 +41,15 @@ begin
wait
until
rising_edge
(
rstn_i
);
wait
until
rising_edge
(
clk_i
);
eb_simbridge_init
(
stop_until_connected
,
to_integer
(
signed
(
g_sdb_address
)));
eb_simbridge_init
(
stop_until_connected
,
to_integer
(
signed
(
g_sdb_address
)),
to_integer
(
signed
(
g_simbridge_msi
.
sdb_component
.
addr_first
)),
to_integer
(
signed
(
g_simbridge_msi
.
sdb_component
.
addr_last
)));
while
true
loop
wait
until
rising_edge
(
clk_i
);
eb_simbridge_control_out
(
master_o_cyc
,
master_o_stb
,
master_o_we
,
master_o_adr
,
master_o_dat
,
master_o_sel
);
eb_simbridge_msi_slave_in
(
msi_slave_i_cyc
,
msi_slave_i_stb
,
msi_slave_i_we
,
msi_slave_i_adr
,
msi_slave_i_dat
,
msi_slave_i_sel
);
eb_simbridge_master_out
(
master_o_cyc
,
master_o_stb
,
master_o_we
,
master_o_adr
,
master_o_dat
,
master_o_sel
);
master_o
.
cyc
<=
master_o_cyc
;
master_o
.
stb
<=
master_o_stb
;
master_o
.
we
<=
master_o_we
;
...
...
@@ -52,7 +63,8 @@ begin
master_i_rty
:
=
master_i
.
rty
;
master_i_stall
:
=
master_i
.
stall
;
master_i_dat
:
=
to_integer
(
signed
(
master_i
.
dat
));
eb_simbridge_control_in
(
master_i_ack
,
master_i_err
,
master_i_rty
,
master_i_stall
,
master_i_dat
);
eb_simbridge_master_in
(
master_i_ack
,
master_i_err
,
master_i_rty
,
master_i_stall
,
master_i_dat
);
eb_simbridge_msi_slave_out
(
msi_slave_o_ack
,
msi_slave_o_err
,
msi_slave_o_rty
,
msi_slave_o_stall
,
msi_slave_o_dat
);
end
loop
;
end
process
;
...
...
hdl/eb_sim_core/simbridge_pkg.vhd
View file @
7f73d07d
...
...
@@ -20,32 +20,49 @@ package simbridge_pkg is
--eb_slave_control(master_o_cyc,master_o_stb,master_o_we,master_o_adr,master_o_dat,
-- master_i_ack,master_i_err,master_i_rty,master_i_stall_master_i_dat);
procedure
eb_simbridge_init
(
stop_unitl_connected
:
in
integer
;
sdb_adr
:
in
integer
);
procedure
eb_simbridge_init
(
stop_unitl_connected
:
in
integer
;
sdb_adr
,
msi_addr_first
,
msi_addr_last
:
in
integer
);
attribute
foreign
of
eb_simbridge_init
:
procedure
is
"VHPIDIRECT eb_simbridge_init"
;
procedure
eb_simbridge_
control
_out
(
cyc
,
stb
,
we
:
out
std_logic
;
adr
,
dat
,
sel
:
out
integer
);
attribute
foreign
of
eb_simbridge_
control_out
:
procedure
is
"VHPIDIRECT eb_simbridge_control
_out"
;
procedure
eb_simbridge_
master
_out
(
cyc
,
stb
,
we
:
out
std_logic
;
adr
,
dat
,
sel
:
out
integer
);
attribute
foreign
of
eb_simbridge_
master_out
:
procedure
is
"VHPIDIRECT eb_simbridge_master
_out"
;
procedure
eb_simbridge_control_in
(
ack
,
err
,
rty
,
stall
:
in
std_logic
;
dat
:
in
integer
);
attribute
foreign
of
eb_simbridge_control_in
:
procedure
is
"VHPIDIRECT eb_simbridge_control_in"
;
procedure
eb_simbridge_master_in
(
ack
,
err
,
rty
,
stall
:
in
std_logic
;
dat
:
in
integer
);
attribute
foreign
of
eb_simbridge_master_in
:
procedure
is
"VHPIDIRECT eb_simbridge_master_in"
;
procedure
eb_simbridge_msi_slave_out
(
ack
,
err
,
rty
,
stall
:
out
std_logic
;
dat
:
out
integer
);
attribute
foreign
of
eb_simbridge_msi_slave_out
:
procedure
is
"VHPIDIRECT eb_simbridge_msi_slave_out"
;
procedure
eb_simbridge_msi_slave_in
(
cyc
,
stb
,
we
:
in
std_logic
;
adr
,
dat
,
sel
:
in
integer
);
attribute
foreign
of
eb_simbridge_msi_slave_in
:
procedure
is
"VHPIDIRECT eb_simbridge_msi_slave_in"
;
end
package
;
package
body
simbridge_pkg
is
procedure
eb_simbridge_init
(
stop_unitl_connected
:
in
integer
;
sdb_adr
:
in
integer
)
is
procedure
eb_simbridge_init
(
stop_unitl_connected
:
in
integer
;
sdb_adr
,
msi_addr_first
,
msi_addr_last
:
in
integer
)
is
begin
assert
false
report
"VHPI"
severity
failure
;
end
procedure
;
procedure
eb_simbridge_master_out
(
cyc
,
stb
,
we
:
out
std_logic
;
adr
,
dat
,
sel
:
out
integer
)
is
begin
assert
false
report
"VHPI"
severity
failure
;
end
procedure
;
procedure
eb_simbridge_
control_out
(
cyc
,
stb
,
we
:
out
std_logic
;
adr
,
dat
,
sel
:
out
integer
)
is
procedure
eb_simbridge_
master_in
(
ack
,
err
,
rty
,
stall
:
in
std_logic
;
dat
:
in
integer
)
is
begin
assert
false
report
"VHPI"
severity
failure
;
end
procedure
;
procedure
eb_simbridge_
control_in
(
ack
,
err
,
rty
,
stall
:
in
std_logic
;
dat
:
in
integer
)
is
procedure
eb_simbridge_
msi_slave_out
(
ack
,
err
,
rty
,
stall
:
out
std_logic
;
dat
:
out
integer
)
is
begin
assert
false
report
"VHPI"
severity
failure
;
end
procedure
;
procedure
eb_simbridge_msi_slave_in
(
cyc
,
stb
,
we
:
in
std_logic
;
adr
,
dat
,
sel
:
in
integer
)
is
begin
assert
false
report
"VHPI"
severity
failure
;
end
procedure
;
end
package
body
;
\ No newline at end of file
hdl/eb_sim_core/simbridge_pkg_c.cpp
View file @
7f73d07d
...
...
@@ -95,10 +95,12 @@ public:
}
EBslave
(
bool
stop_until_connected
,
uint32_t
sdb_adr
)
EBslave
(
bool
stop_until_connected
,
uint32_t
sdb_adr
,
uint32_t
msi_addr_first
,
uint32_t
msi_addr_last
)
{
_stop_until_connected
=
stop_until_connected
;
eb_sdb_adr
=
sdb_adr
;
eb_sdb_adr
=
sdb_adr
;
eb_msi_adr_first
=
msi_addr_first
;
eb_msi_adr_last
=
msi_addr_last
;
init
();
}
...
...
@@ -173,7 +175,7 @@ public:
}
void
control
_out
(
std_logic_t
*
cyc
,
std_logic_t
*
stb
,
std_logic_t
*
we
,
int
*
adr
,
int
*
dat
,
int
*
sel
)
{
void
master
_out
(
std_logic_t
*
cyc
,
std_logic_t
*
stb
,
std_logic_t
*
we
,
int
*
adr
,
int
*
dat
,
int
*
sel
)
{
// std::cerr << "out " << state << std::endl;
// std::cerr << "control_out" << std::endl;
...
...
@@ -199,12 +201,12 @@ public:
break
;
case
EB_SLAVE_STATE_EB_HEADER
:
if
(
next_word
(
word
))
{
// eb record header
eb_flag_bca
=
word
&
0x80000000
;
eb_flag_rca
=
word
&
0x40000000
;
eb_flag_rff
=
word
&
0x20000000
;
eb_flag_cyc
=
word
&
0x08000000
;
eb_flag_wca
=
word
&
0x04000000
;
eb_flag_wff
=
word
&
0x02000000
;
eb_flag_bca
=
word
&
0x80000000
;
eb_flag_rca
=
word
&
0x40000000
;
eb_flag_rff
=
word
&
0x20000000
;
eb_flag_cyc
=
word
&
0x08000000
;
eb_flag_wca
=
word
&
0x04000000
;
eb_flag_wff
=
word
&
0x02000000
;
eb_byte_en
=
(
word
&
0x00ff0000
)
>>
16
;
eb_wcount
=
(
word
&
0x0000ff00
)
>>
8
;
eb_rcount
=
(
word
&
0x000000ff
)
>>
0
;
...
...
@@ -293,6 +295,47 @@ public:
// ... or here ????
wb_stbs
.
push_back
(
wb_stb
(
eb_sdb_adr
,
eb_sdb_adr
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
case
0x2c
:
wb_stbs
.
push_back
(
wb_stb
(
0x1
,
0x1
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
case
0x34
:
wb_stbs
.
push_back
(
wb_stb
(
eb_msi_adr_first
,
eb_msi_adr_first
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
case
0x3c
:
wb_stbs
.
push_back
(
wb_stb
(
eb_msi_adr_last
,
eb_msi_adr_last
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
case
0x40
:
// msi_adr
if
(
msi_queue
.
size
()
>
0
)
{
msi_adr
=
msi_queue
.
front
().
adr
;
msi_dat
=
msi_queue
.
front
().
dat
;
msi_cnt
=
1
;
if
(
msi_queue
.
size
()
>
1
)
{
msi_cnt
=
3
;
}
}
else
{
msi_cnt
=
0
;
}
wb_stbs
.
push_back
(
wb_stb
(
msi_adr
,
msi_adr
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
case
0x44
:
// msi_dat
wb_stbs
.
push_back
(
wb_stb
(
msi_dat
,
msi_dat
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
case
0x48
:
wb_stbs
.
push_back
(
wb_stb
(
msi_cnt
,
msi_cnt
,
false
,
true
));
// not a real strobe, just a pass-through
break
;
// x"00000000" when "01000", -- 0x20 = 0[010 00]00
// x"00000000" when "01001", -- 0x24 = 0[010 01]00
// x"00000000" when "01010", -- 0x28
// x"00000001" when "01011", -- 0x2c
// x"00000000" when "01100", -- 0x30
// c_ebs_msi.sdb_component.addr_first(31 downto 0) when "01101", -- 0x34
// x"00000000" when "01110", -- 0x38
// c_ebs_msi.sdb_component.addr_last(31 downto 0) when "01111", -- 0x3c
// msi_adr when "10000", -- 0x40 = 0[100 00]00
// msi_dat when "10001", -- 0x44 = 0[100 01]00
// msi_cnt when "10010", -- 0x48 = 0[100 10]00
// x"00000000" when others;
default
:
wb_stbs
.
push_back
(
wb_stb
(
0x0
,
0x0
,
false
,
true
));
// not a real strobe, just a pass-through
wb_stbs
.
back
().
err
=
true
;
...
...
@@ -308,7 +351,8 @@ public:
if
(
eb_wcount
>
0
)
{
if
(
next_word
(
base_write_adr
))
{
// output_word_buffer.push_back(base_write_adr);
wb_stbs
.
push_back
(
wb_stb
(
base_write_adr
,
base_write_adr
,
false
,
true
));
// not a real strobe, just a pass-through
wb_stbs
.
push_back
(
wb_stb
(
0x0
,
0x0
,
false
,
true
));
// not a real strobe, just a pass-through
// wb_stbs.back().zero = true;
state
=
EB_SLAVE_STATE_EB_WISHBONE_REST
;
}
}
else
if
(
eb_rcount
>
0
)
{
...
...
@@ -330,6 +374,7 @@ public:
wb_stbs
.
push_back
(
wb_stb
(
base_write_adr
,
write_val
,
true
));
if
(
eb_wcount
==
0
)
{
wb_stbs
.
back
().
new_header
=
true
;
wb_stbs
.
back
().
new_header_value
=
new_header
;
}
else
{
wb_stbs
.
back
().
zero
=
true
;
}
...
...
@@ -434,7 +479,7 @@ public:
}
// should be called on falling_edge(clk)
void
control
_in
(
std_logic_t
ack
,
std_logic_t
err
,
std_logic_t
rty
,
std_logic_t
stall
,
int
dat
)
{
void
master
_in
(
std_logic_t
ack
,
std_logic_t
err
,
std_logic_t
rty
,
std_logic_t
stall
,
int
dat
)
{
// std::cerr << "in" << std::endl;
// std::cerr << "control_in wb_stbs.size() = " << std::dec << (int)wb_stbs.size() << std::endl;
handle_pass_through
();
...
...
@@ -447,7 +492,7 @@ public:
if
(
wb_wait_for_acks
.
front
().
zero
)
{
output_word_buffer
.
push_back
(
0x0
);
}
else
if
(
wb_wait_for_acks
.
front
().
new_header
)
{
output_word_buffer
.
push_back
(
new_header
);
output_word_buffer
.
push_back
(
wb_wait_for_acks
.
front
().
new_header_value
);
}
else
{
output_word_buffer
.
push_back
(
wb_wait_for_acks
.
front
().
dat
);
}
...
...
@@ -466,6 +511,31 @@ public:
}
void
msi_slave_out
(
std_logic_t
*
ack
,
std_logic_t
*
err
,
std_logic_t
*
rty
,
std_logic_t
*
stall
,
int
*
dat
)
{
*
ack
=
STD_LOGIC_0
;
*
err
=
STD_LOGIC_0
;
*
rty
=
STD_LOGIC_0
;
*
stall
=
STD_LOGIC_0
;
if
(
msi_slave_out_ack
)
*
ack
=
STD_LOGIC_1
;
if
(
msi_slave_out_err
)
*
err
=
STD_LOGIC_1
;
*
dat
=
0x0
;
}
void
msi_slave_in
(
std_logic_t
cyc
,
std_logic_t
stb
,
std_logic_t
we
,
int
adr
,
int
dat
,
int
sel
)
{
msi_slave_out_ack
=
false
;
msi_slave_out_err
=
false
;
if
(
cyc
==
STD_LOGIC_1
&&
stb
==
STD_LOGIC_1
)
{
if
(
we
==
STD_LOGIC_1
)
{
msi_slave_out_ack
=
true
;
msi_queue
.
push_back
(
MSI
(
adr
,
dat
));
// ignore sel
}
else
{
msi_slave_out_err
=
true
;
// msi_slave is write-only!
}
}
}
private
:
struct
pollfd
pfds
[
1
];
std
::
deque
<
uint32_t
>
input_word_buffer
;
...
...
@@ -484,6 +554,21 @@ private:
uint32_t
error_shift_reg
;
uint32_t
eb_sdb_adr
;
uint32_t
eb_msi_adr_first
;
uint32_t
eb_msi_adr_last
;
bool
msi_slave_out_ack
;
bool
msi_slave_out_err
;
struct
MSI
{
MSI
(
uint32_t
a
,
uint32_t
d
)
:
adr
(
a
),
dat
(
d
)
{}
uint32_t
adr
;
uint32_t
dat
;
};
std
::
deque
<
MSI
>
msi_queue
;
uint32_t
msi_adr
;
uint32_t
msi_dat
;
uint32_t
msi_cnt
;
// state machine of the EB-slave
...
...
@@ -512,6 +597,7 @@ private:
bool
passthrough
;
bool
zero
;
bool
new_header
;
uint32_t
new_header_value
;
wb_stb
(
uint32_t
a
,
uint32_t
d
,
bool
w
,
bool
pt
=
false
)
:
adr
(
a
),
dat
(
d
),
we
(
w
),
ack
(
false
),
err
(
false
),
passthrough
(
pt
),
zero
(
false
),
new_header
(
false
)
{};
};
...
...
@@ -527,23 +613,40 @@ private:
EBslave
*
slave
;
extern
"C"
void
eb_simbridge_init
(
int
stop_until_connected
,
int
sdb_adr
)
{
slave
=
new
EBslave
(
stop_until_connected
,
sdb_adr
);
void
eb_simbridge_init
(
int
stop_until_connected
,
int
sdb_adr
,
int
msi_addr_first
,
int
msi_addr_last
)
{
slave
=
new
EBslave
(
stop_until_connected
,
sdb_adr
,
msi_addr_first
,
msi_addr_last
);
}
extern
"C"
void
eb_simbridge_
control
_out
(
char
*
cyc
,
char
*
stb
,
char
*
we
,
int
*
adr
,
int
*
dat
,
int
*
sel
)
void
eb_simbridge_
master
_out
(
char
*
cyc
,
char
*
stb
,
char
*
we
,
int
*
adr
,
int
*
dat
,
int
*
sel
)
{
std_logic_t
_cyc
,
_stb
,
_we
;
slave
->
control
_out
(
&
_cyc
,
&
_stb
,
&
_we
,
adr
,
dat
,
sel
);
slave
->
master
_out
(
&
_cyc
,
&
_stb
,
&
_we
,
adr
,
dat
,
sel
);
*
cyc
=
(
char
)
_cyc
;
*
stb
=
(
char
)
_stb
;
*
we
=
(
char
)
_we
;
}
extern
"C"
void
eb_simbridge_
control
_in
(
std_logic_t
ack
,
std_logic_t
err
,
std_logic_t
rty
,
std_logic_t
stall
,
int
dat
)
void
eb_simbridge_
master
_in
(
std_logic_t
ack
,
std_logic_t
err
,
std_logic_t
rty
,
std_logic_t
stall
,
int
dat
)
{
// std::cerr << "in" << std::endl;
slave
->
control_in
(
ack
,
err
,
rty
,
stall
,
dat
);
slave
->
master_in
(
ack
,
err
,
rty
,
stall
,
dat
);
}
extern
"C"
void
eb_simbridge_msi_slave_in
(
std_logic_t
cyc
,
std_logic_t
stb
,
std_logic_t
we
,
int
adr
,
int
dat
,
int
sel
)
{
slave
->
msi_slave_in
(
cyc
,
stb
,
we
,
adr
,
dat
,
sel
);
}
extern
"C"
void
eb_simbridge_msi_slave_out
(
char
*
ack
,
char
*
err
,
char
*
rty
,
char
*
stall
,
int
*
dat
)
{
std_logic_t
_ack
,
_err
,
_rty
,
_stall
;
slave
->
msi_slave_out
(
&
_ack
,
&
_err
,
&
_rty
,
&
_stall
,
dat
);
*
ack
=
(
char
)
_ack
;
*
err
=
(
char
)
_err
;
*
rty
=
(
char
)
_rty
;
*
stall
=
(
char
)
_stall
;
}
\ No newline at end of file
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