|
接收端的架构必须根据传输端的规划把传输的数据再解回来
(这边同样须规划 timing diagram => coding => simulation 看是不是符合所想要的时序)
ps : 真正在两个 device 间的传输, 不可以跑这么快的频率, 需要注意一下, 这边是简单的举个很实用的例子分享喔~ :$
module ext_pll_slave
(
// system input
osc_50,
rstn,
// 2-wire interface
max_sclk,
max_sdat,
// device 1 output
clk1_pr,
clk1_od,
clk1_os,
clk1_ce,
clk1_rstn,
// device 2 output
clk2_pr,
clk2_od,
clk2_os,
clk2_ce,
clk2_rstn,
// device 3 output
clk3_pr,
clk3_od,
clk3_os,
clk3_ce,
clk3_rstn
);
//=======================================================
// Port declarations
//=======================================================
// system input
input osc_50;
input rstn;
// 2-wire interface
input max_sclk;
inout max_sdat;
// device 1 output
output [1:0] clk1_pr;
output [2:0] clk1_od;
output [1:0] clk1_os;
output clk1_ce;
output clk1_rstn;
// device 2 output
output [1:0] clk2_pr;
output [2:0] clk2_od;
output [1:0] clk2_os;
output clk2_ce;
output clk2_rstn;
// device 3 output
output [1:0] clk3_pr;
output [2:0] clk3_od;
output [1:0] clk3_os;
output clk3_ce;
output clk3_rstn;
//=======================================================
// Parameter declarations
//=======================================================
//=======================================================
// Signal declarations
//=======================================================
reg [3:0] clk3_set;
reg [3:0] clk2_set;
reg [3:0] clk1_set;
wire [11:0] conf_data;
reg conf_duration;
reg conf_duration_d;
reg max_sdat_d;
reg [4:0] conf_counter;
wire duration_end;
wire conf_counter_zero;
reg conf_wr;
reg [11:0] s2p;
wire wr_data_ready_temp;
reg wr_data_ready;
reg p2s;
reg p2s_act;
//=======================================================
// Structural coding
//=======================================================
assign max_sdat = p2s_act ? p2s : 1'bz;
assign conf_data = {clk3_set, clk2_set, clk1_set};
assign duration_end = (conf_counter == 5'd16) ? 1'b1 : 1'b0;
assign conf_counter_one = (conf_counter == 5'd1) ? 1'b1 : 1'b0;
assign wr_data_ready_temp = (conf_counter == 5'd14) ? 1'b1 : 1'b0;
//--- pipe delay ---//
always @ (posedge osc_50 or negedge rstn)
if (!rstn)
max_sdat_d <= 1'b1;
else
max_sdat_d <= max_sdat;
//--- config duration ---//
always @ (posedge osc_50 or negedge rstn)
if (!rstn)
conf_duration <= 1'b0;
else if (duration_end)
conf_duration <= 1'b0;
else if (max_sdat_d && !max_sdat)
conf_duration <= 1'b1;
//--- config counter---//
always @ (posedge osc_50 or negedge rstn)
if (!rstn)
conf_counter <= 5'b0;
else if (!conf_duration)
conf_counter <= 5'b0;
else
conf_counter <= conf_counter + 1;
//--- s2p convert ---//
always @ (posedge max_sclk)
if (conf_duration)
begin
if (conf_counter_one)
conf_wr <= max_sdat;
if (conf_wr)
s2p <= {s2p[10:0], max_sdat};
end
always @ (posedge osc_50 or negedge rstn)
if(!rstn)
wr_data_ready <= 1'b0;
else if (conf_wr && wr_data_ready_temp)
wr_data_ready <= 1'b1;
else
wr_data_ready <= 1'b0;
//--- p2s convert ---//
always @ (posedge osc_50 or negedge rstn)
if (!rstn)
begin
p2s <= 1'b1; p2s_act <= 1'b0;
end
else if (!conf_wr)
case (conf_counter)
5'd2 : begin p2s <= conf_data[11]; p2s_act <= 1'b1; end
5'd3 : p2s <= conf_data[10];
5'd4 : p2s <= conf_data[9];
5'd5 : p2s <= conf_data[8];
5'd6 : p2s <= conf_data[7];
5'd7 : p2s <= conf_data[6];
5'd8 : p2s <= conf_data[5];
5'd9 : p2s <= conf_data[4];
5'd10 : p2s <= conf_data[3];
5'd11 : p2s <= conf_data[2];
5'd12 : p2s <= conf_data[1];
5'd13 : p2s <= conf_data[0];
default : begin p2s <= 1'b1; p2s_act <= 1'b0; end
endcase
else
p2s_act <= 1'b0;
//--- programming data latched ---//
always @ (posedge osc_50 or negedge rstn)
if (!rstn)
begin
clk3_set <= 4'h4; //only for test
clk2_set <= 4'ha; //only for test
clk1_set <= 4'hc; //only for test
end
else if (wr_data_ready)
begin
clk3_set <= s2p[11:8];
clk2_set <= s2p[7:4];
clk1_set <= s2p[3:0];
end
endmodule |
|