📄 lpcinterface.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity lpcinterface is port(
clk,rst,iosel : in std_logic;
ext_rd,ext_wr : in std_logic;
ext_add : in std_logic_vector(7 downto 0);
ad : inout std_logic_vector(15 downto 0);
ldrq,serirq : in std_logic;
lad : inout std_logic_vector(3 downto 0);
led0,led1,led2,led3 : out std_logic;
lframe,lreset : out std_logic);
end lpcinterface;
architecture beha of lpcinterface is
type lpcst is (idle,startst,rdctst,wrctst,addst1,addst2,addst3,addst4,tarst1,tarst2,syncst,rddatast1,rddatast2,wrdatast1,wrdatast2,tarst3,tarst4,stopst);
signal pre_state,nxt_state : lpcst;
signal cmd_sel,rdreg_sel,wrreg_sel,addreg_sel,cmd_clr,startrd,startwr,ready : std_logic;
signal timeout,clr : std_logic;
signal ctreg : std_logic_vector(6 downto 0);
signal cmd_reg,wr_reg,rd_reg,add_reg : std_logic_vector(15 downto 0);
begin
con_state : process(clk,rst)
begin if iosel='1' and ext_add="00000100" then cmd_sel<='1';
else cmd_sel<='0';
end if;
if iosel='1' and ext_add="00001000" then rdreg_sel<='1';
else rdreg_sel<='0';
end if;
if iosel='1' and ext_add="00001100" then wrreg_sel<='1';
else wrreg_sel<='0';
end if;
if iosel='1' and ext_add="00010000" then addreg_sel<='1';
else addreg_sel<='0';
end if;
if rst='0' or cmd_clr='1' then cmd_reg<=(others=>'0');
elsif rising_edge(clk) then if cmd_sel='1' and ext_wr='1'
then cmd_reg<=ad(15 downto 0);
end if;
end if;
if rst='0' then wr_reg<=(others=>'0');
elsif rising_edge(clk) then if wrreg_sel='1' and ext_wr='1'
then wr_reg<=ad(15 downto 0);
end if;
end if;
if rst='0' then add_reg<=(others=>'0');
elsif rising_edge(clk) then if addreg_sel='1' and ext_wr='1'
then add_reg<=ad(15 downto 0);
end if;
end if;
startrd<=cmd_reg(0);
startwr<=cmd_reg(4);
if lad="0000" then ready<='1';
else ready<='0';
end if;
case pre_state is
when idle => if startrd='1' or startwr='1' then nxt_state<=startst;
else nxt_state<=idle;
end if;
when startst => if startrd='1' then nxt_state<=rdctst;
else nxt_state<=wrctst;
end if;
when rdctst => nxt_state<=addst1;
when wrctst => nxt_state<=addst1;
when addst1 => nxt_state<=addst2;
when addst2 => nxt_state<=addst3;
when addst3 => nxt_state<=addst4;
when addst4 => if startwr='1' then nxt_state<=wrdatast1;
else nxt_state<=tarst1;
end if;
when wrdatast1 => nxt_state<=wrdatast2;
when wrdatast2 => nxt_state<=tarst1;
when tarst1 => nxt_state<=tarst2;
when tarst2 => nxt_state<=syncst;
when syncst => if ready='1' and startrd='1' then nxt_state<=rddatast1;
elsif ready='1' and startwr='1' then nxt_state<=tarst3;
elsif timeout='1' then nxt_state<=stopst;
else nxt_state<=syncst;
end if;
when rddatast1 => nxt_state<=rddatast2;
when rddatast2 => nxt_state<=tarst3;
when tarst3 => nxt_state<=tarst4;
when tarst4 => nxt_state<=idle;
when stopst => nxt_state<=idle;
when others => nxt_state<=idle;
end case;
if rising_edge(clk) then if pre_state=addst1 then clr<='1';
else clr<='0';
end if;
end if;
if rst='0' or clr='1' then ctreg<=(others=>'0');
elsif rising_edge(clk) then ctreg<=ctreg+1;
end if;
if rising_edge(clk) then if ctreg="111100" then timeout<='1';
else timeout<='0';
end if;
end if;
if rising_edge(clk) then if pre_state=tarst3 then cmd_clr<='1';
else cmd_clr<='0';
end if;
end if;
if rst='0' then rd_reg<=(others=>'0');
elsif rising_edge(clk) then if pre_state=rddatast1
then rd_reg(3 downto 0)<=lad;
end if;
if pre_state=rddatast2 then
rd_reg(7 downto 4)<=lad;
end if;
end if;
if rst='0' then led0<='0';
elsif rising_edge(clk) then if pre_state=syncst and lad="0000" then led0<='1';
end if;
end if;
if rst='0' then led1<='0';
elsif rising_edge(clk) then if pre_state=syncst and lad="0101" then led1<='1';
end if;
end if;
if rst='0' then led2<='0';
elsif rising_edge(clk) then if pre_state=syncst and lad="0110" then led2<='1';
end if;
end if;
if rst='0' then led3<='0';
elsif rising_edge(clk) then if pre_state=syncst and lad="1010" then led3<='1';
end if;
end if;
end process;
st_pro : process(clk,rst)
begin if rst='0' then pre_state<=idle;
elsif rising_edge(clk) then pre_state<=nxt_state;
end if;
end process;
lreset<=rst;
lframe<='0' when pre_state=startst or pre_state=stopst
else '1';
lad<="0000" when pre_state=startst or pre_state=rdctst
else "0010" when pre_state=wrctst
else add_reg(15 downto 12) when pre_state=addst1
else add_reg(11 downto 8) when pre_state=addst2
else add_reg(7 downto 4) when pre_state=addst3
else add_reg(3 downto 0) when pre_state=addst4
else "1111" when pre_state=tarst1 or pre_state=tarst3 or pre_state=stopst
else wr_reg(3 downto 0) when pre_state=wrdatast1
else wr_reg(7 downto 4) when pre_state=wrdatast2
else "ZZZZ";
ad<=cmd_reg when ext_rd='1' and cmd_sel='1'
else rd_reg when ext_rd='1' and rdreg_sel='1'
else wr_reg when ext_rd='1' and wrreg_sel='1'
else add_reg when ext_rd='1' and addreg_sel='1'
else "ZZZZZZZZZZZZZZZZ";
end beha;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -