axi_ad9361/tdd: Update the synchronization logic

The master will regenerate a sync pulse periodically. The period can be defined by software.
main
Istvan Csomortani 2015-08-19 12:21:23 +03:00
parent bcee3e04d4
commit 10d9de39a1
10 changed files with 127 additions and 129 deletions

View File

@ -113,8 +113,8 @@ module axi_ad9361 (
enable,
txnrx,
tdd_sync_req,
tdd_sync_ack,
tdd_sync_out,
tdd_sync_in,
// axi interface
@ -232,8 +232,8 @@ module axi_ad9361 (
output enable;
output txnrx;
inout tdd_sync_req;
inout tdd_sync_ack;
output tdd_sync_out;
input tdd_sync_in;
// axi interface
@ -409,8 +409,8 @@ module axi_ad9361 (
.tdd_tx_rf_en(tdd_tx_rf_en_s),
.tdd_enabled (tdd_enabled),
.tdd_status(tdd_status_s),
.tdd_sync_req(tdd_sync_req),
.tdd_sync_ack(tdd_sync_ack),
.tdd_sync_out(tdd_sync_out),
.tdd_sync_in(tdd_sync_in),
.tx_valid_i0(dac_valid_i0_s),
.tx_valid_q0(dac_valid_q0_s),
.tx_valid_i1(dac_valid_i1_s),

View File

@ -60,8 +60,8 @@ module axi_ad9361_tdd (
// sync signals
tdd_sync_req,
tdd_sync_ack,
tdd_sync_out,
tdd_sync_in,
// tx/rx data flow control
@ -114,8 +114,8 @@ module axi_ad9361_tdd (
output tdd_enabled;
input [ 7:0] tdd_status;
inout tdd_sync_req;
inout tdd_sync_ack;
output tdd_sync_out;
input tdd_sync_in;
// tx data flow control
@ -157,7 +157,6 @@ module axi_ad9361_tdd (
output [41:0] tdd_dbg;
reg tdd_slave_synced = 1'b0;
reg tdd_sync_o = 1'b0;
// internal signals
@ -174,6 +173,7 @@ module axi_ad9361_tdd (
wire [23:0] tdd_frame_length_s;
wire tdd_terminal_type_s;
wire tdd_sync_enable_s;
wire [31:0] tdd_sync_period_s;
wire [23:0] tdd_vco_rx_on_1_s;
wire [23:0] tdd_vco_rx_off_1_s;
wire [23:0] tdd_vco_tx_on_1_s;
@ -194,12 +194,13 @@ module axi_ad9361_tdd (
wire [23:0] tdd_tx_off_2_s;
wire [23:0] tdd_tx_dp_on_2_s;
wire [23:0] tdd_tx_dp_off_2_s;
wire tdd_resync_s;
wire [23:0] tdd_counter_status;
wire tdd_tx_dp_en_s;
assign tdd_dbg = {tdd_counter_status, tdd_enable_s, tdd_tx_dp_en_s,
assign tdd_dbg = {tdd_counter_status, tdd_enable_s, tdd_enable_synced_s, tdd_tx_dp_en_s,
tdd_rx_vco_en, tdd_tx_vco_en, tdd_rx_rf_en, tdd_tx_rf_en};
// tx/rx data flow control
@ -240,6 +241,7 @@ module axi_ad9361_tdd (
.tdd_frame_length(tdd_frame_length_s),
.tdd_terminal_type(tdd_terminal_type_s),
.tdd_sync_enable(tdd_sync_enable_s),
.tdd_sync_period(tdd_sync_period_s),
.tdd_vco_rx_on_1(tdd_vco_rx_on_1_s),
.tdd_vco_rx_off_1(tdd_vco_rx_off_1_s),
.tdd_vco_tx_on_1(tdd_vco_tx_on_1_s),
@ -282,6 +284,7 @@ module axi_ad9361_tdd (
.tdd_burst_count(tdd_burst_count_s),
.tdd_rx_only(tdd_rx_only_s),
.tdd_tx_only(tdd_tx_only_s),
.tdd_resync (tdd_resync_s),
.tdd_vco_rx_on_1(tdd_vco_rx_on_1_s),
.tdd_vco_rx_off_1(tdd_vco_rx_off_1_s),
.tdd_vco_tx_on_1(tdd_vco_tx_on_1_s),
@ -312,13 +315,14 @@ module axi_ad9361_tdd (
ad_tdd_sync i_tdd_sync (
.clk(clk),
.rst(rst),
.tdd_sync_en(tdd_sync_enable_s),
.tdd_term_type(tdd_terminal_type_s),
.tdd_enable_in(tdd_enable_s),
.tdd_enable_out(tdd_enable_synced_s),
.sync_req(tdd_sync_req),
.sync_ack(tdd_sync_ack),
.sync_dbg(tdd_sync_dbg)
.sync_en(tdd_sync_enable_s),
.device_type(tdd_terminal_type_s),
.sync_period(tdd_sync_period_s),
.enable_in(tdd_enable_s),
.enable_out(tdd_enable_synced_s),
.sync_out(tdd_sync_out),
.sync_in(tdd_sync_in),
.resync(tdd_resync_s)
);
endmodule

View File

@ -75,6 +75,7 @@ module ad_tdd_control(
tdd_tx_off_2,
tdd_tx_dp_on_2,
tdd_tx_dp_off_2,
tdd_resync,
// TDD control signals
@ -123,6 +124,7 @@ module ad_tdd_control(
input [23:0] tdd_tx_off_2;
input [23:0] tdd_tx_dp_on_2;
input [23:0] tdd_tx_dp_off_2;
input tdd_resync;
output tdd_tx_dp_en; // initiate vco tx2rx switch
output tdd_rx_vco_en; // initiate vco rx2tx switch
@ -207,6 +209,11 @@ module ad_tdd_control(
tdd_counter_state <= ON;
end else
// resync slave to master
if (tdd_resync == 1'b1) begin
tdd_counter <= 24'b0;
end
// free running counter
if (tdd_counter_state == ON) begin
if (tdd_counter == tdd_frame_length) begin

View File

@ -47,121 +47,94 @@ module ad_tdd_sync (
// control signals
tdd_sync_en, // synchronization enabled
tdd_term_type, // master or slave
tdd_enable_in, // tdd_enable signal asserted by software
tdd_enable_out, // synchronized tdd_enable
sync_en, // synchronization enabled
device_type, // master or slave
sync_period, // periodicity of the sync pulse,
enable_in, // tdd enable signal asserted by software
enable_out, // synchronized tdd_enable
// sync interface
sync_req, // sync request generated by master
sync_ack, // sync acknowledge generated by slave
sync_out, // sync output for slave
sync_in, // sync input
// debug
sync_dbg
resync // resync pulse for slave device
);
input clk;
input rst;
input tdd_sync_en;
input tdd_term_type;
input tdd_enable_in;
output tdd_enable_out;
input sync_en;
input device_type;
input [31:0] sync_period;
inout sync_req;
inout sync_ack;
input enable_in;
output enable_out;
output [5:0] sync_dbg;
output sync_out;
input sync_in;
reg tdd_enable_out = 1'b0;
reg tdd_enable_synced = 1'b0;
reg tdd_enable_d = 1'b0;
reg sync_req_i = 1'b0;
reg sync_ack_i = 1'b0;
output resync;
// internal registers
reg enable_out = 1'b0;
reg enable_synced = 1'b0;
reg sync_in_d = 1'b0;
reg sync_out = 1'b0;
reg resync = 1'b0;
reg [ 2:0] pulse_width = 3'h7;
wire sync_ack_o_s;
wire sync_req_o_s;
wire sync_req_t_s;
wire sync_ack_t_s;
reg [31:0] pulse_counter = 32'h0;
// the sync module can be bypassed
always @(posedge clk) begin
if (rst == 1) begin
tdd_enable_out <= 1'b0;
enable_out <= 1'b0;
end else begin
tdd_enable_out <= (tdd_sync_en) ? tdd_enable_synced : tdd_enable_in;
enable_out <= (sync_en) ? enable_synced : enable_in;
end
end
// iobuffers for the syncronization lines
assign sync_req_t_s = ~tdd_term_type;
assign sync_ack_t_s = tdd_term_type;
assign sync_dbg = {sync_ack_i_s,
sync_ack_o_s,
sync_ack_t_s,
sync_req_i,
sync_req_o_s,
sync_req_t_s};
ad_iobuf #(
.DATA_WIDTH(1)
) i_sync_req_iobuf (
.dio_t (sync_req_t_s),
.dio_i (sync_req_i),
.dio_o (sync_req_o_s),
.dio_p (sync_req)
);
ad_iobuf #(
.DATA_WIDTH(1)
) i_sync_ack_iobuf (
.dio_t (sync_ack_i_s),
.dio_i (sync_ack_i),
.dio_o (sync_ack_o_s),
.dio_p (sync_ack)
);
// generate sync pulse
always @(posedge clk) begin
if(rst == 1) begin
tdd_enable_d <= 1'b0;
sync_req_i <= 1'b0;
sync_ack_i <= 1'b0;
pulse_counter <= 0;
pulse_width <= 3'h7;
sync_out <= 1'h0;
end else begin
tdd_enable_d <= tdd_enable_in;
// device is master
if (tdd_term_type == 1) begin
if (~tdd_enable_d & tdd_enable_in == 1'b1) begin // generate sync request
sync_req_i <= 1'b1;
pulse_width <= 1'b0;
if (device_type == 1) begin
pulse_counter <= (pulse_counter < sync_period) ? pulse_counter + 1 : 32'h0;
if(pulse_counter == sync_period) begin
sync_out <= enable_in;
pulse_width <= 3'h0;
end else begin
pulse_width <= (pulse_width < 3'h7) ? pulse_width + 1 : pulse_width;
sync_req_i <= (pulse_width == 3'h7) ? 1'b0 : 1'b1;
sync_out <= (pulse_width == 3'h7) ? 0 : enable_in;
end
end
end
end
if (sync_ack_o_s == 1'b1) begin // sync acknowledge arrived
tdd_enable_synced <= tdd_enable_in;
// syncronize enalbe_in and generate resync for slave
always @(posedge clk) begin
sync_in_d <= sync_in;
if(device_type == 1'b1) begin
enable_synced <= enable_in;
resync <= 1'b0;
end else begin
tdd_enable_synced <= (tdd_enable_in == 1'b0) ? 1'b0 : tdd_enable_synced;
end
// device is slave
if (~sync_in_d & sync_in) begin
enable_synced <= enable_in;
resync <= 1'b1;
end else begin
if (sync_req_o_s == 1'b1) begin
tdd_enable_synced <= tdd_enable_in;
sync_ack_i <= 1'b1;
end else begin
tdd_enable_synced <= (tdd_enable_in == 1'b0) ? 1'b0 : tdd_enable_synced;
sync_ack_i <= 1'b0;
end
resync <= 1'b0;
end
end
end

View File

@ -56,6 +56,7 @@ module up_tdd_cntrl (
tdd_frame_length,
tdd_terminal_type,
tdd_sync_enable,
tdd_sync_period,
tdd_vco_rx_on_1,
tdd_vco_rx_off_1,
tdd_vco_tx_on_1,
@ -111,6 +112,7 @@ module up_tdd_cntrl (
output [23:0] tdd_frame_length;
output tdd_terminal_type;
output tdd_sync_enable;
output [31:0] tdd_sync_period;
output [23:0] tdd_vco_rx_on_1;
output [23:0] tdd_vco_rx_off_1;
output [23:0] tdd_vco_tx_on_1;
@ -162,6 +164,7 @@ module up_tdd_cntrl (
reg up_tdd_gated_rx_dmapath = 1'h0;
reg up_tdd_terminal_type = 1'h0;
reg up_tdd_sync_enable = 1'h0;
reg [31:0] up_tdd_sync_period = 32'h0;
reg [ 7:0] up_tdd_burst_count = 8'h0;
reg [23:0] up_tdd_counter_init = 24'h0;
@ -214,6 +217,7 @@ module up_tdd_cntrl (
up_tdd_gated_rx_dmapath <= 1'h0;
up_tdd_terminal_type <= 1'h0;
up_tdd_sync_enable <= 1'h0;
up_tdd_sync_period <= 32'h0;
up_tdd_counter_init <= 24'h0;
up_tdd_frame_length <= 24'h0;
up_tdd_burst_count <= 8'h0;
@ -258,6 +262,9 @@ module up_tdd_cntrl (
up_tdd_terminal_type <= up_wdata[1];
up_tdd_sync_enable <= up_wdata[0];
end
if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h15)) begin
up_tdd_sync_period <= up_wdata;
end
if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h20)) begin
up_tdd_vco_rx_on_1 <= up_wdata[23:0];
end
@ -342,6 +349,7 @@ module up_tdd_cntrl (
8'h13: up_rdata <= { 8'h0, up_tdd_frame_length};
8'h14: up_rdata <= {30'h0, up_tdd_terminal_type,
up_tdd_sync_enable};
8'h15: up_rdata <= up_tdd_sync_period;
8'h18: up_rdata <= {24'h0, up_tdd_status_s};
8'h20: up_rdata <= { 8'h0, up_tdd_vco_rx_on_1};
8'h21: up_rdata <= { 8'h0, up_tdd_vco_rx_off_1};
@ -371,7 +379,7 @@ module up_tdd_cntrl (
// rf tdd control signal CDC
up_xfer_cntrl #(.DATA_WIDTH(16)) i_tdd_control (
up_xfer_cntrl #(.DATA_WIDTH(48)) i_tdd_control (
.up_rstn(up_rstn),
.up_clk(up_clk),
.up_data_cntrl({up_tdd_enable,
@ -382,7 +390,8 @@ module up_tdd_cntrl (
up_tdd_gated_tx_dmapath,
up_tdd_burst_count,
up_tdd_terminal_type,
up_tdd_sync_enable
up_tdd_sync_enable,
up_tdd_sync_period
}),
.up_xfer_done(),
.d_rst(rst),
@ -395,7 +404,8 @@ module up_tdd_cntrl (
tdd_gated_tx_dmapath,
tdd_burst_count,
tdd_terminal_type,
tdd_sync_enable
tdd_sync_enable,
tdd_sync_period
}));
up_xfer_cntrl #(.DATA_WIDTH(528)) i_tdd_counter_values (

View File

@ -19,8 +19,8 @@ create_bd_port -dir O enable
create_bd_port -dir O txnrx
create_bd_port -dir O tdd_enabled
create_bd_port -dir IO tdd_sync_req
create_bd_port -dir IO tdd_sync_ack
create_bd_port -dir O tdd_sync_out
create_bd_port -dir I tdd_sync_in
# ad9361 core
@ -139,8 +139,8 @@ ad_connect util_ad9361_dac_upack/dac_data_3 axi_ad9361/dac_data_q1
ad_connect util_ad9361_dac_upack/dac_valid axi_ad9361_dac_dma/fifo_rd_en
ad_connect util_ad9361_dac_upack/dac_data axi_ad9361_dac_dma/fifo_rd_dout
ad_connect axi_ad9361_dac_dma/fifo_rd_underflow axi_ad9361/dac_dunf
ad_connect tdd_sync_req axi_ad9361/tdd_sync_req
ad_connect tdd_sync_ack axi_ad9361/tdd_sync_ack
ad_connect tdd_sync_out axi_ad9361/tdd_sync_out
ad_connect tdd_sync_in axi_ad9361/tdd_sync_in
ad_connect tdd_enabled axi_ad9361/tdd_enabled

View File

@ -36,9 +36,8 @@ set_property -dict {PACKAGE_PIN B17 IOSTANDARD LVDS} [get_ports tx_data_o
set_property -dict {PACKAGE_PIN A17 IOSTANDARD LVDS} [get_ports tx_data_out_n[5]] ; ## IO_L18N_T2_AD13N_35
set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS18} [get_ports enable] ; ## IO_L11P_T1_SRCC_35
set_property -dict {PACKAGE_PIN F14 IOSTANDARD LVCMOS18} [get_ports txnrx] ; ## IO_L11N_T1_SRCC_35
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD LVCMOS25} [get_ports tdd_sync_req] ; ## IO_L24_13_JX2_N
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS25} [get_ports tdd_sync_ack] ; ## IO_L23_13_JX2_N
set_property -dict {PACKAGE_PIN AA18 IOSTANDARD LVCMOS25} [get_ports tdd_sync_out] ; ## IO_L24_13_JX2_N
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS25} [get_ports tdd_sync_in] ; ## IO_L23_13_JX2_N
set_property -dict {PACKAGE_PIN D13 IOSTANDARD LVCMOS18} [get_ports gpio_status[0]] ; ## IO_L19P_T3_35
set_property -dict {PACKAGE_PIN C13 IOSTANDARD LVCMOS18} [get_ports gpio_status[1]] ; ## IO_L19N_T3_VREF_35

View File

@ -109,8 +109,8 @@ module system_top (
tx_data_out_n,
enable,
txnrx,
tdd_sync_req,
tdd_sync_ack,
tdd_sync_out,
tdd_sync_in,
gpio_rf0,
gpio_rf1,
@ -198,8 +198,8 @@ module system_top (
output [ 5:0] tx_data_out_n;
output enable;
output txnrx;
inout tdd_sync_req;
inout tdd_sync_ack;
output tdd_sync_out;
input tdd_sync_in;
inout gpio_rf0;
inout gpio_rf1;
@ -364,8 +364,8 @@ module system_top (
.tx_frame_out_p (tx_frame_out_p),
.txnrx (txnrx_s),
.tdd_enabled (tdd_enabled_s),
.tdd_sync_req (tdd_sync_req),
.tdd_sync_ack (tdd_sync_ack));
.tdd_sync_out (tdd_sync_out),
.tdd_sync_in (tdd_sync_in));
endmodule

View File

@ -36,8 +36,8 @@ set_property -dict {PACKAGE_PIN AB15 IOSTANDARD LVDS_25} [get_ports tx_data_o
set_property -dict {PACKAGE_PIN AB14 IOSTANDARD LVDS_25} [get_ports tx_data_out_n[5]] ; ## H20 FMC_LPC_LA15_N
set_property -dict {PACKAGE_PIN AE18 IOSTANDARD LVCMOS25} [get_ports enable] ; ## G18 FMC_LPC_LA16_P
set_property -dict {PACKAGE_PIN AE17 IOSTANDARD LVCMOS25} [get_ports txnrx] ; ## G19 FMC_LPC_LA16_N
set_property -dict {PACKAGE_PIN AC19 IOSTANDARD LVCMOS25} [get_ports tdd_sync_req] ; ## PMOD1_7_LS
set_property -dict {PACKAGE_PIN AA20 IOSTANDARD LVCMOS25} [get_ports tdd_sync_ack] ; ## PMOD1_5_LS
set_property -dict {PACKAGE_PIN AC19 IOSTANDARD LVCMOS25} [get_ports tdd_sync_out] ; ## PMOD1_7_LS
set_property -dict {PACKAGE_PIN AA20 IOSTANDARD LVCMOS25} [get_ports tdd_sync_in] ; ## PMOD1_5_LS
set_property -dict {PACKAGE_PIN AG26 IOSTANDARD LVCMOS25} [get_ports gpio_status[0]] ; ## G21 FMC_LPC_LA20_P
set_property -dict {PACKAGE_PIN AG27 IOSTANDARD LVCMOS25} [get_ports gpio_status[1]] ; ## G22 FMC_LPC_LA20_N

View File

@ -92,8 +92,8 @@ module system_top (
enable,
txnrx,
tdd_sync_req,
tdd_sync_ack,
tdd_sync_out,
tdd_sync_in,
gpio_muxout_tx,
gpio_muxout_rx,
@ -164,8 +164,8 @@ module system_top (
output enable;
output txnrx;
inout tdd_sync_req;
inout tdd_sync_ack;
output tdd_sync_out;
input tdd_sync_in;
inout gpio_muxout_tx;
inout gpio_muxout_rx;
@ -243,6 +243,11 @@ module system_top (
.dio_o (gpio_i[14:0]),
.dio_p (gpio_bd));
//========================================================
// debug syncronization pulses
//========================================================
system_wrapper i_system_wrapper (
.ddr_addr (ddr_addr),
.ddr_ba (ddr_ba),
@ -321,8 +326,8 @@ module system_top (
.tx_frame_out_p (tx_frame_out_p),
.txnrx (txnrx_s),
.tdd_enabled (tdd_enabled_s),
.tdd_sync_req(tdd_sync_req),
.tdd_sync_ack(tdd_sync_ack));
.tdd_sync_out(tdd_sync_out),
.tdd_sync_in(tdd_sync_in));
endmodule