/* * xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB * * Copyright (C) 2011 RIEGL Research ForschungsGmbH * Copyright (C) 2011 Clifford Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ module top( clk, tck, tms, tdi, tdo, init, init_b, fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7, ctl0, ctl1, ctl2, pc0, pc1, pc2, pc3, pc4, pc5, pc6, pc7, pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7 ); // General Signal input clk; // JTAG Interface output tck, tms, tdi, init; input tdo, init_b; // GPIF Interface input fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7; input ctl0, ctl1, ctl2; // The entire PC and PD regs for various flags output pc0, pc1, pc2, pc3, pc4, pc5, pc6, pc7; input pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7; // simple direct i/o mappings assign pc3 = tdo; assign pc1 = init_b; assign init = pd2; // checksum wire chksum_rst, chksum_clk; reg [23:0] chksum_buffer; always @(posedge chksum_clk) begin if (chksum_rst) chksum_buffer <= `include "hardware_cksum_vl.inc" ; else chksum_buffer <= chksum_buffer << 1; end assign chksum_rst = pd0; assign chksum_clk = pd1; assign pc2 = chksum_buffer[23]; // main engine reg [3:0] sync; reg [7:0] lastbyte; reg go_exec0, go_exec1, set_sync, err; reg reg_tck, reg_tms, reg_tdi, reg_tdo, reg_tdo_en; always @(negedge clk) begin go_exec0 <= 0; go_exec1 <= 0; if (!ctl0) begin lastbyte <= { fd7, fd6, fd5, fd4, fd3, fd2, fd1, fd0 }; go_exec0 <= 1; end if (!ctl1) begin lastbyte <= lastbyte >> 4; go_exec0 <= 1; end if (!ctl2) begin go_exec1 <= 1; end if (go_exec0) begin reg_tdo_en <= 0; if (set_sync) begin sync <= lastbyte[3:0]; set_sync <= 0; end else if (lastbyte[3:0] == 0) begin /* NOP */ end else if (lastbyte[3:0] == 1) begin /* Set sync signal in next insn */ set_sync <= 1; end else if (lastbyte[3:1] == 1) begin /* reserved */ end else if (lastbyte[3:2] == 1) begin /* transaction with or without TDO check */ reg_tck <= 0; reg_tdo <= 'bx; reg_tms <= lastbyte[1]; reg_tdi <= lastbyte[0]; end else if (lastbyte[3] == 1) begin /* transaction with TDO check */ reg_tck <= 0; reg_tdo <= lastbyte[2]; reg_tms <= lastbyte[1]; reg_tdi <= lastbyte[0]; reg_tdo_en <= 1; end end if (go_exec1) begin reg_tck <= 1; if (reg_tdo_en && tdo != reg_tdo) err <= 1; end if (pd3) begin /* RESET ERR */ err <= 0; end if (pd4) begin /* RESET SYNC */ set_sync <= 0; sync <= 0; end end assign tck = reg_tck; assign tms = reg_tms; assign tdi = reg_tdi; assign pc7 = sync[3]; assign pc6 = sync[2]; assign pc5 = sync[1]; assign pc4 = sync[0]; assign pc0 = err; endmodule