yuhzhq
驱动牛犊
驱动牛犊
  • 注册日期2004-08-05
  • 最后登录2004-09-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1298回复:2

高手大哥帮帮忙,帮我看看我的程序问题出在哪?

楼主#
更多 发布于:2004-09-04 10:50
高手大哥帮帮忙,帮我看看我的程序问题出在哪?
明天要验收了,搞不定就死了,一个设计8253的程序,暂时只添加了通道0。方式0时,每次后计数值最后两位为01后就输出OUT就翻转了,例如,从00000111计到00000101后OUT变高了,然后继续减到00000100再到00000011就再也不动了(我设置了计数到0后将计数器挂起)为什么啊??
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CTER IS
PORT(rd,wr,cs,a1,a0:IN STD_LOGIC;
 d  :inout std_logic_vector(7 downto 0);
 out0 :inout STD_LOGIC;--,out1,out2
 --ct0_out:out std_logic_vector(5 downto 0);
      
 --wait0_out : out std_logic;
 --h1_out,counter0_out,ref0_out:out std_logic;
 --h1_edge_out:out std_logic;
 clk0:in std_logic;
 gate0:in std_logic);
end cter;
ARCHITECTURE i8253 OF CTER IS
SIGNAL internal_bus_in :std_logic_vector(7 downto 0);
SIGNAL internal_bus_out:std_logic_vector(7 downto 0);
SIGNAL ct0_con:std_logic_vector(5 downto 0);
        
SIGNAL crreg0:std_logic_vector(15 downto 0);
          
SIGNAL olreg0:std_logic_vector(15 downto 0);
        
SIGNAL cereg0:std_logic_vector(15 downto 0);
SIGNAL h1:std_logic;
SIGNAL h1_edge:std_logic;
SIGNAL COUNTER0_ENABLE:std_logic;
SIGNAL wait0,wait1:std_logic;
SIGNAL ref0:std_logic;
SIGNAL cereg0_h,cereg0_10,cereg0_0,cereg0_1,cereg0_2:std_logic;
SIGNAL mode0_0,mode0_2,mode0_3:std_logic;
SIGNAL mode0_0c,mode0_2c,mode0_3c,out0_c:std_logic;
BEGIN
--*************************************

----- DATA CATHE BLOCK
DATA_CATHE:process(wr,rd,cs)
begin
 if (wr='0'and cs='0') then
  internal_bus_out<=d;
 elsif (rd='0' and cs='0')then
  d<=internal_bus_in;
 else
  d<="ZZZZZZZZ";
 END IF;
end process DATA_CATHE;
--******************************

