题意整理

对于奇数分频电路,主要难点在于50%占空比的实现。单触发沿在奇数分频中是没有办法实现50%占空比的,因此需要考虑使用双边沿加组合逻辑实现50%占空比

题解主体

通过简单的状态转移表就能够得出,clkout7的翻转第一次是在上升沿,第二次是在下降沿。

clkin

clkout7

cnt

0

0

0

1

1

1

0

1

1

1

1

2

0

1

2

1

1

3

0

1

3

1

1

4

0

0

4

1

0

5

0

0

5

1

0

6

0

0

6

1

0

7

0

0

7

1

1

8

要让两个不同的时钟边沿触发的分频信号进行组合逻辑,分析应该有下面的时许构成:


很容易看出,做法应该是将两个信号进行或操作

将逻辑转换成Verilog代码描述如下



   reg [3:0]            cnt ;

   always @(posedge clk_in or negedge rst) begin

      if (!rst) begin

         cnt    <= 'b0 ;

      end

      else if (cnt == N-1) begin

         cnt    <= 'b0 ;

      end

      else begin

         cnt    <= cnt + 1'b1 ;

      end

   end


   reg                  clkp ;

   always @(posedge clk_in or negedge rst) begin

      if (!rst) begin

         clkp <= 1'b0 ;

      end

      else if (cnt == (N>>1)) begin

        clkp <= 1 ;

      end

      else if (cnt == N-1) begin

        clkp <= 0 ;

      end

   end

 


   reg                  clkn ;

   always @(negedge clk_in or negedge rst) begin

      if (!rst) begin

         clkn <= 1'b0 ;

      end

      else if (cnt == (N>>1) ) begin

        clkn <= 1 ;

      end

      else if (cnt == N-1) begin

        clkn <= 0 ;

      end

   end



   assign clk_out7 = clkp | clkn ;


因此实现方式为如下的电路,综合得到:

参考答案

`timescale 1ns/1ns


module odo_div_or
  #(parameter N = 7)
   (
    input    wire  rst ,
    input    wire  clk_in,
    output   wire  clk_out7
    );



   reg [3:0]            cnt ;
   always @(posedge clk_in or negedge rst) begin
      if (!rst) begin
         cnt    <= 'b0 ;
      end
      else if (cnt == N-1) begin
         cnt    <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end

   reg                  clkp ;
   always @(posedge clk_in or negedge rst) begin
      if (!rst) begin
         clkp <= 1'b0 ;
      end
      else if (cnt == (N>>1)) begin 
        clkp <= 1 ;
      end
      else if (cnt == N-1) begin 
        clkp <= 0 ;
      end
   end
  

   reg                  clkn ;
   always @(negedge clk_in or negedge rst) begin
      if (!rst) begin
         clkn <= 1'b0 ;
      end
      else if (cnt == (N>>1) ) begin 
        clkn <= 1 ;
      end
      else if (cnt == N-1) begin 
        clkn <= 0 ;
      end
   end


   assign clk_out7 = clkp | clkn ;


endmodule