预览模式: 普通 | 列表

双向口问题小节 VHDL

双向口问题小节
在工程应用中,双向电路是设计者不得不面对的问题.在实际应用中,数据总线往往是双向的.如何正确处理数据总线是进行时序逻辑电路设计的基础.在程序设计过程中,关键技术在于:实体部分必须对端口属性进行申明,端口属性必须为inout类型,在构造体需要对输出信号进行有条件的高阻控制.在双向电路的处理问题上,常用的处理方式有两种,在介绍双向电路的处理方式之前,先看看双向电路的基本格式:

ENTITY bidir_pin IS
(
bidir : INOUT std_logic;
oe, clk, from_core : IN std_logic;
to_core : OUT std_logic;
……
END bidir_pin;

ARCHITECTURE behavior OF bidir_pin IS
BEGIN
   bidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;
   to_core <= bidir;
_
_
_
END behavior;


 该程序揭示了双向电路的处理技巧,首先在实体部分bidir属于双向信号,在端口定义时,端口属性为inout类型,即把bidir信号作为输入三态输出. 语句“bidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;”表示bidir信号三态输出,语句”to_core <= bidir;”把bidir信号作为输入信号.
 由此可见,双向电路在程序设计中,didir输入当着普通的in类型,而在输出时,需要加一定的控制条件,三态输出.问题的关键在于:如何确定这个条件?

1)双向信号作一个信号的输入,作另一信号的输出

ENTITY bidir IS
PORT(
bidir : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);
oe, clk : IN STD_LOGIC;
from_core : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
to_core : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END bidir;

ARCHITECTURE logic OF bidir IS
SIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0);
SIGNAL b : STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
PROCESS (clk)
BEGIN
   IF clk = '1' AND clk'EVENT THEN
       a <= from_core;
       to_core <= b;
   END IF;
END PROCESS;

PROCESS (oe, bidir)
BEGIN
  IF( oe = '0') THEN
     bidir <= "ZZZZZZZZ";
     b <= bidir;
  ELSE
     bidir <= a;
     b <= bidir;
  END IF;
END PROCESS;
END logic;

 这种设计方式叫做寄存双向信号的方法.本设计中bidir为双向信号,from_core为数据输入端,to_core为数据输出端,oe为三态输出使能,clk为读写数据的时钟.在程序设计中,需要定义两个signal a和b信号.a信号用于输入数据from_core的寄存器,b用于输出数据to_core的寄存器.采用寄存器的方法需要设计两个进程,一个进程把a,b信号在时钟的控制下负责端口的输入信号from_core和端口输出信号to_core的连接,这一步实现了寄存双向的功能.另外一个进程则负责信号a,b和双向口之间的赋值关系.本设计只揭示了简单的双向信号操作方式,即bidir既可以作为from_core的输出,又可以作为to_core的输入

2)双向信号既做输出又做输出

上例是最简单的双向信号应用的特例.在实际的工程中,双向信号既做信号的输入,又做信号的输出,常见的数据总线就是这种操作模式.

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity dir_data is
  port(
   clk : in STD_LOGIC;
   rst : in STD_LOGIC;
   rw : in STD_LOGIC;
   address : in STD_LOGIC_VECTOR(1 downto 0);
   data : inout STD_LOGIC_VECTOR(7 downto 0)
      );
end dir_data;

architecture arc_dir of dir_data is 

signal data_in : STD_LOGIC_VECTOR(7 downto 0);
signal data_out: STD_LOGIC_VECTOR(7 downto 0);
signal reg_a: STD_LOGIC_VECTOR(7 downto 0);
signal reg_b: STD_LOGIC_VECTOR(7 downto 0);

begin   
 
 data_in<=data;
 
 d1:process(clk,rst,rw)
 begin
  if rst='1' then
       reg_a<= (others=>'0');
       reg_b<= (others=>'0');
  elsif clk'event and clk='1' then
     if rw='1' then
        if address="00" then  
        reg_a<=data_in;
     elsif address="01" then
        reg_b<=data_in;
     else null;
     end if;
   else null;
   end if;
  else null;
  end if;
  end process d1;

 d2:process(clk,rw,reg_a,reg_b) 
 begin
 if clk'event and clk='1' then
    if rw='0' then
        if address="00" then
           data_out<=reg_a;
        elsif address="01" then
           data_out<=reg_b;
        else null;
    end if;
  else null;
  end if;
 else null;
 end if;
 end process d2; 
  
 data<=data_out when (rw='0' and address(1)='0') else
   (others=>'Z');
 
end arc_dir;

 在程序设计中,首先需要定义data_in, data_out, reg_a, reg_b四个signal,我们把data_in叫做输入寄存器,它是从双向信号data接收数据的寄存器,data_out叫做输出寄存器,它是向双向信号data发送信号的寄存器,reg_a和reg_b叫做操作寄存器,它们是在一定的时序控制下把data_in数据送给reg_a,reg_b,在一定的时序控制下从reg_a和reg_b读出数据的.
 这样的处理方式必须有两个进程,因为在architecture arc_dir of dir_data is和begin之间定义了data_in, data_out, reg_a, reg_b四个signal,它在同一进程内不支持既赋值,又调用,也就是说它不支持在d1进程中对信号reg_a, reg_b赋值,又在d1进程中又调用reg_a, reg_b.
