jssd 发表于 2018-8-1 16:11:54

求助:VHDL写的51总线代码,出现输出乱码错误,如何解决

如下图,在网上搞了一个51总线的VHDL代码,稍微改了一下,编译过了。运行可以,可是代码不健壮啊!现在问题如下:
1.如果单片机和CPLD同时上电,则完全没问题,
2.如果单片机分开上电,或者在运行过程中复位单片机,则输出乱码,也就是总线时序乱了,不能自动恢复
自己想的解决办法:
1.在ALE下降沿后置一个标志位,如果读写信号来了发现标志位没置位则忽略,反之则读数据和复位标志位,保证总线时序是先读地址再读数据。

奈何眼高手低,VHDL里不能在两个process里对同一个信号赋值!!!请教大神,这个标志位如何写~~{:3_59:}


代码如下:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity bus_51 is
port(
        P0:                 inout STD_LOGIC_VECTOR(7 downto 0);
        P2:                 in STD_LOGIC_VECTOR(5 downto 0);
        ALE:                 in STD_LOGIC;
        WR,RD:                 in STD_LOGIC;
       
        AUDBY:                 in STD_LOGIC;
        KEY1:                in STD_LOGIC_VECTOR(7 downto 0);
        KEY2:                in STD_LOGIC_VECTOR(7 downto 0);
        S1:                           in STD_LOGIC_VECTOR(4 downto 0);
        S2:                           in STD_LOGIC_VECTOR(4 downto 0);
        H1:                           in STD_LOGIC_VECTOR(3 downto 0);
        H2:                           in STD_LOGIC_VECTOR(3 downto 0);
        COIN1:                 in STD_LOGIC_VECTOR(1 downto 0);
        COIN2:                 in STD_LOGIC_VECTOR(1 downto 0);
        MB_C:                in STD_LOGIC_VECTOR(3 downto 0);
        SW1:                   in STD_LOGIC_VECTOR(7 downto 0);
        LCDBY1:                in STD_LOGIC;
        LCDBY2:                in STD_LOGIC;
        SP485BY1:        in STD_LOGIC;
        SP485BY2:        in STD_LOGIC;
       
        LED0:           out STD_LOGIC_VECTOR(0 downto 0);
        LEDA:           out STD_LOGIC_VECTOR(1 downto 0);
        LEDB:           out STD_LOGIC_VECTOR(1 downto 0);
        LED8:           out STD_LOGIC_VECTOR(7 downto 0);
        LEDY:           out STD_LOGIC_VECTOR(3 downto 0);
        SSR1:           out STD_LOGIC_VECTOR(0 downto 0);
        SSR2:           out STD_LOGIC_VECTOR(0 downto 0);
        SSL1:           out STD_LOGIC_VECTOR(0 downto 0);
        SSL2:           out STD_LOGIC_VECTOR(0 downto 0);
        MB_O:           out STD_LOGIC_VECTOR(3 downto 0);
        ST1032:         out STD_LOGIC_VECTOR(3 downto 0);

        SP485EN1_O:   out STD_LOGIC_VECTOR(0 downto 0);
        SP485EN2_O:   out STD_LOGIC_VECTOR(0 downto 0)

        );
end bus_51;

Architecture C51_FPGA_BUS of bus_51 is
        signal C51_Addr16        :STD_LOGIC_VECTOR(15 downto 0);---16 bit address
        signal WR_EN,RD_EN        :STD_LOGIC;-----WR/RD Enable
       
        ------------------------- INTPUT --------------------------------------------
        signal REG_IN_AUDBY        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_WJA        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_WJB        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_S1           :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_S2           :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_H1           :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_H2           :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_COIN1        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_COIN2        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_MB        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_SW1        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
