URL
https://opencores.org/ocsvn/s80186/s80186/trunk
Subversion Repositories s80186
[/] [s80186/] [trunk/] [fpga/] [common/] [JTAGBridge.sv] - Rev 2
Compare with Previous | Blame | View Log
// Copyright Jamie Iles, 2017//// This file is part of s80x86.//// s80x86 is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// s80x86 is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with s80x86. If not, see <http://www.gnu.org/licenses/>.module JTAGBridge(input logic tck,input logic cpu_clk,input logic reset,input logic [1:0] ir,output logic tdo,input logic tdi,input logic sdr,input logic cdr,input logic udr,input logic debug_stopped,output logic debug_seize,output logic debug_reset,output logic debug_run,output logic [7:0] debug_addr,output logic [15:0] debug_wr_val,input logic [15:0] debug_val,output logic debug_wr_en);typedef enum bit [1:0] {IDCODE,STATUS_CONTROL,VALUE,RUN_PROCEDURE} DEBUG_REG_t;reg bypass;reg [31:0] idcode_reg;reg status_control_reg_wr_en;reg [15:0] status_control_reg;reg [16:0] value_reg;wire value_reg_wr_en = value_reg[16];reg [15:0] shadow_value_reg;reg [7:0] run_procedure_reg;reg jtag_seize = 1'b0;reg jtag_reset = 1'b0;reg jtag_update_value = 1'b0;reg jtag_run_prodedure = 1'b0;reg jtag_debug_busy = 1'b0;wire [15:0] shadow_value_wr_val;wire jtag_update_debug_val;wire jtag_debug_stopped;reg debug_running = 1'b0;reg debug_complete_load = 1'b0;wire debug_val_ready;assign tdo = sdr && ir == IDCODE ? idcode_reg[0] :sdr && ir == STATUS_CONTROL ? status_control_reg[0] :sdr && ir == VALUE ? value_reg[0] :sdr && ir == RUN_PROCEDURE ? 1'b0 : bypass;BitSync StoppedSync(.clk(tck),.d(debug_stopped),.q(jtag_debug_stopped));BitSync SeizeSync(.clk(cpu_clk),.d(jtag_seize),.q(debug_seize));BitSync JTAGResetSync(.clk(cpu_clk),.d(jtag_reset),.q(debug_reset));// Debug write value, JTAG -> CPUMCP #(.width(16),.reset_val(16'b0))DebugValueMCP(.reset(reset),.clk_a(tck),.a_ready(),.a_send(jtag_update_value),.a_datain(value_reg[15:0]),.clk_b(cpu_clk),.b_data(debug_wr_val),.b_load(debug_wr_en));// Debug read value, CPU -> JTAGMCP #(.width(16),.reset_val(16'b0))DebugReadValueMCP(.reset(reset),.clk_a(cpu_clk),.a_ready(debug_val_ready),.a_send(debug_complete_load),.a_datain(debug_val),.clk_b(tck),.b_data(shadow_value_wr_val),.b_load(jtag_update_debug_val));// Debug procedure run, JTAG -> CPUMCP #(.width(8),.reset_val(8'b0))DebugProcMCP(.reset(reset),.clk_a(tck),.a_ready(),.a_send(jtag_run_prodedure),.a_datain(run_procedure_reg),.clk_b(cpu_clk),.b_data(debug_addr),.b_load(debug_run));// Generate debug value load signals from CPU into JTAG domainalways_ff @(posedge cpu_clk or posedge reset)if (reset) begindebug_running <= 1'b0;end else beginif (debug_run)debug_running <= 1'b1;else if (debug_running && debug_stopped && debug_val_ready)debug_running <= 1'b0;endalways_ff @(posedge cpu_clk)debug_complete_load <= debug_running && debug_stopped && debug_val_ready;always_ff @(posedge tck)if (ir == IDCODE) beginif (cdr)idcode_reg <= 32'h53454c49;else if (sdr)idcode_reg <= {tdi, idcode_reg[31:1]};endalways_ff @(posedge tck)if (ir == STATUS_CONTROL) beginif (cdr)status_control_reg <= {14'b0, debug_reset, ~jtag_debug_stopped};else if (sdr){status_control_reg_wr_en, status_control_reg} <={tdi, status_control_reg_wr_en, status_control_reg[15:1]};else if (udr)status_control_reg_wr_en <= 1'b0;endalways_ff @(posedge tck)if (ir == VALUE) beginif (cdr)value_reg <= {~jtag_debug_busy, shadow_value_reg};else if (sdr)value_reg <= {tdi, value_reg[16:1]};else if (udr)value_reg[16] <= 1'b0;endalways_ff @(posedge tck)if (ir == RUN_PROCEDURE && sdr)run_procedure_reg <= {tdi, run_procedure_reg[7:1]};always_ff @(posedge tck)bypass <= tdi;always_ff @(posedge tck)if (jtag_update_debug_val)shadow_value_reg <= shadow_value_wr_val;always_ff @(posedge tck)if (jtag_update_debug_val)jtag_debug_busy <= 1'b0;elsejtag_debug_busy <= (ir == RUN_PROCEDURE) && udr;always_ff @(posedge tck)if (ir == STATUS_CONTROL && udr && status_control_reg_wr_en) beginjtag_seize <= ~status_control_reg[0];jtag_reset <= status_control_reg[1];endalways_ff @(posedge tck)jtag_run_prodedure <= (ir == RUN_PROCEDURE) && udr;always_ff @(posedge tck)jtag_update_value <= (ir == VALUE) && udr && value_reg_wr_en;endmodule
