zynq-sandbox

old FPGA projects for ZYNQ
git clone http://frotz.net/git/zynq-sandbox.git
Log | Files | Refs | README

jtag_debug_port.sv (3943B)


      1 // Copyright 2014 Brian Swetland <swetland@frotz.net>
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      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 `timescale 1ns / 1ps
     16 
     17 /* Exposes a 36bit register on JTAG USER4:
     18  *
     19  * 35                                  0
     20  *  CAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
     21  *  |  |                               |
     22  *  |  addr                         data
     23  *  commit 
     24  *
     25  * - on JTAG UPDATE
     26  *   - if commit bit is set:
     27  *     bits 34:32 are presented on o_addr, 
     28  *     31:0 are presented on o_wdata,
     29  *     and o_wr is strobed
     30  *   - otherwise bits 34:32 are presented on o_addr,
     31  *     o_rd is strobed, and i_rdata is captured on the next clock
     32  *
     33  *  - to write a register via JTAG:
     34  *    - shift in {1, addr, data}, UPDATE
     35  *
     36  *  - to read a register via JTAG:
     37  *    - shift in {0, addr, dontcare}, UPDATE
     38  *    - data will be returned on next read or write
     39  * 
     40  *  - data read back via JTAG will be {1, addr, data}
     41  *    - addr is the last address read or written
     42  *    - data is the data that was read or written
     43  *    - high bit is one
     44  */
     45 
     46 module jtag_debug_port(
     47 	output reg o_rd,
     48 	output reg o_wr,
     49 	output [RBITS-1:0]o_addr,
     50 	output [31:0]o_wdata,
     51 	input [31:0]i_rdata,
     52 	input clk
     53 	);
     54 
     55 parameter RBITS = 3;
     56 
     57 wire capture, sel, shift;
     58 wire tck, tdi, update;
     59 
     60 reg [RBITS+32:0]data_sr;      // JTAG shift register
     61 reg [RBITS+32:0]data_to_jtag; // captured on CAPTURE by sr
     62 reg [RBITS+32:0]data_to_port; // captured on UPDATE from sr
     63 reg [RBITS+32:0]data_to_jtag_next;
     64 reg [RBITS+32:0]data_to_port_next;
     65 reg o_rd_next;
     66 reg o_wr_next;
     67 
     68 assign o_wdata = data_to_port[31:0];
     69 assign o_addr = data_to_port[RBITS+31:32];
     70 
     71 wire do_txn;
     72 
     73 `ifndef verilator
     74 BSCANE2 #(
     75 	.JTAG_CHAIN(4)
     76 	) bscan (
     77 	.CAPTURE(capture),
     78 	.DRCK(),
     79 	.RESET(),
     80 	.RUNTEST(),
     81 	.SEL(sel),
     82 	.SHIFT(shift),
     83 	.TCK(tck),
     84 	.TDI(tdi),
     85 	.TMS(),
     86 	.UPDATE(update),
     87 	.TDO(data_sr[0])
     88 	);
     89 `endif
     90 
     91 localparam STATE_IDLE = 0;
     92 localparam STATE_READ = 1;
     93 localparam STATE_READ2 = 2;
     94 localparam STATE_WRITE = 3;
     95 
     96 reg [1:0]state = STATE_IDLE;
     97 reg [1:0]state_next;
     98 
     99 always @(*) begin
    100 	state_next = state;
    101 	data_to_port_next = data_to_port;
    102 	data_to_jtag_next = data_to_jtag;
    103 	o_rd_next = 0;
    104 	o_wr_next = 0;
    105 
    106 	case (state)
    107 	STATE_IDLE: begin
    108 		if (do_txn) begin
    109 			data_to_port_next = data_sr;
    110 			if (data_sr[RBITS+32]) begin
    111 				state_next = STATE_WRITE;
    112 				o_wr_next = 1;
    113 			end else begin
    114 				state_next = STATE_READ;
    115 				o_rd_next = 1;
    116 			end
    117 		end
    118 	end
    119 	STATE_READ: begin
    120 		state_next = STATE_READ2;
    121 	end
    122 	STATE_READ2: begin
    123 		state_next = STATE_IDLE;
    124 		data_to_jtag_next = { 1'b1, data_to_port[RBITS+31:32], i_rdata };
    125 	end	
    126 	STATE_WRITE: begin
    127 		state_next = STATE_IDLE;
    128 		data_to_jtag_next = { 1'b1, data_to_port[RBITS+31:0] };
    129 	end
    130 	endcase
    131 end	
    132 
    133 always @(posedge clk) begin
    134 	state <= state_next;
    135 	data_to_port <= data_to_port_next;
    136 	data_to_jtag <= data_to_jtag_next;
    137 	o_rd <= o_rd_next;
    138 	o_wr <= o_wr_next;
    139 end
    140 
    141 wire do_capture = sel & capture;
    142 wire do_update = sel & update;
    143 wire do_shift = sel & shift;
    144 
    145 always @(posedge tck)
    146 	if (do_capture)
    147 		data_sr <= data_to_jtag;
    148 	else if (do_shift)
    149 		data_sr <= { tdi, data_sr[RBITS+32:1] };
    150 
    151 sync s0(
    152 	.clk_in(tck),
    153 	.in(do_update),
    154 	.clk_out(clk),
    155 	.out(do_txn)
    156 	);
    157 
    158 endmodule
    159 
    160 module sync(
    161 	input clk_in,
    162 	input clk_out,
    163 	input in,
    164 	output out
    165 	);
    166 reg toggle = 1'b0;
    167 reg [2:0] sync = 3'b0;
    168 always @(posedge clk_in)
    169 	if (in) toggle <= ~toggle;
    170 always @(posedge clk_out)
    171 	sync <= { sync[1:0], toggle };
    172 assign out = (sync[2] ^ sync[1]);
    173 endmodule