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
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