jhwangfei
驱动牛犊
驱动牛犊
  • 注册日期2002-07-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1939回复:5

我用vhdl写8254计数器,出现了些问题, 请高手帮忙看看!谢了

楼主#
更多 发布于:2002-11-28 16:49
      library ieee;
      use ieee.std_logic_1164.all;
      use ieee.std_logic_unsigned.all;

      entity chip8254 is
      port(
      clk: in std_logic;--时钟
      gate: in std_logic;--门信号
      wr: in std_logic;--读信号
      cs: in std_logic;--片选
      cout: buffer std_logic;--输出
      data: inout std_logic_vector(7 downto 0)--数据端
      );
      end chip8254;

      architecture behave of chip8254 is
      signal pcr:std_logic_vector(7 downto 0):=\"00000000\";--初值寄存缓冲
      signal cr:std_logic_vector(7 downto 0):=\"00000000\";--初值寄存器
      signal ce:std_logic_vector(7 downto 0):=\"00000000\";--计数执行单元
      signal cnr:std_logic_vector(7 downto 0):=\"00000000\";--控制字寄存器
      signal nullcount: std_logic:=\'1\';--是否置入初值
      signal stopcount: std_logic:=\'0\';--是否停止计数
      begin
      process(wr)--读数
      begin
      if rising_edge(wr) then--读信号的上升沿
      if cnr=0 then--还没有写入控制字
      cnr<=data;--写入控制字
      case cnr(3 downto 1) is--写入控制字后的cout变化
      when \"000\"=>cout<=\'0\';
      when \"001\"=>cout<=\'1\';
      when \"010\"=>cout<=\'1\';
      when \"011\"=>cout<=\'0\';
      when \"100\"=>cout<=\'1\';
      when \"101\"=>cout<=\'1\';
      when others=>null;
      end case;
      else--写入初值
      pcr<=data;
      if cnr(3 downto 1)=\"000\" or cnr(3 downto 1)=\"100\" then
      cr<=pcr;--在方式0和方式4中,初值随时变化
      end if;
      end if;
      end if;
      end process;

      process(gate)--门信号的触发作用
      begin
      if rising_edge(gate) then--上升沿
      if cnr(3 downto 1)=\"000\" then--方式0
      stopcount<=\'0\';--继续计数
      elsif cnr(3 downto 1)=\"001\" then--方式1
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      ce<=cr;--开始计数
      nullcount<=\'0\';
      cout<=\'0\';
      elsif cnr(3 downto 1)=\"010\" then--方式2
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      ce<=cr;--开始计数
      nullcount<=\'0\';
      elsif cnr(3 downto 1)=\"011\" then--方式3
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      if cr(0)=\'0\' then--初值为偶数
      ce<=cr;--初值装入ce
      else
      ce<=cr-1;--初值为奇数,初值减一装入ce
      end if;
      nullcount<=\'0\';--开始计数
      elsif cnr(3 downto 1)=\"100\" then--方式4
      ce<=cr;--开始计数
      nullcount<=\'0\';
      elsif cnr(3 downto 1)=\"101\" then--方式5
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      ce<=cr;--开始计数
      nullcount<=\'0\';
      else
      null;
      end if;
      end if;
      end process;

      process(gate)--门信号触发
      begin
      if falling_edge(gate) then --下降沿
      if cnr(3 downto 1)=\"000\" then--方式0
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"001\" then--方式1
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      elsif cnr(3 downto 1)=\"010\" then--方式2
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"011\" then--方式3
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"100\" then--方式4
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"101\" then--方式5
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      else
      null;
      end if;
      end if;
      end process;

      process(clk)--时钟
      begin
      if rising_edge(clk) then--时钟上升沿
      if cnr(3 downto 1)=\"000\" then--方式0
      if cs=\'1\'and gate=\'1\' and stopcount=\'0\'and nullcount=\'0\' then
      if ce/=0 then--计数未结束
      ce<=ce-1;
      else--计数结束
      cout<=\'1\';
      nullcount<=\'1\';
      end if;
      end if;
      elsif cnr(3 downto 1)=\"001\" then--方式1
      if cs=\'1\' and nullcount=\'0\' then
      if ce/=0 then
      ce<=ce-1;
      else
      cout<=\'1\';
      nullcount<=\'1\';
      end if;
      end if;
      elsif cnr(3 downto 1)=\"010\" then--方式2
      if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then
      if ce/=0 then--计数未结束
      if ce=1 then--计数值为1
      cout<=\'0\';
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      else
      ce<=ce-1;
      end if;
      else--计数结束
      cout<=\'1\';
      ce<=cr;--重新装入初值,开始计数
      nullcount<=\'0\';
      end if;
      end if;
      elsif cnr(3 downto 1)=\"011\" then--方式3
      if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then
      if cr(0)=\'0\' then--初值为偶数
      if ce/=0 then--计数未结束
      ce<=ce-2;
      else--计数结束
      cout<= not cout;--cout反向
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      if cr(0)=\'0\' then--初值为偶数
      ce<=cr;--装入初值
      else--初值为奇数
      ce<=cr-1;--装入初值减一
      end if;
      nullcount<=\'0\';--重新计数
      end if;
      else--初值为奇数
      if cout=\'1\' then--cout为高电平
      if ce/=-2 then
      ce<=ce-2;
      else--计数到-2
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      cout<=\'0\';
      ce<=cr-1;--初值减一装入ce
      nullcount<=\'0\';--重新开始计数
      end if;
      else--cout为低电平
      if ce/=0 then
      ce<=ce-2;
      else--计数结束
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      cout<=\'1\';
      ce<=cr-1;--初值减一装入ce
      nullcount<=\'0\';--重新开始计数
      end if;
      end if;
      end if;
      end if;
      elsif cnr(3 downto 1)=\"100\" then--方式4
      if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then
      if ce/=0 then
      ce<=ce-1;
      else--计数结束
      cout<=\'0\';
      nullcount<=\'1\';
      end if;
      elsif cout=\'0\' and nullcount=\'1\' and ce=0 then--让计数结束后cout值保持一个时钟的低电平
      cout<=\'1\';
      end if;
      elsif cnr(3 downto 1)=\"101\" then--方式5
      if cs=\'1\' and nullcount=\'0\' then
      if ce/=0 then
      ce<=ce-1;
      else--计数结束
      cout<=\'0\';
      nullcount<=\'1\';
      end if;
      elsif cout=\'0\' and nullcount=\'1\' and ce=0 then
      cout<=\'1\';--让计数结束后cout只保持一个时钟的低电平
      end if;
      else
      null;
      end if;
      end if;

      end process;
      end behave;
