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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [misclib/] [tap_jtag.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
--!
2
--! Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
3
--!
4
--! Licensed under the Apache License, Version 2.0 (the "License");
5
--! you may not use this file except in compliance with the License.
6
--! You may obtain a copy of the License at
7
--!
8
--!     http://www.apache.org/licenses/LICENSE-2.0
9
--! Unless required by applicable law or agreed to in writing, software
10
--! distributed under the License is distributed on an "AS IS" BASIS,
11
--! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
--! See the License for the specific language governing permissions and
13
--! limitations under the License.
14
--!
15
 
16
library ieee;
17
use ieee.std_logic_1164.all;
18
library commonlib;
19
use commonlib.types_common.all;
20
--! AMBA system bus specific library.
21
library ambalib;
22
--! AXI4 configuration constants.
23
use ambalib.types_amba4.all;
24
library misclib;
25
use misclib.types_misc.all;
26
 
27
entity tap_jtag is
28
  generic (
29
    ainst  : integer range 0 to 255 := 2;
30
    dinst  : integer range 0 to 255 := 3);
31
  port (
32
    nrst  : in std_logic;
33
    clk  : in std_logic;
34
    i_tck   : in std_logic;   -- in: Test Clock
35
    i_ntrst   : in std_logic;
36
    i_tms   : in std_logic;   -- in: Test Mode State
37
    i_tdi   : in std_logic;   -- in: Test Data Input
38
    o_tdo   : out std_logic;   -- out: Test Data Output
39
         o_jtag_vref : out std_logic;
40
    i_msti   : in nasti_master_in_type;
41
    o_msto   : out nasti_master_out_type;
42
    o_mstcfg : out nasti_master_config_type
43
    );
44
end;
45
 
46
 
47
architecture rtl of tap_jtag is
48
 
49
  constant ADDBITS : integer := 10;
50
 
51
  constant xmstconfig : nasti_master_config_type := (
52
     descrsize => PNP_CFG_MASTER_DESCR_BYTES,
53
     descrtype => PNP_CFG_TYPE_MASTER,
54
     vid => VENDOR_GNSSSENSOR,
55
     did => GNSSSENSOR_JTAG_TAP
56
  );
57
 
58
  type dma_req_state_type is (
59
      DMAREQ_IDLE,
60
      DMAREQ_SYNC_START,
61
      DMAREQ_START,
62
      DMAREQ_WAIT_READ_RESP,
63
      DMAREQ_SYNC_RESP
64
   );
65
 
66
  type tckpreg_type is record
67
    addr       : std_logic_vector(34 downto 0);
68
    datashft   : std_logic_vector(32 downto 0);
69
    done_sync  : std_ulogic;
70
    prun       : std_ulogic;
71
    inshift    : std_ulogic;
72
    holdn      : std_ulogic;
73
  end record;
74
 
75
  type tcknreg_type is record
76
    run: std_ulogic;
77
    done_sync1: std_ulogic;
78
    qual_rdata: std_ulogic;
79
    addrlo    : std_logic_vector(ADDBITS-1 downto 2);
80
    data       : std_logic_vector(32 downto 0);
81
  end record;
82
 
83
  type axireg_type is record
84
    dma : dma_bank_type;
85
    run_sync:  std_logic_vector(1 downto 0);
86
    qual_dreg: std_ulogic;
87
    qual_areg: std_ulogic;
88
    areg: std_logic_vector(34 downto 0);
89
    dreg: std_logic_vector(31 downto 0);
90
    done: std_ulogic;
91
    dma_req_state : dma_req_state_type;
92
  end record;
93
 
94
  signal ar, arin : axireg_type;
95
  signal tpr, tprin: tckpreg_type;
96
  signal tnr, tnrin: tcknreg_type;
97
 
98
  signal qual_rdata, rdataq: std_logic_vector(31 downto 0);
99
  signal qual_dreg,  dregq: std_logic_vector(31 downto 0);
100
  signal qual_areg,  aregqin, aregq: std_logic_vector(34 downto 0);
101
 
102
  signal dma_response : dma_response_type;
103
 
104
  signal tapi_tdo : std_logic;
105
  signal tapo_rst : std_logic;
106
  signal tapo_tck : std_logic;
107
  signal tapo_tdi : std_logic;
108
  signal tapo_inst : std_logic_vector(7 downto 0);
109
  signal tapo_capt   : std_logic;
110
  signal tapo_shft   : std_logic;
111
  signal tapo_upd    : std_logic;
112
  signal tapo_xsel1  : std_logic;
113
  signal tapo_xsel2  : std_logic;
114
 
115
  attribute syn_keep: boolean;
116
  attribute syn_keep of rdataq : signal is true;
117
  attribute syn_keep of dregq : signal is true;
118
  attribute syn_keep of aregq : signal is true;
119
 
120
  component dcom_jtag is generic (
121
    irlen  : integer range 2 to 8 := 2;
122
    idcode : integer range 0 to 255 := 9;
123
    ainst  : integer range 0 to 255 := 2;  -- IR rw,address,size (35 bits)
124
    dinst  : integer range 0 to 255 := 3;  -- IR data (32 bits)
125
    id : std_logic_vector(31 downto 0) := X"01040093"
126
  );
127
  port (
128
    rst         : in std_ulogic;
129
    tck         : in std_ulogic;
130
    tms         : in std_ulogic;
131
    tdi         : in std_ulogic;
132
    tdo         : out std_ulogic;
133
    tapi_tdo    : in std_ulogic;
134
    tapo_tck    : out std_ulogic;
135
    tapo_tdi    : out std_ulogic;
136
    tapo_inst   : out std_logic_vector(7 downto 0);
137
    tapo_rst    : out std_ulogic;
138
    tapo_capt   : out std_ulogic;
139
    tapo_shft   : out std_ulogic;
140
    tapo_upd    : out std_ulogic;
141
    tapo_xsel1  : out std_ulogic;
142
    tapo_xsel2  : out std_ulogic
143
    );
144
  end component;
145
 
146
 
147
begin
148
 
149
  qual_rdata <= (others => tnr.qual_rdata);
150
  rdataq <= not (ar.dreg(31 downto 0) and qual_rdata(31 downto 0));
151
 
152
  qual_dreg <= (others => ar.qual_dreg);
153
  dregq <= not (tnr.data(31 downto 0) and qual_dreg(31 downto 0));
154
 
155
  qual_areg <= (others => ar.qual_areg);
156
  aregqin <= tpr.addr(34 downto ADDBITS) &
157
             tnr.addrlo(ADDBITS-1 downto 2) &
158
             tpr.addr(1 downto 0);
159
  aregq <= not (aregqin and qual_areg(34 downto 0));
160
 
161
 
162
  comb : process (nrst, ar, dma_response,
163
                  tapo_tck, tapo_tdi, tapo_inst, tapo_rst, tapo_capt, tapo_shft, tapo_upd, tapo_xsel1, tapo_xsel2,
164
                  i_msti, tpr, tnr, aregq, dregq, rdataq)
165
    variable av : axireg_type;
166
    variable tpv : tckpreg_type;
167
    variable tnv : tcknreg_type;
168
    variable asel, dsel : std_ulogic;
169
    variable vtapi_tdo : std_logic;
170
    variable write, seq : std_ulogic;
171
    variable wb_dma_request : dma_request_type;
172
    variable wb_dma_response : dma_response_type;
173
    variable wb_msto : nasti_master_out_type;
174
 
175
  begin
176
 
177
    av := ar;
178
    tpv := tpr;
179
    tnv := tnr;
180
 
181
    ---------------------------------------------------------------------------
182
    -- TCK side logic
183
    ---------------------------------------------------------------------------
184
    asel := tapo_xsel1;
185
    dsel := tapo_xsel2;
186
    vtapi_tdo := tpr.addr(0);
187
    if dsel='1' then
188
      vtapi_tdo := tpr.datashft(0) and tpr.holdn;
189
    end if;
190
    write := tpr.addr(34);
191
    seq := tpr.datashft(32);
192
 
193
    -- Sync regs using alternating phases
194
    tnv.done_sync1 := ar.done;
195
    tpv.done_sync  := tnr.done_sync1;
196
 
197
    -- Data CDC
198
    if tnr.qual_rdata='1' then
199
        tpv.datashft(32 downto 0) := '1' & (not rdataq);
200
    end if;
201
 
202
    if tapo_capt = '1' then
203
        tpv.addr(ADDBITS-1 downto 2) := tnr.addrlo;
204
    end if;
205
 
206
    -- Track whether we're in the middle of shifting
207
    if tapo_shft = '1' then
208
        tpv.inshift:='1';
209
    end if;
210
    if tapo_upd = '1' then
211
        tpv.inshift:='0';
212
    end if;
213
 
214
    if tapo_shft = '1' then
215
        if asel = '1' and tpr.prun='0'  then
216
            tpv.addr(34 downto 0) := tapo_tdi & tpr.addr(34 downto 1);
217
        end if;
218
        if dsel = '1' and tpr.holdn='1' then
219
            tpv.datashft(32 downto 0) := tapo_tdi & tpr.datashft(32 downto 1);
220
        end if;
221
    end if;
222
 
223
    if tnr.run='0' then
224
        tpv.holdn := '1';
225
    end if;
226
    tpv.prun := tnr.run;
227
 
228
    if tpr.prun='0' then
229
        tnv.qual_rdata := '0';
230
        if tapo_shft = '0' and tapo_upd = '1' then
231
            if asel = '1' then
232
                tnv.addrlo := tpr.addr(ADDBITS-1 downto 2);
233
            end if;
234
            if dsel = '1' then
235
                tnv.data := tpr.datashft;
236
            end if;
237
            if (asel and not write) = '1' then
238
                tpv.holdn := '0';
239
                tnv.run := '1';
240
            end if;
241
            if (dsel and (write or (not write and seq))) = '1' then
242
                tnv.run := '1';
243
                if (seq and not write) = '1' then
244
                    tnv.addrlo := tnr.addrlo + 1;
245
                    tpv.holdn := '0';
246
                end if;
247
            end if;
248
        end if;
249
    else
250
      if tpr.done_sync='1' and (tpv.inshift='0' or write='1') then
251
        tnv.run := '0';
252
        if write='0' then
253
          tnv.qual_rdata := '1';
254
        end if;
255
        if (write and tnr.data(32)) = '1' then
256
          tnv.addrlo := tnr.addrlo + 1;
257
        end if;
258
      end if;
259
    end if;
260
 
261
    if tapo_rst = '1' then
262
      tpv.inshift := '0';
263
      tnv.run := '0';
264
    end if;
265
 
266
    av.qual_dreg := '0';
267
    av.qual_areg := '0';
268
 
269
    wb_dma_request.valid := '0';
270
    wb_dma_request.ready := '0';
271
    wb_dma_request.write := '0';
272
    wb_dma_request.addr := (others => '0');
273
    wb_dma_request.size := (others => '0');
274
    wb_dma_request.bytes := (others => '0');
275
    wb_dma_request.wdata := (others => '0');
276
 
277
    --! DMA control
278
    case ar.dma_req_state is
279
    when DMAREQ_IDLE =>
280
        if ar.run_sync(0) = '1' then
281
           av.qual_dreg := '1';
282
           av.qual_areg := '1';
283
           av.dma_req_state := DMAREQ_SYNC_START;
284
        end if;
285
 
286
    when DMAREQ_SYNC_START =>
287
        av.dma_req_state := DMAREQ_START;
288
 
289
    when DMAREQ_START =>
290
        wb_dma_request.valid := '1';
291
        wb_dma_request.addr := ar.areg(31 downto 0);
292
        wb_dma_request.bytes := conv_std_logic_vector(4, 11);
293
        wb_dma_request.size := '0' & ar.areg(33 downto 32);  -- 010=4 bytes; 011=8 bytes (not impl. yet)
294
        if ar.areg(34) = '1' then
295
            wb_dma_request.write := '1';
296
            wb_dma_request.wdata := ar.dreg(31 downto 0) & ar.dreg(31 downto 0);
297
            if dma_response.ready = '1' then
298
                av.done := '1';
299
                av.dma_req_state := DMAREQ_SYNC_RESP;
300
            end if;
301
        else
302
            wb_dma_request.write := '0';
303
            wb_dma_request.wdata := (others => '0');
304
            av.dma_req_state := DMAREQ_WAIT_READ_RESP;
305
        end if;
306
 
307
    when DMAREQ_WAIT_READ_RESP =>
308
        wb_dma_request.ready := '1';
309
        if dma_response.valid = '1' then
310
            av.done := '1';
311
            av.dreg := dma_response.rdata(31 downto 0);
312
            av.dma_req_state := DMAREQ_SYNC_RESP;
313
        end if;
314
 
315
    when DMAREQ_SYNC_RESP =>
316
        if ar.run_sync(0) = '0' then
317
            av.done := '0';
318
            av.dma_req_state := DMAREQ_IDLE;
319
        end if;
320
    when others =>
321
    end case;
322
 
323
 
324
    procedureAxi4DMA(
325
        i_request => wb_dma_request,
326
        o_response => wb_dma_response,
327
        i_bank => ar.dma,
328
        o_bank => av.dma,
329
        i_msti => i_msti,
330
        o_msto => wb_msto
331
    );
332
    dma_response <= wb_dma_response;
333
 
334
    -- Sync regs and CDC transfer
335
    av.run_sync := tnr.run & ar.run_sync(1);
336
 
337
    if ar.qual_dreg='1' then
338
        av.dreg:=not dregq;
339
    end if;
340
    if ar.qual_areg='1' then
341
        av.areg := not aregq;
342
    end if;
343
 
344
 
345
    if (nrst = '0') then
346
      av.dma := DMA_BANK_RESET;
347
      av.dma_req_state := DMAREQ_IDLE;
348
      av.qual_dreg := '0';
349
      av.qual_areg := '0';
350
      av.done := '0';
351
      av.areg := (others => '0');
352
      av.dreg := (others => '0');
353
    end if;
354
 
355
    tprin <= tpv;
356
    tnrin <= tnv;
357
    arin <= av;
358
    tapi_tdo <= vtapi_tdo;
359
    o_msto <= wb_msto;
360
  end process;
361
 
362
 
363
  o_jtag_vref <= '1';
364
  o_mstcfg <= xmstconfig;
365
 
366
  jtagcom0 : dcom_jtag generic map (
367
      irlen => 4,
368
      idcode => 9,
369
      ainst => ainst,
370
      dinst => dinst,
371
      id => X"01040093"
372
  ) port map (
373
    rst         => nrst,
374
    tck         => i_tck,
375
    tms         => i_tms,
376
    tdi         => i_tdi,
377
    tdo         => o_tdo,
378
    tapi_tdo => tapi_tdo,
379
    tapo_tck => tapo_tck,
380
    tapo_tdi => tapo_tdi,
381
    tapo_inst => tapo_inst,
382
    tapo_rst => tapo_rst,
383
    tapo_capt => tapo_capt,
384
    tapo_shft => tapo_shft,
385
    tapo_upd => tapo_upd,
386
    tapo_xsel1 => tapo_xsel1,
387
    tapo_xsel2 => tapo_xsel2
388
  );
389
 
390
  axireg : process(clk)
391
  begin
392
    if rising_edge(clk) then
393
        ar <= arin;
394
    end if;
395
  end process;
396
 
397
  tckpreg: process(tapo_tck, tapo_rst)
398
  begin
399
    if rising_edge(tapo_tck) then
400
      tpr <= tprin;
401
    end if;
402
    if tapo_rst = '1' then
403
      tpr.addr <= (others => '0');
404
      tpr.datashft <= (others => '0');
405
      tpr.done_sync <= '0';
406
      tpr.prun <= '0';
407
      tpr.inshift <= '0';
408
      tpr.holdn <= '1';
409
    end if;
410
  end process;
411
 
412
  tcknreg: process(tapo_tck, tapo_rst)
413
  begin
414
    if falling_edge(tapo_tck) then
415
      tnr <= tnrin;
416
    end if;
417
    if tapo_rst = '1' then
418
      tnr.run <= '0';
419
      tnr.done_sync1 <= '0';
420
      tnr.qual_rdata <= '0';
421
      tnr.addrlo <= (others => '0');
422
      tnr.data <= (others => '0');
423
    end if;
424
  end process;
425
 
426
end;

powered by: WebSVN 2.1.0

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