求助: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;
用 51 的 ALE 做一个 EDGE 的输入来控制,简单的说就是放一颗 74373 来做地址解码的处理行不?!
看了下时序图,我总结如下;ALE的下降沿你用来锁存地址,WR的上升沿你读入数据,RD的下降沿你吧给定地址的数据输出
页:
[1]