ad_tdd_sync: Update the synchronization logic

The synchronization interface is a single bidirectional line. Output for Master, input for Slave.
The sync_period value is relative to frame length and the digital interface clock. The actual synchronization
period will be: sync_period * frame_length * fb_clock_cycle
main
Istvan Csomortani 2015-09-09 12:31:58 +03:00
parent 5a566b9e5d
commit 85ffc25ec5
5 changed files with 87 additions and 56 deletions

View File

@ -69,8 +69,9 @@ module axi_ad9361 (
// tdd sync (1s pulse)
tdd_sync_out,
tdd_sync_in,
tdd_sync_o,
tdd_sync_i,
tdd_sync_t,
// delay clock
@ -192,8 +193,9 @@ module axi_ad9361 (
// tdd sync (1s pulse)
output tdd_sync_out;
input tdd_sync_in;
output tdd_sync_o;
input tdd_sync_i;
output tdd_sync_t;
// delay clock
@ -423,8 +425,9 @@ module axi_ad9361 (
.tdd_tx_rf_en (tdd_tx_rf_en_s),
.tdd_enabled (tdd_mode_s),
.tdd_status (tdd_status_s),
.tdd_sync_out (tdd_sync_out),
.tdd_sync_in (tdd_sync_in),
.tdd_sync_o (tdd_sync_o),
.tdd_sync_i (tdd_sync_i),
.tdd_sync_t (tdd_sync_t),
.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,9 @@ module axi_ad9361_tdd (
// sync signals
tdd_sync_out,
tdd_sync_in,
tdd_sync_o,
tdd_sync_i,
tdd_sync_t,
// tx/rx data flow control
@ -114,8 +115,9 @@ module axi_ad9361_tdd (
output tdd_enabled;
input [ 7:0] tdd_status;
output tdd_sync_out;
input tdd_sync_in;
output tdd_sync_o;
input tdd_sync_i;
output tdd_sync_t;
// tx data flow control
@ -173,7 +175,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 [ 7: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;
@ -195,12 +197,13 @@ module axi_ad9361_tdd (
wire [23:0] tdd_tx_dp_on_2_s;
wire [23:0] tdd_tx_dp_off_2_s;
wire tdd_resync_s;
wire tdd_endof_frame_s;
wire [23:0] tdd_counter_status;
wire tdd_tx_dp_en_s;
assign tdd_dbg = {tdd_counter_status, tdd_enable_s, tdd_enable_synced_s, tdd_tx_dp_en_s,
assign tdd_dbg = {tdd_counter_status, tdd_enable_s, tdd_sync_i, 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
@ -291,6 +294,7 @@ module axi_ad9361_tdd (
.tdd_rx_only(tdd_rx_only_s),
.tdd_tx_only(tdd_tx_only_s),
.tdd_resync (tdd_resync_s),
.tdd_endof_frame (tdd_endof_frame_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),
@ -326,9 +330,11 @@ module axi_ad9361_tdd (
.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)
.sync_o(tdd_sync_o),
.sync_i(tdd_sync_i),
.sync_t(tdd_sync_t),
.resync(tdd_resync_s),
.endof_frame (tdd_endof_frame_s)
);
endmodule

View File

@ -76,6 +76,7 @@ module ad_tdd_control(
tdd_tx_dp_on_2,
tdd_tx_dp_off_2,
tdd_resync,
tdd_endof_frame,
// TDD control signals
@ -128,6 +129,7 @@ module ad_tdd_control(
input [23:0] tdd_tx_dp_on_2;
input [23:0] tdd_tx_dp_off_2;
input tdd_resync;
output tdd_endof_frame;
output tdd_tx_dp_en; // initiate vco tx2rx switch
output tdd_rx_vco_en; // initiate vco rx2tx switch
@ -172,6 +174,7 @@ module ad_tdd_control(
reg counter_at_tdd_tx_off_2 = 1'b0;
reg counter_at_tdd_tx_dp_on_2 = 1'b0;
reg counter_at_tdd_tx_dp_off_2 = 1'b0;
reg tdd_endof_frame = 1'h0;
reg tdd_enable_d = 1'h0;
@ -229,15 +232,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
tdd_counter <= 22'h0;
tdd_endof_frame <= 1'b1;
tdd_counter <= 24'h0;
if (tdd_burst_counter > 1) begin // inside a burst
tdd_burst_counter <= tdd_burst_counter - 1;
tdd_counter_state <= ON;
@ -253,7 +252,8 @@ module ad_tdd_control(
end
end
else begin
tdd_counter <= tdd_counter + 1;
tdd_endof_frame <= 1'b0;
tdd_counter <= (tdd_resync == 1'b1) ? 24'h0 : tdd_counter + 1;
end
end
end

View File

@ -50,14 +50,16 @@ module ad_tdd_sync (
sync_en, // synchronization enabled
device_type, // master or slave
sync_period, // periodicity of the sync pulse,
endof_frame,
enable_in, // tdd enable signal asserted by software
enable_out, // synchronized tdd_enable
// sync interface
sync_out, // sync output for slave
sync_in, // sync input
sync_o, // sync output
sync_i, // sync input
sync_t, // sync 3-state
resync // resync pulse for slave device
@ -68,28 +70,29 @@ module ad_tdd_sync (
input sync_en;
input device_type;
input [31:0] sync_period;
input [ 7:0] sync_period;
input endof_frame;
input enable_in;
output enable_out;
output sync_out;
input sync_in;
output sync_o;
input sync_i;
output sync_t;
output resync;
// internal registers
reg enable_in_d = 1'b0;
reg enable_out = 1'b0;
reg enable_synced = 1'b0;
reg sync_in_d = 1'b0;
reg sync_out = 1'b0;
reg sync_i_d = 1'b0;
reg sync_o = 1'b0;
reg resync = 1'b0;
reg [ 2:0] pulse_width = 3'h7;
reg [31:0] pulse_counter = 32'h0;
reg [ 7:0] frame_counter = 32'h0;
reg [ 2:0] pulse_counter = 3'h7;
reg pulse_en = 1'h0;
// the sync module can be bypassed
@ -101,36 +104,55 @@ module ad_tdd_sync (
end
end
// generate sync pulse
// sync pulse is generated at every posedge of enable_in
// OR after [sync_period] number of endof_frame
always @(posedge clk) begin
if(rst == 1) begin
pulse_counter <= 0;
pulse_width <= 3'h7;
sync_out <= 1'h0;
if (rst == 1) begin
enable_in_d <= 1'b0;
frame_counter <= 0;
pulse_en <= 0;
end else begin
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_out <= (pulse_width == 3'h7) ? 0 : enable_in;
end
enable_in_d <= enable_in;
if(endof_frame == 1) begin
frame_counter <= frame_counter + 1;
end
if((frame_counter == sync_period) || (~enable_in_d & enable_in == 1)) begin
frame_counter <= 1'b0;
pulse_en <= 1'b1;
end else begin
pulse_en <= 1'b0;
end
end
end
// generate pulse with a specified width
always @(posedge clk) begin
if (rst == 1) begin
pulse_counter <= 0;
sync_o <= 0;
end else begin
if(pulse_en == 1'b1) begin
sync_o <= 1'b1;
end else if(pulse_counter == 3'h7) begin
sync_o <= 1'b0;
end
pulse_counter <= (sync_o == 1'b1) ? pulse_counter + 1 : 3'h0;
end
end
assign sync_t = ~device_type;
// syncronize enalbe_in and generate resync for slave
always @(posedge clk) begin
sync_in_d <= sync_in;
sync_i_d <= sync_i;
if(device_type == 1'b1) begin
enable_synced <= enable_in;
resync <= 1'b0;
end else begin
if (~sync_in_d & sync_in) begin
if (~sync_i_d & sync_i) begin
enable_synced <= enable_in;
resync <= 1'b1;
end else begin

View File

@ -112,7 +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 [ 7: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;
@ -164,7 +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_sync_period = 8'h0;
reg [ 7:0] up_tdd_burst_count = 8'h0;
reg [23:0] up_tdd_counter_init = 24'h0;
@ -217,7 +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_sync_period <= 8'h0;
up_tdd_counter_init <= 24'h0;
up_tdd_frame_length <= 24'h0;
up_tdd_burst_count <= 8'h0;
@ -263,7 +263,7 @@ module up_tdd_cntrl (
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;
up_tdd_sync_period <= up_wdata[7:0];
end
if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h20)) begin
up_tdd_vco_rx_on_1 <= up_wdata[23:0];
@ -349,7 +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'h15: up_rdata <= {24'h0, 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};
@ -379,7 +379,7 @@ module up_tdd_cntrl (
// rf tdd control signal CDC
up_xfer_cntrl #(.DATA_WIDTH(48)) i_tdd_control (
up_xfer_cntrl #(.DATA_WIDTH(24)) i_tdd_control (
.up_rstn(up_rstn),
.up_clk(up_clk),
.up_data_cntrl({up_tdd_enable,