реклама на сайте
подробности

 
 
> модуль spi slave verilog
sergey sva
сообщение May 9 2015, 15:14
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Хочу попробовать запустить spi slave на циклоне. Поискал в сети готовые исходники, примеров много для этого интерфейса не знаю с какого начать, подскажите пожалуйста ссылку на проверенный пример, который вам понравился ))
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sergey sva
сообщение May 10 2015, 09:03
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Благодарю за код, давайте если не жалко )).
Есть какие отличия ? На верилоге вроде компактнее получается код, конечно у меня опыта не много поэтому утверждать не буду.
Сейчас попробую протестировать на stm32f407 ep3c5e результат напишу.

Значок решетка что означает? Немного не по теме, случайно не знаете в квартусе 13,1 есть автоформатирование кода ?
Go to the top of the page
 
+Quote Post
Maverick
сообщение May 10 2015, 11:20
Сообщение #3


я только учусь...
******

Группа: Модераторы
Сообщений: 3 447
Регистрация: 29-01-07
Из: Украина
Пользователь №: 24 839



Цитата(sergey sva @ May 10 2015, 12:03) *
Благодарю за код, давайте если не жалко )).
Есть какие отличия ?


описание на VHDL - функциональных отличий нет по сравнению с описанием на verilog.

CODE
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity spi_slave is
generic (DATA_LENGTH : integer:=8;
SHIFT_DIRECTION: std_logic := '0';
CLOCK_POLARITY:std_logic:='0';
CLOCK_PHASE:std_logic:='0');
port (
CSn : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
WR_RD : in std_logic;
DATA_OUT : out std_logic_vector(7 downto 0);
TX_RDY : out std_logic;
RX_RDY : out std_logic;
TX_ERR : out std_logic;
RX_ERR : out std_logic;
CLK_I : in std_logic;
RST_I : in std_logic;
MISO_SLAVE : out std_logic;
MOSI_SLAVE : in std_logic;
CSn_SLAVE : in std_logic;
SCLK_SLAVE : in std_logic
);

end;

architecture arch of spi_slave is
constant UDLY:time:=1 ns;
signal latch_s_data:std_logic_vector(7 downto 0);
signal reg_rxdata:std_logic_vector(DATA_LENGTH-1 downto 0);
signal reg_txdata:std_logic_vector(DATA_LENGTH-1 downto 0);
signal rx_shift_data:std_logic_vector(DATA_LENGTH-1 downto 0);

signal reg_toe:std_logic;
signal reg_roe:std_logic;
signal reg_trdy:std_logic;
signal reg_rrdy:std_logic;

signal tx_done:std_logic;
signal rx_done:std_logic;
signal rx_done_flip1:std_logic;
signal rx_done_flip2:std_logic;
signal rx_done_flip3:std_logic;
signal tx_done_flip1:std_logic;
signal tx_done_flip2:std_logic;
signal tx_done_flip3:std_logic;
signal rx_data_cnt:std_logic_vector(5 downto 0);
signal tx_data_cnt:std_logic_vector(5 downto 0);

begin

TX_RDY<=reg_trdy;
RX_RDY<=reg_rrdy;
TX_ERR<=reg_toe;
RX_ERR<=reg_roe;
DATA_OUT<=reg_rxdata;

process(CLK_I,RST_I) begin
if(RST_I='1') then
latch_s_data <= (others => '0');
elsif rising_edge(CLK_I) then
if (WR_RD='0' and CSn='0' and reg_trdy='1') then
latch_s_data <=DATA_IN;
end if;
end if;
end process;

--Receive Data Register
process(CLK_I,RST_I) begin
if(RST_I='1') then
reg_rxdata <=(others => '0');
elsif rising_edge(CLK_I) then
if (rx_done_flip1='1' and rx_done_flip2='0') then
reg_rxdata <= rx_shift_data;
end if;
end if;
end process;

--Transmit Data Register
process(CLK_I,RST_I) begin
if(RST_I='1') then
reg_txdata <= (others => '0');
elsif rising_edge(CLK_I) then
reg_txdata <= latch_s_data;
end if;
end process;

-------------------------------For Rx data,
-------------------sample at posedge when CLOCK_POLARITY=0 and CLOCK_PHASE is 0

u1: if CLOCK_POLARITY='0' and CLOCK_PHASE='0' generate

