liu_jing_yang 发表于 2010-2-24 10:20:55

ARM与FPGA之间的数据传输(出现问题,请高手帮忙,附源程序)

ARM与FPGA之间的数据传输:
ARM(主)负责分析处理数据,FPGA(从)负责收集存储数据,两者之间通过地址/数据总线方式通信(不复用),下面是我编写的通信程序。ARM通过FPGA的内部RAM对数据进行读写处理。开发软件libero,在仿真中数据读写都正确,写到板子上功能就不对了,大家给分析下我写的程序是否有问题,谢谢!
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
----FPGA内部寄存器地址定义:
packageinterface is
constant addr_reg1 : std_logic_vector(9 downto 0) := "0000000000";
constant addr_reg2 : std_logic_vector(9 downto 0) := "0000000001";
constant addr_reg3 : std_logic_vector(9 downto 0) := "0000000010";
constant addr_reg4 : std_logic_vector(9 downto 0) := "0000000011";
end;


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

entity arm_fpga is
port(
mcudata : inout std_logic_vector(7 downto 0);--8位数据
mcuaddress : in std_logic_vector(9 downto 0);--10位地址
wr : in std_logic;--写信号
rd : in std_logic;
cs : in std_logic;
led : out std_logic_vector(7 downto 0));
end;

architecturearmfpga of arm_fpga is
signaladdresstemp : std_logic_vector(9 downto 0);--内部寄存器
signaldatatemp1, datatemp2, datatemp3, datatemp4 : std_logic_vector(7 downto 0);
signalwr_en,rd_en : std_logic;--读写使能

begin
addresstemp <= mcuaddress;
wr_en <= (wr and rd) or wr;
rd_en <= (wr and rd) or rd;
--ARM写数据到FPGA:
process(wr,wr_en)
begin
ifwr'event and wr = '0' then
if cs = '0'andwr_en = '0' then
case addresstemp is
when addr_reg1 =>
datatemp1 <= mcudata;

when addr_reg2 =>
datatemp2 <= mcudata;

when addr_reg3 =>
datatemp3 <= mcudata;

when addr_reg4 =>
datatemp4 <= mcudata;

when others => null;
end case;
end if;
end if;
end process;
--ARM从FPGA读取数据:
process(rd,rd_en)
begin
ifrd'event and rd = '0'then
if cs = '0' and rd_en = '0' then
case addresstemp is
when addr_reg1 =>
mcudata <= datatemp1;

when addr_reg2 =>
mcudata <= datatemp2;

when addr_reg3 =>
mcudata <= datatemp3;

when addr_reg4 =>
mcudata <= datatemp4;

when others => null;
end case;
end if;
end if;
end process;

led <= mcudata; --验证传输数据,LED显示
end;


还有一个问题,我在综合的时候出现了一个警告:
Failed to find top level module 'work.arm_fpga' as specified in project file
这是什么原因?没搞明白

liurangzhou 发表于 2010-2-24 12:26:31

mcudata是双向总线,在没有输出时要输出'Z'

liu_jing_yang 发表于 2010-2-24 13:05:38

回复【1楼】liurangzhou
mcudata是双向总线,在没有输出时要输出'Z'
-----------------------------------------------------------------------

行,我加上试试

liu_jing_yang 发表于 2010-2-24 13:55:01

回复【2楼】liu_jing_yang
-----------------------------------------------------------------------
高手来啊

qinxg 发表于 2010-2-24 14:08:19

wr_en <= (wr and rd) or wr;
rd_en <= (wr and rd) or rd;    ?? 这个是什么逻辑,不明白.

其实用简单的锁存就可以了, 代码总共10行. 而且地址用低2位就可以了
写:
datatemp1 <= mcudata when( cs='0' and wr='0' and addresstemp = "00");
datatemp2 <= mcudata when( cs='0' and wr='0' and addresstemp = "01");
.....

