打印

vhdl可以实现9分频吗?

[复制链接]
4133|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
清风致影|  楼主 | 2009-9-18 16:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
lelee007| | 2009-9-19 20:41 | 只看该作者
当然可以实现

但是具体综合结果要看你的库好不好使,一般免费的库估计不一定能综合出来

还有奇数分频其实非常简单,很多种方式都可以做

俺有个移位寄存器的实现方法,原创

你到网上找一下,用触发器搭的电路也有几种

使用特权

评论回复
板凳
zgl7903| | 2009-9-21 21:36 | 只看该作者
下面模块里的两种方式都可以,但是实现方式有所不同
第一种利用输入和输入的异或关系补脉冲的方式
第二种倍频计数方式

module CLK9 (pReset, inClk, outClk);
  input pReset; //reset
  input inClk;  //input clk
  output [2:1]outClk; //output clk
  
  reg [2:1]outClk;
  
////////////////////////////////////  
  reg [3:0]count1;  
  wire clkW1 = inClk ^ outClk[1];
  always @(posedge pReset or posedge clkW1)
    begin
      if(pReset)
        begin
          count1 <= 0;
          outClk[1] <= 1'b0;
        end
      else
        begin
          if(count1 >= 4)
            begin
              count1 <= 0;
              outClk[1] <= !outClk;
            end
          else
            begin
              count1 <= count1 + 1'b1;        
            end
        end
    end  
  
  reg [4:0]count2;      
  reg clk2;  wire clkW2 = inClk ^ clk2;
  always @(posedge pReset or posedge clkW2)
    begin
      if(pReset)
        begin
          clk2 <= 1'b0;
          count2 <= 0;
          outClk[2] <= 1'b0;
        end
      else
        begin
          clk2 <= inClk;
          if(count2 >= 8)
            begin
              count2 <= 0;
              outClk[2] <= !outClk[2];
            end
          else
            begin
              count2 <= count2 + 1'b1;
            end
        end
    end  
endmodule

使用特权

评论回复
地板
mr.king| | 2009-9-22 19:25 | 只看该作者
楼主是想要50%占空的?如果不是,基本计数器就可以了

使用特权

评论回复
5
清风致影|  楼主 | 2009-9-23 10:57 | 只看该作者
我觉得分频只能分2的倍数频, 奇数分频不好分。

使用特权

评论回复
6
sondj| | 2009-12-7 11:26 | 只看该作者
可以奇数50%占空比分频

使用特权

评论回复
7
sleepybear| | 2009-12-7 12:18 | 只看该作者
本帖最后由 sleepybear 于 2009-12-7 13:12 编辑

前一阵正好专门研究过这个问题。用逻辑是可以实现任意比的分频的,二的整数次幂的分频只是一种特殊情况而已。当然,前提是时序满足要求,可用。否则,还是用专用的PLL/DLL来做更好些。
核心思想无非就是构建一个计数器,从计数器的某一位抽头。要N分频,就用模N的计数器。计数器计数植可以不规则。
以五分频为例,可以构建以下模五计数循环:
000—001—011—111—110—000—……
然后从bit2来抽头(也可从其他bit抽头,相应改变计数循环就行),其变换规律就是0-0-0-1-1。这就是五分频。要占空比50%,可以用另一个时钟沿打一下(比如计数器用的是时钟上跳沿,就可以用下跳沿打一下),再和原信号相与或者相或一下就行了。当然,前提还是要满足是许要求,一般FPGA设计是不提倡使用双沿的。另外,改变计数循环,可以相应调整占空比,比如可以搞0-1-1-1-1-0/0-0-1-1-1-0等等。
七分频/九分频……的道理相同,只需相应构建计数器,选择好抽头即可。计数器逻辑可用case语句来控制其循环
以上是奇数倍分频,其实偶数倍同理(这里专指非2的整数幂的分频)。比如六分频,可以构建计数器:
000—001—011—111—110—100—000……,以bit0为抽头,其变换规律为:0-1-1-1-0-0-……

使用特权

评论回复
8
sleepybear| | 2009-12-7 13:17 | 只看该作者
0000—0001—0011—0111—1111—1101—1100—1000—1010—0000……
这个循环,用bit0抽头,就是九分频。用另一个时钟沿打一下,再与之相与,就是50%占空比。

使用特权

评论回复
9
一只小蜗牛| | 2009-12-7 15:20 | 只看该作者
睡熊的思维不错,赞一个。

使用特权

