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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [work/] [tb/] [jtag_sim.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 2016 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
------------------------------------------------------------------------------
6
 
7
library ieee;
8
use ieee.std_logic_1164.all;
9
library std;
10
use std.textio.all;
11
library commonlib;
12
use commonlib.types_common.all;
13
use commonlib.types_util.all;
14
 
15
entity jtag_sim is
16
  generic (
17
    clock_rate : integer := 10;
18
    irlen : integer := 4
19
  );
20
  port (
21
    rst : in std_logic;
22
    clk : in std_logic;
23
    i_test_ena : in std_logic;
24
    i_test_burst : in std_logic_vector(7 downto 0);
25
    i_test_addr : in std_logic_vector(31 downto 0);
26
    i_test_we : in std_logic;
27
    i_test_wdata : in std_logic_vector(31 downto 0);
28
    i_tdi  : in std_logic;
29
    o_tck : out std_logic;
30
    o_ntrst : out std_logic;
31
    o_tms : out std_logic;
32
    o_tdo : out std_logic
33
  );
34
end;
35
 
36
architecture jtag_sim_rtl of jtag_sim is
37
 
38
  type state_type is (test_rst, run_idle, start_ir, select_dr, capture_dr, shift_dr, exit1_dr,
39
                      pause_dr, exit2_dr, update_dr, select_ir, capture_ir, shift_ir,
40
                      exit1_ir, pause_ir, exit2_ir, update_ir);
41
 
42
  constant ADDR_WIDTH : integer := 32;
43
  constant DATA_WIDTH : integer := 32;
44
  constant REG1_LEN : integer := ADDR_WIDTH + 3; -- 3 = 1 bit we field + 2 bits transaction size
45
  constant REG2_LEN : integer := DATA_WIDTH + 1; -- 1 bulk bit
46
  constant SHIFT_LEN : integer := irlen + REG1_LEN; -- maximal length
47
 
48
  type registers is record
49
      jtagstate : state_type;
50
      jtagstatez : state_type;
51
      burst_cnt : integer;
52
      shift_reg1 : std_logic_vector(REG1_LEN-1 downto 0);
53
      shift_reg2 : std_logic_vector(REG2_LEN-1 downto 0);
54
      shift_reg : std_logic_vector(irlen + REG1_LEN-1 downto 0);
55
      shift_length : integer;
56
      clk_rate_cnt : integer;
57
      is_data : std_logic;
58
      instr : integer range 1 to 2;
59
      op_cnt : integer;
60
      rdata : std_logic_vector(DATA_WIDTH-1 downto 0);
61
      edge : std_logic;
62
      ntrst : std_logic;
63
      tms : std_logic;
64
  end record;
65
 
66
  signal r, rin : registers;
67
 
68
begin
69
 
70
  comblogic : process(rst, r, i_tdi, i_test_ena, i_test_addr, i_test_we, i_test_wdata)
71
    variable v : registers;
72
    variable w_posedge : std_logic;
73
    variable w_negedge : std_logic;
74
  begin
75
     v := r;
76
     w_posedge := '0';
77
     w_negedge := '0';
78
     if r.clk_rate_cnt = (clock_rate - 1) then
79
         v.clk_rate_cnt := 0;
80
         v.edge := not r.edge;
81
         w_posedge := not r.edge;
82
         w_negedge := r.edge;
83
     else
84
         v.clk_rate_cnt := r.clk_rate_cnt + 1;
85
     end if;
86
 
87
     if i_test_ena = '1' and r.jtagstate = run_idle then
88
        v.burst_cnt := conv_integer(i_test_burst);
89
        v.shift_reg1(34) := i_test_we;
90
        v.shift_reg1(33 downto 32) := "10"; -- size: 0=1 byte; 1=hword; 2=word; 3=dword
91
        v.shift_reg1(31 downto 0) := i_test_addr;
92
        if i_test_burst = X"00" then
93
            v.shift_reg2(32) := '0'; -- bulk=0
94
        else
95
            v.shift_reg2(32) := '1'; -- bulk=1
96
        end if;
97
        v.shift_reg2(31 downto 0) := i_test_wdata;
98
        v.is_data := '1';
99
     elsif w_posedge = '1' then
100
        v.is_data := '0';
101
     end if;
102
 
103
     if w_posedge = '1' then
104
        v.jtagstatez := r.jtagstate;
105
 
106
        case r.jtagstate is
107
        when test_rst =>
108
            v.ntrst := '0';
109
            v.op_cnt := r.op_cnt + 1;
110
            if r.op_cnt = 3 then
111
                v.jtagstate := run_idle;
112
                v.op_cnt := 0;
113
                v.ntrst := '1';
114
            end if;
115
        when run_idle =>
116
            if r.is_data = '1' then
117
                v.tms := '1';
118
                v.instr := 1;
119
                v.op_cnt := 0;
120
                v.jtagstate := start_ir;
121
            end if;
122
        when start_ir => -- the same as select_dr
123
            v.tms := '1';
124
            v.jtagstate := select_ir;
125
 
126
        when select_ir =>
127
            v.tms := '0';
128
            v.jtagstate := capture_ir;
129
        when capture_ir =>
130
            v.tms := '0';
131
            v.op_cnt := 0;
132
            v.jtagstate := shift_ir;
133
            if r.instr = 1 then
134
                v.shift_reg := r.shift_reg1 & conv_std_logic_vector(2, irlen);
135
                v.shift_length := 35-1;
136
            else
137
                v.shift_reg := "00" & r.shift_reg2 & conv_std_logic_vector(3, irlen);
138
                v.shift_length := 33-1;
139
            end if;
140
            v.op_cnt := 0;
141
        when shift_ir =>
142
            v.tms := '0';
143
            v.op_cnt := r.op_cnt + 1;
144
            if r.op_cnt = irlen-1 then
145
                v.tms := '1';
146
                v.jtagstate := exit1_ir;
147
            end if;
148
        when exit1_ir =>
149
            v.tms := '1';
150
            v.jtagstate := update_ir;
151
        when update_ir =>
152
            v.tms := '1';
153
            v.jtagstate := select_dr;
154
 
155
        when select_dr =>
156
            v.tms := '0';
157
            v.jtagstate := capture_dr;
158
        when capture_dr =>
159
            v.tms := '0';
160
            v.op_cnt := 0;
161
            v.jtagstate := shift_dr;
162
            v.rdata := (others => '0');
163
        when shift_dr =>
164
            v.tms := '0';
165
            v.rdata := i_tdi & r.rdata(DATA_WIDTH-1 downto 1);
166
            v.op_cnt := r.op_cnt + 1;
167
            if r.op_cnt = r.shift_length then
168
                v.tms := '1';
169
                v.jtagstate := exit1_dr;
170
            end if;
171
        when exit1_dr =>
172
            v.tms := '1';
173
            v.rdata := i_tdi & r.rdata(DATA_WIDTH-1 downto 1);
174
            v.jtagstate := update_dr;
175
        when update_dr =>
176
            -- TODO: and size == size_bulk
177
            if r.instr = 2 then
178
                if r.burst_cnt = 0 then
179
                    v.tms := '0';
180
                    v.jtagstate := run_idle;
181
                else
182
                    v.tms := '1';
183
                    v.jtagstate := start_ir;
184
                    v.burst_cnt := r.burst_cnt - 1;
185
                    if r.burst_cnt = 1 then
186
                        v.shift_reg2(32) := '0'; -- bulk=0
187
                    end if;
188
                end if;
189
            else
190
                v.tms := '1';
191
                v.instr := 2;
192
                v.jtagstate := start_ir;
193
            end if;
194
        when others =>
195
        end case;
196
 
197
 
198
        if r.jtagstatez = shift_ir or r.jtagstatez = shift_dr then
199
            v.shift_reg := '0' & r.shift_reg(SHIFT_LEN-1 downto 1);
200
        end if;
201
     end if;
202
 
203
     -- Reset
204
     if rst = '1' then
205
        v.jtagstate := test_rst;
206
        v.jtagstatez := test_rst;
207
        v.clk_rate_cnt := 0;
208
        v.op_cnt := 0;
209
        v.is_data := '0';
210
        v.shift_reg1 := (others => '0');
211
        v.shift_reg2 := (others => '0');
212
        v.shift_reg := (others => '0');
213
        v.burst_cnt := 0;
214
        v.edge := '0';
215
        v.ntrst := '0';
216
        v.tms := '0';
217
     end if;
218
 
219
     rin <= v;
220
   end process;
221
 
222
   o_tdo <= r.shift_reg(0);
223
   o_tck <= r.edge;
224
   o_tms <= r.tms;
225
   o_ntrst <= r.ntrst;
226
 
227
 
228
  procCheck : process (clk)
229
  begin
230
    if rising_edge(clk) then
231
        r <= rin;
232
    end if;
233
  end process;
234
 
235
end;

powered by: WebSVN 2.1.0

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