jssd 发表于 2010-5-13 14:52:59

请教~~~~~~~~~~~~~~~~~~~VHDL同时读取时钟上升沿和下降沿出现的出错问题

--我想要实现的功能:rMCU下降沿时输出数据,然后拉低wMCU表示数据已经准备好。等待rMCU拉高,然后wMCU拉高准备下一次读写.
rMCU: input读
wMCU: output写
datout:数据输出。

rMCU:   ~~~\________/~~~~~~~~\________/~~~~~~~~\__
datout: ~~~\AAAAAAAAAAAAAAAAA\BBBBBBBBBBBBBBBBB\CCCC
wMCU:   ~~~~~\_____/~~~~~~~~~~~\_____/~~~~~~~~~~~\_

--以下是我写的程序
library ieee;
use ieee.std_logic_1164.all;

entity MCUtest is
    port(rMCU: in std_logic;
         wMCU: out std_logic;
         datout: inout std_logic_vector(7 downto 0));
end MCUtest;

architecture behav of MCUtest is
signal datnum: integer range 0 to 8;
signal datstart: std_logic_vector(7 downto 0);
signal datx1h,daty1h,datx2h,daty2h,datx1l,daty1l,datx2l,daty2l: std_logic_vector(7 downto 0);
begin
    datstart <= "10101010";
    process(rMCU)
    begin
    if(rMCU'event and rMCU = '0') then
      case(datnum) is
            when 0 => datout <= datstart;
            when 1 => datout <= datx1h;
            when 2 => datout <= datx1l;
            when 3 => datout <= daty1h;
            when 4 => datout <= daty1l;
            when 5 => datout <= datx2h;
            when 6 => datout <= datx2l;
            when 7 => datout <= daty2h;
            when 8 => datout <= daty2l;
      end case;
      wMCU <= '0';
      if(datnum = 8) then
            datnum <= 0;
      else
            datnum <= datnum + 1;
      end if;
    end if;
               
    if(rMCU'event and rMCU = '1') then
      wMCU <= '1';
    end if;
    end process;
end behav;

问题是最后
    if(rMCU'event and rMCU = '1') then
      wMCU <= '1';
    end if;
    end process;
编译时出错
Error (10819): Netlist error at MCUtest.vhd(40): can't infer register for wMCU because it changes value on both rising and falling edges of the clock

请问怎么解决?
或者有其他什么样的编程方法吗?

40130064 发表于 2010-5-13 15:45:29

一个进程只能有一个边沿检测

试试这个,我没在Q2上试,也许有错.
begin
    --datstart <= "10101010";--
    process
    begin
    if(rMCU = '0') then
      case(datnum) is
            when 0 => datout <= datstart;
            when 1 => datout <= datx1h;
            when 2 => datout <= datx1l;
            when 3 => datout <= daty1h;
            when 4 => datout <= daty1l;
            when 5 => datout <= datx2h;
            when 6 => datout <= datx2l;
            when 7 => datout <= daty2h;
            when 8 => datout <= daty2l;
      end case;
      wMCU <= '0';
      if(datnum = 8) then
            datnum <= 0;
      else
            datnum <= datnum + 1;
      end if;
    else
    wMCU <= '1';
    end if;   
    end if;
    wait on rMCU;
    end process;
end behav;

vipcff 发表于 2010-5-13 16:23:22

mark

jssd 发表于 2010-5-13 17:04:46

回复【1楼】40130064
一个进程只能有一个边沿检测
试试这个,我没在q2上试,也许有错.
begin
    --datstart &lt;= "10101010";--
    process
    begin
    if(rmcu = '0') then
      case(datnum) is
            when 0 =&gt; datout &lt;= datstart;
            when 1 =&gt; datout &lt;= datx1h;
            when 2 =&gt; datout &lt;= datx1l;
            when 3 =&gt; datout &lt;= daty1h;
            when 4 =&gt; datout &lt;= daty1l;
......
-----------------------------------------------------------------------

试过,用户else也不行。一样的错误。
还有我开了两个进程,
architecture behav of MCUtest is
signal datnum: integer range 0 to 8;
signal datstart: std_logic_vector(7 downto 0);
signal datx1h,daty1h,datx2h,daty2h,datx1l,daty1l,datx2l,daty2l: std_logic_vector(7 downto 0);
begin
    datstart <= "10101010";
    process(rMCU)
    begin
    if(rMCU'event and rMCU = '0') then
      case(datnum) is
            when 0 => datout <= datstart;
            when 1 => datout <= datx1h;
            when 2 => datout <= datx1l;
            when 3 => datout <= daty1h;
            when 4 => datout <= daty1l;
            when 5 => datout <= datx2h;
            when 6 => datout <= datx2l;
            when 7 => datout <= daty2h;
            when 8 => datout <= daty2l;
      end case;
      wMCU <= '0';
      if(datnum = 8) then
            datnum <= 0;
      else
            datnum <= datnum + 1;
      end if;
    end if;
    end process;

    process(rMCU)
    begin
      if(rMCU'event and rMCU = '1') then
            wMCU <= '1';
      end if;
    end process;
end behav;
这样会出现另外一个问题。是不能在两个进程对同一个寄存器附值。

最后我只能把wMCU去掉。

jssd 发表于 2010-5-13 17:05:51

如果我想实现这个时序。应该怎么样子写呢?
rMCU: input读
wMCU: output写
datout:数据输出。

rMCU:   ~~~\________/~~~~~~~~\________/~~~~~~~~\__
datout: ~~~\AAAAAAAAAAAAAAAAA\BBBBBBBBBBBBBBBBB\CCCC
wMCU:   ~~~~~\_____/~~~~~~~~~~~\_____/~~~~~~~~~~~\_

40130064 发表于 2010-5-13 17:16:35

你没试 我用的wait on rMCU;rMCU变化进程运行一次只一个敏感信号 不过好像多了个END IF
你要是用这个和MCU通信 方法都不对

jssd 发表于 2010-5-13 17:59:31

begin
        speaker <= '1';
    --datstart <= "10101010";--
    process
    begin
    if(rMCU = '0') then
      case(datnum) is
            when 0 => datout <= datstart;
            when 1 => datout <= datx1h;
            when 2 => datout <= datx1l;
            when 3 => datout <= daty1h;
            when 4 => datout <= daty1l;
            when 5 => datout <= datx2h;
            when 6 => datout <= datx2l;
            when 7 => datout <= daty2h;
            when 8 => datout <= daty2l;
      end case;
      wMCU <= '0';
      if(datnum = 8) then
            datnum <= 0;
      else
            datnum <= datnum + 1;
      end if;
    else
    wMCU <= '1';   
    end if;
    wait on rMCU;
    end process;
end behav;

Error (10533): VHDL Wait Statement error at mouse.vhd(42): Wait Statement must contain condition clause with UNTIL keyword

楼上的大哥,不好意思。刚才看到你的else以为是我测试过的那个。你这个我也测试了。还是不对。你说的方法是哪种?我现在MCU就只有10个IO脚可以用。其他的都被占用了。

jssd 发表于 2010-5-13 18:02:38

还有,你说的变化一次是只从1->0还是从0->1还是从1->0->1呢?

jssd 发表于 2010-5-13 18:13:59

library ieee;
use ieee.std_logic_1164.all;

entity MCUtest is
    port(rMCU: in std_logic;
         wMCU: out std_logic;
         datout: inout std_logic_vector(7 downto 0));
end MCUtest;

architecture behav of MCUtest is
signal flag: std_logic;
signal datnum: integer range 0 to 8;
signal datstart: std_logic_vector(7 downto 0);
begin
    datstart <= "10101010";

    process(rMCU)
    begin
      if(flag = '1') then
            flag <= '0';
            wMCU <= '1';
      else
      if(rMCU'event and rMCU = '0') then
            flag <= '1';
            case(datnum) is
                when 0 => datout <= datstart;
                when 1 => datout <= datx1h;
                when 2 => datout <= datx1l;
                when 3 => datout <= daty1h;
                when 4 => datout <= daty1l;
                when 5 => datout <= datx2h;
                when 6 => datout <= datx2l;
                when 7 => datout <= daty2h;
                when 8 => datout <= daty2l;
            end case;
            wMCU <= '0';
            if(datnum = 8) then
                datnum <= 0;
            else
                datnum <= datnum + 1;
            end if;
      end if;
      end if;
    end process;
end behav;
楼上的大哥,我根据你那个1次进入一次进程写的。这样就能通过了。不过总觉得这样写好样有点。。。。

jssd 发表于 2010-5-13 18:15:07

这里果然不支持TAB键的。。。
页: [1]
查看完整版本: 请教~~~~~~~~~~~~~~~~~~~VHDL同时读取时钟上升沿和下降沿出现的出错问题