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