硬件平台:44b0+fpga.
44b0和fpga之间通过总线连接,把fpga映射至BANK4,现在在fpga中编写了一个简单的16位计数器,对外部8路输入脉冲计数。把八个计数器映射到了一个寄存器,并给它们分配地址。
现在出现奇怪的问题如下:
1、我现在测第三通道PUL3输入脉冲频率,第一次执行读操作,读出来的值是正确的,可是我第二次、第三次执行读操作(在44b0程序里,一次读操作的语句为:pulse = PULSE3;其中PULSE3是对计数器对应地址空间取值),即使改变了实际输入信号的频率,读出来的值也不改变,还是第一次的值。这时按下复位键后,第一次读数正确,后面又不改变数值,一直是第一次的读数。
2、更奇怪现象是: 比如我用JTAG下载VHDL程序或者按下复位键后,我先测第三通道的输入脉冲,这时会出现1所述现象。此时,如果我还不按复位键,而把信号发生器的输出脉冲接到第五通道上,然后再读第五通道的数值,这时发现读出来的数值是0。不论我怎么改变实际输入频率,读第五通道的数值总是0。这时如果复位,再读第五通道数值,第一次是正确的,后面又不正确。如果此时我把信号发生器输出接到第三通道,发现读第三通道数值又变为0了。
3、我开始怀疑原因是:读了一个通道数值后,数据总线上的值一直不变导致1所述现象。于是执行完脉冲测试子函数后,我去执行其它子函数,比如灯测试程序或者pwm输出程序,这时总得改变数据总线上的数据了吧?然后又返回去执行脉冲计数测试函数,发现这时的值还是没有变化。这是不是说明应该不是44b0程序的问题?
我觉得可能还是44b0和fpga读写的接口有问题。数据总线是不是得加三态门控制啊?从上面的现象来看,脉冲计数模块对外输出只是第一次有效,后面的对外输出一直是不变化的,除非来了复位信号
相应VHDL程序如下:
文件counter_control.vhd:
--使用测频法进行计数,该模块用于产生标准闸门信号,同时处理与单片机的接口时序 --闸门宽度可以是1s,也可是0.1s,0.01s,0.001s --这里每隔1s输出一个脉冲(宽度为0.1us),由脉冲的上升沿触发开始计数
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY counter_control IS  ORT ( reset :in std_logic;---active is low d :in std_logic_vector(15 downto 0);--闸门时间到时,锁存计数值 clk :in std_logic;--外部输入时钟 gate ut std_logic;--标准闸门信号时钟,可以是1HZ,10HZ,100HZ,1000HZ等 counter_cs:in std_logic;--各个计数器的片选信号,实际上由各个计数器寄存器的地址译码所得 data_out ut std_logic_vector(15 downto 0)--计数器输出缓冲器 ); END counter_control;
--***************************************************** ARCHITECTURE rtl OF counter_control IS signal cnt : INTEGER RANGE 0 TO 10000000;--std_logic_vector(24 downto 0);用于分频得到标准闸门信号 signal temp1 : std_logic_vector(15 downto 0); signal temp2 : std_logic; --******************************************************* BEGIN process(clk) begin if(reset = '0') then--复位计数器 cnt <= 10000000; temp1 <= (OTHERS =>'0'); elsif(clk'event and clk='1') then if(cnt = 0)then--满1秒 cnt <= 10000000; temp1 <= d; temp2 <= '1'; else cnt <= cnt - 1; temp2 <= '0'; end if; end if; end process;
data_out <= temp1 when counter_cs='0' else (OTHERS => 'Z');--counter_cs由fpga片选和计数器地址、读允许信号译码得到 gate <= temp2;
END rtl;
文件counter.vhd:
--16位加法计数器 --高电平脉冲清零计数器 --低电平开始计数
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all;
ENTITY counter IS  ORT ( pulse :in std_logic;--被测信号 clr :in std_logic;--计数器清零信号 counter_output ut std_logic_vector(15 downto 0)--计数值输出 ); END counter;
--***************************************************** ARCHITECTURE rtl OF counter IS signal temp0 : std_logic_vector(15 downto 0); --******************************************************* BEGIN process(pulse,clr) begin if(clr = '1') then--在clr=‘1’的时候进行计数器清零 temp0 <= (OTHERS =>'0'); elsif(pulse'event and pulse = '1') then temp0 <= temp0+1; end if; end process;
counter_output <= temp0; END rtl;
还有一个顶层文件,用于把上面两个模块连接起来。发在另一个贴子里,这里发不下。
请各位朋友帮忙看看,这是毕业设计最重要的一部分,现在卡在这上面不能往下继续!
谢谢
|