process(SCLK_SLAVE,RST_I) begin
if (RST_I='1') then
rx_shift_data <= (others => '0');
elsif rising_edge(SCLK_SLAVE) then
if (CSn_SLAVE='0') then
if (SHIFT_DIRECTION='1') then
rx_shift_data <= MOSI_SLAVE & rx_shift_data(DATA_LENGTH-1 downto 1);
else
rx_shift_data <= rx_shift_data(DATA_LENGTH-2 downto 0) & MOSI_SLAVE;
end if;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_data_cnt <= (others => '0');
elsif rising_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_data_cnt <=(others => '0');
elsif (CSn_SLAVE='0') then
rx_data_cnt <=rx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_done <= '0';
elsif rising_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_done <= '1';
else
rx_done <= '0';
end if;
end if;
end process;
end generate;
-------------------sample at negedge when CLOCK_POLARITY=0 and CLOCK_PHASE is 1
u2: if CLOCK_POLARITY='0' and CLOCK_PHASE='1' generate
--For Rx data, sample at negedge when CLOCK_PHASE is 1
process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_shift_data <= (others => '0');
elsif falling_edge(SCLK_SLAVE) then
if (CSn_SLAVE='0') then
if (SHIFT_DIRECTION='1') then
rx_shift_data <= MOSI_SLAVE & rx_shift_data(DATA_LENGTH-1 downto 1);
else
rx_shift_data <= rx_shift_data(DATA_LENGTH-2 downto 0) & MOSI_SLAVE;
end if;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_data_cnt <= (others => '0');
elsif falling_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_data_cnt <=(others => '0');
elsif (CSn_SLAVE='0') then
rx_data_cnt <=rx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_done <= '0';
elsif falling_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_done <= '1';
else
rx_done <= '0';
end if;
end if;
end process;
end generate;
-------------------sample at negedge when CLOCK_POLARITY=1 and CLOCK_PHASE is 0
u3:if CLOCK_POLARITY='1' and CLOCK_PHASE='0' generate

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_shift_data <= (others => '0');
elsif falling_edge(SCLK_SLAVE) then
if (CSn_SLAVE='0') then
if (SHIFT_DIRECTION='1') then
rx_shift_data <= MOSI_SLAVE & rx_shift_data(DATA_LENGTH-1 downto 1);
else
rx_shift_data <= rx_shift_data(DATA_LENGTH-2 downto 0) & MOSI_SLAVE;
end if;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_data_cnt <= (others => '0');
elsif falling_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_data_cnt <=(others => '0');
elsif (CSn_SLAVE='0') then
rx_data_cnt <=rx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_done <= '0';
elsif falling_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_done <= '1';
else
rx_done <= '0';
end if;
end if;
end process;
end generate;

-------------------sample at posedge when CLOCK_POLARITY=1 and CLOCK_PHASE is 1
u4: if CLOCK_POLARITY='1' and CLOCK_PHASE='1' generate
--For Rx data, sample at negedge when CLOCK_PHASE is 1
process(SCLK_SLAVE,RST_I) begin
if (RST_I='1') then
rx_shift_data <= (others => '0');
elsif rising_edge(SCLK_SLAVE) then
if (CSn_SLAVE='0') then
if (SHIFT_DIRECTION='1') then
rx_shift_data <= MOSI_SLAVE & rx_shift_data(DATA_LENGTH-1 downto 1);
else
rx_shift_data <= rx_shift_data(DATA_LENGTH-2 downto 0) & MOSI_SLAVE;
end if;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_data_cnt <= (others => '0');
elsif rising_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_data_cnt <=(others => '0');
elsif (CSn_SLAVE='0') then
rx_data_cnt <=rx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
rx_done <= '0';
elsif rising_edge(SCLK_SLAVE) then
if (rx_data_cnt = DATA_LENGTH - 1) then
rx_done <= '1';
else
rx_done <= '0';
end if;
end if;
end process;
end generate;

process(CLK_I,RST_I) begin
if (RST_I='1') then
rx_done_flip1 <= '0';
rx_done_flip2 <= '0';
rx_done_flip3 <= '0';
elsif rising_edge(CLK_I) then
rx_done_flip1 <= rx_done;
rx_done_flip2 <= rx_done_flip1;
rx_done_flip3 <= rx_done_flip2;
end if;
end process;


process(CLK_I,RST_I) begin
if (RST_I='1') then
reg_rrdy <= '0';
elsif rising_edge(CLK_I) then
if (rx_done_flip2='1' and rx_done_flip3='0') then
reg_rrdy <= '1';
elsif (WR_RD='1' and CSn='0') then
reg_rrdy <= '0';
end if;
end if;
end process;