ERROR:signal\'cr\' has multiple sources
      signal\'ce\' has multiple sources
      signal\'nullcount\'has multiple sources
      signal\'stopcount\'has multiple sources
      signal\'count\'has multiple sources


          

atuhappy
驱动老牛
驱动老牛
  • 注册日期2002-03-15
  • 最后登录2009-09-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-11-28 19:09
     library ieee;
      use ieee.std_logic_1164.all;
      use ieee.std_logic_unsigned.all;

      entity chip8254 is
      port(
      clk: in std_logic;--时钟
      gate: in std_logic;--门信号
      wr: in std_logic;--读信号
      cs: in std_logic;--片选
      cout: buffer std_logic;--输出
      data: inout std_logic_vector(7 downto 0)--数据端
      );
      end chip8254;

      architecture behave of chip8254 is
      signal pcr:std_logic_vector(7 downto 0):=\"00000000\";--初值寄存缓冲
      signal cr:std_logic_vector(7 downto 0):=\"00000000\";--初值寄存器
      signal ce:std_logic_vector(7 downto 0):=\"00000000\";--计数执行单元
      signal cnr:std_logic_vector(7 downto 0):=\"00000000\";--控制字寄存器
      signal nullcount: std_logic:=\'1\';--是否置入初值
      signal stopcount: std_logic:=\'0\';--是否停止计数
      begin
      process(wr)--读数
      begin
      if rising_edge(wr) then--读信号的上升沿
      if cnr=0 then--还没有写入控制字
      cnr<=data;--写入控制字
      case cnr(3 downto 1) is--写入控制字后的cout变化
      when \"000\"=>cout<=\'0\';
      when \"001\"=>cout<=\'1\';
      when \"010\"=>cout<=\'1\';
      when \"011\"=>cout<=\'0\';
      when \"100\"=>cout<=\'1\';
      when \"101\"=>cout<=\'1\';
      when others=>null;
      end case;
      else--写入初值
      pcr<=data;
      if cnr(3 downto 1)=\"000\" or cnr(3 downto 1)=\"100\" then
      cr<=pcr;--在方式0和方式4中,初值随时变化
      end if;
      end if;
      end if;
      end process;

      process(gate)--门信号的触发作用
      begin
      if rising_edge(gate) then--上升沿
      if cnr(3 downto 1)=\"000\" then--方式0
      stopcount<=\'0\';--继续计数
      elsif cnr(3 downto 1)=\"001\" then--方式1
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      ce<=cr;--开始计数
      nullcount<=\'0\';
      cout<=\'0\';
      elsif cnr(3 downto 1)=\"010\" then--方式2
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      ce<=cr;--开始计数
      nullcount<=\'0\';
      elsif cnr(3 downto 1)=\"011\" then--方式3
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      if cr(0)=\'0\' then--初值为偶数
      ce<=cr;--初值装入ce
      else
      ce<=cr-1;--初值为奇数,初值减一装入ce
      end if;
      nullcount<=\'0\';--开始计数
      elsif cnr(3 downto 1)=\"100\" then--方式4
      ce<=cr;--开始计数
      nullcount<=\'0\';
      elsif cnr(3 downto 1)=\"101\" then--方式5
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      ce<=cr;--开始计数
      nullcount<=\'0\';
      else
      null;
      end if;
      end if;
      end process;

      process(gate)--门信号触发
      begin
      if falling_edge(gate) then --下降沿
      if cnr(3 downto 1)=\"000\" then--方式0
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"001\" then--方式1
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      elsif cnr(3 downto 1)=\"010\" then--方式2
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"011\" then--方式3
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"100\" then--方式4
      stopcount<=\'1\';--停止计数
      elsif cnr(3 downto 1)=\"101\" then--方式5
      if pcr/=cr then--更新初值
      cr<=pcr;
      end if;
      else
      null;
      end if;
      end if;
      end process;

      process(clk)--时钟
      begin
      if rising_edge(clk) then--时钟上升沿
      if cnr(3 downto 1)=\"000\" then--方式0
      if cs=\'1\'and gate=\'1\' and stopcount=\'0\'and nullcount=\'0\' then
      if ce/=0 then--计数未结束
      ce<=ce-1;
      else--计数结束
      cout<=\'1\';
      nullcount<=\'1\';
      end if;
      end if;
      elsif cnr(3 downto 1)=\"001\" then--方式1
      if cs=\'1\' and nullcount=\'0\' then
      if ce/=0 then
      ce<=ce-1;
      else
      cout<=\'1\';
      nullcount<=\'1\';
      end if;
      end if;
      elsif cnr(3 downto 1)=\"010\" then--方式2
      if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then
      if ce/=0 then--计数未结束
      if ce=1 then--计数值为1
      cout<=\'0\';
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      else
      ce<=ce-1;
      end if;
      else--计数结束
      cout<=\'1\';
      ce<=cr;--重新装入初值,开始计数
      nullcount<=\'0\';
      end if;
      end if;
      elsif cnr(3 downto 1)=\"011\" then--方式3
      if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then
      if cr(0)=\'0\' then--初值为偶数
      if ce/=0 then--计数未结束
      ce<=ce-2;
      else--计数结束
      cout<= not cout;--cout反向
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      if cr(0)=\'0\' then--初值为偶数
      ce<=cr;--装入初值
      else--初值为奇数
      ce<=cr-1;--装入初值减一
      end if;
      nullcount<=\'0\';--重新计数
      end if;
      else--初值为奇数
      if cout=\'1\' then--cout为高电平
      if ce/=-2 then
      ce<=ce-2;
      else--计数到-2
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      cout<=\'0\';
      ce<=cr-1;--初值减一装入ce
      nullcount<=\'0\';--重新开始计数
      end if;
      else--cout为低电平
      if ce/=0 then
      ce<=ce-2;
      else--计数结束
      if cr/=pcr then--更新初值
      cr<=pcr;
      end if;
      cout<=\'1\';
      ce<=cr-1;--初值减一装入ce
      nullcount<=\'0\';--重新开始计数
      end if;
      end if;
      end if;
      end if;
      elsif cnr(3 downto 1)=\"100\" then--方式4
      if cs=\'1\' and nullcount=\'0\' and stopcount=\'0\' and gate=\'1\' then
      if ce/=0 then
      ce<=ce-1;
      else--计数结束
      cout<=\'0\';
      nullcount<=\'1\';
      end if;
      elsif cout=\'0\' and nullcount=\'1\' and ce=0 then--让计数结束后cout值保持一个时钟的低电平
      cout<=\'1\';
      end if;
      elsif cnr(3 downto 1)=\"101\" then--方式5
      if cs=\'1\' and nullcount=\'0\' then
      if ce/=0 then
      ce<=ce-1;
      else--计数结束
      cout<=\'0\';
      nullcount<=\'1\';
      end if;
      elsif cout=\'0\' and nullcount=\'1\' and ce=0 then
      cout<=\'1\';--让计数结束后cout只保持一个时钟的低电平
      end if;
      else
      null;
      end if;
      end if;

      end process;
      end behave;
