⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpcinterface.vhd

📁 lpc源代码verilog实现的。操作low pin count设备
💻 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 + -