打印

基于CPLD的测频程序的问题,有做过的高手来看下.............

[复制链接]
2107|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jzw1987|  楼主 | 2008-11-17 16:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  我用VHDL写了一个等精度测频的程序,其中标准频率用的是100M ,待测频率为32768左右,对两路待测频率同时测量.用的是7160SCL84-6的片子,可在实际使用时发现隔几秒就会跳出一个错值出来,而且也没有精度也没有想像中的高.要当测量时间到200毫秒时,测得结果才会比较稳定(比理论上的差大多了).怀疑是对100M频率计数的程序有点问题.第一次接触VHDL语言,有点搞不清楚,希望高手指教.
程序如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity four0ut is
    port(
    f0,fx,fy,rs,en : in std_logic;      --    f0:标准频率  fx:待测频率1  fy待测频率2  rs:清零程序  en:允许信号
    choose: in std_logic_vector (4 downto 0);  --输出选择信号
    output: out std_logic_vector (7 downto 0));  --输出信号
    end four0ut;
architecture behave of four0ut is

signal out_fx0,out_fx1,out_fx2,out_fx3  :std_logic_vector (3 downto 0);              --待测频率1计数存放
signal out_fy0,out_fy1,out_fy2,out_fy3   :std_logic_vector (3 downto 0);              --待测频率2计数存放
 signal  out_f00,out_f01,out_f02,out_f03,out_f04,out_f05,out_f06   :std_logic_vector (3 downto 0);       --待测频率1对应的标准频率计数存放
 signal out_f10,out_f11,out_f12,out_f13,out_f14,out_f15,out_f16   :std_logic_vector (3 downto 0);       --待测频率2对应的标准频率计数存放

    signal star1,star2: std_logic; --两路信号开始计数的标志位(类似用来实现D触发器的功能)                             
    begin