ERROR:signal\'cr\' has multiple sources
      signal\'ce\' has multiple sources
      signal\'nullcount\'has multiple sources
      signal\'stopcount\'has multiple sources
      signal\'count\'has multiple sources


          

 



在不同的进程中对同一信号赋值了
这是不允许的
在一回首间,才忽然发现,原来,我一生的种种努力,不过只是为了要使周遭的人都对我满意而已。为了要博得他人的称许和微笑,我战战兢兢得将自己套入所有得模式,所有的桎梏。走到中途,才忽然发现,我只剩下一副模糊得面目,和一条不能回头的路...
poplar
驱动牛犊
驱动牛犊
  • 注册日期2001-05-04
  • 最后登录2007-01-08
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-11-28 20:52
原代码我没看完,不过这些信号都是同一个错误的。
就是一个信号同时被多个输出驱动,这错误是很明显的,多个输出同时接到一起肯定有问题,你可以用一些数据选择器或三态输出。
可以写成:
   if 条件1 then
      OUT <= OUT1;
   elsif 条件2 then
      OUT <= OUT2;
   elsif 条件3 then
      OUT <= OUT3;
也可用:
  case is
    
  endcase
这两种方式实现,推荐后一种.



[编辑 -  11/28/02 by  poplar]
大巧不工,重剑无锋.
jhwangfei
驱动牛犊
驱动牛犊
  • 注册日期2002-07-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-11-28 21:44
但是在不同的PROCESS中不好用上面的方法,在不同PROCESS对同一信号赋值有什么技巧啊
poplar
驱动牛犊
驱动牛犊
  • 注册日期2001-05-04
  • 最后登录2007-01-08
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-12-01 01:10
用多路开关啊。
大巧不工,重剑无锋.
green_pine
驱动太牛
驱动太牛
  • 注册日期2002-10-22
  • 最后登录2019-06-10
  • 粉丝3
  • 关注0
  • 积分48分
  • 威望599点
  • 贡献值1点
  • 好评度144点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2002-12-07 15:03
process1:process(clk)
     data1:=q1;
.........
end process;
process2:process(clk)
     data2:=q2;
end process;
process3:process(temp)
if temp=\'1\' then
data:=data1;
else
data:=data2;
end if;
end process;
加一个控制量就行了
游客

返回顶部