首先有语句”data_in<=data;”它表示输入寄存器无条件的接收双先信号的数据.在d1进程中,首先在rst信号有效时,对操作寄存器reg_a,和reg_b进行清零操作,然后在时钟(clk)的控制下,在写(rw)信号有效的情况下,对reg_a, reg_b寄存器在不同的地址控制下写入不同的data_in值.在d2进程中,在时钟(clk)的控制下,在读(rw)信号有效的时候,把不同地址的reg_a, reg_b的值送进data_out中.
最关键的是最后一句:“data<=data_out when (rw='0' and address(1)='0') else (others=>'Z');”它表示双向信号的三态输出,而最最关键的是when后面的条件,如果条件限制太宽,就会错误占用双向信号总线,引起总线的误操作,如果条件限制太窄,输出寄存器的数据就不能够正确的送到数据总线上去,会引起数据的丢失.也就是说,只有正确的限制了when语句后面的条件,才能够把输出寄存器的数据正确地送到数据总线上去.仔细查看此条件,有如下的规律:when语句后的条件是操作寄存器写入输出寄存器的条件的公共条件.比如:rw=’0’是操作寄存器的数据写入输出寄存器的读使能信号,address(1)是地址线的公共部分.在实际工程应用中,需要设计者在分配地址总线的时候掌握一定的技巧,尽量从地址的低位到到高位,保证地址总线有更多位的公共部分,比如只对四个寄存器操作时,地址线分配为”100”,”010”,”110”,”001”是不科学的,而”000”,”001”,”010”和”011”则是理想的.两者不同的是前者地址线没有公共部分,这样的设计无法用when语句对条件进行直接的控制,如果置之不理,由于列举不全,在逻辑综合时,电路会利用器件的乘积项和查找表的资源形成一个Latch, Latch不仅会把电路的时序变得复杂,而且电路存在潜在的危险性.虽然when语句后的条件不能够对条件进行直接的控制,但是可以使用枚举法一一把用到的地址线罗列出来,表示只有在这样的地址线的情况下才会用到数据总线,否则其他状态对数据总线送高阻,表示不占用数据总线.
总而言之,双向信号是程序设计中尤其重要的基础,设计者在设计程序的时候,要尤其注意,何时会占用数据总线,何时不占用数据总线.

分类:草兄随笔 | 固定链接 | 评论: 2 | 引用: 0 | 查看次数: 154

西铁城 K3247 液晶驱动

这块西铁城K3247 2‘8寸的液晶屏买了放那已经好久了,最近花了点功夫用CPLD把它驱动起来。
还没加显存,下次在弄块Sram上去!

这是CPLD的顶层文件

查看更多...

分类:草作一点 | 固定链接 | 评论: 3 | 引用: 0 | 查看次数: 219

C Sharp 畅想曲 之 [序幕]




在学习C Sharp过程中,突然想到了做个桌面时钟小软件,
于是就开始花了一个晚上的时间,找资料 完成了这个不大成熟的作品!

查看更多...

分类:草作一点 | 固定链接 | 评论: 1 | 引用: 0 | 查看次数: 315

深层剖析解的特征 

每道都由题干(即问题)与四个选项组成。我对四个选项这样划分:其中一个是答案的选项称为解,其余三个选项不称为选项,而称为干扰项,因为几乎每个选项都被命题者加上了十足的功力,麻痹考生,以达到不容易被考生答对的目的。这样由命题难度梯度决定,解必然有如下特点: 

查看更多...

分类:草兄随笔 | 固定链接 | 评论: 1 | 引用: 0 | 查看次数: 278

一个线性三端稳压器扩流电路

分类:草屋科技 | 固定链接 | 评论: 2 | 引用: 0 | 查看次数: 1289

我是一块硬盘(感动T_T)

一个小小(电脑)世界里关于工作、爱情和友情的甘苦人生。
  之所以感动,或许是因为你我就是那块硬盘、那条内存、那个CMOS或BIOS吧。


查看更多...

分类:草兄随笔 | 固定链接 | 评论: 4 | 引用: 0 | 查看次数: 1749

电赛 上海赛区颁奖

     
    全国大学生电子设计竞赛的颁奖居然拖到了昨天才颁奖,我作为指导教师,跟着几个学生和另外几个指导教师也去参加了下。 
    我们这届获得的成绩还是蛮不错的,2个上海赛区一等奖。 
    可惜啊,我们学校领导不识货(我只能说他们不识货了),一点也没有关心的意思,只是在校门口大屏幕上打了几个“热烈祝贺我校通信系学生在2007年全国大学生电子设计竞赛中获得2个一等奖”,就这几个字,还是“残缺不全”的(点阵屏上有坏点!晕倒!)。
    就说这次去领奖吧,人家学校都是特意安排一辆校车送去交大的。看看我们跟人家的差别,居然安排一辆“便车”,是其他部门安排学生去面试,“顺便”送我们6个学生和6个指导教师去交大。 顺便就说了,回来时居然也是顺便搭车回来,还要我们到处找校车!老大们,我们获的是一等奖啊。而且其中一组还是本科组一等奖啊! 校领导们,别忘了我们只是高职啊! 是不是觉得这个比赛没意义啊。。。?   我倒现在想09年还搞不搞,这样子的话,太没意思了!

查看更多...

分类:草兄随笔 | 固定链接 | 评论: 4 | 引用: 0 | 查看次数: 1506

一篇很棒的 电子元器件知识

电子元器件基础知识(1)——电阻

导电体对电流的阻碍作用称为电阻,用符号R表示,单位为欧姆、千欧、兆欧,分别用Ω、KΩ、MΩ表示。一、电阻的型号命名方法:

国产电阻器的型号由四部分组成(不适用敏感电阻)

查看更多...

分类:草屋科技 | 固定链接 | 评论: 3 | 引用: 0 | 查看次数: 1545