jtag-mpsse

JTAG tools for FTDI MPSSE transports
git clone http://frotz.net/git/jtag-mpsse.git
Log | Files | Refs

debugport.v (2920B)


      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 
     16 `timescale 1ns / 1ps
     17 
     18 /* Exposes a 36bit register on JTAG USER4:
     19  *
     20  * 35                                  0
     21  *  CAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
     22  *  |  |                               |
     23  *  |  addr                         data
     24  *  commit 
     25  *
     26  * - on JTAG UPDATE
     27  *   - if commit bit is set:
     28  *     bits 34:32 are presented on o_addr, 
     29  *     31:0 are presented on o_wdata,
     30  *     and o_wr is strobed
     31  *   - otherwise bits 34:32 are presented on o_addr,
     32  *     o_rd is strobed, and i_rdata is captured
     33  *
     34  *  - to write a register via JTAG:
     35  *    - shift in {1, addr, data}, UPDATE
     36  *
     37  *  - to read a register via JTAG:
     38  *    - shift in {0, addr, dontcare}, UPDATE
     39  *    - data will be returned on next read or write
     40  * 
     41  */
     42 module debugport(
     43 	output o_rd,
     44 	output o_wr,
     45 	output [2:0]o_addr,
     46 	output [31:0]o_wdata,
     47 	input [31:0]i_rdata,
     48 	input clk
     49 	);
     50 
     51 wire capture, sel, shift;
     52 wire tck, tdi, update;
     53 
     54 (* KEEP = "TRUE" *) reg [31:0] io = 32'd0;
     55 (* KEEP = "TRUE" *) reg [35:0] data = 36'd0;
     56 
     57 wire do_txn;
     58 reg do_rd, do_wr;
     59 
     60 assign o_wdata = io;
     61 assign o_wr = do_wr;
     62 
     63 assign o_addr = data[34:32];
     64 assign o_rd = do_txn & (~data[35]);
     65 
     66 `ifndef verilator
     67 BSCANE2 #(
     68 	.JTAG_CHAIN(4)
     69 	) bscan (
     70 	.CAPTURE(capture),
     71 	.DRCK(),
     72 	.RESET(),
     73 	.RUNTEST(),
     74 	.SEL(sel),
     75 	.SHIFT(shift),
     76 	.TCK(tck),
     77 	.TDI(tdi),
     78 	.TMS(),
     79 	.UPDATE(update),
     80 	.TDO(data[0])
     81 	);
     82 `endif
     83 
     84 reg [31:0]io_next;
     85 reg do_wr_next;
     86 reg do_rd_next;
     87 
     88 always @(*) begin
     89 	io_next = io;
     90 	do_wr_next = 1'b0;
     91 	do_rd_next = 1'b0;
     92 	if (do_txn) begin
     93 		io_next = data[31:0];
     94 		if (data[35])
     95 			do_wr_next = 1'b1;
     96 		else
     97 			do_rd_next = 1'b1;
     98 	end else if(do_rd) begin
     99 		io_next = i_rdata;
    100 	end
    101 end
    102 
    103 always @(posedge clk) begin
    104 	io <= io_next;
    105 	do_wr <= do_wr_next;
    106 	do_rd <= do_rd_next;
    107 end
    108 
    109 wire do_capture = sel & capture;
    110 wire do_update = sel & update;
    111 wire do_shift = sel & shift;
    112 
    113 always @(posedge tck)
    114 	if (do_capture)
    115 		data <= { 4'h0, io };
    116 	else if (do_shift)
    117 		data <= { tdi, data[35:1] };
    118 
    119 sync s0(
    120 	.clk_in(tck),
    121 	.in(do_update),
    122 	.clk_out(clk),
    123 	.out(do_txn)
    124 	);
    125 
    126 endmodule
    127 
    128 
    129 module sync(
    130 	input clk_in,
    131 	input clk_out,
    132 	input in,
    133 	output out
    134 	);
    135 reg toggle = 1'b0;
    136 reg [2:0] sync = 3'b0;
    137 always @(posedge clk_in)
    138 	if (in) toggle <= ~toggle;
    139 always @(posedge clk_out)
    140 	sync <= { sync[1:0], toggle };
    141 assign out = (sync[2] ^ sync[1]);
    142 endmodule