process(CLK_I,RST_I) begin
if (RST_I='1') then
reg_roe <= '0';
elsif rising_edge(CLK_I) then
if (rx_done_flip2='1' and rx_done_flip3='0' and reg_rrdy='1') then
reg_roe <= '1';
elsif (WR_RD='1' and CSn='0') then
reg_roe <= '0';
end if;
end if;
end process;

----------------------For Tx data,
-------------------------------------update at negedge when CLOCK_POLARITY=0 and CLOCK_PHASE is 0
u11: if CLOCK_POLARITY='0' and CLOCK_PHASE='0' generate

process(reg_txdata,tx_data_cnt,CSn_SLAVE ) begin
if (CSn_SLAVE='0') then
if(SHIFT_DIRECTION='1') then
MISO_SLAVE <= reg_txdata(conv_integer(tx_data_cnt));
else
MISO_SLAVE <= reg_txdata(conv_integer(DATA_LENGTH-tx_data_cnt-1));
end if;
else
MISO_SLAVE<='Z';
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_data_cnt <= (others => '0');
elsif falling_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_data_cnt <= (others => '0');
elsif (CSn_SLAVE='0') then
tx_data_cnt <= tx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_done <='0';
elsif falling_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_done <= '1';
else
tx_done <= '0';
end if;
end if;
end process;
end generate;
-------------------------------------update at posedge when CLOCK_POLARITY=0 and CLOCK_PHASE is 1
u22: if CLOCK_POLARITY='0' and CLOCK_PHASE='1' generate

process (SCLK_SLAVE) begin
if rising_edge(CLK_I) then
if (CSn_SLAVE='0') then
if(SHIFT_DIRECTION='1') then
MISO_SLAVE <= reg_txdata(conv_integer(tx_data_cnt));
else
MISO_SLAVE <= reg_txdata(conv_integer(DATA_LENGTH-tx_data_cnt-1));
end if;
else
MISO_SLAVE<='Z';
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_data_cnt <= (others => '0');
elsif rising_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_data_cnt <= (others => '0');
elsif (CSn_SLAVE='0') then
tx_data_cnt <= tx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_done <= '0';
elsif rising_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_done <= '1';
else
tx_done <= '0';
end if;
end if;
end process;
end generate;

-------------------------------------update at posedge when CLOCK_POLARITY=1 and CLOCK_PHASE is 0
u33: if CLOCK_POLARITY='1' and CLOCK_PHASE='0' generate
process(reg_txdata,tx_data_cnt,CSn_SLAVE ) begin
if (CSn_SLAVE='0') then
if(SHIFT_DIRECTION='1') then
MISO_SLAVE <= reg_txdata(conv_integer(tx_data_cnt));
else
MISO_SLAVE <= reg_txdata(conv_integer(DATA_LENGTH-tx_data_cnt-1));
end if;
else
MISO_SLAVE<='Z';
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_data_cnt <= (others => '0');
elsif rising_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_data_cnt <= (others => '0');
elsif (CSn_SLAVE='0') then
tx_data_cnt <= tx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_done <= '0';
elsif rising_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_done <= '1';
else
tx_done <= '0';
end if;
end if;
end process;

end generate;

-------------------------------------update at negedge when CLOCK_POLARITY=1 and CLOCK_PHASE is 1
u44: if CLOCK_POLARITY='1' and CLOCK_PHASE='1' generate

process (SCLK_SLAVE) begin
if falling_edge(CLK_I) then
if (CSn_SLAVE='0') then
if(SHIFT_DIRECTION='1') then
MISO_SLAVE <= reg_txdata(conv_integer(tx_data_cnt));
else
MISO_SLAVE <= reg_txdata(conv_integer(DATA_LENGTH-tx_data_cnt-1));
end if;
else
MISO_SLAVE<='Z';
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_data_cnt <= (others => '0');
elsif falling_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_data_cnt <= (others => '0');
elsif (CSn_SLAVE='0') then
tx_data_cnt <= tx_data_cnt + 1;
end if;
end if;
end process;

process(SCLK_SLAVE ,RST_I) begin
if (RST_I='1') then
tx_done <='0';
elsif falling_edge(SCLK_SLAVE) then
if (tx_data_cnt = DATA_LENGTH - 1) then
tx_done <= '1';
else
tx_done <= '0';
end if;
end if;
end process;

