--本程序用来测试STM32对CPLD的读写操作
--测试功能如下:
--向0x05地址写入0x01,LED灯停止闪烁,写入其他数据闪烁继续
--0x03,0x04寄存器为定值,可以通过STM32读取然后使用串口输出看看是否一致
--文件名:AD.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity AD is
port(
-- 系统信号线
CLK: in std_logic;
LED: out std_logic;
-- ARM相连的信号线
Adr_L: in std_logic_vector(7 downto 0); --A7...A0,只使用了低八位地址线
D: inout std_logic_vector(7 downto 0); --只使用了低八位数据线
FSMC_NE4: in std_logic;
FSMC_NOE: in std_logic;
FSMC_NWE: in std_logic
);
end AD;
architecture art of AD is
--设置存储数据的寄存器
signal AD0_H_data,AD0_L_data,AD1_H_data,AD1_L_data,LED_ctrl: std_logic_vector(7 downto 0);
--数据缓冲寄存器
signal data_buf: std_logic_vector(7 downto 0);
--数据输出控制
signal data_outctl: std_logic;
signal datacnt:integer range 0 to 4000000;--分频计数
--LED闪烁使能
signal LED_flag: std_logic;
--统一编址,地址线数据线为八位,每个地址数据宽度8位
--"00000001" AD0_H_data 0x01
--"00000010" AD0_L_data 0x02
--"00000011" AD1_H_data 0x03
--"00000100" AD1_L_data 0x04
--"00000101" LED_ctrl 0x05
begin
AD1_H_data <="10100001";
AD1_L_data <="00010001";
--LED 闪烁,用作CPLD运行指示
process(LED_ctrl) is
begin
if(LED_ctrl="00000001") then
LED_flag <= '0';
else
LED_flag <= '1';
end if;
end process;
process(CLK)is
begin
if(CLK'event and CLK='1') then
if(LED_flag='1') then
datacnt<=datacnt+1;
if (datacnt>2000000) then
LED <= '1';
end if;
if (datacnt>=4000000) then
LED <='0';
datacnt <=0;
end if;
end if;
end if;
end process;
--当读取CPLD数据时用来判断何时向总线上输出数据
data_outctl <= (not FSMC_NE4) and (not FSMC_NOE) and (FSMC_NWE);
D <= data_buf when (data_outctl='1') else "ZZZZZZZZ";--向数据线输出数据,否则保持为高阻态
-- 写操作,模式1,时序图在数据手册P331
process(FSMC_NE4,FSMC_NWE,Adr_L,FSMC_NOE) is --,FSMC_NBL,D,RESET
begin
if(FSMC_NWE'event and FSMC_NWE='1') then
if((FSMC_NOE and (not FSMC_NE4))='1') then
case (Adr_L) is
when "00000001" =>
AD0_H_data<= D; --0x01
when "00000010" =>
AD0_L_data<= D; --0x02
when "00000101" =>
LED_ctrl<= D; --0x05
when others =>
AD0_H_data<= AD0_H_data;
AD0_L_data<= AD0_L_data;
end case;
end if;
end if;
end process;
--读操作,模式1,P331
process(FSMC_NE4,FSMC_NWE,Adr_L,FSMC_NOE) is
begin
if(FSMC_NOE='0' and FSMC_NOE'event) then --直接在NOE的下降沿更新数据
case (Adr_L) is
when "00000001" =>
data_buf <= AD0_H_data; --0x01
when "00000010" =>
data_buf <= AD0_L_data; --0x02
when "00000011" =>
data_buf <= AD1_H_data; --0x03
when "00000100" =>
data_buf <= AD1_L_data; --0x04
when others => data_buf <= "ZZZZZZZZ";
end case;
end if;
end process;
end;