7
mirror of https://github.com/EEVengers/ThunderScope.git synced 2025-04-04 21:36:55 +00:00

Moved XDMA to Archive Repo, Added Build Scripts

This commit is contained in:
Aleksa Bjelogrlic 2024-10-18 15:21:40 -04:00
parent f90583f3d8
commit 74dcc5fc30
228 changed files with 59 additions and 2294182 deletions
Firmware
LiteX
XDMA
README.md
bd
cfg
hdl
multiboot_address_table
output
src_proc.tcl
utils
xci
xdc
xdma_gen.tcl
install_openFPGAloader.sh
Software
TS.NETbuild_libtslitex.shbuild_ngscopeclient.shbuild_ts_net.shinstall_ts_litex_driver.sh
libthunderscope
scopehal-apps
xdma_driver_linux
xdma_driver_win_src_2018_2

Submodule Firmware/LiteX deleted from 0fd27d5b48

View File

@ -1,22 +0,0 @@
# XDMA
## Build
In this directory with Vivado tcl console, run `source src_proc.tcl`
Then run `src ./xdma_gen.tcl <target> <threads>`
* Targets (Default is 200t)
* `50t`
* `100t`
* `200t`
* Threads (Default is 6) If threads is used, target must be used
* `1`
* `...`
* `16`
## TODO:
* Check SPI clk for Flash write.
* Update MCS file decode.
* look at quad writes and reads for frimware updates.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

View File

