阅读:1298回复:2
高手大哥帮帮忙,帮我看看我的程序问题出在哪?
高手大哥帮帮忙,帮我看看我的程序问题出在哪?
明天要验收了,搞不定就死了,一个设计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; |
|
沙发#
发布于: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; |
|
板凳#
发布于:2004-09-04 11:13
LIBRARY IEEE; |
|