end generate;

process(CLK_I,RST_I) begin
if (RST_I='1') then
tx_done_flip1 <= '0';
tx_done_flip2 <= '0';
tx_done_flip3 <= '0';
elsif rising_edge(CLK_I) then
tx_done_flip1 <= tx_done;
tx_done_flip2 <= tx_done_flip1;
tx_done_flip3 <= tx_done_flip2;
end if;
end process;

process(CLK_I,RST_I) begin
if (RST_I='1') then
reg_roe <= '0';
elsif rising_edge(CLK_I) then
if (rx_done_flip2='1' and rx_done_flip3='0' and reg_rrdy='1') then
reg_roe <= '1';
elsif (WR_RD='1' and CSn='0') then
reg_roe <= '0';
end if;
end if;
end process;


process(CLK_I,RST_I) begin
if (RST_I='1') then
reg_trdy <= '1';
elsif rising_edge(CLK_I) then
if (WR_RD='0' and CSn='0') then
reg_trdy <= '0';
elsif (tx_done_flip2='1' and tx_done_flip3='0') then
reg_trdy <= '1';
end if;
end if;
end process;


process(CLK_I,RST_I) begin
if (RST_I='1') then
reg_toe <= '0';
elsif rising_edge(CLK_I) then
if(reg_trdy='0' and WR_RD='0' and CSn='0') then
reg_toe <= '1';
elsif(WR_RD='0' and CSn='0') then
reg_toe <= '0';
end if;
end if;
end process;

end arch;


тестбенч:

CODE
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity spi_master is
port(
sclk_master: out std_logic;
csn_master: out std_logic;
mosi_master: out std_logic;
miso_master: in std_logic
);
end;

architecture arch_spi_master of spi_master is

constant CLOCK_PHASE:std_logic:='0';
constant CLOCK_POLARITY:std_logic:='0';
constant SHIFT_DIRECTION:std_logic:='0';
constant DATA_LENGTH:integer:= 8;

--signal master_data_in:std_logic_vector(7 downto 0);
--signal master_data_out:std_logic_vector(7 downto 0);
--
--signal cnt:std_logic_vector(2 downto 0);

signal sclk_master_tmp: std_logic;
signal csn_master_tmp: std_logic;
signal mosi_master_tmp: std_logic;

function slv4_xcha (inp: STD_LOGIC_VECTOR(3 downto 0)) return CHARACTER is
variable result: character;

begin
case inp is
when "0000" => result := '0';
when "0001" => result := '1';
when "0010" => result := '2';
when "0011" => result := '3';
when "0100" => result := '4';
when "0101" => result := '5';
when "0110" => result := '6';
when "0111" => result := '7';
when "1000" => result := '8';
when "1001" => result := '9';
when "1010" => result := 'a';
when "1011" => result := 'b';
when "1100" => result := 'c';
when "1101" => result := 'd';
when "1110" => result := 'e';
when "1111" => result := 'f';
when others => result := 'x';
end case;
return result;
end;

function slv8_xstr (inp: STD_LOGIC_VECTOR(7 downto 0)) return STRING is
variable result : string (1 to 2);

begin
result := slv4_xcha(inp(7 downto 4)) & slv4_xcha(inp(3 downto 0));
return result;
end;

procedure spi_master_operation (signal sclk_master_tmp : out std_logic;
signal csn_master_tmp: out std_logic;
signal mosi_master_tmp: out std_logic;
signal miso_master: in std_logic;
constant data_out:in STD_LOGIC_VECTOR(7 downto 0);
constant CLOCK_PHASE : in std_logic;
constant CLOCK_POLARITY : in std_logic;
constant SHIFT_DIRECTION : in std_logic;
constant DATA_LENGTH : in integer
) is
variable master_data_in:std_logic_vector(7 downto 0):=(others => '0');
variable master_data_out:std_logic_vector(7 downto 0):=(others => '0');
variable cnt:integer;
variable i:integer;
variable sclk_cycle:time:=40 ns;