@ -1,358 +0,0 @@
`timescale 1 ps / 1 ps
module dso_top
(output [14:0] DDR3_addr,
output [2:0] DDR3_ba,
output DDR3_cas_n,
output [0:0] DDR3_ck_n,
output [0:0] DDR3_ck_p,
output [0:0] DDR3_cke,
output [0:0] DDR3_cs_n,
output [3:0] DDR3_dm,
inout [31:0] DDR3_dq,
inout [3:0] DDR3_dqs_n,
inout [3:0] DDR3_dqs_p,
output [0:0] DDR3_odt,
output DDR3_ras_n,
output DDR3_reset_n,
output DDR3_we_n,
input [0:0] pcie_clk_n,
input [0:0] pcie_clk_p,
input [3:0] pcie_mgt_rxn,
input [3:0] pcie_mgt_rxp,
output [3:0] pcie_mgt_txn,
output [3:0] pcie_mgt_txp,
input pcie_perstn,
output led,
output sync,
output [3:0] atten,
output [3:0] dc_cpl,
output [3:0] term,
output i2c_sda,
output i2c_scl,
output spi_sdio,
output spi_sclk,
output [3:0] pga_cs,
output adc_cs,
output acq_en,
output osc_oe,
output fe_en,
output probe_comp,
input adc_lclk_p,
input adc_lclk_n,
input adc_fclk_p,
input adc_fclk_n,
input[7:0] adc_data_p,
input[7:0] adc_data_n,
input Vp_Vn_0_v_n,
input Vp_Vn_0_v_p,
inout qspi_d0,
inout qspi_d1,
inout qspi_d2,
inout qspi_d3,
output qspi_cs,
output eth_rst_n,
input ext_clk_p,
input ext_clk_n
);
wire [31:0]AXI_STR_TXD_0_tdata;
wire AXI_STR_TXD_0_tlast;
wire AXI_STR_TXD_0_tready;
wire AXI_STR_TXD_0_tvalid;
wire S01_ARESETN;
wire [71:0]S_AXIS_S2MM_CMD_tdata;
wire S_AXIS_S2MM_CMD_tready;
wire S_AXIS_S2MM_CMD_tvalid;
wire [127:0]S_AXIS_S2MM_tdata;
wire S_AXIS_S2MM_tready;
wire S_AXIS_S2MM_tvalid;
wire S_AXIS_S2MM_tlast;
wire axi_aclk;
wire axi_aresetn;
wire [31:0]gpio2_io_i;
wire [31:0]gpio2_io_o_0;
wire [31:0]gpio_io_o_0;
wire s2mm_err;
wire s2mm_halt;
wire s2mm_halt_cmplt;
wire s2mm_wr_xfer_cmplt;
wire fe_sda_buf;
wire fe_scl_buf;
wire divclk;
wire[63:0] data_deser;
reg[63:0] adc_data;
wire serdes_ready;
wire spi_rtl_0_io0_i;
wire spi_rtl_0_io0_io;
wire spi_rtl_0_io0_o;
wire spi_rtl_0_io0_t;
wire spi_rtl_0_io1_i;
wire spi_rtl_0_io1_io;
wire spi_rtl_0_io1_o;
wire spi_rtl_0_io1_t;
wire spi_rtl_0_io2_i;
wire spi_rtl_0_io2_io;
wire spi_rtl_0_io2_o;
wire spi_rtl_0_io2_t;
wire spi_rtl_0_io3_i;
wire spi_rtl_0_io3_io;
wire spi_rtl_0_io3_o;
wire spi_rtl_0_io3_t;
wire ss_o_0;
wire init_calib_complete_0;
assign eth_rst_n = 0;
assign term = gpio_io_o_0[15:12];
assign atten = gpio_io_o_0[19:16];
assign dc_cpl = ~gpio_io_o_0[23:20];
assign led = ~(serdes_ready & init_calib_complete_0);
//assign sync = S01_ARESETN;
assign acq_en = gpio_io_o_0[24];
assign osc_oe = gpio_io_o_0[25];
assign fe_en = gpio_io_o_0[26];
assign i2c_sda = (i2c_sda_buf) ? (1'bz) : (1'b0);
assign i2c_scl = (i2c_scl_buf) ? (1'bz) : (1'b0);
assign qspi_cs = (ss_o_0) ? (1'bz) : (1'b0);
reg[15:0] sync_counter;
reg sync_clk = 1'b0;
always @ (posedge divclk) begin
if (sync_counter==16'h1869) begin //devide 125MHz clk by 6250 per each period of 10kHz clock
sync_counter <= 16'h0000;
sync_clk <= ~sync_clk;
end
else
sync_counter <= sync_counter + 1'b1;
end
assign sync = sync_clk;
reg[15:0] probe_div_counter;
reg probe_div_clk = 1'b0;
always @ (posedge axi_aclk) begin
if (probe_div_counter==16'h1869) begin //devide 125MHz clk by 6250 per each period of 10kHz clock
probe_div_counter <= 16'h0000;
probe_div_clk <= ~probe_div_clk;
end
else
probe_div_counter <= probe_div_counter + 1'b1;
end
assign probe_comp = probe_div_clk;
reg[63:0] twos_comp;
always @(*) begin
twos_comp[63:56] <= {data_deser[63],~data_deser[62:56]};
twos_comp[55:48] <= {data_deser[55],~data_deser[54:48]};
twos_comp[47:40] <= {data_deser[47],~data_deser[46:40]};
twos_comp[39:32] <= {data_deser[39],~data_deser[38:32]};
twos_comp[31:24] <= {data_deser[31],~data_deser[30:24]};
twos_comp[23:16] <= {~data_deser[23],data_deser[22:16]};
twos_comp[15:8] <= {data_deser[15],~data_deser[14:8]};
twos_comp[7:0] <= {data_deser[7],~data_deser[6:0]};
end
wire[1:0] channel_mux;
reg [2:0] channel_mux_cdc_0;
reg [2:0] channel_mux_cdc_1;
always @(posedge divclk) begin
channel_mux_cdc_0 <= { channel_mux_cdc_0[1:0], gpio_io_o_0[4] };
channel_mux_cdc_1 <= { channel_mux_cdc_1[1:0], gpio_io_o_0[5] };
end
assign channel_mux = {channel_mux_cdc_1[2],channel_mux_cdc_0[2]};
always @(*)
begin
case(channel_mux)
2'b00: adc_data <= {twos_comp[63:0]};
2'b01: adc_data <= {twos_comp[63:56],twos_comp[31:24],twos_comp[55:48],twos_comp[23:16],twos_comp[47:40],twos_comp[15:8],twos_comp[39:32],twos_comp[7:0]};
2'b10: adc_data <= {twos_comp[63:56],twos_comp[47:40],twos_comp[31:24],twos_comp[15:8],twos_comp[55:48],twos_comp[39:32],twos_comp[23:16],twos_comp[7:0]};
2'b11: adc_data <= {twos_comp[63:56],twos_comp[47:40],twos_comp[31:24],twos_comp[15:8],twos_comp[55:48],twos_comp[39:32],twos_comp[23:16],twos_comp[7:0]};
endcase
end
/*
assign adc_data = data_deser_twos_comp;
assign adc_data = {8'h77,8'h66,8'h55,8'h44,8'h33,8'h22,8'h11,8'h00};
reg[7:0] adc_ramp_counter;
always @(posedge axi_aclk) begin
if (!S01_ARESETN)
adc_ramp_counter <= 0;
else
adc_ramp_counter <= adc_ramp_counter + 1;
end
always @(*) begin
adc_data <= {8{adc_ramp_counter}};
end
*/
wire serdes_rst;
reg [2:0] serdes_rst_cdc = 3'b111;
always @(posedge divclk)
serdes_rst_cdc <= { serdes_rst_cdc[1:0], ~gpio_io_o_0[2] }; //gpio_io_o_0[2] is SERDES RSTn
assign serdes_rst = serdes_rst_cdc[2];
wire ddr_ready;
reg [2:0] ddr_ready_cdc = 3'b000;
always @(posedge divclk)
ddr_ready_cdc <= { ddr_ready_cdc[1:0], init_calib_complete_0};
assign ddr_ready = ddr_ready_cdc[2];
serdes serdes (
.rst (serdes_rst),
.adc_lclk_p (adc_lclk_p),
.adc_lclk_n (adc_lclk_n),
.adc_fclk_p (adc_fclk_p),
.adc_fclk_n (adc_fclk_n),
.adc_data_p (adc_data_p),
.adc_data_n (adc_data_n),
.axi_aclk (axi_aclk),
.divclk (divclk),
.data_deser (data_deser),
.ready (serdes_ready)
);
adc_to_datamover adc_to_datamover (
.axi_aclk(axi_aclk),
.axi_aresetn(axi_aresetn),
.S01_ARESETN(S01_ARESETN),
.axis_cmd_tready(S_AXIS_S2MM_CMD_tready),
.axis_cmd_tdata(S_AXIS_S2MM_CMD_tdata),
.axis_cmd_tvalid(S_AXIS_S2MM_CMD_tvalid),
.axis_data_tready(S_AXIS_S2MM_tready),
.axis_data_tdata(S_AXIS_S2MM_tdata),
.axis_data_tvalid(S_AXIS_S2MM_tvalid),
.axis_data_tlast(S_AXIS_S2MM_tlast),
.adc_data(adc_data),
.adc_divclk(divclk),
.s2mm_err(s2mm_err),
.s2mm_halt(s2mm_halt),
.s2mm_halt_cmplt(s2mm_halt_cmplt),
.s2mm_wr_xfer_cmplt(s2mm_wr_xfer_cmplt),
.gpio_io_o_0(gpio_io_o_0),
.gpio2_io_i(gpio2_io_i),
.gpio2_io_o_0(gpio2_io_o_0),
.serdes_ready (serdes_ready),
.ddr_ready(ddr_ready)
);
serial_controller serial_controller(
.clk(axi_aclk),
.rst(axi_aresetn),
.AXI_STR_TXD_0_tdata(AXI_STR_TXD_0_tdata),
.AXI_STR_TXD_0_tready(AXI_STR_TXD_0_tready),
.AXI_STR_TXD_0_tvalid(AXI_STR_TXD_0_tvalid),
.i2c_sda(i2c_sda_buf),
.i2c_scl(i2c_scl_buf),
.spi_sdio(spi_sdio),
.spi_sclk(spi_sclk),
.pga_cs(pga_cs),
.adc_cs(adc_cs)
);
design_1 design_1_i
(
.AXI_STR_TXD_0_tdata(AXI_STR_TXD_0_tdata),
.AXI_STR_TXD_0_tlast(AXI_STR_TXD_0_tlast),
.AXI_STR_TXD_0_tready(AXI_STR_TXD_0_tready),
.AXI_STR_TXD_0_tvalid(AXI_STR_TXD_0_tvalid),
.DDR3_addr(DDR3_addr),
.DDR3_ba(DDR3_ba),
.DDR3_cas_n(DDR3_cas_n),
.DDR3_ck_n(DDR3_ck_n),
.DDR3_ck_p(DDR3_ck_p),
.DDR3_cke(DDR3_cke),
.DDR3_cs_n(DDR3_cs_n),
.DDR3_dm(DDR3_dm),
.DDR3_dq(DDR3_dq),
.DDR3_dqs_n(DDR3_dqs_n),
.DDR3_dqs_p(DDR3_dqs_p),
.DDR3_odt(DDR3_odt),
.DDR3_ras_n(DDR3_ras_n),
.DDR3_reset_n(DDR3_reset_n),
.DDR3_we_n(DDR3_we_n),
.S01_ARESETN(S01_ARESETN),
.S_AXIS_S2MM_CMD_tdata(S_AXIS_S2MM_CMD_tdata),
.S_AXIS_S2MM_CMD_tready(S_AXIS_S2MM_CMD_tready),
.S_AXIS_S2MM_CMD_tvalid(S_AXIS_S2MM_CMD_tvalid),
.S_AXIS_S2MM_tdata(S_AXIS_S2MM_tdata),
.S_AXIS_S2MM_tkeep(16'hFFFF),
.S_AXIS_S2MM_tready(S_AXIS_S2MM_tready),
.S_AXIS_S2MM_tvalid(S_AXIS_S2MM_tvalid),
.S_AXIS_S2MM_tlast(S_AXIS_S2MM_tlast),
.axi_aclk(axi_aclk),
.axi_aresetn(axi_aresetn),
.gpio2_io_i(gpio2_io_i),
.gpio2_io_o_0(gpio2_io_o_0),
.gpio_io_o_0(gpio_io_o_0),
.pcie_clk_n(pcie_clk_n),
.pcie_clk_p(pcie_clk_p),
.pcie_mgt_rxn(pcie_mgt_rxn),
.pcie_mgt_rxp(pcie_mgt_rxp),
.pcie_mgt_txn(pcie_mgt_txn),
.pcie_mgt_txp(pcie_mgt_txp),
.pcie_perstn(pcie_perstn),
.s2mm_err(s2mm_err),
.s2mm_halt(s2mm_halt),
.s2mm_halt_cmplt(s2mm_halt_cmplt),
.s2mm_wr_xfer_cmplt(s2mm_wr_xfer_cmplt),
.Vp_Vn_0_v_n(Vp_Vn_0_v_n),
.Vp_Vn_0_v_p(Vp_Vn_0_v_p),
.SPI_0_0_io0_i(spi_rtl_0_io0_i),
.SPI_0_0_io0_o(spi_rtl_0_io0_o),
.SPI_0_0_io0_t(spi_rtl_0_io0_t),
.SPI_0_0_io1_i(spi_rtl_0_io1_i),
.SPI_0_0_io1_o(spi_rtl_0_io1_o),
.SPI_0_0_io1_t(spi_rtl_0_io1_t),
.SPI_0_0_io2_i(spi_rtl_0_io2_i),
.SPI_0_0_io2_o(spi_rtl_0_io2_o),
.SPI_0_0_io2_t(spi_rtl_0_io2_t),
.SPI_0_0_io3_i(spi_rtl_0_io3_i),
.SPI_0_0_io3_o(spi_rtl_0_io3_o),
.SPI_0_0_io3_t(spi_rtl_0_io3_t),
.SPI_0_0_ss_t(),
.ss_o_0(ss_o_0),
.init_calib_complete_0(init_calib_complete_0),
.ext_clk_p(ext_clk_p),
.ext_clk_n(ext_clk_n)
);
IOBUF spi_rtl_0_io0_iobuf
(.I(spi_rtl_0_io0_o),
.IO(qspi_d0),
.O(spi_rtl_0_io0_i),
.T(spi_rtl_0_io0_t));
IOBUF spi_rtl_0_io1_iobuf
(.I(spi_rtl_0_io1_o),
.IO(qspi_d1),
.O(spi_rtl_0_io1_i),
.T(spi_rtl_0_io1_t));
IOBUF spi_rtl_0_io2_iobuf
(.I(spi_rtl_0_io2_o),
.IO(qspi_d2),
.O(spi_rtl_0_io2_i),
.T(spi_rtl_0_io2_t));
IOBUF spi_rtl_0_io3_iobuf
(.I(spi_rtl_0_io3_o),
.IO(qspi_d3),
.O(spi_rtl_0_io3_i),
.T(spi_rtl_0_io3_t));
endmodule

View File

@ -1,353 +0,0 @@
`timescale 1 ps / 1 ps
module dso_top
(output [12:0] DDR3_addr,
output [2:0] DDR3_ba,
output DDR3_cas_n,
output [0:0] DDR3_ck_n,
output [0:0] DDR3_ck_p,
output [0:0] DDR3_cke,
output [0:0] DDR3_cs_n,
output [3:0] DDR3_dm,
inout [31:0] DDR3_dq,
inout [3:0] DDR3_dqs_n,
inout [3:0] DDR3_dqs_p,
output [0:0] DDR3_odt,
output DDR3_ras_n,
output DDR3_reset_n,
output DDR3_we_n,
input [0:0] pcie_clk_n,
input [0:0] pcie_clk_p,
input [3:0] pcie_mgt_rxn,
input [3:0] pcie_mgt_rxp,
output [3:0] pcie_mgt_txn,
output [3:0] pcie_mgt_txp,
input pcie_perstn,
output led,
output sync,
output [3:0] atten,
output [3:0] dc_cpl,
output [3:0] term,
output i2c_sda,
output i2c_scl,
output spi_sdio,
output spi_sclk,
output [3:0] pga_cs,
output adc_cs,
output acq_en,
output osc_oe,
output fe_en,
output probe_comp,
input adc_lclk_p,
input adc_lclk_n,
input adc_fclk_p,
input adc_fclk_n,
input[7:0] adc_data_p,
input[7:0] adc_data_n,
input Vp_Vn_0_v_n,
input Vp_Vn_0_v_p,
inout qspi_d0,
inout qspi_d1,
inout qspi_d2,
inout qspi_d3,
output qspi_cs,
input ext_clk
);
wire [31:0]AXI_STR_TXD_0_tdata;
wire AXI_STR_TXD_0_tlast;
wire AXI_STR_TXD_0_tready;
wire AXI_STR_TXD_0_tvalid;
wire S01_ARESETN;
wire [71:0]S_AXIS_S2MM_CMD_tdata;
wire S_AXIS_S2MM_CMD_tready;
wire S_AXIS_S2MM_CMD_tvalid;
wire [127:0]S_AXIS_S2MM_tdata;
wire S_AXIS_S2MM_tready;
wire S_AXIS_S2MM_tvalid;
wire S_AXIS_S2MM_tlast;
wire axi_aclk;
wire axi_aresetn;
wire [31:0]gpio2_io_i;
wire [31:0]gpio_io_o_0;
wire s2mm_err;
wire s2mm_halt;
wire s2mm_halt_cmplt;
wire s2mm_wr_xfer_cmplt;
wire fe_sda_buf;
wire fe_scl_buf;
wire divclk;
wire[63:0] data_deser;
reg[63:0] adc_data;
wire serdes_ready;
wire spi_rtl_0_io0_i;
wire spi_rtl_0_io0_io;
wire spi_rtl_0_io0_o;
wire spi_rtl_0_io0_t;
wire spi_rtl_0_io1_i;
wire spi_rtl_0_io1_io;
wire spi_rtl_0_io1_o;
wire spi_rtl_0_io1_t;
wire spi_rtl_0_io2_i;
wire spi_rtl_0_io2_io;
wire spi_rtl_0_io2_o;
wire spi_rtl_0_io2_t;
wire spi_rtl_0_io3_i;
wire spi_rtl_0_io3_io;
wire spi_rtl_0_io3_o;
wire spi_rtl_0_io3_t;
wire ss_o_0;
wire init_calib_complete_0;
assign term = gpio_io_o_0[15:12];
assign atten = gpio_io_o_0[19:16];
assign dc_cpl = ~gpio_io_o_0[23:20];
assign led = serdes_ready & init_calib_complete_0;
//assign sync = S01_ARESETN;
assign acq_en = gpio_io_o_0[24];
assign osc_oe = gpio_io_o_0[25];
assign fe_en = gpio_io_o_0[26];
assign i2c_sda = (i2c_sda_buf) ? (1'bz) : (1'b0);
assign i2c_scl = (i2c_scl_buf) ? (1'bz) : (1'b0);
assign qspi_cs = (ss_o_0) ? (1'bz) : (1'b0);
reg[15:0] sync_counter;
reg sync_clk = 1'b0;
always @ (posedge divclk) begin
if (sync_counter==16'h1869) begin //devide 125MHz clk by 6250 per each period of 10kHz clock
sync_counter <= 16'h0000;
sync_clk <= ~sync_clk;
end
else
sync_counter <= sync_counter + 1'b1;
end
assign sync = sync_clk;
reg[15:0] probe_div_counter;
reg probe_div_clk = 1'b0;
always @ (posedge axi_aclk) begin
if (probe_div_counter==16'h1869) begin //devide 125MHz clk by 6250 per each period of 10kHz clock
probe_div_counter <= 16'h0000;
probe_div_clk <= ~probe_div_clk;
end
else
probe_div_counter <= probe_div_counter + 1'b1;
end
assign probe_comp = probe_div_clk;
reg[63:0] twos_comp;
always @(*) begin
twos_comp[63:56] <= {data_deser[63],~data_deser[62:56]};
twos_comp[55:48] <= {data_deser[55],~data_deser[54:48]};
twos_comp[47:40] <= {data_deser[47],~data_deser[46:40]};
twos_comp[39:32] <= {~data_deser[39],data_deser[38:32]}; //not inverted
twos_comp[31:24] <= {data_deser[31],~data_deser[30:24]};
twos_comp[23:16] <= {data_deser[23],~data_deser[22:16]};
twos_comp[15:8] <= {~data_deser[15],data_deser[14:8]}; //not inverted
twos_comp[7:0] <= {~data_deser[7],data_deser[6:0]}; //not inverted
end
wire[1:0] channel_mux;
reg [2:0] channel_mux_cdc_0;
reg [2:0] channel_mux_cdc_1;
always @(posedge divclk) begin
channel_mux_cdc_0 <= { channel_mux_cdc_0[1:0], gpio_io_o_0[4] };
channel_mux_cdc_1 <= { channel_mux_cdc_1[1:0], gpio_io_o_0[5] };
end
assign channel_mux = {channel_mux_cdc_1[2],channel_mux_cdc_0[2]};
always @(*)
begin
case(channel_mux)
2'b00: adc_data <= {twos_comp[63:0]};
2'b01: adc_data <= {twos_comp[63:56],twos_comp[31:24],twos_comp[55:48],twos_comp[23:16],twos_comp[47:40],twos_comp[15:8],twos_comp[39:32],twos_comp[7:0]};
2'b10: adc_data <= {twos_comp[63:56],twos_comp[47:40],twos_comp[31:24],twos_comp[15:8],twos_comp[55:48],twos_comp[39:32],twos_comp[23:16],twos_comp[7:0]};
2'b11: adc_data <= {twos_comp[63:56],twos_comp[47:40],twos_comp[31:24],twos_comp[15:8],twos_comp[55:48],twos_comp[39:32],twos_comp[23:16],twos_comp[7:0]};
endcase
end
/*
assign adc_data = data_deser_twos_comp;
assign adc_data = {8'h77,8'h66,8'h55,8'h44,8'h33,8'h22,8'h11,8'h00};
reg[7:0] adc_ramp_counter;
always @(posedge axi_aclk) begin
if (!S01_ARESETN)
adc_ramp_counter <= 0;
else
adc_ramp_counter <= adc_ramp_counter + 1;
end
always @(*) begin
adc_data <= {8{adc_ramp_counter}};
end
*/
wire serdes_rst;
reg [2:0] serdes_rst_cdc = 3'b111;
always @(posedge divclk)
serdes_rst_cdc <= { serdes_rst_cdc[1:0], ~gpio_io_o_0[2] }; //gpio_io_o_0[2] is SERDES RSTn
assign serdes_rst = serdes_rst_cdc[2];
wire ddr_ready;
reg [2:0] ddr_ready_cdc = 3'b000;
always @(posedge divclk)
ddr_ready_cdc <= { ddr_ready_cdc[1:0], init_calib_complete_0};
assign ddr_ready = ddr_ready_cdc[2];
serdes serdes (
.rst (serdes_rst),
.adc_lclk_p (adc_lclk_p),
.adc_lclk_n (adc_lclk_n),
.adc_fclk_p (adc_fclk_p),
.adc_fclk_n (adc_fclk_n),
.adc_data_p (adc_data_p),
.adc_data_n (adc_data_n),
.axi_aclk (axi_aclk),
.divclk (divclk),
.data_deser (data_deser),
.ready (serdes_ready)
);
adc_to_datamover adc_to_datamover (
.axi_aclk(axi_aclk),
.axi_aresetn(axi_aresetn),
.S01_ARESETN(S01_ARESETN),
.axis_cmd_tready(S_AXIS_S2MM_CMD_tready),
.axis_cmd_tdata(S_AXIS_S2MM_CMD_tdata),
.axis_cmd_tvalid(S_AXIS_S2MM_CMD_tvalid),
.axis_data_tready(S_AXIS_S2MM_tready),
.axis_data_tdata(S_AXIS_S2MM_tdata),
.axis_data_tvalid(S_AXIS_S2MM_tvalid),
.axis_data_tlast(S_AXIS_S2MM_tlast),
.adc_data(adc_data),
.adc_divclk(divclk),
.s2mm_err(s2mm_err),
.s2mm_halt(s2mm_halt),
.s2mm_halt_cmplt(s2mm_halt_cmplt),
.s2mm_wr_xfer_cmplt(s2mm_wr_xfer_cmplt),
.gpio_io_o_0(gpio_io_o_0),
.gpio2_io_i(gpio2_io_i),
.gpio2_io_o_0(gpio2_io_o_0),
.serdes_ready (serdes_ready),
.ddr_ready(ddr_ready)
);
serial_controller serial_controller(
.clk(axi_aclk),
.rst(axi_aresetn),
.AXI_STR_TXD_0_tdata(AXI_STR_TXD_0_tdata),
.AXI_STR_TXD_0_tready(AXI_STR_TXD_0_tready),
.AXI_STR_TXD_0_tvalid(AXI_STR_TXD_0_tvalid),
.i2c_sda(i2c_sda_buf),
.i2c_scl(i2c_scl_buf),
.spi_sdio(spi_sdio),
.spi_sclk(spi_sclk),
.pga_cs(pga_cs),
.adc_cs(adc_cs)
);
design_1 design_1_i
(
.AXI_STR_TXD_0_tdata(AXI_STR_TXD_0_tdata),
.AXI_STR_TXD_0_tlast(AXI_STR_TXD_0_tlast),
.AXI_STR_TXD_0_tready(AXI_STR_TXD_0_tready),
.AXI_STR_TXD_0_tvalid(AXI_STR_TXD_0_tvalid),
.DDR3_addr(DDR3_addr),
.DDR3_ba(DDR3_ba),
.DDR3_cas_n(DDR3_cas_n),
.DDR3_ck_n(DDR3_ck_n),
.DDR3_ck_p(DDR3_ck_p),
.DDR3_cke(DDR3_cke),
.DDR3_cs_n(DDR3_cs_n),
.DDR3_dm(DDR3_dm),
.DDR3_dq(DDR3_dq),
.DDR3_dqs_n(DDR3_dqs_n),
.DDR3_dqs_p(DDR3_dqs_p),
.DDR3_odt(DDR3_odt),
.DDR3_ras_n(DDR3_ras_n),
.DDR3_reset_n(DDR3_reset_n),
.DDR3_we_n(DDR3_we_n),
.S01_ARESETN(S01_ARESETN),
.S_AXIS_S2MM_CMD_tdata(S_AXIS_S2MM_CMD_tdata),
.S_AXIS_S2MM_CMD_tready(S_AXIS_S2MM_CMD_tready),
.S_AXIS_S2MM_CMD_tvalid(S_AXIS_S2MM_CMD_tvalid),
.S_AXIS_S2MM_tdata(S_AXIS_S2MM_tdata),
.S_AXIS_S2MM_tkeep(16'hFFFF),
.S_AXIS_S2MM_tready(S_AXIS_S2MM_tready),
.S_AXIS_S2MM_tvalid(S_AXIS_S2MM_tvalid),
.S_AXIS_S2MM_tlast(S_AXIS_S2MM_tlast),
.axi_aclk(axi_aclk),
.axi_aresetn(axi_aresetn),
.gpio2_io_i(gpio2_io_i),
.gpio2_io_o_0(gpio2_io_o_0),
.gpio_io_o_0(gpio_io_o_0),
.pcie_clk_n(pcie_clk_n),
.pcie_clk_p(pcie_clk_p),
.pcie_mgt_rxn(pcie_mgt_rxn),
.pcie_mgt_rxp(pcie_mgt_rxp),
.pcie_mgt_txn(pcie_mgt_txn),
.pcie_mgt_txp(pcie_mgt_txp),
.pcie_perstn(pcie_perstn),
.s2mm_err(s2mm_err),
.s2mm_halt(s2mm_halt),
.s2mm_halt_cmplt(s2mm_halt_cmplt),
.s2mm_wr_xfer_cmplt(s2mm_wr_xfer_cmplt),
.Vp_Vn_0_v_n(Vp_Vn_0_v_n),
.Vp_Vn_0_v_p(Vp_Vn_0_v_p),
.SPI_0_0_io0_i(spi_rtl_0_io0_i),
.SPI_0_0_io0_o(spi_rtl_0_io0_o),
.SPI_0_0_io0_t(spi_rtl_0_io0_t),
.SPI_0_0_io1_i(spi_rtl_0_io1_i),
.SPI_0_0_io1_o(spi_rtl_0_io1_o),
.SPI_0_0_io1_t(spi_rtl_0_io1_t),
.SPI_0_0_io2_i(spi_rtl_0_io2_i),
.SPI_0_0_io2_o(spi_rtl_0_io2_o),
.SPI_0_0_io2_t(spi_rtl_0_io2_t),
.SPI_0_0_io3_i(spi_rtl_0_io3_i),
.SPI_0_0_io3_o(spi_rtl_0_io3_o),
.SPI_0_0_io3_t(spi_rtl_0_io3_t),
.SPI_0_0_ss_t(),
.ss_o_0(ss_o_0),
.init_calib_complete_0(init_calib_complete_0),
.ext_clk(ext_clk)
);
IOBUF spi_rtl_0_io0_iobuf
(.I(spi_rtl_0_io0_o),
.IO(qspi_d0),
.O(spi_rtl_0_io0_i),
.T(spi_rtl_0_io0_t));
IOBUF spi_rtl_0_io1_iobuf
(.I(spi_rtl_0_io1_o),
.IO(qspi_d1),
.O(spi_rtl_0_io1_i),
.T(spi_rtl_0_io1_t));
IOBUF spi_rtl_0_io2_iobuf
(.I(spi_rtl_0_io2_o),
.IO(qspi_d2),
.O(spi_rtl_0_io2_i),
.T(spi_rtl_0_io2_t));
IOBUF spi_rtl_0_io3_iobuf
(.I(spi_rtl_0_io3_o),
.IO(qspi_d3),
.O(spi_rtl_0_io3_i),
.T(spi_rtl_0_io3_t));
endmodule

View File

@ -1,121 +0,0 @@
`timescale 1ns / 1ps
module I2C_Transmit(
input clk,
input [7:0] data,
input data_ready,
input en,
output reg data_req,
output reg sda,
output reg scl,
output reg done
);
parameter[2:0] IDLE = 3'b000,
START = 3'b001,
SEND = 3'b010,
ACK_STOP = 3'b011,
ACK_SEND = 3'b100,
STOP_LOW = 3'b101,
STOP_SCL = 3'b110,
STOP_SDA = 3'b111;
reg[2:0] state = IDLE;
reg[7:0] piso;
reg[4:0] clk_counter; //clk_counter[4:1] is number of bits sent, since 2 clk_stb/bit
reg[7:0] div_counter;
reg clk_stb;
always @ (posedge clk) begin
clk_stb <= 1'b0;
if (div_counter==8'h9B) begin //devide 125MHz clk by 156 to get ~800kHz (801.3kHz) which results in 400kHz I2C
div_counter <= 8'h00;
clk_stb <= 1'b1;
end
else
div_counter <= div_counter + 1'b1;
end
always @ (posedge clk) begin
done <= 1'b0;
case (state)
IDLE:
if (data_ready & en) begin
state <= START;
data_req <= 1'b1;
end
else begin
state <= IDLE;
scl <= 1'b1;
sda <= 1'b1;
end
START:
if (data_req) begin
piso <= data;
data_req <= 1'b0;
end
else if (clk_stb) begin
state <= SEND;
clk_counter <= 5'h00;
sda <= 1'b0;
end
SEND:
if (clk_counter[4] & clk_stb & data_ready & en) begin
state <= ACK_SEND;
data_req <= 1'b1;
scl <= 1'b0;
sda <= 1'b0;
end
else if (clk_counter[4] & clk_stb) begin
state <= ACK_STOP;
sda <= 1'b0;
scl <= 1'b0;
end
else if (clk_stb) begin
state <= SEND;
clk_counter <= clk_counter + 1'b1;
scl <= clk_counter[0];
if (clk_counter[0]==1'b0) begin
piso <= {piso[6:0],1'b0};
sda <= piso[7];
end
end
ACK_STOP:
if (clk_stb) begin
state <= STOP_LOW;
scl <= 1'b1;
end
ACK_SEND:
if (data_req) begin
piso <= data;
data_req <= 1'b0;
end
else if (clk_stb) begin
state <= SEND;
clk_counter <= 5'h00;
scl <= 1'b1;
end
STOP_LOW:
if (clk_stb) begin
state <= STOP_SCL;
sda <= 1'b0;
scl <= 1'b0;
end
STOP_SCL:
if (clk_stb) begin
state <= STOP_SDA;
sda <= 1'b0;
scl <= 1'b1;
end
STOP_SDA:
if (clk_stb) begin
state <= IDLE;
sda <= 1'b1;
scl <= 1'b1;
done <= 1'b1;
end
endcase
end
endmodule

View File

@ -1,87 +0,0 @@
`timescale 1ns / 1ps
module SPI_Transmit(
input clk,
input [7:0] data,
input data_ready,
input en,
output reg data_req,
output reg sdo,
output reg sclk,
output reg cs,
output reg done
);
parameter[1:0] IDLE = 2'b00,
READ = 2'b01,
SEND = 2'b10;
reg[1:0] state = IDLE;
reg[7:0] piso;
reg[5:0] clk_counter; //clk_counter[5:2] is number of bits sent, since 4 clks/bit
reg[3:0] div_counter;
reg clk_stb;
initial cs = 1'b1;
initial sclk = 1'b1;
always @ (posedge clk) begin
clk_stb <= 1'b0;
if (div_counter==4'hF) begin
div_counter <= 4'h0;
clk_stb <= 1'b1;
end
else
div_counter <= div_counter + 1'b1;
end
always @ (posedge clk) begin
done <= 1'b0;
case (state)
IDLE:
if (data_ready & en) begin
state <= READ;
data_req <= 1'b1;
end
else
state <= IDLE;
READ:
if (data_req) begin
piso <= data;
data_req <= 1'b0;
end
else if (clk_stb) begin
state <= SEND;
clk_counter <= 6'h00;
end
SEND:
if (clk_stb) begin
if (clk_counter[5]) begin //if clk_counter ticks over to 100000 and data wasn't ready at 011110
state <= IDLE;
sdo <= 1'b0;
done <= 1'b1;
cs <= 1'b1;
sclk <= 1'b1;
end
else if (clk_counter[4:0]==5'b11110 & data_ready & en) begin
state <= READ;
data_req <= 1'b1;
cs <= 1'b0;
sclk <= 1'b1;
end
else begin
state <= SEND;
clk_counter <= clk_counter + 1'b1;
sclk <= clk_counter[1];
cs <= 1'b0;
if (clk_counter[1:0]==2'b00) begin
piso <= {piso[6:0],1'b0};
sdo <= piso[7];
end
end
end
endcase
end
endmodule

View File

@ -1,149 +0,0 @@
`timescale 1ns / 1ps
module adc_to_datamover(
input axi_aclk,
input axi_aresetn,
output S01_ARESETN,
input axis_cmd_tready,
output[71:0] axis_cmd_tdata,
output axis_cmd_tvalid,
input axis_data_tready,
output[127:0] axis_data_tdata,
output axis_data_tvalid,
output axis_data_tlast,
input[63:0] adc_data,
input adc_divclk,
input s2mm_err,
output s2mm_halt,
input s2mm_halt_cmplt,
input s2mm_wr_xfer_cmplt,
input[31:0] gpio_io_o_0,
output[31:0] gpio2_io_i,
input[31:0] gpio2_io_o_0,
input serdes_ready,
input ddr_ready
);
wire fifo_full;
wire fifo_empty;
wire fifo_valid;
wire fifo_rd_en;
wire[127:0] fifo_data;
reg cmd_tvalid;
reg [27:0] address;
always @(posedge axi_aclk) begin
cmd_tvalid <= 1;
if (!S01_ARESETN) begin
address <= 0;
cmd_tvalid <= 0;
end
else if (axis_cmd_tready) begin
address <= address + 16'h1000;
end
end
assign axis_cmd_tvalid = cmd_tvalid;
//Reserved[3:0], Tag[3:0], SADDR[31:0], DRE, EOF, DSA[3:0], Type, BTT[22:0]
assign axis_cmd_tdata = {4'h0,4'h0,4'h0,address,1'b0,1'b1,6'h00,1'b1,23'h001000};
wire new_sample;
assign new_sample = axis_data_tready & ~fifo_empty;
assign fifo_rd_en = new_sample;
assign axis_data_tvalid = new_sample & fifo_valid;
reg [7:0] data_counter;
reg data_tlast;
always @(posedge axi_aclk) begin
if (!S01_ARESETN) begin
data_counter <= 0;
end
else if (new_sample) begin
data_counter <= data_counter + 1;
data_tlast <= 0;
if (data_counter==16'd254) begin
data_tlast <= 1;
end
end
end
assign axis_data_tlast = data_tlast;
assign axis_data_tdata = {fifo_data[63:0],fifo_data[127:64]};
/* always @(*)
begin
case(gpio_io_o_0[5:4]) // pga_cs demux
2'b00: axis_data_tdata <= {fifo_data[63:0],fifo_data[127:64]};
2'b01: axis_data_tdata <= {fifo_data[63:56],fifo_data[31:24],fifo_data[55:48],fifo_data[23:16],fifo_data[47:40],fifo_data[15:8],fifo_data[39:32],fifo_data[7:0],fifo_data[127:120],fifo_data[95:88],fifo_data[119:112],fifo_data[87:80],fifo_data[111:104],fifo_data[79:72],fifo_data[103:96],fifo_data[71:64]};
2'b10: axis_data_tdata <= {fifo_data[63:56],fifo_data[47:40],fifo_data[31:24],fifo_data[15:8],fifo_data[55:48],fifo_data[39:32],fifo_data[23:16],fifo_data[7:0],fifo_data[127:120],fifo_data[111:104],fifo_data[95:88],fifo_data[79:72],fifo_data[119:112],fifo_data[103:96],fifo_data[87:80],fifo_data[71:64]};
2'b11: axis_data_tdata <= {fifo_data[63:56],fifo_data[47:40],fifo_data[31:24],fifo_data[15:8],fifo_data[55:48],fifo_data[39:32],fifo_data[23:16],fifo_data[7:0],fifo_data[127:120],fifo_data[111:104],fifo_data[95:88],fifo_data[79:72],fifo_data[119:112],fifo_data[103:96],fifo_data[87:80],fifo_data[71:64]};
endcase
end*/
//Transfer Counter
reg [15:0] transfer_counter;
always @(posedge axi_aclk) begin
if (!S01_ARESETN) begin
transfer_counter <= 0;
end
else if (s2mm_wr_xfer_cmplt) begin
transfer_counter <= transfer_counter + 1;
end
end
wire fifo_full_aclk;
reg [2:0] fifo_full_cdc = 3'b000;
always @(posedge axi_aclk)
fifo_full_cdc <= { fifo_full_cdc[1:0], fifo_full};
assign fifo_full_aclk = fifo_full_cdc[2];
reg [10:0] fifo_full_counter;
always @(posedge axi_aclk) begin
if (!S01_ARESETN) begin
fifo_full_counter <= 0;
end
else if (fifo_full) begin
fifo_full_counter <= fifo_full_counter + 1;
end
end
reg wraparound = 0;
reg wraparound_overflow = 0;
always @(posedge axi_aclk) begin
if (!S01_ARESETN) begin
wraparound <= 0;
wraparound_overflow <= 0;
end
else if (gpio2_io_o_0[16]) begin
wraparound <= 0;
end
else if (gpio2_io_o_0[17]) begin
wraparound_overflow <= 0;
end
else if (address == 28'hFFFF000) begin
wraparound <= 1;
if (wraparound) begin
wraparound_overflow <= 1;
end
end
end
//Status GPIOs
assign gpio2_io_i = {s2mm_err,fifo_full_aclk,s2mm_halt_cmplt,fifo_full_counter,wraparound_overflow,wraparound,transfer_counter};
assign S01_ARESETN = (axi_aresetn & gpio_io_o_0[1]);
assign s2mm_halt = ~gpio_io_o_0[0];
fifo_generator_0 adc_fifo (
.rst(~S01_ARESETN),
.wr_clk(adc_divclk),
.rd_clk(axi_aclk),
.din(adc_data),
.wr_en(serdes_ready & ddr_ready), //add a state machine to deal with fifo full
.rd_en(fifo_rd_en),
.dout(fifo_data),
.full(fifo_full),
.empty(fifo_empty),
.valid(fifo_valid)
);
endmodule

View File

@ -1,409 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2012 Xilinx, Inc.
// This design is confidential and proprietary of Xilinx, All Rights Reserved.
//////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version: 1.0
// \ \ Filename: delay_controller_wrap.v
// / / Date Last Modified: Mar 30, 2016
// /___/ /\ Date Created: Jan 8, 2013
// \ \ / \
// \___\/\___\
//
//Device: 7 Series
//Purpose: Controls delays on a per-bit basis
// Number of bits from each serdes set via an attribute
//
//Reference: XAPP585.pdf
//
//Revision History:
// Rev 1.0 - First created (nicks)
//
//////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
//
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to you
// by Xilinx, and to the maximum extent permitted by applicable law:
// (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
// AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
// FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
// or tort, including negligence, or under any other theory of liability) for any loss or damage
// of any kind or nature related to, arising under or in connection with these materials,
// including for any direct, or any indirect, special, incidental, or consequential loss
// or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
// as a result of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// Critical Applications:
//
// Xilinx products are not designed or intended to be fail-safe, or for use in any application
// requiring fail-safe performance, such as life-support or safety devices or systems,
// Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
// or any other applications that could lead to death, personal injury, or severe property or
// environmental damage (individually and collectively, "Critical Applications"). Customer assumes
// the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
// to applicable laws and regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
//////////////////////////////////////////////////////////////////////////////
`timescale 1ps/1ps
module delay_controller_wrap (m_datain, s_datain, enable_phase_detector, enable_monitor, reset, clk, c_delay_in, m_delay_out, s_delay_out, data_out, bt_val, results, m_delay_1hot, del_mech) ;
parameter integer S = 4 ; // Set the number of bits
input [S-1:0] m_datain ; // Inputs from master serdes
input [S-1:0] s_datain ; // Inputs from slave serdes
input enable_phase_detector ; // Enables the phase detector logic when high
input enable_monitor ; // Enables the eye monitoring logic when high
input reset ; // Reset line synchronous to clk
input clk ; // Global/Regional clock
input [4:0] c_delay_in ; // delay value found on clock line
output [4:0] m_delay_out ; // Master delay control value
output [4:0] s_delay_out ; // Master delay control value
output reg [S-1:0] data_out ; // Output data
input [4:0] bt_val ; // Calculated bit time value for slave devices
output reg [31:0] results ; // eye monitor result data
output reg [31:0] m_delay_1hot ; // Master delay control value as a one-hot vector
input del_mech ; // changes delay mechanism slightly at higher bit rates
reg [S-1:0] mdataouta ;
reg mdataoutb ;
reg [S-1:0] mdataoutc ;
reg [S-1:0] sdataouta ;
reg sdataoutb ;
reg [S-1:0] sdataoutc ;
reg s_ovflw ;
reg [1:0] m_delay_mux ;
reg [1:0] s_delay_mux ;
reg data_mux ;
reg dec_run ;
reg inc_run ;
reg eye_run ;
reg [4:0] s_state ;
reg [5:0] pdcount ;
reg [4:0] m_delay_val_int ;
reg [4:0] s_delay_val_int ;
reg [4:0] s_delay_val_eye ;
reg meq_max ;
reg meq_min ;
reg pd_max ;
reg pd_min ;
reg delay_change ;
wire [S-1:0] all_high ;
wire [S-1:0] all_low ;
wire [7:0] msxoria ;
wire [7:0] msxorda ;
reg [1:0] action ;
reg [1:0] msxor_cti ;
reg [1:0] msxor_ctd ;
reg [1:0] msxor_ctix ;
reg [1:0] msxor_ctdx ;
wire [2:0] msxor_ctiy ;
wire [2:0] msxor_ctdy ;
reg [7:0] match ;
reg [31:0] shifter ;
reg [7:0] pd_hold ;
assign m_delay_out = m_delay_val_int ;
assign s_delay_out = s_delay_val_int ;
genvar i ;
generate
for (i = 0 ; i <= S-2 ; i = i+1) begin : loop0
assign msxoria[i+1] = ((~s_ovflw & ((mdataouta[i] & ~mdataouta[i+1] & ~sdataouta[i]) | (~mdataouta[i] & mdataouta[i+1] & sdataouta[i]))) |
( s_ovflw & ((mdataouta[i] & ~mdataouta[i+1] & ~sdataouta[i+1]) | (~mdataouta[i] & mdataouta[i+1] & sdataouta[i+1])))) ; // early bits
assign msxorda[i+1] = ((~s_ovflw & ((mdataouta[i] & ~mdataouta[i+1] & sdataouta[i]) | (~mdataouta[i] & mdataouta[i+1] & ~sdataouta[i])))) |
( s_ovflw & ((mdataouta[i] & ~mdataouta[i+1] & sdataouta[i+1]) | (~mdataouta[i] & mdataouta[i+1] & ~sdataouta[i+1]))) ; // late bits
end
endgenerate
assign msxoria[0] = ((~s_ovflw & ((mdataoutb & ~mdataouta[0] & ~sdataoutb) | (~mdataoutb & mdataouta[0] & sdataoutb))) | // first early bit
( s_ovflw & ((mdataoutb & ~mdataouta[0] & ~sdataouta[0]) | (~mdataoutb & mdataouta[0] & sdataouta[0])))) ;
assign msxorda[0] = ((~s_ovflw & ((mdataoutb & ~mdataouta[0] & sdataoutb) | (~mdataoutb & mdataouta[0] & ~sdataoutb)))) | // first late bit
( s_ovflw & ((mdataoutb & ~mdataouta[0] & sdataouta[0]) | (~mdataoutb & mdataouta[0] & ~sdataouta[0]))) ;
always @ (posedge clk) begin // generate number of incs or decs for low 4 bits
case (msxoria[3:0])
4'h0 : msxor_cti <= 2'h0 ;
4'h1 : msxor_cti <= 2'h1 ;
4'h2 : msxor_cti <= 2'h1 ;
4'h3 : msxor_cti <= 2'h2 ;
4'h4 : msxor_cti <= 2'h1 ;
4'h5 : msxor_cti <= 2'h2 ;
4'h6 : msxor_cti <= 2'h2 ;
4'h8 : msxor_cti <= 2'h1 ;
4'h9 : msxor_cti <= 2'h2 ;
4'hA : msxor_cti <= 2'h2 ;
4'hC : msxor_cti <= 2'h2 ;
default : msxor_cti <= 2'h3 ;
endcase
case (msxorda[3:0])
4'h0 : msxor_ctd <= 2'h0 ;
4'h1 : msxor_ctd <= 2'h1 ;
4'h2 : msxor_ctd <= 2'h1 ;
4'h3 : msxor_ctd <= 2'h2 ;
4'h4 : msxor_ctd <= 2'h1 ;
4'h5 : msxor_ctd <= 2'h2 ;
4'h6 : msxor_ctd <= 2'h2 ;
4'h8 : msxor_ctd <= 2'h1 ;
4'h9 : msxor_ctd <= 2'h2 ;
4'hA : msxor_ctd <= 2'h2 ;
4'hC : msxor_ctd <= 2'h2 ;
default : msxor_ctd <= 2'h3 ;
endcase
case (msxoria[7:4]) // generate number of incs or decs for high n bits, max 4
4'h0 : msxor_ctix <= 2'h0 ;
4'h1 : msxor_ctix <= 2'h1 ;
4'h2 : msxor_ctix <= 2'h1 ;
4'h3 : msxor_ctix <= 2'h2 ;
4'h4 : msxor_ctix <= 2'h1 ;
4'h5 : msxor_ctix <= 2'h2 ;
4'h6 : msxor_ctix <= 2'h2 ;
4'h8 : msxor_ctix <= 2'h1 ;
4'h9 : msxor_ctix <= 2'h2 ;
4'hA : msxor_ctix <= 2'h2 ;
4'hC : msxor_ctix <= 2'h2 ;
default : msxor_ctix <= 2'h3 ;
endcase
case (msxorda[7:4])
4'h0 : msxor_ctdx <= 2'h0 ;
4'h1 : msxor_ctdx <= 2'h1 ;
4'h2 : msxor_ctdx <= 2'h1 ;
4'h3 : msxor_ctdx <= 2'h2 ;
4'h4 : msxor_ctdx <= 2'h1 ;
4'h5 : msxor_ctdx <= 2'h2 ;
4'h6 : msxor_ctdx <= 2'h2 ;
4'h8 : msxor_ctdx <= 2'h1 ;
4'h9 : msxor_ctdx <= 2'h2 ;
4'hA : msxor_ctdx <= 2'h2 ;
4'hC : msxor_ctdx <= 2'h2 ;
default : msxor_ctdx <= 2'h3 ;
endcase
end
assign msxor_ctiy = {1'b0, msxor_cti} + {1'b0, msxor_ctix} ;
assign msxor_ctdy = {1'b0, msxor_ctd} + {1'b0, msxor_ctdx} ;
always @ (posedge clk) begin
if (msxor_ctiy == msxor_ctdy) begin
action <= 2'h0 ;
end
else if (msxor_ctiy > msxor_ctdy) begin
action <= 2'h1 ;
end
else begin
action <= 2'h2 ;
end
end
generate
for (i = 0 ; i <= S-1 ; i = i+1) begin : loop1
assign all_high[i] = 1'b1 ;
assign all_low[i] = 1'b0 ;
end
endgenerate
always @ (posedge clk) begin
mdataouta <= m_datain ;
mdataoutb <= mdataouta[S-1] ;
sdataouta <= s_datain ;
sdataoutb <= sdataouta[S-1] ;
end
always @ (posedge clk) begin
if (reset == 1'b1) begin
s_ovflw <= 1'b0 ;
pdcount <= 6'b100000 ;
m_delay_val_int <= c_delay_in ; // initial master delay
s_delay_val_int <= c_delay_in ; // initial slave delay
data_mux <= 1'b0 ;
m_delay_mux <= 2'b01 ;
s_delay_mux <= 2'b01 ;
s_state <= 5'b00000 ;
inc_run <= 1'b0 ;
dec_run <= 1'b0 ;
eye_run <= 1'b0 ;
s_delay_val_eye <= 5'h00 ;
shifter <= 32'h00000001 ;
delay_change <= 1'b0 ;
results <= 32'h00000000 ;
pd_hold <= 8'h00 ;
end
else begin
case (m_delay_mux)
2'b00 : mdataoutc <= {mdataouta[S-2:0], mdataoutb} ;
2'b10 : mdataoutc <= {m_datain[0], mdataouta[S-1:1]} ;
default : mdataoutc <= mdataouta ;
endcase
case (s_delay_mux)
2'b00 : sdataoutc <= {sdataouta[S-2:0], sdataoutb} ;
2'b10 : sdataoutc <= {s_datain[0], sdataouta[S-1:1]} ;
default : sdataoutc <= sdataouta ;
endcase
if (m_delay_val_int == bt_val) begin
meq_max <= 1'b1 ;
end else begin
meq_max <= 1'b0 ;
end
if (m_delay_val_int == 5'h00) begin
meq_min <= 1'b1 ;
end else begin
meq_min <= 1'b0 ;
end
if (pdcount == 6'h3F && pd_max == 1'b0 && delay_change == 1'b0) begin
pd_max <= 1'b1 ;
end else begin
pd_max <= 1'b0 ;
end
if (pdcount == 6'h00 && pd_min == 1'b0 && delay_change == 1'b0) begin
pd_min <= 1'b1 ;
end else begin
pd_min <= 1'b0 ;
end
if (delay_change == 1'b1 || inc_run == 1'b1 || dec_run == 1'b1 || eye_run == 1'b1) begin
pd_hold <= 8'hFF ;
pdcount <= 6'b100000 ;
end // increment filter count
else if (pd_hold[7] == 1'b1) begin
pdcount <= 6'b100000 ;
pd_hold <= {pd_hold[6:0], 1'b0} ;
end
else if (action[0] == 1'b1 && pdcount != 6'b111111) begin
pdcount <= pdcount + 6'h01 ;
end // decrement filter count
else if (action[1] == 1'b1 && pdcount != 6'b000000) begin
pdcount <= pdcount - 6'h01 ;
end
if ((enable_phase_detector == 1'b1 && pd_max == 1'b1 && delay_change == 1'b0) || inc_run == 1'b1) begin // increment delays, check for master delay = max
delay_change <= 1'b1 ;
if (meq_max == 1'b0 && inc_run == 1'b0) begin
m_delay_val_int <= m_delay_val_int + 5'h01 ;
end
else begin // master is max
s_state[3:0] <= s_state[3:0] + 4'h1 ;
case (s_state[3:0])
4'b0000 : begin inc_run <= 1'b1 ; s_delay_val_int <= bt_val ; end // indicate state machine running and set slave delay to bit time
4'b0110 : begin data_mux <= 1'b1 ; m_delay_val_int <= 5'b00000 ; end // change data mux over to forward slave data and set master delay to zero
4'b1001 : begin m_delay_mux <= m_delay_mux - 2'h1 ; end // change delay mux over to forward with a 1-bit less advance
4'b1110 : begin data_mux <= 1'b0 ; end // change data mux over to forward master data
4'b1111 : begin s_delay_mux <= m_delay_mux ; inc_run <= 1'b0 ; end // change delay mux over to forward with a 1-bit less advance
default : begin inc_run <= 1'b1 ; end
endcase
end
end
else if ((enable_phase_detector == 1'b1 && pd_min == 1'b1 && delay_change == 1'b0) || dec_run == 1'b1) begin // decrement delays, check for master delay = 0
delay_change <= 1'b1 ;
if (meq_min == 1'b0 && dec_run == 1'b0) begin
m_delay_val_int <= m_delay_val_int - 5'h01 ;
end
else begin // master is zero
s_state[3:0] <= s_state[3:0] + 4'h1 ;
case (s_state[3:0])
4'b0000 : begin dec_run <= 1'b1 ; s_delay_val_int <= 5'b00000 ; end // indicate state machine running and set slave delay to zero
4'b0110 : begin data_mux <= 1'b1 ; m_delay_val_int <= bt_val ; end // change data mux over to forward slave data and set master delay to bit time
4'b1001 : begin m_delay_mux <= m_delay_mux + 2'h1 ; end // change delay mux over to forward with a 1-bit more advance
4'b1110 : begin data_mux <= 1'b0 ; end // change data mux over to forward master data
4'b1111 : begin s_delay_mux <= m_delay_mux ; dec_run <= 1'b0 ; end // change delay mux over to forward with a 1-bit less advance
default : begin dec_run <= 1'b1 ; end
endcase
end
end
else if (enable_monitor == 1'b1 && (eye_run == 1'b1 || delay_change == 1'b1)) begin
delay_change <= 1'b0 ;
s_state <= s_state + 5'h01 ;
case (s_state)
5'b00000 : begin eye_run <= 1'b1 ; s_delay_val_int <= s_delay_val_eye ; end // indicate state machine running and set slave delay to monitor value
5'b10110 : begin
if (match == 8'hFF) begin results <= results | shifter ; end //. set or clear result bit
else begin results <= results & ~shifter ; end
if (s_delay_val_eye == bt_val) begin // only monitor active taps, ie as far as btval
shifter <= 32'h00000001 ; s_delay_val_eye <= 5'h00 ; end
else begin shifter <= {shifter[30:0], shifter[31]} ;
s_delay_val_eye <= s_delay_val_eye + 5'h01 ; end //
eye_run <= 1'b0 ; s_state <= 5'h00 ; end
default : begin eye_run <= 1'b1 ; end
endcase
end
else begin
delay_change <= 1'b0 ;
if (m_delay_val_int >= {1'b0, bt_val[4:1]} && del_mech == 1'b0) begin // set slave delay to 1/2 bit period beyond or behind the master delay
s_delay_val_int <= m_delay_val_int - {1'b0, bt_val[4:1]} ;
s_ovflw <= 1'b0 ;
end
else begin
s_delay_val_int <= m_delay_val_int + {1'b0, bt_val[4:1]} ;
s_ovflw <= 1'b1 ;
end
end
if (enable_phase_detector == 1'b0 && delay_change == 1'b0) begin
delay_change <= 1'b1 ;
end
end
if (enable_phase_detector == 1'b1) begin
if (data_mux == 1'b0) begin
data_out <= mdataoutc ;
end else begin
data_out <= sdataoutc ;
end
end
else begin
data_out <= m_datain ;
end
end
always @ (posedge clk) begin
if ((mdataouta == sdataouta)) begin
match <= {match[6:0], 1'b1} ;
end else begin
match <= {match[6:0], 1'b0} ;
end
end
always @ (m_delay_val_int) begin
case (m_delay_val_int)
5'b00000 : m_delay_1hot <= 32'h00000001 ;
5'b00001 : m_delay_1hot <= 32'h00000002 ;
5'b00010 : m_delay_1hot <= 32'h00000004 ;
5'b00011 : m_delay_1hot <= 32'h00000008 ;
5'b00100 : m_delay_1hot <= 32'h00000010 ;
5'b00101 : m_delay_1hot <= 32'h00000020 ;
5'b00110 : m_delay_1hot <= 32'h00000040 ;
5'b00111 : m_delay_1hot <= 32'h00000080 ;
5'b01000 : m_delay_1hot <= 32'h00000100 ;
5'b01001 : m_delay_1hot <= 32'h00000200 ;
5'b01010 : m_delay_1hot <= 32'h00000400 ;
5'b01011 : m_delay_1hot <= 32'h00000800 ;
5'b01100 : m_delay_1hot <= 32'h00001000 ;
5'b01101 : m_delay_1hot <= 32'h00002000 ;
5'b01110 : m_delay_1hot <= 32'h00004000 ;
5'b01111 : m_delay_1hot <= 32'h00008000 ;
5'b10000 : m_delay_1hot <= 32'h00010000 ;
5'b10001 : m_delay_1hot <= 32'h00020000 ;
5'b10010 : m_delay_1hot <= 32'h00040000 ;
5'b10011 : m_delay_1hot <= 32'h00080000 ;
5'b10100 : m_delay_1hot <= 32'h00100000 ;
5'b10101 : m_delay_1hot <= 32'h00200000 ;
5'b10110 : m_delay_1hot <= 32'h00400000 ;
5'b10111 : m_delay_1hot <= 32'h00800000 ;
5'b11000 : m_delay_1hot <= 32'h01000000 ;
5'b11001 : m_delay_1hot <= 32'h02000000 ;
5'b11010 : m_delay_1hot <= 32'h04000000 ;
5'b11011 : m_delay_1hot <= 32'h08000000 ;
5'b11100 : m_delay_1hot <= 32'h10000000 ;
5'b11101 : m_delay_1hot <= 32'h20000000 ;
5'b11110 : m_delay_1hot <= 32'h40000000 ;
default : m_delay_1hot <= 32'h80000000 ;
endcase
end
endmodule

View File

@ -1,94 +0,0 @@
`timescale 1ns / 1ps
module serdes(
input rst,
input adc_lclk_p,
input adc_lclk_n,
input adc_fclk_p,
input adc_fclk_n,
input[7:0] adc_data_p,
input[7:0] adc_data_n,
input axi_aclk,
output divclk,
output[63:0] data_deser,
output ready
);
wire delay_ready;
wire rx_lckd;
wire clk0;
wire[7:0] fclk_deser;
reg bitslip_ready;
reg state = 1'b0;
reg bitslip;
reg[3:0] count;
assign ready = bitslip_ready && delay_ready && rx_lckd;
always @(posedge divclk) begin
if (rst) begin
state <= 0;
bitslip <= 0;
count <= 0;
bitslip_ready <= 0;
end
else begin
if (state == 0) begin
if (fclk_deser != 8'h0f) begin
bitslip <= 1'b1; // bitslip needed
state <= 1;
count <= 4'b0000;
bitslip_ready <= 0;
end
else
bitslip_ready <= 1;
end
else if (state == 1) begin
bitslip <= 1'b0 ; // bitslip low
count <= count + 4'b0001;
if (count == 4'b1111)
state <= 0;
end
end
end
clk_wiz_0 serdes_clocking(
.clk_in1 (axi_aclk),
.clk_out1 (ref_clock)
);
IDELAYCTRL icontrol ( // Instantiate input delay control block
.REFCLK (ref_clock),
.RST (rst),
.RDY (delay_ready));
serdes_1_to_468_idelay_ddr #(
.S (8), // Set the serdes factor (4, 6 or 8)
.HIGH_PERFORMANCE_MODE ("TRUE"),
.D (9), // Number of data lines
.REF_FREQ (300.0), // Set idelay control reference frequency, 300 MHz shown
.CLKIN_PERIOD (2), // Set input clock period, 500MHz
.DATA_FORMAT ("PER_CHANL")) // PER_CLOCK or PER_CHANL data formatting
rx0 (
.clkin_p (adc_lclk_p),
.clkin_n (adc_lclk_n),
.datain_p ({adc_fclk_p,adc_data_p}),
.datain_n ({adc_fclk_n,adc_data_n}),
.enable_phase_detector (1'b1), // enable phase detector (active alignment) operation
.enable_monitor (1'b0), // enables data eye monitoring
.dcd_correct (1'b0), // enables clock duty cycle correction
.rxclk (),
.idelay_rdy (delay_ready),
.system_clk (divclk),
.reset (rst),
.rx_lckd (rx_lckd),
.bitslip (bitslip),
.rx_data ({fclk_deser,data_deser}),
.bit_rate_value (16'h1000), // required bit rate value in BCD (1000 Mbps)
.bit_time_value (), // bit time value
.eye_info (), // data eye monitor per line
.m_delay_1hot (), // sample point monitor per line
.debug ()) ; // debug bus
endmodule

View File

@ -1,545 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2012 Xilinx, Inc.
// This design is confidential and proprietary of Xilinx, All Rights Reserved.
//////////////////////////////////////////////////////////////////////////////
// ____ ____
// / /\/ /
// /___/ \ / Vendor: Xilinx
// \ \ \/ Version: 1.0
// \ \ Filename: serdes_1_to_468_idelay_ddr.v
// / / Date Last Modified: Mar 30, 2016
// /___/ /\ Date Created: Mar 5, 2011
// \ \ / \
// \___\/\___\
//
//Device: 7 Series
//Purpose: 1 to 4, 6 or 8 DDR data receiver.
// Data formatting is set by the DATA_FORMAT parameter. Serdes factor by the S parameter
// PER_CLOCK (default) format receives bits for 0, 1, 2 .. on the same sample edge
// PER_CHANL format receives bits for 0, 4, 8 .. (1:4 serdes) on the same sample edge
//
//Reference:
//
//Revision History:
// Rev 1.0 - First created (nicks)
// Rev 1.1 - CR1107363 (JT)
//
//////////////////////////////////////////////////////////////////////////////
//
// Disclaimer:
//
// This disclaimer is not a license and does not grant any rights to the materials
// distributed herewith. Except as otherwise provided in a valid license issued to you
// by Xilinx, and to the maximum extent permitted by applicable law:
// (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
// AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
// INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
// FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
// or tort, including negligence, or under any other theory of liability) for any loss or damage
// of any kind or nature related to, arising under or in connection with these materials,
// including for any direct, or any indirect, special, incidental, or consequential loss
// or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
// as a result of any action brought by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the possibility of the same.
//
// Critical Applications:
//
// Xilinx products are not designed or intended to be fail-safe, or for use in any application
// requiring fail-safe performance, such as life-support or safety devices or systems,
// Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
// or any other applications that could lead to death, personal injury, or severe property or
// environmental damage (individually and collectively, "Critical Applications"). Customer assumes
// the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
// to applicable laws and regulations governing limitations on product liability.
//
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
//
//////////////////////////////////////////////////////////////////////////////
`timescale 1ps/1ps
module serdes_1_to_468_idelay_ddr (clkin_p, clkin_n, datain_p, datain_n, enable_phase_detector, enable_monitor, rxclk, idelay_rdy, reset, system_clk, bitslip,
rx_lckd, rx_data, debug, bit_rate_value, bit_time_value, dcd_correct, eye_info, m_delay_1hot, clock_sweep) ;
parameter integer S = 8 ; // Set the serdes factor to 4, 6 or 8
parameter integer D = 8 ; // Parameter to set the number of data lines
parameter real REF_FREQ = 200 ; // Parameter to set reference frequency used by idelay controller
parameter HIGH_PERFORMANCE_MODE = "FALSE";// Parameter to set HIGH_PERFORMANCE_MODE of input delays to reduce jitter
parameter real CLKIN_PERIOD = 6.000 ; // clock period (ns) of input clock on clkin_p
parameter DATA_FORMAT = "PER_CLOCK" ; // Parameter Used to determine method for mapping input parallel word to output serial words
input clkin_p ; // Input from LVDS clock receiver pin
input clkin_n ; // Input from LVDS clock receiver pin
input [D-1:0] datain_p ; // Input from LVDS clock data pins
input [D-1:0] datain_n ; // Input from LVDS clock data pins
input enable_phase_detector ; // Enables the phase detector logic when high
input enable_monitor ; // Enables the eye monitoring logic when high
input reset ; // Reset line
input bitslip ; // Bitslip line
input idelay_rdy ; // input delays are ready
output rxclk ; // Global/BUFIO rx clock network
output system_clk ; // Global/Regional clock output
output rx_lckd ; // Locked, synchronous to system_clk
output [D*S-1:0] rx_data ; // Received Data
output [10*D+18:0] debug ; // debug info
input [15:0] bit_rate_value ; // Bit rate in Mbps, for example 16'h0585 16'h1050 ..
input dcd_correct ; // '0' = square, '1' = assume 10% DCD
output [4:0] bit_time_value ; // Calculated bit time value for slave devices
output [D*32-1:0] eye_info ; // eye info
output [D*32-1:0] m_delay_1hot ; // Master delay control value as a one-hot vector
output reg [31:0] clock_sweep ; // clock eye info
reg rst_iserdes ;
wire [D*5-1:0] m_delay_val_in ;
wire [D*5-1:0] m_delay_val_out ;
wire [D*5-1:0] s_delay_val_in ;
wire [D*5-1:0] s_delay_val_out ;
wire [3:0] cdataout ;
wire rx_clk_in_p ;
reg [3:0] clk_iserdes_data_d ;
reg [4:0] state2_count ;
reg rx_lckd_intd4 ;
reg not_rx_lckd_intd4 ;
wire [D-1:0] rx_data_in_p ;
wire [D-1:0] rx_data_in_n ;
wire [D-1:0] rx_data_in_m ;
wire [D-1:0] rx_data_in_s ;
wire [D-1:0] rx_data_in_md ;
wire [D-1:0] rx_data_in_sd ;
wire [(S*D)-1:0] mdataout ;
wire [(S*D)-1:0] mdataoutd ;
wire [(S*D)-1:0] sdataout ;
wire [(8*D)-1:0] m_serdes ;
wire [(8*D)-1:0] s_serdes ;
reg data_different ;
reg [4:0] bt_val ;
reg su_locked ;
reg [5:0] m_count ;
reg [4:0] c_sweep_delay ;
reg [31:0] temp_shift ;
reg zflag ;
reg del_mech ;
reg [4:0] initial_delay ;
parameter [D-1:0] RX_SWAP_MASK = 16'h0000 ; // pinswap mask for input data bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
assign debug = {c_sweep_delay, 4'h0, cdataout, s_delay_val_out, m_delay_val_out, bitslip, initial_delay} ;
assign rx_lckd = ~not_rx_lckd_intd4 & su_locked ;
assign bit_time_value = bt_val ;
if (REF_FREQ < 210.0) begin
always @ (bit_rate_value) begin // Generate tap number to be used for input bit rate (200 MHz ref clock)
if (bit_rate_value > 16'h1984) begin bt_val <= 5'h07 ; end
else if (bit_rate_value > 16'h1717) begin bt_val <= 5'h08 ; end
else if (bit_rate_value > 16'h1514) begin bt_val <= 5'h09 ; end
else if (bit_rate_value > 16'h1353) begin bt_val <= 5'h0A ; end
else if (bit_rate_value > 16'h1224) begin bt_val <= 5'h0B ; end
else if (bit_rate_value > 16'h1117) begin bt_val <= 5'h0C ; end
else if (bit_rate_value > 16'h1027) begin bt_val <= 5'h0D ; end
else if (bit_rate_value > 16'h0951) begin bt_val <= 5'h0E ; end
else if (bit_rate_value > 16'h0885) begin bt_val <= 5'h0F ; end
else if (bit_rate_value > 16'h0828) begin bt_val <= 5'h10 ; end
else if (bit_rate_value > 16'h0778) begin bt_val <= 5'h11 ; end
else if (bit_rate_value > 16'h0733) begin bt_val <= 5'h12 ; end
else if (bit_rate_value > 16'h0694) begin bt_val <= 5'h13 ; end
else if (bit_rate_value > 16'h0658) begin bt_val <= 5'h14 ; end
else if (bit_rate_value > 16'h0626) begin bt_val <= 5'h15 ; end
else if (bit_rate_value > 16'h0597) begin bt_val <= 5'h16 ; end
else if (bit_rate_value > 16'h0570) begin bt_val <= 5'h17 ; end
else if (bit_rate_value > 16'h0546) begin bt_val <= 5'h18 ; end
else if (bit_rate_value > 16'h0524) begin bt_val <= 5'h19 ; end
else if (bit_rate_value > 16'h0503) begin bt_val <= 5'h1A ; end
else if (bit_rate_value > 16'h0484) begin bt_val <= 5'h1B ; end
else if (bit_rate_value > 16'h0466) begin bt_val <= 5'h1C ; end
else if (bit_rate_value > 16'h0450) begin bt_val <= 5'h1D ; end
else if (bit_rate_value > 16'h0435) begin bt_val <= 5'h1E ; end
else begin bt_val <= 5'h1F ; end // min bit rate 420 Mbps
end
end
else begin
always @ (bit_rate_value or dcd_correct) begin // Generate tap number to be used for input bit rate (300 MHz ref clock)
if (dcd_correct == 1'b0 && (bit_rate_value > 16'h2030) || dcd_correct == 1'b1 && bit_rate_value > 16'h1845) begin bt_val <= 5'h0A ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1836) || dcd_correct == 1'b1 && bit_rate_value > 16'h1669) begin bt_val <= 5'h0B ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1675) || dcd_correct == 1'b1 && bit_rate_value > 16'h1523) begin bt_val <= 5'h0C ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1541) || dcd_correct == 1'b1 && bit_rate_value > 16'h1401) begin bt_val <= 5'h0D ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1426) || dcd_correct == 1'b1 && bit_rate_value > 16'h1297) begin bt_val <= 5'h0E ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1328) || dcd_correct == 1'b1 && bit_rate_value > 16'h1207) begin bt_val <= 5'h0F ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1242) || dcd_correct == 1'b1 && bit_rate_value > 16'h1129) begin bt_val <= 5'h10 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1167) || dcd_correct == 1'b1 && bit_rate_value > 16'h1061) begin bt_val <= 5'h11 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1100) || dcd_correct == 1'b1 && bit_rate_value > 16'h0999) begin bt_val <= 5'h12 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h1040) || dcd_correct == 1'b1 && bit_rate_value > 16'h0946) begin bt_val <= 5'h13 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0987) || dcd_correct == 1'b1 && bit_rate_value > 16'h0897) begin bt_val <= 5'h14 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0939) || dcd_correct == 1'b1 && bit_rate_value > 16'h0853) begin bt_val <= 5'h15 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0895) || dcd_correct == 1'b1 && bit_rate_value > 16'h0814) begin bt_val <= 5'h16 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0855) || dcd_correct == 1'b1 && bit_rate_value > 16'h0777) begin bt_val <= 5'h17 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0819) || dcd_correct == 1'b1 && bit_rate_value > 16'h0744) begin bt_val <= 5'h18 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0785) || dcd_correct == 1'b1 && bit_rate_value > 16'h0714) begin bt_val <= 5'h19 ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0754) || dcd_correct == 1'b1 && bit_rate_value > 16'h0686) begin bt_val <= 5'h1A ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0726) || dcd_correct == 1'b1 && bit_rate_value > 16'h0660) begin bt_val <= 5'h1B ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0700) || dcd_correct == 1'b1 && bit_rate_value > 16'h0636) begin bt_val <= 5'h1C ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0675) || dcd_correct == 1'b1 && bit_rate_value > 16'h0614) begin bt_val <= 5'h1D ; end
else if (dcd_correct == 1'b0 && (bit_rate_value > 16'h0652) || dcd_correct == 1'b1 && bit_rate_value > 16'h0593) begin bt_val <= 5'h1E ; end
else begin bt_val <= 5'h1F ; end // min bit rate 631 Mbps
end
end
always @ (bt_val) begin
if (bt_val < 5'b10110) begin // adjust delay mechanism when tap values are low enough
del_mech <= 1'b1 ;
end
else begin
del_mech <= 1'b0 ;
end
end
// Clock input
IBUFGDS #(
.IBUF_LOW_PWR ("FALSE"))
iob_clk_in (
.I (clkin_p),
.IB (clkin_n),
.O (rx_clk_in_p));
genvar i ;
genvar j ;
IDELAYE2 #(
.REFCLK_FREQUENCY (REF_FREQ),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.IDELAY_VALUE (1),
.DELAY_SRC ("IDATAIN"),
.IDELAY_TYPE ("VAR_LOAD"))
idelay_cm(
.DATAOUT (rx_clk_in_pd),
.C (system_clk),
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.IDATAIN (rx_clk_in_p),
.LD (1'b1),
.LDPIPEEN (1'b0),
.REGRST (1'b0),
.CINVCTRL (1'b0),
.CNTVALUEIN (c_sweep_delay),
.CNTVALUEOUT ());
ISERDESE2 #(
.DATA_WIDTH (S),
.DATA_RATE ("DDR"),
.SERDES_MODE ("MASTER"),
.IOBDELAY ("IFD"),
.INTERFACE_TYPE ("NETWORKING"),
.NUM_CE (1))
iserdes_cm (
.D (rx_clk_in_p),
.DDLY (rx_clk_in_pd),
.CE1 (1'b1),
.CE2 (1'b1),
.CLK (rxclk),
.CLKB (~rxclk),
.RST (rst_iserdes),
.CLKDIV (system_clk),
.CLKDIVP (1'b0),
.OCLK (1'b0),
.OCLKB (1'b0),
.DYNCLKSEL (1'b0),
.DYNCLKDIVSEL (1'b0),
.SHIFTIN1 (1'b0),
.SHIFTIN2 (1'b0),
.BITSLIP (1'b0),
.O (rx_clk_in_pc),
.Q8 (),
.Q7 (),
.Q6 (),
.Q5 (),
.Q4 (cdataout[0]),
.Q3 (cdataout[1]),
.Q2 (cdataout[2]),
.Q1 (cdataout[3]),
.OFB (),
.SHIFTOUT1 (),
.SHIFTOUT2 ());
BUFIO bufio_mmcm_xn (.I (rx_clk_in_pc), .O(rxclk)) ;
generate
if (S == 4) begin : loop2a
BUFR #(.BUFR_DIVIDE("2"),.SIM_DEVICE("7SERIES"))bufr_mmcm_x1 (.I(rx_clk_in_pc),.CE(1'b1),.O(system_clk),.CLR(1'b0)) ;
end
if (S == 6) begin : loop2b
BUFR #(.BUFR_DIVIDE("3"),.SIM_DEVICE("7SERIES"))bufr_mmcm_x1 (.I(rx_clk_in_pc),.CE(1'b1),.O(system_clk),.CLR(1'b0)) ;
end
if (S == 8) begin : loop2c
BUFR #(.BUFR_DIVIDE("4"),.SIM_DEVICE("7SERIES"))bufr_mmcm_x1 (.I(rx_clk_in_pc),.CE(1'b1),.O(system_clk),.CLR(1'b0)) ;
end
endgenerate
always @ (posedge system_clk) begin // sweep data
if (su_locked == 1'b0) begin
c_sweep_delay <= 5'b00000 ;
temp_shift <= 32'h00000001 ;
clock_sweep <= 32'h00000000 ;
zflag <= 1'b0 ;
rx_lckd_intd4 <= 1'b0 ;
not_rx_lckd_intd4 <= 1'b1 ;
initial_delay <= 5'h00 ;
end
else begin
not_rx_lckd_intd4 <= ~rx_lckd_intd4 ;
if (state2_count == 5'h1F) begin
if (c_sweep_delay != bt_val) begin
if (zflag == 1'b0) begin
c_sweep_delay <= c_sweep_delay + 5'h01 ;
temp_shift <= {temp_shift[30:0], temp_shift[31]} ;
end
else begin
zflag <= 1'b0 ;
end
end
else begin
c_sweep_delay <= 5'h00 ;
zflag <= 1'b1 ;
temp_shift <= 32'h00000001 ;
end
if (zflag == 1'b0) begin
if (data_different == 1'b1) begin
clock_sweep <= clock_sweep & ~temp_shift ;
if (initial_delay == 5'h00) begin
rx_lckd_intd4 <= 1'b1 ;
if (c_sweep_delay < {1'b0, bt_val[4:1]}) begin // choose the lowest delay value to minimise jitter
initial_delay <= c_sweep_delay + {1'b0, bt_val[4:1]} ;
end
else begin
initial_delay <= c_sweep_delay - {1'b0, bt_val[4:1]} ;
end
end
end
else begin
clock_sweep <= clock_sweep | temp_shift ;
end
end
end
end
end
always @ (posedge system_clk or posedge reset or negedge idelay_rdy) begin
if (reset == 1'b1 || idelay_rdy == 1'b0) begin
su_locked <= 1'b0 ;
m_count <= 6'h00 ;
rst_iserdes <= 1'b1 ;
end else begin // dummy startup delay
if (m_count == 6'h3C) begin
rst_iserdes <= 1'b0 ;
m_count <= m_count + 6'h01 ;
end
else if (m_count == 6'h3F) begin
su_locked <= 1'b1 ;
end
else begin
m_count <= m_count + 6'h01 ;
end
end
end
always @ (posedge system_clk) begin
if (su_locked == 1'b0) begin
state2_count <= 5'h00 ;
end
else begin
state2_count <= state2_count + 5'h01 ;
if (state2_count == 5'h00) begin
clk_iserdes_data_d <= cdataout ;
end
else if (state2_count <= 5'h08) begin
data_different <= 1'b0 ;
end
else if (cdataout != clk_iserdes_data_d) begin
data_different <= 1'b1 ;
end
end
end
generate
for (i = 0 ; i <= D-1 ; i = i+1)
begin : loop3
delay_controller_wrap # (
.S (S))
dc_inst (
.m_datain (mdataout[S*i+S-1:S*i]),
.s_datain (sdataout[S*i+S-1:S*i]),
.enable_phase_detector (enable_phase_detector),
.enable_monitor (enable_monitor),
.reset (not_rx_lckd_intd4),
.clk (system_clk),
.c_delay_in (initial_delay),
.m_delay_out (m_delay_val_in[5*i+4:5*i]),
.s_delay_out (s_delay_val_in[5*i+4:5*i]),
.data_out (mdataoutd[S*i+S-1:S*i]),
.bt_val (bt_val),
.del_mech (del_mech),
.results (eye_info[32*i+31:32*i]),
.m_delay_1hot (m_delay_1hot[32*i+31:32*i])) ;
end
endgenerate
// Data bit Receivers
generate
for (i = 0 ; i <= D-1 ; i = i+1) begin : loop0
for (j = 0 ; j <= S-1 ; j = j+1) begin : loop1 // Assign data bits to correct serdes according to required format
if (DATA_FORMAT == "PER_CLOCK") begin
assign rx_data[D*j+i] = mdataoutd[S*i+j] ;
end
else begin
assign rx_data[S*i+j] = mdataoutd[S*i+j] ;
end
end
IBUFDS_DIFF_OUT #(
.IBUF_LOW_PWR ("FALSE"))
data_in (
.I (datain_p[i]),
.IB (datain_n[i]),
.O (rx_data_in_p[i]),
.OB (rx_data_in_n[i]));
assign rx_data_in_m[i] = rx_data_in_p[i] ^ RX_SWAP_MASK[i] ;
assign rx_data_in_s[i] = rx_data_in_n[i] ^ RX_SWAP_MASK[i] ;
IDELAYE2 #(
.REFCLK_FREQUENCY (REF_FREQ),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.IDELAY_VALUE (0),
.DELAY_SRC ("IDATAIN"),
.IDELAY_TYPE ("VAR_LOAD"))
idelay_m(
.DATAOUT (rx_data_in_md[i]),
.C (system_clk),
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.IDATAIN (rx_data_in_m[i]),
.LD (1'b1),
.LDPIPEEN (1'b0),
.REGRST (1'b0),
.CINVCTRL (1'b0),
.CNTVALUEIN (m_delay_val_in[5*i+4:5*i]),
.CNTVALUEOUT (m_delay_val_out[5*i+4:5*i]));
ISERDESE2 #(
.DATA_WIDTH (S),
.DATA_RATE ("DDR"),
.SERDES_MODE ("MASTER"),
.IOBDELAY ("IFD"),
.INTERFACE_TYPE ("NETWORKING"),
.NUM_CE (1))
iserdes_m (
.D (1'b0),
.DDLY (rx_data_in_md[i]),
.CE1 (1'b1),
.CE2 (1'b1),
.CLK (rxclk),
.CLKB (~rxclk),
.RST (rst_iserdes),
.CLKDIV (system_clk),
.CLKDIVP (1'b0),
.OCLK (1'b0),
.OCLKB (1'b0),
.DYNCLKSEL (1'b0),
.DYNCLKDIVSEL (1'b0),
.SHIFTIN1 (1'b0),
.SHIFTIN2 (1'b0),
.BITSLIP (bitslip),
.O (),
.Q8 (m_serdes[8*i+0]),
.Q7 (m_serdes[8*i+1]),
.Q6 (m_serdes[8*i+2]),
.Q5 (m_serdes[8*i+3]),
.Q4 (m_serdes[8*i+4]),
.Q3 (m_serdes[8*i+5]),
.Q2 (m_serdes[8*i+6]),
.Q1 (m_serdes[8*i+7]),
.OFB (),
.SHIFTOUT1 (),
.SHIFTOUT2 ());
IDELAYE2 #(
.REFCLK_FREQUENCY (REF_FREQ),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.IDELAY_VALUE (0),
.DELAY_SRC ("IDATAIN"),
.IDELAY_TYPE ("VAR_LOAD"))
idelay_s(
.DATAOUT (rx_data_in_sd[i]),
.C (system_clk),
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.IDATAIN (rx_data_in_s[i]),
.LD (1'b1),
.LDPIPEEN (1'b0),
.REGRST (1'b0),
.CINVCTRL (1'b0),
.CNTVALUEIN (s_delay_val_in[5*i+4:5*i]),
.CNTVALUEOUT (s_delay_val_out[5*i+4:5*i]));
ISERDESE2 #(
.DATA_WIDTH (S),
.DATA_RATE ("DDR"),
.SERDES_MODE ("MASTER"),
.IOBDELAY ("IFD"),
.INTERFACE_TYPE ("NETWORKING"),
.NUM_CE (1))
iserdes_s (
.D (1'b0),
.DDLY (rx_data_in_sd[i]),
.CE1 (1'b1),
.CE2 (1'b1),
.CLK (rxclk),
.CLKB (~rxclk),
.RST (rst_iserdes),
.CLKDIV (system_clk),
.CLKDIVP (1'b0),
.OCLK (1'b0),
.OCLKB (1'b0),
.DYNCLKSEL (1'b0),
.DYNCLKDIVSEL (1'b0),
.SHIFTIN1 (1'b0),
.SHIFTIN2 (1'b0),
.BITSLIP (bitslip),
.O (),
.Q8 (s_serdes[8*i+0]),
.Q7 (s_serdes[8*i+1]),
.Q6 (s_serdes[8*i+2]),
.Q5 (s_serdes[8*i+3]),
.Q4 (s_serdes[8*i+4]),
.Q3 (s_serdes[8*i+5]),
.Q2 (s_serdes[8*i+6]),
.Q1 (s_serdes[8*i+7]),
.OFB (),
.SHIFTOUT1 (),
.SHIFTOUT2 ());
// sort out necessary bits from iserdes
if (S == 4) begin : loop0a
assign mdataout[4*i+3:4*i] = m_serdes[8*i+7:8*i+4] ;
assign sdataout[4*i+3:4*i] = ~s_serdes[8*i+7:8*i+4] ;
end
if (S == 6) begin : loop0b
assign mdataout[6*i+5:6*i] = m_serdes[8*i+7:8*i+2] ;
assign sdataout[6*i+5:6*i] = ~s_serdes[8*i+7:8*i+2] ;
end
if (S == 8) begin : loop0c
assign mdataout[8*i+7:8*i] = m_serdes[8*i+7:8*i] ;
assign sdataout[8*i+7:8*i] = ~s_serdes[8*i+7:8*i] ;
end
end
endgenerate
endmodule

View File

@ -1,112 +0,0 @@
module serial_controller(
input clk,
input rst,
input [31:0]AXI_STR_TXD_0_tdata,
input AXI_STR_TXD_0_tvalid,
output reg AXI_STR_TXD_0_tready,
output i2c_sda,
output i2c_scl,
output reg spi_sdio,
output reg spi_sclk,
output reg[3:0] pga_cs,
output reg adc_cs
);
wire i2c_data_req, spi_data_req;
wire[7:0] fifo_rd_data;
assign fifo_rd_data = AXI_STR_TXD_0_tdata[7:0];
parameter[1:0] IDLE = 2'b00,
CONTROL_BYTE = 2'b01,
TRANSMIT_WAIT = 2'b10,
TRANSMIT = 2'b11;
reg[1:0] state = IDLE;
reg[2:0] mux_control;
reg en, spi_en, i2c_en;
reg sys_data_req;
always @(posedge clk) begin
case (state)
IDLE:
if (AXI_STR_TXD_0_tvalid) begin
state <= CONTROL_BYTE;
sys_data_req <= 1'b1;
end
else
state <= IDLE;
CONTROL_BYTE:
begin
state <= TRANSMIT_WAIT;
sys_data_req <= 1'b0;
mux_control <= fifo_rd_data[2:0];
end
TRANSMIT_WAIT:
if (AXI_STR_TXD_0_tvalid) begin
state <= TRANSMIT;
en <= 1'b1;
end
else
state <= TRANSMIT_WAIT;
TRANSMIT:
if (spi_done | i2c_done) begin
state <= IDLE;
en <= 1'b0;
end
else
state <= TRANSMIT;
endcase
end
always @(*)
begin
AXI_STR_TXD_0_tready = sys_data_req | i2c_data_req | spi_data_req;
spi_en = (~&mux_control) ? (en) : (1'b0);
i2c_en = (&mux_control) ? (en) : (1'b0);
spi_sdio = sdo;
spi_sclk = sclk;
case(mux_control) // pga_cs demux
3'b000: pga_cs = {cs,1'b1,1'b1,1'b1};
3'b001: pga_cs = {1'b1,cs,1'b1,1'b1};
3'b010: pga_cs = {1'b1,1'b1,cs,1'b1};
3'b011: pga_cs = {1'b1,1'b1,1'b1,cs};
default: pga_cs = 4'b1111;
endcase
adc_cs = (mux_control[2:1] == 2'b10) ? (cs) : (1'b1);
//TODO: Add program flash SPI muxes
end
I2C_Transmit I2C_Transmit(
.clk (clk),
.data (fifo_rd_data),
.data_ready (AXI_STR_TXD_0_tvalid),
.en (i2c_en),
.data_req (i2c_data_req),
.sda (i2c_sda),
.scl (i2c_scl),
.done (i2c_done)
);
SPI_Transmit SPI_Transmit(
.clk (clk),
.data (fifo_rd_data),
.data_ready (AXI_STR_TXD_0_tvalid),
.en (spi_en),
.data_req (spi_data_req),
.sdo (sdo),
.sclk (sclk),
.cs (cs),
.done (spi_done)
);
endmodule

View File

@ -1,603 +0,0 @@
#!/usr/bin/env tclsh
# Generate a Multiboot address table
#
# Inputs:
# - bitstream size
# - flash type
# - configuration data width
# - frequency (MHz)
# - flash density (Mbit)
#
# Assumptions:
# - The special configuration startup condition DCI_WAIT is assumed to be
# required and is included by default. This can be a significant factor
# in the spaceing between images, especially in smaller flash devices.
# This can be disable in the call to the NextBitstreamAddress procedure
# if you are confident that DCI_WAIT is not required in your design.
# If disabled, a small wait for PLL startup will be used instead.
# However, this cannot be disabled in the current design but the extra
# spacing required is small and likely not significant even in the
# smallest flash devices.
# - Using a sector size of 256 kB (smaller sectors will align)
# - timer image size = 1 kB
# - Only SPI and BPIx16 is supported (BPIx8 support not tested)
#
# TODO: Verify write_cfgmem settings and XDC contraints output
# Possible features:
# - Add a list of FPGA bitstream sizes
# - Automatically search for a bin file and get its size
# - Change verbose-ness so that it can be piped with other commands
# better (For example, it should be able to be output only the
# write_cfgmem command to stdout)
## Globals ##
set INSTRUCTIONS "
Usage: [info script]
This Tcl script calculates the multiboot address maps for using
timer barrier images for Multi-boot 7 series designs.
See XAPP1246 or XAPP1247 for more information
Usage:
Interactive mode:
[info script]
Interactive mode with given bitstream size in bytes:
[info script] <bitstream_size>
Batch mode (all arguments are required in the given order):
[info script] <flash_type> <data_width> <freq_mhz> <flash_size_mbit> <bitstream_size>
<flash_type> : Flash type: spi, bpi
<data_width> : Flash data width: 1, 2, 4, 8, 16
<freq_mhz> : Frequency of CCLK (enter highest frequency used)
<flash_size_mbit> : Size of flash device in Mbit (ex: 128, 256, 512, 1024)
<bitstream_size> : Size of bitstream in bytes. Get this from UG470 or
UG570. If compression is enabled and reading this
directly form the bitstream file itself, be aware that
subsequent builds can vary significantly in size and
this script will need to be re-run.
Interactive mode instructions:
- Select the parameters when prompted
- The first item listed is the default
- An empty answer will select the default
- Unless passed as the only command line argument, the
bitstream length defaults to 0.
"
## Option ranges and default values
# To change a default value, make it the first value in the list
set FLASH_TYPES [list spi bpi]
set FLASH_WIDTH [list 4 1 2 8 16]
set FREQ_MHZ_RANGE [list 100 3 150]
set FLASH_DENSITIES [list 256 32 64 128 512 1024 2048 4096 8192]
# Very rough ranges on valid bitstream sizes in bytes
set MIN_BIT_SIZE 131072 ; # 1 Mbit (in bytes)
set MAX_BIT_SIZE 536870912 ; # 4 Gbit (in bytes)
set BIT_SIZE_RANGE [list 0 $MIN_BIT_SIZE $MAX_BIT_SIZE]
# hexpr --
#
# Arguments:
# args: values to return formatted as hexidecimal
# All values are passed along to expr
#
# Results:
proc hexpr args {
uplevel "format \"0x%08X\" \"[expr $args] \""
}
# PromptForOption --
#
# Arguments:
# prompt: text to display to at prompt
# values: list of values to display and select from
# range: if this is true, treat values as a list of three integers:
# 0 - default
# 1 - minumum value
# 2 - maximum value
#
# Results: A valid response is returned from values
proc PromptForOption {prompt values {range 0}} {
while {1} {
puts -nonewline "${prompt} ( "
foreach i $values {
puts -nonewline "$i "
}
puts -nonewline ") : "
flush stdout;
if {[gets stdin line] < 0 && [eof stdin]} {
return -code error "end of file detected"
} elseif {[string length [string trim $line]] < 1} {
return [lindex $values 0]
} else {
if {$range} {
scan $line "%d" freq
if {$freq > [lindex $values 1] && $freq < [lindex $values 2]} {
return $freq
}
} else {
set value [string tolower [string trim $line]]
if {[lsearch $values $value] >= 0} {
return $value
}
}
}
puts "$line not recognized"
}
# shouldn't get here
error -code error "Failed to get a valid option"
}
# InteractiveMode --
#
# Arguments:
# bits: Optional size of bitstream (will be prompted otherwize)
#
# Results: A valid response is returned from values
proc InteractiveMode {{bits 0}} {
global INSTRUCTIONS
global FLASH_TYPES
global FLASH_WIDTH
global FREQ_MHZ_RANGE
global FLASH_DENSITIES
global BIT_SIZE_RANGE
set options {}
puts "$INSTRUCTIONS"
puts "Entering interactive mode\n"
set prompt "Enter flash type: "
lappend options [PromptForOption $prompt $FLASH_TYPES]
set prompt "Enter flash width (bits): "
lappend options [PromptForOption $prompt $FLASH_WIDTH]
set prompt "Enter CCLK frequency (MHz): "
lappend options [PromptForOption $prompt $FREQ_MHZ_RANGE 1]
set prompt "Enter Flash density in Mbit (2^20 bits):\n "
lappend options [PromptForOption $prompt $FLASH_DENSITIES]
if {$bits == 0} {
set prompt "Enter bitstream size in bytes:\n "
set size [PromptForOption $prompt $BIT_SIZE_RANGE 1]
while {$size == 0} {
puts "No default bitstream size available, please enter \
correct bitstream size"
set size [PromptForOption $prompt $BIT_SIZE_RANGE 1]
}
lappend options $size
} else {
lappend options $bits
}
return $options
}
# GetOptions --
#
# Arguments:
#
# Results: Interactive mode is run or command line arguments are processed for
# valid values
proc GetOptions {argc argv} {
global INSTRUCTIONS
global MIN_BIT_SIZE
global MAX_BIT_SIZE
if { $argc == 1 } {
if {![scan [lindex $argv 0] "%d" bit_size_bytes]} {
puts "Single argument must be an integer"
puts $INSTRUCTIONS
return -1
}
if { $bit_size_bytes < $MIN_BIT_SIZE || \
$bit_size_bytes > $MAX_BIT_SIZE } {
puts "\"[lindex $argv 0]\" is not a valid bitstream size"
puts "Expecting between $MIN_BIT_SIZE and $MAX_BIT_SIZE bytes"
puts $INSTRUCTIONS
return -1
} else {
set options [InteractiveMode $bit_size_bytes]
}
} elseif { $argc == 5 } {
set options {}
scan [lindex $argv 0] "%s" flash_type
scan [lindex $argv 1] "%d" data_width
scan [lindex $argv 2] "%d" freq_mhz
scan [lindex $argv 3] "%d" flash_size_mbit
scan [lindex $argv 4] "%d" bit_size_bytes
lappend options $flash_type
lappend options $data_width
lappend options $freq_mhz
lappend options $flash_size_mbit
lappend options $bit_size_bytes
} elseif { $argc == 0 } {
set options [InteractiveMode]
} else {
puts "Unrecognized argument list: $argv"
puts $INSTRUCTIONS
return -1
}
# puts "DEBUG(GetOptions): Options: $options"
return $options
}
# NextBitstreamAddress --
#
# Calculate the address for the next bitstream. There is a minimum buffer
# requirement between bitstreams as certain startup conditions can delay
# configuration. If a following bitstream inserts new configuration commands,
# it could cause a configuration failure of the first bitstream
#
# Arguments:
# bits: size of the bitstream
# start: start address for the bitstream (0 by default)
# width: (optional) Configuration width (defaults to 16)
# freq: (optional) Configuration frequency in MHz (defaults to 134)
# dci_wait: (optional) Is DCI wait needed. Should be set to 1 if any DCI is
# being used in the design. Recommended to leave this at the
# default unless no DCI is used in the design
# family: (optional) 7: 7 series, 8: UltraScale (defaults to 7)
# Safe to leave at 7 for UltraScale
#
# results:
# Returns the next address at which it is safe to place a new bitstream (such
# as the timer images)
proc NextBitstreamAddress {bits start {width 16} {freq_mhz 134} {dci_wait 1} \
{family 7}} {
# Constants
# Always assume at least PLL lock waitup is needed. This is quite small
set pll_tlockmax_us 200
# Use 256 kB sectors, smaller sectors may save a little bit of buffer
# space, but will likely cause problems if used on 256 kB sector devices
set sector_size [expr 256 * 2**10]
if {$family == 8} {
set dcu_wait_ms 4
} else {
set dcu_wait_ms 10
}
set dcu_wait_us [expr $dcu_wait_ms * 1000]
# DCI Wait is always larger then pll_tlockmax_us, use it if enabled
if {$dci_wait} {
set wait_time [expr $dcu_wait_us * pow(10, -6)]
} else {
set wait_time [expr $pll_tlockmax_us * pow(10, -6)]
}
set frequency [expr $freq_mhz * 10**6]
# Find the number CCLK cycles needed for the max wait time
set wait_cycles [expr int(ceil($wait_time * $frequency))]
# puts " -- Wait cycles: $wait_cycles"
# The extra bits needed for the buffer
set extra_bytes [expr ($wait_cycles * $width) / 8]
# int(ceil(($frequency * $width / 8)))]
# puts " -- Extra Bytes: $extra_bytes"
# Add the extra bytes to the bitstream size and get the end address
set bits_end [expr $bits + $start + $extra_bytes]
set end_sector [expr int(ceil((1.0 * $bits_end) / $sector_size))]
set end_address [expr $end_sector * $sector_size]
# puts " -- Next available address: [hexpr $end_address]"
return $end_address
}
# FirstTimerAddress --
#
# Calculate the first timer address based off the multiboot address
#
# Arguments:
# multiboot_address: Address of the multiboot image. This is the next "safe"
# sector after the golden bitstream
# Results:
# returns the address to place the first timer
proc FirstTimerAddress {multiboot_address} {
set timer_size 1024
return [expr $multiboot_address - $timer_size]
}
# WbstarAddress --
#
# Calculate the first timer address
#
# Arguments:
# multiboot_address: Address of the multiboot image. This is the next "safe"
# sector after the golden bitstream
# Results:
# returns the address for WBSTAR (BITSTREAM.CONFIG.NEXT_CONFIG_ADDR)
proc WbstarAddress {multiboot_address} {
set wbstar_offset 512
return [expr $multiboot_address - $wbstar_offset]
}
# CreateNext4Bytes --
#
# Formats 4 bytes for a bitstream SPI or BPIx16
#
# Arguments:
# bitswap (optional) - Swap the bits in the byte
#
# Results:
# return a single byte
proc CreateNext4Bytes {word {bitswap 0} {byteswap 0}} {
set return_string ""
# puts "DEBUG: Next hex string : $word"
switch $byteswap {
0 {
set byte_sequence {0 2 4 6}
}
1 {
set byte_sequence {2 0 6 4}
}
default {
error "Unknown byte swap pattern: $byteswap"
}
}
foreach i $byte_sequence {
set out_data [binary format H2 [string range $word $i [expr $i + 1]]]
binary scan $out_data B8 bin_string
# puts "DEBUG: Next byte : $bin_string"
if {$bitswap} {
append return_string [string reverse $bin_string]
} else {
append return_string $bin_string
}
}
# puts "DEBUG: Next string: $return_string"
return $return_string
}
# CreateTimers --
#
# Create the BIN files for the Timers
#
# Arguments:
# timer - either 1 or 2 for the timer to be built
# bitswap (optional) - Swap the bits in each byte
# byteswap (optional) - Swap the bytes (every other byte)
#
# Results:
# timer1.bin and timer2.bin are created.
#
# timer1.bin will be 1024 bytes with the bus width detect, sync word and timer
# values near the end of the .bin file.
#
# timer2.bin will be just over 256 bytes (includes 256 bytes of dummy words
# before the sync word
proc CreateTimers {timer {bitswap 0} {byteswap 0}} {
# set timer1_size 1024
#
set dummy_word "FFFFFFFF"
set sync_word "AA995566"
set bus_width_detect_word "000000BB"
set bus_width_word "11220044"
set noop_word "20000000"
set timer_word "30022001"
set timer_set_value [expr int(0x40000000)]
# puts "DEBUG(CreateTimers): timer_set_value: $timer_set_value"
if {$timer == "1"} {
set timer_filename timer1.bin
set header_size_words 242
set timer_count 0x4000
} else {
set timer_filename "timer${timer}.bin"
set header_size_words 1
set timer_count 1
}
puts "Writing Timer: $timer_filename"
set timer_list ""
# Add the dummy words
set i 0
while {$i < $header_size_words} {
incr i
lappend timer_list $dummy_word
}
# Here's the main content of the timer image
lappend timer_list $bus_width_detect_word
lappend timer_list $bus_width_word
lappend timer_list $dummy_word
lappend timer_list $dummy_word
lappend timer_list $sync_word
lappend timer_list $noop_word
lappend timer_list $noop_word
lappend timer_list $noop_word
lappend timer_list $timer_word
# Figure out the timer string
set timer_string [format "%08X" [expr $timer_set_value | $timer_count]]
lappend timer_list $timer_string
# Add a few dummy words and no-ops
lappend timer_list $noop_word
lappend timer_list $noop_word
lappend timer_list $dummy_word
lappend timer_list $dummy_word
set fp [open $timer_filename w]
fconfigure $fp -translation binary
foreach i $timer_list {
set next_word [CreateNext4Bytes $i $bitswap $byteswap]
puts -nonewline $fp [binary format B32 $next_word]
}
close $fp
}
# CompareAddress2Size --
#
# Check that given address is within the bounds of the flash device
#
# Arguments:
# address: address in bytes
# size : size of flash device in bits
#
# Results:
# Return the size difference in bytes (rounded up) between the address and
# size of the flash. Negative means address is with the flash density
proc CompareAddress2Size {address size_mbit} {
# convert address to bits
set size_bytes [expr ($size_mbit/8) * 2**20]
return [expr $address - $size_bytes]
}
## ---- Main (script entry) ----
set options [GetOptions $argc $argv]
if {$options == -1} {
exit -1
}
set type [lindex $options 0]
set width [lindex $options 1]
set freq_mhz [lindex $options 2]
set flash_size_mbit [lindex $options 3]
set bitsize_bytes [lindex $options 4]
puts "Flash type : [string toupper $type]"
puts "Flash width (bits) : $width"
puts "CCLK frequency (MHz): $freq_mhz"
puts "Flash density (Mbit): $flash_size_mbit"
puts "Bitstream size (B) : $bitsize_bytes"
# By default, do not swap bits or bytes
set bitswap 0
set byteswap 0
# Select the appropriate configuration mode
switch ${type}_${width} {
"spi_1" {
set interface "SPIx1"
}
"spi_2" {
set interface "SPIx2"
}
"spi_4" {
set interface "SPIx4"
}
"spi_8" {
set interface "SPIx8"
}
"bpi_8" {
set interface "BPIx8"
set bitswap 1
}
"bpi_16" {
set interface "BPIx16"
set bitswap 1
set byteswap 1
}
default {
error "Unknown width and flash type combo: $type/$width"
}
}
# Create the timer images
puts ""
CreateTimers 1 $bitswap $byteswap
CreateTimers 2 $bitswap $byteswap
set multiboot_address [NextBitstreamAddress $bitsize_bytes 0 $width $freq_mhz 0]
set timer1_address [FirstTimerAddress $multiboot_address]
set timer2_address [NextBitstreamAddress $bitsize_bytes $multiboot_address \
$width $freq_mhz 0]
# Check that the sizes make sense
set crit_warn "\nCritical Warning: The"
set beyond_msg "address is beyond the end of the flash device"
set size_check [CompareAddress2Size $timer1_address $flash_size_mbit]
if {$size_check > 0} {
puts "$crit_warn Timer1 $beyond_msg"
}
set size_check [CompareAddress2Size $multiboot_address $flash_size_mbit]
if {$size_check > 0} {
puts "$crit_warn Multiboot start $beyond_msg"
}
set size_check [CompareAddress2Size $timer2_address $flash_size_mbit]
if {$size_check > 0} {
puts "$crit_warn Timer2 $beyond_msg"
}
# Adjust for BPI addressing if required
if {[string match $interface "BPIx16"]} {
set multiboot_address [expr $multiboot_address >> 1]
set timer1_address [expr $timer1_address >> 1]
set timer2_address [expr $timer2_address >> 1]
}
puts ""
puts "Golden bitstream address: [hexpr 0]"
puts "Timer1 image address : [hexpr $timer1_address]"
puts "Multiboot image address : [hexpr $multiboot_address]"
puts "Timer2 image address : [hexpr $timer2_address]"
# Write out the write_cfgmem command line
puts ""
puts "write_cfgmem command:"
puts -nonewline "write_cfgmem -format mcs -size [expr ($flash_size_mbit/8)]"
puts -nonewline " -interface $interface"
puts -nonewline " -loadbit \""
puts -nonewline "up [hexpr 0] <golden>"
puts -nonewline " up [hexpr $multiboot_address] <multiboot>\" "
puts -nonewline " -loaddata \""
puts -nonewline "up [hexpr $timer1_address] timer1.bin"
puts -nonewline " up [hexpr $timer2_address] timer2.bin\""
puts -nonewline " <output_mcs>"
puts ""

View File

@ -1,101 +0,0 @@
*************************************************************************
____ ____
/ /\/ /
/___/ \ /
\ \ \/ © Copyright 2015 Xilinx, Inc. All rights reserved.
\ \ This file contains confidential and proprietary
/ / information of Xilinx, Inc. and is protected under U.S.
/___/ /\ and international copyright and other intellectual
\ \ / \ property laws.
\___\/\___\
*************************************************************************
Vendor: Xilinx
Current readme.txt Version: 1.0.0
Date Last Modified: 19April2015
Date Created: 19April2015
Associated Filename: xapp1247.zip
Associated Document: XAPP1247, MultiBoot with 7Series FPGAs using SPI Interface
Supported Device(s): 7Series
*************************************************************************
Disclaimer:
This disclaimer is not a license and does not grant any rights to
the materials distributed herewith. Except as otherwise provided in
a valid license issued to you by Xilinx, and to the maximum extent
permitted by applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE
"AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
(2) Xilinx shall not be liable (whether in contract or tort,
including negligence, or under any other theory of liability) for
any loss or damage of any kind or nature related to, arising under
or in connection with these materials, including for any direct, or
any indirect, special, incidental, or consequential loss or damage
(including loss of data, profits, goodwill, or any type of loss or
damage suffered as a result of any action brought by a third party)
even if such damage or loss was reasonably foreseeable or Xilinx
had been advised of the possibility of the same.
Critical Applications:
Xilinx products are not designed or intended to be fail-safe, or
for use in any application requiring fail-safe performance, such as
life-support or safety devices or systems, Class III medical
devices, nuclear facilities, applications related to the deployment
of airbags, or any other applications that could lead to death,
personal injury, or severe property or environmental damage
(individually and collectively, "Critical Applications"). Customer
assumes the sole risk and liability of any use of Xilinx products
in Critical Applications, subject only to applicable laws and
regulations governing limitations on product liability.
THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS
FILE AT ALL TIMES.
*************************************************************************
This readme file contains these sections:
1. REVISION HISTORY
2. OVERVIEW
3. SOFTWARE TOOLS AND SYSTEM REQUIREMENTS
4. DESIGN FILE HIERARCHY
5. SUPPORT
1. REVISION HISTORY
Readme
Date Version Revision Description
=========================================================================
19April2015 1.0 Initial Xilinx release.
=========================================================================
2. OVERVIEW
This readme describes how to use the files that come with XAPP1247.
multiboot_address_table directory contains tcl script to generate Barrier images along with address map locations of images in flash memory device.
3. SOFTWARE TOOLS AND SYSTEM REQUIREMENTS
* Xilinx Vivado Design Suite 2015.1
4. DESIGN FILE HIERARCHY
\multiboot_address_table
| This folder contains multiboot_address_table.tcl script to generate barrier/timer
| images. For insturcitons how to use this script refer to Advanced section of xapp1247.
5. SUPPORT
To obtain technical support for this reference design, go to
www.xilinx.com/support to locate answers to known issues in the Xilinx
Answers Database or to create a WebCase.

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
===================================
Configuration Memory information
===================================
File Format MCS
Interface SPIX4
Size 32M
Start Address 0x00000000
End Address 0x01FFFFFF
Addr1 Addr2 Date File(s)
0x00000000 0x002620D3 Sep 13 00:41:17 2024 ./output/xdma_prj_100t_gold.bit
0x0097FC00 0x0097FFFF Apr 13 15:25:20 2024 ./cfg/timer1.bin
0x00980000 0x00BE20D3 Sep 13 00:40:56 2024 ./output/xdma_prj_100t.bit
0x01300000 0x0130003B Apr 13 15:25:20 2024 ./cfg/timer2.bin

Some files were not shown because too many files have changed in this diff Show More