新学的FPGA,写了个SPI的状态机,有什么不对吗?仿真似乎总有问题。
时间:10-02
整理:3721RD
点击:
拜托各位达人了
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SPI3578 IS
GENERIC(
N_WAITCLK : INTEGER := 10;
N_DELAYCLK : INTEGER := 4
);
PORT(
ICLK
: IN STD_LOGIC;
IRESET
: IN STD_LOGIC;
IEN : IN STD_LOGIC;
SPICLK
: OUT STD_LOGIC;
SDO
: IN STD_LOGIC;
SDI
: OUT STD_LOGIC;
CS
: OUT STD_LOGIC;
DATAIN
: IN
STD_LOGIC_VECTOR(15 DOWNTO 0);
DATAOUT : OUT
STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END ENTITY;
ARCHITECTURE BEHAVIOR OF SPI3578 IS
TYPE SPI_STATE IS (S0_IDLE,S1_REP,S2_PLACE,S3_RECIVE,S4_DELAY);
SIGNAL CURRENT_STATE,NEXT_STATE : SPI_STATE;
SIGNAL CNT ,NDLAY : INTEGER RANGE 0 TO 127;
SIGNAL BITL
:INTEGER RANGE 0 TO 15;
SIGNAL SCLK
: STD_LOGIC := '0';
SIGNAL TX_DATA
: STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL RX_DATA
: STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN
STATE_RENEW
ROCESS(ICLK,IRESET)
BEGIN
IF RISING_EDGE(ICLK)
THEN
IF (IRESET ='0')
THEN
CURRENT_STATE
<= S0_IDLE;
SPICLK
<= '0';
CS
<= '1';
ELSE
CURRENT_STATE
<= NEXT_STATE;
END IF;
END IF;
END PROCESS;
STATE_CREATROCESS(CURRENT_STATE,IEN,ICLK)
BEGIN
CASE (CURRENT_STATE) IS
WHEN S0_IDLE
=>
IF IEN = '1' THEN
NEXT_STATE <= S0_IDLE;
CNT <= 0;
CS <= '1';
ELSE
NEXT_STATE
<= S1_REP;
END IF;
WHEN S1_REP
=>
IF CNT <= N_WAITCLK THEN
CNT <= CNT + 1;
NEXT_STATE <= S1_REP;
ELSE
NEXT_STATE <= S2_PLACE;
BITL <= 0;
END IF;
WHEN S2_PLACE
=>
SDI <= TX_DATA(15-BITL);
SCLK <= NOT SCLK;
SPICLK
<=
SCLK;
NEXT_STATE <= S3_RECIVE;
WHEN S3_RECIVE
=>
TX_DATA(15-BITL)<= SDO;
SCLK <= NOT SCLK;
SPICLK
<=
SCLK;
IF BITL
<= 14
THEN
BITL
<= BITL + 1;
NEXT_STATE <= S2_PLACE;
ELSE
NEXT_STATE <= S4_DELAY;
END IF;
WHEN S4_DELAY
=>
IF NDLAY <= N_DELAYCLK THEN
NEXT_STATE <=S4_DELAY;
NDLAY
<=
NDLAY +1;
ELSE
NEXT_STATE <= S0_IDLE;
END IF;
WHEN OTHERS
=> NULL;
END CASE;
END PROCESS;
--SPICLK
<=
SCLK;
END BEHAVIOR ;
谢谢诸位
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SPI3578 IS
GENERIC(
N_WAITCLK : INTEGER := 10;
N_DELAYCLK : INTEGER := 4
);
PORT(
ICLK
: IN STD_LOGIC;
IRESET
: IN STD_LOGIC;
IEN : IN STD_LOGIC;
SPICLK
: OUT STD_LOGIC;
SDO
: IN STD_LOGIC;
SDI
: OUT STD_LOGIC;
CS
: OUT STD_LOGIC;
DATAIN
: IN
STD_LOGIC_VECTOR(15 DOWNTO 0);
DATAOUT : OUT
STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END ENTITY;
ARCHITECTURE BEHAVIOR OF SPI3578 IS
TYPE SPI_STATE IS (S0_IDLE,S1_REP,S2_PLACE,S3_RECIVE,S4_DELAY);
SIGNAL CURRENT_STATE,NEXT_STATE : SPI_STATE;
SIGNAL CNT ,NDLAY : INTEGER RANGE 0 TO 127;
SIGNAL BITL
:INTEGER RANGE 0 TO 15;
SIGNAL SCLK
: STD_LOGIC := '0';
SIGNAL TX_DATA
: STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL RX_DATA
: STD_LOGIC_VECTOR(15 DOWNTO 0);
BEGIN
STATE_RENEW
ROCESS(ICLK,IRESET)
BEGIN
IF RISING_EDGE(ICLK)
THEN
IF (IRESET ='0')
THEN
CURRENT_STATE
<= S0_IDLE;
SPICLK
<= '0';
CS
<= '1';
ELSE
CURRENT_STATE
<= NEXT_STATE;
END IF;
END IF;
END PROCESS;
STATE_CREATROCESS(CURRENT_STATE,IEN,ICLK)
BEGIN
CASE (CURRENT_STATE) IS
WHEN S0_IDLE
=>
IF IEN = '1' THEN
NEXT_STATE <= S0_IDLE;
CNT <= 0;
CS <= '1';
ELSE
NEXT_STATE
<= S1_REP;
END IF;
WHEN S1_REP
=>
IF CNT <= N_WAITCLK THEN
CNT <= CNT + 1;
NEXT_STATE <= S1_REP;
ELSE
NEXT_STATE <= S2_PLACE;
BITL <= 0;
END IF;
WHEN S2_PLACE
=>
SDI <= TX_DATA(15-BITL);
SCLK <= NOT SCLK;
SPICLK
<=
SCLK;
NEXT_STATE <= S3_RECIVE;
WHEN S3_RECIVE
=>
TX_DATA(15-BITL)<= SDO;
SCLK <= NOT SCLK;
SPICLK
<=
SCLK;
IF BITL
<= 14
THEN
BITL
<= BITL + 1;
NEXT_STATE <= S2_PLACE;
ELSE
NEXT_STATE <= S4_DELAY;
END IF;
WHEN S4_DELAY
=>
IF NDLAY <= N_DELAYCLK THEN
NEXT_STATE <=S4_DELAY;
NDLAY
<=
NDLAY +1;
ELSE
NEXT_STATE <= S0_IDLE;
END IF;
WHEN OTHERS
=> NULL;
END CASE;
END PROCESS;
--SPICLK
<=
SCLK;
END BEHAVIOR ;
IF CNT <= N_WAITCLK THEN
CNT <= CNT + 1;
NEXT_STATE <= S1_REP;
ELSE
NEXT_STATE <= S2_PLACE;
BITL <= 0;
END IF;
这块似乎有问题,process里边不加clk,就执行不下去。
所以,如果 当前状态和下一状态都是 S1_REP,是不是触发不了状态更新的操作
[img]
谢谢诸位
不看别的,有这么多红线,说明有很多信号被驱动乱掉了,或者是没有被驱动,在复位信号后,自己设计的逻辑一定不能有未知量