--        signal REG_IN_SW2        :STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_LCDBY1:STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_LCDBY2:STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_485BY1:STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
        signal REG_IN_485BY2:STD_LOGIC_VECTOR(7 downto 0) := "11111111"; ---internal Register input
       
        --------------------------- INTPUT OUTPUT -----------------------------------
        signal REG_INOUT_LED0        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_LEDA        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_LEDB        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_LED8        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_LEDY        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_SSR1        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_SSR2        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_SSL1        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_SSL2        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_MB                :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_485EN1        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_485EN2        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
--        signal REG_INOUT_Z                :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
--        signal REG_INOUT_M                :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
--        signal REG_INOUT_N                :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
        signal REG_INOUT_1032        :STD_LOGIC_VECTOR(7 downto 0) := "00000000"; ---internal Register input
       
        -------------------------- ADDR INPUT -------------------------------------------
        CONSTANT ADDR_IN_AUDIO        :STD_LOGIC_VECTOR(15 downto 0) := x"8000"; ---internal Register input
        CONSTANT ADDR_IN_WJA        :STD_LOGIC_VECTOR(15 downto 0) := x"8001"; ---internal Register input
        CONSTANT ADDR_IN_WJB        :STD_LOGIC_VECTOR(15 downto 0) := x"8002"; ---internal Register input
        CONSTANT ADDR_IN_S1           :STD_LOGIC_VECTOR(15 downto 0) := x"8003"; ---internal Register input
        CONSTANT ADDR_IN_S2           :STD_LOGIC_VECTOR(15 downto 0) := x"8004"; ---internal Register input
        CONSTANT ADDR_IN_H1           :STD_LOGIC_VECTOR(15 downto 0) := x"8005"; ---internal Register input
        CONSTANT ADDR_IN_H2           :STD_LOGIC_VECTOR(15 downto 0) := x"8006"; ---internal Register input
        CONSTANT ADDR_IN_COIN1        :STD_LOGIC_VECTOR(15 downto 0) := x"8007"; ---internal Register input
        CONSTANT ADDR_IN_COIN2        :STD_LOGIC_VECTOR(15 downto 0) := x"8008"; ---internal Register input
        CONSTANT ADDR_IN_MB                :STD_LOGIC_VECTOR(15 downto 0) := x"8009"; ---internal Register input
        CONSTANT ADDR_IN_SW1        :STD_LOGIC_VECTOR(15 downto 0) := x"800E"; ---internal Register input
        CONSTANT ADDR_IN_SW2        :STD_LOGIC_VECTOR(15 downto 0) := x"800F"; ---internal Register input
        CONSTANT ADDR_IN_LCDBY1        :STD_LOGIC_VECTOR(15 downto 0) := x"8010"; ---internal Register input
        CONSTANT ADDR_IN_LCDBY2        :STD_LOGIC_VECTOR(15 downto 0) := x"8011"; ---internal Register input
        CONSTANT ADDR_IN_485BY1        :STD_LOGIC_VECTOR(15 downto 0) := x"8012"; ---internal Register input
        CONSTANT ADDR_IN_485BY2        :STD_LOGIC_VECTOR(15 downto 0) := x"8013"; ---internal Register input
       
        ---------------------------ADDR INTPUT OUTPUT -----------------------------------
        CONSTANT ADDR_INOUT_LED0        :STD_LOGIC_VECTOR(15 downto 0) := x"8080"; ---internal Register input
        CONSTANT ADDR_INOUT_LEDA        :STD_LOGIC_VECTOR(15 downto 0) := x"8081"; ---internal Register input
        CONSTANT ADDR_INOUT_LEDB        :STD_LOGIC_VECTOR(15 downto 0) := x"8082"; ---internal Register input
        CONSTANT ADDR_INOUT_LED8        :STD_LOGIC_VECTOR(15 downto 0) := x"8083"; ---internal Register input
        CONSTANT ADDR_INOUT_LEDY        :STD_LOGIC_VECTOR(15 downto 0) := x"8084"; ---internal Register input
        CONSTANT ADDR_INOUT_SSR1        :STD_LOGIC_VECTOR(15 downto 0) := x"8085"; ---internal Register input
        CONSTANT ADDR_INOUT_SSR2        :STD_LOGIC_VECTOR(15 downto 0) := x"8086"; ---internal Register input
        CONSTANT ADDR_INOUT_SSL1        :STD_LOGIC_VECTOR(15 downto 0) := x"8087"; ---internal Register input
        CONSTANT ADDR_INOUT_SSL2        :STD_LOGIC_VECTOR(15 downto 0) := x"8088"; ---internal Register input
        CONSTANT ADDR_INOUT_MB                :STD_LOGIC_VECTOR(15 downto 0) := x"8089"; ---internal Register input
        CONSTANT ADDR_INOUT_485EN1        :STD_LOGIC_VECTOR(15 downto 0) := x"808A"; ---internal Register input
        CONSTANT ADDR_INOUT_485EN2        :STD_LOGIC_VECTOR(15 downto 0) := x"808B"; ---internal Register input