begin
csn_master_tmp<='1';
mosi_master_tmp<='0';
report "SPI master sends data " & slv8_xstr(data_out);
master_data_out:=data_out;
csn_master_tmp<='0';
if(CLOCK_POLARITY='0') then
if(CLOCK_PHASE='0') then
cnt:=0;
for i in 7 downto 0 loop
if(SHIFT_DIRECTION='1') then
mosi_master_tmp<=master_data_out(cnt);
else
mosi_master_tmp<=master_data_out(DATA_LENGTH-cnt-1);
end if;
wait for sclk_cycle;
sclk_master_tmp<='1';
master_data_in:=(master_data_in(6 downto 0) & miso_master);
wait for sclk_cycle;
sclk_master_tmp<='0';
cnt:=cnt+1;
end loop;
wait for 2 ns;
csn_master_tmp<='1';
else
cnt:=0;
for i in 7 downto 0 loop
wait for sclk_cycle;
sclk_master_tmp<='1';
if(SHIFT_DIRECTION='1') then
mosi_master_tmp<=master_data_out(cnt);
else
mosi_master_tmp<=master_data_out(DATA_LENGTH-cnt-1);
end if;
cnt:=cnt+1;
wait for sclk_cycle;
sclk_master_tmp<='0';
master_data_in:=(master_data_in(6 downto 0) & miso_master);
end loop;
wait for 2 ns;
csn_master_tmp<='1';
end if;

else
if(CLOCK_PHASE='0') then
cnt:=0;
for i in 7 downto 0 loop
if(SHIFT_DIRECTION='1') then
mosi_master_tmp<=master_data_out(cnt);
else
mosi_master_tmp<=master_data_out(DATA_LENGTH-cnt-1);
end if;
wait for sclk_cycle;
sclk_master_tmp<='0';
master_data_in:=(master_data_in(6 downto 0) & miso_master);
wait for sclk_cycle;
sclk_master_tmp<='1';
cnt:=cnt+1;
end loop;
wait for 2 ns;
csn_master_tmp<='1';

else
cnt:=0;
for i in 7 downto 0 loop
wait for sclk_cycle;
sclk_master_tmp<='0';
if(SHIFT_DIRECTION='1') then
mosi_master_tmp<=master_data_out(cnt);
else
mosi_master_tmp<=master_data_out(DATA_LENGTH-cnt-1);
end if;
cnt:=cnt+1;
wait for sclk_cycle;
sclk_master_tmp<='1';
master_data_in:=(master_data_in(6 downto 0) & miso_master);
end loop;
wait for 2 ns;
csn_master_tmp<='1';
end if;
end if;
report "SPI master receive data " & slv8_xstr(master_data_in);
end;

begin

sclk_master<=sclk_master_tmp;
csn_master<=csn_master_tmp;
mosi_master<=mosi_master_tmp;

initial: process begin
--wait for 1 ns;
if(CLOCK_POLARITY='1') then
sclk_master_tmp<='1' after 1 ns;
else
sclk_master_tmp<='0';
end if;

wait for 306 ns;

spi_master_operation(sclk_master_tmp,csn_master_tmp,mosi_master_tmp,miso_master,
"01110011",CLOCK_PHASE,CLOCK_POLARITY,SHIFT_DIRECTION,DATA_LENGTH);

wait for 100 ns;

spi_master_operation(sclk_master_tmp,csn_master_tmp,mosi_master_tmp,miso_master,
"01000011",CLOCK_PHASE,CLOCK_POLARITY,SHIFT_DIRECTION,DATA_LENGTH);

wait for 104 ns;

spi_master_operation(sclk_master_tmp,csn_master_tmp,mosi_master_tmp,miso_master,
"00011001",CLOCK_PHASE,CLOCK_POLARITY,SHIFT_DIRECTION,DATA_LENGTH);

wait for 100 ns;

spi_master_operation(sclk_master_tmp,csn_master_tmp,mosi_master_tmp,miso_master,
"01010101",CLOCK_PHASE,CLOCK_POLARITY,SHIFT_DIRECTION,DATA_LENGTH);

wait for 100 ns;

spi_master_operation(sclk_master_tmp,csn_master_tmp,mosi_master_tmp,miso_master,
"10101010",CLOCK_PHASE,CLOCK_POLARITY,SHIFT_DIRECTION,DATA_LENGTH);

wait for 100 ns;
wait;
end process;

end arch_spi_master;


-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity back_end_device is
port(
CSn: out std_logic;
DATA_IN:in STD_LOGIC_VECTOR(7 downto 0);
WR_RD: out std_logic;
DATA_OUT:out STD_LOGIC_VECTOR(7 downto 0);
TX_RDY: in std_logic;
RX_RDY: in std_logic;
TX_ERR: in std_logic;
RX_ERR: in std_logic;
CLK: out std_logic;
RST: out std_logic
);
end;