-------WRITE CTR BLOCK
CTR_REG: process(wr,cs)
variable wr_con_flag:std_logic_vector(7 downto 0);
variable ad   :std_logic_vector(1 downto 0);
BEGIN
if (wr='0'and cs ='0') then
wr_con_flag:=d(7 downto 0);
ad:=a1 & a0;
end if;
IF (wr'event and wr='1') then
 IF (ad="11" AND cs='0')then
  IF wr_con_flag(5 downto 4)/="00" then
   case wr_con_flag(7 downto 6) is
   WHEN "00"=>ct0_con<=internal_bus_out(5 downto 0);
   counter0_enable<='0';
   WHEN others =>NULL;
   END CASE;      
  ELSE --锁存模式
   case wr_con_flag(7 downto 6) is
   WHEN "00"=>olreg0<=cereg0;
   WHEN OTHERS=> NULL;
   end case ;
  END IF;
 ELSIF ad="00" and cs='0' THEN
   case ct0_con(5 downto 4) IS
   WHEN "01"=>
    crreg0(7 downto 0)<=internal_bus_out;
    crreg0(15 downto 8)<="00000000";
    counter0_enable<='1';
   WHEN "10"=>
    crreg0(15 downto 8)<=internal_bus_out;
    crreg0(7 downto 0)<="00000000";
    counter0_enable<='1';
   WHEN "11"=>
    IF h1='0' then
    crreg0(7 downto 0)<=internal_bus_out;
    ELSIF h1= '1' THEN
    crreg0(15 downto 8)<=internal_bus_out;
    counter0_enable<='1';
    END IF;
   WHEN OTHERS =>NULL;
   END case;
  END IF;
 END IF;
END PROCESS CTR_REG;
--*************************************

-------H/L CODE
HL_CTR:PROCESS(h1_edge,cs,a1,a0)
  begin
   IF(a1='1' and a0='1' and cs='0') THEN
     h1<='1';    
   ELSIF h1_edge'event and h1_edge='1' THEN
     h1<= not h1;
   END IF;
  END process HL_CTR;
h1_edge<=rd xor wr;

--******************************************

--------READ DATA BLOCK
value_RD:PROCESS(a1,a0,h1)
  BEGIN
 IF (cs='0' and a1='0' and a0='0') THEN
   IF ct0_con(5 downto 4)="01" then
  internal_bus_in<=olreg0(7 downto 0);
   ELSIF ct0_con(5 downto 4)="10" THEN
  internal_bus_in<=olreg0(15 downto 8);
   ELSIF ct0_con(5 downto 0)="11" THEN
     if h1='0' then
  internal_bus_in<=olreg0(7 downto 0);
  elsif h1='1' then
  internal_bus_in<=olreg0(15 downto 0);
  end if;
   END IF;
 END IF;
END PROCESS value_RD;
--***********************************

------value OF CE BLOCK
ce:PROCESS(cereg0)
 variable tmp:std_logic;
 BEGIN
   tmp:='0';
   for i IN 15 downto 2 loop
    tmp:=tmp and cereg0(i);
  end loop;
  cereg0_h<=not tmp;
 end process ce;
cereg0_2<=cereg0_h and cereg0_h and cereg0(1) and  not cereg0(0);
cereg0_10<=cereg0_h and not cereg0(1);
cereg0_1<=cereg0_10 and cereg0(0);
cereg0_0<=cereg0_10 and  not cereg0(0);

--***********************************

--mode0 change
mode0_0<=not (ct0_con(1)or ct0_con(2) or ct0_con(3));
mode0_0c<=mode0_0 and cereg0_1;
--mode2 change
mode0_2<=not ct0_con(1) and ct0_con(2);
mode0_2c<=mode0_2 and (cereg0_2 or cereg0_1);
--mode2 change
mode0_3<=ct0_con(1) and ct0_con(2);
mode0_3c<=mode0_3 and cereg0_0;
--all change
out0_c<= mode0_0c or mode0_2c or mode0_3c;
--**********************************************

-----REFILL BLOCK
ref_0: PROCESS(clk0)
 BEGIN
   IF counter0_enable='0' THEN
    ref0<='1';
   ELSIF clk0'event AND clk0='0' then
   IF ref0='1' THEN
   ref0<='0';
   elsif ct0_con(2)='1' AND cereg0_2='1' THEN
      ref0<='1';
   end if;
     end if;
end process ref_0;
--*******************************
-------WAIT BLOCK

wait_0: PROCESS (clk0)
 BEGIN
  IF counter0_enable='0' THEN
    wait0<='0';
  ELSIF clk0'event and clk0='0' then
    IF mode0_0='1' AND cereg0_0='1' AND gate0='1' AND ref0='0'
    THEN wait0<='1';
    END IF;
  END IF;
 END PROCESS wait_0;
--***************************************************

-----------OUT BLOCK
out_0: PROCESS(clk0)
 BEGIN
  IF counter0_enable='0' THEN
   out0<=ct0_con(3) or ct0_con(2) or ct0_con(1);
  ELSIF clk0'event and clk0='0' THEN
   IF gate0='1' and out0_c='1' THEN
   out0<=not out0;
   END IF;
  END IF;
 END PROCESS out_0;
--*************************************************

---COUNTER CONTROL BLOCK
PROCESS(CLK0)
 BEGIN
IF counter0_enable='0'THEN
  cereg0<="1111111111111111";
 ELSIF (clk0'event and clK0='0') THEN
 IF ref0='1' THEN
   cereg0<=crreg0;
 ELSIF gate0='1' AND wait0='0' THEN
   IF  ct0_con(0)='1' AND cereg0(3 downto 0)=0 THEN
   cereg0(3 downto 1)<="100";
   cereg0(0)<=NOT mode0_3;
   ELSE
   IF mode0_3='0' THEN
   cereg0(3 downto 0)<=cereg0(3 downto 0)-1;
   ELSE
   IF NOT (cereg0(0) and out0)='1' THEN
   cereg0(3 downto 1)<=cereg0(3 downto 1)-1;
   END IF;
   cereg0(0)<='0';
   END IF;
   END IF;
    if  cereg0(3 downto 0)=0 then
    if ct0_con(0)='1'and cereg0(7 downto 4)=0 then
    cereg0(7 downto 4)<="1001";
    else cereg0(7 downto 4)<=cereg0(7 downto 4)-1;
    end if;
    end if;
   IF cereg0(7 downto 0)=0 THEN
   IF ct0_con(0)='1' AND cereg0(11 downto 8)=0 THEN
   cereg0(11 downto 8)<="1001";
   ELSE cereg0(11 downto 8)<=cereg0(11 downto 8)-1;
   END IF ;
   END IF;
 if cereg0(11 downto 0)=0 then
 if ct0_con(0)='1' and cereg0(15 downto 12)=0 then
 cereg0(15 downto 12)<="1001";
 else cereg0(15 downto 12)<=cereg0(15 downto 12)-1;
 end if;
 end if;
END IF;END IF;
END PROCESS;
END i8253;

yuhzhq
驱动牛犊
驱动牛犊
  • 注册日期2004-08-05
  • 最后登录2004-09-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-09-04 10:52
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CTER IS
PORT(rd,wr,cs,a1,a0:IN STD_LOGIC;
 d  :inout std_logic_vector(7 downto 0);
 out0 :inout STD_LOGIC;
 clk0:in std_logic;
 gate0:in std_logic);
end cter;
ARCHITECTURE i8253 OF CTER IS
SIGNAL internal_bus_in :std_logic_vector(7 downto 0);
--总线输入锁存
SIGNAL internal_bus_out:std_logic_vector(7 downto 0);
--总线输出锁存
SIGNAL ct0_con:std_logic_vector(5 downto 0);
--计数器控制字
SIGNAL crreg0:std_logic_vector(15 downto 0);
--计数器初使值          
SIGNAL olreg0:std_logic_vector(15 downto 0);
--计数器锁存        
SIGNAL cereg0:std_logic_vector(15 downto 0);
--计数当前值
SIGNAL h1:std_logic;--高/低字节的读写指示
SIGNAL h1_edge:std_logic;
SIGNAL COUNTER0_ENABLE:std_logic;--计数器使能
SIGNAL wait0:std_logic;--计数器挂起
SIGNAL ref0:std_logic;--计数器重装
SIGNAL cereg0_h,cereg0_10,cereg0_0,cereg0_1,cereg0_2:std_logic;
--计数当前值指示信号
SIGNAL mode0_0,mode0_2,mode0_3:std_logic;
--当前工作方式指示信号
SIGNAL mode0_0c,mode0_2c,mode0_3c,out0_c:std_logic;
--OUT0信号翻转指示信号
BEGIN
--************************************************************************

----- DATA CATHE BLOCK 数据缓存
DATA_CATHE:process(wr,rd,cs)
begin
 if (wr='0'and cs='0') then
  internal_bus_out<=d;
 elsif (rd='0' and cs='0')then
  d<=internal_bus_in;
 else
  d<="ZZZZZZZZ";
 END IF;
end process DATA_CATHE;
--*********************************************************************

-------WRITE CTR BLOCK 写控制寄存器或计数器0
CTR_REG: process(wr,cs)
variable wr_con_flag:std_logic_vector(7 downto 0);
variable ad   :std_logic_vector(1 downto 0);
BEGIN
if (wr='0'and cs ='0') then
wr_con_flag:=d(7 downto 0);
ad:=a1 & a0;
end if;
IF (wr'event and wr='1') then
 IF (ad="11" AND cs='0')then --选择控制寄存器写
  IF wr_con_flag(5 downto 4)/="00" then--不是锁存
   case wr_con_flag(7 downto 6) is
   WHEN "00"=>ct0_con<=internal_bus_out(5 downto 0);
   counter0_enable<='0';-----计数器0禁止
   WHEN others =>NULL;
   END CASE;      
  ELSE      -----锁存模式
   case wr_con_flag(7 downto 6) is
   WHEN "00"=>olreg0<=cereg0;
   WHEN OTHERS=> NULL;
   end case ;
  END IF;
 ELSIF ad="00" and cs='0' THEN-------选择计数器0
   case ct0_con(5 downto 4) IS
   WHEN "01"=>        
    crreg0(7 downto 0)<=internal_bus_out;--只写低8位
    crreg0(15 downto 8)<="00000000";
    counter0_enable<='1';
   WHEN "10"=>
    crreg0(15 downto 8)<=internal_bus_out;--只写高8位
    crreg0(7 downto 0)<="00000000";
    counter0_enable<='1';
   WHEN "11"=>
    IF h1='0' then
    crreg0(7 downto 0)<=internal_bus_out;---先低后高
    ELSIF h1= '1' THEN
    crreg0(15 downto 8)<=internal_bus_out;
    counter0_enable<='1';
    END IF;
   WHEN OTHERS =>
   END case;
  END IF;
 END IF;
END PROCESS CTR_REG;
--**********************************************************************

-------HIGH/LOW TURN  生成高低字节顺序信号
HL_CTR:PROCESS(h1_edge,cs,a1,a0)----高低字节读写指示
  begin
   IF(a1='1' and a0='1' and cs='0') THEN
     h1<='1';      
   --h1初始化
   ELSIF h1_edge'event and h1_edge='1' THEN
   --读/写信号下降沿h1翻转
     h1<= not h1;
   END IF;
  END process HL_CTR;
h1_edge<=rd xor wr;

--******************************************************************
--------READ DATA BLOCK 读计数值
value_RD:PROCESS(a1,a0,h1)
  BEGIN
--IF (rd'event and rd='1') THEN
 IF (cs='0' and a1='0' and a0='0') THEN
   IF ct0_con(5 downto 4)="01" then
  internal_bus_in<=olreg0(7 downto 0);
   ELSIF ct0_con(5 downto 4)="10" THEN
  internal_bus_in<=olreg0(15 downto 8);
   ELSIF ct0_con(5 downto 0)="11" THEN
     if h1='0' then
  internal_bus_in<=olreg0(7 downto 0);
  elsif h1='1' then
  internal_bus_in<=olreg0(15 downto 0);
  end if;
   END IF;
 END IF;
--END IF;
END PROCESS value_RD;
--******************************************************************

------value OF CE BLOCK 判断当前计数值
ce:PROCESS(cereg0)
 variable tmp:std_logic;
 BEGIN
   tmp:='0';
   for i IN 15 downto 2 loop
    tmp:=tmp and cereg0(i);
  end loop;
  cereg0_h<=not tmp;---计数器当前计数值15 到2位为0
 end process ce;
--**************************************************
cereg0_2<=cereg0_h and cereg0_h and cereg0(1) and  not cereg0(0);---当前计数值为2
cereg0_10<=cereg0_h and not cereg0(1);  ---当前计数值为1或0
cereg0_1<=cereg0_10 and cereg0(0);   ---当前计数值为1
cereg0_0<=cereg0_10 and  not cereg0(0);  ---当前计数值为0
--mode0 change 方式0计数值为1时OUT翻转
mode0_0<=not (ct0_con(1)or ct0_con(2) or ct0_con(3));
mode0_0c<=mode0_0 and cereg0_1;
--mode2 change 方式2计数值为1或2时OUT翻转
mode0_2<=not ct0_con(1) and ct0_con(2);
mode0_2c<=mode0_2 and (cereg0_2 or cereg0_1);
--mode3 change  方式3计数值为0时OUT翻转
mode0_3<=ct0_con(1) and ct0_con(2);
mode0_3c<=mode0_3 and cereg0_0;
--all change
out0_c<= mode0_0c or mode0_2c or mode0_3c;
--**************************************************

-----REFILL BLOCK 计数值重装,与方式2和3配合
ref_0: PROCESS(clk0)
 BEGIN
   IF counter0_enable='0' THEN --准备初始时,准备装填
    ref0<='1';
   ELSIF clk0'event AND clk0='0' then
   IF ref0='1' THEN    --完成装填时停止装填
   ref0<='0';
   elsif ct0_con(2)='1' AND cereg0_2='1' THEN
  --在方式2和3计数到2后在下一个时钟下降沿将REF0置为1
      ref0<='1';
   end if;
     end if;
end process ref_0;
--*********************************************************
-------WAIT BLOCK 挂起信号控制 与方式0配合

wait_0: PROCESS (clk0)
 BEGIN
  IF counter0_enable='0' THEN
    wait0<='0';
  ELSIF clk0'event and clk0='0' then
    IF mode0_0='1' AND cereg0_0='1' AND gate0='1' AND ref0='0'
    THEN wait0<='1';
--计数到0,方式0,不重新装填且GATE为1时设置wait,挂起计数器
    END IF;
  END IF;
 END PROCESS wait_0;
--***************************************************

-----------OUT BLOCK 输出信号控制 三种方式共有
out_0: PROCESS(clk0)
 BEGIN
  IF counter0_enable='0' THEN
   out0<=ct0_con(3) or ct0_con(2) or ct0_con(1);
  ELSIF clk0'event and clk0='0' THEN
   IF gate0='1' and out0_c='1' THEN
   out0<=not out0;---GATE有?且OUT应该发生变化时,OUT发生变化
   END IF;
  END IF;
 END PROCESS out_0;
--******************************************************

---COUNTER CONTROL BLOCK 计数执行模块,三种方式共有
PROCESS(CLK0)
 BEGIN
IF counter0_enable='0'THEN
cereg0<="1111111111111111";--在计数器未运行前初始化
ELSIF (clk0'event and clK0='0') THEN
IF ref0='1' THEN
cereg0<=crreg0;   --计数值装填
  ELSIF gate0='1' AND wait0='0' THEN
    IF  ct0_con(0)='1' AND cereg0(3 downto 0)=0 THEN
    cereg0(3 downto 1)<="100";
    cereg0(0)<=NOT mode0_3;
    ELSE
    IF mode0_3='0' THEN
    cereg0(3 downto 0)<=cereg0(3 downto 0)-1;
    ELSE
    IF NOT (cereg0(0) and out0)='1' THEN
    cereg0(3 downto 1)<=cereg0(3 downto 1)-1;
    END IF;
    cereg0(0)<='0';
    END IF;
    END IF;
   if  cereg0(3 downto 0)=0 then
   if ct0_con(0)='1'and cereg0(7 downto 4)=0 then
   cereg0(7 downto 4)<="1001";
   else cereg0(7 downto 4)<=cereg0(7 downto 4)-1;
   end if;
   end if;
    IF cereg0(7 downto 0)=0 THEN
    IF ct0_con(0)='1' AND cereg0(11 downto 8)=0 THEN
    cereg0(11 downto 8)<="1001";
    ELSE cereg0(11 downto 8)<=cereg0(11 downto 8)-1;
    END IF ;
    END IF;
   if cereg0(11 downto 0)=0 then
   if ct0_con(0)='1' and cereg0(15 downto 12)=0 then
   cereg0(15 downto 12)<="1001";
   else cereg0(15 downto 12)<=cereg0(15 downto 12)-1;
   end if;
   end if;
END IF;
END IF;
END PROCESS;
END i8253;
jec017
驱动太牛
驱动太牛
  • 注册日期2002-08-22
  • 最后登录2008-01-09
  • 粉丝0
  • 关注0
  • 积分91分
  • 威望10点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-09-04 11:13
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CTER IS
PORT(rd,wr,cs,a1,a0:IN STD_LOGIC;
 d  :inout std_logic_vector(7 downto 0);
 out0 :inout STD_LOGIC;
 clk0:in std_logic;
 gate0:in std_logic);
end cter;
ARCHITECTURE i8253 OF CTER IS
SIGNAL internal_bus_in :std_logic_vector(7 downto 0);
--总线输入锁存
SIGNAL internal_bus_out:std_logic_vector(7 downto 0);
--总线输出锁存
SIGNAL ct0_con:std_logic_vector(5 downto 0);
--计数器控制字
SIGNAL crreg0:std_logic_vector(15 downto 0);
--计数器初使值          
SIGNAL olreg0:std_logic_vector(15 downto 0);
--计数器锁存        
SIGNAL cereg0:std_logic_vector(15 downto 0);
--计数当前值
SIGNAL h1:std_logic;--高/低字节的读写指示
SIGNAL h1_edge:std_logic;
SIGNAL COUNTER0_ENABLE:std_logic;--计数器使能
SIGNAL wait0:std_logic;--计数器挂起
SIGNAL ref0:std_logic;--计数器重装
SIGNAL cereg0_h,cereg0_10,cereg0_0,cereg0_1,cereg0_2:std_logic;
--计数当前值指示信号
SIGNAL mode0_0,mode0_2,mode0_3:std_logic;
--当前工作方式指示信号
SIGNAL mode0_0c,mode0_2c,mode0_3c,out0_c:std_logic;
--OUT0信号翻转指示信号
BEGIN
--************************************************************************

----- DATA CATHE BLOCK 数据缓存
DATA_CATHE:process(wr,rd,cs)
begin
 if (wr='0'and cs='0') then
  internal_bus_out<=d;
 elsif (rd='0' and cs='0')then
  d<=internal_bus_in;
 else
  d<="ZZZZZZZZ";
 END IF;
end process DATA_CATHE;
--*********************************************************************

-------WRITE CTR BLOCK 写控制寄存器或计数器0
CTR_REG: process(wr,cs)
variable wr_con_flag:std_logic_vector(7 downto 0);
variable ad   :std_logic_vector(1 downto 0);
BEGIN
if (wr='0'and cs ='0') then
wr_con_flag:=d(7 downto 0);
ad:=a1 & a0;
end if;
IF (wr'event and wr='1') then
 IF (ad="11" AND cs='0')then --选择控制寄存器写
  IF wr_con_flag(5 downto 4)/="00" then--不是锁存
   case wr_con_flag(7 downto 6) is
   WHEN "00"=>ct0_con<=internal_bus_out(5 downto 0);
   counter0_enable<='0';-----计数器0禁止
   WHEN others =>NULL;
   END CASE;      
  ELSE      -----锁存模式
   case wr_con_flag(7 downto 6) is
   WHEN "00"=>olreg0<=cereg0;
   WHEN OTHERS=> NULL;
   end case ;
  END IF;
 ELSIF ad="00" and cs='0' THEN-------选择计数器0
   case ct0_con(5 downto 4) IS
   WHEN "01"=>        
    crreg0(7 downto 0)<=internal_bus_out;--只写低8位
    crreg0(15 downto 8)<="00000000";
    counter0_enable<='1';
   WHEN "10"=>
    crreg0(15 downto 8)<=internal_bus_out;--只写高8位
    crreg0(7 downto 0)<="00000000";
    counter0_enable<='1';
   WHEN "11"=>
    IF h1='0' then
    crreg0(7 downto 0)<=internal_bus_out;---先低后高
    ELSIF h1= '1' THEN
    crreg0(15 downto 8)<=internal_bus_out;
    counter0_enable<='1';
    END IF;
   WHEN OTHERS =>
   END case;
  END IF;
 END IF;
END PROCESS CTR_REG;
--**********************************************************************

-------HIGH/LOW TURN  生成高低字节顺序信号
HL_CTR:PROCESS(h1_edge,cs,a1,a0)----高低字节读写指示
  begin
   IF(a1='1' and a0='1' and cs='0') THEN
     h1<='1';      
   --h1初始化
   ELSIF h1_edge'event and h1_edge='1' THEN
   --读/写信号下降沿h1翻转
     h1<= not h1;
   END IF;
  END process HL_CTR;
h1_edge<=rd xor wr;

--******************************************************************
--------READ DATA BLOCK 读计数值
value_RD:PROCESS(a1,a0,h1)
  BEGIN
--IF (rd'event and rd='1') THEN
 IF (cs='0' and a1='0' and a0='0') THEN
   IF ct0_con(5 downto 4)="01" then
  internal_bus_in<=olreg0(7 downto 0);
   ELSIF ct0_con(5 downto 4)="10" THEN
  internal_bus_in<=olreg0(15 downto 8);
   ELSIF ct0_con(5 downto 0)="11" THEN
     if h1='0' then
  internal_bus_in<=olreg0(7 downto 0);
  elsif h1='1' then
  internal_bus_in<=olreg0(15 downto 0);
  end if;
   END IF;
 END IF;
--END IF;
END PROCESS value_RD;
--******************************************************************

------value OF CE BLOCK 判断当前计数值
ce:PROCESS(cereg0)
 variable tmp:std_logic;
 BEGIN
   tmp:='0';
   for i IN 15 downto 2 loop
    tmp:=tmp and cereg0(i);
  end loop;
  cereg0_h<=not tmp;---计数器当前计数值15 到2位为0
 end process ce;
--**************************************************
cereg0_2<=cereg0_h and cereg0_h and cereg0(1) and  not cereg0(0);---当前计数值为2
cereg0_10<=cereg0_h and not cereg0(1);  ---当前计数值为1或0
cereg0_1<=cereg0_10 and cereg0(0);   ---当前计数值为1
cereg0_0<=cereg0_10 and  not cereg0(0);  ---当前计数值为0
--mode0 change 方式0计数值为1时OUT翻转
mode0_0<=not (ct0_con(1)or ct0_con(2) or ct0_con(3));
mode0_0c<=mode0_0 and cereg0_1;
--mode2 change 方式2计数值为1或2时OUT翻转
mode0_2<=not ct0_con(1) and ct0_con(2);
mode0_2c<=mode0_2 and (cereg0_2 or cereg0_1);
--mode3 change  方式3计数值为0时OUT翻转
mode0_3<=ct0_con(1) and ct0_con(2);
mode0_3c<=mode0_3 and cereg0_0;
--all change
out0_c<= mode0_0c or mode0_2c or mode0_3c;
--**************************************************

-----REFILL BLOCK 计数值重装,与方式2和3配合
ref_0: PROCESS(clk0)
 BEGIN
   IF counter0_enable='0' THEN --准备初始时,准备装填
    ref0<='1';
   ELSIF clk0'event AND clk0='0' then
   IF ref0='1' THEN    --完成装填时停止装填
   ref0<='0';
   elsif ct0_con(2)='1' AND cereg0_2='1' THEN
  --在方式2和3计数到2后在下一个时钟下降沿将REF0置为1
      ref0<='1';
   end if;
     end if;
end process ref_0;
--*********************************************************
-------WAIT BLOCK 挂起信号控制 与方式0配合

wait_0: PROCESS (clk0)
 BEGIN
  IF counter0_enable='0' THEN
    wait0<='0';
  ELSIF clk0'event and clk0='0' then
    IF mode0_0='1' AND cereg0_0='1' AND gate0='1' AND ref0='0'
    THEN wait0<='1';
--计数到0,方式0,不重新装填且GATE为1时设置wait,挂起计数器
    END IF;
  END IF;
 END PROCESS wait_0;
--***************************************************

-----------OUT BLOCK 输出信号控制 三种方式共有
out_0: PROCESS(clk0)
 BEGIN
  IF counter0_enable='0' THEN
   out0<=ct0_con(3) or ct0_con(2) or ct0_con(1);
  ELSIF clk0'event and clk0='0' THEN
   IF gate0='1' and out0_c='1' THEN
   out0<=not out0;---GATE有?且OUT应该发生变化时,OUT发生变化
   END IF;
  END IF;
 END PROCESS out_0;
--******************************************************

---COUNTER CONTROL BLOCK 计数执行模块,三种方式共有
PROCESS(CLK0)
 BEGIN
IF counter0_enable='0'THEN
cereg0<="1111111111111111";--在计数器未运行前初始化
ELSIF (clk0'event and clK0='0') THEN
IF ref0='1' THEN
cereg0<=crreg0;   --计数值装填
  ELSIF gate0='1' AND wait0='0' THEN
    IF  ct0_con(0)='1' AND cereg0(3 downto 0)=0 THEN
    cereg0(3 downto 1)<="100";
    cereg0(0)<=NOT mode0_3;
    ELSE
    IF mode0_3='0' THEN
    cereg0(3 downto 0)<=cereg0(3 downto 0)-1;
    ELSE
    IF NOT (cereg0(0) and out0)='1' THEN
    cereg0(3 downto 1)<=cereg0(3 downto 1)-1;
    END IF;
    cereg0(0)<='0';
    END IF;
    END IF;
   if  cereg0(3 downto 0)=0 then
   if ct0_con(0)='1'and cereg0(7 downto 4)=0 then
   cereg0(7 downto 4)<="1001";
   else cereg0(7 downto 4)<=cereg0(7 downto 4)-1;
   end if;
   end if;
    IF cereg0(7 downto 0)=0 THEN
    IF ct0_con(0)='1' AND cereg0(11 downto 8)=0 THEN
    cereg0(11 downto 8)<="1001";
    ELSE cereg0(11 downto 8)<=cereg0(11 downto 8)-1;
    END IF ;
    END IF;
   if cereg0(11 downto 0)=0 then
   if ct0_con(0)='1' and cereg0(15 downto 12)=0 then
   cereg0(15 downto 12)<="1001";
   else cereg0(15 downto 12)<=cereg0(15 downto 12)-1;
   end if;
   end if;
END IF;
END IF;
END PROCESS;
END i8253;
 
游客

返回顶部