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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hdl-core-lib
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.
...
@@ -8,7 +8,9 @@ transfers. On the WB side, the addresses are rebased from 0.
Features
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
* A disable ADEM (set to 0) results in an unimplemented ADER, to reduce gate
usage.
usage.
* CSR Reset bit is handled as a pulse (will reset on the next write).
* 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
...
@@ -217,7 +217,7 @@ entity VME64xCore_Top is
VME_ADDR_o
:
out
std_logic_vector
(
31
downto
1
);
VME_ADDR_o
:
out
std_logic_vector
(
31
downto
1
);
VME_DATA_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_o
:
out
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_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
...
@@ -277,15 +277,9 @@ architecture RTL of VME64xCore_Top is
...
@@ -277,15 +277,9 @@ architecture RTL of VME64xCore_Top is
signal
s_reset
:
std_logic
;
signal
s_reset
:
std_logic
;
signal
s_reset_n
:
std_logic
;
signal
s_reset_n
:
std_logic
;
signal
s_VME_DATA_IRQ
:
std_logic_vector
(
31
downto
0
);
signal
s_VME_IRQ_n_o
:
std_logic_vector
(
7
downto
1
);
signal
s_VME_DATA_VMEbus
:
std_logic_vector
(
31
downto
0
);
signal
s_irq_ack
:
std_logic
;
signal
s_VME_DTACK_VMEbus
:
std_logic
;
signal
s_irq_pending
:
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
);
-- CR/CSR
-- CR/CSR
signal
s_cr_csr_addr
:
std_logic_vector
(
18
downto
2
);
signal
s_cr_csr_addr
:
std_logic_vector
(
18
downto
2
);
...
@@ -299,7 +293,7 @@ architecture RTL of VME64xCore_Top is
...
@@ -299,7 +293,7 @@ architecture RTL of VME64xCore_Top is
signal
s_vme_berr_n
:
std_logic
;
signal
s_vme_berr_n
:
std_logic
;
signal
s_irq_vector
:
std_logic_vector
(
7
downto
0
);
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_addr
:
std_logic_vector
(
18
downto
2
);
signal
s_user_csr_data_i
:
std_logic_vector
(
7
downto
0
);
signal
s_user_csr_data_i
:
std_logic_vector
(
7
downto
0
);
signal
s_user_csr_data_o
:
std_logic_vector
(
7
downto
0
);
signal
s_user_csr_data_o
:
std_logic_vector
(
7
downto
0
);
...
@@ -400,19 +394,21 @@ begin
...
@@ -400,19 +394,21 @@ begin
VME_RETRY_OE_o
=>
VME_RETRY_OE_o
,
VME_RETRY_OE_o
=>
VME_RETRY_OE_o
,
VME_WRITE_n_i
=>
s_VME_WRITE_n
(
2
),
VME_WRITE_n_i
=>
s_VME_WRITE_n
(
2
),
VME_DS_n_i
=>
s_VME_DS_n
(
5
downto
4
),
VME_DS_n_i
=>
s_VME_DS_n
(
5
downto
4
),
VME_DTACK_n_o
=>
s_VME_DTACK_VMEbus
,
VME_DTACK_n_o
=>
VME_DTACK_n_o
,
VME_DTACK_OE_o
=>
s_VME_DTACK_OE_VMEbus
,
VME_DTACK_OE_o
=>
VME_DTACK_OE_o
,
VME_BERR_n_o
=>
s_vme_berr_n
,
VME_BERR_n_o
=>
s_vme_berr_n
,
VME_ADDR_i
=>
VME_ADDR_i
,
VME_ADDR_i
=>
VME_ADDR_i
,
VME_ADDR_o
=>
VME_ADDR_o
,
VME_ADDR_o
=>
VME_ADDR_o
,
VME_ADDR_DIR_o
=>
VME_ADDR_DIR_o
,
VME_ADDR_DIR_o
=>
VME_ADDR_DIR_o
,
VME_ADDR_OE_N_o
=>
VME_ADDR_OE_N_o
,
VME_ADDR_OE_N_o
=>
VME_ADDR_OE_N_o
,
VME_DATA_i
=>
VME_DATA_i
,
VME_DATA_i
=>
VME_DATA_i
,
VME_DATA_o
=>
s_VME_DATA_VMEbus
,
VME_DATA_o
=>
VME_DATA_o
,
VME_DATA_DIR_o
=>
s_VME_DATA_DIR_VMEbus
,
VME_DATA_DIR_o
=>
VME_DATA_DIR_o
,
VME_DATA_OE_N_o
=>
VME_DATA_OE_N_o
,
VME_DATA_OE_N_o
=>
VME_DATA_OE_N_o
,
VME_AM_i
=>
VME_AM_i
,
VME_AM_i
=>
VME_AM_i
,
VME_IACK_n_i
=>
s_VME_IACK_n
(
2
),
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
-- WB signals
stb_o
=>
STB_o
,
stb_o
=>
STB_o
,
...
@@ -440,7 +436,12 @@ begin
...
@@ -440,7 +436,12 @@ begin
cr_csr_data_o
=>
s_cr_csr_data_i
,
cr_csr_data_o
=>
s_cr_csr_data_i
,
cr_csr_we_o
=>
s_cr_csr_we
,
cr_csr_we_o
=>
s_cr_csr_we
,
module_enable_i
=>
s_module_enable
,
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
));
s_reset
<=
(
not
rst_n_i
)
or
(
not
s_VME_RST_n
(
2
));
...
@@ -476,25 +477,7 @@ begin
...
@@ -476,25 +477,7 @@ begin
-- Output
-- Output
------------------------------------------------------------------------------
------------------------------------------------------------------------------
VME_IRQ_o
<=
not
s_VME_IRQ_n_o
;
-- The buffers will invert again the logic level
VME_IRQ_o
<=
not
s_VME_IRQ_n_o
;
-- The buffers will invert again the logic level
irq_ack_o
<=
s_VME_DTACK_IRQ
;
irq_ack_o
<=
s_irq_ack
;
-- 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
;
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- Interrupter
-- Interrupter
...
@@ -506,19 +489,11 @@ begin
...
@@ -506,19 +489,11 @@ begin
port
map
(
port
map
(
clk_i
=>
clk_i
,
clk_i
=>
clk_i
,
reset_n_i
=>
s_reset_n
,
-- asserted when low
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_Level_i
=>
s_irq_level
,
INT_Vector_i
=>
s_irq_vector
,
INT_Req_i
=>
irq_i
,
INT_Req_i
=>
irq_i
,
VME_IRQ_n_o
=>
s_VME_IRQ_n_o
,
irq_pending_o
=>
s_irq_pending
,
VME_IACKOUT_n_o
=>
VME_IACKOUT_n_o
,
irq_ack_i
=>
s_irq_ack
,
VME_DTACK_n_o
=>
s_VME_DTACK_IRQ
,
VME_IRQ_n_o
=>
s_VME_IRQ_n_o
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
);
);
------------------------------------------------------------------------------
------------------------------------------------------------------------------
...
@@ -591,7 +566,7 @@ begin
...
@@ -591,7 +566,7 @@ begin
gen_ext_user_csr
:
if
g_USER_CSR_EXT
=
true
generate
gen_ext_user_csr
:
if
g_USER_CSR_EXT
=
true
generate
s_user_csr_data_i
<=
user_csr_data_i
;
s_user_csr_data_i
<=
user_csr_data_i
;
s_irq_vector
<=
irq_vector_i
;
s_irq_vector
<=
irq_vector_i
;
s_irq_level
<=
irq_level_i
;
s_irq_level
<=
irq_level_i
(
2
downto
0
)
;
end
generate
;
end
generate
;
user_csr_addr_o
<=
s_user_csr_addr
;
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
...
@@ -134,74 +134,28 @@ entity VME_IRQ_Controller is
port
(
port
(
clk_i
:
in
std_logic
;
clk_i
:
in
std_logic
;
reset_n_i
:
in
std_logic
;
reset_n_i
:
in
std_logic
;
VME_IACKIN_n_i
:
in
std_logic
;
INT_Level_i
:
in
std_logic_vector
(
2
downto
0
);
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_Req_i
:
in
std_logic
;
INT_Req_i
:
in
std_logic
;
VME_IRQ_n_o
:
out
std_logic_vector
(
6
downto
0
);
irq_pending_o
:
out
std_logic
;
VME_IACKOUT_n_o
:
out
std_logic
;
irq_ack_i
:
in
std_logic
;
VME_DTACK_n_o
:
out
std_logic
;
VME_IRQ_n_o
:
out
std_logic_vector
(
7
downto
1
)
VME_DTACK_OE_o
:
out
std_logic
;
VME_DATA_o
:
out
std_logic_vector
(
31
downto
0
);
VME_DATA_DIR_o
:
out
std_logic
);
);
end
VME_IRQ_Controller
;
end
VME_IRQ_Controller
;
architecture
Behavioral
of
VME_IRQ_Controller
is
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_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_state
:
t_retry_state
;
signal
retry_count
:
unsigned
(
23
downto
0
);
signal
retry_count
:
unsigned
(
23
downto
0
);
signal
retry_mask
:
std_logic
;
signal
retry_mask
:
std_logic
;
signal
s_irq_pending
:
std_logic
;
begin
begin
irq_pending_o
<=
s_irq_pending
;
-- Input sampling and edge detection
-- Interrupts are automatically masked for g_RETRY_TIMEOUT (ie 1 ms) once
p_detect_as_edges
:
process
(
clk_i
)
-- they are acknowledge by the interrupt handler until they are deasserted
begin
-- by the interrupter.
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
;
p_retry_fsm
:
process
(
clk_i
)
p_retry_fsm
:
process
(
clk_i
)
begin
begin
if
rising_edge
(
clk_i
)
then
if
rising_edge
(
clk_i
)
then
...
@@ -211,7 +165,7 @@ begin
...
@@ -211,7 +165,7 @@ begin
else
else
case
retry_state
is
case
retry_state
is
when
WAIT_IRQ
=>
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_state
<=
WAIT_RETRY
;
retry_count
<=
(
others
=>
'0'
);
retry_count
<=
(
others
=>
'0'
);
retry_mask
<=
'0'
;
retry_mask
<=
'0'
;
...
@@ -220,15 +174,14 @@ begin
...
@@ -220,15 +174,14 @@ begin
end
if
;
end
if
;
when
WAIT_RETRY
=>
when
WAIT_RETRY
=>
if
(
INT_Req_i
=
'0'
)
then
if
INT_Req_i
=
'0'
then
retry_state
<=
WAIT_IRQ
;
retry_state
<=
WAIT_IRQ
;
else
else
retry_count
<=
retry_count
+
1
;
retry_count
<=
retry_count
+
1
;
if
(
retry_count
=
g_RETRY_TIMEOUT
)
then
if
retry_count
=
g_RETRY_TIMEOUT
then
retry_state
<=
WAIT_IRQ
;
retry_state
<=
WAIT_IRQ
;
end
if
;
end
if
;
end
if
;
end
if
;
end
case
;
end
case
;
end
if
;
end
if
;
end
if
;
end
if
;
...
@@ -238,100 +191,22 @@ begin
...
@@ -238,100 +191,22 @@ begin
begin
begin
if
rising_edge
(
clk_i
)
then
if
rising_edge
(
clk_i
)
then
if
reset_n_i
=
'0'
then
if
reset_n_i
=
'0'
then
state
<=
IDLE
;
VME_IRQ_n_o
<=
(
others
=>
'1'
);
VME_IACKOUT_n_o
<=
'1'
;
s_irq_pending
<=
'0'
;
VME_DATA_DIR_o
<=
'0'
;
VME_DTACK_n_o
<=
'1'
;
VME_DTACK_OE_o
<=
'0'
;
else
else
case
state
is
if
s_irq_pending
=
'0'
then
when
IDLE
=>
VME_IRQ_n_o
<=
(
others
=>
'1'
);
VME_IACKOUT_n_o
<=
'1'
;
VME_DATA_DIR_o
<=
'0'
;
if
INT_Req_i
=
'1'
and
retry_mask
=
'1'
and
INT_Level_i
/=
"000"
then
VME_DTACK_n_o
<=
'1'
;
s_irq_pending
<=
'1'
;
VME_DTACK_OE_o
<=
'0'
;
VME_IRQ_n_o
(
to_integer
(
unsigned
(
INT_Level_i
)))
<=
'0'
;
VME_IRQ_n_o
<=
(
others
=>
'1'
);
end
if
;
else
if
INT_Req_i
=
'1'
and
retry_mask
=
'1'
then
if
irq_ack_i
=
'1'
then
if
VME_IACKIN_n_i
/=
'0'
then
s_irq_pending
<=
'0'
;
-- FIXME: what if INT_Level_i is 0 (irq won't be visible and
end
if
;
-- thus never acked) ?
end
if
;
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
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
end
process
;
VME_DATA_o
<=
x"000000"
&
INT_Vector_i
;
end
Behavioral
;
end
Behavioral
;
hdl/vme64x-core/rtl/VME_User_CSR.vhd
View file @
74e4bdd3
...
@@ -72,14 +72,14 @@ entity VME_User_CSR is
...
@@ -72,14 +72,14 @@ entity VME_User_CSR is
we_i
:
in
std_logic
;
we_i
:
in
std_logic
;
irq_vector_o
:
out
std_logic_vector
(
7
downto
0
);
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
;
end
VME_User_CSR
;
architecture
rtl
of
VME_User_CSR
is
architecture
rtl
of
VME_User_CSR
is
signal
s_irq_vector
:
std_logic_vector
(
7
downto
0
);
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
-- Value for unused memory locations
constant
c_UNUSED
:
std_logic_vector
(
7
downto
0
)
:
=
x"ff"
;
constant
c_UNUSED
:
std_logic_vector
(
7
downto
0
)
:
=
x"ff"
;
...
@@ -104,12 +104,12 @@ begin
...
@@ -104,12 +104,12 @@ begin
if
rising_edge
(
clk_i
)
then
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
if
rst_n_i
=
'0'
then
s_irq_vector
<=
x"00"
;
s_irq_vector
<=
x"00"
;
s_irq_level
<=
x"
00"
;
s_irq_level
<=
"0
00"
;
else
else
if
we_i
=
'1'
then
if
we_i
=
'1'
then
case
to_integer
(
unsigned
(
addr_i
))
is
case
to_integer
(
unsigned
(
addr_i
))
is
when
c_IRQ_VECTOR
=>
s_irq_vector
<=
data_i
;
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
;
when
others
=>
null
;
end
case
;
end
case
;
end
if
;
end
if
;
...
@@ -129,7 +129,7 @@ begin
...
@@ -129,7 +129,7 @@ begin
else
else
case
to_integer
(
unsigned
(
addr_i
))
is
case
to_integer
(
unsigned
(
addr_i
))
is
when
c_IRQ_VECTOR
=>
data_o
<=
s_irq_vector
;
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_ENDIAN
=>
data_o
<=
x"00"
;
when
c_WB32BITS
=>
data_o
<=
x"01"
;
when
c_WB32BITS
=>
data_o
<=
x"01"
;
when
others
=>
data_o
<=
c_UNUSED
;
when
others
=>
data_o
<=
c_UNUSED
;
...
...
hdl/vme64x-core/rtl/VME_bus.vhd
View file @
74e4bdd3
...
@@ -97,9 +97,10 @@ entity VME_bus is
...
@@ -97,9 +97,10 @@ entity VME_bus is
VME_DATA_DIR_o
:
out
std_logic
;
VME_DATA_DIR_o
:
out
std_logic
;
VME_DATA_OE_N_o
:
out
std_logic
;
VME_DATA_OE_N_o
:
out
std_logic
;
VME_AM_i
:
in
std_logic_vector
(
5
downto
0
);
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
VME_IACKIN_n_i
:
in
std_logic
;
-- because VME_IACKIN_n_i is delayed the
VME_IACK_n_i
:
in
std_logic
;
-- more you are away from Slots 0
VME_IACKOUT_n_o
:
out
std_logic
;
-- WB signals
-- WB signals
stb_o
:
out
std_logic
;
stb_o
:
out
std_logic
;
ack_i
:
in
std_logic
;
ack_i
:
in
std_logic
;
...
@@ -126,7 +127,13 @@ entity VME_bus is
...
@@ -126,7 +127,13 @@ entity VME_bus is
cr_csr_data_o
:
out
std_logic_vector
(
7
downto
0
);
cr_csr_data_o
:
out
std_logic_vector
(
7
downto
0
);
cr_csr_we_o
:
out
std_logic
;
cr_csr_we_o
:
out
std_logic
;
module_enable_i
:
in
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
;
end
VME_bus
;
...
@@ -193,9 +200,15 @@ architecture RTL of VME_bus is
...
@@ -193,9 +200,15 @@ architecture RTL of VME_bus is
-- Assert DTACK
-- Assert DTACK
DTACK_LOW
,
DTACK_LOW
,
--
Increment address for block transfers
-- Increment address for block transfers
INCREMENT_ADDR
,
INCREMENT_ADDR
,
-- Check if IACK is for this slave
IRQ_CHECK
,
-- Pass IACKIN to IACKOUT
IRQ_PASS
,
-- Wait until AS is deasserted
-- Wait until AS is deasserted
WAIT_END
WAIT_END
);
);
...
@@ -209,6 +222,7 @@ architecture RTL of VME_bus is
...
@@ -209,6 +222,7 @@ architecture RTL of VME_bus is
-- Access decode signals
-- Access decode signals
signal
s_conf_sel
:
std_logic
;
-- CR or CSR is addressed
signal
s_conf_sel
:
std_logic
;
-- CR or CSR is addressed
signal
s_card_sel
:
std_logic
;
-- WB memory 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_is_d64
:
std_logic
;
signal
s_err
:
std_logic
;
signal
s_err
:
std_logic
;
...
@@ -298,10 +312,10 @@ begin
...
@@ -298,10 +312,10 @@ begin
VME_DATA_DIR_o
<=
'0'
;
VME_DATA_DIR_o
<=
'0'
;
VME_ADDR_DIR_o
<=
'0'
;
VME_ADDR_DIR_o
<=
'0'
;
VME_BERR_n_o
<=
'1'
;
VME_BERR_n_o
<=
'1'
;
VME_ADDR_o
<=
(
others
=>
'0'
);
VME_ADDR_o
<=
(
others
=>
'0'
);
VME_LWORD_n_o
<=
'1'
;
VME_LWORD_n_o
<=
'1'
;
VME_DATA_o
<=
(
others
=>
'0'
);
VME_DATA_o
<=
(
others
=>
'0'
);
VME_IACKOUT_n_o
<=
'1'
;
s_dataPhase
<=
'0'
;
s_dataPhase
<=
'0'
;
s_MBLT_Data
<=
'0'
;
s_MBLT_Data
<=
'0'
;
s_mainFSMstate
<=
IDLE
;
s_mainFSMstate
<=
IDLE
;
...
@@ -318,6 +332,8 @@ begin
...
@@ -318,6 +332,8 @@ begin
s_card_sel
<=
'0'
;
s_card_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_irq_sel
<=
'0'
;
irq_ack_o
<=
'0'
;
else
else
s_conf_req
<=
'0'
;
s_conf_req
<=
'0'
;
decode_start_o
<=
'0'
;
decode_start_o
<=
'0'
;
...
@@ -326,26 +342,28 @@ begin
...
@@ -326,26 +342,28 @@ begin
VME_DATA_DIR_o
<=
'0'
;
VME_DATA_DIR_o
<=
'0'
;
VME_ADDR_DIR_o
<=
'0'
;
VME_ADDR_DIR_o
<=
'0'
;
VME_BERR_n_o
<=
'1'
;
VME_BERR_n_o
<=
'1'
;
VME_IACKOUT_n_o
<=
'1'
;
irq_ack_o
<=
'0'
;
case
s_mainFSMstate
is
case
s_mainFSMstate
is
when
IDLE
=>
when
IDLE
=>
-- During the Interrupt ack cycle the Slave can't be accessed
if
VME_AS_n_i
=
'0'
then
-- 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
;
-- Store ADDR, AM and LWORD
-- Store ADDR, AM and LWORD
s_ADDRlatched
<=
VME_ADDR_i
;
s_ADDRlatched
<=
VME_ADDR_i
;
s_LWORDlatched_n
<=
VME_LWORD_n_i
;
s_LWORDlatched_n
<=
VME_LWORD_n_i
;
s_AMlatched
<=
VME_AM_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
else
s_mainFSMstate
<=
IDLE
;
s_mainFSMstate
<=
IDLE
;
end
if
;
end
if
;
...
@@ -366,6 +384,7 @@ begin
...
@@ -366,6 +384,7 @@ begin
-- Address is not yet decoded.
-- Address is not yet decoded.
s_card_sel
<=
'0'
;
s_card_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_irq_sel
<=
'0'
;
-- DS latch counter
-- DS latch counter
s_DS_latch_count
<=
to_unsigned
(
num_latchDS
,
3
);
s_DS_latch_count
<=
to_unsigned
(
num_latchDS
,
3
);
...
@@ -428,6 +447,8 @@ begin
...
@@ -428,6 +447,8 @@ begin
-- Note: before entering this state, s_DS_latch_count must be set.
-- Note: before entering this state, s_DS_latch_count must be set.
if
VME_DS_n_i
/=
"11"
then
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_WRITElatched_n
<=
VME_WRITE_n_i
;
s_DS_latch_count
<=
s_DS_latch_count
-
1
;
s_DS_latch_count
<=
s_DS_latch_count
-
1
;
s_mainFSMstate
<=
LATCH_DS
;
s_mainFSMstate
<=
LATCH_DS
;
...
@@ -455,7 +476,9 @@ begin
...
@@ -455,7 +476,9 @@ begin
end
if
;
end
if
;
if
s_DS_latch_count
=
0
then
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.
-- MBLT: ack address.
-- (Data are also read but discarded).
-- (Data are also read but discarded).
s_mainFSMstate
<=
DTACK_LOW
;
s_mainFSMstate
<=
DTACK_LOW
;
...
@@ -600,7 +623,7 @@ begin
...
@@ -600,7 +623,7 @@ begin
VME_ADDR_DIR_o
<=
(
s_is_d64
)
and
s_WRITElatched_n
;
VME_ADDR_DIR_o
<=
(
s_is_d64
)
and
s_WRITElatched_n
;
-- Set DTACK (or retry or berr)
-- 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'
;
VME_BERR_n_o
<=
'0'
;
else
else
VME_DTACK_n_o
<=
'0'
;
VME_DTACK_n_o
<=
'0'
;
...
@@ -620,7 +643,9 @@ begin
...
@@ -620,7 +643,9 @@ begin
-- DS latch counter
-- DS latch counter
s_DS_latch_count
<=
to_unsigned
(
num_latchDS
,
3
);
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
-- Cycle should be finished, but allow another access at
-- the same address (RMW).
-- the same address (RMW).
s_mainFSMstate
<=
WAIT_FOR_DS
;
s_mainFSMstate
<=
WAIT_FOR_DS
;
...
@@ -665,6 +690,32 @@ begin
...
@@ -665,6 +690,32 @@ begin
(
unsigned
(
s_ADDRlatched
(
11
downto
1
))
+
addr_word_incr
);
(
unsigned
(
s_ADDRlatched
(
11
downto
1
))
+
addr_word_incr
);
s_mainFSMstate
<=
WAIT_FOR_DS
;
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
=>
when
WAIT_END
=>
-- Will stay here until AS is released.
-- Will stay here until AS is released.
s_mainFSMstate
<=
WAIT_END
;
s_mainFSMstate
<=
WAIT_END
;
...
...
hdl/vme64x-core/rtl/vme64x_pack.vhd
View file @
74e4bdd3
...
@@ -179,7 +179,7 @@ package vme64x_pack is
...
@@ -179,7 +179,7 @@ package vme64x_pack is
VME_ADDR_o
:
out
std_logic_vector
(
31
downto
1
);
VME_ADDR_o
:
out
std_logic_vector
(
31
downto
1
);
VME_DATA_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_o
:
out
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_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
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
...
@@ -115,7 +115,7 @@ entity xvme64x_core is
VME_ADDR_b_o
:
out
std_logic_vector
(
31
downto
1
);
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_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_b_o
:
out
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_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
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
...
@@ -140,7 +140,7 @@ package xvme64x_core_pkg is
VME_ADDR_b_o
:
out
std_logic_vector
(
31
downto
1
);
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_i
:
in
std_logic_vector
(
31
downto
0
);
VME_DATA_b_o
:
out
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_IACKIN_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACK_n_i
:
in
std_logic
;
VME_IACKOUT_n_o
:
out
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
...
@@ -840,6 +840,7 @@ begin
end
if
;
end
if
;
end
loop
;
end
loop
;
VME_IACK_n_i
<=
'0'
;
VME_IACK_n_i
<=
'0'
;
VME_WRITE_n_i
<=
'1'
;
wait
for
35
ns
;
wait
for
35
ns
;
VME_AS_n_i
<=
'0'
;
VME_AS_n_i
<=
'0'
;
if
not
(
VME_DTACK_OE_o
=
'0'
and
VME_BERR_o
=
'0'
)
then
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