Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Gateware
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
12
Issues
12
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Gateware
Commits
cfe39eca
Commit
cfe39eca
authored
Dec 07, 2010
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hdl: wrsw_swcore: fixed input block dreq_o generation bug
parent
c387c8e0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
992 additions
and
990 deletions
+992
-990
swc_input_block.vhd
swc_input_block.vhd
+992
-990
No files found.
swc_input_block.vhd
View file @
cfe39eca
...
...
@@ -95,270 +95,270 @@ entity swc_input_block is
-------------------------------------------------------------------------------
-- indicates that a port X wants to write page address of the "write" access
mmu_page_alloc_req_o
:
out
std_logic
;
mmu_page_alloc_req_o
:
out
std_logic
;
mmu_page_alloc_done_i
:
in
std_logic
;
-- array of pages' addresses to which ports want to write
mmu_pageaddr_i
:
in
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
mmu_pageaddr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
mmu_pageaddr_i
:
in
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
mmu_pageaddr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
-- force freeing package starting with page outputed on mmu_pageaddr_o
mmu_force_free_o
:
out
std_logic
;
mmu_force_free_o
:
out
std_logic
;
mmu_force_free_done_i
:
in
std_logic
;
mmu_force_free_addr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
-- set user count to the already allocated page (on mmu_pageaddr_o)
mmu_set_usecnt_o
:
out
std_logic
;
mmu_set_usecnt_done_i
:
in
std_logic
;
mmu_set_usecnt_o
:
out
std_logic
;
mmu_set_usecnt_done_i
:
in
std_logic
;
-- user count to be set (associated with an allocated page) in two cases:
-- * mmu_pagereq_o is HIGH - normal allocation
-- * mmu_set_usecnt_o is HIGH - force user count to existing page alloc
mmu_usecnt_o
:
out
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
mmu_usecnt_o
:
out
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
-- memory full
mmu_nomem_i
:
in
std_logic
;
mmu_nomem_i
:
in
std_logic
;
-------------------------------------------------------------------------------
-- I/F with Routing Table Unit (RTU)
-------------------------------------------------------------------------------
rtu_rsp_valid_i
:
in
std_logic
;
rtu_rsp_valid_i
:
in
std_logic
;
rtu_rsp_ack_o
:
out
std_logic
;
rtu_dst_port_mask_i
:
in
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
rtu_drop_i
:
in
std_logic
;
rtu_prio_i
:
in
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
rtu_dst_port_mask_i
:
in
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
rtu_drop_i
:
in
std_logic
;
rtu_prio_i
:
in
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
-------------------------------------------------------------------------------
-- I/F with Multiport Memory (MPU)
-------------------------------------------------------------------------------
-- indicates the beginning of the package
mpm_pckstart_o
:
out
std_logic
;
mpm_pckstart_o
:
out
std_logic
;
-- array of pages' addresses to which ports want to write
mpm_pageaddr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
mpm_pageaddr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
mpm_pagereq_o
:
out
std_logic
;
-- indicator that the current page is about to be full (the last FB SRAM word
-- is being pumped in currently), after ~c_swc_packet_mem_multiply cycles
-- from the rising edge of this signal this page will finish
mpm_pageend_i
:
in
std_logic
;
mpm_pageend_i
:
in
std_logic
;
mpm_data_o
:
out
std_logic_vector
(
c_swc_data_width
-
1
downto
0
);
mpm_data_o
:
out
std_logic_vector
(
c_swc_data_width
-
1
downto
0
);
mpm_ctrl_o
:
out
std_logic_vector
(
c_swc_ctrl_width
-
1
downto
0
);
mpm_ctrl_o
:
out
std_logic_vector
(
c_swc_ctrl_width
-
1
downto
0
);
-- data ready - request from each port to write data to port's pump
mpm_drdy_o
:
out
std_logic
;
mpm_drdy_o
:
out
std_logic
;
-- the input register of a pump is full, this means that the pump cannot
-- be written by the port. As soon as the data which is in the input registet
-- is written to FB SRAM memory, the signal goes LOW and writing is possible
mpm_full_i
:
in
std_logic
;
mpm_full_i
:
in
std_logic
;
-- request to write the content of pump's input register to FB SRAM memory,
-- thus flash/clean input register of the pump
mpm_flush_o
:
out
std_logic
;
mpm_wr_sync_i
:
in
std_logic
;
mpm_flush_o
:
out
std_logic
;
mpm_wr_sync_i
:
in
std_logic
;
-------------------------------------------------------------------------------
-- I/F with Page Transfer Arbiter (PTA)
-------------------------------------------------------------------------------
-- indicates the beginning of the package, strobe
pta_transfer_pck_o
:
out
std_logic
;
pta_transfer_pck_o
:
out
std_logic
;
pta_transfer_ack_i
:
in
std_logic
;
-- array of pages' addresses to which ports want to write
pta_pageaddr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
pta_pageaddr_o
:
out
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
-- destination mask - indicates to which ports the packet should be
-- forwarded
pta_mask_o
:
out
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
pta_pck_size_o
:
out
std_logic_vector
(
c_swc_max_pck_size_width
-
1
downto
0
);
pta_mask_o
:
out
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
pta_pck_size_o
:
out
std_logic_vector
(
c_swc_max_pck_size_width
-
1
downto
0
);
pta_prio_o
:
out
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
)
pta_prio_o
:
out
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
)
);
end
swc_input_block
;
architecture
syn
of
swc_input_block
is
signal
fifo_data_in
:
std_logic_vector
(
c_swc_data_width
+
c_swc_ctrl_width
+
2
-
1
downto
0
);
signal
fifo_wr
:
std_logic
;
signal
fifo_clean
:
std_logic
;
signal
fifo_rd
:
std_logic
;
signal
fifo_data_out
:
std_logic_vector
(
c_swc_data_width
+
c_swc_ctrl_width
+
2
-
1
downto
0
);
signal
fifo_empty
:
std_logic
;
signal
fifo_full
:
std_logic
;
signal
fifo_usedw
:
std_logic_vector
(
5
-1
downto
0
);
signal
tx_ctrl_trans
:
std_logic_vector
(
c_swc_ctrl_width
-
1
downto
0
);
signal
transfering_pck
:
std_logic
;
signal
pta_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
pta_mask
:
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
signal
pta_prio
:
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
signal
pta_pck_size
:
std_logic_vector
(
c_swc_max_pck_size_width
-
1
downto
0
);
signal
write_ctrl_in
:
std_logic_vector
(
1
downto
0
);
signal
write_ctrl_out
:
std_logic_vector
(
1
downto
0
);
signal
write_ctrl
:
std_logic_vector
(
c_swc_ctrl_width
-
1
downto
0
);
signal
write_data
:
std_logic_vector
(
c_swc_data_width
-
1
downto
0
);
signal
read_mask
:
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
signal
read_prio
:
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
signal
read_usecnt
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
signal
write_mask
:
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
signal
write_prio
:
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
signal
write_usecnt
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
signal
pck_size
:
std_logic_vector
(
c_swc_max_pck_size_width
-
1
downto
0
);
signal
current_pckstart_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
usecnt_d0
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
type
t_read_state
is
(
S_IDLE
,
-- we wait for other processes (page fsm and
-- transfer) to be ready
S_READY_FOR_PCK
,
-- this is introduced to diminish optimization
-- (optimized design did not work) in this state,
S_WAIT_FOR_SOF
,
-- we've got RTU response, but there is no SOF
S_WAIT_FOR_RTU_RSP
,
-- we've got SOF (request from previous pck) but
-- there is no RTU valid signal (quite improbable)
S_WRITE_FIFO
,
S_WRITE_DUMMY_EOF
,
S_WAIT_FOR_TRANSFER
,
S_WAIT_FOR_CLEAN_FIFO
,
S_DROP_PCK
);
-- droping pck
type
t_page_state
is
(
S_IDLE
,
-- waiting for some work :)
S_PCKSTART_SET_USECNT
,
-- setting usecnt to a page which was allocated
-- in advance to be used for the first page of
-- the pck
-- (only in case of the initially allocated usecnt
-- is different than required)
S_INTERPCK_SET_USECNT
,
-- setting usecnt to a page which was allocated
-- in advance to be used for the page which is
-- not first
-- in the pck, this is needed, only if the page
-- was allocated during transfer of previous pck
-- but was not used in the previous pck,
-- only if usecnt of both pcks are different
S_PCKSTART_PAGE_REQ
,
-- allocating in advnace first page of the pck
S_INTERPCK_PAGE_REQ
);
-- allocating in advance page to be used by
-- all but first page of the pck
type
t_write_state
is
(
S_IDLE
,
S_START_FIFO_RD
,
S_START_MPM_WR
,
S_WRITE_MPM
,
S_LAST_MPM_WR
,
S_NEW_PCK_IN_FIFO
,
S_WAIT_WITH_TRANSFER
,
S_PERROR
);
signal
read_state
:
t_read_state
;
signal
write_state
:
t_write_state
;
signal
page_state
:
t_page_state
;
signal
mmu_force_free
:
std_logic
;
signal
start_transfer
:
std_logic
;
signal
zeros
:
std_logic_vector
(
63
downto
0
);
signal
tx_dreq
:
std_logic
;
signal
rtu_rsp_ack
:
std_logic
;
signal
pckstart_page_in_advance
:
std_logic
;
signal
pckstart_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
pckstart_page_alloc_req
:
std_logic
;
signal
pckstart_usecnt_req
:
std_logic
;
signal
pckstart_usecnt_in_advance
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
-- this is a page which used within the pck
signal
interpck_page_in_advance
:
std_logic
;
signal
interpck_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
interpck_page_alloc_req
:
std_logic
;
signal
interpck_usecnt_req
:
std_logic
;
signal
interpck_usecnt_in_advance
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
signal
mmu_force_free_addr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
need_pckstart_usecnt_set
:
std_logic
;
signal
need_interpck_usecnt_set
:
std_logic
;
signal
tmp_cnt
:
std_logic_vector
(
7
downto
0
);
signal
tx_rerror_reg
:
std_logic
;
signal
tx_rerror_or
:
std_logic
;
signal
mpm_pckstart
:
std_logic
;
signal
mpm_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
mpm_pagereq
:
std_logic
;
signal
flush_sig
:
std_logic
;
signal
flush_reg
:
std_logic
;
signal
mpm_flush
:
std_logic
;
signal
tx_rerror
:
std_logic
;
signal
fifo_populated_enough
:
std_logic
;
signal
first_pck_word
:
std_logic
;
signal
clean_pck_cnt
:
std_logic
;
signal
sof_in_fifo
:
std_logic
;
signal
eof_in_fifo
:
std_logic
;
signal
fifo_full_in_advance
:
std_logic
;
signal
drdy
:
std_logic
;
signal
flush_with_valid_data
:
std_logic
;
architecture
syn
of
swc_input_block
is
signal
fifo_data_in
:
std_logic_vector
(
c_swc_data_width
+
c_swc_ctrl_width
+
2
-
1
downto
0
);
signal
fifo_wr
:
std_logic
;
signal
fifo_clean
:
std_logic
;
signal
fifo_rd
:
std_logic
;
signal
fifo_data_out
:
std_logic_vector
(
c_swc_data_width
+
c_swc_ctrl_width
+
2
-
1
downto
0
);
signal
fifo_empty
:
std_logic
;
signal
fifo_full
:
std_logic
;
signal
fifo_usedw
:
std_logic_vector
(
5
-1
downto
0
);
signal
tx_ctrl_trans
:
std_logic_vector
(
c_swc_ctrl_width
-
1
downto
0
);
signal
transfering_pck
:
std_logic
;
signal
pta_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
pta_mask
:
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
signal
pta_prio
:
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
signal
pta_pck_size
:
std_logic_vector
(
c_swc_max_pck_size_width
-
1
downto
0
);
signal
write_ctrl_in
:
std_logic_vector
(
1
downto
0
);
signal
write_ctrl_out
:
std_logic_vector
(
1
downto
0
);
signal
write_ctrl
:
std_logic_vector
(
c_swc_ctrl_width
-
1
downto
0
);
signal
write_data
:
std_logic_vector
(
c_swc_data_width
-
1
downto
0
);
signal
read_mask
:
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
signal
read_prio
:
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
signal
read_usecnt
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
signal
write_mask
:
std_logic_vector
(
c_swc_num_ports
-
1
downto
0
);
signal
write_prio
:
std_logic_vector
(
c_swc_prio_width
-
1
downto
0
);
signal
write_usecnt
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
signal
pck_size
:
std_logic_vector
(
c_swc_max_pck_size_width
-
1
downto
0
);
signal
current_pckstart_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
usecnt_d0
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
type
t_read_state
is
(
S_IDLE
,
-- we wait for other processes (page fsm and
-- transfer) to be ready
S_READY_FOR_PCK
,
-- this is introduced to diminish optimization
-- (optimized design did not work) in this state,
S_WAIT_FOR_SOF
,
-- we've got RTU response, but there is no SOF
S_WAIT_FOR_RTU_RSP
,
-- we've got SOF (request from previous pck) but
-- there is no RTU valid signal (quite improbable)
S_WRITE_FIFO
,
S_WRITE_DUMMY_EOF
,
S_WAIT_FOR_TRANSFER
,
S_WAIT_FOR_CLEAN_FIFO
,
S_DROP_PCK
);
-- droping pck
type
t_page_state
is
(
S_IDLE
,
-- waiting for some work :)
S_PCKSTART_SET_USECNT
,
-- setting usecnt to a page which was allocated
-- in advance to be used for the first page of
-- the pck
-- (only in case of the initially allocated usecnt
-- is different than required)
S_INTERPCK_SET_USECNT
,
-- setting usecnt to a page which was allocated
-- in advance to be used for the page which is
-- not first
-- in the pck, this is needed, only if the page
-- was allocated during transfer of previous pck
-- but was not used in the previous pck,
-- only if usecnt of both pcks are different
S_PCKSTART_PAGE_REQ
,
-- allocating in advnace first page of the pck
S_INTERPCK_PAGE_REQ
);
-- allocating in advance page to be used by
-- all but first page of the pck
type
t_write_state
is
(
S_IDLE
,
S_START_FIFO_RD
,
S_START_MPM_WR
,
S_WRITE_MPM
,
S_LAST_MPM_WR
,
S_NEW_PCK_IN_FIFO
,
S_WAIT_WITH_TRANSFER
,
S_PERROR
);
signal
read_state
:
t_read_state
;
signal
write_state
:
t_write_state
;
signal
page_state
:
t_page_state
;
signal
mmu_force_free
:
std_logic
;
signal
start_transfer
:
std_logic
;
signal
zeros
:
std_logic_vector
(
63
downto
0
);
signal
tx_dreq
:
std_logic
;
signal
rtu_rsp_ack
:
std_logic
;
signal
pckstart_page_in_advance
:
std_logic
;
signal
pckstart_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
pckstart_page_alloc_req
:
std_logic
;
signal
pckstart_usecnt_req
:
std_logic
;
signal
pckstart_usecnt_in_advance
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
-- this is a page which used within the pck
signal
interpck_page_in_advance
:
std_logic
;
signal
interpck_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
interpck_page_alloc_req
:
std_logic
;
signal
interpck_usecnt_req
:
std_logic
;
signal
interpck_usecnt_in_advance
:
std_logic_vector
(
c_swc_usecount_width
-
1
downto
0
);
signal
mmu_force_free_addr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
need_pckstart_usecnt_set
:
std_logic
;
signal
need_interpck_usecnt_set
:
std_logic
;
signal
tmp_cnt
:
std_logic_vector
(
7
downto
0
);
signal
tx_rerror_reg
:
std_logic
;
signal
tx_rerror_or
:
std_logic
;
signal
mpm_pckstart
:
std_logic
;
signal
mpm_pageaddr
:
std_logic_vector
(
c_swc_page_addr_width
-
1
downto
0
);
signal
mpm_pagereq
:
std_logic
;
signal
flush_sig
:
std_logic
;
signal
flush_reg
:
std_logic
;
signal
mpm_flush
:
std_logic
;
signal
tx_rerror
:
std_logic
;
signal
fifo_populated_enough
:
std_logic
;
signal
first_pck_word
:
std_logic
;
signal
clean_pck_cnt
:
std_logic
;
signal
sof_in_fifo
:
std_logic
;
signal
eof_in_fifo
:
std_logic
;
signal
fifo_full_in_advance
:
std_logic
;
signal
drdy
:
std_logic
;
signal
flush_with_valid_data
:
std_logic
;
-------------------------------------------------------------------------------
-- Function which calculates number of 1's in a vector
-------------------------------------------------------------------------------
function
cnt
(
a
:
std_logic_vector
)
return
integer
is
variable
nmb
:
integer
range
0
to
a
'LENGTH
;
variable
ai
:
std_logic_vector
(
a
'LENGTH
-1
downto
0
);
constant
middle
:
integer
:
=
a
'
LENGTH
/
2
;
function
cnt
(
a
:
std_logic_vector
)
return
integer
is
variable
nmb
:
integer
range
0
to
a
'length
;
variable
ai
:
std_logic_vector
(
a
'length
-1
downto
0
);
constant
middle
:
integer
:
=
a
'
length
/
2
;
begin
ai
:
=
a
;
if
ai
'length
>=
2
then
if
ai
'length
>=
2
then
nmb
:
=
cnt
(
ai
(
ai
'length
-1
downto
middle
))
+
cnt
(
ai
(
middle
-1
downto
0
));
else
if
ai
(
0
)
=
'1'
then
nmb
:
=
1
;
else
nmb
:
=
0
;
if
ai
(
0
)
=
'1'
then
nmb
:
=
1
;
else
nmb
:
=
0
;
end
if
;
end
if
;
return
nmb
;
...
...
@@ -366,61 +366,61 @@ type t_read_state is (S_IDLE, -- we wait for other processes (
begin
--arch
begin
--arch
zeros
<=
(
others
=>
'0'
);
-- adding info about tx_bytesel
tx_ctrl_trans
<=
b"1111"
when
(
tx_ctrl_i
=
x"7"
and
tx_bytesel_i
=
'1'
)
else
tx_ctrl_i
;
zeros
<=
(
others
=>
'0'
);
-- adding info about tx_bytesel
tx_ctrl_trans
<=
b"1111"
when
(
tx_ctrl_i
=
x"7"
and
tx_bytesel_i
=
'1'
)
else
tx_ctrl_i
;
--==================================================================================================
-- FIFO
--==================================================================================================
fifo_data_in
(
c_swc_data_width
-
1
downto
0
)
<=
tx_data_i
;
fifo_data_in
(
c_swc_data_width
+
c_swc_ctrl_width
-
1
downto
c_swc_data_width
)
<=
tx_ctrl_trans
;
fifo_data_in
(
c_swc_data_width
+
c_swc_ctrl_width
+
1
downto
c_swc_data_width
+
c_swc_ctrl_width
)
<=
write_ctrl_in
;
write_ctrl_in
<=
b"01"
when
(
first_pck_word
=
'1'
)
else
b"10"
when
(
tx_valid_i
=
'1'
and
tx_eof_p1_i
=
'1'
)
else
b"11"
when
(
read_state
=
S_WRITE_DUMMY_EOF
)
else
b"00"
;
write_ctrl_out
<=
fifo_data_out
(
c_swc_data_width
+
c_swc_ctrl_width
+
1
downto
c_swc_data_width
+
c_swc_ctrl_width
);
write_data
<=
fifo_data_out
(
c_swc_data_width
-
1
downto
0
);
write_ctrl
<=
fifo_data_out
(
c_swc_data_width
+
c_swc_ctrl_width
-
1
downto
c_swc_data_width
)
;
fifo_wr
<=
'1'
when
(
read_state
=
S_WRITE_DUMMY_EOF
)
else
tx_valid_i
when
(
read_state
=
S_WRITE_FIFO
)
else
'0'
;
fifo_rd
<=
((
not
fifo_empty
)
and
(
not
mpm_full_i
))
when
(
write_state
=
S_WRITE_MPM
or
write_state
=
S_START_FIFO_RD
)
else
'0'
;
fifo_populated_enough
<=
'1'
when
((
fifo_usedw
>
std_logic_vector
(
to_unsigned
(
c_swc_packet_mem_multiply
,
c_swc_input_fifo_size_log2
)))
or
fifo_full
=
'1'
)
else
'0'
;
fifo_full_in_advance
<=
'1'
when
((
fifo_usedw
>
std_logic_vector
(
to_unsigned
(
c_swc_fifo_full_in_advance
,
c_swc_input_fifo_size_log2
)))
or
fifo_full
=
'1'
)
else
'0'
;
FIFO
:
generic_sync_fifo
generic
map
(
g_width
=>
c_swc_data_width
+
c_swc_ctrl_width
+
2
,
g_depth
=>
c_swc_input_fifo_size
,
g_depth_log2
=>
c_swc_input_fifo_size_log2
)
port
map
(
clk_i
=>
clk_i
,
clear_i
=>
fifo_clean
,
fifo_data_in
(
c_swc_data_width
-
1
downto
0
)
<=
tx_data_i
;
fifo_data_in
(
c_swc_data_width
+
c_swc_ctrl_width
-
1
downto
c_swc_data_width
)
<=
tx_ctrl_trans
;
fifo_data_in
(
c_swc_data_width
+
c_swc_ctrl_width
+
1
downto
c_swc_data_width
+
c_swc_ctrl_width
)
<=
write_ctrl_in
;
write_ctrl_in
<=
b"01"
when
(
first_pck_word
=
'1'
)
else
b"10"
when
(
tx_valid_i
=
'1'
and
tx_eof_p1_i
=
'1'
)
else
b"11"
when
(
read_state
=
S_WRITE_DUMMY_EOF
)
else
b"00"
;
write_ctrl_out
<=
fifo_data_out
(
c_swc_data_width
+
c_swc_ctrl_width
+
1
downto
c_swc_data_width
+
c_swc_ctrl_width
);
write_data
<=
fifo_data_out
(
c_swc_data_width
-
1
downto
0
);
write_ctrl
<=
fifo_data_out
(
c_swc_data_width
+
c_swc_ctrl_width
-
1
downto
c_swc_data_width
)
;
fifo_wr
<=
'1'
when
(
read_state
=
S_WRITE_DUMMY_EOF
)
else
tx_valid_i
when
(
read_state
=
S_WRITE_FIFO
)
else
'0'
;
fifo_rd
<=
((
not
fifo_empty
)
and
(
not
mpm_full_i
))
when
(
write_state
=
S_WRITE_MPM
or
write_state
=
S_START_FIFO_RD
)
else
'0'
;
fifo_populated_enough
<=
'1'
when
((
fifo_usedw
>
std_logic_vector
(
to_unsigned
(
c_swc_packet_mem_multiply
,
c_swc_input_fifo_size_log2
)))
or
fifo_full
=
'1'
)
else
'0'
;
fifo_full_in_advance
<=
'1'
when
((
fifo_usedw
>
std_logic_vector
(
to_unsigned
(
c_swc_fifo_full_in_advance
,
c_swc_input_fifo_size_log2
)))
or
fifo_full
=
'1'
)
else
'0'
;
FIFO
:
generic_sync_fifo
generic
map
(
g_width
=>
c_swc_data_width
+
c_swc_ctrl_width
+
2
,
g_depth
=>
c_swc_input_fifo_size
,
g_depth_log2
=>
c_swc_input_fifo_size_log2
)
port
map
(
clk_i
=>
clk_i
,
clear_i
=>
fifo_clean
,
wr_req_i
=>
fifo_wr
,
d_i
=>
fifo_data_in
,
...
...
@@ -428,110 +428,110 @@ begin --arch
rd_req_i
=>
fifo_rd
,
q_o
=>
fifo_data_out
,
empty_o
=>
fifo_empty
,
full_o
=>
fifo_full
,
usedw_o
=>
fifo_usedw
empty_o
=>
fifo_empty
,
full_o
=>
fifo_full
,
usedw_o
=>
fifo_usedw
);
--==================================================================================================
-- PCK size cnt
--==================================================================================================
-- here we calculate pck size: we increment when
-- the valid_i is HIGH
-- cleaning counter
clean_pck_cnt
<=
'1'
when
((
write_state
=
S_START_FIFO_RD
)
or
(
write_state
=
S_NEW_PCK_IN_FIFO
))
else
'0'
;
pck_size_cnt
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
pck_size
<=
(
others
=>
'0'
);
else
if
(
clean_pck_cnt
=
'1'
)
then
pck_size
<=
(
others
=>
'0'
);
elsif
(
drdy
=
'1'
)
then
pck_size
<=
std_logic_vector
(
unsigned
(
pck_size
)
+
1
);
end
if
;
end
if
;
end
if
;
end
process
;
--==================================================================================================
-- PCK transition (after pck has been received)
--==================================================================================================
-- we need to know whether there is Start of Pck or End of Pck in the FIFO in order to handle
-- errors correctly
transition_check
:
process
(
clk_i
,
rst_n_i
)
begin
--==================================================================================================
-- PCK size cnt
--==================================================================================================
-- here we calculate pck size: we increment when
-- the valid_i is HIGH
-- cleaning counter
clean_pck_cnt
<=
'1'
when
((
write_state
=
S_START_FIFO_RD
)
or
(
write_state
=
S_NEW_PCK_IN_FIFO
))
else
'0'
;
pck_size_cnt
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
pck_size
<=
(
others
=>
'0'
);
else
if
(
clean_pck_cnt
=
'1'
)
then
pck_size
<=
(
others
=>
'0'
);
elsif
(
drdy
=
'1'
)
then
pck_size
<=
std_logic_vector
(
unsigned
(
pck_size
)
+
1
);
end
if
;
end
if
;
end
if
;
end
process
;
--==================================================================================================
-- PCK transition (after pck has been received)
--==================================================================================================
-- we need to know whether there is Start of Pck or End of Pck in the FIFO in order to handle
-- errors correctly
transition_check
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--================================================
sof_in_fifo
<=
'0'
;
eof_in_fifo
<=
'0'
;
--================================================
sof_in_fifo
<=
'0'
;
eof_in_fifo
<=
'0'
;
--================================================
else
if
(
tx_sof_p1_i
=
'1'
)
then
sof_in_fifo
<=
'1'
;
sof_in_fifo
<=
'1'
;
elsif
(
write_ctrl_out
=
b"01"
or
tx_rerror
=
'1'
)
then
sof_in_fifo
<=
'0'
;
end
if
;
sof_in_fifo
<=
'0'
;
end
if
;
--if(tx_eof_p1_i = '1' or tx_rerror_p1_i = '0' ) then
if
(
tx_eof_p1_i
=
'1'
)
then
if
(
tx_eof_p1_i
=
'1'
)
then
eof_in_fifo
<=
'1'
;
elsif
(
flush_sig
=
'1'
)
then
elsif
(
flush_sig
=
'1'
)
then
eof_in_fifo
<=
'0'
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
--==================================================================================================
-- FSM to read pck from Fabric Interface (F/I <-> FIFO) and RTU response
--==================================================================================================
--
read_fsm
:
process
(
clk_i
,
rst_n_i
)
--==================================================================================================
-- FSM to read pck from Fabric Interface (F/I <-> FIFO) and RTU response
--==================================================================================================
--
read_fsm
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--================================================
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
read_state
<=
S_IDLE
;
rtu_rsp_ack
<=
'0'
;
read_mask
<=
(
others
=>
'0'
);
read_prio
<=
(
others
=>
'0'
);
read_usecnt
<=
(
others
=>
'0'
);
tx_rerror
<=
'0'
;
first_pck_word
<=
'0'
;
--================================================
tx_dreq
<=
'0'
;
rtu_rsp_ack
<=
'0'
;
read_mask
<=
(
others
=>
'0'
);
read_prio
<=
(
others
=>
'0'
);
read_usecnt
<=
(
others
=>
'0'
);
tx_rerror
<=
'0'
;
first_pck_word
<=
'0'
;
--================================================
else
-- needed for additionl info we attache to
...
...
@@ -541,224 +541,224 @@ begin --arch
elsif
(
first_pck_word
=
'1'
and
tx_valid_i
=
'1'
)
then
first_pck_word
<=
'0'
;
end
if
;
-- main finite state machine
case
read_state
is
--========================================================================================
when
S_IDLE
=>
--========================================================================================
tx_dreq
<=
'0'
;
fifo_clean
<=
'0'
;
tx_rerror
<=
'0'
;
--========================================================================================
tx_dreq
<=
'0'
;
fifo_clean
<=
'0'
;
tx_rerror
<=
'0'
;
--if(fifo_full = '0' ) then -- obvious: fifo full, no writing
if
(
fifo_full_in_advance
=
'0'
)
then
-- obvious: fifo full, no writing
-- prepared to be accepting new package
read_state
<=
S_READY_FOR_PCK
;
if
(
fifo_full_in_advance
=
'0'
)
then
-- obvious: fifo full, no writing
-- prepared to be accepting new package
read_state
<=
S_READY_FOR_PCK
;
end
if
;
--========================================================================================
when
S_READY_FOR_PCK
=>
--========================================================================================
-- [TODO: conseder change]: merge IDLE and READY_FOR_PCK
fifo_clean
<=
'0'
;
tx_dreq
<=
'0'
;
if
(
rtu_rsp_valid_i
=
'1'
and
-- we've got RTU decision
(
rtu_drop_i
=
'1'
or
-- RTU says DROP
rtu_dst_port_mask_i
=
zeros
(
c_swc_num_ports
-
1
downto
0
)))
then
-- mask = 0 means DROP !!!
-- if we've got RTU decision to drop, we don't give a damn about
-- anything else, just pretend to be receiving the msg
tx_dreq
<=
'1'
;
rtu_rsp_ack
<=
'1'
;
read_state
<=
S_DROP_PCK
;
--========================================================================================
-- [TODO: conseder change]: merge IDLE and READY_FOR_PCK
elsif
(
fifo_full
=
'0'
)
then
fifo_clean
<=
'0'
;
tx_dreq
<=
'0'
;
if
(
rtu_rsp_valid_i
=
'1'
and
tx_sof_p1_i
=
'1'
)
then
-- beutifull, everything that is needed, is there:
-- * RTU decision
-- * SOF
read_state
<=
S_WRITE_FIFO
;
tx_dreq
<=
'1'
;
rtu_rsp_ack
<=
'1'
;
-- remember
read_mask
<=
rtu_dst_port_mask_i
;
read_prio
<=
rtu_prio_i
;
read_usecnt
<=
std_logic_vector
(
to_signed
(
cnt
(
rtu_dst_port_mask_i
),
read_usecnt
'length
));
elsif
(
rtu_rsp_valid_i
=
'1'
and
tx_sof_p1_i
=
'0'
)
then
-- so we've got RTU decision, but no SOF, let's wait for SOF
-- but remember RTU RSP and ack it, so RTU is free
rtu_rsp_ack
<=
'1'
;
read_state
<=
S_WAIT_FOR_SOF
;
tx_dreq
<=
'1'
;
--- remember
read_mask
<=
rtu_dst_port_mask_i
;
read_prio
<=
rtu_prio_i
;
read_usecnt
<=
std_logic_vector
(
to_signed
(
cnt
(
rtu_dst_port_mask_i
),
read_usecnt
'length
));
elsif
(
rtu_rsp_valid_i
=
'0'
and
tx_sof_p1_i
=
'1'
)
then
-- we've got SOF because it was requested at the end of the last PCK
-- but the RTU is still processing
rtu_rsp_ack
<=
'0'
;
read_state
<=
S_WAIT_FOR_RTU_RSP
;
tx_dreq
<=
'0'
;
end
if
;
end
if
;
--========================================================================================
when
S_WAIT_FOR_SOF
=>
--========================================================================================
rtu_rsp_ack
<=
'0'
;
if
(
rtu_rsp_valid_i
=
'1'
and
-- we've got RTU decision
(
rtu_drop_i
=
'1'
or
-- RTU says DROP
rtu_dst_port_mask_i
=
zeros
(
c_swc_num_ports
-
1
downto
0
)))
then
-- mask = 0 means DROP !!!
-- if we've got RTU decision to drop, we don't give a damn about
-- anything else, just pretend to be receiving the msg
tx_dreq
<=
'1'
;
rtu_rsp_ack
<=
'1'
;
read_state
<=
S_DROP_PCK
;
if
(
tx_sof_p1_i
=
'1
'
)
then
elsif
(
fifo_full
=
'0
'
)
then
-- very nicely, everything is in place, we can go ahead
tx_dreq
<=
'1'
;
read_state
<=
S_WRITE_FIFO
;
if
(
rtu_rsp_valid_i
=
'1'
and
tx_sof_p1_i
=
'1'
)
then
-- beutifull, everything that is needed, is there:
-- * RTU decision
-- * SOF
read_state
<=
S_WRITE_FIFO
;
tx_dreq
<=
'1'
;
rtu_rsp_ack
<=
'1'
;
-- remember
read_mask
<=
rtu_dst_port_mask_i
;
read_prio
<=
rtu_prio_i
;
read_usecnt
<=
std_logic_vector
(
to_signed
(
cnt
(
rtu_dst_port_mask_i
),
read_usecnt
'length
));
elsif
(
rtu_rsp_valid_i
=
'1'
and
tx_sof_p1_i
=
'0'
)
then
-- so we've got RTU decision, but no SOF, let's wait for SOF
-- but remember RTU RSP and ack it, so RTU is free
rtu_rsp_ack
<=
'1'
;
read_state
<=
S_WAIT_FOR_SOF
;
tx_dreq
<=
'1'
;
--- remember
read_mask
<=
rtu_dst_port_mask_i
;
read_prio
<=
rtu_prio_i
;
read_usecnt
<=
std_logic_vector
(
to_signed
(
cnt
(
rtu_dst_port_mask_i
),
read_usecnt
'length
));
elsif
(
rtu_rsp_valid_i
=
'0'
and
tx_sof_p1_i
=
'1'
)
then
-- we've got SOF because it was requested at the end of the last PCK
-- but the RTU is still processing
rtu_rsp_ack
<=
'0'
;
read_state
<=
S_WAIT_FOR_RTU_RSP
;
tx_dreq
<=
'0'
;
end
if
;
end
if
;
--========================================================================================
when
S_WAIT_FOR_SOF
=>
--========================================================================================
rtu_rsp_ack
<=
'0'
;
if
(
tx_sof_p1_i
=
'1'
)
then
-- very nicely, everything is in place, we can go ahead
tx_dreq
<=
'1'
;
read_state
<=
S_WRITE_FIFO
;
end
if
;
--========================================================================================
when
S_WAIT_FOR_RTU_RSP
=>
--========================================================================================
if
(
tx_rerror_p1_i
=
'1'
)
then
when
S_WAIT_FOR_RTU_RSP
=>
--========================================================================================
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
if
(
tx_rerror_p1_i
=
'1'
)
then
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
elsif
(
rtu_rsp_valid_i
=
'1'
)
then
tx_dreq
<=
'1'
;
rtu_rsp_ack
<=
'1'
;
if
(
rtu_drop_i
=
'1'
or
-- RTU says DROP
rtu_dst_port_mask_i
=
zeros
(
c_swc_num_ports
-
1
downto
0
)
-- mask = 0 means DROP !!!
)
then
if
(
rtu_drop_i
=
'1'
or
-- RTU says DROP
rtu_dst_port_mask_i
=
zeros
(
c_swc_num_ports
-
1
downto
0
)
-- mask = 0 means DROP !!!
)
then
read_state
<=
S_DROP_PCK
;
read_state
<=
S_DROP_PCK
;
else
read_state
<=
S_WRITE_FIFO
;
read_state
<=
S_WRITE_FIFO
;
--remember
read_mask
<=
rtu_dst_port_mask_i
;
read_prio
<=
rtu_prio_i
;
read_usecnt
<=
std_logic_vector
(
to_signed
(
cnt
(
rtu_dst_port_mask_i
),
read_usecnt
'length
));
read_usecnt
<=
std_logic_vector
(
to_signed
(
cnt
(
rtu_dst_port_mask_i
),
read_usecnt
'length
));
end
if
;
end
if
;
--========================================================================================
when
S_WRITE_FIFO
=>
--========================================================================================
--========================================================================================
if
(
tx_rerror_p1_i
=
'1'
)
then
--if(sof_in_fifo = '1') then
if
(
eof_in_fifo
=
'1'
and
sof_in_fifo
=
'1'
)
then
-- StartOfFrame and EndOfFrame are in the fifo, his means that the error refers to
-- the second pck which is in the FIFO, we have to wait for teh first PCK to be
-- written to MPM and than just clean the second pck from the fifo
read_state
<=
S_WAIT_FOR_CLEAN_FIFO
;
tx_dreq
<=
'0'
;
read_state
<=
S_WAIT_FOR_CLEAN_FIFO
;
tx_dreq
<=
'0'
;
else
-- there is only one pck in the fifo, just stap reception and indicate to
-- Error FSM (tx_rerror) that there is job for it to do, clean what is in
-- the FIFO
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
fifo_clean
<=
'1'
;
tx_rerror
<=
'1'
;
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
fifo_clean
<=
'1'
;
tx_rerror
<=
'1'
;
end
if
;
elsif
(
tx_valid_i
=
'1'
and
tx_eof_p1_i
=
'1'
)
then
elsif
(
tx_valid_i
=
'1'
and
tx_eof_p1_i
=
'1'
)
then
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
elsif
(
tx_valid_i
=
'0'
and
tx_eof_p1_i
=
'1'
)
then
read_state
<=
S_WRITE_DUMMY_EOF
;
tx_dreq
<=
'0'
;
else
-- if the fifo usecnt > (max - 3), this enables us to stop
-- Fabric Interface just in time for the FIFO to be full
if
(
fifo_full_in_advance
=
'1'
)
then
tx_dreq
<=
'0'
;
else
tx_dreq
<=
'1'
;
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
elsif
(
tx_valid_i
=
'0'
and
tx_eof_p1_i
=
'1'
)
then
end
if
;
read_state
<=
S_WRITE_DUMMY_EOF
;
tx_dreq
<=
'0'
;
else
-- if the fifo usecnt > (max - 3), this enables us to stop
-- Fabric Interface just in time for the FIFO to be full
if
(
fifo_full_in_advance
=
'1'
)
then
tx_dreq
<=
'0'
;
else
tx_dreq
<=
'1'
;
end
if
;
end
if
;
end
if
;
--========================================================================================
when
S_WAIT_FOR_CLEAN_FIFO
=>
--========================================================================================
when
S_WAIT_FOR_CLEAN_FIFO
=>
--========================================================================================
if
(
eof_in_fifo
=
'0'
)
then
-- the valid pck transfered
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
fifo_clean
<=
'1'
;
tx_rerror
<=
'1'
;
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
fifo_clean
<=
'1'
;
tx_rerror
<=
'1'
;
end
if
;
--========================================================================================
when
S_WRITE_DUMMY_EOF
=>
--========================================================================================
read_state
<=
S_IDLE
;
--========================================================================================
read_state
<=
S_IDLE
;
--========================================================================================
when
S_DROP_PCK
=>
--========================================================================================
rtu_rsp_ack
<=
'0'
;
if
(
tx_eof_p1_i
=
'1'
or
tx_rerror_p1_i
=
'1'
)
then
when
S_DROP_PCK
=>
--========================================================================================
rtu_rsp_ack
<=
'0'
;
if
(
tx_eof_p1_i
=
'1'
or
tx_rerror_p1_i
=
'1'
)
then
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
end
if
;
--========================================================================================
when
others
=>
--========================================================================================
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
--========================================================================================
--========================================================================================
--========================================================================================
read_state
<=
S_IDLE
;
tx_dreq
<=
'0'
;
--========================================================================================
--========================================================================================
end
case
;
...
...
@@ -766,36 +766,36 @@ begin --arch
end
if
;
end
process
;
--==================================================================================================
-- FSM to write pck to Multiport memory write pump (FIFO -> MPM)
--==================================================================================================
--
write_fsm
:
process
(
clk_i
,
rst_n_i
)
--==================================================================================================
-- FSM to write pck to Multiport memory write pump (FIFO -> MPM)
--==================================================================================================
--
write_fsm
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--================================================
write_state
<=
S_IDLE
;
start_transfer
<=
'0'
;
mpm_pckstart
<=
'0'
;
mpm_pagereq
<=
'0'
;
current_pckstart_pageaddr
<=
(
others
=>
'1'
);
write_mask
<=
(
others
=>
'0'
);
write_prio
<=
(
others
=>
'0'
);
write_usecnt
<=
(
others
=>
'0'
);
mpm_pckstart
<=
'0'
;
mpm_pageaddr
<=
(
others
=>
'1'
);
mpm_pagereq
<=
'0'
;
flush_reg
<=
'0'
;
mmu_force_free_addr
<=
(
others
=>
'0'
);
mmu_force_free
<=
'0'
;
--================================================
write_state
<=
S_IDLE
;
start_transfer
<=
'0'
;
mpm_pckstart
<=
'0'
;
mpm_pagereq
<=
'0'
;
current_pckstart_pageaddr
<=
(
others
=>
'1'
);
write_mask
<=
(
others
=>
'0'
);
write_prio
<=
(
others
=>
'0'
);
write_usecnt
<=
(
others
=>
'0'
);
mpm_pckstart
<=
'0'
;
mpm_pageaddr
<=
(
others
=>
'1'
);
mpm_pagereq
<=
'0'
;
flush_reg
<=
'0'
;
mmu_force_free_addr
<=
(
others
=>
'0'
);
mmu_force_free
<=
'0'
;
--================================================
else
-- main finite state machine
...
...
@@ -803,152 +803,152 @@ begin --arch
--========================================================================================
when
S_IDLE
=>
--========================================================================================
start_transfer
<=
'0'
;
flush_reg
<=
'0'
;
start_transfer
<=
'0'
;
mpm_pagereq
<=
'0'
;
--========================================================================================
start_transfer
<=
'0'
;
flush_reg
<=
'0'
;
start_transfer
<=
'0'
;
mpm_pagereq
<=
'0'
;
if
((
fifo_populated_enough
=
'1'
)
and
-- at least on "c_swc_packet_mem_multiply"
(
pckstart_page_in_advance
=
'1'
)
and
-- needed to write first page
mpm_full_i
=
'0'
)
then
-- obvious, no write to full MPM
write_state
<=
S_START_FIFO_RD
;
if
((
fifo_populated_enough
=
'1'
)
and
-- at least on "c_swc_packet_mem_multiply"
(
pckstart_page_in_advance
=
'1'
)
and
-- needed to write first page
mpm_full_i
=
'0'
)
then
-- obvious, no write to full MPM
write_state
<=
S_START_FIFO_RD
;
end
if
;
--========================================================================================
when
S_START_FIFO_RD
=>
--========================================================================================
--========================================================================================
-- here is a small trick, we already request data from FIFO with fifo_rd HIHG
-- but the drdy (which is the same signal as fifo_rd) is not HIGH here because
-- drdy is restricted only to S_WRITE_MPM !!! thanx to this trick we can have things
-- simple
write_state
<=
S_WRITE_MPM
;
-- first word of the pck, need to be remembered (for i.e. transfer, force free)
current_pckstart_pageaddr
<=
pckstart_pageaddr
;
write_mask
<=
read_mask
;
write_prio
<=
read_prio
;
write_usecnt
<=
read_usecnt
;
write_state
<=
S_WRITE_MPM
;
-- first word of the pck, need to be remembered (for i.e. transfer, force free)
current_pckstart_pageaddr
<=
pckstart_pageaddr
;
write_mask
<=
read_mask
;
write_prio
<=
read_prio
;
write_usecnt
<=
read_usecnt
;
-- indicate this is the first pck, set page
mpm_pckstart
<=
'1'
;
mpm_pagereq
<=
'1'
;
mpm_pageaddr
<=
pckstart_pageaddr
;
mpm_pckstart
<=
'1'
;
mpm_pagereq
<=
'1'
;
mpm_pageaddr
<=
pckstart_pageaddr
;
--========================================================================================
when
S_WRITE_MPM
=>
--========================================================================================
mpm_pckstart
<=
'0'
;
mpm_pagereq
<=
'0'
;
------------------------------------------------------------------------------------------
if
(
tx_rerror
=
'1'
)
then
-- handling error, this signal is generated by read_fsm
------------------------------------------------------------------------------------------
flush_reg
<=
'1'
;
write_state
<=
S_PERROR
;
mmu_force_free_addr
<=
current_pckstart_pageaddr
;
mmu_force_free
<=
'1'
;
------------------------------------------------------------------------------------------
elsif
(
write_ctrl_out
/=
b"01"
and
-- the data coming from FIFO indicates its not first
-- word of PCK
mpm_pckstart
=
'1'
)
then
-- we are saying to MPM it's first word of PCK
------------------------------------------------------------------------------------------
-- this is pathologic situation, bad, not sure what to do
assert
false
report
"write_fsm: S_WRITE_MPM, should not go here"
;
write_state
<=
S_START_FIFO_RD
;
------------------------------------------------------------------------------------------
else
-- in normal case, we end up here
------------------------------------------------------------------------------------------
--========================================================================================
if
(
mpm_pagereq
=
'0'
and
-- not setting yet new page
mpm_pageend_i
=
'1'
and
-- detecting info from MPM: new page needed
interpck_page_in_advance
=
'1'
)
then
-- we have a spare page allocated
mpm_pageaddr
<=
interpck_pageaddr
;
mpm_pagereq
<=
'1'
;
else
mpm_pckstart
<=
'0'
;
mpm_pagereq
<=
'0'
;
------------------------------------------------------------------------------------------
if
(
tx_rerror
=
'1'
)
then
-- handling error, this signal is generated by read_fsm
------------------------------------------------------------------------------------------
flush_reg
<=
'1'
;
write_state
<=
S_PERROR
;
mmu_force_free_addr
<=
current_pckstart_pageaddr
;
mmu_force_free
<=
'1'
;
------------------------------------------------------------------------------------------
elsif
(
write_ctrl_out
/=
b"01"
and
-- the data coming from FIFO indicates its not first
-- word of PCK
mpm_pckstart
=
'1'
)
then
-- we are saying to MPM it's first word of PCK
------------------------------------------------------------------------------------------
mpm_pageaddr
<=
(
others
=>
'1'
);
mpm_pagereq
<=
'0'
;
end
if
;
if
(
write_ctrl_out
=
b"11"
or
-- EOF with valid data
write_ctrl_out
=
b"10"
)
then
-- EOF without valid data
write_state
<=
S_LAST_MPM_WR
;
-- this is pathologic situation, bad, not sure what to do
assert
false
report
"write_fsm: S_WRITE_MPM, should not go here"
;
write_state
<=
S_START_FIFO_RD
;
------------------------------------------------------------------------------------------
else
-- in normal case, we end up here
------------------------------------------------------------------------------------------
if
(
mpm_pagereq
=
'0'
and
-- not setting yet new page
mpm_pageend_i
=
'1'
and
-- detecting info from MPM: new page needed
interpck_page_in_advance
=
'1'
)
then
-- we have a spare page allocated
mpm_pageaddr
<=
interpck_pageaddr
;
mpm_pagereq
<=
'1'
;
else
mpm_pageaddr
<=
(
others
=>
'1'
);
mpm_pagereq
<=
'0'
;
end
if
;
if
(
write_ctrl_out
=
b"11"
or
-- EOF with valid data
write_ctrl_out
=
b"10"
)
then
-- EOF without valid data
write_state
<=
S_LAST_MPM_WR
;
end
if
;
------------------------------------------------------------------------------------------
end
if
;
------------------------------------------------------------------------------------------
end
if
;
--===========================================================================================
when
S_LAST_MPM_WR
=>
--===========================================================================================
start_transfer
<=
'0'
;
flush_reg
<=
'0'
;
mpm_pageaddr
<=
(
others
=>
'1'
);
mpm_pagereq
<=
'0'
;
-- if another page needs to be allocated for the last chunck
-- of date, transfer only if we have spare page for that.
-- otherwise, we can end up reading pck without last piece of data !!!!
--===========================================================================================
when
S_LAST_MPM_WR
=>
--===========================================================================================
start_transfer
<=
'0'
;
flush_reg
<=
'0'
;
mpm_pageaddr
<=
(
others
=>
'1'
);
mpm_pagereq
<=
'0'
;
-- if another page needs to be allocated for the last chunck
-- of date, transfer only if we have spare page for that.
-- otherwise, we can end up reading pck without last piece of data !!!!
-- if(interpck_page_in_advance = '0' and -- no spare page
if
(
mpm_pageend_i
=
'1'
)
then
-- new page needed to write last chucnk of data
write_state
<=
S_WAIT_WITH_TRANSFER
;
else
start_transfer
<=
'1'
;
if
(
write_ctrl_out
=
b"01"
)
then
write_state
<=
S_NEW_PCK_IN_FIFO
;
if
(
mpm_pageend_i
=
'1'
)
then
-- new page needed to write last chucnk of data
write_state
<=
S_WAIT_WITH_TRANSFER
;
else
write_state
<=
S_IDLE
;
start_transfer
<=
'1'
;
if
(
write_ctrl_out
=
b"01"
)
then
write_state
<=
S_NEW_PCK_IN_FIFO
;
else
write_state
<=
S_IDLE
;
end
if
;
end
if
;
end
if
;
--===========================================================================================
when
S_WAIT_WITH_TRANSFER
=>
--===========================================================================================
-- we need to be sure that the last chunk of data is written to MPM before it's read
-- on the other side, if the MPM is full, allocating new page may take looooong time
-- so we transfer only if there is page prepared
-- Of course, this is the case only if the pck finished while pgend request HIGH
if
(
interpck_page_in_advance
=
'1'
)
then
start_transfer
<=
'1'
;
mpm_pageaddr
<=
interpck_pageaddr
;
mpm_pagereq
<=
'1'
;
--===========================================================================================
when
S_WAIT_WITH_TRANSFER
=>
--===========================================================================================
-- we need to be sure that the last chunk of data is written to MPM before it's read
-- on the other side, if the MPM is full, allocating new page may take looooong time
-- so we transfer only if there is page prepared
-- Of course, this is the case only if the pck finished while pgend request HIGH
if
(
write_ctrl_out
=
b"01"
)
then
write_state
<=
S_NEW_PCK_IN_FIFO
;
else
write_state
<=
S_IDLE
;
if
(
interpck_page_in_advance
=
'1'
)
then
start_transfer
<=
'1'
;
mpm_pageaddr
<=
interpck_pageaddr
;
mpm_pagereq
<=
'1'
;
if
(
write_ctrl_out
=
b"01"
)
then
write_state
<=
S_NEW_PCK_IN_FIFO
;
else
write_state
<=
S_IDLE
;
end
if
;
end
if
;
end
if
;
--===========================================================================================
when
S_NEW_PCK_IN_FIFO
=>
--===========================================================================================
start_transfer
<=
'0'
;
mpm_pagereq
<=
'0'
;
-- i'm not usre here
--===========================================================================================
when
S_NEW_PCK_IN_FIFO
=>
--===========================================================================================
start_transfer
<=
'0'
;
mpm_pagereq
<=
'0'
;
-- i'm not usre here
-- if(mpm_pagereq = '0' and -- not setting yet new page
-- mpm_pageend_i = '1' and -- detecting info from MPM: new page needed
-- interpck_page_in_advance = '1') then -- we have a spare page allocated
...
...
@@ -962,320 +962,320 @@ begin --arch
-- mpm_pagereq <= '0';
--
-- end if;
if
((
fifo_populated_enough
=
'1'
)
and
-- at least on "c_swc_packet_mem_multiply"
(
pckstart_page_in_advance
=
'1'
)
and
-- needed to write first page
mpm_full_i
=
'0'
)
then
-- obvious, no write to full MPM
-- first word of the pck
current_pckstart_pageaddr
<=
pckstart_pageaddr
;
write_mask
<=
read_mask
;
write_prio
<=
read_prio
;
write_usecnt
<=
read_usecnt
;
mpm_pckstart
<=
'1'
;
mpm_pagereq
<=
'1'
;
mpm_pageaddr
<=
pckstart_pageaddr
;
write_state
<=
S_WRITE_MPM
;
end
if
;
--===========================================================================================
when
S_PERROR
=>
--===========================================================================================
flush_reg
<=
'0'
;
if
(
mmu_force_free_done_i
=
'1'
)
then
mmu_force_free
<=
'0'
;
write_state
<=
S_IDLE
;
end
if
;
--===========================================================================================
when
others
=>
--===========================================================================================
write_state
<=
S_IDLE
;
start_transfer
<=
'0'
;
mpm_pckstart
<=
'0'
;
mpm_pagereq
<=
'0'
;
--===========================================================================================
end
case
;
--===========================================================================================
if
((
fifo_populated_enough
=
'1'
)
and
-- at least on "c_swc_packet_mem_multiply"
(
pckstart_page_in_advance
=
'1'
)
and
-- needed to write first page
mpm_full_i
=
'0'
)
then
-- obvious, no write to full MPM
-- first word of the pck
current_pckstart_pageaddr
<=
pckstart_pageaddr
;
write_mask
<=
read_mask
;
write_prio
<=
read_prio
;
write_usecnt
<=
read_usecnt
;
mpm_pckstart
<=
'1'
;
mpm_pagereq
<=
'1'
;
mpm_pageaddr
<=
pckstart_pageaddr
;
write_state
<=
S_WRITE_MPM
;
end
if
;
--===========================================================================================
when
S_PERROR
=>
--===========================================================================================
flush_reg
<=
'0'
;
if
(
mmu_force_free_done_i
=
'1'
)
then
mmu_force_free
<=
'0'
;
write_state
<=
S_IDLE
;
end
if
;
--===========================================================================================
when
others
=>
--===========================================================================================
write_state
<=
S_IDLE
;
start_transfer
<=
'0'
;
mpm_pckstart
<=
'0'
;
mpm_pagereq
<=
'0'
;
--===========================================================================================
end
case
;
--===========================================================================================
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
--==================================================================================================
-- FSM to allocate pages in advance and set USECNT of pages allocated in advance
--==================================================================================================
-- Auxiliary Finite State Machine which talks with
-- Memory Management Unit, it controls:
-- * page allocation
-- * usecnt setting
fsm_page
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--========================================
page_state
<=
S_IDLE
;
interpck_pageaddr
<=
(
others
=>
'0'
);
interpck_page_alloc_req
<=
'0'
;
interpck_usecnt_in_advance
<=
(
others
=>
'0'
);
interpck_usecnt_req
<=
'0'
;
pckstart_pageaddr
<=
(
others
=>
'0'
);
pckstart_page_alloc_req
<=
'0'
;
pckstart_usecnt_req
<=
'0'
;
pckstart_usecnt_in_advance
<=
(
others
=>
'0'
);
--========================================
else
-- main finite state machine
case
page_state
is
--===========================================================================================
when
S_IDLE
=>
--===========================================================================================
interpck_page_alloc_req
<=
'0'
;
interpck_usecnt_req
<=
'0'
;
pckstart_page_alloc_req
<=
'0'
;
pckstart_usecnt_req
<=
'0'
;
if
((
need_pckstart_usecnt_set
=
'1'
and
need_interpck_usecnt_set
=
'1'
)
or
(
need_pckstart_usecnt_set
=
'1'
and
need_interpck_usecnt_set
=
'0'
)
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
end
process
;
--==================================================================================================
-- FSM to allocate pages in advance and set USECNT of pages allocated in advance
--==================================================================================================
-- Auxiliary Finite State Machine which talks with
-- Memory Management Unit, it controls:
-- * page allocation
-- * usecnt setting
fsm_page
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--========================================
page_state
<=
S_IDLE
;
interpck_pageaddr
<=
(
others
=>
'0'
);
interpck_page_alloc_req
<=
'0'
;
interpck_usecnt_in_advance
<=
(
others
=>
'0'
);
interpck_usecnt_req
<=
'0'
;
pckstart_pageaddr
<=
(
others
=>
'0'
);
pckstart_page_alloc_req
<=
'0'
;
pckstart_usecnt_req
<=
'0'
;
pckstart_usecnt_in_advance
<=
(
others
=>
'0'
);
--========================================
else
-- main finite state machine
case
page_state
is
--===========================================================================================
when
S_IDLE
=>
--===========================================================================================
interpck_page_alloc_req
<=
'0'
;
interpck_usecnt_req
<=
'0'
;
pckstart_page_alloc_req
<=
'0'
;
pckstart_usecnt_req
<=
'0'
;
elsif
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
interpck_page_in_advance
=
'0'
)
then
interpck_page_alloc_req
<=
'1'
;
page_state
<=
S_INTERPCK_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
end
if
;
--===========================================================================================
when
S_PCKSTART_SET_USECNT
=>
--===========================================================================================
if
(
mmu_set_usecnt_done_i
=
'1'
)
then
pckstart_usecnt_req
<=
'0'
;
-- remember the count of allocated page
-- this is becuase, we will use it for different
-- pck with probably different uscnt
pckstart_usecnt_in_advance
<=
usecnt_d0
;
if
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
interpck_page_in_advance
=
'0'
)
then
interpck_page_alloc_req
<=
'1'
;
page_state
<=
S_INTERPCK_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
S_INTERPCK_SET_USECNT
=>
--===========================================================================================
if
((
need_pckstart_usecnt_set
=
'1'
and
need_interpck_usecnt_set
=
'1'
)
or
(
need_pckstart_usecnt_set
=
'1'
and
need_interpck_usecnt_set
=
'0'
))
then
if
(
mmu_set_usecnt_done_i
=
'1'
)
then
interpck_usecnt_req
<=
'0'
;
-- remember the count of allocated page
-- this is becuase, we will use it for different
-- pck with probably different uscnt
-- we do it here as well, because it's possible
-- that this page is not used by the pck
-- which set the USECNT
interpck_usecnt_in_advance
<=
usecnt_d0
;
if
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
need_pckstart_usecnt_set
=
'0'
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
S_PCKSTART_PAGE_REQ
=>
--===========================================================================================
if
(
mmu_page_alloc_done_i
=
'1'
)
then
pckstart_page_alloc_req
<=
'0'
;
-- remember the page start addr
pckstart_pageaddr
<=
mmu_pageaddr_i
;
pckstart_usecnt_in_advance
<=
usecnt_d0
;
if
(
need_pckstart_usecnt_set
=
'1'
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
elsif
(
interpck_page_in_advance
=
'0'
)
then
interpck_page_alloc_req
<=
'1'
;
page_state
<=
S_INTERPCK_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
elsif
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
interpck_page_in_advance
=
'0'
)
then
interpck_page_alloc_req
<=
'1'
;
page_state
<=
S_INTERPCK_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
end
if
;
--===========================================================================================
when
S_PCKSTART_SET_USECNT
=>
--===========================================================================================
if
(
mmu_set_usecnt_done_i
=
'1'
)
then
pckstart_usecnt_req
<=
'0'
;
-- remember the count of allocated page
-- this is becuase, we will use it for different
-- pck with probably different uscnt
pckstart_usecnt_in_advance
<=
usecnt_d0
;
if
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
interpck_page_in_advance
=
'0'
)
then
interpck_page_alloc_req
<=
'1'
;
page_state
<=
S_INTERPCK_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
S_INTERPCK_SET_USECNT
=>
--===========================================================================================
if
(
mmu_set_usecnt_done_i
=
'1'
)
then
interpck_usecnt_req
<=
'0'
;
-- remember the count of allocated page
-- this is becuase, we will use it for different
-- pck with probably different uscnt
-- we do it here as well, because it's possible
-- that this page is not used by the pck
-- which set the USECNT
interpck_usecnt_in_advance
<=
usecnt_d0
;
if
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
need_pckstart_usecnt_set
=
'0'
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
S_PCKSTART_PAGE_REQ
=>
--===========================================================================================
if
(
mmu_page_alloc_done_i
=
'1'
)
then
pckstart_page_alloc_req
<=
'0'
;
-- remember the page start addr
pckstart_pageaddr
<=
mmu_pageaddr_i
;
pckstart_usecnt_in_advance
<=
usecnt_d0
;
if
(
need_pckstart_usecnt_set
=
'1'
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
elsif
(
interpck_page_in_advance
=
'0'
)
then
interpck_page_alloc_req
<=
'1'
;
page_state
<=
S_INTERPCK_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
S_INTERPCK_PAGE_REQ
=>
--===========================================================================================
page_state
<=
S_IDLE
;
end
if
;
end
if
;
if
(
mmu_page_alloc_done_i
=
'1'
)
then
interpck_page_alloc_req
<=
'0'
;
interpck_pageaddr
<=
mmu_pageaddr_i
;
--remember the usecnt which was at the time of
-- page allocation, this is in case that the page
-- is used to store another pck then the current one.
-- therefore we compare this stored value with the
-- current usecnt
interpck_usecnt_in_advance
<=
usecnt_d0
;
interpck_page_alloc_req
<=
'0'
;
if
(
need_pckstart_usecnt_set
=
'1'
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
--===========================================================================================
when
S_INTERPCK_PAGE_REQ
=>
--===========================================================================================
elsif
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
others
=>
--===========================================================================================
page_state
<=
S_IDLE
;
if
(
mmu_page_alloc_done_i
=
'1'
)
then
end
case
;
usecnt_d0
<=
write_usecnt
;
end
if
;
end
if
;
interpck_page_alloc_req
<=
'0'
;
interpck_pageaddr
<=
mmu_pageaddr_i
;
--remember the usecnt which was at the time of
-- page allocation, this is in case that the page
-- is used to store another pck then the current one.
-- therefore we compare this stored value with the
-- current usecnt
interpck_usecnt_in_advance
<=
usecnt_d0
;
interpck_page_alloc_req
<=
'0'
;
if
(
need_pckstart_usecnt_set
=
'1'
)
then
page_state
<=
S_PCKSTART_SET_USECNT
;
pckstart_usecnt_req
<=
'1'
;
elsif
(
pckstart_page_in_advance
=
'0'
)
then
pckstart_page_alloc_req
<=
'1'
;
page_state
<=
S_PCKSTART_PAGE_REQ
;
elsif
(
need_interpck_usecnt_set
=
'1'
)
then
page_state
<=
S_INTERPCK_SET_USECNT
;
interpck_usecnt_req
<=
'1'
;
else
page_state
<=
S_IDLE
;
end
if
;
end
if
;
--===========================================================================================
when
others
=>
--===========================================================================================
page_state
<=
S_IDLE
;
end
case
;
usecnt_d0
<=
write_usecnt
;
end
if
;
end
if
;
end
process
;
end
process
;
--================================================================================================
-- this proces controls Package Transfer Arbiter
--================================================================================================
pta_if
:
process
(
clk_i
,
rst_n_i
)
pta_if
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--===================================================
transfering_pck
<=
'0'
;
pta_pageaddr
<=
(
others
=>
'0'
);
pta_mask
<=
(
others
=>
'0'
);
pta_prio
<=
(
others
=>
'0'
);
pta_pck_size
<=
(
others
=>
'0'
);
--===================================================
transfering_pck
<=
'0'
;
pta_pageaddr
<=
(
others
=>
'0'
);
pta_mask
<=
(
others
=>
'0'
);
pta_prio
<=
(
others
=>
'0'
);
pta_pck_size
<=
(
others
=>
'0'
);
--===================================================
else
if
(
start_transfer
=
'1'
)
then
if
(
start_transfer
=
'1'
)
then
-- normal case, transfer arbiter free
transfering_pck
<=
'1'
;
pta_pageaddr
<=
current_pckstart_pageaddr
;
pta_mask
<=
write_mask
;
pta_prio
<=
write_prio
;
pta_pck_size
<=
pck_size
;
pta_pck_size
<=
std_logic_vector
(
unsigned
(
pck_size
)
-
1
);
pta_pageaddr
<=
current_pckstart_pageaddr
;
pta_mask
<=
write_mask
;
pta_prio
<=
write_prio
;
pta_pck_size
<=
pck_size
;
pta_pck_size
<=
std_logic_vector
(
unsigned
(
pck_size
)
-
1
);
elsif
(
pta_transfer_ack_i
=
'1'
and
transfering_pck
=
'1'
)
then
--transfer finished
transfering_pck
<=
'0'
;
pta_pageaddr
<=
(
others
=>
'0'
);
pta_mask
<=
(
others
=>
'0'
);
pta_prio
<=
(
others
=>
'0'
);
pta_pck_size
<=
(
others
=>
'0'
);
transfering_pck
<=
'0'
;
pta_pageaddr
<=
(
others
=>
'0'
);
pta_mask
<=
(
others
=>
'0'
);
pta_prio
<=
(
others
=>
'0'
);
pta_pck_size
<=
(
others
=>
'0'
);
end
if
;
...
...
@@ -1286,99 +1286,101 @@ end process;
--================================================================================================
-- for page allocation
--================================================================================================
page_if
:
process
(
clk_i
,
rst_n_i
)
page_if
:
process
(
clk_i
,
rst_n_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
--===================================================
pckstart_page_in_advance
<=
'0'
;
interpck_page_in_advance
<=
'0'
;
need_pckstart_usecnt_set
<=
'0'
;
need_interpck_usecnt_set
<=
'0'
;
--===================================================
pckstart_page_in_advance
<=
'0'
;
interpck_page_in_advance
<=
'0'
;
need_pckstart_usecnt_set
<=
'0'
;
need_interpck_usecnt_set
<=
'0'
;
--===================================================
else
if
(
mpm_pckstart
=
'1'
)
then
else
if
(
mpm_pckstart
=
'1'
)
then
if
(
read_usecnt
=
pckstart_usecnt_in_advance
)
then
need_pckstart_usecnt_set
<=
'0'
;
pckstart_page_in_advance
<=
'0'
;
need_pckstart_usecnt_set
<=
'0'
;
pckstart_page_in_advance
<=
'0'
;
else
need_pckstart_usecnt_set
<=
'1'
;
need_pckstart_usecnt_set
<=
'1'
;
end
if
;
if
(
read_usecnt
=
interpck_usecnt_in_advance
)
then
need_interpck_usecnt_set
<=
'0'
;
if
(
read_usecnt
=
interpck_usecnt_in_advance
)
then
need_interpck_usecnt_set
<=
'0'
;
else
need_interpck_usecnt_set
<=
'1'
;
need_interpck_usecnt_set
<=
'1'
;
end
if
;
elsif
(
page_state
=
S_INTERPCK_SET_USECNT
and
mmu_set_usecnt_done_i
=
'1'
)
then
need_interpck_usecnt_set
<=
'0'
;
need_interpck_usecnt_set
<=
'0'
;
elsif
(
page_state
=
S_PCKSTART_SET_USECNT
and
mmu_set_usecnt_done_i
=
'1'
)
then
need_pckstart_usecnt_set
<=
'0'
;
need_pckstart_usecnt_set
<=
'0'
;
end
if
;
--if(write_state = S_SET_NEXT_PAGE or write_state = S_SET_LAST_NEXT_PAGE) then
if
(
mpm_pagereq
=
'1'
and
mpm_pckstart
=
'0'
)
then
if
(
mpm_pagereq
=
'1'
and
mpm_pckstart
=
'0'
)
then
interpck_page_in_advance
<=
'0'
;
elsif
(
mmu_page_alloc_done_i
=
'1'
and
interpck_page_alloc_req
=
'1'
)
then
interpck_page_in_advance
<=
'1'
;
end
if
;
if
(
mmu_set_usecnt_done_i
=
'1'
and
page_state
=
S_PCKSTART_SET_USECNT
)
then
if
(
mmu_set_usecnt_done_i
=
'1'
and
page_state
=
S_PCKSTART_SET_USECNT
)
then
pckstart_page_in_advance
<=
'0'
;
elsif
(
mmu_page_alloc_done_i
=
'1'
and
pckstart_page_alloc_req
=
'1'
)
then
pckstart_page_in_advance
<=
'1'
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
--================================================================================================
-- Output signals
--================================================================================================
tx_dreq_o
<=
'0'
when
(
read_state
=
S_IDLE
)
else
'1'
when
(
read_state
=
S_DROP_PCK
)
else
tx_dreq
;
flush_with_valid_data
<=
'1'
when
(
write_ctrl_out
=
b"10"
)
else
'0'
;
drdy
<=
((
not
(
fifo_empty
and
(
not
flush_with_valid_data
)))
and
(
not
mpm_full_i
))
when
(
write_state
=
S_WRITE_MPM
)
else
'0'
;
tx_dreq_o
<=
'0'
when
tx_eof_p1_i
=
'1'
else
'0'
when
(
read_state
=
S_IDLE
)
else
'1'
when
(
read_state
=
S_DROP_PCK
)
else
tx_dreq
;
flush_sig
<=
(
write_ctrl_out
(
1
))
when
(
write_state
=
S_WRITE_MPM
)
else
'0'
;
mpm_flush
<=
flush_reg
or
flush_sig
;
rtu_rsp_ack_o
<=
rtu_rsp_ack
;
mmu_force_free_addr_o
<=
mmu_force_free_addr
;
mmu_set_usecnt_o
<=
pckstart_usecnt_req
or
interpck_usecnt_req
;
mmu_usecnt_o
<=
write_usecnt
;
--read_usecnt;
mmu_page_alloc_req_o
<=
interpck_page_alloc_req
or
pckstart_page_alloc_req
;
mmu_force_free_o
<=
mmu_force_free
;
mmu_pageaddr_o
<=
interpck_pageaddr
when
(
page_state
=
S_INTERPCK_SET_USECNT
)
else
pckstart_pageaddr
when
(
page_state
=
S_PCKSTART_SET_USECNT
)
else
(
others
=>
'0'
)
;
flush_with_valid_data
<=
'1'
when
(
write_ctrl_out
=
b"10"
)
else
'0'
;
drdy
<=
((
not
(
fifo_empty
and
(
not
flush_with_valid_data
)))
and
(
not
mpm_full_i
))
when
(
write_state
=
S_WRITE_MPM
)
else
'0'
;
flush_sig
<=
(
write_ctrl_out
(
1
))
when
(
write_state
=
S_WRITE_MPM
)
else
'0'
;
mpm_flush
<=
flush_reg
or
flush_sig
;
rtu_rsp_ack_o
<=
rtu_rsp_ack
;
mmu_force_free_addr_o
<=
mmu_force_free_addr
;
mmu_set_usecnt_o
<=
pckstart_usecnt_req
or
interpck_usecnt_req
;
mmu_usecnt_o
<=
write_usecnt
;
--read_usecnt;
mmu_page_alloc_req_o
<=
interpck_page_alloc_req
or
pckstart_page_alloc_req
;
mmu_force_free_o
<=
mmu_force_free
;
mmu_pageaddr_o
<=
interpck_pageaddr
when
(
page_state
=
S_INTERPCK_SET_USECNT
)
else
pckstart_pageaddr
when
(
page_state
=
S_PCKSTART_SET_USECNT
)
else
(
others
=>
'0'
);
mpm_pckstart_o
<=
mpm_pckstart
;
mpm_pageaddr_o
<=
mpm_pageaddr
;
mpm_pagereq_o
<=
mpm_pagereq
;
mpm_data_o
<=
write_data
;
mpm_ctrl_o
<=
write_ctrl
;
mpm_drdy_o
<=
drdy
;
mpm_flush_o
<=
mpm_flush
;
pta_transfer_pck_o
<=
transfering_pck
;
pta_pageaddr_o
<=
pta_pageaddr
;
pta_mask_o
<=
pta_mask
;
pta_prio_o
<=
pta_prio
;
pta_pck_size_o
<=
pta_pck_size
;
mpm_pckstart_o
<=
mpm_pckstart
;
mpm_pageaddr_o
<=
mpm_pageaddr
;
mpm_pagereq_o
<=
mpm_pagereq
;
mpm_data_o
<=
write_data
;
mpm_ctrl_o
<=
write_ctrl
;
mpm_drdy_o
<=
drdy
;
mpm_flush_o
<=
mpm_flush
;
pta_transfer_pck_o
<=
transfering_pck
;
pta_pageaddr_o
<=
pta_pageaddr
;
pta_mask_o
<=
pta_mask
;
pta_prio_o
<=
pta_prio
;
pta_pck_size_o
<=
pta_pck_size
;
end
syn
;
-- arch
end
syn
;
-- arch
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