dzf2222 发表于 2010-1-14 10:32:39

单片机读写FPGA内部构建的双口RAM问题

请教:单片机读写FPGA内部构建的双口RAM
单片机通过P0,ALE,RD,WR与FPGA连接(总线连接方式),我的具体做法是在FPGA内开辟n(0~255)个寄存器,用其中一个寄存器端口映射双口RAM的Qout,在读写操作时单个地址没有问题,单当对RAM地址累计、写入或读出多个字节时出现问题。
请教有没人做过类似的项目,请赐教。谢谢!!

dzf2222 发表于 2010-1-14 10:37:12

我的VHDL语句如下:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity Registers is
port(
   CSFPGA      :instd_logic;
   Reset_N   :instd_logic;                        
   Clk50M      :instd_logic;                                          
   ALE         :instd_logic;                        
   RD          :instd_logic;                              
   WR          :instd_logic;                           
   DataToMCU   :out std_logic_vector(7 downto 0);      
   DataFromMCU : instd_logic_vector(7 downto 0);                                                                  
   MemRdClk    : out std_logic;
   ErrData_R   : instd_logic_vector(7 downto 0);   --记录的出错点相对位置信息
   ErrData_G   : instd_logic_vector(7 downto 0);   --记录的出错点相对位置信息
   ErrData_B   : instd_logic_vector(7 downto 0);   --记录的出错点相对位置信息                                 
   --RdReq       : out std_logic;                         --读记录出错点位置信息RAM请求,实际未使用                                 
   RdAddr      : out std_logic_vector(10 downto 0);   --读地址                                                   
   ED_StartOut : out std_logic;                         --从MCU来的检测命令
   ED_ModeEn   : instd_logic:='0';                  --‘1’ 检测模式                                       
   ED_ACK      : instd_logic;                         --握手确认FSM已经收到检测命令                              
   PixelCnt    : out std_logic_vector(9 downto 0)       --需要检测的段数量                                          
);
end Registers;

architecture syn of Registers is
signal ALE_int : std_logic;
signal RD_int: std_logic;
signal WR_int: std_logic;
signal CSFPGA_int: std_logic;
--signal CMDREG: std_logic_vector(7 downto 0);
--signal ED_STATE: std_logic_vector(7 downto 0);
signal CONREG_R: std_logic_vector(7 downto 0);
signal CONREG_G: std_logic_vector(7 downto 0);
signal CONREG_B: std_logic_vector(7 downto 0);
signal ADDRESSREG : std_logic_vector(7 downto 0);
signal LocSetting : std_logic:='0';
signal ED_Start: std_logic:='0';
signal ED_ModeEn_int:std_logic;   
signal PixelCnt_int: std_logic_vector(9 downto 0);
signal RdAddress_int : std_logic_vector(10 downto 0);

--signal CS    : std_logic;
begin
ED_StartOut<=ED_Start;
PixelCnt<=PixelCnt_int;
ED_ModeEn_int<=ED_ModeEn;
ALE_int<=ALE;
RD_int <=RD;
WR_int <=WR;
CSFPGA_int <= CSFPGA;
--****************************************

    ADDRESS: process(ALE_int)
    begin
      if (ALE_int'EVENT AND ALE_int = '0') then
         ADDRESSREG<=DataFromMCU;
      end if;
    end process;
    WRDATA: process(WR_int)
    begin
      IF(WR_int'EVENT AND WR_int='0') then
          CASE ADDRESSREG IS               --ADDRESS INPUT
            WHEN "00000001" =>
                  IF(DataFromMCU=X"ED") THEN
                     ED_Start<='1';
                  END IF;
            WHEN "00000111" =>
                  IF(DataFromMCU=X"00") THEN
                     ED_Start<='0';
                  END IF;            
            WHEN "11111111" =>
                  IF(LocSetting='0') THEN
                     PixelCnt_int(7 downto 0)<=DataFromMCU;
                     LocSetting<='1';
                  ELSE
                     PixelCnt_int(9 downto 8)<=DataFromMCU(1 downto 0);
                     LocSetting<='0';
                  END IF;   
            WHEN OTHERS =>
                  NULL;
          END CASE;      
      END IF;
   END PROCESS WRDATA;         
--****************************************
MemRdClk <=Clk50M;
RdAddr   <=RdAddress_int;               
    RDDATA:process(RD_int,Clk50M,ADDRESSREG)
   begin
      if (RD_int='1') then
          RdAddress_int<="00000000000";
      elsif rising_edge(Clk50M) then
      
         IF (ADDRESSREG="00000010" ) THEN
               DataToMCU<=ErrData_R;
             IF (RdAddress_int(9 downto 0)=PixelCnt_int ) THEN
               RdAddress_int(10 downto 0)<=(others=>'0');
             ELSE
                  RdAddress_int<=RdAddress_int+1;
             END IF;
            
            
         END IF;
                  
                  --NULL;
         --END CASE;
       END IF;
      --END IF;
   END process RDDATA;   
--*******************************************************************************--   
end syn;

dzf2222 发表于 2010-1-14 10:41:41

RDDATA:process(RD_int,Clk50M,ADDRESSREG)
   begin
      if (RD_int='1') then
          RdAddress_int<="00000000000";
      elsif rising_edge(Clk50M) then
         
         IF (ADDRESSREG="00000010" ) THEN
               DataToMCU<=ErrData_R;
             IF (RdAddress_int(9 downto 0)=PixelCnt_int ) THEN
               RdAddress_int(10 downto 0)<=(others=>'0');
             ELSE
                  RdAddress_int<=RdAddress_int+1;
             END IF;
            
               
         END IF;
                  
                  --NULL;
         --END CASE;
       END IF;
      --END IF;
   END process RDDATA;   
在这个语句中我用逻辑仪看了下RdAddress_int地址累加不到PixelCnt_int设定的地址。
单片机的程序为:
/*********************MCU Read FPGA Registers*************************/
unsigned char RFPGA(unsigned char nPort)
{
unsigned char nVal;
unsigned char xdata *exAddress;
exAddress=0xff00+nPort;

nVal = *exAddress;

   return nVal;

}
/*********************MCU Write FPGA Registers*************************/
void WFPGA(unsigned char nPort, unsigned char nVal)
{
unsigned char xdata *exAddress;
exAddress=0xff00+nPort;
*exAddress = nVal;

}
/*********************LocSetting**************************************/
void LocSetting(void)
{
RegData=(char)PixelCnt;
WFPGA(0xff,RegData);

RegData=(char)(PixelCnt>>8);
WFPGA(0xff,RegData);

}
.
.
.

dzf2222 发表于 2010-1-14 10:45:40

怎么没有人赐教啊!!!

wang110 发表于 2010-1-14 21:46:31

WRDATA: process(WR_int)
    begin
      IF(WR_int'EVENT AND WR_int='0') then
如果单片机的写信号是低电平有效的话,上句 是否应改为IF(WR_int'EVENT AND WR_int='1') then

NJ8888 发表于 2010-1-14 22:06:44

没看清,删了,
页: [1]
查看完整版本: 单片机读写FPGA内部构建的双口RAM问题