architecture arch_back_end_device of back_end_device is
constant clk_cycle:time:=5 ns;
signal clk_temp:std_logic;
signal data_out_temp:STD_LOGIC_VECTOR(7 downto 0);
signal i:integer:=0;

function slv4_xcha_r (inp: STD_LOGIC_VECTOR(3 downto 0)) return CHARACTER is
variable result: character;

begin
case inp is
when "0000" => result := '0';
when "0001" => result := '1';
when "0010" => result := '2';
when "0011" => result := '3';
when "0100" => result := '4';
when "0101" => result := '5';
when "0110" => result := '6';
when "0111" => result := '7';
when "1000" => result := '8';
when "1001" => result := '9';
when "1010" => result := 'a';
when "1011" => result := 'b';
when "1100" => result := 'c';
when "1101" => result := 'd';
when "1110" => result := 'e';
when "1111" => result := 'f';
when others => result := 'x';
end case;
return result;
end;

function slv8_xstr_r (inp: STD_LOGIC_VECTOR(7 downto 0)) return STRING is
variable result : string (1 to 2);

begin
result := slv4_xcha_r(inp(7 downto 4)) & slv4_xcha_r(inp(3 downto 0));
return result;
end;
begin

clk_gen:process
begin
clk_temp<='0';
wait for clk_cycle;
loop
clk_temp<=not clk_temp;
wait for clk_cycle;
end loop;
end process;

CLK<=clk_temp;
DATA_OUT<=data_out_temp;

initial: process begin
RST<='0';
CSn<='1';
WR_RD<='1';
data_out_temp<=(others => '0');

wait for 2 ns;
RST<='1';
wait for 202 ns;
RST<='0';

while(i<3) loop
wait until clk_temp'event and clk_temp = '1';
if(RX_RDY='1' or TX_RDY='1') then
if(TX_RDY='1') then
CSn<='0' after 1 ns;
WR_RD<='0' after 1 ns;
if(i=0) then
data_out_temp<="00001000" after 1 ns;
elsif(i=1) then
data_out_temp<="11101101" after 1 ns;
elsif(i=2) then
data_out_temp<="11011001" after 1 ns;
end if;
i<=i+1;
wait for 1 ns;
report "Back end device send data " & slv8_xstr_r(data_out_temp);
wait until clk_temp'event and clk_temp = '1';
CSn<='1' after 1 ns;
WR_RD<='1' after 1 ns;
elsif(RX_RDY='1') then
CSn<='0' after 1 ns;
WR_RD<='1' after 1 ns;
report "Back end device receive data " & slv8_xstr_r(DATA_IN);

wait until clk_temp'event and clk_temp = '1';
CSn<='1' after 1 ns;
WR_RD<='1' after 1 ns;
end if;
end if;
end loop;

while(i=3) loop
wait until clk_temp'event and clk_temp = '1';
CSn<='0' after 1 ns;
WR_RD<='0' after 1 ns;
data_out_temp<="11100011" after 1 ns;
wait for 1 ns;
report "Back end device send data " & slv8_xstr_r(data_out_temp);
wait until clk_temp'event and clk_temp = '1';
CSn<='1' after 1 ns;
WR_RD<='1' after 1 ns;
i<=4;
end loop;
wait for 2500 ns;
--wait;
end process;


end arch_back_end_device;

-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity spi_speripheral_tb is
end spi_speripheral_tb;

architecture arch_spi_speripheral_tb of spi_speripheral_tb is

component spi_slave is
--generic (DATA_LENGTH : integer:=8;
-- SHIFT_DIRECTION: std_logic := '0';
-- CLOCK_POLARITY:std_logic:='0';
-- CLOCK_PHASE:std_logic:='0');
port (
CSn : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
WR_RD : in std_logic;
DATA_OUT : out std_logic_vector(7 downto 0);
TX_RDY : out std_logic;
RX_RDY : out std_logic;
TX_ERR : out std_logic;
RX_ERR : out std_logic;
CLK_I : in std_logic;
RST_I : in std_logic;
MISO_SLAVE : out std_logic;
MOSI_SLAVE : in std_logic;
CSn_SLAVE : in std_logic;
SCLK_SLAVE : in std_logic
);

end component;

