Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
V
VME64x core - msaccani
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
1
Merge Requests
1
Wiki
Wiki
Snippets
Snippets
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Mathieu Saccani
VME64x core - msaccani
Commits
c8c501f5
Commit
c8c501f5
authored
Jan 23, 2020
by
Tristan Gingold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vme_bus: new prefetch.
parent
e9ae25eb
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
187 additions
and
423 deletions
+187
-423
vme_bus.vhd
hdl/rtl/vme_bus.vhd
+187
-423
No files found.
hdl/rtl/vme_bus.vhd
View file @
c8c501f5
...
...
@@ -55,6 +55,7 @@ use ieee.std_logic_1164.all;
use
ieee
.
numeric_std
.
all
;
use
work
.
vme64x_pkg
.
all
;
use
work
.
wishbone_pkg
.
all
;
use
work
.
gencores_pkg
.
all
;
entity
vme_bus
is
generic
(
...
...
@@ -128,13 +129,10 @@ entity vme_bus is
end
vme_bus
;
architecture
rtl
of
vme_bus
is
-- Local data
signal
s_locDataIn
:
std_logic_vector
(
63
downto
0
);
signal
s_locDataOut
:
std_logic_vector
(
63
downto
0
);
-- VME latched signals - corresponds to the input dff in the pad.
-- latched at the rising edge of /AS:
signal
vme_idff_addr
:
std_logic_vector
(
31
downto
1
);
signal
vme_idff_data
:
std_logic_vector
(
31
downto
0
);
signal
vme_idff_lword_n
:
std_logic
;
signal
vme_idff_am
:
std_logic_vector
(
5
downto
0
);
...
...
@@ -146,7 +144,17 @@ architecture rtl of vme_bus is
signal
vme_odff_addr
:
std_logic_vector
(
31
downto
1
);
signal
vme_odff_data
:
std_logic_vector
(
31
downto
0
);
signal
vme_odff_lword_n
:
std_logic
;
signal
vme_odff_addr_dir
:
std_logic
;
signal
vme_odff_addr_dir
:
std_logic
;
-- Register containing the address. Initialized from VME, adjusted
-- by address decoder, and incremented during DMA.
signal
addr_reg
:
std_logic_vector
(
31
downto
0
);
-- Load addr_reg from vme idff (for address phase1).
signal
load_addr_reg_phase1
:
std_logic
;
-- Data register, owned by the WB fsm.
signal
data_reg
:
std_logic_vector
(
63
downto
0
);
type
t_addressingType
is
(
A24
,
...
...
@@ -190,9 +198,6 @@ architecture rtl of vme_bus is
-- Decode DS, generate WB request
CHECK_TRANSFER_TYPE
,
-- Wait for WB FSM
WAIT_WB_FSM
,
-- For read cycle, put data on the bus
DATA_TO_BUS
,
...
...
@@ -221,7 +226,6 @@ architecture rtl of vme_bus is
-- Main FSM signals
signal
s_mainFSMstate
:
t_mainFSMstates
;
signal
s_conf_req
:
std_logic
;
-- Global memory request
signal
s_dataPhase
:
std_logic
;
-- for MBLT
signal
s_MBLT_Data
:
std_logic
;
-- for MBLT: '1' in Addr
-- Access decode signals
...
...
@@ -256,26 +260,18 @@ architecture rtl of vme_bus is
-- WB FSM signals
signal
s_WBFSMstate
:
t_WBFSMstates
;
signal
s_WB_prefetch_buffer
:
std_logic_vector
(
63
downto
0
);
-- Synch signals for MAIN FSM and WB FSM
signal
s_wb_done
:
std_logic
;
signal
s_wb_start
:
std_logic
;
signal
s_wb_DTACK_LOW
:
std_logic
;
signal
s_wb_prefetch
:
std_logic
;
signal
s_wb_first_pf
:
std_logic
;
signal
s_wb_dataPhase
:
std_logic
;
signal
s_wb_vme_addr_reg
:
std_logic_vector
(
31
downto
1
);
signal
s_wb_locDataIn
:
std_logic_vector
(
63
downto
0
);
signal
s_wb_locDataOut
:
std_logic_vector
(
63
downto
0
);
signal
s_wb_dataphase
:
std_logic
;
signal
s_data_on_bus
:
std_logic
;
-- Set after address increment to enable a new prefetch.
signal
s_pom
:
std_logic
;
signal
incr
:
natural
range
0
to
7
;
-- just to keep track of addr_word_incr
begin
-- These output signals are connected to the buffers on the board
-- SN74VMEH22501A Function table: (A is fpga, B is VME connector)
...
...
@@ -330,7 +326,6 @@ begin
-- MAIN FSM
------------------------------------------------------------------------------
p_VMEmainFSM
:
process
(
clk_i
)
is
variable
addr_word_incr
:
natural
range
0
to
7
;
begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
or
vme_as_n_i
=
'1'
then
...
...
@@ -344,21 +339,18 @@ begin
vme_dtack_oe_o
<=
'0'
;
vme_dtack_n_o
<=
'1'
;
vme_data_dir_o
<=
'0'
;
vme_
addr_dir_o
<=
'0'
;
vme_
odff_addr_dir
<=
'0'
;
vme_berr_n_o
<=
'1'
;
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
;
s_data_on_bus
<=
'0'
;
-- WB
wb_sel_o
<=
"0000"
;
s_wb_start
<=
'0'
;
s_wb_first_pf
<=
'1'
;
s_wb_prefetch
<=
'0'
;
vme_idff_addr
<=
(
others
=>
'0'
);
...
...
@@ -367,6 +359,8 @@ begin
vme_odff_addr
<=
(
others
=>
'0'
);
vme_odff_addr_dir
<=
'0'
;
load_addr_reg_phase1
<=
'0'
;
s_card_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
s_irq_sel
<=
'0'
;
...
...
@@ -377,11 +371,14 @@ begin
vme_dtack_oe_o
<=
'0'
;
vme_dtack_n_o
<=
'1'
;
vme_data_dir_o
<=
'0'
;
vme_
addr_dir_o
<=
'0'
;
vme_
odff_addr_dir
<=
'0'
;
vme_berr_n_o
<=
'1'
;
vme_iackout_n_o
<=
'1'
;
irq_ack_o
<=
'0'
;
load_addr_reg_phase1
<=
'0'
;
s_wb_start
<=
'0'
;
case
s_mainFSMstate
is
when
IDLE
=>
...
...
@@ -394,6 +391,9 @@ begin
vme_idff_lword_n
<=
vme_lword_n_i
;
vme_idff_am
<=
vme_am_i
;
-- Address will be put to addr_reg.
load_addr_reg_phase1
<=
'1'
;
if
vme_iack_n_i
=
'1'
then
-- ANSI/VITA 1-1994 Rule 2.11
-- Slaves MUST NOT respond to DTB cycles when IACK* is low.
...
...
@@ -404,21 +404,6 @@ begin
end
if
;
when
REFORMAT_ADDRESS
=>
-- Reformat address according to the mode (A16, A24, A32)
-- FIXME: not needed if ADEM are correctly reduced to not compare
-- MSBs of A16 or A24 addresses.
vme_odff_addr
<=
vme_idff_addr
;
case
s_addressingType
is
when
A16
=>
vme_odff_addr
(
31
downto
16
)
<=
(
others
=>
'0'
);
-- A16
when
A24
|
A24_BLT
|
A24_MBLT
=>
vme_odff_addr
(
31
downto
24
)
<=
(
others
=>
'0'
);
-- A24
when
others
=>
null
;
-- A32
end
case
;
vme_odff_lword_n
<=
vme_idff_lword_n
;
-- Address is not yet decoded.
s_card_sel
<=
'0'
;
s_conf_sel
<=
'0'
;
...
...
@@ -465,10 +450,9 @@ begin
if
decode_sel_i
=
'1'
and
module_enable_i
=
'1'
then
-- card_sel = '1' it means WB application addressed
s_card_sel
<=
'1'
;
-- Keep only the local part of the address.
vme_odff_addr
<=
addr_decoder_i
;
if
vme_ds_n_i
=
"11"
then
-- Still have to wait for DS...
s_mainFSMstate
<=
WAIT_FOR_DS
;
else
s_mainFSMstate
<=
LATCH_DS
;
...
...
@@ -487,79 +471,17 @@ begin
-- wait until DS /= "11"
-- Note: before entering this state, s_DS_latch_count must be set.
-- if vme_ds_n_i /= "11" then
-- -- ANSI/VITA 1-1994 Table 4-1
-- -- For interrupts ack, the handler MUST NOT drive WRITE* low
-- vme_idff_write_n <= vme_write_n_i;
-- if s_DS_latch_count /= 0 then
-- s_DS_latch_count <= s_DS_latch_count - 1;
-- end if;
-- s_mainFSMstate <= LATCH_DS;
-- else
-- s_mainFSMstate <= WAIT_FOR_DS;
-- end if;
if
s_wb_prefetch
=
'1'
and
s_transferType
=
MBLT
and
s_WBFSMstate
=
IDLE
and
vme_ds_n_i
=
"11"
and
s_data_on_bus
=
'0'
then
-- Previous Data was read, new Data is prefetched, but a new
-- read req is not yet issued by the master
-- Already prepare data on vmebus
-- Put data to VME bus from s_wb_locDataOut
vme_addr_o
<=
s_wb_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_wb_locDataOut
(
32
);
vme_data_o
<=
s_wb_locDataOut
(
31
downto
0
);
vme_data_dir_o
<=
'1'
;
vme_addr_dir_o
<=
'1'
;
vme_dtack_oe_o
<=
'1'
;
s_data_on_bus
<=
'1'
;
end
if
;
-- MBLT read only going to S1, S2 (Should optimize this state
-- obviously)
if
vme_ds_n_i
/=
"11"
and
s_transferType
=
MBLT
and
s_wb_prefetch
=
'1'
and
s_WBFSMstate
=
IDLE
then
if
vme_ds_n_i
/=
"11"
then
-- ANSI/VITA 1-1994 Table 4-1
-- For interrupts ack, the handler MUST NOT drive WRITE* low
vme_idff_write_n
<=
vme_write_n_i
;
if
s_DS_latch_count
/=
0
then
s_DS_latch_count
<=
s_DS_latch_count
-
1
;
end
if
;
if
s_data_on_bus
=
'0'
then
s_mainFSMstate
<=
S1
;
-- Put data to VME bus from s_wb_locDataOut
vme_addr_o
<=
s_wb_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_wb_locDataOut
(
32
);
vme_data_o
<=
s_wb_locDataOut
(
31
downto
0
);
vme_data_dir_o
<=
'1'
;
vme_addr_dir_o
<=
'1'
;
vme_dtack_oe_o
<=
'1'
;
else
s_mainFSMstate
<=
S2
;
vme_dtack_n_o
<=
'0'
;
-- start prefetch
s_wb_start
<=
'1'
;
vme_data_dir_o
<=
'1'
;
vme_addr_dir_o
<=
'1'
;
vme_dtack_oe_o
<=
'1'
;
s_data_on_bus
<=
'0'
;
end
if
;
elsif
vme_ds_n_i
/=
"11"
and
s_wb_prefetch
/=
'1'
then
-- ANSI/VITA 1-1994 Table 4-1
-- For interrupts ack, the handler MUST NOT drive WRITE* low
-- Sample write. It must be stable before DS.
vme_idff_write_n
<=
vme_write_n_i
;
if
s_DS_latch_count
/=
0
then
s_DS_latch_count
<=
s_DS_latch_count
-
1
;
end
if
;
s_mainFSMstate
<=
LATCH_DS
;
else
s_mainFSMstate
<=
WAIT_FOR_DS
;
...
...
@@ -573,39 +495,35 @@ begin
-- During all read cycles [...], the responding slave MUST NOT
-- drive the D[] lines until DSA* goes low.
vme_data_dir_o
<=
vme_idff_write_n
;
vme_
addr_dir_o
<=
'0'
;
vme_
odff_addr_dir
<=
'0'
;
if
g_VME32
and
s_transferType
=
MBLT
then
s_dataPhase
<=
'1'
;
if
s_DS_latch_count
=
0
or
s_transferType
=
MBLT
then
-- Read DS (which is delayed to avoid metastability).
vme_idff_ds_n
<=
vme_ds_n_i
;
-- Start with D[31..0] when writing, but D[63..32] when reading.
vme_odff_addr
(
2
)
<=
not
vme_idff_write_n
;
else
s_dataPhase
<=
'0'
;
end
if
;
-- Read DATA (which are stable)
vme_idff_addr
<=
vme_addr_i
;
vme_idff_lword_n
<=
vme_lword_n_i
;
vme_idff_data
<=
vme_data_i
;
if
s_DS_latch_count
=
0
or
s_transferType
=
MBLT
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
;
if
vme_idff_write_n
=
'1'
then
-- Can fetch the first data.
s_wb_start
<=
'1'
;
end
if
;
else
s_mainFSMstate
<=
CHECK_TRANSFER_TYPE
;
if
s_wb_prefetch
=
'0'
then
-- For every single access or every access at MBLT WRITE
s_wb_start
<=
'1'
;
-- lets do it when entering CTT
-- For every single access or every access at MBLT WRITE
if
not
(
s_transferType
=
MBLT
and
vme_idff_write_n
=
'1'
)
then
s_wb_start
<=
'1'
;
end
if
;
end
if
;
-- Read DS (which is delayed to avoid metastability).
vme_idff_ds_n
<=
vme_ds_n_i
;
-- Read DATA (which are stable)
s_locDataIn
(
63
downto
33
)
<=
vme_addr_i
;
vme_idff_lword_n
<=
vme_lword_n_i
;
vme_odff_data
<=
vme_data_i
;
else
s_mainFSMstate
<=
LATCH_DS
;
s_DS_latch_count
<=
s_DS_latch_count
-
1
;
...
...
@@ -613,8 +531,6 @@ begin
when
CHECK_TRANSFER_TYPE
=>
vme_data_dir_o
<=
vme_idff_write_n
;
vme_addr_dir_o
<=
'0'
;
s_dataPhase
<=
s_dataPhase
;
-- vme_addr is an output during MBLT *read* data transfer.
if
s_transferType
=
MBLT
and
vme_idff_write_n
=
'1'
and
g_VME32
then
...
...
@@ -623,34 +539,6 @@ begin
vme_odff_addr_dir
<=
'0'
;
end
if
;
s_locDataIn
(
32
)
<=
vme_idff_lword_n
;
s_locDataIn
(
31
downto
0
)
<=
vme_odff_data
;
if
vme_odff_lword_n
=
'1'
and
vme_odff_addr
(
1
)
=
'0'
and
g_VME32
then
-- Word/byte access with A1=0
s_locDataIn
(
31
downto
16
)
<=
vme_odff_data
(
15
downto
0
);
end
if
;
-- Translate DS+LWORD+ADDR to WB byte selects
if
not
g_VME32
then
-- 16bit access on a 16bit bus.
wb_sel_o
(
3
downto
2
)
<=
"00"
;
wb_sel_o
(
1
downto
0
)
<=
not
vme_idff_ds_n
;
elsif
vme_odff_lword_n
=
'0'
then
-- 32bit access
wb_sel_o
<=
"1111"
;
else
-- 16bit access on a 32bit bus.
wb_sel_o
<=
"0000"
;
case
vme_odff_addr
(
1
)
is
when
'0'
=>
wb_sel_o
(
3
downto
2
)
<=
not
vme_idff_ds_n
;
when
'1'
=>
wb_sel_o
(
1
downto
0
)
<=
not
vme_idff_ds_n
;
when
others
=>
null
;
end
case
;
end
if
;
-- ANSI/VITA 1-1994 Rule 2.6
-- A Slave MUST NOT respond with a falling edge on DTACK* during
-- an unaligned transfer cycle, if it does not have UAT
...
...
@@ -658,63 +546,39 @@ begin
if
vme_odff_lword_n
=
'0'
and
vme_idff_ds_n
/=
"00"
then
-- unaligned.
s_mainFSMstate
<=
WAIT_END
;
elsif
s_WBFSMstate
=
IDLE
and
s_wb_prefetch
=
'1'
then
-- There was a prefetch that has finished. So, only if prefetch
-- is done and there is a new read request
s_mainFSMstate
<=
DATA_TO_BUS
;
s_wb_start
<=
'1'
;
-- start next prefetch
s_locDataOut
<=
s_wb_locDataOut
;
-- Take the prefetched data
else
s_mainFSMstate
<=
WAIT_WB_FSM
;
-- s_wb_start <= '1'; -- lets do it when entering CTT
s_mainFSMstate
<=
DATA_TO_BUS
;
s_conf_req
<=
s_conf_sel
;
end
if
;
-- Needed to add this here because it must be available sooner
-- for prefetch. May be reduntant at CTT
if
g_VME32
and
vme_odff_lword_n
=
'0'
and
vme_idff_write_n
=
'1'
then
if
s_transferType
=
MBLT
then
-- 64 bit
addr_word_incr
:
=
4
;
else
-- 32 bit
addr_word_incr
:
=
2
;
end
if
;
else
null
;
-- Just do it for MBLT read, let other cases be determined at their places
end
if
;
when
DATA_TO_BUS
=>
vme_dtack_oe_o
<=
'1'
;
vme_data_dir_o
<=
vme_idff_write_n
;
vme_addr_dir_o
<=
vme_odff_addr_dir
;
if
g_VME32
then
-- only for MBLT
vme_addr_o
<=
s_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_locDataOut
(
32
);
end
if
;
vme_data_o
<=
s_locDataOut
(
31
downto
0
);
-- ANSI/VITA 1-1994 Rule 2.54a
-- During all read cycles, the responding Slave MUST NOT drive
-- DTACK* low before it drives D[].
s_mainFSMstate
<=
DTACK_LOW
;
-- Update what WB FSM prepared
if
s_conf_sel
=
'1'
or
s_wb_done
=
'1'
or
s_irq_sel
=
'1'
then
vme_dtack_oe_o
<=
'1'
;
vme_data_dir_o
<=
vme_idff_write_n
;
if
g_VME32
then
-- only for MBLT
vme_addr_o
<=
data_reg
(
63
downto
33
);
vme_lword_n_o
<=
data_reg
(
32
);
end
if
;
vme_data_o
<=
data_reg
(
31
downto
0
);
if
vme_idff_write_n
=
'1'
then
-- if it is a read, but not MBLT or 1st MBLT data
vme_dtack_n_o
<=
'0
'
;
end
if
;
if
s_transferType
=
MBLT
and
vme_idff_write_n
=
'1'
then
-- Prefetch.
s_wb_start
<=
'1
'
;
end
if
;
if
s_wb_prefetch
=
'1'
then
s_wb_start
<=
'0'
;
-- ANSI/VITA 1-1994 Rule 2.54a
-- During all read cycles, the responding Slave MUST NOT drive
-- DTACK* low before it drives D[].
s_mainFSMstate
<=
DTACK_LOW
;
end
if
;
when
DTACK_LOW
=>
--
Think this block can execute when moving from WAIT_WB_FSM to DTACK_LOW
--
Set /DTACK, wait until /DS[1:0] are released.
vme_dtack_oe_o
<=
'1'
;
vme_data_dir_o
<=
vme_idff_write_n
;
vme_addr_dir_o
<=
vme_odff_addr_dir
;
-- Set DTACK (or retry or berr)
if
s_card_sel
=
'1'
and
s_err
=
'1'
then
...
...
@@ -744,65 +608,21 @@ begin
-- the same address (RMW).
s_mainFSMstate
<=
WAIT_FOR_DS
;
else
-- Any block transfer.
if
g_VME32
and
s_transferType
=
MBLT
and
s_MBLT_Data
=
'0'
then
-- MBLT: end of address phase.
s_mainFSMstate
<=
WAIT_FOR_DS
;
s_MBLT_Data
<=
'1'
;
else
-- Block
s_mainFSMstate
<=
INCREMENT_ADDR
;
end
if
;
s_mainFSMstate
<=
WAIT_FOR_DS
;
end
if
;
else
s_mainFSMstate
<=
DTACK_LOW
;
end
if
;
if
s_wb_prefetch
=
'1'
and
s_transferType
=
MBLT
and
s_WBFSMstate
=
IDLE
and
vme_ds_n_i
=
"11"
and
s_data_on_bus
=
'0'
then
-- Previous Data was read, new Data is prefetched, but a new read
-- req is not yet issued by the master
-- Already prepare data on vmebus
-- Put data to VME bus from s_wb_locDataOut
vme_addr_o
<=
s_wb_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_wb_locDataOut
(
32
);
vme_data_o
<=
s_wb_locDataOut
(
31
downto
0
);
vme_data_dir_o
<=
'1'
;
vme_addr_dir_o
<=
'1'
;
vme_dtack_oe_o
<=
'1'
;
s_data_on_bus
<=
'1'
;
end
if
;
when
INCREMENT_ADDR
=>
vme_dtack_oe_o
<=
'1'
;
vme_addr_dir_o
<=
vme_odff_addr_dir
;
if
g_VME32
and
vme_odff_lword_n
=
'0'
then
if
s_transferType
=
MBLT
then
-- 64 bit
addr_word_incr
:
=
4
;
else
-- 32 bit
addr_word_incr
:
=
2
;
end
if
;
else
if
vme_idff_ds_n
(
0
)
=
'0'
then
-- Next word for D16 or D08(O)
addr_word_incr
:
=
1
;
else
addr_word_incr
:
=
0
;
end
if
;
end
if
;
-- Only increment within the window, don't check the limit.
-- BLT --> limit = 256 bytes (rule 2.12a ANSI/VITA 1-1994)
-- MBLT --> limit = 2048 bytes (rule 2.78 ANSI/VITA 1-1994)
vme_odff_addr
(
11
downto
1
)
<=
std_logic_vector
(
unsigned
(
vme_odff_addr
(
11
downto
1
))
+
addr_word_incr
);
s_mainFSMstate
<=
WAIT_FOR_DS
;
if
s_wb_prefetch
=
'1'
then
...
...
@@ -819,9 +639,9 @@ begin
-- read req is not yet issued by the master
-- Already prepare data on vmebus
-- Put data to VME bus from s_wb_locDataOut
vme_addr_o
<=
s_wb_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_wb_locDataOut
(
32
);
vme_data_o
<=
s_wb_locDataOut
(
31
downto
0
);
vme_addr_o
<=
data_reg
(
63
downto
33
);
vme_lword_n_o
<=
data_reg
(
32
);
vme_data_o
<=
data_reg
(
31
downto
0
);
vme_data_dir_o
<=
'1'
;
vme_addr_dir_o
<=
'1'
;
vme_dtack_oe_o
<=
'1'
;
...
...
@@ -835,8 +655,8 @@ begin
and
irq_pending_i
=
'1'
then
-- That's for us
s_locDataOut
<=
(
others
=>
'0'
);
s_locDataOut
(
7
downto
0
)
<=
int_vector_i
;
vme_odff_data
<=
(
others
=>
'0'
);
vme_odff_data
(
7
downto
0
)
<=
int_vector_i
;
s_irq_sel
<=
'1'
;
irq_ack_o
<=
'1'
;
...
...
@@ -859,71 +679,6 @@ begin
-- Will stay here until AS is released.
s_mainFSMstate
<=
WAIT_END
;
when
WAIT_WB_FSM
=>
-- Update what WB FSM prepared
s_dataPhase
<=
s_wb_dataPhase
;
if
s_wb_done
=
'1'
then
-- Solving the unaligned data during write
s_locDataIn
<=
s_wb_locDataIn
;
elsif
s_WBFSMstate
=
MEMORY_PAUSE
then
s_locDataIn
<=
s_wb_locDataIn
;
end
if
;
s_locDataOut
<=
s_wb_locDataOut
;
vme_odff_addr
<=
s_wb_vme_addr_reg
;
--may be possible only 1 bit
s_wb_start
<=
'0'
;
if
s_wb_done
=
'1'
then
s_mainFSMstate
<=
DATA_TO_BUS
;
if
(
s_transferType
=
MBLT
)
and
(
vme_idff_write_n
=
'1'
)
then
-- MBLT read (Might want to specify exactly the one MBLT of
-- interest)
s_wb_prefetch
<=
'1'
;
-- needs to be reset somewhere
s_wb_start
<=
'1'
;
s_dataPhase
<=
'1'
;
-- because WB FMS will be reading 1st
-- 32 bit word first when prefetching
-- Only increment within the window, don't check the limit.
-- MBLT --> limit = 2048 bytes (rule 2.78 ANSI/VITA 1-1994)
if
s_wb_first_pf
=
'1'
then
vme_odff_addr
(
11
downto
1
)
<=
std_logic_vector
(
unsigned
(
vme_odff_addr
(
11
downto
1
))
+
addr_word_incr
/
2
);
-- Only for first prefetch, @ A32 MBLT 64
s_wb_first_pf
<=
'0'
;
else
null
;
-- the other MAIN FSM states will prepare the adress in case of not first prefetch
end
if
;
end
if
;
if
vme_idff_write_n
=
'1'
and
s_wb_prefetch
=
'0'
then
-- if it is a read, but not MBLT or 1st MBLT data
vme_dtack_oe_o
<=
'1'
;
vme_data_dir_o
<=
vme_idff_write_n
;
vme_addr_dir_o
<=
vme_odff_addr_dir
;
if
g_VME32
then
-- only for MBLT
vme_addr_o
<=
s_wb_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_wb_locDataOut
(
32
);
end
if
;
vme_data_o
<=
s_wb_locDataOut
(
31
downto
0
);
end
if
;
elsif
((
s_wb_DTACK_LOW
=
'1'
)
or
((
s_WBFSMstate
=
MEMORY_REQ
)
and
(
s_DataPhase
=
'0'
)
and
(
vme_idff_write_n
=
'0'
)
and
(
wb_ack_i
=
'1'
)))
then
-- added or to not loose a cycle for acknowledging.
-- Solving for write only 1st.
s_mainFSMstate
<=
DTACK_LOW
;
-- Maybe DTACK LOW needs to use this info for further actions?
else
s_mainFSMstate
<=
WAIT_WB_FSM
;
end
if
;
when
s1
=>
s_mainFSMstate
<=
s2
;
vme_dtack_n_o
<=
'0'
;
...
...
@@ -962,9 +717,9 @@ begin
-- Previous Data was read, new Data is prefetched, but a new read req is not yet issued by the master
-- Already prepare data on vmebus
-- Put data to VME bus from s_wb_locDataOut
vme_addr_o
<=
s_wb_locDataOut
(
63
downto
33
);
vme_lword_n_o
<=
s_wb_locDataOut
(
32
);
vme_data_o
<=
s_wb_locDataOut
(
31
downto
0
);
vme_addr_o
<=
data_reg
(
63
downto
33
);
vme_lword_n_o
<=
data_reg
(
32
);
vme_data_o
<=
data_reg
(
31
downto
0
);
vme_data_dir_o
<=
'1'
;
vme_addr_dir_o
<=
'1'
;
vme_dtack_oe_o
<=
'1'
;
...
...
@@ -986,7 +741,6 @@ begin
end
if
;
end
if
;
end
if
;
incr
<=
addr_word_incr
;
end
process
;
------------------------------------------------------------------------------
...
...
@@ -1004,10 +758,10 @@ begin
-- WB
wb_cyc_o
<=
'0'
;
wb_stb_o
<=
'0'
;
wb_sel_o
<=
"0000"
;
wb_we_o
<=
'0'
;
s_err
<=
'0'
;
s_wb_DTACK_LOW
<=
'0'
;
s_wb_done
<=
'0'
;
else
case
s_WBFSMstate
is
...
...
@@ -1016,31 +770,85 @@ begin
-- cycle.
assert
vme_as_n_i
=
'0'
;
s_wb_DTACK_LOW
<=
'0'
;
s_wb_done
<=
'0'
;
if
load_addr_reg_phase1
=
'1'
then
addr_reg
(
31
downto
1
)
<=
vme_idff_addr
;
addr_reg
(
0
)
<=
vme_idff_lword_n
;
-- Reformat address according to the mode (A16, A24, A32)
-- FIXME: not needed if ADEM are correctly reduced to not compare
-- MSBs of A16 or A24 addresses.
case
s_addressingType
is
when
A16
=>
addr_reg
(
31
downto
16
)
<=
(
others
=>
'0'
);
-- A16
when
A24
|
A24_BLT
|
A24_MBLT
=>
addr_reg
(
31
downto
24
)
<=
(
others
=>
'0'
);
-- A24
when
others
=>
null
;
-- A32
end
case
;
end
if
;
-- Latching some important signals from the main FSM
s_wb_dataPhase
<=
s_dataPhase
;
s_wb_vme_addr_reg
<=
vme_odff_addr
;
s_wb_locDataIn
<=
s_locDataIn
;
if
decode_done_i
=
'1'
then
-- Keep only the local part of the address.
addr_reg
(
31
downto
1
)
<=
addr_decoder_i
;
end
if
;
if
s_wb_start
=
'1'
then
-- Start WB cycle.
wb_cyc_o
<=
s_card_sel
;
wb_stb_o
<=
s_card_sel
;
s_stall
<=
'1'
;
-- Can stall
s_err
<=
'0'
;
s_WBFSMstate
<=
MEMORY_REQ
;
elsif
vme_ds_n_i
/=
"11"
and
s_wb_prefetch
=
'1'
and
s_pom
=
'1'
then
if
s_wb_start
=
'1'
or
s_wb_prefetch
=
'1'
then
-- Start WB cycle.
wb_cyc_o
<=
s_card_sel
;
wb_stb_o
<=
s_card_sel
;
wb_we_o
<=
not
vme_idff_write_n
;
s_wb_done
<=
'0'
;
--if vme_odff_lword_n = '1' and vme_odff_addr(1) = '0' and g_VME32 then
-- -- Word/byte access with A1=0
-- s_locDataIn(31 downto 16) <= vme_odff_data(15 downto 0);
--end if;
if
vme_idff_write_n
=
'0'
then
-- Get the data to write (in case of write!).
if
g_VME32
and
s_transferType
=
MBLT
then
data_reg
(
0
)
<=
vme_idff_lword_n
;
data_reg
(
31
downto
1
)
<=
vme_idff_addr
;
data_reg
(
63
downto
32
)
<=
vme_idff_data
;
else
data_reg
(
31
downto
0
)
<=
vme_idff_data
;
data_reg
(
32
)
<=
vme_idff_lword_n
;
data_reg
(
63
downto
33
)
<=
vme_idff_addr
;
end
if
;
end
if
;
-- Translate DS+LWORD+ADDR to WB byte selects
if
not
g_VME32
then
-- 16bit access on a 16bit bus.
wb_sel_o
(
3
downto
2
)
<=
"00"
;
wb_sel_o
(
1
downto
0
)
<=
not
vme_idff_ds_n
;
elsif
addr_reg
(
0
)
=
'0'
then
-- 32bit access
wb_sel_o
<=
"1111"
;
else
-- 16bit access on a 32bit bus.
wb_sel_o
<=
"0000"
;
case
addr_reg
(
1
)
is
when
'0'
=>
wb_sel_o
(
3
downto
2
)
<=
not
vme_idff_ds_n
;
when
'1'
=>
wb_sel_o
(
1
downto
0
)
<=
not
vme_idff_ds_n
;
when
others
=>
null
;
end
case
;
end
if
;
s_wb_dataphase
<=
f_to_std_logic
(
s_transferType
=
MBLT
);
s_stall
<=
'1'
;
-- Can stall
s_err
<=
'0'
;
s_WBFSMstate
<=
MEMORY_REQ
;
s_wb_dataPhase
<=
'1'
;
if
s_card_sel
=
'1'
then
s_WBFSMstate
<=
MEMORY_REQ
;
else
s_wb_done
<=
'1'
;
s_WBFSMstate
<=
IDLE
;
end
if
;
else
-- Wait in IDLE until s_wb_start = '1'
s_WBFSMstate
<=
IDLE
;
...
...
@@ -1051,10 +859,6 @@ begin
-- generate a pulse on s_conf_req signal
-- Assert STB if stall was asserted.
if
s_dataPhase
=
'1'
then
-- fix Data for write
s_wb_locDataIn
<=
s_locDataIn
;
end
if
;
case
g_WB_MODE
is
when
CLASSIC
=>
-- Maintain STB.
...
...
@@ -1071,26 +875,31 @@ begin
then
-- WB ack
wb_stb_o
<=
'0'
;
s_err
<=
s_card_sel
and
wb_err_i
;
if
s_transferType
/=
SINGLE
then
-- Next word for any block transfer.
addr_reg
(
11
downto
2
)
<=
std_logic_vector
(
unsigned
(
addr_reg
(
11
downto
2
))
+
1
);
end
if
;
if
(
s_card_sel
and
wb_err_i
)
=
'1'
then
-- Error
s_
wb_DTACK_LOW
<=
'1'
;
s_
err
<=
'1'
;
s_WBFSMstate
<=
IDLE
;
elsif
vme_idff_write_n
=
'0'
then
-- Write cycle.
if
s_wb_dataPhase
=
'1'
then
-- MBLT
s_wb_dataPhase
<=
'0'
;
s_wb_vme_addr_reg
(
2
)
<=
'0'
;
s_wb_locDataIn
(
31
downto
0
)
<=
s_wb_locDataIn
(
63
downto
32
);
data_reg
(
31
downto
0
)
<=
data_reg
(
63
downto
32
);
-- STB is 0, wait one cycle before the 2nd xfer.
s_WBFSMstate
<=
MEMORY_PAUSE
;
else
s_wb_DTACK_LOW
<=
'1'
;
-- done, IDLE?
s_wb_done
<=
'1'
;
s_WBFSMstate
<=
IDLE
;
end
if
;
...
...
@@ -1098,23 +907,23 @@ begin
-- Read cycle
-- Mux (CS-CSR or WB)
s_wb_locDataOut
(
63
downto
32
)
<=
s_wb_locDataOut
(
31
downto
0
);
s_wb_locDataOut
(
31
downto
0
)
<=
(
others
=>
'0'
);
data_reg
(
63
downto
32
)
<=
data_reg
(
31
downto
0
);
data_reg
(
31
downto
0
)
<=
(
others
=>
'0'
);
if
s_card_sel
=
'1'
then
if
g_VME32
and
vme_odff_lword_n
=
'1'
and
s_wb_vme_addr_reg
(
1
)
=
'0'
then
if
g_VME32
and
vme_odff_lword_n
=
'1'
and
addr_reg
(
1
)
=
'0'
then
-- Word/byte access with A1 = 0 on a 32bit bus.
s_wb_locDataOut
(
15
downto
0
)
<=
wb_dat_i
(
31
downto
16
);
data_reg
(
15
downto
0
)
<=
wb_dat_i
(
31
downto
16
);
else
s_wb_locDataOut
(
31
downto
0
)
<=
wb_dat_i
;
data_reg
(
31
downto
0
)
<=
wb_dat_i
;
end
if
;
else
s_wb_locDataOut
(
7
downto
0
)
<=
cr_csr_data_i
;
data_reg
(
7
downto
0
)
<=
cr_csr_data_i
;
end
if
;
if
s_wb_dataPhase
=
'1'
and
g_VME32
then
-- MBLT
s_wb_dataPhase
<=
'0'
;
s_wb_vme_addr_reg
(
2
)
<=
'1'
;
-- STB is 0, wait one cycle before the 2nd xfer.
s_WBFSMstate
<=
MEMORY_PAUSE
;
...
...
@@ -1151,74 +960,29 @@ begin
-- WB Master
-- g_wb_addr32: if g_VME32 generate
-- with g_WB_GRANULARITY select
-- wb_adr_o <= "00" & vme_odff_addr(31 downto 2) when WORD,
-- vme_odff_addr(31 downto 2) & "00" when BYTE;
-- end generate;
-- g_wb_addr16: if not g_VME32 generate
-- with g_WB_GRANULARITY select
-- wb_adr_o <= "0" & vme_odff_addr(31 downto 1) when WORD,
-- vme_odff_addr(31 downto 1) & "0" when BYTE;
-- end generate;
-- -- g_wb_addr32_pf: if g_VME32 generate
-- -- with g_WB_GRANULARITY select
-- -- wb_adr_o <= "00" & s_wb_vme_addr_reg(31 downto 2) when WORD,
-- -- s_wb_vme_addr_reg(31 downto 2) & "00" when BYTE;
-- -- end generate;
-- -- g_wb_addr16_pf: if not g_VME32 generate
-- -- with g_WB_GRANULARITY select
-- -- wb_adr_o <= "0" & s_wb_vme_addr_reg(31 downto 1) when WORD,
-- -- s_wb_vme_addr_reg(31 downto 1) & "0" when BYTE;
-- -- end generate;
process
(
vme_odff_addr
,
s_wb_vme_addr_reg
)
begin
if
(
s_wb_prefetch
=
'0'
)
then
if
g_VME32
then
if
g_WB_GRANULARITY
=
WORD
then
wb_adr_o
<=
"00"
&
vme_odff_addr
(
31
downto
2
);
elsif
g_WB_GRANULARITY
=
BYTE
then
wb_adr_o
<=
vme_odff_addr
(
31
downto
2
)
&
"00"
;
end
if
;
elsif
(
not
g_VME32
)
then
if
g_WB_GRANULARITY
=
WORD
then
wb_adr_o
<=
"0"
&
vme_odff_addr
(
31
downto
1
);
elsif
g_WB_GRANULARITY
=
BYTE
then
wb_adr_o
<=
vme_odff_addr
(
31
downto
1
)
&
"0"
;
end
if
;
end
if
;
elsif
(
s_wb_prefetch
=
'1'
)
then
if
g_VME32
then
if
g_WB_GRANULARITY
=
WORD
then
wb_adr_o
<=
"00"
&
s_wb_vme_addr_reg
(
31
downto
2
);
elsif
g_WB_GRANULARITY
=
BYTE
then
wb_adr_o
<=
s_wb_vme_addr_reg
(
31
downto
2
)
&
"00"
;
end
if
;
elsif
(
not
g_VME32
)
then
if
g_WB_GRANULARITY
=
WORD
then
wb_adr_o
<=
"0"
&
s_wb_vme_addr_reg
(
31
downto
1
);
elsif
g_WB_GRANULARITY
=
BYTE
then
wb_adr_o
<=
s_wb_vme_addr_reg
(
31
downto
1
)
&
"0"
;
end
if
;
end
if
;
end
if
;
end
process
;
g_wb_addr32
:
if
g_VME32
generate
with
g_WB_GRANULARITY
select
wb_adr_o
<=
"00"
&
addr_reg
(
31
downto
2
)
when
WORD
,
addr_reg
(
31
downto
2
)
&
"00"
when
BYTE
;
end
generate
;
g_wb_addr16
:
if
not
g_VME32
generate
with
g_WB_GRANULARITY
select
wb_adr_o
<=
"0"
&
addr_reg
(
31
downto
1
)
when
WORD
,
addr_reg
(
31
downto
1
)
&
"0"
when
BYTE
;
end
generate
;
wb_we_o
<=
not
vme_idff_write_n
;
wb_dat_o
<=
s_locDataIn
(
31
downto
0
);
wb_dat_o
<=
data_reg
(
31
downto
0
);
-- Function Decoder
addr_decoder_o
<=
vme_odff_addr
;
addr_decoder_o
<=
addr_reg
(
31
downto
1
)
;
am_o
<=
vme_idff_am
;
-- CR/CSR In/Out
cr_csr_data_o
<=
s_locDataIn
(
7
downto
0
);
cr_csr_addr_o
<=
vme_odff_addr
(
18
downto
2
);
cr_csr_we_o
<=
'1'
when
s_conf_req
=
'1'
and
vme_idff_write_n
=
'0'
else
'0'
;
cr_csr_data_o
<=
data_reg
(
7
downto
0
);
cr_csr_addr_o
<=
addr_reg
(
18
downto
2
);
cr_csr_we_o
<=
'1'
when
s_conf_req
=
'1'
and
vme_idff_write_n
=
'0'
else
'0'
;
vme_addr_dir_o
<=
vme_odff_addr_dir
;
end
rtl
;
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