搜索
bottom↓
回复: 9

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

[复制链接]

出0入55汤圆

发表于 2010-5-13 14:52:59 | 显示全部楼层 |阅读模式
--我想要实现的功能: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

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 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;

出0入0汤圆

发表于 2010-5-13 16:23:22 | 显示全部楼层
mark

出0入55汤圆

 楼主| 发表于 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去掉。

出0入55汤圆

 楼主| 发表于 2010-5-13 17:05:51 | 显示全部楼层
如果我想实现这个时序。应该怎么样子写呢?
rMCU: input读
wMCU: output写
datout:数据输出。

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

出0入0汤圆

发表于 2010-5-13 17:16:35 | 显示全部楼层
你没试 我用的wait on rMCU;rMCU变化进程运行一次  只一个敏感信号 不过好像多了个END IF
你要是用这个和MCU通信 方法都不对

出0入55汤圆

 楼主| 发表于 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脚可以用。其他的都被占用了。

出0入55汤圆

 楼主| 发表于 2010-5-13 18:02:38 | 显示全部楼层
还有,你说的变化一次是只从1->0还是从0->1还是从1->0->1呢?

出0入55汤圆

 楼主| 发表于 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次进入一次进程写的。这样就能通过了。不过总觉得这样写好样有点。。。。

出0入55汤圆

 楼主| 发表于 2010-5-13 18:15:07 | 显示全部楼层
这里果然不支持TAB键的。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 17:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表