我們正在開發一個程序,需要兩個設備上的同步時鐘來測量超聲波信號的飛行時間。獨立的Nexys 4時鐘隨時間推移而不同步
的問題是,當我們合成程序並測試它的兩個獨立的FPGA Nexys4的距離趨向於隨時間降低(0.13釐米/秒)。這個比例是不變的,並且一直在下降,這導致我們認爲問題出現在代碼中。
當我們只在一個合成程序Nexys 4,沒有減少被認爲是隨着時間的推移。
我們有一個模塊來監聽信號(每個從站3個從站,3個從站),稱爲dataListener:信號SendCommand是UART模塊的控制信號,該模塊向SRF02超聲發送方向和命令,該模塊爲在兩臺設備上完全相同。
module dataListener(
input mclk,
input clkSync,
input reset,
input rxDataRdy,
output wire[7:0] command,
output reg[7:0] direction,
output reg read,
output reg sendCommand,
output reg dataChanged,
output reg [1:0] slave,
output reg [1:0] sensor
);
parameter dir0 = 8'd0;
parameter dir1 = 8'd3;
parameter dir2 = 8'd6;
parameter rangingCommand = 8'd87;
parameter readCommand = 8'd94;
//parameter clkTime = 0.000000001; // 1ns Simulation // 10ns FPGA
//parameter windowTime = 0.08; // 80 ms
//parameter listenTime = 0.07; // 70ms
parameter windowCyclesDuration = 8000000;
parameter listenCyclesDuration = 7000000;
reg [54:0] windowCounter;
reg emitSent;
reg readSent;
reg slave1;
reg slave2;
reg slave3;
assign command = emitSent ? readCommand : rangingCommand;
///////////////////////////////////////////////////////////////////
always @(posedge mclk) begin
if(reset)begin
sensor <= 2'b0;
windowCounter <= 55'b0;
emitSent <= 0;
readSent <= 0;
slave <=0;
end else begin
if(clkSync) begin
if(windowCounter >= windowCyclesDuration)begin //Window ended
windowCounter <= 55'b0; //resetCounter
emitSent <= 0;
readSent <= 0;
if(sensor == 2'd2)begin
sensor <= 2'b0;
if(slave == 2'd2)
slave <= 2'b0;
else
slave <= slave+1'b1;
end else begin
sensor <= sensor + 1'b1;
end
end else begin
windowCounter <= windowCounter + 1'b1; //Window in process
if(!emitSent)begin
sendCommand <= 1;
end
else if((windowCounter >= listenCyclesDuration) && !readSent)begin //listen done, time to send the read command
sendCommand <= 1;
end
end
if(sendCommand)begin
sendCommand <= 0; //Shut down "sendCommand" signal.
if(!emitSent)
emitSent <= 1;
else
readSent <= 1;
end
end
/// Process incoming data
if(rxDataRdy)begin
read <= 1;
end else if(read)begin
read <= 0;
end
end
end
//////////////////////////////////////////////////////////////////
always @(sensor) begin
case(sensor)
2'd0: begin
direction <= dir0;
end
2'd1: begin
direction <= dir1;
end
2'd2: begin
direction <= dir2;
end
default: begin
direction <= dir0;
end
endcase
end
endmodule
從屬設備上的模塊,其發送所述命令:
module slave(
input mclk,
input clkSync,
input reset,
output [7:0] command,
output [7:0] direction,
output reg sendCommand,
output inWindow
);
parameter numSlave = 2'b0; //Between 0-2
parameter dir=8'd0; //Depends on the slaves direction
parameter comm=8'd92;
assign command = comm;
assign direction = dir;
parameter windowCyclesDuration = 8000000;
reg [54:0] windowCounter;
reg [1:0] sensor, slave;
reg commandSent;
assign inWindow = (slave == numSlave);
always @(posedge mclk) begin
if(reset)begin
windowCounter <= 55'b0;
sendCommand <=0;
commandSent <= 1;
slave <= 2'b0;
sensor <= 2'b0;
end else begin
if(clkSync) begin
if(windowCounter >= windowCyclesDuration)begin //Window ended
windowCounter <= 55'b0; //resetCounter
commandSent <= 0;
if(sensor == 2'd2)begin
sensor <= 2'b0;
if(slave == 2'd2)
slave <= 2'b0;
else
slave <= slave + 1'b1;
end else begin
sensor <= sensor + 1'b1;
end
end else begin
windowCounter <= windowCounter + 1'b1; //Window in process
if(inWindow && !commandSent)begin //im in my window and command not sent yet
sendCommand <= 1;//send when a new window is about to begin
commandSent <= 1;
end
end
if(sendCommand)begin
sendCommand <= 0; //Shut down "sendCommand" signal.
end
end
end
end
endmodule
信號clkSync
當兩個設備是「同步」時,纔會激活,只在通過電纜起作用的啓動happend然後移除以允許移動。
這裏是主站的同步模塊:
module SyncM(
input mclk,
input reset,
input response1,
input response2,
input response3,
output reg call1,
output reg call2,
output reg call3,
output reg clkSync,
output reg slave1,
output reg slave2,
output reg slave3
);
always @ (posedge mclk) begin
if(reset)begin
clkSync <= 0;
slave1 <= 0;
slave2 <= 0;
slave3 <= 0;
call1 <= 0;
call2 <= 0;
call3 <= 0;
end else begin
if(btn && !call1)begin
call1 <= 1;
call2 <= 1;
call3 <= 1;
clkSync <= 1;
end
if(response1)
slave1 <= 1;
if(response2)
slave2 <= 1;
if(response3)
slave3 <= 1;
end
end
endmodule
和從同步模塊,所述call
信號是從主發送通過電纜向從屬。
`timescale 1ns/1ps
module SyncS(
input reset,
input call,
output reg clkSync,
output reg response
);
always @ (reset or call) begin
if(reset) begin
clkSync <= 0;
response <= 0;
end else begin
if (call) begin
response <= 1;
clkSync <= 1;
end
end
end
endmodule
在一塊電路板上,當它保持同步時,是否使用了2個獨立的晶體振盪器?我懷疑沒有,所以你看到振盪器漂移的頻率。如果需要,可以使用相同的振盪器,從一個板連接到另一個板,或通過RF鏈路傳送同步信號。 –