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
这是什么原因?没搞明白 mcudata是双向总线,在没有输出时要输出'Z' 回复【1楼】liurangzhou
mcudata是双向总线,在没有输出时要输出'Z'
-----------------------------------------------------------------------
行,我加上试试 回复【2楼】liu_jing_yang
-----------------------------------------------------------------------
高手来啊 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锁死. 回复【4楼】qinxg
-----------------------------------------------------------------------
先感谢你的帮助!
wr_en,rd_en是读写使能信号
地址线是10位 因为数据传输的原因,8位不够
我照你写的编了下,正在调试中
感觉逻辑关系比较简单,不知道这么写能实现ARM与FPGA的通信不?我觉得关键是ARM通过地址线读取FPGA内部RAM的数据,为啥实现不了? 回复【3楼】liu_jing_yang
回复【2楼】liu_jing_yang
-----------------------------------------------------------------------
高手来啊
-----------------------------------------------------------------------
行还是不行? 回复【3楼】liu_jing_yang
回复【2楼】liu_jing_yang
-----------------------------------------------------------------------
高手来啊
-----------------------------------------------------------------------
问题解决了没? 回复【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处错误 回复【7楼】liurangzhou
-----------------------------------------------------------------------
编译错误提示:
ERROR: syntax error near when (VHDL-1261)
读数据进程出现的错误提示 回复【4楼】qinxg
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进程出现错误提示,ERROR: syntax error near when (VHDL-1261) 楼主误解了. 不需要进程, 只是简单的并行语句,不需要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 ; 回复【9楼】liu_jing_yang
回复【7楼】liurangzhou
-----------------------------------------------------------------------
编译错误提示:
ERROR: syntax error near when (VHDL-1261)
读数据进程出现的错误提示
-----------------------------------------------------------------------
在进程中条件为时钟边沿的IF里面不能这样写 回复【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的数据? 相当于没有时序了啊 回复【12楼】liurangzhou
回复【9楼】liu_jing_yang
回复【7楼】liurangzhou
-----------------------------------------------------------------------
编译错误提示:
ERROR: syntax error near when (VHDL-1261)
读数据进程出现的错误提示
-----------------------------------------------------------------------
在进程中条件为时钟边沿的IF里面不能这样写
-----------------------------------------------------------------------
恩 写的语句不对,经过调试已经修改正确了~ 首先感谢论坛的朋友qinxg和liurangzhou的热心帮助少后我上传个单片机与FPGA通讯的PDF文件,希望能对研究此类项目的朋友有所帮助,不过我这个通讯问题还没有解决,我也正在努力调试中,同时也希望能得到更多的朋友的帮助! 回复【15楼】liu_jing_yang
首先感谢论坛的朋友qinxg和liurangzhou的热心帮助少后我上传个单片机与FPGA通讯的PDF文件,希望能对研究此类项目的朋友有所帮助,不过我这个通讯问题还没有解决,我也正在努力调试中,同时也希望能得到更多的朋友的帮助!
-----------------------------------------------------------------------
这个问题并不复杂,你可以用内部逻辑分析仪看下问题 回复【楼主位】liu_jing_yang
-----------------------------------------------------------------------
上传个单片机与FPGA通信的PDF资料,有原理和原程序
单片机与FPGA通信的PDF资料,有原理和原程序ourdev_535353.pdf(文件大小:266K) (原文件名:mcu-fpga.pdf) 回复【楼主位】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; 我的语句是可以用的,rd,wr在when的条件语句中用到了,是简单的锁存器逻辑.
你用rd,wr的时钟逻辑也是可以的,不过在FPGA内部要占用GCLK资源, 而且rd,wr最好接在FPGA的全局时钟管脚上. 否则延时不可控. 回复【19楼】qinxg
我的语句是可以用的,rd,wr在when的条件语句中用到了,是简单的锁存器逻辑.
你用rd,wr的时钟逻辑也是可以的,不过在FPGA内部要占用GCLK资源, 而且rd,wr最好接在FPGA的全局时钟管脚上. 否则延时不可控.
-----------------------------------------------------------------------
恩,仔细看看,你的程序确实比较简洁,节省很多资源,目前的情况为编译可以通过,但仿真出现错误,我得再调调 回复【20楼】liu_jing_yang
-----------------------------------------------------------------------
顶起来 初步看了你的代码,你的MCUDATA是双向的,但是虽然你的数据是双向,但是在FPGA内部它是有分的,知道我的意思吗?不能那样赋值 mark 搞定没有啊? 不要瞎搞,先去看看书吧 mark mark lz搞定没 Q俺:609702901 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锁死.
mark{:smile:{:smile:}{:smile:}{:smile:}{:smile:}
页:
[1]