Quellcode durchsuchen

Выявление источника нестабильности

Anatoliy Chigirinskiy vor 6 Monaten
Ursprung
Commit
ec1ca88dc8

+ 7 - 11
src/constr/SbTmsg.sdc

@@ -1,18 +1,14 @@
 //Copyright (C)2014-2025 GOWIN Semiconductor Corporation.
 //All rights reserved.
 //File Title: Timing Constraints file
-//Tool Version: V1.9.11 (64-bit) 
-//Created Time: 2025-06-04 14:02:12
+//Tool Version: V1.9.11.02 (64-bit) 
+//Created Time: 2025-06-09 11:49:38
 create_clock -name clk5 -period 200 -waveform {0 100} [get_nets {clk5}]
 create_clock -name clk60 -period 16.667 -waveform {0 8.334} [get_nets {clk60}]
 create_clock -name Clk_i -period 41.667 -waveform {0 20.834} [get_ports {Clk_i}]
-create_clock -name Sck_i -period 10 -waveform {0 5} [get_ports {Sck_i}]
-create_clock -name clk50 -period 20 -waveform {0 10} [get_nets {clk50}]
-set_clock_groups -asynchronous -group [get_clocks {Clk_i}] -group [get_clocks {Sck_i}]
-set_false_path -from [get_clocks {Sck_i}] -to [get_clocks {Clk_i}] 
-set_false_path -from [get_clocks {Sck_i}] -to [get_clocks {Sck_i}] 
-set_false_path -from [get_clocks {Sck_i}] -to [get_clocks {clk60}] 
-set_false_path -from [get_clocks {clk60}] -to [get_clocks {Sck_i}] 
+create_clock -name Sck_i -period 16.667 -waveform {0 8.334} [get_ports {Sck_i}]
+create_generated_clock -name clk50 -source [get_ports {Clk_i}] -master_clock Clk_i -divide_by 12 -multiply_by 25 [get_nets {clk50}]
 set_false_path -from [get_regs {InitRst/signal_o_s1}] 
-report_timing -setup -from_clock [get_clocks {clk50}] -to_clock [get_clocks {clk50}]
-report_timing -setup -from_clock [get_clocks {clk60}] -to_clock [get_clocks {clk60}]
+report_timing -hold -from_clock [get_clocks {clk60}] -to_clock [get_clocks {Sck_i}] -max_paths 100 -max_common_paths 1
+report_timing -hold -from_clock [get_clocks {Sck_i}] -to_clock [get_clocks {clk60}] -max_paths 100 -max_common_paths 1
+report_timing -setup -from [get_regs {DDSWrapper/ssReg_s0}] -to [get_regs {DDSWrapper/DdsSyncFpga_o_s0}]

+ 1 - 0
src/src/FifoCtrl/FifoCtrl.v

@@ -56,6 +56,7 @@ assign Data_o = dataReg[OUT_WIDTH-1:0];
 //================================================================================
 //	CODING
 //================================================================================
+
 generate
     if (PARITY_CHECK) begin
         always @(posedge WrClk_i) begin 

+ 19 - 4
src/src/InterfaceArbiter/InterfaceArbiter.v

@@ -47,8 +47,8 @@ module InterfaceArbiter
 //================================================================================
 //  REG/WIRE
 
-	localparam [1:0] IDLE = 0;
-	localparam [1:0] DATARX = 1;
+	localparam [1:0] IDLE = 2'b01;
+	localparam [1:0] DATARX = 2'b10;
 	
 	reg [OUTWORDWIDTH-1:0] dataRegSSpi;
 	reg [OUTWORDWIDTH-1:0] dataRegQSpi;
@@ -101,15 +101,19 @@ module InterfaceArbiter
 	reg plsToggleSyncC;
 	reg plsToggleSyncSignalR;
 
+	/* SpiMode Sync Signals */
+	reg spiModeSyncA;
+	reg spiModeSyncB;
+
 //================================================================================
 //  ASSIGNMENTS
 	assign ssPos = ssRegR & !ssRegRR;
 
 	
 	assign DataVal_o = plsToggleSyncSignalR;
-	assign Data_o = (spiMode)? dataRegQSpi:dataRegSSpi;
+	assign Data_o = (spiModeSyncB)? dataRegQSpi:dataRegSSpi;
 
-	assign plsToggleSyncSignal = plsToggleSyncB^plsToggleSyncA;
+	assign plsToggleSyncSignal = plsToggleSyncC^plsToggleSyncB;
 
 	//assign ssCntRstThresh = (spiMode) ? QSPIWORDWIDTH-1:SSPIWORDWIDTH-1;
 	
@@ -127,6 +131,17 @@ module InterfaceArbiter
     	end
 	end
 
+	always @(posedge Clk_i) begin 
+		if (Rst_i) begin 
+			spiModeSyncA <= 1'b0;
+			spiModeSyncB <= 1'b0;
+		end
+		else begin 
+			spiModeSyncA <= spiMode;
+			spiModeSyncB <= spiModeSyncA;
+		end
+	end
+
 	always @(posedge Clk_i) begin 
 	    if (Rst_i) begin 
 	        plsToggleSyncC <= 1'b0;

+ 222 - 0
src/src/Top/QSpiParse.py

@@ -0,0 +1,222 @@
+
+
+
+
+def calculate_ftw_freq(ftw):
+    fs = 1e9  
+    freq = (fs*ftw)/2**48
+    return freq
+
+def parse_header (header) :
+    # bit 0 - Terminate bit #
+    # bit 1 - number of words for Attenuator #
+    # bit 2 - number of words for DAC #
+    # bits [4:3] - number of words for Pot #
+    # bits [7:6] - number of words for ShReg #
+    # bits [11:9] - number of words for MAX#
+    # bits [15:12] - number of words for LMX #
+    # bits [17:16] - number of words for GPIO #
+    # bits [21:19] - number of words for DDS #
+    #bit [23] - mode; 0 - SingleSpi, 1 - QuadSpi #
+    terminate_bit = header & 0x01
+    num_words_attenuator = (header >> 1) & 0x01
+    num_words_dac = (header >> 2) & 0x01
+    num_words_pot = (header >> 3) & 0x03
+    num_words_shreg = (header >> 6) & 0x03
+    num_words_max = (header >> 9) & 0x07
+    num_words_lmx = (header >> 12) & 0x0F
+    num_words_gpio = (header >> 16) & 0x03
+    num_words_dds = (header >> 19) & 0x07
+    mode = (header >> 23) & 0x01
+    return {
+        "terminate_bit": terminate_bit,
+        "num_words_attenuator": num_words_attenuator,
+        "num_words_dac": num_words_dac,
+        "num_words_pot": num_words_pot,
+        "num_words_shreg": num_words_shreg,
+        "num_words_max": num_words_max,
+        "num_words_lmx": num_words_lmx,
+        "num_words_gpio": num_words_gpio,
+        "num_words_dds": num_words_dds,
+        "mode": "SingleSpi" if mode == 0 else "QuadSpi"
+    }
+
+
+def main():
+    # Enter the width of the QSpi. Possible values are 8, 16, 24, 32
+    width = int(input("Enter the width of the QSpi: "))
+    if width not in [8, 16, 24, 32]:
+        print("Invalid width. Please enter 8, 16, 24, or 32.")
+        return
+    # Ask if you need to parse a header
+    parse_header_input = input("Do you want to parse a header? (y/n): ").lower() == 'y'
+    if parse_header_input:
+        # 
+        # Enter the mosi0Reg value in hex.
+        mosi0_header_input = input("Enter the Mosi0Reg value for header (hex): ")
+        try:
+            mosi0_header = int(mosi0_header_input, 16)
+            if mosi0_header < 0 or mosi0_header > 255:
+                print("Invalid Mosi0Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+        # Enter the mosi1Reg value in hex.
+        mosi1_header_input = input("Enter the Mosi1Reg value for header (hex): ")
+        try:
+            mosi1_header = int(mosi1_header_input, 16)
+            if mosi1_header < 0 or mosi1_header > 255:
+                print("Invalid Mosi1Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+        # Enter the mosi2Reg value in hex.
+        mosi2_header_input = input("Enter the Mosi2Reg value for header (hex): ")
+        try:
+            mosi2_header = int(mosi2_header_input, 16)
+            if mosi2_header < 0 or mosi2_header > 255:
+                print("Invalid Mosi2Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+        # Enter the mosi3Reg value in hex.
+        mosi3_header_input = input("Enter the Mosi3Reg value for header (hex): ")
+        try:
+            mosi3_header = int(mosi3_header_input, 16)
+            if mosi3_header < 0 or mosi3_header > 255:
+                print("Invalid Mosi3Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+        # Combine the Mosi registers into a single header value.
+        if width == 32:
+            header_input = (mosi0_header | (mosi1_header << 8) | 
+                            (mosi2_header << 16) | (mosi3_header << 24))
+        elif width == 24:
+            header_input = (mosi0_header | (mosi1_header << 6) | 
+                            (mosi2_header << 12) | (mosi3_header << 18))
+        elif width == 16:
+            header_input = (mosi0_header | (mosi1_header << 4) | 
+                            (mosi2_header << 8) | (mosi3_header << 12))
+        elif width == 8:
+            header_input = (mosi0_header | (mosi1_header << 2) | 
+                            (mosi2_header << 4) | (mosi3_header << 6))
+
+        
+        # Parse the header
+        parsed_header = parse_header(header_input)
+        
+        # Print the parsed values
+        print("\n--- Parsed Header ---")
+        for key, value in parsed_header.items():
+            print(f"{key}: {value}")
+        print("\n--- End of Header Parsing ---")
+    
+    # Do you want to contnue 
+    continue_input = input("Do you want to continue (y/n): ").lower() == 'y'
+    if not continue_input:
+        print("Exiting the program.")
+        return
+    # Ask if this is a DDS device
+    is_dds = input("Is this a DDS device? (y/n): ").lower() == 'y'
+    
+    dds_word_count = 0
+    dds_values = []
+    
+    # If DDS, we need to collect 4 words
+    total_words = 4 if is_dds else 1
+    
+    # Collect data for all required words
+    all_qmosi_values = []
+    
+    for word in range(total_words):
+        if is_dds and word > 0:
+            print(f"\n--- Entering data for DDS word {word+1}/4 ---")
+            
+        # Enter the Mosi0Reg value in hex.
+        mosi0_input = input("Enter the Mosi0Reg value (hex): ")
+        try:
+            mosi0_reg = int(mosi0_input, 16)
+            if mosi0_reg < 0 or mosi0_reg > 255:
+                print("Invalid Mosi0Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+            
+        # Enter the Mosi1Reg value in hex.
+        mosi1_input = input("Enter the Mosi1Reg value (hex): ")
+        try:
+            mosi1_reg = int(mosi1_input, 16)
+            if mosi1_reg < 0 or mosi1_reg > 255:
+                print("Invalid Mosi1Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+            
+        # Enter the Mosi2Reg value in hex.
+        mosi2_input = input("Enter the Mosi2Reg value (hex): ")
+        try:
+            mosi2_reg = int(mosi2_input, 16)
+            if mosi2_reg < 0 or mosi2_reg > 255:
+                print("Invalid Mosi2Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+            
+        # Enter the Mosi3Reg value in hex.
+        mosi3_input = input("Enter the Mosi3Reg value (hex): ")
+        try:
+            mosi3_reg = int(mosi3_input, 16)
+            if mosi3_reg < 0 or mosi3_reg > 255:
+                print("Invalid Mosi3Reg value. Please enter a value between 0x00 and 0xFF.")
+                return
+        except ValueError:
+            print("Invalid hex value. Please enter a valid hexadecimal number.")
+            return
+            
+        # Merge the Mosi registers into a single value.
+        if width == 32:
+            qmosi_value = mosi0_reg | (mosi1_reg << 8) | (mosi2_reg << 16) | (mosi3_reg << 24)
+        elif width == 24:
+            qmosi_value = mosi0_reg | (mosi1_reg << 6) | (mosi2_reg << 12) | (mosi3_reg << 18)
+        elif width == 16:
+            qmosi_value = mosi0_reg | (mosi1_reg << 4) | (mosi2_reg << 8) | (mosi3_reg << 12)
+        elif width == 8:
+            qmosi_value = mosi0_reg | (mosi1_reg << 2) | (mosi2_reg << 4) | (mosi3_reg << 6)
+        
+        all_qmosi_values.append(qmosi_value)
+        
+        if not is_dds or word == total_words - 1:
+            print("\n--- Result ---")
+            
+            # Print individual values
+            for i, value in enumerate(all_qmosi_values):
+                if is_dds:
+                    print(f"DDS Word {i+1}: {value:#0{width//4 + 2}x}")
+                else:
+                    print(f"QSpi Mosi value: {value:#0{width//4 + 2}x}")
+            
+            if is_dds and width == 24:
+                dds_combined = 0
+                for i, value in enumerate(all_qmosi_values):
+                    dds_combined |= (value << (24 * (3-i)))  
+                
+                print(f"\nDDS 96-bit combined value: {dds_combined:#0{96//4 + 2}x}")
+                #bin #
+                print(f"DDS 96-bit combined value (binary): {dds_combined:096b}")
+                
+
+                # Calculate the DDS frequency if needed. Take the lower 48 bits.
+                ftw = dds_combined & 0xFFFFFFFFFFFF
+                freq = calculate_ftw_freq(ftw)
+                print(f"DDS Frequency: {freq:.2f} Hz")
+
+if __name__ == "__main__":
+    main()

+ 3 - 3
src/src/Top/TopSbTmsgTb.sv

@@ -1,4 +1,4 @@
-`timescale 1ns/1ns
+`timescale 1ns/1ps
 
 module TopSbTmsgTb(inout Mosi1_io);
    parameter CLK_PERIOD = 8.13; // Clock period in ns
@@ -326,7 +326,7 @@ always_comb begin
     else begin 
         // if (!rstInit && locked) begin
             if (trCnt == 0) begin 
-                SPIdata = InitGpio1Header;
+                SPIdata = AllDevQSPIHeader;
             end
             else if (trCnt == 2) begin 
                 SPIdata = InitGpio1Header;
@@ -417,7 +417,7 @@ always_comb begin
         .Lag_i(LAG_i),
         .Lead_i(LEAD_i),
         .EndianSel_i(EndianSel_i),
-        .Stop_i(6'h3),
+        .Stop_i(6'h0),
         .PulsePol_i(PulsePol_i),
         .Mosi0_o(mosi0Q),
         .Mosi1_o(Mosi1_o),