module spiOverJtag ( `ifdef spartan6 output sck, output csn, output sdi_dq0, input sdo_dq1, output wpn_dq2, output hldn_dq3 `define QSPI `elsif spartan3e output sck, output csn, output sdi_dq0, input sdo_dq1 `elsif virtex6 output csn, output sdi_dq0 `elsif xilinxultrascale `else // Xilinx 7 but not ultrascale output csn, output sdi_dq0, input sdo_dq1, output wpn_dq2, output hldn_dq3 `define QSPI `endif `ifdef secondaryflash output sdi_sec_dq0, input sdo_sec_dq1, output wpn_sec_dq2, output hldn_sec_dq3, output csn_sec `endif // secondaryflash ); wire capture, drck, sel, update; wire runtest; wire tdi; reg fsm_csn; `ifdef QSPI assign wpn_dq2 = 1'b1; assign hldn_dq3 = 1'b1; `endif // jtag -> spi flash assign sdi_dq0 = tdi; `ifdef virtex6 wire di; wire tdo = (sel) ? di : tdi; `else wire tdo = (sel) ? sdo_dq1 : tdi; `endif assign csn = fsm_csn; wire tmp_cap_s = capture && sel; wire tmp_up_s = update && sel; always @(posedge drck, posedge runtest) begin if (runtest) begin fsm_csn <= 1'b1; end else begin if (tmp_cap_s) begin fsm_csn <= 1'b0; end else if (tmp_up_s) begin fsm_csn <= 1'b1; end else begin fsm_csn <= fsm_csn; end end end `ifdef xilinxultrascale wire [3:0] di; assign wpn_dq2 = 1'b1; assign hldn_dq3 = 1'b1; assign sdo_dq1 = di[1]; wire [3:0] do = {hldn_dq3, wpn_dq2, 1'b0, sdi_dq0}; wire [3:0] dts = 4'b0010; STARTUPE3 #( .PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams. .SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency (ns) for simulation. ) startupe3_inst ( .CFGCLK (), // 1-bit output: Configuration main clock output. .CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output. .DI (di), // 4-bit output: Allow receiving on the D input pin. .EOS (), // 1-bit output: Active-High output signal indicating the End Of Startup. .PREQ (), // 1-bit output: PROGRAM request to fabric output. .DO (do), // 4-bit input: Allows control of the D pin output. .DTS (dts), // 4-bit input: Allows tristate of the D pin. .FCSBO (csn), // 1-bit input: Controls the FCS_B pin for flash access. .FCSBTS (1'b0), // 1-bit input: Tristate the FCS_B pin. .GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port). .GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name). .KEYCLEARB(1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM). .PACK (1'b0), // 1-bit input: PROGRAM acknowledge input. .USRCCLKO (sck), // 1-bit input: User CCLK input. .USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input. .USRDONEO (1'b1), // 1-bit input: User DONE pin output control. .USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output. ); `elsif spartan3e assign sck = drck; assign runtest = tmp_up_s; `elsif spartan6 assign sck = drck; `elsif virtex6 STARTUP_VIRTEX6 #( .PROG_USR("FALSE") ) startup_virtex6_inst ( .CFGCLK(), // unused .CFGMCLK(), // unused .CLK(1'b0), // unused .DINSPI(di), // data from SPI flash .EOS(), .GSR(1'b0), // unused .GTS(1'b0), // unused .KEYCLEARB(1'b0), // not used .PACK(1'b1), // tied low for 'safe' operations .PREQ(), // unused .TCKSPI(), // echo of CCLK from TCK pin .USRCCLKO (drck), // user FPGA -> CCLK pin .USRCCLKTS(1'b0), // drive CCLK not in high-Z .USRDONEO (1'b1), // why both USRDONE are high? .USRDONETS(1'b1) // ?? ); `else STARTUPE2 #( .PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams. .SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation. ) startupe2_inst ( .CFGCLK (), // 1-bit output: Configuration main clock output .CFGMCLK (), // 1-bit output: Configuration internal oscillator clock output .EOS (), // 1-bit output: Active high output signal indicating the End Of Startup. .PREQ (), // 1-bit output: PROGRAM request to fabric output .CLK (1'b0), // 1-bit input: User start-up clock input .GSR (1'b0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name) .GTS (1'b0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name) .KEYCLEARB(1'b0), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM) .PACK (1'b1), // 1-bit input: PROGRAM acknowledge input .USRCCLKO (drck), // 1-bit input: User CCLK input .USRCCLKTS(1'b0), // 1-bit input: User CCLK 3-state enable input .USRDONEO (1'b1), // 1-bit input: User DONE pin output control .USRDONETS(1'b1) // 1-bit input: User DONE 3-state enable output ); `endif `ifdef spartan3e BSCAN_SPARTAN3 bscane2_inst ( .CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller. .DRCK1 (drck), // 1-bit output: Gated TCK output. When SEL // is asserted, DRCK toggles when // CAPTURE or SHIFT are asserted. .DRCK2 (), // 1-bit output: USER2 function .RESET (), // 1-bit output: Reset output for TAP controller. .SEL1 (sel), // 1-bit output: USER1 instruction active output. .SEL2 (), // 1-bit output: USER2 instruction active output. .SHIFT (), // 1-bit output: SHIFT output from TAP controller. .TDI (tdi), // 1-bit output: Test Data Input (TDI) output // from TAP controller. .UPDATE (update), // 1-bit output: UPDATE output from TAP controller .TDO1 (tdo), // 1-bit input: Test Data Output (TDO) input // for USER1 function. .TDO2 () // 1-bit input: USER2 function ); `else `ifdef virtex6 BSCAN_VIRTEX6 #( `elsif spartan6 BSCAN_SPARTAN6 #( `else BSCANE2 #( `endif .JTAG_CHAIN(1) // Value for USER command. ) bscane2_inst ( .CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller. .DRCK (drck), // 1-bit output: Gated TCK output. When SEL // is asserted, DRCK toggles when // CAPTURE or SHIFT are asserted. .RESET (), // 1-bit output: Reset output for TAP controller. .RUNTEST(runtest), // 1-bit output: Output asserted when TAP // controller is in Run Test/Idle state. .SEL (sel), // 1-bit output: USER instruction active output. .SHIFT (), // 1-bit output: SHIFT output from TAP controller. .TCK (), // 1-bit output: Test Clock output. // Fabric connection to TAP Clock pin. .TDI (tdi), // 1-bit output: Test Data Input (TDI) output // from TAP controller. .TMS (), // 1-bit output: Test Mode Select output. // Fabric connection to TAP. .UPDATE (update), // 1-bit output: UPDATE output from TAP controller .TDO (tdo) // 1-bit input: Test Data Output (TDO) input // for USER function. ); `endif `ifdef secondaryflash reg fsm_csn_sec; wire tdo_sec; // secondary BSCANE3 signals wire sel_sec, drck_sec; wire sck = (sel_sec) ? drck_sec : drck; assign wpn_sec_dq2 = 1'b1; assign hldn_sec_dq3 = 1'b1; assign sdi_sec_dq0 = tdi; assign tdo_sec = (sel_sec) ? sdo_sec_dq1 : tdi; assign csn_sec = fsm_csn_sec; wire tmp_cap_sec_s = capture && sel_sec; wire tmp_up_sec_s = update && sel_sec; always @(posedge drck_sec, posedge runtest) begin if (runtest) begin fsm_csn_sec <= 1'b1; end else begin if (tmp_cap_sec_s) begin fsm_csn_sec <= 1'b0; end else if (tmp_up_sec_s) begin fsm_csn_sec <= 1'b1; end else begin fsm_csn_sec <= fsm_csn_sec; end end end BSCANE2 #( .JTAG_CHAIN(2) // Value for USER command. ) bscane2_sec_inst ( .CAPTURE(), // 1-bit output: CAPTURE output from TAP controller. .DRCK (drck_sec), // 1-bit output: Gated TCK output. When SEL // is asserted, DRCK toggles when // CAPTURE or SHIFT are asserted. .RESET (), // 1-bit output: Reset output for TAP controller. .RUNTEST(), // 1-bit output: Output asserted when TAP // controller is in Run Test/Idle state. .SEL (sel_sec), // 1-bit output: USER instruction active output. .SHIFT (), // 1-bit output: SHIFT output from TAP controller. .TCK (), // 1-bit output: Test Clock output. // Fabric connection to TAP Clock pin. .TDI (), // 1-bit output: Test Data Input (TDI) output // from TAP controller. .TMS (), // 1-bit output: Test Mode Select output. // Fabric connection to TAP. .UPDATE (), // 1-bit output: UPDATE output from TAP controller .TDO (tdo_sec) // 1-bit input: Test Data Output (TDO) input // for USER function. ); `endif // secondaryflash endmodule