Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
P
Platform-independent core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
14
Issues
14
List
Board
Labels
Milestones
Merge Requests
5
Merge Requests
5
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
Platform-independent core collection
Commits
4d5408f3
Commit
4d5408f3
authored
Oct 10, 2012
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
common/gc_word_packer: uploaded missing source file
parent
8f591190
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
207 additions
and
0 deletions
+207
-0
gc_word_packer.vhd
modules/common/gc_word_packer.vhd
+207
-0
No files found.
modules/common/gc_word_packer.vhd
0 → 100644
View file @
4d5408f3
-------------------------------------------------------------------------------
-- Title : Word packer/unpacker
-- Project : General Cores Collection library
-------------------------------------------------------------------------------
-- File : gc_word_packer.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2012-09-13
-- Last update: 2012-09-13
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Packs/unpacks g_input_width-sized word(s) into g_output_width-
-- sized word(s). Data is packed starting from the least significant word.
-- Packet width must be integer multiple of the unpacked width.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library
ieee
;
use
ieee
.
std_logic_1164
.
all
;
use
ieee
.
numeric_std
.
all
;
use
work
.
genram_pkg
.
all
;
entity
gc_word_packer
is
generic
(
-- width of the input words
g_input_width
:
integer
;
-- width of the output words
g_output_width
:
integer
);
port
(
clk_i
:
in
std_logic
;
rst_n_i
:
in
std_logic
;
-- input data
d_i
:
in
std_logic_vector
(
g_input_width
-1
downto
0
);
-- input data valid
d_valid_i
:
in
std_logic
;
-- synchronous input data request, when active, the source
-- is allowed to assert d_valid_i in next clock cycle.
d_req_o
:
out
std_logic
;
-- flushes packer input, immediately outputting (incomplete) packed word to q_o
-- even if the number of input words is less than g_output_width.
-- Unused when g_input_width > g_output_width (unpacking)
flush_i
:
in
std_logic
:
=
'0'
;
-- data output
q_o
:
out
std_logic_vector
(
g_output_width
-1
downto
0
);
-- data output valid
q_valid_o
:
out
std_logic
;
-- synchronous data request: if active, packer can output data in following
-- clock cycle.
q_req_i
:
in
std_logic
);
end
gc_word_packer
;
architecture
rtl
of
gc_word_packer
is
function
f_max
(
a
:
integer
;
b
:
integer
)
return
integer
is
begin
if
(
a
>
b
)
then
return
a
;
else
return
b
;
end
if
;
end
f_max
;
function
f_min
(
a
:
integer
;
b
:
integer
)
return
integer
is
begin
if
(
a
<
b
)
then
return
a
;
else
return
b
;
end
if
;
end
f_min
;
constant
c_sreg_size
:
integer
:
=
f_max
(
g_input_width
,
g_output_width
);
constant
c_sreg_entries
:
integer
:
=
c_sreg_size
/
f_min
(
g_input_width
,
g_output_width
);
signal
sreg
:
std_logic_vector
(
c_sreg_size
-1
downto
0
);
signal
count
:
unsigned
(
f_log2_size
(
c_sreg_entries
+
1
)
-
1
downto
0
);
signal
empty
:
std_logic
;
signal
q_valid_comb
,
q_valid_reg
,
q_req_d0
:
std_logic
;
begin
-- rtl
-- Fixme: flush functionality.
gen_grow
:
if
(
g_output_width
>
g_input_width
)
generate
p_grow
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
count
<=
(
others
=>
'0'
);
else
if
(
d_valid_i
=
'1'
)
then
if
(
q_valid_reg
=
'0'
)
then
sreg
(
to_integer
(
count
)
*
g_input_width
+
g_input_width
-1
downto
to_integer
(
count
)
*
g_input_width
)
<=
d_i
;
else
sreg
(
g_input_width
-1
downto
0
)
<=
d_i
;
end
if
;
end
if
;
if
(
q_valid_comb
=
'1'
)
then
count
<=
(
others
=>
'0'
);
elsif
(
d_valid_i
=
'1'
)
then
count
<=
count
+
1
;
end
if
;
q_valid_reg
<=
q_valid_comb
;
end
if
;
end
if
;
end
process
;
q_valid_o
<=
q_valid_reg
;
q_valid_comb
<=
'1'
when
(
q_req_i
=
'1'
and
(
count
=
c_sreg_entries
or
(
count
=
c_sreg_entries
-1
and
d_valid_i
=
'1'
)))
else
'0'
;
d_req_o
<=
'1'
when
q_req_i
=
'1'
and
(
count
/=
c_sreg_entries
)
else
'0'
;
q_o
<=
sreg
;
end
generate
gen_grow
;
gen_shrink
:
if
(
g_output_width
<
g_input_width
)
generate
p_shrink
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
rst_n_i
=
'0'
then
count
<=
(
others
=>
'0'
);
empty
<=
'1'
;
q_req_d0
<=
'0'
;
else
q_req_d0
<=
q_req_i
;
if
(
d_valid_i
=
'1'
)
then
sreg
<=
d_i
;
end
if
;
if
(
count
=
c_sreg_entries
-1
and
d_valid_i
=
'0'
and
q_valid_comb
=
'1'
)
then
empty
<=
'1'
;
elsif
(
d_valid_i
=
'1'
)
then
empty
<=
'0'
;
end
if
;
if
(
q_valid_comb
=
'1'
)
then
if
(
count
=
c_sreg_entries
-1
)
then
count
<=
(
others
=>
'0'
);
else
count
<=
count
+
1
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
;
q_valid_o
<=
q_valid_comb
;
d_req_o
<=
'1'
when
d_valid_i
=
'0'
and
(
empty
=
'1'
or
(
q_req_i
=
'1'
and
count
=
c_sreg_entries
-1
))
else
'0'
;
p_gen_output
:
process
(
count
,
sreg
,
empty
,
d_i
,
d_valid_i
,
q_req_d0
)
begin
if
(
q_req_d0
=
'1'
and
empty
=
'0'
)
then
q_valid_comb
<=
'1'
;
q_o
<=
sreg
(
to_integer
(
count
)
*
g_output_width
+
g_output_width
-1
downto
to_integer
(
count
)
*
g_output_width
);
elsif
(
empty
=
'1'
and
d_valid_i
=
'1'
and
q_req_d0
=
'1'
)
then
q_valid_comb
<=
'1'
;
q_o
<=
d_i
(
g_output_width
-1
downto
0
);
else
q_valid_comb
<=
'0'
;
q_o
<=
(
others
=>
'X'
);
end
if
;
end
process
;
end
generate
gen_shrink
;
gen_equal
:
if
(
g_output_width
=
g_input_width
)
generate
q_o
<=
d_i
;
q_valid_o
<=
d_valid_i
;
d_req_o
<=
q_req_i
;
end
generate
gen_equal
;
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