Помогите. Голова уже не соображает. Вот диаграмма. Код.
CODE
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SPI_Master is
Generic ( Quarz_Taktfrequenz : integer := 96000000;
SPI_Taktfrequenz : integer := 48000000;
Laenge : integer := 16
);
Port (
RX_Data : out STD_LOGIC_VECTOR (Laenge-1 downto 0);
MISO : in STD_LOGIC;
SCLK : out STD_LOGIC;
SS : out STD_LOGIC;
TX_Start : in STD_LOGIC;
TX_Done : out STD_LOGIC;
clk : in STD_LOGIC
);
end SPI_Master;
architecture Behavioral of SPI_Master is
signal delay : integer range 0 to (Quarz_Taktfrequenz/(2*SPI_Taktfrequenz));
constant clock_delay : integer := (Quarz_Taktfrequenz/(4*SPI_Taktfrequenz));
type spitx_states is (spi_stx,spi_txactive,spi_etx);
signal spitxstate : spitx_states := spi_stx;
signal spiclk : std_logic;
signal spiclklast: std_logic;
signal bitcounter : integer range 0 to Laenge; -- wenn bitcounter = Laenge --> alle Bits uebertragen
signal rx_reg : std_logic_vector(Laenge-1 downto 0) := (others=>'0');
begin
process begin
wait until falling_edge(CLK);
if(delay>0) then delay <= delay-1;
else delay <= clock_delay;
end if;
spiclklast <= spiclk;
case spitxstate is
when spi_stx =>
SS <= '1';
TX_Done <= '0';
bitcounter <= Laenge;
spiclk <= '1';
if(TX_Start = '1') then
spitxstate <= spi_txactive;
SS <= '0';
delay <= clock_delay;
end if;
when spi_txactive =>
if (delay=0) then
spiclk <= not spiclk;
if (bitcounter=0) then
spiclk <= '1';
spitxstate <= spi_etx;
end if;
if(spiclk='1') then
bitcounter <= bitcounter-1;
end if;
end if;
when spi_etx =>
SS <= '1';
TX_Done <= '1';
if(TX_Start = '0') then
spitxstate <= spi_stx;
end if;
end case;
end process;
process begin
wait until falling_edge(CLK);
if (spiclk='1' and spiclklast='0' ) then
rx_reg <= rx_reg(rx_reg'left-1 downto 0) & MISO;
end if;
end process;
SCLK <= spiclk;
RX_Data <= rx_reg;
end Behavioral;
И тестБенч.
CODE
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb_SPI_Master_vhd IS
END tb_SPI_Master_vhd;
ARCHITECTURE behavior OF tb_SPI_Master_vhd IS
COMPONENT SPI_Master
Port ( RX_Data : out STD_LOGIC_VECTOR (15 downto 0);
MISO : in STD_LOGIC;
SCLK : out STD_LOGIC;
SS : out STD_LOGIC;
TX_Start : in STD_LOGIC;
TX_Done : out STD_LOGIC;
clk : in STD_LOGIC
);
END COMPONENT;
SIGNAL MISO : std_logic := '0';
SIGNAL TX_Start : std_logic := '0';
SIGNAL clk : std_logic := '0';
SIGNAL RX_Data : std_logic_vector(15 downto 0);
SIGNAL SCLK : std_logic;
SIGNAL SS : std_logic;
SIGNAL TX_Done : std_logic;
SIGNAL rxsrslave : std_logic_vector(15 downto 0) := x"0000";
BEGIN
uut: SPI_Master PORT MAP(
RX_Data => RX_Data,
MISO => MISO,
SCLK => SCLK,
SS => SS,
TX_Start => TX_Start,
TX_Done => TX_Done,
clk => clk
);
clk <= not clk after 5.2 ns; -- 96 MHz
process (sclk) begin
if (falling_edge(SCLK)) then
rxsrslave <= rxsrslave(14 downto 0) & MISO;
end if;
end process;
b : PROCESS BEGIN
wait for 3035 ns;
MISO<='1';
wait for 106688 ns;
MISO<='0';
wait;
END PROCESS;
tb : PROCESS BEGIN
wait for 3 us;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait for 100000 ns;
wait for 3 us;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait for 100000 ns;
wait for 3 us;
TX_Start <= '1';
wait until TX_Done='1';
TX_Start <= '0';
wait;
END PROCESS;
END;
В Rx_date записывается лишнее значение. rxrslave прописан в тестбенче, он тактируется SCLK , поэтому там правильно записывается(по заднему фронту). Rx_date тактируется clk, запись туда производится при spiclk='1' and spiclklast='0' . И в самом конце он производит лишнюю запись. Как исправить ? Никак не соображу что понаделал.
Сообщение отредактировал des00 - Mar 31 2013, 17:48
Причина редактирования: используйте тег codebox для больших участков кода (с) модератор
Эскизы прикрепленных изображений