caicaidabing 发表于 2011-9-23 15:21:14

VHDL 12864 EPM7128

驱动12864显示的程序
--12864液晶(st7920)的显示--
--时钟频率:10MHZ-----------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity lcd12864 is
generic(
    divide_500k:integer:=10000--10000分频后:1000HZ:周期:1ms
    );
port(
   clk,reset:in std_logic;
   rs,rw,en:out std_logic;
   data:out std_logic_vector(7 downto 0)
   );
end entity;

architecture behavior of lcd12864 is
type word1 is array(0 to 5) of std_logic_vector(7 downto 0);
type word2 is array (0 to 5) of std_logic_vector(7 downto 0);
type state is(
   reset_state,
   set_dlnf1,set_dlnf2,set_cursor,set_dcb,set_shift,
   set_ddram,
   write_name,
   set_ddram2,
   write_name2,
   over
   );

--constant name:word:=("11010110","11010000","10111001","11111010");--中D6D0 国B9FA
constant name1:word1:=("11001010","10110001","10111100","11100100","10100001","11000011");--时间:
constant name2:word2:=("11001000","11010101","11000110","11011010","10100001","11000011"); ---日期:
signal pr_state:state;
signal newclk:std_logic;

begin
en<=newclk; ----状态机时钟信号,同时也是液晶时钟信号,其周期应该满足液晶数据的建立:频率不能太小,否则液晶无法正常显示。
-- rw<='0'; --写数据
process(clk) is
variable num:integer range 0 to divide_500k;
begin
   if(clk'event and clk='1')then
    num:=num+1;
    if(num=divide_500k) then
   num:=0;
    end if;
    if(num<divide_500k/2) then
   newclk<='0';
    else newclk<='1';
    end if;   
   end if;
end process;

process(newclk,reset,pr_state) is
   variable cnt:integer range 0 to 10:=0;
    variable cnt2:integer range 0 to 10:=0;
begin
   if(reset='0') then
    cnt:=0;
    cnt2:=0;
    data<="ZZZZZZZZ";
    pr_state<=set_dlnf1;--把状态set_dlnf1赋于pr_state
   elsif(newclk'event and newclk='1') then
    case pr_state is
   when set_dlnf1=>
      rs<='0';--命令
      rw<='0';
      data<="00110000";--选择8位数据基本指令集:0x30
      pr_state<=set_dlnf2;--把状态set_dlnf2赋于pr_state
   when set_dlnf2=>
      data<="00110000";--选择8位数据基本指令集:0x30,本人见过的程序中,0x30都被写了两次。尝试着去掉一个0x30的写入,对结果无影响。。不知为何,望指教?
      pr_state<=set_cursor;
   when set_cursor=>
      data<="00001100";--整体显示设置:光标OFF 反光0FF:0x0c
      pr_state<=set_dcb;
   when set_dcb=>
      data<="00000001";--清除显示,并且认定地址指针为00h:0x01
      pr_state<=set_shift;
   when set_shift=>
      data<="00000110";--指定游标的移动方向及指定显示的移位:0x06
      pr_state<=set_ddram;
   when set_ddram=>
       data<="10000000";--从第一行的第一个字开始显示:0x80
       pr_state<=write_name;
   when write_name=>
       rs<='1';
       data<=name1(cnt);
      cnt:=cnt+1;
      if(cnt=6) then
      cnt:=0;
       pr_state<=set_ddram2;
    end if;   
    when set_ddram2=>
       RS<='0';
      data<="10010000";--从第一行的第一个字开始显示:0x90
      pr_state<=write_name2;
   when write_name2=>
      rs<='1';
      data<=name2(cnt);
      cnt:=cnt+1;
      if(cnt=6) then
       cnt:=0;
       pr_state<=over;
      end if;   
   when over=>
      rs<='Z'; --此处一定要对rs,rw,data进行操作。
      rw<='Z'; --否则使能端时钟信号的驱使下不断地高低变化,会把上次的数据不停的写入液晶
      data<=(others=>'Z');
      cnt:=0;
   when others=>
      null;
    end case;
   end if;
end process;
end architecture;



编译的时候,出现错误,
Error: Design requires 9 output enable signals, but the device can contain only 6 output enable signals
Error: Can't find fit
Error: Quartus II Fitter was unsuccessful. 2 errors, 0 warnings
        Error: Peak virtual memory: 163 megabytes
        Error: Processing ended: Fri Sep 23 11:08:15 2011
        Error: Elapsed time: 00:00:00
        Error: Total CPU time (on all processors): 00:00:00
Error: Quartus II Full Compilation was unsuccessful. 4 errors, 1 warning

网上找了段BLOG   

最近写了一个程序,老是出现这样的错误:Error: Design requires 7 output enable signals, but the device can contain only 6 output enable signals ,当我写7个(others => 'Z')时,就会出现这样的错误,原以为这是芯片的限制,只能用6个高阻,然后其他的高阻我就用信号转发,signal <= (others => 'Z') ,io <= signal,这样语法上是没错,但实际上io口并不能呈高阻状态,所以一定要有7个高阻状态才能实现我所要的功能,冥思苦想未果,最后认识了网友“水滴”,她告诉我是逻辑单元占用过多造成,我的程序里与门确实过多,简化之后就可以了

我想知道如何简化代码?占用逻辑单元过多,为啥 ,哪些代码会占用过多的呢,谢谢

uindex 发表于 2011-9-24 23:28:10

楼主还是改用verilog吧
页: [1]
查看完整版本: VHDL 12864 EPM7128