读:
mcudata <= datatemp1 when( cs='0 and rd='0' and addresstemp = "00") else
         datatemp2 when( cs='0 and rd='0' and addresstemp = "01") else
         ................
         "ZZZZZZZZ";      -- "ZZ"不可少,否则总线被FPGA锁死.

liu_jing_yang 发表于 2010-2-24 15:10:57

回复【4楼】qinxg
-----------------------------------------------------------------------
先感谢你的帮助!
wr_en,rd_en是读写使能信号
地址线是10位 因为数据传输的原因,8位不够
我照你写的编了下,正在调试中
感觉逻辑关系比较简单,不知道这么写能实现ARM与FPGA的通信不?我觉得关键是ARM通过地址线读取FPGA内部RAM的数据,为啥实现不了?

liurangzhou 发表于 2010-2-24 15:48:00

回复【3楼】liu_jing_yang
回复【2楼】liu_jing_yang
-----------------------------------------------------------------------
高手来啊
-----------------------------------------------------------------------

行还是不行?

liurangzhou 发表于 2010-2-24 17:45:09

回复【3楼】liu_jing_yang
回复【2楼】liu_jing_yang
-----------------------------------------------------------------------
高手来啊
-----------------------------------------------------------------------

问题解决了没?

liu_jing_yang 发表于 2010-2-25 14:24:28

回复【7楼】liurangzhou
-----------------------------------------------------------------------

-- mcufpga.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
----FPGA内部寄存器地址定义:
packageinterface is
constant addr_reg1 : std_logic_vector(9 downto 0) := "0000000000";
constant addr_reg2 : std_logic_vector(9 downto 0) := "0000000001";
constant addr_reg3 : std_logic_vector(9 downto 0) := "0000000010";
constant addr_reg4 : std_logic_vector(9 downto 0) := "0000000011";
end;

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

entity arm_fpga is
port(
mcudata : inout std_logic_vector(7 downto 0);--8位数据
mcuaddress : in std_logic_vector(9 downto 0);--10位地址
wr : in std_logic;--写信号
rd : in std_logic;
cs : in std_logic;
led : out std_logic_vector(7 downto 0));
end;

architecturearmfpga of arm_fpga is
signaladdresstemp : std_logic_vector(9 downto 0);--内部寄存器
signaldatatemp : std_logic_vector(31 downto 0);
--signalwr_en,rd_en : std_logic;--读写使能

begin
addresstemp <= mcuaddress;

--ARM写数据到FPGA:
process(wr,cs)
begin

--datatemp1 <= mcudatawhen(cs= '0' and wr = '0' and addresstemp = addr_reg1);
if wr'event and wr = '0' and cs = '0' then
case addresstemp is
when addr_reg1 => datatemp(7 downto 0) <= mcudata;
when addr_reg2 => datatemp(15 downto 8) <= mcudata;
when addr_reg3 => datatemp(23 downto 16) <= mcudata;
when addr_reg4 => datatemp(31 downto 24) <= mcudata;
when others => null;
end case;
end if;
end process;

--ARM从FPGA读取数据:
process(rd,cs)
begin

if rd'event and rd = '0' and cs = '0' then
--case addresstemp is
--when addr_reg1 => mcudata <= datatemp(7 downto 0);
--when addr_reg2 => mcudata <= datatemp(15 downto 8);
--when addr_reg3 => mcudata <= datatemp(23 downto 16);
--when addr_reg4 => mcudata <= datatemp(31 downto 24);
--when others => mcudata <= "ZZZZZZZZ";
mcudata <=
datatemp(7 downto 0) when (addresstemp = addr_reg1) else
datatemp(15 downto 8) when (addresstemp = addr_reg2) else
datatemp(23 downto 16) when (addresstemp = addr_reg3) else
datatemp(31 downto 24) when (addresstemp = addr_reg4) else
"ZZZZZZZZ";
end case;
end if;
end process;
led <= mcudata;
end;

哥们 你在 软件上编译一下,我这里怎么就是不对啊?读数据进程
老是提示WHEN处错误

liu_jing_yang 发表于 2010-2-25 14:25:27

回复【7楼】liurangzhou
-----------------------------------------------------------------------

编译错误提示:
ERROR: syntax error near when (VHDL-1261)
读数据进程出现的错误提示

liu_jing_yang 发表于 2010-2-25 14:26:32

回复【4楼】qinxg
wr_en &lt;= (wr and rd) or wr;
rd_en &lt;= (wr and rd) or rd;    ?? 这个是什么逻辑,不明白.
其实用简单的锁存就可以了, 代码总共10行. 而且地址用低2位就可以了
写:
datatemp1 &lt;= mcudata when( cs='0' and wr='0' and addresstemp = "00");
datatemp2 &lt;= mcudata when( cs='0' and wr='0' and addresstemp = "01");
.....
读:
mcudata &lt;= datatemp1 when( cs='0 and rd='0' and addresstemp = "00") else
         datatemp2 when( cs='0 and ......
-----------------------------------------------------------------------

哥们 我照你说的编译了一下,结果没通过编译,RD进程出现错误提示,ERROR: syntax error near when (VHDL-1261)

qinxg 发表于 2010-2-25 14:48:57

楼主误解了. 不需要进程, 只是简单的并行语句,不需要rd,wr的时钟逻辑.


-----------------------------------------------------------------------

-- mcufpga.vhd

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

entity arm_fpga is
port(
mcudata : inout std_logic_vector(7 downto 0);--8位数据
mcuaddress : in std_logic_vector(9 downto 0);--10位地址
wr : in std_logic;--写信号
rd : in std_logic;
cs : in std_logic;
led : out std_logic_vector(7 downto 0));
end;

architecturearmfpga of arm_fpga is
signaladdresstemp : std_logic_vector(1 downto 0);--内部寄存器
signaldatatemp : std_logic_vector(31 downto 0);

begin
addresstemp <= mcuaddress(1 downto 0);

--ARM写数据到FPGA:
datatemp(7 downto 0) <= mcudata when( cs='0' and wr='0' and addresstemp = "00");
datatemp(15 downto 8)<= mcudata when( cs='0' and wr='0' and addresstemp = "01");
datatemp(23 downto 16)<= mcudata when( cs='0' and wr='0' and addresstemp = "10");
datatemp(31 downto 24)<= mcudata when( cs='0' and wr='0' and addresstemp = "11");


--ARM从FPGA读取数据:
mcudata <= datatemp(7 downto 0) when( cs='0 and rd='0' and addresstemp = "00") else
         datatemp(15 downto 8) when( cs='0 and rd='0' and addresstemp = "01") else
         datatemp(23 downto 16) when( cs='0 and rd='0' and addresstemp = "10") else
         datatemp(31 downto 24) when( cs='0 and rd='0' and addresstemp = "11") else
         "ZZZZZZZZ";      -- "ZZ"不可少,否则总线被FPGA锁死.

led <= mcudata;

end armfpga ;

liurangzhou 发表于 2010-2-25 16:09:48

回复【9楼】liu_jing_yang
回复【7楼】liurangzhou
-----------------------------------------------------------------------
编译错误提示:
ERROR: syntax error near when (VHDL-1261)
读数据进程出现的错误提示
-----------------------------------------------------------------------

在进程中条件为时钟边沿的IF里面不能这样写

liu_jing_yang 发表于 2010-2-25 16:31:36

回复【11楼】qinxg
-----------------------------------------------------------------------

回复【11楼】qinxg
楼主误解了. 不需要进程, 只是简单的并行语句,不需要rd,wr的时钟逻辑.
-----------------------------------------------------------------------
-- mcufpga.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity arm_fpga is
port(
mcudata : inout std_logic_vector(7 downto 0);--8位数据
mcuaddress : in std_logic_vector(9 downto 0);--10位地址
wr : in std_logic......
-----------------------------------------------------------------------

哥们 ,能这么写吗?我调调试试把,怎么感觉好象优点问题啊,没有了WRRD 信号指令,单片机怎么读写FPGA内部RAM的数据? 相当于没有时序了啊

liu_jing_yang 发表于 2010-2-25 16:32:52

回复【12楼】liurangzhou
回复【9楼】liu_jing_yang
回复【7楼】liurangzhou   
-----------------------------------------------------------------------
编译错误提示:
ERROR: syntax error near when (VHDL-1261)
读数据进程出现的错误提示
-----------------------------------------------------------------------
在进程中条件为时钟边沿的IF里面不能这样写
-----------------------------------------------------------------------

恩 写的语句不对,经过调试已经修改正确了~

liu_jing_yang 发表于 2010-2-25 16:38:35

首先感谢论坛的朋友qinxg和liurangzhou的热心帮助少后我上传个单片机与FPGA通讯的PDF文件,希望能对研究此类项目的朋友有所帮助,不过我这个通讯问题还没有解决,我也正在努力调试中,同时也希望能得到更多的朋友的帮助!

liurangzhou 发表于 2010-2-25 21:07:14

回复【15楼】liu_jing_yang
首先感谢论坛的朋友qinxg和liurangzhou的热心帮助少后我上传个单片机与FPGA通讯的PDF文件,希望能对研究此类项目的朋友有所帮助,不过我这个通讯问题还没有解决,我也正在努力调试中,同时也希望能得到更多的朋友的帮助!
-----------------------------------------------------------------------

这个问题并不复杂,你可以用内部逻辑分析仪看下问题

liu_jing_yang 发表于 2010-2-26 07:53:51

回复【楼主位】liu_jing_yang
-----------------------------------------------------------------------

上传个单片机与FPGA通信的PDF资料,有原理和原程序
单片机与FPGA通信的PDF资料,有原理和原程序ourdev_535353.pdf(文件大小:266K) (原文件名:mcu-fpga.pdf)

liu_jing_yang 发表于 2010-2-26 07:56:44

回复【楼主位】liu_jing_yang
-----------------------------------------------------------------------

问题目前得到初步解决,程序见下面,目前来说这个程序下到板子上可以实现ARM与FPGA的读写操作,还需要进一步调试,有可能还会出现问题,程序如下,大家可以和第一帖的程序坐下对比:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity arm_fpga is
port(
mcudata : inout std_logic_vector(7 downto 0);--8位数据
mcuaddress : in std_logic_vector(9 downto 0);--10位地址
wr : in std_logic;--写信号
rd : in std_logic;
cs : in std_logic;
led : out std_logic_vector(7 downto 0));
end;

architecturearmfpga of arm_fpga is
constant addr_reg1 : std_logic_vector(9 downto 0) := "0000000000";
constant addr_reg2 : std_logic_vector(9 downto 0) := "0000000001";
constant addr_reg3 : std_logic_vector(9 downto 0) := "0000000010";
constant addr_reg4 : std_logic_vector(9 downto 0) := "0000000011";

signaladdresstemp : std_logic_vector(9 downto 0);--内部寄存器
signaldatatemp : std_logic_vector(31 downto 0);
--signalwr_en,rd_en : std_logic;--读写使能

begin
addresstemp <= mcuaddress;

--ARM写数据到FPGA:
process(wr,cs)
begin

if( wr'event and wr = '0' )then
if( cs = '0') then
case addresstemp is
when addr_reg1 => datatemp(7 downto 0) <= mcudata;
when addr_reg2 => datatemp(15 downto 8) <= mcudata;
when addr_reg3 => datatemp(23 downto 16) <= mcudata;
when addr_reg4 => datatemp(31 downto 24) <= mcudata;
when others =>
datatemp<=(others=>'0');
end case;
else
datatemp<=(others=>'0');
end if;
end if;
end process;

--ARM从FPGA读取数据:
process(rd,cs)
begin

if (rd'event and rd = '0' ) then
if (cs = '0')then
case addresstemp is
when addr_reg1 => mcudata<=datatemp(7 downto 0);
when addr_reg2 => mcudata<=datatemp(15 downto 8);
when addr_reg3 => mcudata<=datatemp(23 downto 16);
when addr_reg4 => mcudata<=datatemp(31 downto 24);
when others=>mcudata<="ZZZZZZZZ";
end case;
else
mcudata<="ZZZZZZZZ";
end if;
end if;
end process;
led <= mcudata;
end;

qinxg 发表于 2010-2-26 09:11:38

我的语句是可以用的,rd,wr在when的条件语句中用到了,是简单的锁存器逻辑.
你用rd,wr的时钟逻辑也是可以的,不过在FPGA内部要占用GCLK资源, 而且rd,wr最好接在FPGA的全局时钟管脚上. 否则延时不可控.

liu_jing_yang 发表于 2010-2-27 08:06:27

回复【19楼】qinxg
我的语句是可以用的,rd,wr在when的条件语句中用到了,是简单的锁存器逻辑.
你用rd,wr的时钟逻辑也是可以的,不过在FPGA内部要占用GCLK资源, 而且rd,wr最好接在FPGA的全局时钟管脚上. 否则延时不可控.

-----------------------------------------------------------------------

恩,仔细看看,你的程序确实比较简洁,节省很多资源,目前的情况为编译可以通过,但仿真出现错误,我得再调调

liu_jing_yang 发表于 2010-4-9 08:33:12

回复【20楼】liu_jing_yang
-----------------------------------------------------------------------

顶起来

SZSBS 发表于 2010-4-13 17:15:57

初步看了你的代码,你的MCUDATA是双向的,但是虽然你的数据是双向,但是在FPGA内部它是有分的,知道我的意思吗?不能那样赋值

jordonwu 发表于 2010-9-8 09:21:03

mark

281229961 发表于 2010-9-8 09:28:16

搞定没有啊?

wanmyqawdr 发表于 2010-9-8 10:26:50

不要瞎搞,先去看看书吧

popoochen 发表于 2011-7-29 22:52:54

mark

jjjcmxz 发表于 2011-7-30 16:36:53

mark lz搞定没

SZSBS 发表于 2011-8-1 13:55:28

Q俺:609702901

lkl10800139 发表于 2012-5-6 03:46:34

12楼有点小错误:漏了一个'
--ARM从FPGA读取数据:
mcudata <= datatemp(7 downto 0) when( cs='0 and rd='0' and addresstemp = "00") else
                  datatemp(15 downto 8) when( cs='0 and rd='0' and addresstemp = "01") else
                  datatemp(23 downto 16) when( cs='0 and rd='0' and addresstemp = "10") else
                  datatemp(31 downto 24) when( cs='0 and rd='0' and addresstemp = "11") else
                  "ZZZZZZZZ";      -- "ZZ"不可少,否则总线被FPGA锁死.
加上:
--ARM从FPGA读取数据:
mcudata <= datatemp(7 downto 0) when( cs='0' and rd='0' and addresstemp = "00") else
                  datatemp(15 downto 8) when( cs='0' and rd='0' and addresstemp = "01") else
                  datatemp(23 downto 16) when( cs='0' and rd='0' and addresstemp = "10") else
                  datatemp(31 downto 24) when( cs='0' and rd='0' and addresstemp = "11") else
                  "ZZZZZZZZ";      -- "ZZ"不可少,否则总线被FPGA锁死.

越事故乡名 发表于 2015-10-26 22:15:39

mark{:smile:{:smile:}{:smile:}{:smile:}{:smile:}
页: [1]
查看完整版本: ARM与FPGA之间的数据传输(出现问题,请高手帮忙,附源程序)