component spi_master is
port(
sclk_master: out std_logic;
csn_master: out std_logic;
mosi_master: out std_logic;
miso_master: in std_logic
);
end component;

component back_end_device is
port(
CSn: out std_logic;
DATA_IN: in std_logic_vector(7 downto 0);
WR_RD: out std_logic;
DATA_OUT: out std_logic_vector(7 downto 0);
TX_RDY: in std_logic;
RX_RDY: in std_logic;
TX_ERR: in std_logic;
RX_ERR: in std_logic;
CLK: out std_logic;
RST: out std_logic
);
end component;

signal clk,rst:std_logic;
signal mosi,csn_spi,sclk:std_logic;
signal csn,wr_rd:std_logic;
signal data_out:std_logic_vector(7 downto 0);

signal miso:std_logic;
signal tx_rdy,rx_rdy,tx_err,rx_err:std_logic;
signal data_in:std_logic_vector(7 downto 0);

begin

spi_master_uut: spi_master port map(
sclk_master=>sclk,
csn_master=>csn_spi,
mosi_master=>mosi,
miso_master=>miso
);

spi_slave_uut: spi_slave port map
(
CSn=>csn,
DATA_IN=>data_in,
WR_RD=>wr_rd,
DATA_OUT=>data_out,
TX_RDY=>tx_rdy,
RX_RDY=>rx_rdy,
TX_ERR=>tx_err,
RX_ERR=>rx_err,

MISO_SLAVE=>miso,
MOSI_SLAVE=>mosi,
CSn_SLAVE=>csn_spi,
SCLK_SLAVE=>sclk,
CLK_I=>clk,
RST_I=>rst
);

back_end_device_uut: back_end_device port map(
CSn=>csn,
DATA_IN=>data_out,
WR_RD=>wr_rd,
DATA_OUT=>data_in,
TX_RDY=>tx_rdy,
RX_RDY=>rx_rdy,
TX_ERR=>tx_err,
RX_ERR=>rx_err,
CLK=>clk,
RST=>rst
);

end arch_spi_speripheral_tb;


Цитата
Значок решетка что означает?

#100; (verilog) = wait for 100 ns; (vhdl)

PS у меня это описание работало в "железе"
PS PS Мне не жалко, в надежде, что когда мне что-то понадобиться, то тоже люди тоже откликнуться и помогут...


--------------------
If it doesn't work in simulation, it won't work on the board.

"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- sergey sva   модуль spi slave verilog   May 9 2015, 15:14
- - Maverick   RE: модуль spi slave verilog   May 9 2015, 17:48
- - sergey sva   Благодарю вас. Эта задержка синтезируется или это ...   May 10 2015, 13:09
|- - Maverick   Цитата(sergey sva @ May 10 2015, 16:09) Б...   May 10 2015, 13:10
|- - johan   Цитата(Maverick @ May 10 2015, 16:10) тол...   May 10 2015, 17:52
|- - Maverick   Цитата(johan @ May 10 2015, 20:52) Где-то...   May 10 2015, 17:58
||- - johan   Цитата(Maverick @ May 10 2015, 20:58) а ч...   May 10 2015, 18:59
|- - Nepoch   Цитата(johan @ May 10 2015, 21:52) Где-то...   May 20 2015, 17:58
- - sergey sva   Понятно. Попробовал сразу все заработало)). Частот...   May 10 2015, 13:20
|- - Maverick   Цитата(sergey sva @ May 10 2015, 16:20) Е...   May 10 2015, 13:57
- - sergey sva   Да совпадают Код RCC_APB2PeriphClockCmd(RCC_A...   May 10 2015, 15:35
- - sergey sva   Можно как то синтезировать задержку? Иногда очень ...   May 10 2015, 18:30
- - krux   #1 сильно помогает "старой гвардии", при...   May 20 2015, 18:11
- - fookat   Здравствуйте. Недавно начал вникать в тему FPGA и ...   Aug 3 2016, 08:17
|- - Tausinov   Путем таких нехитрых условий требуемое действие пр...   Aug 3 2016, 09:31
- - glb   Доброго дня! Использовал приведенный пример SP...   Aug 23 2016, 12:53
- - likeasm   Цитата(glb @ Aug 23 2016, 15:53) Доброго ...   Aug 26 2016, 08:04
- - Jenya7   решил поднять тему. посмотрел описание SPI Slave н...   Feb 20 2017, 07:50


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 16:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01634 секунд с 7
ELECTRONIX ©2004-2016