高手们看下我这段VHDL程序哪里还有问题
library IEEE;use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder is
port
(
sec_modA : in std_logic;--模式选择信号
sec_modB : in std_logic;--模式选择信号
sec_modC : in std_logic;--模式选择信号
sec_modD : in std_logic;--模式选择信号
dat_in: in std_logic_vector(7 downto 0);--系统时钟输入
mcu_clk : in std_logic ;--单片机输出时钟信号
ack : out std_logic;--输出搞定平,指示单片机可以发送数据
datOutD : out std_logic_vector(15 downto 0)--数据从输出
)
end entity;
architecture rtl of adder is
signal temp:std_logic_vector(7 downto 0);
signal mtmp:std_logic_vector(3 downto 0);
subtype word is std_logic_vector(7 downto 0);
type memoryis array(1 downto 0) of word;--定义2个字节的内存
begin
ack<='1';--一开始就输出高电平,指示mcu可以发送数据
temp<=dat_in; --读数据
mtmp<= sec_modD & sec_modC & sec_modB & sec_modA;--读工作模式
N1: process (mcu_clk,mtmp)
variable i: integer range 0 to 1 :=0;
variable REG8:memory;--定义内存
begin
if(rising_edge(mcu_clk) ) then
if(mtmp="0000" ) then
i:=0;
for n in 0 to 1 loop--初始化内存
REG8(n):= "11111111";
end loop;
elsif(mtmp="0001" ) then
REG8(i):=temp; --写内存
i:=i+1;
elsif(mtmp="0010" ) then
datOutD<= REG8(0) & REG8(1);--将内存数据输出,以便检查内存数据是否正确
end if;
end if;
end process;
end rtl;
就是想通过单片机对CPLD内定义的2字节内存操作,波形仿真都对了,下载下去,单片机输出数据,CPLD根本就没有反应,高手们给点意见,我该如何去调试 http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_629324SARIJ7.GIF
(原文件名:1.GIF) 仿真正确了,当然管脚都已经配置过了,是否就说CPLD的程序是没有问题了,谁能给点意见,刚接触VHDL 路过的朋友,请发表下意见 你还在C语言的思想写VHDL,VHDL是描述硬件,有实时的特点,少用IF和FOR循环
程序的主要问题是在mcu_clk变化时,你那么多IF,CPLD做不了那么多事,不能捕捉到信号.
核心改动如下,你试试,另外你上位机控制信号mtmp应在mcu_clk跳变时处理好同步/异步的问题.
if(mtmp = "0000" ) then --初始化
i:=0;
REG8(1):= "11111111"; --初始化内存
REG8(0):= "11111111"; --初始化内存
elsif(mtmp != "0000" ) then --非空运行
if(rising_edge(mcu_clk) ) then --上升沿时执行
if(mtmp="0001" ) then --mcu_clk上升沿同时mtmp="0001"时执行
REG8(i):=temp; --写内存--第一次将数据写入REG8(0),REG8(1)将在下一mcu_clk上升沿写入
i:=i+1; --i+1
elsif(mtmp="0010" ) then
datOutD<= REG8(0) & REG8(1);--将内存数据输出,以便检查内存数据是否正确
end if;
end if;
end if; 优化如下:
if(rising_edge(mcu_clk) ) then
case mtmp is
when "0000" =>
i:=0;
REG8(1):= "11111111"; --初始化内存
REG8(0):= "11111111"; --初始化内存
when "0001" =>
REG8(i):=temp; --第一次将数据写入REG8(0),REG8(1)将在下一mcu_clk上升沿写入
i:=i+1; --i+1
when "0010" =>
datOutD(15 downto 8)<= REG8(1);--将内存数据输出,以便检查内存数据是否正确
datOutD(7 downto 0)<= REG8(0);--将内存数据输出,以便检查内存数据是否正确
when others =>
i := 0;
REG8(1) := "XXXXXXXX";
REG8(0) := "XXXXXXXX";
datOutD := "XXXXXXXXXXXXXXXX";
end case;
end if; 这行要执行的话 datOutD<= REG8(0) & REG8(1); mcu_clk,要有一个有变化不知你MCU有没有给 估计是MCU程序问题 谢谢,看了您的优化,写的真好,受益匪浅。谢谢 给了,我再仔细检查下,呵呵真失败,搞了好几天没有弄出来 失败很好,印象深刻,记的牢.
CPLD/FPGA不同于MCU,没有中断的概念,电路都是并行瞬间发生的,
复习复习课本前几章. 好的,受教了。 试试我这个简单的写程序,你要只是很能少字节传输。 基于寄存器和状态机变形 相当好用
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY MCUPIORW IS
PORT (
REST,EN:INstd_logic;
WCLK :INstd_logic;
DATA_OUT :OUT std_logic_vector(7 downto 0);
M_state :IN std_logic_vector(7 downto 0);
DATA_IN ,abdata:IN std_logic_vector(15 downto 0));
END MCUPIORW;
ARCHITECTURE EP2C5 OF MCUPIORW IS
TYPE state is (s0,s1,s2,s3,s4);
signal C_state:state;
BEGIN
PROCESS (WCLK,REST)
BEGIN
IF(REST='0')THEN
C_state<=s0;
DATA_OUT<= (OTHERS=>'1');
ELSIF WCLK = '1' AND WCLK 'EVENT THEN
IF(EN='1')THEN
IF (C_state=s0)THEN
DATA_OUT <=DATA_IN(15 downto 8);
C_state<=s1;
END IF;
if (C_state=s1)THEN
DATA_OUT <= DATA_IN(7 downto 0);
C_state<=s2;
END IF;
IF (C_state=s2)THEN
DATA_OUT <=abdata(15 downto 8);
C_state<=s3;
END IF;
if (C_state=s3)THEN
DATA_OUT <= abdata(7 downto 0);
C_state<=s4;
END IF;
if (C_state=s4)THEN
DATA_OUT<= M_state(7 downto 0);
C_state<=s0;
END IF;
ELSE
DATA_OUT<= (OTHERS=>'1');
END IF;
END IF;
END PROCESS;
END EP2C5; 好的,谢谢 试了,可以。呵呵谢谢,今天终于进步了 那一段程序可以用啊,分析下问题出在哪里也好举一反三,
才显得这个帖子有点价值啊。不然路过的都飘过了~ 优化如下:
if(rising_edge(mcu_clk) ) then
case mtmp is
when "0000" =>
i:=0;
REG8(1):= "11111111"; --初始化内存
REG8(0):= "11111111"; --初始化内存
when "0001" =>
REG8(i):=temp; --第一次将数据写入REG8(0),REG8(1)将在下一mcu_clk上升沿写入
i:=i+1; --i+1
when "0010" =>
datOutD(15 downto 8)<= REG8(1);--将内存数据输出,以便检查内存数据是否正确
datOutD(7 downto 0)<= REG8(0);--将内存数据输出,以便检查内存数据是否正确
when others =>
i := 0;
REG8(1) := "XXXXXXXX";
REG8(0) := "XXXXXXXX";
datOutD := "XXXXXXXXXXXXXXXX";
end case;
end if; 这段程序可以用 串行语句 if语句和case语句的区别,我写了个测试程序
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder is
port
(
sec : in std_logic_vector(1 downto 0);
Dout: out std_logic_vector(1 downto 0)
);
end entity;
architecture rtl of adder is
signal temp : std_logic_vector ( 1 DOWNTO 0 );
begin
temp<= sec;
N1: process (temp)
begin
if(temp="11") then Dout<="11";
elsif (temp="10") then Dout<="10";
elsif (temp="01") then Dout<="01";
else Dout<="00";
end if;
end process;
end rtl;
--N1: process (temp)
-- begin
-- case temp is
-- when "11" => Dout<="11";
-- when "10" => Dout<="10";
-- when "01" => Dout<="01";
-- when others => Dout<="00";
-- end case;
-- end process;
--end rtl;
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_629512L1MFAX.GIF
RTL图是用if语句写的 (原文件名:1.GIF)
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_629513UR3QU6.GIF
RTL图是用case语句写 (原文件名:2.GIF) 怎么会有如此大的区别?? 这是编译优化的结果:
if有分支判断,于是电路复杂了点;根据IF镶套的优先级来看.
CASE分支判断,你没有判断,所以直连了;
所以你要少用IF,多用CASE,尽量把所有的情况都写到分支中. 再请问个问题,进程里的顺序语句在仿真时是有明显的顺序性,但是下载到硬件里后是如何执行的?看了书不是很理解,书上好像就说是执行到end process时再过δ时间去执行; 所有process的顺序语句都是并行执行的,只有IF等判断语句的分支会按照优先级顺序执行下去;
而不管是CASE还是IF,分支判断语句内的顺序语句都是并行执行的.
比如
以下在CLK上升沿时分别判断A或B,并行执行,无关联;
process (clk,A,B)
if(rising_edge(clk) ) then
IF A = '1' THEN
...
END IF;
IF B = '1' THEN
...
END IF;
end if
END process;
以下在CLK上升沿时分别先判断A再判断B,顺序执行,A比B快;
process (clk,A,B)
if(rising_edge(clk) ) then
IF A = '1' THEN
...
ELSIF B = '1' THEN
X <= '0'; ---这里X,Y是同时赋值的.
Y <= '1';
END IF;
end if
END process; 进程不是函数,你可以看作一个确实存在的硬件,收到指令就指定的部件. 谢谢,那假如进程里if... elsif.... elsif...else end if;很多个;那么进程结束了,会不会导致判断来不及?? 学习了 这要看跳变沿的速度,如果if语句的分支很多,每个分支等同于触发器或逻辑,那么累积的物理延迟不能超过CLK的周期的1/2(这样说不准确,或者说CLK跳变沿时,你的其他变量不能变化(或中间状态),不然仿真OK,扳子干活时跑飞(语句正确,但时序不达标).考虑到这种情况,应该转用case语句;尽量将If语句中的各种功能拆成小进程,信号偶合多的组合一个进程,并行运行关系不紧密的功能分开. hawkflyking 牛人呵呵还是个好人 回复【25楼】jinhancn
-----------------------------------------------------------------------
我是菜鸟一只,潜水日久手痒. 少用锁存器.
多用IF ,少用CASE -WHEN 哈 ^^^^
页:
[1]