335 lines
11 KiB
Verilog
335 lines
11 KiB
Verilog
`default_nettype none
|
|
module spiOverJtag
|
|
(
|
|
`ifndef xilinxultrascale
|
|
output wire csn,
|
|
|
|
`ifdef spartan6
|
|
output wire sck,
|
|
`endif
|
|
`ifdef spartan3e
|
|
output wire sck,
|
|
`endif
|
|
`ifdef virtex6
|
|
output wire sdi_dq0
|
|
`else
|
|
output wire sdi_dq0,
|
|
input wire sdo_dq1,
|
|
output wire wpn_dq2,
|
|
output wire hldn_dq3
|
|
`endif
|
|
`endif // xilinxultrascale
|
|
|
|
`ifdef secondaryflash
|
|
output wire sdi_sec_dq0,
|
|
input wire sdo_sec_dq1,
|
|
output wire wpn_sec_dq2,
|
|
output wire hldn_sec_dq3,
|
|
output wire csn_sec
|
|
`endif // secondaryflash
|
|
);
|
|
|
|
wire capture, drck, sel, update, shift;
|
|
wire tdi, tdo;
|
|
|
|
`ifndef spartan3e
|
|
`ifndef virtex6
|
|
/* Version Interface. */
|
|
wire ver_sel, ver_cap, ver_shift, ver_drck, ver_tdi, ver_tdo;
|
|
wire spi_clk;
|
|
|
|
spiOverJtag_core spiOverJtag_core_prim (
|
|
/* JTAG state/controls */
|
|
.sel(sel),
|
|
.capture(capture),
|
|
.update(update),
|
|
.shift(shift),
|
|
.drck(drck),
|
|
.tdi(tdi),
|
|
.tdo(tdo),
|
|
|
|
/* JTAG endpoint to version */
|
|
.ver_sel(ver_sel),
|
|
.ver_cap(ver_cap),
|
|
.ver_shift(ver_shift),
|
|
.ver_drck(ver_drck),
|
|
.ver_tdi(ver_tdi),
|
|
.ver_tdo(ver_tdo),
|
|
|
|
/* phys */
|
|
.csn(csn),
|
|
.sck(spi_clk),
|
|
.sdi_dq0(sdi_dq0),
|
|
.sdo_dq1(sdo_dq1),
|
|
.wpn_dq2(wpn_dq2),
|
|
.hldn_dq3(hldn_dq3)
|
|
);
|
|
`endif /* !virtex6 */
|
|
`endif /* !spartan3e */
|
|
|
|
`ifdef spartan6
|
|
assign sck = spi_clk;
|
|
`else // !spartan6
|
|
`ifdef spartan3e
|
|
assign sck = drck;
|
|
`else // !spartan6 && !spartan3e
|
|
`ifdef xilinxultrascale
|
|
assign sck = drck;
|
|
wire [3:0] di;
|
|
assign sdo_dq1 = di[1];
|
|
wire [3:0] do = {hldn_dq3, wpn_dq2, 1'b0, sdi_dq0};
|
|
wire [3:0] dts = 4'b0010;
|
|
// secondary BSCANE3 signals
|
|
wire sel_sec, spi_clk_sec;
|
|
|
|
wire sck = (sel_sec) ? spi_clk_sec : spi_clk;
|
|
|
|
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 virtex6 // !spartan6 && !spartan3e && !xilinxultrascale
|
|
wire di;
|
|
|
|
wire runtest;
|
|
reg fsm_csn;
|
|
// jtag -> spi flash
|
|
assign sdi_dq0 = tdi;
|
|
assign tdo = (sel) ? di : tdi;
|
|
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
|
|
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 // !spartan6 && !spartan3e && !xilinxultrascale && !virtex6
|
|
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 (spi_clk), // 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
|
|
`endif
|
|
`endif
|
|
|
|
`ifdef spartan3e
|
|
wire runtest;
|
|
reg fsm_csn;
|
|
assign wpn_dq2 = 1'b1;
|
|
assign hldn_dq3 = 1'b1;
|
|
// jtag -> spi flash
|
|
assign sdi_dq0 = tdi;
|
|
assign tdo = (sel) ? sdo_dq1 : tdi;
|
|
assign csn = fsm_csn;
|
|
|
|
wire tmp_cap_s = capture && sel;
|
|
wire tmp_up_s = update && sel;
|
|
assign runtest = tmp_up_s;
|
|
|
|
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
|
|
|
|
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.
|
|
`ifdef virtex6
|
|
.RUNTEST(runtest),
|
|
`else
|
|
.RUNTEST(), // 1-bit output: Output asserted when TAP
|
|
// controller is in Run Test/Idle state.
|
|
`endif
|
|
.SEL (sel), // 1-bit output: USER instruction active output.
|
|
.SHIFT (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.
|
|
);
|
|
|
|
/* BSCAN for Version Interface. */
|
|
`ifndef virtex6
|
|
`ifdef spartan6
|
|
BSCAN_SPARTAN6 #(
|
|
`else
|
|
BSCANE2 #(
|
|
`endif
|
|
.JTAG_CHAIN(4) // Value for USER command.
|
|
) bscane2_version (
|
|
.CAPTURE(ver_cap),
|
|
.DRCK (ver_drck),
|
|
.RESET (),
|
|
.RUNTEST(),
|
|
.SEL (ver_sel),
|
|
.SHIFT (ver_shift),
|
|
.TCK (),
|
|
.TDI (ver_tdi),
|
|
.TMS (),
|
|
.UPDATE (),
|
|
.TDO (ver_tdo)
|
|
);
|
|
`endif
|
|
`endif /* !virtex6 */
|
|
|
|
`ifdef secondaryflash
|
|
wire drck_sec;
|
|
|
|
spiOverJtag_core spiOverJtag_core_sec (
|
|
/* JTAG state/controls */
|
|
.sel(sel_sec),
|
|
.capture(capture),
|
|
.update(update),
|
|
.shift(shift),
|
|
.drck(drck_sec),
|
|
.tdi(tdi),
|
|
.tdo(tdo_sec),
|
|
|
|
/* JTAG endpoint to version (Unused) */
|
|
.ver_sel(1'b0),
|
|
.ver_cap(1'b0),
|
|
.ver_shift(1'b0),
|
|
.ver_drck(1'b0),
|
|
.ver_tdi(1'b0),
|
|
.ver_tdo(),
|
|
|
|
/* phys */
|
|
.csn(csn_sec),
|
|
.sck(spi_clk_sec),
|
|
.sdi_dq0(sdi_sec_dq0),
|
|
.sdo_dq1(sdo_sec_dq1),
|
|
.wpn_dq2(wpn_sec_dq2),
|
|
.hldn_dq3(hldn_sec_dq3)
|
|
);
|
|
|
|
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
|