--*********以下是第一路频率的测量部分************************

   process(fx,rs,en)
        begin 
        if(rs='0') then 
             star1 <= '0';
            out_fx0 <="0000"; out_fx1 <="0000"; out_fx2 <="0000";          out_fx3 <="0000"; 
            elsif(fx' event and fx = '1') then 
               if(en='1') then
                    if (out_fx0 = 15)  then   out_fx0 <="0000";
                    if (out_fx1 = 15)  then   out_fx1 <="0000";
                     if (out_fx2 = 15)  then   out_fx2 <="0000";
                    if (out_fx3 = 15)  then   out_fx3 <="0000";
                       else out_fx3 <= out_fx3 + 1 ;
                       end if;
                     else out_fx2 <= out_fx2 + 1 ;
                     end if;
                     else out_fx1 <= out_fx1 + 1 ;
                    end if;
                    else out_fx0 <= out_fx0 + 1 ;
                  end if;                                            
                    star1 <= '1';
                elsif(star1 ='1') then
                   star1 <= '0';
                end if; 
            end if;
     end process;

  
--**************以下是第二路频率的测量部分*************************

 process(fy,rs,en)
        begin 
        if(rs='0') then 
             star2 <= '0';
             out_fy0 <="0000"; out_fy1 <="0000"; out_fy2 <="0000";          out_fy3 <="0000"; 
            elsif(fy' event and fy = '1') then 
               if(en='1') then
               if (out_fy0 = 15)  then   out_fy0 <="0000";
               if (out_fy1 = 15)  then   out_fy1 <="0000";
                if (out_fy2 = 15)  then   out_fy2 <="0000";
                if (out_fy3 = 15)  then   out_fy3 <="0000";
                else out_fy3 <= out_fy3 + 1 ;
                  end if;
            else out_fy2 <= out_fy2 + 1 ;
                 end if;
                else out_fy1 <= out_fy1 + 1 ;
               end if;
                  else out_fy0 <= out_fy0 + 1 ;
                  end if;                                            
                    star2 <= '1';
                elsif(star2 ='1') then
                   star2 <= '0';
                end if; 
            end if;
     end process;



--*************以下是标准频率的测量部分**********************

   process(f0,rs,star1)
        begin
        if(rs = '0') then 
            out_f00 <="0000"; out_f01 <="0000"; out_f02 <="0000"; out_f03 <="0000"; out_f04 <="0000"; out_f05 <="0000"; out_f06<="0000";
            elsif(f0' event and f0 = '1') then
                if(star1 = '1') then
                if (out_f00 = 15)  then   out_f00 <="0000";
                if (out_f01 = 15)  then   out_f01 <="0000";
                 if (out_f02 = 15)  then   out_f02 <="0000";
                  if (out_f03 = 15)  then   out_f03 <="0000";
                  if (out_f04 = 15)  then   out_f04 <="0000";
                 if (out_f05 = 15)  then   out_f05 <="0000";
                 if(out_f06 = 15 ) then  out_f06 <="0000";
                  else out_f06 <= out_f06+1 ;
                  end if;
                 else out_f05 <= out_f05 + 1 ;
                  end if;
                  else out_f04 <= out_f04 + 1 ;
                 end if;
                 else out_f03 <= out_f03 + 1 ;
                    end if;
                 else out_f02 <= out_f02 + 1 ;
                   end if;
                  else out_f01 <= out_f01 + 1 ;
                  end if;
                  else out_f00 <= out_f00 + 1 ;
                     end if; 
                end if;
              end if;
            end process;

   process(f0,rs,star2)
        begin
             if(rs = '0') then  
             out_f10 <="0000"; out_f11 <="0000"; out_f12 <="0000";         out_f13 <="0000"; out_f14 <="0000"; out_f15 <="0000";        out_f16<="0000";
             elsif(f0' event and f0 = '1') then
             if(star2 = '1') then
             if (out_f10 = 15)  then   out_f10 <="0000";
             if (out_f11 = 15)  then   out_f11 <="0000";
             if (out_f12 = 15)  then   out_f12 <="0000";
             if (out_f13 = 15)  then   out_f13 <="0000";
             if (out_f14 = 15)  then   out_f14 <="0000";
             if (out_f15 = 15)  then   out_f15 <="0000";
             if(out_f16 = 15 ) then  out_f16 <="0000";
             else out_f16 <= out_f16+1 ;
             end if;
             else out_f15 <= out_f15 + 1 ;
              end if;
             else out_f14 <= out_f14 + 1 ;
             end if;
             else out_f13 <= out_f13 + 1 ;
             end if;
              else out_f12 <= out_f12 + 1 ;
               end if;
              else out_f11 <= out_f11 + 1 ;
               end if;
             else out_f10 <= out_f10 + 1 ;
              end if; 
                end if;
            end if;
     end process;

--*******以下是输出部分程序***************************

     process(choose)
        begin
      case choose is

--*****************以下是第一组测量结果的输出 *******                   when "00111" => output(7 downto 4) <= "0000";
                            output(3 downto 0) <= out_f06;
            when "00100" => output(7 downto 4) <= out_f05 ;
                           output(3 downto 0) <= out_f04 ;
            when "00101" => output(7 downto 4) <= out_f03 ;
                           output(3 downto 0) <= out_f02 ;
            when "00110" => output(7 downto 4) <= out_f01 ;
                           output(3 downto 0) <= out_f00 ;
       

            when "00001" => output(7 downto 4) <= out_fx3 ;
                           output(3 downto 0) <= out_fx2 ;
            when "00010" => output(7 downto 4) <= out_fx1 ;
                           output(3 downto 0) <= out_fx0 ;

--*********以下是第二组测量结果的输出*********************

            when "01111" =>  output(7 downto 4) <= "0000";
                            output(3 downto 0) <= out_f16;
            when "01100" => output(7 downto 4) <= out_f15 ;
                           output(3 downto 0) <= out_f14 ;
            when "01101" => output(7 downto 4) <= out_f13 ;
                           output(3 downto 0) <= out_f12 ;
            when "01110" => output(7 downto 4) <= out_f11 ;
                           output(3 downto 0) <= out_f10 ;

            when "01001" => output(7 downto 4) <= out_fy3 ;
                           output(3 downto 0) <= out_fy2 ;
            when "01010" => output(7 downto 4) <= out_fy1 ;
                           output(3 downto 0) <= out_fy0 ;

          when others => output <= "ZZZZZZZZ";
         end case;                     
      end process;
     end behave;

相关帖子

沙发
jzw1987|  楼主 | 2008-11-18 14:26 | 只看该作者

有点不太明白

1. 用f0来监控fx,fy是什么意思?是在f0上升沿的时候才去查看fx和fy是否为上升沿吗? 这样会不会出现漏掉的情况,比如说在f0脉冲中间的时候出现fx,fy的上升沿怎么办呢?

2. 因为要求测量时间是可调的,所以不能分内部方法.  我现在用的是把en接到fx,和fy组成的D触发器中,应该是可以使en的准确性提高.

3. 寄存器锁存在VHDL中是怎么操作的?(不好意思,刚接触,有些东西不太懂),我现在是在计数完成后,由cpu发出的choose信号来控制CPLD的输出.

4. 输入: 每个输入信号(rst,en)都要2级D触发器和f0同步,还是一样,不知道同步怎么实现.
  谢谢解答....

使用特权

评论回复
板凳
jzw1987|  楼主 | 2008-11-22 08:42 | 只看该作者

谢谢解答....

使用特权

评论回复
地板
jian0052| | 2008-12-4 10:30 | 只看该作者

Quartus II的仿真问题

求教,本人新学CPLD不久,用Verilog编写了一段Quartus II程序,通过单片机和CPLD对继电器开关进行开合控制,CPLD选用的是EPM7512AETC144-10。在仿真的时候,功能仿真出现错误,时序仿真确是正确的,让我比较困惑。求教各位前辈高手指点指点。 
程序如下: 
module zc(in,data,out,rst); 
input data,rst; 
input [1:0]in; 
output [3:0]out; 
reg [3:0]out,add,add1,latch; 


always@(in or data or rst or latch ) 
        begin 
        if(rst) 
                begin 
                add  = 4'b1111; 
                add1 = 4'b1111; 
                latch= 4'b1111; 
                out  = 4'b1111; 
                end 
        else 
                begin 
                        if(!data)  
                                begin 
                                        case(in) 
                                        2'b00:add=4'b1110; 
                                        2'b01:add=4'b1101; 
                                        2'b10:add=4'b1011; 
                                        2'b11:add=4'b0111; 
                                        endcase 
                                        add1=add&latch; 
                                        //latch=add1; 
                                        out[0]=add1[0]?1'b1:1'b0; 
                                        out[1]=add1[1]?1'b1:1'b0; 
                                        out[2]=add1[2]?1'b1:1'b0; 
                                        out[3]=add1[3]?1'b1:1'b0; 
                                        latch=out; 
                                end 
                        else 
                                begin 
                                        case(in) 
                                        2'b00:begin add=4'b1110;end 
                                        2'b01:begin add=4'b1101;end 
                                        2'b10:begin add=4'b1011;end 
                                        2'b11:begin add=4'b0110;end 
                                        endcase 
                                        out[0]=add[0]?latch[0]:1'b1; 
                                        out[1]=add[1]?latch[1]:1'b1; 
                                        out[2]=add[2]?latch[2]:1'b1; 
                                        out[3]=add[3]?latch[3]:1'b1; 
                                        latch=out; 
                                end 
                                         
                end 
        end 
endmodule

综合编译有两个警告:
Warning: Verilog HDL Always Construct warning at zc.v(8): variable add1 may not be assigned a new value in every possible path through the Always Construct.  Variable add1 holds its previous value in every path with no new value assignment, which may create a combinational loop in the current design. 
Warning: Verilog HDL Always Construct warning at zc.v(8): variable latch may not be assigned a new value in every possible path through the Always Construct.  Variable latch holds its previous value in every path with no new value assignment, which may create a combinational loop in the current design.  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

7

帖子

0

粉丝