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 4

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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