--        CONSTANT ADDR_INOUT_Z                :STD_LOGIC_VECTOR(15 downto 0) := x"808C"; ---internal Register input
--        CONSTANT ADDR_INOUT_M                :STD_LOGIC_VECTOR(15 downto 0) := x"808D"; ---internal Register input
--        CONSTANT ADDR_INOUT_N                :STD_LOGIC_VECTOR(15 downto 0) := x"808E"; ---internal Register input
        CONSTANT ADDR_INOUT_1032        :STD_LOGIC_VECTOR(15 downto 0) := x"808F"; ---internal Register input


Begin
       
        Address_p:process(ALE)----AddressLatch
        begin
                if ALE'event and ALE = '0' and ALE'LAST_VALUE='1' then
                        C51_Addr16 <= P2(5 downto 5)&"00"&P2(4 downto 0)&P0;
                end if;
        end process;
       
        REG_IN_AUDBY(7 downto 0) <= "1111111" & AUDBY;
        REG_IN_WJA(7 downto 0) <= KEY1(7 downto 0);
        REG_IN_WJB(7 downto 0) <= KEY2(7 downto 0);
        REG_IN_S1(4 downto 0) <= S1(4 downto 0);
        REG_IN_S2(4 downto 0) <= S2(4 downto 0);
        REG_IN_H1(3 downto 0) <= H1(3 downto 0);
        REG_IN_H2(3 downto 0) <= H2(3 downto 0);
        REG_IN_COIN1(1 downto 0) <= COIN1(1 downto 0);
        REG_IN_COIN2(1 downto 0) <= COIN2(1 downto 0);
        REG_IN_MB(3 downto 0) <= MB_C(3 downto 0);
        REG_IN_SW1(7 downto 0) <= SW1(7 downto 0);
        REG_IN_LCDBY1(7 downto 0) <= "1111111" & LCDBY1;
        REG_IN_LCDBY2(7 downto 0) <= "1111111" & LCDBY2;
        REG_IN_485BY1(7 downto 0) <= "1111111" & SP485BY1;
        REG_IN_485BY2(7 downto 0) <= "1111111" & SP485BY2;
       
        WR_EN <= (WR AND RD) OR WR;-----WR Enable
        RD_EN <= (WR AND RD) OR RD;-----RD Enable
       
        -----Read FPGA internal Register-----------
        P0<=REG_IN_AUDBY(7 downto 0) when C51_Addr16 = ADDR_IN_AUDIO and RD_EN='0' else
                REG_IN_WJA(7 downto 0) when C51_Addr16 = ADDR_IN_WJA and RD_EN='0' else
                REG_IN_WJB(7 downto 0) when C51_Addr16 = ADDR_IN_WJB and RD_EN='0' else
                REG_IN_S1(7 downto 0) when C51_Addr16 = ADDR_IN_S1 and RD_EN='0' else
                REG_IN_S2(7 downto 0) when C51_Addr16 = ADDR_IN_S2 and RD_EN='0' else
                REG_IN_H1(7 downto 0) when C51_Addr16 = ADDR_IN_H1 and RD_EN='0' else
                REG_IN_H2(7 downto 0) when C51_Addr16 = ADDR_IN_H2 and RD_EN='0' else
                REG_IN_COIN1(7 downto 0) when C51_Addr16 = ADDR_IN_COIN1 and RD_EN='0' else
                REG_IN_COIN2(7 downto 0) when C51_Addr16 = ADDR_IN_COIN2 and RD_EN='0' else
                REG_IN_MB(7 downto 0) when C51_Addr16 = ADDR_IN_MB and RD_EN='0' else
                REG_IN_SW1(7 downto 0) when C51_Addr16 = ADDR_IN_SW1 and RD_EN='0' else
