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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [fpga/] [common/] [JTAGBridge.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see .
17
 
18
module JTAGBridge(input logic tck,
19
                  input logic cpu_clk,
20
                  input logic reset,
21
                  input logic [1:0] ir,
22
                  output logic tdo,
23
                  input logic tdi,
24
                  input logic sdr,
25
                  input logic cdr,
26
                  input logic udr,
27
                  input logic debug_stopped,
28
                  output logic debug_seize,
29
                  output logic debug_reset,
30
                  output logic debug_run,
31
                  output logic [7:0] debug_addr,
32
                  output logic [15:0] debug_wr_val,
33
                  input logic [15:0] debug_val,
34
                  output logic debug_wr_en);
35
 
36
typedef enum bit [1:0] {
37
    IDCODE,
38
    STATUS_CONTROL,
39
    VALUE,
40
    RUN_PROCEDURE
41
} DEBUG_REG_t;
42
 
43
reg bypass;
44
reg [31:0] idcode_reg;
45
reg status_control_reg_wr_en;
46
reg [15:0] status_control_reg;
47
reg [16:0] value_reg;
48
wire value_reg_wr_en = value_reg[16];
49
reg [15:0] shadow_value_reg;
50
reg [7:0] run_procedure_reg;
51
 
52
reg jtag_seize = 1'b0;
53
reg jtag_reset = 1'b0;
54
reg jtag_update_value = 1'b0;
55
reg jtag_run_prodedure = 1'b0;
56
reg jtag_debug_busy = 1'b0;
57
wire [15:0] shadow_value_wr_val;
58
wire jtag_update_debug_val;
59
wire jtag_debug_stopped;
60
 
61
reg debug_running = 1'b0;
62
reg debug_complete_load = 1'b0;
63
wire debug_val_ready;
64
 
65
assign tdo = sdr && ir == IDCODE ? idcode_reg[0] :
66
             sdr && ir == STATUS_CONTROL ? status_control_reg[0] :
67
             sdr && ir == VALUE ? value_reg[0] :
68
             sdr && ir == RUN_PROCEDURE ? 1'b0 : bypass;
69
 
70
BitSync StoppedSync(.clk(tck),
71
                    .d(debug_stopped),
72
                    .q(jtag_debug_stopped));
73
 
74
BitSync SeizeSync(.clk(cpu_clk),
75
                  .d(jtag_seize),
76
                  .q(debug_seize));
77
 
78
BitSync JTAGResetSync(.clk(cpu_clk),
79
                      .d(jtag_reset),
80
                      .q(debug_reset));
81
 
82
// Debug write value, JTAG -> CPU
83
MCP     #(.width(16),
84
          .reset_val(16'b0))
85
        DebugValueMCP(.reset(reset),
86
                      .clk_a(tck),
87
                      .a_ready(),
88
                      .a_send(jtag_update_value),
89
                      .a_datain(value_reg[15:0]),
90
                      .clk_b(cpu_clk),
91
                      .b_data(debug_wr_val),
92
                      .b_load(debug_wr_en));
93
 
94
// Debug read value, CPU -> JTAG
95
MCP     #(.width(16),
96
          .reset_val(16'b0))
97
        DebugReadValueMCP(.reset(reset),
98
                          .clk_a(cpu_clk),
99
                          .a_ready(debug_val_ready),
100
                          .a_send(debug_complete_load),
101
                          .a_datain(debug_val),
102
                          .clk_b(tck),
103
                          .b_data(shadow_value_wr_val),
104
                          .b_load(jtag_update_debug_val));
105
 
106
// Debug procedure run, JTAG -> CPU
107
MCP     #(.width(8),
108
          .reset_val(8'b0))
109
        DebugProcMCP(.reset(reset),
110
                     .clk_a(tck),
111
                     .a_ready(),
112
                     .a_send(jtag_run_prodedure),
113
                     .a_datain(run_procedure_reg),
114
                     .clk_b(cpu_clk),
115
                     .b_data(debug_addr),
116
                     .b_load(debug_run));
117
 
118
// Generate debug value load signals from CPU into JTAG domain
119
always_ff @(posedge cpu_clk or posedge reset)
120
    if (reset) begin
121
        debug_running <= 1'b0;
122
    end else begin
123
        if (debug_run)
124
            debug_running <= 1'b1;
125
        else if (debug_running && debug_stopped && debug_val_ready)
126
            debug_running <= 1'b0;
127
    end
128
 
129
always_ff @(posedge cpu_clk)
130
    debug_complete_load <= debug_running && debug_stopped && debug_val_ready;
131
 
132
always_ff @(posedge tck)
133
    if (ir == IDCODE) begin
134
        if (cdr)
135
            idcode_reg <= 32'h53454c49;
136
        else if (sdr)
137
            idcode_reg <= {tdi, idcode_reg[31:1]};
138
    end
139
 
140
always_ff @(posedge tck)
141
    if (ir == STATUS_CONTROL) begin
142
        if (cdr)
143
            status_control_reg <= {14'b0, debug_reset, ~jtag_debug_stopped};
144
        else if (sdr)
145
            {status_control_reg_wr_en, status_control_reg} <=
146
                {tdi, status_control_reg_wr_en, status_control_reg[15:1]};
147
        else if (udr)
148
            status_control_reg_wr_en <= 1'b0;
149
    end
150
 
151
always_ff @(posedge tck)
152
    if (ir == VALUE) begin
153
        if (cdr)
154
            value_reg <= {~jtag_debug_busy, shadow_value_reg};
155
        else if (sdr)
156
            value_reg <= {tdi, value_reg[16:1]};
157
        else if (udr)
158
            value_reg[16] <= 1'b0;
159
    end
160
 
161
always_ff @(posedge tck)
162
    if (ir == RUN_PROCEDURE && sdr)
163
        run_procedure_reg <= {tdi, run_procedure_reg[7:1]};
164
 
165
always_ff @(posedge tck)
166
    bypass <= tdi;
167
 
168
always_ff @(posedge tck)
169
    if (jtag_update_debug_val)
170
        shadow_value_reg <= shadow_value_wr_val;
171
 
172
always_ff @(posedge tck)
173
    if (jtag_update_debug_val)
174
        jtag_debug_busy <= 1'b0;
175
    else
176
        jtag_debug_busy <= (ir == RUN_PROCEDURE) && udr;
177
 
178
always_ff @(posedge tck)
179
    if (ir == STATUS_CONTROL && udr && status_control_reg_wr_en) begin
180
        jtag_seize <= ~status_control_reg[0];
181
        jtag_reset <= status_control_reg[1];
182
    end
183
 
184
always_ff @(posedge tck)
185
    jtag_run_prodedure <= (ir == RUN_PROCEDURE) && udr;
186
 
187
always_ff @(posedge tck)
188
    jtag_update_value <= (ir == VALUE) && udr && value_reg_wr_en;
189
 
190
endmodule

powered by: WebSVN 2.1.0

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