Цитата(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.
"Ты живешь в своих поступках, а не в теле. Ты — это твои действия, и нет другого тебя" Антуан де Сент-Экзюпери повесть "Маленький принц"