评论回复
10
一只小蜗牛| | 2009-12-7 16:29 | 只看该作者
突然玩心大起,我给大家写了一个参数化的50%占空比的模块。从0-255 皆可,当然了,你可以轻而易举地把它扩大到更大的范围。写得匆忙,没写注释,不要见笑。一个重要建议是:如果用分频器产生的频率时(这已经是异步的了)最好先把他输出到外面,在从PAD环回来,这样可以避免FPGA神经错乱。不过不是迫不得已,我既不建议使用下降沿,也不建议使用异步设计。还是同步设计稳定。
`timescale 1ns/10ps
module divider (
   clock  ,   // input clock
   resetb ,   // input reset
   freqout    // output divided frequency
);

parameter freq_div = 2 ;

input    clock   ;
input    resetb  ;
output   freqout ;

wire   clock   ;
wire   resetb  ;
wire   freqout ;

reg   [7:0] counter    ;
wire  [7:0] freq_divid ;
wire  [7:0] freq_div2  ;
reg         freq_even  ;
reg         freq_odd0   ;
reg         freq_odd1   ;
wire        freq_odd   ;


assign freq_divid = freq_div ;
assign freq_div2  = freq_divid >> 1;

always @(posedge clock or negedge resetb )
begin
   if ( ~ resetb )
   begin
      counter <= 8'h00 ;
   end
   else if ( counter == freq_div - 1 )
   begin
     counter <= 8'h00 ;
   end
   else
   begin
     counter <= counter + 1'b1 ;
   end
end

always @(posedge clock or negedge resetb )
begin
   if ( ~ resetb )
   begin
      freq_even <= 1'b0 ;
   end
   else if ( freq_divid[0] == 1'b0 )
   begin
      if ( counter == freq_div2 - 1 )
      begin
         freq_even <= 1'b1 ;
      end
      else if ( counter == freq_div - 1 )
      begin
         freq_even <= 1'b0 ;
      end
   end
   else
   begin
      freq_even <= 1'b0 ;
   end
end

always @(posedge clock or negedge resetb )
begin
   if ( ~ resetb )
   begin
      freq_odd0 <= 1'b0 ;
   end
   else if ( freq_divid[0] == 1'b1 )
   begin
      if ( counter == freq_div2 - 1 )
      begin
         freq_odd0 <= 1'b1 ;
      end
      else if ( counter == freq_div - 1 )
      begin
         freq_odd0 <= 1'b0 ;
      end
   end
   else
   begin
      freq_odd0 <= 1'b0 ;
   end
end

always @(negedge clock or negedge resetb )
begin
   if ( ~ resetb )
   begin
      freq_odd1 <= 1'b0 ;
   end
   else
   begin
      freq_odd1 <= freq_odd0 ;
   end
end

assign freq_odd = freq_odd0 & freq_odd1 ;

assign freqout = ( freq_div <= 1 ) ? clock : freq_odd | freq_even ;


endmodule

使用特权

评论回复
11
一只小蜗牛| | 2009-12-7 16:33 | 只看该作者
大家尽可以放心使用,这是我刚花了将近一个小时(写代码+验证)的原创作品,版权免费!:lol

使用特权

评论回复
12
sleepybear| | 2009-12-7 18:53 | 只看该作者
蜗牛的这个好。顶一个。

使用特权

评论回复
13
一只小蜗牛| | 2009-12-8 09:36 | 只看该作者
说实话,这个模型是因睡熊而写的,一般情况下写代码到三四年的时候就会到达睡熊那样的境界(努力的话),即在某些代码和局部电路上积累了很多。这是任何人必走的一个过程,但是国内这方面的教育比较差,很多人走到此便停住了脚步。大家都经常说" top-bottom" 设计,模块化设计,等等。以睡熊为例吧,他的想法都是“汇编“的想法,这在设计较小的时候,没任何问题,小设计用汇编,即快又省,挺好的,但设计大了,你迟早会转到c上来。说到c与汇编的区别大家都清楚得很,就不说了。那怎样才可以实现“top-bottom"设计呢?并不是说一个设计分成几个模块来写就叫模块化设计了,这是一种思维方式,你眼里不再有代码,不再有0,1,有的只是一个一个的功能模块,对任何一件事情你都可以用模块的形式重述,千万不要再想什么电路。如果有几十个分频器,你还老想着抽头,头不抽大了才怪呢。(我知道我说这句话很危险,如果你达不到睡熊对代码的那种熟练程度,会写出上帝都看不懂的模块来,对底层代码的熟悉是毕竟的路,不可跳过)。对初学者来说,一定先要去搞清楚什么叫同步,什么是异步,一定要去看一下触发器的基本原理。
对于有些经验的来说,不要津津乐道于底层的那些奇技淫巧,当设计到了百万门的时候,省几个触发器屁用也没有,稳定,可复用,易管理才是王道。

使用特权

评论回复
14
sleepybear| | 2009-12-8 12:07 | 只看该作者
蜗牛的话,我看懂了。
自己确实是还处在“汇编”阶段,工作以来做的多是一些接口和数据流控制方面的模块级的工作。只是最近才完整的做了一个稍大的系统级的工作(构架都是原来的,我只是根据新系统的需求做了一些增减、整合工作)。
受教了。多些蜗牛。:)

使用特权

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

本版积分规则

个人签名:我在背后默默的看着你 默默的看着你渐去渐远渐无影

164

主题

1166

帖子

2

粉丝