--                REG_IN_SW2(7 downto 0) when C51_Addr16 = ADDR_IN_SW2 and RD_EN='0' else
                REG_IN_LCDBY1(7 downto 0) when C51_Addr16 = ADDR_IN_LCDBY1 and RD_EN='0' else
                REG_IN_LCDBY2(7 downto 0) when C51_Addr16 = ADDR_IN_LCDBY2 and RD_EN='0' else
                REG_IN_485BY1(7 downto 0) when C51_Addr16 = ADDR_IN_485BY1 and RD_EN='0' else
                REG_IN_485BY2(7 downto 0) when C51_Addr16 = ADDR_IN_485BY2 and RD_EN='0' else
               
                REG_INOUT_LED0(7 downto 0) when C51_Addr16 = ADDR_INOUT_LED0 and RD_EN='0' else
                REG_INOUT_LEDA(7 downto 0) when C51_Addr16 = ADDR_INOUT_LEDA and RD_EN='0' else
                REG_INOUT_LEDB(7 downto 0) when C51_Addr16 = ADDR_INOUT_LEDB and RD_EN='0' else
                REG_INOUT_LED8(7 downto 0) when C51_Addr16 = ADDR_INOUT_LED8 and RD_EN='0' else
                REG_INOUT_LEDY(7 downto 0) when C51_Addr16 = ADDR_INOUT_LEDY and RD_EN='0' else
                REG_INOUT_SSR1(7 downto 0) when C51_Addr16 = ADDR_INOUT_SSR1 and RD_EN='0' else
                REG_INOUT_SSR2(7 downto 0) when C51_Addr16 = ADDR_INOUT_SSR2 and RD_EN='0' else
                REG_INOUT_SSL1(7 downto 0) when C51_Addr16 = ADDR_INOUT_SSL1 and RD_EN='0' else
                REG_INOUT_SSL2(7 downto 0) when C51_Addr16 = ADDR_INOUT_SSL2 and RD_EN='0' else
                REG_INOUT_MB(7 downto 0) when C51_Addr16 = ADDR_INOUT_MB and RD_EN='0' else
                REG_INOUT_485EN1(7 downto 0) when C51_Addr16 = ADDR_INOUT_485EN1 and RD_EN='0' else
                REG_INOUT_485EN2(7 downto 0) when C51_Addr16 = ADDR_INOUT_485EN2 and RD_EN='0' else
--                REG_INOUT_Z(7 downto 0) when C51_Addr16 = ADDR_INOUT_Z and RD_EN='0' else
--                REG_INOUT_M(7 downto 0) when C51_Addr16 = ADDR_INOUT_M and RD_EN='0' else
--                REG_INOUT_N(7 downto 0) when C51_Addr16 = ADDR_INOUT_N and RD_EN='0' else
                REG_INOUT_1032(7 downto 0) when C51_Addr16 = ADDR_INOUT_1032 and RD_EN='0' else
                "ZZZZZZZZ";

       
        C51_Write_FPGA: process(WR_EN)----Write FPGA interal Register
        begin
                if WR'EVENT and WR'LAST_VALUE='1' and WR_EN='0' then                
                        case C51_Addr16 is
                                when ADDR_INOUT_LED0=>REG_INOUT_LED0(7 downto 0)<=P0;
                                when ADDR_INOUT_LEDA=>REG_INOUT_LEDA(7 downto 0)<=P0;
                                when ADDR_INOUT_LEDB=>REG_INOUT_LEDB(7 downto 0)<=P0;
                                when ADDR_INOUT_LED8=>REG_INOUT_LED8(7 downto 0)<=P0;
                                when ADDR_INOUT_LEDY=>REG_INOUT_LEDY(7 downto 0)<=P0;
                                when ADDR_INOUT_SSR1=>REG_INOUT_SSR1(7 downto 0)<=P0;
                                when ADDR_INOUT_SSR2=>REG_INOUT_SSR2(7 downto 0)<=P0;
                                when ADDR_INOUT_SSL1=>REG_INOUT_SSL1(7 downto 0)<=P0;
                                when ADDR_INOUT_SSL2=>REG_INOUT_SSL2(7 downto 0)<=P0;
                                when ADDR_INOUT_MB=>REG_INOUT_MB(7 downto 0)<=P0;
                                when ADDR_INOUT_485EN1=>REG_INOUT_485EN1(7 downto 0)<=P0;
                                when ADDR_INOUT_485EN2=>REG_INOUT_485EN2(7 downto 0)<=P0;
--                                when ADDR_INOUT_Z=>REG_INOUT_Z(7 downto 0)<=P0;
--                                when ADDR_INOUT_M=>REG_INOUT_M(7 downto 0)<=P0;
--                                when ADDR_INOUT_N=>REG_INOUT_N(7 downto 0)<=P0;
                                when ADDR_INOUT_1032=>REG_INOUT_1032(7 downto 0)<=P0;
                                when OTHERS=>NULL;
                        end case;
                end if;
        end process;
       
        LED0(0 downto 0) <= REG_INOUT_LED0(0 downto 0);
        LEDA(1 downto 0) <= REG_INOUT_LEDA(1 downto 0);
        LEDB(1 downto 0) <= REG_INOUT_LEDB(1 downto 0);
        LED8(7 downto 0) <= REG_INOUT_LED8(7 downto 0);
        LEDY(3 downto 0) <= REG_INOUT_LEDY(3 downto 0);
        SSR1 <= REG_INOUT_SSR1(0 downto 0);
        SSR2 <= REG_INOUT_SSR2(0 downto 0);
        SSL1 <= REG_INOUT_SSL1(0 downto 0);
        SSL2 <= REG_INOUT_SSL2(0 downto 0);
        MB_O(3 downto 0) <= REG_INOUT_MB(3 downto 0);
--        MZ(1 downto 0) <= REG_INOUT_Z(1 downto 0);
--        MM(1 downto 0) <= REG_INOUT_M(1 downto 0);
--        ST6600(2 downto 0) <= REG_INOUT_N(2 downto 0);
        ST1032(3 downto 0) <= REG_INOUT_1032(3 downto 0);

        SP485EN1_O(0 downto 0) <= REG_INOUT_485EN1(0 downto 0);
        SP485EN2_O(0 downto 0) <= REG_INOUT_485EN2(0 downto 0);
       
END C51_FPGA_BUS;

xyz543 发表于 2018-8-2 11:34:25

用 51 的 ALE 做一个 EDGE 的输入来控制,简单的说就是放一颗 74373 来做地址解码的处理行不?!

NJ8888 发表于 2018-8-11 20:36:22

看了下时序图,我总结如下;ALE的下降沿你用来锁存地址,WR的上升沿你读入数据,RD的下降沿你吧给定地址的数据输出
页: [1]
查看完整版本: 求助:VHDL写的51总线代码,出现输出乱码错误,如何解决