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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [gnsslib/] [rf3b/] [axi_rfctrl.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
-----------------------------------------------------------------------------
2
--! @file
3
--! @copyright Copyright 2015 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief     This file implements RF-controller entity axi_rfctrl.
6
-----------------------------------------------------------------------------
7
library ieee;
8
use ieee.std_logic_1164.all;
9
 
10
library commonlib;
11
use commonlib.types_common.all;
12
 
13
--! AMBA system bus specific library
14
library ambalib;
15
--! AXI4 configuration constants.
16
use ambalib.types_amba4.all;
17
 
18
--! @brief     RF-front controller based on MAX2769 ICs.
19
--! @details   This unit implements SPI interface with MAX2769 ICs
20
--!            and interacts with the antenna control signals.
21
entity axi_rfctrl is
22
  generic (
23
    xaddr    : integer := 0;
24
    xmask    : integer := 16#fffff#
25
  );
26
  port (
27
    nrst    : in  std_logic;
28
    clk    : in  std_logic;
29
    o_cfg  : out nasti_slave_config_type;
30
    i_axi   : in  nasti_slave_in_type;
31
    o_axi   : out nasti_slave_out_type;
32
    i_gps_ld : in std_logic;
33
    i_glo_ld : in std_logic;
34
    --! @name  Synthezator's SPI interface signals:
35
    --! @brief Connects to MAX2769 IC.
36
    --! @{
37
    outSCLK  : out std_logic;
38
    outSDATA : out std_logic;
39
    outCSn   : out std_logic_vector(1 downto 0);
40
    --! @}
41
 
42
    --! @name  Antenna control signals:
43
    --! @brief RF front-end IO analog signals.
44
    --! @{
45
    inExtAntStat   : in std_logic;
46
    inExtAntDetect : in std_logic;
47
    outExtAntEna   : out std_logic;
48
    outIntAntContr   : out std_logic
49
    --! @}
50
  );
51
end;
52
 
53
architecture rtl of axi_rfctrl is
54
 
55
  constant xconfig : nasti_slave_config_type := (
56
     descrtype => PNP_CFG_TYPE_SLAVE,
57
     descrsize => PNP_CFG_SLAVE_DESCR_BYTES,
58
     irq_idx => 0,
59
     xaddr => conv_std_logic_vector(xaddr, CFG_NASTI_CFG_ADDR_BITS),
60
     xmask => conv_std_logic_vector(xmask, CFG_NASTI_CFG_ADDR_BITS),
61
     vid => VENDOR_GNSSSENSOR,
62
     did => GNSSSENSOR_RF_CONTROL
63
  );
64
 
65
  type local_addr_array_type is array (0 to CFG_WORDS_ON_BUS-1)
66
       of integer;
67
 
68
  type registers is record
69
    bank_axi : nasti_slave_bank_type;
70
 
71
    conf1       : std_logic_vector(27 downto 0);
72
    conf2       : std_logic_vector(27 downto 0);
73
    conf3       : std_logic_vector(27 downto 0);
74
    pllconf     : std_logic_vector(27 downto 0);
75
    div         : std_logic_vector(27 downto 0);
76
    fdiv        : std_logic_vector(27 downto 0);
77
    strm        : std_logic_vector(27 downto 0);
78
    clkdiv      : std_logic_vector(27 downto 0);
79
    test1       : std_logic_vector(27 downto 0);
80
    test2       : std_logic_vector(27 downto 0);
81
    scale       : std_logic_vector(31 downto 0);
82
    load_run    : std_ulogic;
83
    select_spi  : std_logic_vector(1 downto 0);
84
    loading     : std_ulogic;
85
    ScaleCnt    : std_logic_vector(31 downto 0);
86
    SClkPosedge  : std_ulogic;
87
    SClkNegedge  : std_ulogic;
88
    SCLK         : std_ulogic;
89
    BitCnt       : integer range 0 to 33;
90
    CS           : std_ulogic;  --!! not inversed!!
91
    WordSelector : std_logic_vector(8 downto 0);
92
    SendWord     : std_logic_vector(31 downto 0);
93
    ExtAntEna    : std_ulogic;
94
    IntAntContr  : std_ulogic;
95
  end record;
96
 
97
signal r, rin : registers;
98
 
99
begin
100
 
101
  comblogic : process(nrst, r, i_axi, i_glo_ld, i_gps_ld, inExtAntStat, inExtAntDetect)
102
    variable raddr_reg : local_addr_array_type;
103
    variable waddr_reg : local_addr_array_type;
104
    variable rdata : std_logic_vector(CFG_NASTI_DATA_BITS-1 downto 0);
105
    variable tmp : std_logic_vector(31 downto 0);
106
    variable wstrb : std_logic_vector(CFG_ALIGN_BYTES-1 downto 0);
107
 
108
  variable v : registers;
109
  variable readdata : std_logic_vector(31 downto 0);
110
  variable wNewWord : std_ulogic;
111
  begin
112
 
113
    v := r;
114
    v.load_run := '0';
115
 
116
    procedureAxi4(i_axi, xconfig, r.bank_axi, v.bank_axi);
117
 
118
     -- read registers:
119
     for n in 0 to CFG_WORDS_ON_BUS-1 loop
120
        raddr_reg(n) := conv_integer(r.bank_axi.raddr(n)(11 downto 2));
121
        tmp := (others => '0');
122
        case raddr_reg(n) is
123
          when 0 => tmp  := "0000" & r.conf1;
124
          when 1 => tmp  := "0000" & r.conf2;
125
          when 2 => tmp  := "0000" & r.conf3;
126
          when 3 => tmp  := "0000" & r.pllconf;
127
          when 4 => tmp  := "0000" & r.div;
128
          when 5 => tmp  := "0000" & r.fdiv;
129
          when 6 => tmp  := "0000" & r.strm;
130
          when 7 => tmp  := "0000" & r.clkdiv;
131
          when 8 => tmp  := "0000" & r.test1;
132
          when 9 => tmp  := "0000" & r.test2;
133
          when 10 => tmp  := r.scale;
134
          when 11 =>
135
            tmp(9 downto 0):= conv_std_logic_vector(r.BitCnt,6) & '0' & r.loading & i_glo_ld & i_gps_ld;
136
          when 15 =>
137
            tmp(5 downto 0)  := inExtAntStat & inExtAntDetect & "00"& r.IntAntContr & r.ExtAntEna;
138
          when others =>
139
        end case;
140
        rdata(8*CFG_ALIGN_BYTES*(n+1)-1 downto 8*CFG_ALIGN_BYTES*n) := tmp;
141
     end loop;
142
 
143
 
144
    -- write registers
145
    if i_axi.w_valid = '1' and
146
       r.bank_axi.wstate = wtrans and
147
       r.bank_axi.wresp = NASTI_RESP_OKAY then
148
 
149
      for n in 0 to CFG_WORDS_ON_BUS-1 loop
150
         waddr_reg(n) := conv_integer(r.bank_axi.waddr(n)(11 downto 2));
151
         tmp := i_axi.w_data(32*(n+1)-1 downto 32*n);
152
         wstrb := i_axi.w_strb(CFG_ALIGN_BYTES*(n+1)-1 downto CFG_ALIGN_BYTES*n);
153
 
154
         if conv_integer(wstrb) /= 0 then
155
            case waddr_reg(n) is
156
              when 0 => v.conf1 := tmp(27 downto 0);
157
              when 1 => v.conf2 := tmp(27 downto 0);
158
              when 2 => v.conf3 := tmp(27 downto 0);
159
              when 3 => v.pllconf := tmp(27 downto 0);
160
              when 4 => v.div := tmp(27 downto 0);
161
              when 5 => v.fdiv := tmp(27 downto 0);
162
              when 6 => v.strm := tmp(27 downto 0);
163
              when 7 => v.clkdiv := tmp(27 downto 0);
164
              when 8 => v.test1 := tmp(27 downto 0);
165
              when 9 => v.test2 := tmp(27 downto 0);
166
              when 10 =>
167
                if tmp(31 downto 1) = zero32(31 downto 1) then
168
                   v.scale := conv_std_logic_vector(2,32);
169
                else
170
                   v.scale := tmp;
171
                end if;
172
              when 11 =>
173
                v.load_run := '1';
174
                v.ScaleCnt := (others => '0');
175
                v.BitCnt := 0;
176
                if tmp = zero32 then
177
                  v.select_spi := "01";
178
                elsif tmp = conv_std_logic_vector(1,32) then
179
                  v.select_spi := "10";
180
                else
181
                  v.select_spi := "00";
182
                end if;
183
              when 15 =>
184
                v.ExtAntEna   := tmp(0);
185
                v.IntAntContr := tmp(1);
186
              when others =>
187
           end case;
188
         end if;
189
      end loop;
190
    end if;
191
 
192
 
193
    -- loading procedure:
194
    if((r.SClkNegedge='1') and (r.BitCnt=33)) then wNewWord := '1';
195
    else wNewWord := '0'; end if;
196
 
197
    if(r.load_run='1')                                   then v.loading := '1';
198
    elsif((wNewWord='1')and(r.WordSelector="000000000")) then v.loading := '0'; end if;
199
 
200
    if((r.loading and r.SClkNegedge)='1') then v.ScaleCnt := (others => '0');
201
    elsif(r.loading='1')                  then v.ScaleCnt := r.ScaleCnt+1; end if;
202
 
203
    -- scaler pulse:
204
    if((r.scale/=zero32)and(r.ScaleCnt=r.scale)) then v.SClkNegedge := '1';
205
    else                                              v.SClkNegedge := '0'; end if;
206
 
207
    if((r.scale/=zero32)and(r.ScaleCnt=('0'& r.scale(31 downto 1)))) then v.SClkPosedge := '1';
208
    else                                                                  v.SClkPosedge := '0'; end if;
209
 
210
    -- SCLK former:
211
    if(r.SClkPosedge='1') then v.SCLK := '1';
212
    elsif(r.SClkNegedge='1') then v.SCLK := '0'; end if;
213
 
214
    -- Not inversed CS signal:
215
    if((r.SClkNegedge='1')and(r.BitCnt=33)) then v.BitCnt := 0;
216
    elsif(r.SClkNegedge='1')                then v.BitCnt := r.BitCnt + 1; end if;
217
 
218
    if((r.BitCnt=0)or((r.BitCnt=33))) then v.CS := '0';
219
    else                                   v.CS := '1'; end if;
220
 
221
    -- Word multiplexer:
222
    if(r.load_run='1')  then v.WordSelector := "000000001";
223
    elsif(wNewWord='1') then v.WordSelector := r.WordSelector(7 downto 0) & '0'; end if;
224
 
225
    if(r.load_run='1') then                      v.SendWord := r.conf1 & "0000";
226
    elsif((wNewWord='1')and(r.WordSelector(0)='1')) then v.SendWord := r.conf2 & "0001";
227
    elsif((wNewWord='1')and(r.WordSelector(1)='1')) then v.SendWord := r.conf3 & "0010";
228
    elsif((wNewWord='1')and(r.WordSelector(2)='1')) then v.SendWord := r.pllconf & "0011";
229
    elsif((wNewWord='1')and(r.WordSelector(3)='1')) then v.SendWord := r.div & "0100";
230
    elsif((wNewWord='1')and(r.WordSelector(4)='1')) then v.SendWord := r.fdiv & "0101";
231
    elsif((wNewWord='1')and(r.WordSelector(5)='1')) then v.SendWord := r.strm & "0110";
232
    elsif((wNewWord='1')and(r.WordSelector(6)='1')) then v.SendWord := r.clkdiv & "0111";
233
    elsif((wNewWord='1')and(r.WordSelector(7)='1')) then v.SendWord := r.test1 & "1000";
234
    elsif((wNewWord='1')and(r.WordSelector(8)='1')) then v.SendWord := r.test2 & "1001";
235
    elsif((r.SClkNegedge='1')and(r.BitCnt/=0)and(r.BitCnt/=33)) then  v.SendWord := r.SendWord(30 downto 0)&'0'; end if;
236
 
237
    -- reset operation
238
 
239
    if nrst = '0' then
240
      v.bank_axi := NASTI_SLAVE_BANK_RESET;
241
      v.load_run := '0';
242
      v.conf1 := (others => '0');
243
      v.conf2 := (others => '0');
244
      v.conf3 := (others => '0');
245
      v.pllconf := (others => '0');
246
      v.div := (others => '0');
247
      v.fdiv := (others => '0');
248
      v.strm := (others => '0');
249
      v.clkdiv := (others => '0');
250
      v.test1 := (others => '0');
251
      v.test2 := (others => '0');
252
      v.scale := (others => '0');
253
      v.SCLK := '0';
254
      v.BitCnt := 0;
255
      v.CS := '0';
256
      v.select_spi := (others => '0');
257
      v.ExtAntEna := '0';
258
      v.SendWord := (others=>'0');
259
      v.loading := '0';
260
      v.ScaleCnt := (others => '0');
261
      v.WordSelector := (others => '0');
262
      v.IntAntContr := '0';
263
    end if;
264
 
265
    rin <= v;
266
    o_axi <= functionAxi4Output(r.bank_axi, rdata);
267
 
268
  end process;
269
 
270
 
271
  o_cfg  <= xconfig;
272
 
273
  outSCLK   <= r.SCLK;
274
  outCSn(0) <= not(r.CS and r.select_spi(0));
275
  outCSn(1) <= not(r.CS and r.select_spi(1));
276
  outSDATA  <= r.SendWord(31);
277
 
278
  outExtAntEna <= r.ExtAntEna;
279
  outIntAntContr <= r.IntAntContr;
280
 
281
 
282
  -- registers:
283
  regs : process(clk) begin
284
    if rising_edge(clk) then
285
       r <= rin;
286
    end if;
287
  end process;
288
 
289
end;

powered by: WebSVN 2.1.0

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