|
|
@@ -24,6 +24,7 @@ module DDSWrapper #(
|
|
|
input WrClk_i,
|
|
|
input RdClk_i,
|
|
|
input Rst_i,
|
|
|
+ input RstExt_i,
|
|
|
input [2:0] DdsWordNum_i,
|
|
|
input DdsWordNumVal_i,
|
|
|
input DdsDirectFlag_i,
|
|
|
@@ -33,6 +34,8 @@ module DDSWrapper #(
|
|
|
output reg DdsSyncFpga_o,
|
|
|
output [2:0] DdsWordNumReg_o,
|
|
|
|
|
|
+ output reg ResultOfTest_o,
|
|
|
+
|
|
|
output Ss_o,
|
|
|
output Sck_o,
|
|
|
output Mosi_o
|
|
|
@@ -57,11 +60,24 @@ wire ddsFifoEmpty;
|
|
|
|
|
|
reg ssR;
|
|
|
reg ssReg;
|
|
|
-reg ddsDirectFlagR;
|
|
|
+// reg ddsDirectFlagR;
|
|
|
+reg ddsDirectFlagSyncA;
|
|
|
+reg ddsDirectFlagSyncB;
|
|
|
+reg ddsDirectFlagSyncC;
|
|
|
reg [2:0] ddsWordNumReg;
|
|
|
-reg [2:0] ddsWordNumRegSync;
|
|
|
+reg [2:0] ddsWordNumRegRdDomain;
|
|
|
+reg [2:0] ddsWordNumRegSyncA;
|
|
|
+reg [2:0] ddsWordNumRegSyncB;
|
|
|
+
|
|
|
reg [2:0] ddsSyncCnt;
|
|
|
|
|
|
+/* WordNumVal Synchronization */
|
|
|
+wire ddsWordNumValSyncRdDomain;
|
|
|
+reg plsToggleWordNumVal;
|
|
|
+reg plsToggleWordNumValSyncA;
|
|
|
+reg plsToggleWordNumValSyncB;
|
|
|
+
|
|
|
+
|
|
|
reg plsToggle;
|
|
|
reg plsToggleSyncA;
|
|
|
reg plsToggleSyncB;
|
|
|
@@ -71,6 +87,17 @@ wire [63:0] dataFromDdsFifoCut;
|
|
|
reg [9:0] parityErrors; // Ошибки чётности для каждого байта
|
|
|
wire [9:0] byteParityBits; // Вычисленные биты чётности
|
|
|
wire [9:0] storedParityBits; // Сохранённые биты чётности
|
|
|
+
|
|
|
+// Промежуточные регистры для улучшения тайминга
|
|
|
+reg ssNegEdge;
|
|
|
+reg isLastWord;
|
|
|
+reg directFlagRisingEdge;
|
|
|
+
|
|
|
+reg currentSample;
|
|
|
+
|
|
|
+/* Spi Slave */
|
|
|
+wire valFromSpiSlave;
|
|
|
+wire [79:0] dataFromSpiSlave;
|
|
|
//================================================================================
|
|
|
// ASSIGNMENTS
|
|
|
//================================================================================
|
|
|
@@ -88,9 +115,34 @@ assign byteParityBits[6] = ^dataFromDdsFifo[55:48];
|
|
|
assign byteParityBits[7] = ^dataFromDdsFifo[63:56];
|
|
|
assign byteParityBits[8] = ^dataFromDdsFifo[71:64];
|
|
|
assign byteParityBits[9] = ^dataFromDdsFifo[79:72];
|
|
|
+
|
|
|
+/* ddsWordNumVal Synchronization */
|
|
|
+assign ddsWordNumValSyncRdDomain = plsToggleWordNumValSyncB^plsToggleWordNumValSyncA;
|
|
|
//==========================================================================//
|
|
|
// CODING //
|
|
|
//==========================================================================//
|
|
|
+always @(posedge WrClk_i) begin
|
|
|
+ if (Rst_i) begin
|
|
|
+ plsToggleWordNumVal <= 1'b0;
|
|
|
+ end
|
|
|
+ else if (DdsWordNumVal_i) begin
|
|
|
+ plsToggleWordNumVal <= ~plsToggleWordNumVal;
|
|
|
+ end
|
|
|
+ else begin
|
|
|
+ plsToggleWordNumVal <= plsToggleWordNumVal;
|
|
|
+ end
|
|
|
+end
|
|
|
+always @(posedge RdClk_i) begin
|
|
|
+ if (Rst_i) begin
|
|
|
+ plsToggleWordNumValSyncA <= 1'b0;
|
|
|
+ plsToggleWordNumValSyncB <= 1'b0;
|
|
|
+ end
|
|
|
+ else begin
|
|
|
+ plsToggleWordNumValSyncA <= plsToggleWordNumVal;
|
|
|
+ plsToggleWordNumValSyncB <= plsToggleWordNumValSyncA;
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
/* Check parity bits */
|
|
|
always @(posedge RdClk_i) begin
|
|
|
if (Rst_i) begin
|
|
|
@@ -114,10 +166,14 @@ end
|
|
|
|
|
|
always @(posedge RdClk_i) begin
|
|
|
if (Rst_i) begin
|
|
|
- ddsDirectFlagR <= 1'b0;
|
|
|
+ ddsDirectFlagSyncA <= 1'b0;
|
|
|
+ ddsDirectFlagSyncB <= 1'b0;
|
|
|
+ ddsDirectFlagSyncC <= 1'b0;
|
|
|
end
|
|
|
else begin
|
|
|
- ddsDirectFlagR <= DdsDirectFlag_i;
|
|
|
+ ddsDirectFlagSyncA <= DdsDirectFlag_i;
|
|
|
+ ddsDirectFlagSyncB <= ddsDirectFlagSyncA;
|
|
|
+ ddsDirectFlagSyncC <= ddsDirectFlagSyncB;
|
|
|
end
|
|
|
end
|
|
|
|
|
|
@@ -134,6 +190,28 @@ always @(posedge RdClk_i) begin
|
|
|
end
|
|
|
end
|
|
|
|
|
|
+// Детекция спадающего фронта SS для улучшения тайминга
|
|
|
+always @(posedge RdClk_i) begin
|
|
|
+ if (Rst_i) begin
|
|
|
+ ssNegEdge <= 1'b0;
|
|
|
+ end
|
|
|
+ else begin
|
|
|
+ ssNegEdge <= (!Ss_o && ssReg);
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+// Предварительное вычисление условий для улучшения тайминга
|
|
|
+always @(posedge RdClk_i) begin
|
|
|
+ if (Rst_i) begin
|
|
|
+ isLastWord <= 1'b0;
|
|
|
+ directFlagRisingEdge <= 1'b0;
|
|
|
+ end
|
|
|
+ else begin
|
|
|
+ isLastWord <= (ddsWordNumRegSyncB == 3'h1);
|
|
|
+ directFlagRisingEdge <= (ddsDirectFlagSyncC && !ddsDirectFlagSyncB);
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
always @(posedge RdClk_i) begin
|
|
|
if (Rst_i) begin
|
|
|
plsToggle <= 1'b0;
|
|
|
@@ -175,10 +253,12 @@ end
|
|
|
|
|
|
always @(posedge RdClk_i) begin
|
|
|
if (Rst_i) begin
|
|
|
- ddsWordNumRegSync <= 3'h0;
|
|
|
+ ddsWordNumRegSyncA <= 3'h0;
|
|
|
+ ddsWordNumRegSyncB <= 3'h0;
|
|
|
end
|
|
|
else begin
|
|
|
- ddsWordNumRegSync <= ddsWordNumReg;
|
|
|
+ ddsWordNumRegSyncA <= ddsWordNumReg;
|
|
|
+ ddsWordNumRegSyncB <= ddsWordNumRegSyncA;
|
|
|
end
|
|
|
end
|
|
|
|
|
|
@@ -187,19 +267,40 @@ always @(posedge RdClk_i) begin
|
|
|
DdsSyncFpga_o <= 1'b0;
|
|
|
end
|
|
|
else begin
|
|
|
- if (ddsDirectFlagR && !DdsDirectFlag_i) begin
|
|
|
- DdsSyncFpga_o <= 1'b1;
|
|
|
+ if (directFlagRisingEdge) begin
|
|
|
+ DdsSyncFpga_o <= 1'b1;
|
|
|
end
|
|
|
- else if ((!Ss_o && ssReg) && (ddsWordNumRegSync != 0)) begin
|
|
|
+ else if (ssNegEdge && (ddsWordNumRegSyncB != 0)) begin
|
|
|
DdsSyncFpga_o <= 1'b0;
|
|
|
end
|
|
|
+ else if (isLastWord && ssPosEdge) begin
|
|
|
+ DdsSyncFpga_o <= 1'b1;
|
|
|
+ end
|
|
|
else begin
|
|
|
- if (ddsWordNumRegSync == 3'h1 && (Ss_o && !ssReg)) begin
|
|
|
- DdsSyncFpga_o <= 1'b1;
|
|
|
+ DdsSyncFpga_o <= DdsSyncFpga_o; // Удерживаем состояние
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+/* Spi Master Check */
|
|
|
+always @(posedge RdClk_i) begin
|
|
|
+ if (RstExt_i) begin
|
|
|
+ ResultOfTest_o <= 1'b0;
|
|
|
+ currentSample <= 1'b0;
|
|
|
+ end
|
|
|
+ else begin
|
|
|
+ if (valFromSpiSlave) begin
|
|
|
+ if ((currentSample == 0) && dataFromSpiSlave == 80'hAAAAAAAAAAAAAAAAAAAA ) begin
|
|
|
+ currentSample <= 1'b1;
|
|
|
+ ResultOfTest_o <= 1'b0;
|
|
|
end
|
|
|
- else begin
|
|
|
- DdsSyncFpga_o <= 1'b0;
|
|
|
+ else if ((currentSample == 1) && dataFromSpiSlave == 80'h55555555555555555555 ) begin
|
|
|
+ currentSample <= 1'b0;
|
|
|
+ ResultOfTest_o <= 1'b0;
|
|
|
end
|
|
|
+ else begin
|
|
|
+ ResultOfTest_o <= 1'b1; // Ошибка, данные не совпадают
|
|
|
+ end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
@@ -252,4 +353,16 @@ SpiM #(
|
|
|
.Sck_o (Sck_o)
|
|
|
);
|
|
|
|
|
|
+SpiSlave #(
|
|
|
+ .WIDTH (OUT_WIDTH)
|
|
|
+) SpiS_inst (
|
|
|
+ .Clk_i (RdClk_i),
|
|
|
+ .Rst_i (Rst_i),
|
|
|
+ .Ss_i (Ss_o),
|
|
|
+ .Mosi_i (Mosi_o),
|
|
|
+ .Sck_i (Sck_o),
|
|
|
+ .Val_o (valFromSpiSlave),
|
|
|
+ .Data_o (dataFromSpiSlave)
|
|
|
+);
|
|
|
+
|
|
|
endmodule
|