diff --git a/libraries/base/common/src/vhdl/common_mem_pkg.vhd b/libraries/base/common/src/vhdl/common_mem_pkg.vhd index 444e5c915cda27579b56c56520f7378cec7c3069..0e55fc1db94fc2cc5d2026001f6c53efcf9c7eb5 100644 --- a/libraries/base/common/src/vhdl/common_mem_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_mem_pkg.vhd @@ -18,6 +18,34 @@ -- along with this program. If not, see <http://www.gnu.org/licenses/>. -- ------------------------------------------------------------------------------- +-- +-- Author: E. Kooistra, D. vd Schuur +-- Purpose: Simple memory access (for MM control interface) +-- Description: +-- +-- Assume the MM bus is for a 32 bit processor, therefore on the processor +-- side of a memory peripheral typcially use c_word_w = 32 for the address +-- and data fields in the MM bus records. However the MM bus can also be used +-- on the user side of a memory peripheral and there the data width should +-- not be limited by the processor type but rather by the maximum user data +-- width on the streaming interface. +-- +-- The std_logic_vector widths in the record need to be defined, because in +-- a record they can not be unconstrained. A signal that needs less address +-- or data width simply leaves the unused MSbits at 'X'. The actually used +-- width of a memory gets set via a generic record type t_c_mem. +-- +-- The alternative is to not put the std_logic_vector elements in the record, +-- and declare them seperately, however then the compact representation that +-- records provide gets lost, because the record then only contains wr_en and +-- rd_en. Another alternative is to define the address as a integer and the +-- data as an integer. However this limits their range to 32 bit numbers, +-- which can be too few for data. + +-- Do not change these widths, because c_word_w just fits in a VHDL INTEGER +-- Should wider address range or data width be needed, then define a new +-- record type eg. t_mem_ctlr or t_mem_bus for that with +-- sufficient widths. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; @@ -25,34 +53,6 @@ USE IEEE.NUMERIC_STD.ALL; USE work.common_pkg.ALL; PACKAGE common_mem_pkg IS - - ------------------------------------------------------------------------------ - -- Simple memory access (for MM control interface) - ------------------------------------------------------------------------------ - - -- Assume the MM bus is for a 32 bit processor, therefore on the processor - -- side of a memory peripheral typcially use c_word_w = 32 for the address - -- and data fields in the MM bus records. However the MM bus can also be used - -- on the user side of a memory peripheral and there the data width should - -- not be limited by the processor type but rather by the maximum user data - -- width on the streaming interface. - -- - -- The std_logic_vector widths in the record need to be defined, because in - -- a record they can not be unconstrained. A signal that needs less address - -- or data width simply leaves the unused MSbits at 'X'. The actually used - -- width of a memory gets set via a generic record type t_c_mem. - -- - -- The alternative is to not put the std_logic_vector elements in the record, - -- and declare them seperately, however then the compact representation that - -- records provide gets lost, because the record then only contains wr_en and - -- rd_en. Another alternative is to define the address as a integer and the - -- data as an integer. However this limits their range to 32 bit numbers, - -- which can be too few for data. - - -- Do not change these widths, because c_word_w just fits in a VHDL INTEGER - -- Should wider address range or data width be needed, then define a new - -- record type eg. t_mem_ctlr or t_mem_bus for that with - -- sufficient widths. -- Choose smallest maximum slv lengths that fit all use cases, because unconstrained record fields slv is not allowed CONSTANT c_mem_address_w : NATURAL := 32; -- address range (suits 32-bit processor) @@ -80,9 +80,24 @@ PACKAGE common_mem_pkg IS TYPE t_mem_miso_arr IS ARRAY (INTEGER RANGE <>) OF t_mem_miso; TYPE t_mem_mosi_arr IS ARRAY (INTEGER RANGE <>) OF t_mem_mosi; + -- MOSI/MISO subtypes + SUBTYPE t_mem_copi IS t_mem_mosi; -- Controller Out Peripheral In + SUBTYPE t_mem_cipo IS t_mem_miso; -- Peripheral In Controller Out + + CONSTANT c_mem_cipo_rst : t_mem_cipo := c_mem_miso_rst; + CONSTANT c_mem_copi_rst : t_mem_copi := c_mem_mosi_rst; + + SUBTYPE t_mem_cipo_arr IS t_mem_miso_arr; + SUBTYPE t_mem_copi_arr IS t_mem_mosi_arr; + -- Reset only the control fields of the MM record - FUNCTION RESET_MEM_MOSI_CTRL(mosi : t_mem_mosi) RETURN t_mem_mosi; - FUNCTION RESET_MEM_MISO_CTRL(miso : t_mem_miso) RETURN t_mem_miso; + FUNCTION RESET_MEM_MOSI_CTRL(mosi : t_mem_mosi) RETURN t_mem_mosi; -- deprecated, use RESET_MEM_COPI_CTRL() instead + FUNCTION RESET_MEM_COPI_CTRL(copi : t_mem_copi) RETURN t_mem_copi; + FUNCTION RESET_MEM_COPI_CTRL(copi_arr : t_mem_copi_arr) RETURN t_mem_copi_arr; + + FUNCTION RESET_MEM_MISO_CTRL(miso : t_mem_miso) RETURN t_mem_miso; -- deprecated, use RESET_MEM_CIPO_CTRL() instead + FUNCTION RESET_MEM_CIPO_CTRL(cipo : t_mem_cipo) RETURN t_mem_cipo; + FUNCTION RESET_MEM_CIPO_CTRL(cipo_arr : t_mem_cipo_arr) RETURN t_mem_cipo_arr; -- Resize functions to fit an integer or an SLV in the corresponding t_mem_miso or t_mem_mosi field width FUNCTION TO_MEM_ADDRESS(n : INTEGER) RETURN STD_LOGIC_VECTOR; -- unsigned, use integer to support 32 bit range @@ -94,17 +109,6 @@ PACKAGE common_mem_pkg IS FUNCTION RESIZE_MEM_UDATA( vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- unsigned FUNCTION RESIZE_MEM_SDATA( vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- sign extended FUNCTION RESIZE_MEM_XDATA( vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- set unused MSBits to 'X' - - -- MOSI/MISO subtypes - SUBTYPE t_mem_copi IS t_mem_mosi; -- Controller Out Peripheral In - SUBTYPE t_mem_cipo IS t_mem_miso; -- Peripheral In Controller Out - - CONSTANT c_mem_cipo_rst : t_mem_cipo := c_mem_miso_rst; - CONSTANT c_mem_copi_rst : t_mem_copi := c_mem_mosi_rst; - - SUBTYPE t_mem_cipo_arr IS t_mem_miso_arr; - SUBTYPE t_mem_copi_arr IS t_mem_mosi_arr; - ------------------------------------------------------------------------------ -- Burst memory access (for DDR access interface) @@ -191,7 +195,20 @@ PACKAGE BODY common_mem_pkg IS v_mosi.wr := '0'; RETURN v_mosi; END RESET_MEM_MOSI_CTRL; - + + FUNCTION RESET_MEM_COPI_CTRL(copi : t_mem_copi) RETURN t_mem_copi IS + BEGIN + RETURN RESET_MEM_MOSI_CTRL(copi); + END; + + FUNCTION RESET_MEM_COPI_CTRL(copi_arr : t_mem_copi_arr) RETURN t_mem_copi_arr IS + VARIABLE v_copi_arr : t_mem_copi_arr(copi_arr'RANGE) := copi_arr; + BEGIN + FOR I IN copi_arr'RANGE LOOP + v_copi_arr(I) := RESET_MEM_COPI_CTRL(copi_arr(I)); + END LOOP; + END; + FUNCTION RESET_MEM_MISO_CTRL(miso : t_mem_miso) RETURN t_mem_miso IS VARIABLE v_miso : t_mem_miso := miso; BEGIN @@ -200,6 +217,19 @@ PACKAGE BODY common_mem_pkg IS RETURN v_miso; END RESET_MEM_MISO_CTRL; + FUNCTION RESET_MEM_CIPO_CTRL(cipo : t_mem_cipo) RETURN t_mem_cipo IS + BEGIN + RETURN RESET_MEM_MISO_CTRL(cipo); + END RESET_MEM_CIPO_CTRL; + + FUNCTION RESET_MEM_CIPO_CTRL(cipo_arr : t_mem_cipo_arr) RETURN t_mem_cipo_arr IS + VARIABLE v_cipo_arr : t_mem_cipo_arr(cipo_arr'RANGE) := cipo_arr; + BEGIN + FOR I IN cipo_arr'RANGE LOOP + v_cipo_arr(I) := RESET_MEM_CIPO_CTRL(cipo_arr(I)); + END LOOP; + END RESET_MEM_CIPO_CTRL; + -- Resize functions to fit an integer or an SLV in the corresponding t_mem_miso or t_mem_mosi field width FUNCTION TO_MEM_ADDRESS(n : INTEGER) RETURN STD_LOGIC_VECTOR IS BEGIN