⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 counter.v

📁 设计一个可编程间隔定时器
💻 V
字号:
///////////////////////////////////////////////////////////////////////
//                                                                   //
// File name    : counter.v                                        //
// Title        :                                                    //
// Library      : WORK                                               //
//              :                                                    //
// Purpose      : 8253 counter 0                                     //
//              :                                                    //
// Created On   : 2007-7-15                                          //
//              :                                                    //
// Comments     :                                                    //
//              :                                                    //
// Assumptions  : none                                               //
// Limitations  : none                                               //
// Known Errors : none                                               //
// Developers   : xl                                                 //
//              :                                                    //
// Notes        :                                                    // 
//                                                                   //
///////////////////////////////////////////////////////////////////////

module counter(
               //input
               select,
               data_wr,
               load_counter_low,
               load_counter_high,
               load_over,
               latch_count,
               read_counter_low,
               read_counter_high,
               control_write,
               gate,
               clk,
               //output
               data_rd,
               out
               );

  input  select;
  input  load_counter_low;
  input  load_counter_high;
  input  load_over;
  input  latch_count;
  input  read_counter_low;
  input  read_counter_high;
  input  control_write;
  input  gate;
  input  clk;
  input  [7:0] data_wr;
   
  output out;
  output [7:0] data_rd;
  

  reg  bcd;
  reg  out;
  reg  last_gate;
  reg  gate_rising;
  reg  count_en;
  reg  load_control;
  reg  data_load;
  reg  [2:0] mode;
  reg  [7:0] data_rd;
  reg  [15:0] count_initial;
  reg  [15:0] count_tmp;
  reg  [15:0] count_buffer;
  reg  [15:0] count;


  function [15:0] countnew;
    input [15:0] count;
    input bcd;
    reg  [3:0] temp1,temp2,temp3,temp4;
    begin
      if(!bcd)
        countnew = count - 1;
      else begin
        {temp4,temp3,temp2,temp1} = count;
        temp1 = temp1-1;
        if(temp1 == 4'b1111) begin
           temp1 = 4'b1001;
           temp2 = temp2-1;
             if(temp2 == 4'b1111) begin
               temp2 = 4'b1001;
               temp3 = temp3-1;
                 if(temp3 == 4'b1111) begin
                   temp3 = 4'b1001;
                   temp4 = temp4-1;
                     if(temp4 == 4'b1111) begin
                       temp3 = 4'b1001;
                     end
                 end
             end
        end
        countnew = {temp4,temp3,temp2,temp1};
      end
    end
  endfunction

//----------------------------------------------------------
//load counter_inital
//----------------------------------------------------------
  always @(posedge control_write or posedge load_counter_low or posedge load_counter_high)
    if(control_write && select)
      count_initial <= 0;
    else if(load_counter_low && select)
      count_initial[7:0] <= data_wr;
    else if(load_counter_high && select)
      count_initial[15:8] <= data_wr;
  
//----------------------------------------------------------
//latch current count value                             
//----------------------------------------------------------
  always @(posedge latch_count or posedge control_write)
    if(control_write && select)
      count_buffer <= 16'b0;
    else if(latch_count && select)
      count_buffer <= count;

//----------------------------------------------------------
//read latch count                            
//----------------------------------------------------------
  always @(posedge read_counter_low or posedge read_counter_high)
    if(read_counter_low && select)
       data_rd <= count_buffer[7:0];
    else  if(read_counter_high && select)
       data_rd <= count_buffer[15:8];
     
//----------------------------------------------------------
//set control word
//----------------------------------------------------------
  always @(negedge clk or posedge load_over or posedge gate or posedge control_write)begin
    if(!load_control && control_write && select) begin
      bcd <= data_wr[0];
      mode <= data_wr[3:1];
      load_control <= 1;
      data_load <= 0;
      //if(mode == 3'b010)
      end
    else if(!data_load && load_over && select)begin
      data_load <= 1;
      gate_rising <= 0;
      end
    else if(!gate_rising && gate && !last_gate)
      gate_rising <= 1;
    else begin
      last_gate <= gate;
      load_control <= 0;
/////mode0
      if(mode == 3'b000)begin
        if(data_load == 1)begin            //wr上升沿装入初值
          count <= count_initial;
          data_load <= 0;
          count_en <= 1;
          end
        else if(gate && count && count_en)     //gate为高电平就开始计数
          count = countnew(count,bcd);
          
        if(!count && count_en)                 //计数记到0后就停止计数
          count_en <= 0; 
          
        if(load_control == 1)begin             //设定模式后输出为低
          out <= 0;
          load_control <= 0;
          end
        else if(count_en && !count)            //计数记到0后输出为高
          out <= 1;
        end
      
//////mode1
      if(mode == 3'b001)begin
        if(gate_rising == 1)begin              //gate上升沿装入初值
          count <= count_initial;
          gate_rising <=0;
          count_en <= 1;
          end
        else if(count && count_en)             //开始计数,与gate状态无关
          count = countnew(count,bcd);
          
        if(!count && count_en) begin           //计数完毕后禁止计数,输出为高
          count_en <= 0;
          out <=1;
          end
          
        if(load_control == 1)begin             //载入模式后输出为高
          out <= 1;
          load_control <= 0;
          end
        else if(gate_rising)                   //计数开始后输出为低
          out <= 0;
        end

//////mode2 
      if(mode == 3'b010 || mode == 3'b110)begin
  
        if(data_load && gate)begin             //wr上升沿且gate为高电平装入初值
          count_tmp <= count_initial;
          data_load <= 0;
          count_en <= 1;
          end
          
        if(!gate_rising && gate && count && count_en)     //gate为高电平就开始计数
          count = countnew(count,bcd);
        else if(gate_rising == 1)begin              //gate上升沿装入初值
          count <= count_tmp;
          gate_rising <=0;
          end
        else if(gate && count_en)//if(gate && !count && count_en)    //计数记到0后就重装初值
          count <= count_tmp;
   
        if(load_control == 1)begin             //载入模式后输出为高
          out <= 1;
          load_control <= 0;
          end
        else if(gate && count == 1)            //计数为1时输出为低
          out <= 0;
        else
          out <= 1;
        end
        
//////mode3
      if(mode == 3'b011 || mode == 3'b111)begin
        if(data_load && gate)begin             //wr上升沿且gate为高电平装入初值
          count <= count_initial;
          data_load <= 0;
          count_en <= 1;
          end
  
        if(count==0 && count_en)    //按奇偶方式计数
          count=count_initial;
        else if(gate_rising == 1)begin              //gate上升沿装入初值
          count <= count_initial;
          gate_rising <=0;
          end
        else if(gate &&  !count[0]&& count_en)begin
          count = countnew(count,bcd);
          count = countnew(count,bcd);
          end 
        else if(gate &&  count[0]&& out&& count_en)  
          count = countnew(count,bcd);
        else if(gate && count[0]&& !out && count_en)begin
          count = countnew(count,bcd);
          count = countnew(count,bcd);
          count = countnew(count,bcd);
          end
      
        if(load_control == 1)begin             //载入模式后输出为高
          out <= 1;
          load_control <= 0;
          end
        else if(count==0 && count_en)         //正常输出的翻转
          out = ~out;
        else  if(!gate)
          out = 1 ;
        end
        
//////mode4
      if(mode == 3'b100)begin
        if(data_load == 1)begin            //wr上升沿装入初值
          count <= count_initial;
          data_load <= 0;
          count_en <= 1;
          end
        else if(gate && count && count_en)     //gate为高电平就开始计数
          count = countnew(count,bcd);
        
        if(load_control == 1)begin             //载入模式后输出为高
          out <= 1;
          load_control <= 0;
          end
        else if(!count && out && count_en)begin
          count_en <= 0;
          out <= 0;
          end
        else
          out <= 1; 
        end
        
//////mode5
        if(mode == 3'b101)begin
          if(gate_rising == 1)begin              //gate上升沿装入初值
            count <= count_initial;
            gate_rising <=0;
            count_en <= 1;
            end
          else if(count_en)
            count = countnew(count,bcd);
          
          if(!count && count_en)begin
            count <=count_initial;
            count_en <= 0;
            end
          
          if(load_control == 1)begin             //载入模式后输出为高
            out <= 1;
            load_control <= 0;
            end
          else if(count==0)
            out <= 0;
          else
            out <= 1;
          end
      end
    end

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -