⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cus_spi.vhd

📁 此为VHDL的SPI通信代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
   IF SYS_CLK'EVENT AND SYS_CLK='1' THEN
      BAUD_CLK_L<=BAUD_CLK_C;
      BAUD_CLK_C<=BAUD_CLK;
      BAUD_CLK_FALLEDGE<=BAUD_CLK_L AND (NOT BAUD_CLK_C);
      BAUD_CLK_RISINGEDGE<=BAUD_CLK_C AND (NOT BAUD_CLK_L);
    IF BAUD_CLK_RISINGEDGE='1' THEN
     IF M_COUNT="1000" THEN 
       SS_N1<='1';
       XXXX_B<=NOT XXXX_A;
     END IF;
    ELSIF BAUD_CLK_FALLEDGE='0' THEN
     IF CPHA='0' AND M_COUNT="0000" THEN 
       SS_N1<='0';
     END IF;
    ELSIF BAUD_CLK_FALLEDGE='1' THEN
     IF CPHA='1' AND M_COUNT="0000" AND M_COUNT_EN='1' THEN 
       SS_N1<='0';
     END IF;
    END IF;
   END IF;
  ELSE
    SS_N1<='1';
  END IF;
END PROCESS;
-----------------------------------------------------------------
    XXXX<=XXXX_B XOR XXXX_A;
PROCESS(MSTR,SS_N1,XXXX,SS_NP)
   BEGIN
      IF MSTR='1' THEN
       SS_N<=SS_N1 OR (NOT XXXX);
      ELSIF MSTR='0' THEN 
       IF S_NUM=8 THEN
        SS_N<=SS_NP(7)AND SS_NP(6)AND SS_NP(5)AND SS_NP(4)AND
              SS_NP(3)AND SS_NP(2)AND SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=7 THEN
        SS_N<=SS_NP(6)AND SS_NP(5)AND SS_NP(4)AND
              SS_NP(3)AND SS_NP(2)AND SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=6 THEN
        SS_N<=SS_NP(5)AND SS_NP(4)AND
              SS_NP(3)AND SS_NP(2)AND SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=5 THEN
        SS_N<=SS_NP(4)AND
              SS_NP(3)AND SS_NP(2)AND SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=4 THEN
        SS_N<=SS_NP(3)AND SS_NP(2)AND SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=3 THEN
        SS_N<=SS_NP(2)AND SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=2 THEN
        SS_N<=SS_NP(1)AND SS_NP(0);
       ELSIF S_NUM=1 THEN
        SS_N<=SS_NP(0);
       END IF;
      END IF;
END PROCESS;
--DDDD信号生成----------------------------------------------------
    DDDD<=DDDD_B XOR DDDD_A;
PROCESS(SS_N,DDDD_B,DDDD_A)
   BEGIN
      IF SS_N'EVENT AND SS_N='1' THEN
        DDDD_B<=NOT DDDD_A;
      END IF;
END PROCESS;
--计数使能控制生成----------------------------------------------------
PROCESS(SHIFTOUT_EMPTY,SHIFTIN_FULL)
   BEGIN
      IF SHIFTOUT_EMPTY='1' AND SHIFTIN_FULL='1' THEN
        M_COUNT_EN<='0';
      ELSE
        M_COUNT_EN<='1'; 
      END IF;
END PROCESS;
--主8周期时钟生成-------------------------------------------------------
CLK_SCK_CPHA_SS_N<=(CLK_SCK XOR SS_N) XOR CPHA;
PROCESS(SYS_CLK,CPHA,M_COUNT,BAUD_CLK_CPHA,BAUD_CLK_CPHA_C,BAUD_CLK_CPHA_L)
  BEGIN
   IF SYS_CLK'EVENT AND SYS_CLK='1' THEN
      CLK_SCK_CPHA_SS_N_L<=CLK_SCK_CPHA_SS_N_C;
      CLK_SCK_CPHA_SS_N_C<=CLK_SCK_CPHA_SS_N;
      CLK_SCK_CPHA_SS_N_FALLEDGE<=CLK_SCK_CPHA_SS_N_L AND (NOT CLK_SCK_CPHA_SS_N_C);
      CLK_SCK_CPHA_SS_N_RISINGEDGE<=CLK_SCK_CPHA_SS_N_C AND (NOT CLK_SCK_CPHA_SS_N_L);
    IF MSTR='1' THEN
     IF BAUD_CLK_CPHA_FALLEDGE='1' THEN
      IF M_COUNT_EN='1' THEN
       IF M_COUNT>="1000" THEN
        M_COUNT<="0000";
       ELSE 
        M_COUNT<=M_COUNT+"0001";
       END IF;
      ELSIF M_COUNT_EN='0' THEN
       IF CPHA='0' THEN
        M_COUNT<="1000";
       ELSIF CPHA='1' THEN
        M_COUNT<="0000";
       END IF;
      END IF;
     END IF; 
    END IF;  
   END IF;
END PROCESS;
----移位8周期时钟生成-------------------------------------------------------------------
PROCESS(SYS_CLK,SS_N,CPHA,SHIFT_COUNT)
   BEGIN 
   IF SYS_CLK'EVENT AND SYS_CLK='1' THEN
    IF SS_N='0' THEN 
     IF CLK_SCK_CPHA_SS_N_FALLEDGE='1' THEN
       IF SHIFT_COUNT>="1000" THEN
        SHIFT_COUNT<="0000";
       ELSE 
        SHIFT_COUNT<=SHIFT_COUNT+"0001";
       END IF;
     END IF;
    ELSIF SS_N='1' THEN 
     IF CPHA='0' THEN
      SHIFT_COUNT<="1000";
     ELSIF CPHA='1' THEN
      SHIFT_COUNT<="0000";
     END IF;
    ELSE 
       SHIFT_COUNT<="0000";
    END IF;
   END IF; 
END PROCESS;
-----中间时钟生成----------------------------------------------------------------
PROCESS(MSTR,CPHA,SCK,M_COUNT,CLK_MID,CLK_MASK,SCK,BAUD_CLK)
   BEGIN
   IF MSTR='1' THEN
    IF CPHA='0' THEN 
     IF M_COUNT="1000" THEN
      CLK_MID<='0';
     ELSIF M_COUNT<"1000" THEN
      CLK_MID<=BAUD_CLK;
     END IF;
    ELSIF CPHA='1' THEN 
     IF CLK_MASK='1' THEN
      CLK_MID<='0';
     ELSIF CLK_MASK='0' THEN
      CLK_MID<=BAUD_CLK;
     END IF;
    END IF;
   ELSIF MSTR='0' THEN
      CLK_MID<=SCK;
   END IF;
END PROCESS;
--时钟极性控制-----------------------------------------------------------
PROCESS(CPOL,CLK_MID)
   BEGIN
      IF CPOL='0' THEN
        CLK_SCK<=CLK_MID;
      ELSIF CPOL='1' THEN 
        CLK_SCK<=NOT CLK_MID;  
      END IF;
END PROCESS;
--CPHA='1'时空闲时钟屏蔽--------------------------------------------------
BAUD_CLK_CPHA<=CPHA XOR BAUD_CLK;
PROCESS(BAUD_CLK,M_COUNT,SYS_CLK)
   BEGIN
   IF SYS_CLK'EVENT AND SYS_CLK='1' THEN
      BAUD_CLK_CPHA_L<=BAUD_CLK_CPHA_C;
      BAUD_CLK_CPHA_C<=BAUD_CLK_CPHA;
      BAUD_CLK_CPHA_FALLEDGE<=BAUD_CLK_CPHA_L AND (NOT BAUD_CLK_CPHA_C);
      BAUD_CLK_CPHA_RISINGEDGE<=BAUD_CLK_CPHA_C AND (NOT BAUD_CLK_CPHA_L);
    IF BAUD_CLK_CPHA_RISINGEDGE='1' THEN
     IF M_COUNT="1000" THEN
      CLK_MASK<='1'; 
     END IF;
     IF M_COUNT="0000" AND M_COUNT_EN='1' THEN
      CLK_MASK<='0';
     END IF;
    END IF;
   END IF;
END PROCESS;
--移位输入/输出------------------------------------------------------------
   CLK_SCK_CPHA<=CPHA XOR CLK_SCK; 
PROCESS(SYS_CLK,LSBFE,CPHA,SHIFT_COUNT,SHIFT_IN,SHIFT_OUT,BITIN,SS_N,SPTEF,DATAOUT_BUF,CLK_SCK_CPHA,CLK_SCK_CPHA_L,CLK_SCK_CPHA_C,SHIFTIN_FULL,SHIFTOUT_EMPTY)
   BEGIN
   IF SYS_CLK'EVENT AND SYS_CLK='1' THEN
      CLK_SCK_CPHA_L<=CLK_SCK_CPHA_C;
      CLK_SCK_CPHA_C<=CLK_SCK_CPHA;
      CLK_SCK_CPHA_FALLEDGE<=CLK_SCK_CPHA_L AND (NOT CLK_SCK_CPHA_C);
      CLK_SCK_CPHA_RISINGEDGE<=CLK_SCK_CPHA_C AND (NOT CLK_SCK_CPHA_L);
    IF CLK_SCK_CPHA_SS_N_FALLEDGE='1' AND SHIFT_COUNT/=CONV_STD_LOGIC_VECTOR(7+CONV_INTEGER(CPHA),4) THEN
     IF SHIFTOUT_EMPTY='0' AND SS_N='0' THEN
      IF LSBFE='1' THEN
         BITOUT<=SHIFT_OUT(0);
         SHIFT_OUT<='0'&SHIFT_OUT(7 DOWNTO 1);
      ELSIF LSBFE='0' THEN
         BITOUT<=SHIFT_OUT(7);   
         SHIFT_OUT<=SHIFT_OUT(6 DOWNTO 0)&'0';
      END IF; 
     END IF;
    END IF;
    IF CLK_SCK_CPHA_FALLEDGE='1' THEN
      IF CPHA='0' AND SHIFT_COUNT="0111" AND DDDD='1' THEN
       
       SHIFTIN_FULL_A<=NOT SHIFTIN_FULL_B;
       SHIFTOUT_EMPTY_B<=NOT SHIFTOUT_EMPTY_A;
      END IF;
    END IF;
    IF CLK_SCK_CPHA_RISINGEDGE='1' THEN
      IF CPHA='1' AND SHIFT_COUNT="1000" AND DDDD='1' THEN
       
       SHIFTIN_FULL_A<=NOT SHIFTIN_FULL_B;
       SHIFTOUT_EMPTY_B<=NOT SHIFTOUT_EMPTY_A;
      END IF;
     IF SHIFTIN_FULL='0' AND SS_N='0' THEN
      IF LSBFE='1' THEN
         SHIFT_IN<=BITIN&SHIFT_IN(7 DOWNTO 1);
      ELSIF LSBFE='0' THEN  
         SHIFT_IN<=SHIFT_IN(6 DOWNTO 0)&BITIN;
      END IF; 
     END IF;
    ELSIF CLK_SCK_CPHA_RISINGEDGE='0' AND SHIFT_COUNT="1000" AND CPHA='0' AND DDDD='1' THEN
     IF SHIFTIN_FULL='1' THEN
         SPIF_A<=NOT SPIF_B;
         DATAIN_BUF<=SHIFT_IN;
         SHIFTIN_FULL_A<=SHIFTIN_FULL_B;
     ELSIF SHIFTOUT_EMPTY='1' AND SPTEF='0' THEN
         SHIFT_OUT<=DATAOUT_BUF;
         SHIFTOUT_EMPTY_B<=SHIFTOUT_EMPTY_A;
         SPTEF_B<=NOT SPTEF_A;
     END IF;
    ELSIF CLK_SCK_CPHA_RISINGEDGE='0' AND SHIFT_COUNT="0000" AND CPHA='1' AND DDDD='1' THEN
     IF SHIFTIN_FULL='1' THEN
         SPIF_A<=NOT SPIF_B;
         DATAIN_BUF<=SHIFT_IN;
         SHIFTIN_FULL_A<=SHIFTIN_FULL_B;
     ELSIF SHIFTOUT_EMPTY='1' AND SPTEF='0' THEN
         SHIFT_OUT<=DATAOUT_BUF;
         SHIFTOUT_EMPTY_B<=SHIFTOUT_EMPTY_A;
         SPTEF_B<=NOT SPTEF_A;
     END IF;
    END IF;  
   END IF;
END PROCESS;
SHIFTOUT_EMPTY<=SHIFTOUT_EMPTY_A XOR SHIFTOUT_EMPTY_B;--输出移位寄存器空标志产生
SHIFTIN_FULL<=SHIFTIN_FULL_A XOR SHIFTIN_FULL_B;--输入移位寄存器满标志产生
SPTEF<=SPTEF_A XOR SPTEF_B;--数据缓冲有空间标志产生
SPIF<=SPIF_A XOR SPIF_B;--字节传输

--完--------------------------------------------------------------------
END LIN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -