Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
V
VME64x 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
VME64x core
Commits
74e4bdd3
Commit
74e4bdd3
authored
Sep 29, 2017
by
Tristan Gingold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle IACK cycles in vme_bus to avoid mux after FF.
parent
8e5d875f
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
134 additions
and
230 deletions
+134
-230
VME64x_v2_specs.txt
documentation/specifications/VME64x_v2_specs.txt
+3
-1
VME64xCore_Top.vhd
hdl/vme64x-core/rtl/VME64xCore_Top.vhd
+22
-47
VME_IRQ_Controller.vhd
hdl/vme64x-core/rtl/VME_IRQ_Controller.vhd
+26
-151
VME_User_CSR.vhd
hdl/vme64x-core/rtl/VME_User_CSR.vhd
+5
-5
VME_bus.vhd
hdl/vme64x-core/rtl/VME_bus.vhd
+74
-23
vme64x_pack.vhd
hdl/vme64x-core/rtl/vme64x_pack.vhd
+1
-1
xvme64x_core.vhd
hdl/vme64x-core/rtl/xvme64x_core.vhd
+1
-1
xvme64x_core_pkg.vhd
hdl/vme64x-core/rtl/xvme64x_core_pkg.vhd
+1
-1
top_tb.vhd
hdl/vme64x-core/sim/simple_tb/top_tb.vhd
+1
-0
No files found.
documentation/specifications/VME64x_v2_specs.txt
View file @
74e4bdd3
...
...
@@ -8,7 +8,9 @@ transfers. On the WB side, the addresses are rebased from 0.
Features
--------
* interrupts: 1 with timeout
* interrupts: 1 with automasking. Once acknowledge by the handler, interrupts
are masked for 1ms or until deasserted by the slave. The intent is to
prevent interrupt bursts.
* A disable ADEM (set to 0) results in an unimplemented ADER, to reduce gate
usage.
* CSR Reset bit is handled as a pulse (will reset on the next write).
...
...
hdl/vme64x-core/rtl/VME64xCore_Top.vhd
View file @
74e4bdd3
...
...
@@ -217,7 +217,7 @@ entity VME64xCore_Top is
VME_ADDR_o
:
out
std_logic_vector
(
31
downto
1
);
VME_DATA_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_o
:
out
std_logic_vector
(
31
downto
0
);
VME_IRQ_o
:
out
std_logic_vector
(
6
downto
0
);
-- the same as []*
VME_IRQ_o
:
out
std_logic_vector
(
7
downto
1
);
-- the same as []*
VME_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
...
...
@@ -277,15 +277,9 @@ architecture RTL of VME64xCore_Top is
signal
s_reset
:
std_logic
;
signal
s_reset_n
:
std_logic
;
signal
s_VME_DATA_IRQ
:
std_logic_vector
(
31
downto
0
);
signal
s_VME_DATA_VMEbus
:
std_logic_vector
(
31
downto
0
);
signal
s_VME_DTACK_VMEbus
:
std_logic
;
signal
s_VME_DTACK_IRQ
:
std_logic
;
signal
s_VME_DTACK_OE_VMEbus
:
std_logic
;
signal
s_VME_DTACK_OE_IRQ
:
std_logic
;
signal
s_VME_DATA_DIR_VMEbus
:
std_logic
;
signal
s_VME_DATA_DIR_IRQ
:
std_logic
;
signal
s_VME_IRQ_n_o
:
std_logic_vector
(
6
downto
0
);
signal
s_VME_IRQ_n_o
:
std_logic_vector
(
7
downto
1
);
signal
s_irq_ack
:
std_logic
;
signal
s_irq_pending
:
std_logic
;
-- CR/CSR
signal
s_cr_csr_addr
:
std_logic_vector
(
18
downto
2
);
...
...
@@ -299,7 +293,7 @@ architecture RTL of VME64xCore_Top is
signal
s_vme_berr_n
:
std_logic
;
signal
s_irq_vector
:
std_logic_vector
(
7
downto
0
);
signal
s_irq_level
:
std_logic_vector
(
7
downto
0
);
signal
s_irq_level
:
std_logic_vector
(
2
downto
0
);
signal
s_user_csr_addr
:
std_logic_vector
(
18
downto
2
);
signal
s_user_csr_data_i
:
std_logic_vector
(
7
downto
0
);
signal
s_user_csr_data_o
:
std_logic_vector
(
7
downto
0
);
...
...
@@ -400,19 +394,21 @@ begin
VME_RETRY_OE_o
=>
VME_RETRY_OE_o
,
VME_WRITE_n_i
=>
s_VME_WRITE_n
(
2
),
VME_DS_n_i
=>
s_VME_DS_n
(
5
downto
4
),
VME_DTACK_n_o
=>
s_VME_DTACK_VMEbus
,
VME_DTACK_OE_o
=>
s_VME_DTACK_OE_VMEbus
,
VME_DTACK_n_o
=>
VME_DTACK_n_o
,
VME_DTACK_OE_o
=>
VME_DTACK_OE_o
,
VME_BERR_n_o
=>
s_vme_berr_n
,
VME_ADDR_i
=>
VME_ADDR_i
,
VME_ADDR_o
=>
VME_ADDR_o
,
VME_ADDR_DIR_o
=>
VME_ADDR_DIR_o
,
VME_ADDR_OE_N_o
=>
VME_ADDR_OE_N_o
,
VME_DATA_i
=>
VME_DATA_i
,
VME_DATA_o
=>
s_VME_DATA_VMEbus
,
VME_DATA_DIR_o
=>
s_VME_DATA_DIR_VMEbus
,
VME_DATA_o
=>
VME_DATA_o
,
VME_DATA_DIR_o
=>
VME_DATA_DIR_o
,
VME_DATA_OE_N_o
=>
VME_DATA_OE_N_o
,
VME_AM_i
=>
VME_AM_i
,
VME_IACK_n_i
=>
s_VME_IACK_n
(
2
),
VME_IACKIN_n_i
=>
s_VME_IACKIN_n
(
2
),
VME_IACKOUT_n_o
=>
VME_IACKOUT_n_o
,
-- WB signals
stb_o
=>
STB_o
,
...
...
@@ -440,7 +436,12 @@ begin
cr_csr_data_o
=>
s_cr_csr_data_i
,
cr_csr_we_o
=>
s_cr_csr_we
,
module_enable_i
=>
s_module_enable
,
bar_i
=>
s_bar
bar_i
=>
s_bar
,
INT_Level_i
=>
s_irq_level
,
INT_Vector_i
=>
s_irq_vector
,
irq_pending_i
=>
s_irq_pending
,
irq_ack_o
=>
s_irq_ack
);
s_reset
<=
(
not
rst_n_i
)
or
(
not
s_VME_RST_n
(
2
));
...
...
@@ -476,25 +477,7 @@ begin
-- Output
------------------------------------------------------------------------------
VME_IRQ_o
<=
not
s_VME_IRQ_n_o
;
-- The buffers will invert again the logic level
irq_ack_o
<=
s_VME_DTACK_IRQ
;
-- Multiplexer added on the output signal used by either VMEbus.vhd and the
-- IRQ_controller.vhd
VME_DATA_o
<=
s_VME_DATA_VMEbus
when
s_VME_IACK_n
(
2
)
=
'1'
else
s_VME_DATA_IRQ
;
VME_DTACK_n_o
<=
s_VME_DTACK_VMEbus
and
s_VME_DTACK_IRQ
;
--when s_VME_IACK_n(2) = '1'
--else s_VME_DTACK_IRQ;
VME_DTACK_OE_o
<=
s_VME_DTACK_OE_VMEbus
or
s_VME_DTACK_OE_IRQ
;
--when s_VME_IACK_n(2) = '1'
--else s_VME_DTACK_OE_IRQ;
VME_DATA_DIR_o
<=
s_VME_DATA_DIR_VMEbus
when
s_VME_IACK_n
(
2
)
=
'1'
else
s_VME_DATA_DIR_IRQ
;
irq_ack_o
<=
s_irq_ack
;
------------------------------------------------------------------------------
-- Interrupter
...
...
@@ -506,19 +489,11 @@ begin
port
map
(
clk_i
=>
clk_i
,
reset_n_i
=>
s_reset_n
,
-- asserted when low
VME_IACKIN_n_i
=>
s_VME_IACKIN_n
(
2
),
VME_AS_n_i
=>
s_VME_AS_n
(
2
),
VME_DS_n_i
=>
s_VME_DS_n
(
5
downto
4
),
VME_ADDR_123_i
=>
VME_ADDR_i
(
3
downto
1
),
INT_Level_i
=>
s_irq_level
,
INT_Vector_i
=>
s_irq_vector
,
INT_Req_i
=>
irq_i
,
VME_IRQ_n_o
=>
s_VME_IRQ_n_o
,
VME_IACKOUT_n_o
=>
VME_IACKOUT_n_o
,
VME_DTACK_n_o
=>
s_VME_DTACK_IRQ
,
VME_DTACK_OE_o
=>
s_VME_DTACK_OE_IRQ
,
VME_DATA_o
=>
s_VME_DATA_IRQ
,
VME_DATA_DIR_o
=>
s_VME_DATA_DIR_IRQ
irq_pending_o
=>
s_irq_pending
,
irq_ack_i
=>
s_irq_ack
,
VME_IRQ_n_o
=>
s_VME_IRQ_n_o
);
------------------------------------------------------------------------------
...
...
@@ -591,7 +566,7 @@ begin
gen_ext_user_csr
:
if
g_USER_CSR_EXT
=
true
generate
s_user_csr_data_i
<=
user_csr_data_i
;
s_irq_vector
<=
irq_vector_i
;
s_irq_level
<=
irq_level_i
;
s_irq_level
<=
irq_level_i
(
2
downto
0
)
;
end
generate
;
user_csr_addr_o
<=
s_user_csr_addr
;
...
...
hdl/vme64x-core/rtl/VME_IRQ_Controller.vhd
View file @
74e4bdd3
...
...
@@ -134,74 +134,28 @@ entity VME_IRQ_Controller is
port
(
clk_i
:
in
std_logic
;
reset_n_i
:
in
std_logic
;
VME_IACKIN_n_i
:
in
std_logic
;
VME_AS_n_i
:
in
std_logic
;
VME_DS_n_i
:
in
std_logic_vector
(
1
downto
0
);
VME_ADDR_123_i
:
in
std_logic_vector
(
2
downto
0
);
INT_Level_i
:
in
std_logic_vector
(
7
downto
0
);
INT_Vector_i
:
in
std_logic_vector
(
7
downto
0
);
INT_Level_i
:
in
std_logic_vector
(
2
downto
0
);
INT_Req_i
:
in
std_logic
;
VME_IRQ_n_o
:
out
std_logic_vector
(
6
downto
0
);
VME_IACKOUT_n_o
:
out
std_logic
;
VME_DTACK_n_o
:
out
std_logic
;
VME_DTACK_OE_o
:
out
std_logic
;
VME_DATA_o
:
out
std_logic_vector
(
31
downto
0
);
VME_DATA_DIR_o
:
out
std_logic
irq_pending_o
:
out
std_logic
;
irq_ack_i
:
in
std_logic
;
VME_IRQ_n_o
:
out
std_logic_vector
(
7
downto
1
)
);
end
VME_IRQ_Controller
;
architecture
Behavioral
of
VME_IRQ_Controller
is
function
f_select_irq_line
(
level
:
std_logic_vector
)
return
std_logic_vector
is
begin
case
level
(
7
downto
0
)
is
when
x"01"
=>
return
"1111110"
;
when
x"02"
=>
return
"1111101"
;
when
x"03"
=>
return
"1111011"
;
when
x"04"
=>
return
"1110111"
;
when
x"05"
=>
return
"1101111"
;
when
x"06"
=>
return
"1011111"
;
when
x"07"
=>
return
"0111111"
;
when
others
=>
return
"1111111"
;
end
case
;
end
f_select_irq_Line
;
-- Input signals
type
t_retry_state
is
(
WAIT_IRQ
,
WAIT_RETRY
);
type
t_main_state
is
(
IDLE
,
IRQ
,
WAIT_AS
,
WAIT_DS
,
CHECK
,
DATA_OUT
,
DTACK
,
IACKOUT1
,
IACKOUT2
,
SCHEDULE_IRQ
);
signal
as_n_d0
:
std_logic
;
signal
as_rising_p
,
as_falling_p
:
std_logic
;
signal
vme_addr_latched
:
std_logic_vector
(
2
downto
0
);
signal
state
:
t_main_state
;
signal
retry_state
:
t_retry_state
;
signal
retry_count
:
unsigned
(
23
downto
0
);
signal
retry_mask
:
std_logic
;
signal
s_irq_pending
:
std_logic
;
begin
irq_pending_o
<=
s_irq_pending
;
-- Input sampling and edge detection
p_detect_as_edges
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
as_n_d0
<=
VME_AS_n_i
;
as_rising_p
<=
not
as_n_d0
and
VME_AS_n_i
;
as_falling_p
<=
as_n_d0
and
not
VME_AS_n_i
;
end
if
;
end
process
;
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
as_falling_p
=
'1'
then
vme_addr_latched
<=
VME_ADDR_123_i
;
end
if
;
end
if
;
end
process
;
-- Interrupts are automatically masked for g_RETRY_TIMEOUT (ie 1 ms) once
-- they are acknowledge by the interrupt handler until they are deasserted
-- by the interrupter.
p_retry_fsm
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
...
...
@@ -211,7 +165,7 @@ begin
else
case
retry_state
is
when
WAIT_IRQ
=>
if
(
state
=
IRQ
and
INT_Req_i
=
'1'
)
then
if
s_irq_pending
=
'1'
and
INT_Req_i
=
'1'
then
retry_state
<=
WAIT_RETRY
;
retry_count
<=
(
others
=>
'0'
);
retry_mask
<=
'0'
;
...
...
@@ -220,15 +174,14 @@ begin
end
if
;
when
WAIT_RETRY
=>
if
(
INT_Req_i
=
'0'
)
then
if
INT_Req_i
=
'0'
then
retry_state
<=
WAIT_IRQ
;
else
retry_count
<=
retry_count
+
1
;
if
(
retry_count
=
g_RETRY_TIMEOUT
)
then
if
retry_count
=
g_RETRY_TIMEOUT
then
retry_state
<=
WAIT_IRQ
;
end
if
;
end
if
;
end
case
;
end
if
;
end
if
;
...
...
@@ -238,100 +191,22 @@ begin
begin
if
rising_edge
(
clk_i
)
then
if
reset_n_i
=
'0'
then
state
<=
IDLE
;
VME_IACKOUT_n_o
<=
'1'
;
VME_DATA_DIR_o
<=
'0'
;
VME_DTACK_n_o
<=
'1'
;
VME_DTACK_OE_o
<=
'0'
;
VME_IRQ_n_o
<=
(
others
=>
'1'
);
s_irq_pending
<=
'0'
;
else
case
state
is
when
IDLE
=>
VME_IACKOUT_n_o
<=
'1'
;
VME_DATA_DIR_o
<=
'0'
;
VME_DTACK_n_o
<=
'1'
;
VME_DTACK_OE_o
<=
'0'
;
VME_IRQ_n_o
<=
(
others
=>
'1'
);
if
INT_Req_i
=
'1'
and
retry_mask
=
'1'
then
if
VME_IACKIN_n_i
/=
'0'
then
-- FIXME: what if INT_Level_i is 0 (irq won't be visible and
-- thus never acked) ?
state
<=
IRQ
;
VME_IRQ_n_o
<=
f_select_irq_line
(
INT_Level_i
);
else
-- IACK in progress, wait until idle
state
<=
SCHEDULE_IRQ
;
end
if
;
-- Just forward IACK to the next card in the daisy chain.
elsif
VME_IACKIN_n_i
=
'0'
and
VME_DS_n_i
/=
"11"
then
VME_IACKOUT_n_o
<=
'0'
;
state
<=
IACKOUT2
;
end
if
;
when
SCHEDULE_IRQ
=>
if
(
VME_IACKIN_n_i
/=
'0'
)
then
VME_IRQ_n_o
<=
f_select_irq_line
(
INT_Level_i
);
state
<=
IRQ
;
end
if
;
when
IRQ
=>
if
VME_IACKIN_n_i
=
'0'
then
-- Each interrupter who is driving an interrupt request line
-- low waits for a falling edge on IACKIN input -->
-- the IRQ_Controller have to detect a falling edge on the IACKIN.
state
<=
WAIT_AS
;
end
if
;
when
WAIT_AS
=>
if
VME_AS_n_i
=
'0'
then
state
<=
WAIT_DS
;
end
if
;
when
WAIT_DS
=>
if
VME_DS_n_i
/=
"11"
then
state
<=
CHECK
;
end
if
;
when
CHECK
=>
if
vme_addr_latched
=
INT_Level_i
(
2
downto
0
)
then
state
<=
DATA_OUT
;
-- The interrupter send the vector
VME_DATA_DIR_o
<=
'1'
;
VME_DTACK_OE_o
<=
'1'
;
VME_DTACK_n_o
<=
'1'
;
else
state
<=
IACKOUT1
;
-- The interrupter must pass a
-- falling edge on the IACK output
VME_IACKOUT_n_o
<=
'0'
;
end
if
;
when
IACKOUT1
=>
if
as_rising_p
=
'1'
then
VME_IACKOUT_n_o
<=
'1'
;
state
<=
IRQ
;
end
if
;
when
IACKOUT2
=>
if
VME_AS_n_i
=
'1'
then
VME_IACKOUT_n_o
<=
'1'
;
state
<=
IDLE
;
end
if
;
when
DATA_OUT
=>
VME_DTACK_n_o
<=
'0'
;
VME_IRQ_n_o
<=
(
others
=>
'1'
);
state
<=
DTACK
;
when
DTACK
=>
if
as_rising_p
=
'1'
then
VME_DTACK_OE_o
<=
'0'
;
VME_DATA_DIR_o
<=
'0'
;
state
<=
IDLE
;
end
if
;
end
case
;
if
s_irq_pending
=
'0'
then
VME_IRQ_n_o
<=
(
others
=>
'1'
);
if
INT_Req_i
=
'1'
and
retry_mask
=
'1'
and
INT_Level_i
/=
"000"
then
s_irq_pending
<=
'1'
;
VME_IRQ_n_o
(
to_integer
(
unsigned
(
INT_Level_i
)))
<=
'0'
;
end
if
;
else
if
irq_ack_i
=
'1'
then
s_irq_pending
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
VME_DATA_o
<=
x"000000"
&
INT_Vector_i
;
end
Behavioral
;
hdl/vme64x-core/rtl/VME_User_CSR.vhd
View file @
74e4bdd3
...
...
@@ -72,14 +72,14 @@ entity VME_User_CSR is
we_i
:
in
std_logic
;
irq_vector_o
:
out
std_logic_vector
(
7
downto
0
);
irq_level_o
:
out
std_logic_vector
(
7
downto
0
)
irq_level_o
:
out
std_logic_vector
(
2
downto
0
)
);
end
VME_User_CSR
;
architecture
rtl
of
VME_User_CSR
is
signal
s_irq_vector
:
std_logic_vector
(
7
downto
0
);
signal
s_irq_level
:
std_logic_vector
(
7
downto
0
);
signal
s_irq_level
:
std_logic_vector
(
2
downto
0
);
-- Value for unused memory locations
constant
c_UNUSED
:
std_logic_vector
(
7
downto
0
)
:
=
x"ff"
;
...
...
@@ -104,12 +104,12 @@ begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
s_irq_vector
<=
x"00"
;
s_irq_level
<=
x"
00"
;
s_irq_level
<=
"0
00"
;
else
if
we_i
=
'1'
then
case
to_integer
(
unsigned
(
addr_i
))
is
when
c_IRQ_VECTOR
=>
s_irq_vector
<=
data_i
;
when
c_IRQ_LEVEL
=>
s_irq_level
<=
data_i
;
when
c_IRQ_LEVEL
=>
s_irq_level
<=
data_i
(
2
downto
0
)
;
when
others
=>
null
;
end
case
;
end
if
;
...
...
@@ -129,7 +129,7 @@ begin
else
case
to_integer
(
unsigned
(
addr_i
))
is
when
c_IRQ_VECTOR
=>
data_o
<=
s_irq_vector
;
when
c_IRQ_LEVEL
=>
data_o
<=
s_irq_level
;
when
c_IRQ_LEVEL
=>
data_o
<=
"00000"
&
s_irq_level
;
when
c_ENDIAN
=>
data_o
<=
x"00"
;
when
c_WB32BITS
=>
data_o
<=
x"01"
;
when
others
=>
data_o
<=
c_UNUSED
;
...
...
hdl/vme64x-core/rtl/VME_bus.vhd
View file @
74e4bdd3
...
...
@@ -97,9 +97,10 @@ entity VME_bus is
VME_DATA_DIR_o
:
out
std_logic
;
VME_DATA_OE_N_o
:
out
std_logic
;
VME_AM_i
:
in
std_logic_vector
(
5
downto
0
);
VME_IACK_n_i
:
in
std_logic
;
-- USE VME_IACK_n_i and NOT VME_IACKIN_n_i
-- because VME_IACKIN_n_i is delayed the
-- more you are away from Slots 0
VME_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
-- WB signals
stb_o
:
out
std_logic
;
ack_i
:
in
std_logic
;
...
...
@@ -126,7 +127,13 @@ entity VME_bus is
cr_csr_data_o
:
out
std_logic_vector
(
7
downto
0
);
cr_csr_we_o
:
out
std_logic
;
module_enable_i
:
in
std_logic
;
bar_i
:
in
std_logic_vector
(
4
downto
0
)
bar_i
:
in
std_logic_vector
(
4
downto
0
);
-- Interrupts
INT_Level_i
:
in
std_logic_vector
(
2
downto
0
);
INT_Vector_i
:
in
std_logic_vector
(
7
downto
0
);
irq_pending_i
:
in
std_logic
;
irq_ack_o
:
out
std_logic
);
end
VME_bus
;
...
...
@@ -193,9 +200,15 @@ architecture RTL of VME_bus is
-- Assert DTACK
DTACK_LOW
,
--
Increment address for block transfers
-- Increment address for block transfers
INCREMENT_ADDR
,
-- Check if IACK is for this slave
IRQ_CHECK
,
-- Pass IACKIN to IACKOUT
IRQ_PASS
,
-- Wait until AS is deasserted
WAIT_END
);
...
...
@@ -209,6 +222,7 @@ architecture RTL of VME_bus is
-- Access decode signals
signal
s_conf_sel
:
std_logic
;
-- CR or CSR is addressed
signal
s_card_sel
:
std_logic
;
-- WB memory is addressed
signal
s_irq_sel
:
std_logic
;
-- IACK transaction
signal
s_is_d64
:
std_logic
;
signal
s_err
:
std_logic
;
...
...
@@ -298,10 +312,10 @@ begin
VME_DATA_DIR_o
<=
'0'
;
VME_ADDR_DIR_o
<=
'0'
;
VME_BERR_n_o
<=
'1'
;
VME_ADDR_o
<=
(
others
=>
'0'
);
VME_LWORD_n_o
<=
'1'
;
VME_DATA_o
<=
(
others
=>
'0'
);
VME_ADDR_o
<=
(
others
=>
'0'
);
VME_LWORD_n_o
<=
'1'
;
VME_DATA_o
<=
(
others
=>
'0'
);
VME_IACKOUT_n_o
<=
'1'
;
s_dataPhase
<=
'0'
;
s_MBLT_Data
<=
'0'
;
s_mainFSMstate
<=
IDLE
;
...
...
@@ -318,6 +332,8 @@ begin
s_card_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_irq_sel
<=
'0'
;
irq_ack_o
<=
'0'
;
else
s_conf_req
<=
'0'
;
decode_start_o
<=
'0'
;
...
...
@@ -326,26 +342,28 @@ begin
VME_DATA_DIR_o
<=
'0'
;
VME_ADDR_DIR_o
<=
'0'
;
VME_BERR_n_o
<=
'1'
;
VME_IACKOUT_n_o
<=
'1'
;
irq_ack_o
<=
'0'
;
case
s_mainFSMstate
is
when
IDLE
=>
-- During the Interrupt ack cycle the Slave can't be accessed
-- so if VME_IACK_n_i is asserted the FSM is in IDLE state.
-- The VME_IACK_n_i signal is asserted by the Interrupt handler
-- during all the Interrupt cycle.
-- VITA-1 Rule 2.11
-- Slaves MUST NOT respond to DTB cycles when IACK* is low.
if
VME_AS_n_i
=
'0'
and
VME_IACK_n_i
=
'1'
then
-- if AS falling edge --> start access
s_mainFSMstate
<=
REFORMAT_ADDRESS
;
if
VME_AS_n_i
=
'0'
then
-- Store ADDR, AM and LWORD
s_ADDRlatched
<=
VME_ADDR_i
;
s_LWORDlatched_n
<=
VME_LWORD_n_i
;
s_AMlatched
<=
VME_AM_i
;
if
VME_IACK_n_i
=
'1'
then
-- if AS falling edge --> start access
-- VITA-1 Rule 2.11
-- Slaves MUST NOT respond to DTB cycles when IACK* is low.
s_mainFSMstate
<=
REFORMAT_ADDRESS
;
else
s_mainFSMstate
<=
IRQ_CHECK
;
end
if
;
else
s_mainFSMstate
<=
IDLE
;
end
if
;
...
...
@@ -366,6 +384,7 @@ begin
-- Address is not yet decoded.
s_card_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_irq_sel
<=
'0'
;
-- DS latch counter
s_DS_latch_count
<=
to_unsigned
(
num_latchDS
,
3
);
...
...
@@ -428,6 +447,8 @@ begin
-- Note: before entering this state, s_DS_latch_count must be set.
if
VME_DS_n_i
/=
"11"
then
-- VITAL-1 Table 4-1
-- For interrupts ack, the handler MUST NOT drive WRITE* low
s_WRITElatched_n
<=
VME_WRITE_n_i
;
s_DS_latch_count
<=
s_DS_latch_count
-
1
;
s_mainFSMstate
<=
LATCH_DS
;
...
...
@@ -455,7 +476,9 @@ begin
end
if
;
if
s_DS_latch_count
=
0
then
if
s_transferType
=
MBLT
and
s_MBLT_Data
=
'0'
then
if
s_irq_sel
=
'1'
then
s_mainFSMstate
<=
DATA_TO_BUS
;
elsif
s_transferType
=
MBLT
and
s_MBLT_Data
=
'0'
then
-- MBLT: ack address.
-- (Data are also read but discarded).
s_mainFSMstate
<=
DTACK_LOW
;
...
...
@@ -600,7 +623,7 @@ begin
VME_ADDR_DIR_o
<=
(
s_is_d64
)
and
s_WRITElatched_n
;
-- Set DTACK (or retry or berr)
if
s_err
=
'1'
then
if
s_
card_sel
=
'1'
and
s_
err
=
'1'
then
VME_BERR_n_o
<=
'0'
;
else
VME_DTACK_n_o
<=
'0'
;
...
...
@@ -620,7 +643,9 @@ begin
-- DS latch counter
s_DS_latch_count
<=
to_unsigned
(
num_latchDS
,
3
);
if
s_transferType
=
SINGLE
then
if
s_irq_sel
=
'1'
then
s_mainFSMstate
<=
WAIT_END
;
elsif
s_transferType
=
SINGLE
then
-- Cycle should be finished, but allow another access at
-- the same address (RMW).
s_mainFSMstate
<=
WAIT_FOR_DS
;
...
...
@@ -665,6 +690,32 @@ begin
(
unsigned
(
s_ADDRlatched
(
11
downto
1
))
+
addr_word_incr
);
s_mainFSMstate
<=
WAIT_FOR_DS
;
when
IRQ_CHECK
=>
if
VME_IACKIN_n_i
=
'0'
then
if
s_ADDRlatched
(
3
downto
1
)
=
INT_Level_i
and
irq_pending_i
=
'1'
then
-- That's for us
s_locDataOut
<=
(
others
=>
'0'
);
s_locDataOut
(
7
downto
0
)
<=
INT_Vector_i
;
s_irq_sel
<=
'1'
;
irq_ack_o
<=
'1'
;
s_mainFSMstate
<=
WAIT_FOR_DS
;
else
-- Pass
VME_IACKOUT_n_o
<=
'0'
;
s_mainFSMstate
<=
IRQ_PASS
;
end
if
;
else
s_mainFSMstate
<=
IRQ_CHECK
;
end
if
;
when
IRQ_PASS
=>
-- Will stay here until AS is released.
VME_IACKOUT_n_o
<=
'0'
;
s_mainFSMstate
<=
IRQ_PASS
;
when
WAIT_END
=>
-- Will stay here until AS is released.
s_mainFSMstate
<=
WAIT_END
;
...
...
hdl/vme64x-core/rtl/vme64x_pack.vhd
View file @
74e4bdd3
...
...
@@ -179,7 +179,7 @@ package vme64x_pack is
VME_ADDR_o
:
out
std_logic_vector
(
31
downto
1
);
VME_DATA_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_o
:
out
std_logic_vector
(
31
downto
0
);
VME_IRQ_o
:
out
std_logic_vector
(
6
downto
0
);
VME_IRQ_o
:
out
std_logic_vector
(
7
downto
1
);
VME_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
...
...
hdl/vme64x-core/rtl/xvme64x_core.vhd
View file @
74e4bdd3
...
...
@@ -115,7 +115,7 @@ entity xvme64x_core is
VME_ADDR_b_o
:
out
std_logic_vector
(
31
downto
1
);
VME_DATA_b_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_b_o
:
out
std_logic_vector
(
31
downto
0
);
VME_IRQ_n_o
:
out
std_logic_vector
(
6
downto
0
);
VME_IRQ_n_o
:
out
std_logic_vector
(
7
downto
1
);
VME_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
...
...
hdl/vme64x-core/rtl/xvme64x_core_pkg.vhd
View file @
74e4bdd3
...
...
@@ -140,7 +140,7 @@ package xvme64x_core_pkg is
VME_ADDR_b_o
:
out
std_logic_vector
(
31
downto
1
);
VME_DATA_b_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_b_o
:
out
std_logic_vector
(
31
downto
0
);
VME_IRQ_n_o
:
out
std_logic_vector
(
6
downto
0
);
VME_IRQ_n_o
:
out
std_logic_vector
(
7
downto
1
);
VME_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
...
...
hdl/vme64x-core/sim/simple_tb/top_tb.vhd
View file @
74e4bdd3
...
...
@@ -840,6 +840,7 @@ begin
end
if
;
end
loop
;
VME_IACK_n_i
<=
'0'
;
VME_WRITE_n_i
<=
'1'
;
wait
for
35
ns
;
VME_AS_n_i
<=
'0'
;
if
not
(
VME_DTACK_OE_o
=
'0'
and
VME_BERR_o
=
'0'
)
then
...
...
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