OpenCores
URL https://opencores.org/ocsvn/astron_mm/astron_mm/trunk

Subversion Repositories astron_mm

[/] [astron_mm/] [trunk/] [mm_fields.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2013
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22
-- Purpose:
23
-- . Define fields in an SLV that can be read/written via an MM interface.
24
-- Description:
25
-- . This is basically a wrapper around common_reg_r_w_dc, but with the 
26
--   addition of a generic field description array and package functions
27
--   to ease the definition and assignment of individual fields within
28
--   the i/o SLVs.
29
-- . Each field defined in g_field_arr will get its own 32-bit MM register(s)
30
--   based on its defined length:
31
--   . <32 bits = one dedicated 32-bit register for that field
32
--   . >32 bits = multiple dedicated 32-bit registers for that field
33
-- . The register mode can be "RO" for input from slv_in (e.g. status) or "RW"
34
--   for output via slv_out (e.g. control). Other modes are not supported.
35
--   Hence the length of the reg_slv_* signals is equal to slv_in'LENGTH +
36
--   slv_out'LENGTH.
37
-- . The figure below shows how the following example field array would be mapped. 
38
--
39
--   c_my_field_arr:= (( "my_field_2", "RW",  2 ), 
40
--                     ( "my_field_1", "RO",  2 ), 
41
--                     ( "my_field_0", "RO",  1 ));
42
--
43
--   ----------------------------------------------------------------------------------------------------------------
44
--   | slv_in             reg_slv_in_arr   reg_slv_in     common_reg_r_w     reg_slv_out                     slv_out|
45
--   |                                                                                                              |
46
--   |                            __          __          ______________          __                                |
47
--   |                         w0|f0|      w0|f0|        |0             |      w0|  |                               |
48
--   |                           |  | =====> |  | =====> |      RO      | =====> |  | =====>                        |
49
--   |                           |  |        |  |        |              |        |  |                               |
50
--   |   __                      |--|        |--|        |--------------|        |--|                               |
51
--   |  |f0|                   w1|f1|      w1|f1|        |1             |      w1|  |                          __   |
52
--   |  |f1| ==field_map_in==>   |f1| =====> |f1| =====> |      RO      | =====> |  | =====> field_map_out==> |f2|  |
53
--   |  |f1|                     |  |        |  |        |              |        |  |                         |f2|  |
54
--   |                           |--|        |--|        |--------------|        |--|                               |
55
--   |                         w2|  |      w2|f2|        |2             |      w2|f2|                               |
56
--   |                           |  |  /===> |f2| =====> |      RW      | =====> |f2| ==+==>                        |
57
--   |                           |__|  |     |__|        |______________|        |__|   |                           |
58
--   |                                 |                                                |                           |
59
--   |                                 \================================================/                           |
60
--   |                                                                                                              |
61
--   ----------------------------------------------------------------------------------------------------------------   
62
--   . slv_in  = 3 bits wide
63
--   . slv_out = 2 bits wide (= my_field_2 which is looped back to reg_slv_in because it is defined "RW")
64
--   . reg_reg_slv_in_arr, reg_slv_in, reg_slv_out = 3*c_word_w bits wide
65
-- Remarks:
66
 
67
LIBRARY IEEE, common_pkg_lib, common_ram_lib;
68
USE IEEE.STD_LOGIC_1164.ALL;
69
USE IEEE.NUMERIC_STD.ALL;
70
USE common_pkg_lib.common_pkg.ALL;
71
USE common_ram_lib.common_ram_pkg.ALL;
72
USE work.common_field_pkg.ALL;
73
 
74
ENTITY mm_fields IS
75
  GENERIC (
76
    g_cross_clock_domain : BOOLEAN := TRUE;
77
    g_use_slv_in_val     : BOOLEAN := TRUE;  -- use TRUE when slv_in_val is used, use FALSE to save logic when always slv_in_val='1'
78
    g_field_arr          : t_common_field_arr
79
  );
80
  PORT (
81
    mm_rst     : IN  STD_LOGIC;
82
    mm_clk     : IN  STD_LOGIC;
83
 
84
    mm_mosi    : IN  t_mem_mosi;
85
    mm_miso    : OUT t_mem_miso;
86
 
87
    slv_rst    : IN  STD_LOGIC;
88
    slv_clk    : IN  STD_LOGIC;
89
 
90
    --fields in these SLVs are defined by g_field_arr
91
    slv_in     : IN  STD_LOGIC_VECTOR(field_slv_in_len( g_field_arr)-1 DOWNTO 0) := (OTHERS=>'0');  -- slv of all "RO" fields in g_field_arr
92
    slv_in_val : IN  STD_LOGIC := '0';   -- strobe to signal that slv_in is valid and needs to be captured
93
 
94
    slv_out    : OUT STD_LOGIC_VECTOR(field_slv_out_len(g_field_arr)-1 DOWNTO 0)                    -- slv of all "RW" fields in g_field_arr
95
  );
96
END mm_fields;
97
 
98
 
99
ARCHITECTURE str OF mm_fields IS
100
 
101
  CONSTANT c_reg_nof_words : NATURAL := field_nof_words(g_field_arr, c_word_w);
102
 
103
  CONSTANT c_reg           : t_c_mem := (latency  => 1,
104
                                         adr_w    => ceil_log2(c_reg_nof_words),
105
                                         dat_w    => c_word_w,
106
                                         nof_dat  => c_reg_nof_words,
107
                                         init_sl  => '0');
108
 
109
  CONSTANT c_slv_out_defaults : STD_LOGIC_VECTOR(field_slv_out_len(g_field_arr)-1 DOWNTO 0) := field_map_defaults(g_field_arr);
110
  -- Map the default values onto c_init_reg
111
  CONSTANT c_init_reg : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := RESIZE_UVEC(field_map_in(g_field_arr, c_slv_out_defaults, c_reg.dat_w, "RW"), c_mem_reg_init_w);
112
 
113
  SIGNAL slv_in_arr         : STD_LOGIC_VECTOR(c_reg.dat_w*c_reg.nof_dat-1 DOWNTO 0);
114
  SIGNAL reg_slv_in_arr     : STD_LOGIC_VECTOR(c_reg.dat_w*c_reg.nof_dat-1 DOWNTO 0);
115
  SIGNAL nxt_reg_slv_in_arr : STD_LOGIC_VECTOR(c_reg.dat_w*c_reg.nof_dat-1 DOWNTO 0);
116
 
117
  SIGNAL reg_slv_in         : STD_LOGIC_VECTOR(c_reg.dat_w*c_reg.nof_dat-1 DOWNTO 0);
118
  SIGNAL reg_slv_out        : STD_LOGIC_VECTOR(c_reg.dat_w*c_reg.nof_dat-1 DOWNTO 0);
119
 
120
BEGIN
121
 
122
  -----------------------------------------------------------------------------
123
  -- reg_slv_out is persistent (always valid) while slv_in is not. Register
124
  -- slv_in_arr so reg_slv_in is persistent also.
125
  -----------------------------------------------------------------------------
126
  gen_capture_input : IF g_use_slv_in_val=TRUE GENERATE
127
    p_clk : PROCESS(slv_clk, slv_rst)
128
    BEGIN
129
      IF slv_rst='1' THEN
130
        reg_slv_in_arr <= (OTHERS=>'0');
131
      ELSIF rising_edge(slv_clk) THEN
132
        reg_slv_in_arr <= nxt_reg_slv_in_arr;
133
      END IF;
134
    END PROCESS;
135
 
136
    nxt_reg_slv_in_arr <= slv_in_arr WHEN slv_in_val = '1' ELSE reg_slv_in_arr;
137
  END GENERATE;
138
 
139
  gen_wire_input : IF g_use_slv_in_val=FALSE GENERATE
140
    reg_slv_in_arr <= slv_in_arr;
141
  END GENERATE;
142
 
143
  -----------------------------------------------------------------------------
144
  -- Field mapping
145
  -----------------------------------------------------------------------------
146
  -- Extract the all input fields ("RO") from slv_in and assign them to slv_in_arr
147
  slv_in_arr <= field_map_in(g_field_arr, slv_in, c_reg.dat_w, "RO");
148
 
149
  -- Map reg_slv_out onto slv_out for the write fields
150
  slv_out <= field_map_out(g_field_arr, reg_slv_out, c_reg.dat_w);
151
 
152
  -- Create the correct reg_slv_in using fields from both reg_slv_in_arr ("RO") reg_slv_out ("RW")
153
  reg_slv_in <= field_map(g_field_arr, reg_slv_in_arr, reg_slv_out, c_reg.dat_w);
154
 
155
  -----------------------------------------------------------------------------
156
  -- Actual MM <-> SLV R/W functionality is provided by common_reg_r_w_dc
157
  -----------------------------------------------------------------------------
158
  u_common_reg_r_w_dc : ENTITY work.common_reg_r_w_dc
159
  GENERIC MAP (
160
    g_cross_clock_domain => g_cross_clock_domain,
161
    g_readback           => FALSE,
162
    g_reg                => c_reg,
163
    g_init_reg           => c_init_reg
164
  )
165
  PORT MAP (
166
    mm_rst      => mm_rst,
167
    mm_clk      => mm_clk,
168
    st_rst      => slv_rst,
169
    st_clk      => slv_clk,
170
 
171
    sla_in      => mm_mosi,
172
    sla_out     => mm_miso,
173
 
174
    in_reg      => reg_slv_in,
175
    out_reg     => reg_slv_out
176
  );
177
 
178
END str;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.