verilog实现定时器函数

编程语言及工具

99人已加入

描述

  使用Verilog描述硬件的基本设计单元是模块(module)。构建复杂的电子电路,主要是通过模块的相互连接调用来实现的。模块被包含在关键字module、endmodule之内。实际的电路元件。Verilog中的模块类似C语言中的函数,它能够提供输入、输出端口,可以实例调用其他模块,也可以被其他模块实例调用。模块中可以包括组合逻辑部分、过程时序部分。例如,四选一的多路选择器,就可以用模块进行描述。它具有两个位选输入信号、四个数据输入,一个输出端,在Verilog中可以表示为:

  module mux (out, select, in0, in1, in2, in3);output out;input [1:0] select;input in0, in1, in2, in3;//具体的寄存器传输级代码endmodule

  设计人员可以使用一个顶层模块,通过实例调用上面这个模块的方式来进行测试。这个顶层模块常被称为“测试平台(Testbench)”。为了最大程度地对电路的逻辑进行功能验证,测试代码需要尽可能多地覆盖系统所涉及的语句、分支、条件、路径、触发、状态机状态,验证人员需要在测试平台里创建足够多的输入激励,并连接到被测模块的输入端,然后检测其输出端的表现是否符合预期(诸如SystemVerilog的硬件验证语言能够提供针对验证专门优化的数据结构,以随机测试的方式进行验证,这对于高度复杂的集成电路设计验证可以起到关键作用)。实例调用模块时,需要将端口的连接情况按照这个模块声明时的顺序排列。这个顶层模块由于不需要再被外界调用,因此没有输入输出端口:

  module tester;reg [1:0] SELECT;reg IN0, IN1, IN2, IN3;wire OUT;mux my_mux (OUT, SELECT, IN0, IN1, IN2, IN3); //实例调用mux模块,这个实例被命名为my_muxinitial //需要仿真的激励代码 begin endendmodule

  在这个测试平台模块里,设计人员可以设定仿真时的输入信号以及信号监视程序,然后观察仿真时的输出情况是否符合要求,这样就可以了解设计是否达到了预期。

  示例中的对模块进行实例引用时,按照原模块声明时的顺序罗列了输入变量。除此之外,还可以使用或者采用命名端口连接的方式。使用这种方式,端口的排列顺序可以与原模块声明时不同,甚至可以不连接某些端口:

  mux my_mux (.out(OUT), .select(SELECT), .in0(IN0), .in1(IN1), .in2(IN2), .in3(IN3));//使用命名端口连接,括号外面是模块声明时的端口,括号内是实际的端口连接//括号外相当于C语言的形式参数,括号内相当于实际参数endmodule

  上面所述的情况是,测试平台顶层模块的测试变量直接连接了所设计的功能模块。测试平台还可以是另一种形式,即测试平台并不直接连接所设计的功能模块,而是在这个测试平台之下,将激励模块和功能模块以相同的抽象级别,通过线网相互连接。这两种形式的测试平台都可以完成对功能模块的测试。大型的电路系统,正是由各个层次不同模块之间的连接、调用,来实现复杂的功能的。

  verilog实现定时器函数

  Verilog代码

  module alarm_block (

  input wire rst,

  clk,

  hrs,

  mins,

  alarm,

  output wire [4:0] alarm_hr,

  output wire [5:0] alarm_min

  );

  wire hour_s, min_s;

  alarm_counter counter1 ( rst, hour_s, min_s, clk, alarm_hr, alarm_min );

  state_machine alarm_state ( rst, alarm, hrs, mins, clk, hour_s, min_s );

  endmodule

  module state_machine (

  input wire rst,

  alarm,

  hrs,

  mins,

  clk,

  output reg hrs_out,

  mins_out

  );

  parameter IDLE = 2‘b00,

  SET_HRS = 2’b01,

  SET_MINS = 2‘b11;

  reg[1:0] state, next;

  always@( posedge clk or posedge rst )

  if( rst )

  state 《= IDLE;

  else state 《= next;

  always@( alarm or hrs or mins or state )

  case( state )

  IDLE :

  if( !alarm ) begin

  next = IDLE;

  hrs_out = 0;

  mins_out = 0;

  end else if ( alarm & hrs & !mins ) begin

  next = SET_HRS;

  hrs_out = 1;

  mins_out = 0;

  end

  else if( alarm & !hrs & mins ) begin

  next = SET_MINS;

  hrs_out = 0;

  mins_out = 1;

  end SET_HRS : begin

  if( alarm & hrs & !mins ) begin

  next = SET_HRS;

  hrs_out = 1;

  end else begin next = IDLE;

  hrs_out = 0;

  end

  mins_out = 0;

  end

  SET_MINS : begin

  if( alarm & !hrs & mins ) begin

  next = SET_MINS;

  mins_out = 1;

  end

  else begin

  next = IDLE;

  mins_out = 0;

  end

  hrs_out = 0;

  end

  default : begin

  next = 2‘bx;

  hrs_out = 1’bx;

  mins_out = 1‘bx;

  end

  endcase

  endmodule

  module alarm_counter (

  input wire rst,

  hr_set,

  min_set,

  clk,

  output reg [4:0] hrs,

  output reg [5:0] mins

  );

  //set alarm minutes

  always@ ( posedge clk or posedge rst )

  if( rst )

  mins 《= 0;

  else if( min_set & !hr_set )

  if( mins == 6‘b111011 )

  mins 《= 6’b0;

  else

  mins 《= mins + 6‘b000001;

  //set alarm hours

  always@ ( posedge clk or posedge rst )

  if( rst )

  hrs 《= 0;

  else if( hr_set & !min_set)

  if ( hrs == 5’b10111 )

  hrs 《= 5‘b0;

  else

  hrs 《= hrs + 5’b00001;

  endmodule

  module Alarm_sm_2 (

  input wire rst,

  clk,

  compare_in,

  toggle_on,

  output reg ring

  );

  parameter IDLE = 1‘b0,

  ACTI = 1’b1;

  reg state, next;

  always@ ( posedge clk or posedge rst )

  if ( rst )

  state 《= IDLE;

  else

  state 《= next;

  always@ ( state or compare_in or toggle_on )

  case ( state )

  IDLE :

  if( toggle_on & compare_in ) begin

  next 《= ACTI;

  ring 《= 1;

  end

  else begin

  next 《= IDLE;

  ring 《= 0;

  end

  ACTI :

  if( toggle_on ) begin

  next 《= ACTI;

  ring 《= 1;

  end

  else begin

  next 《= IDLE;

  ring 《= 0;

  end

  default : begin

  next 《= 1‘bx;

  ring 《= 1’bx;

  end

  endcase

  endmodule

  module comparator (

  input wire [4:0] alarm_hr,

  time_hr,

  input wire [5:0] alarm_min,

  time_min,

  output reg compare_out );

  always@ ( * )

  if( ( alarm_hr == time_hr ) && ( alarm_min == time_min ) )

  compare_out = 1;

  else compare_out = 0;

  endmodulemodule convertor_ckt (

  input [4:0]hour,

  input [5:0]min,

  output [13:0]disp1, disp2

  );

  wire [13:0] disp1_0;

  segment_decoder segment_decoder_hr ( {1‘b0, hour}, disp1_0 );

  segment_decoder segment_decoder_min ( min , disp2 );

  Hours_filter filter ( disp1_0, disp1 );

  endmodule

  module segment_decoder (

  input wire [5:0] num,

  output reg [13:0] disp

  );

  always@ ( num )

  case ( num )

  6’b000000 : disp = 14‘b0111111_0111111;

  6’b000001 : disp = 14‘b0111111_0000110;

  6’b000010 : disp = 14‘b0111111_1011011;

  6’b000011 : disp = 14‘b0111111_1001111;

  6’b000100 : disp = 14‘b0111111_1100110;

  6’b000101 : disp = 14‘b0111111_1101101;

  6’b000110 : disp = 14‘b0111111_1111101;

  6’b000111 : disp = 14‘b0111111_0000111;

  6’b001000 : disp = 14‘b0111111_1111111;

  6’b001001 : disp = 14‘b0111111_1101111;

  6’b001010 : disp = 14‘b0000110_0111111;

  6’b001011 : disp = 14‘b0000110_0000110;

  6’b001100 : disp = 14‘b0000110_1011011;

  6’b001101 : disp = 14‘b0000110_1001111;

  6’b001110 : disp = 14‘b0000110_1100110;

  6’b001111 : disp = 14‘b0000110_1101101;

  6’b010000 : disp = 14‘b0000110_1111101;

  6’b010001 : disp = 14‘b0000110_0000111;

  6’b010010 : disp = 14‘b0000110_1111111;

  6’b010011 : disp = 14‘b0000110_1101111;

  6’b010100 : disp = 14‘b1011011_0111111;

  6’b010101 : disp = 14‘b1011011_0000110;

  6‘b010110 : disp = 14’b1011011_1011011;

  6‘b010111 : disp = 14’b1011011_1001111;

  6‘b011000 : disp = 14’b1011011_1100110;

  6‘b011001 : disp = 14’b1011011_1101101;

  6‘b011010 : disp = 14’b1011011_1111101;

  6‘b011011 : disp = 14’b1011011_0000111;

  6‘b011100 : disp = 14’b1011011_1111111;

  6‘b011101 : disp = 14’b1011011_1101111;

  6‘b011110 : disp = 14’b1001111_0111111;

  6‘b011111 : disp = 14’b1001111_0000110;

  6‘b100000 : disp = 14’b1001111_1011011;

  6‘b100001 : disp = 14’b1001111_1001111;

  6‘b100010 : disp = 14’b1001111_1100110;

  6‘b100011 : disp = 14’b1001111_1101101;

  6‘b100100 : disp = 14’b1001111_1111101;

  6‘b100101 : disp = 14’b1001111_0000111;

  6‘b100110 : disp = 14’b1001111_1111111;

  6‘b100111 : disp = 14’b1001111_1101111;

  6‘b101000 : disp = 14’b1100110_0111111;

  6‘b101001 : disp = 14’b1100110_0000110;

  6‘b101010 : disp = 14’b1100110_1011011;

  6‘b101011 : disp = 14’b1100110_1001111;

  6‘b101100 : disp = 14’b1100110_1100110;

  6‘b101101 : disp = 14’b1100110_1101101;

  6‘b101110 : disp = 14’b1100110_1111101;

  6‘b101111 : disp = 14’b1100110_0000111;

  6‘b110000 : disp = 14’b1100110_1111111;

  6‘b110001 : disp = 14’b1100110_1101111;

  6‘b110010 : disp = 14’b1101101_0111111;

  6‘b110011 : disp = 14’b1101101_0000110;

  6‘b110100 : disp = 14’b1101101_1011011;

  6‘b110101 : disp = 14’b1101101_1001111;

  6‘b110110 : disp = 14’b1101101_1100110;

  6‘b110111 : disp = 14’b1101101_1101101;

  6‘b111000 : disp = 14’b1101101_1111101;

  6‘b111001 : disp = 14’b1101101_0000111;

  6‘b111010 : disp = 14’b1101101_1111111;

  6‘b111011 : disp = 14’b1101101_1101111;

  default : disp = 14‘bx;

  endcase

  endmodule

  module Hours_filter (

  input wire [13:0] num,

  output reg [13:0] num_disp

  );

  always@ ( * )

  if ( num[13:7] == 7‘b011_1111 )

  num_disp = { 7’b0, num[6:0] };

  else

  num_disp = num;

  endmodule

  module Mux (

  input wire alarm,

  mode,

  input wire [4:0]alarm_hr,

  time_hr,

  input wire [5:0]alarm_min,

  time_min,

  output reg [1:0]am_pm_display,

  output reg [4:0]hours,

  output reg [5:0]minutes

  );

  always@( * ) begin

  //output hours and minutes

  hours = alarm ? alarm_hr : time_hr

  minutes = alarm ? alarm_min : time_min;

  //12hours system or 24hours system and set am_pm_display

  if ( mode )

  case ( hours )

  0 : begin am_pm_display = 2‘b10; hours = 5’b01100; end

  1 : am_pm_display = 2‘b10;

  2 : am_pm_display = 2’b10;

  3 : am_pm_display = 2‘b10;

  4 : am_pm_display = 2’b10;

  5 : am_pm_display = 2‘b10;

  6 : am_pm_display = 2’b10;

  7 : am_pm_display = 2‘b10;

  8 : am_pm_display = 2’b10;

  9 : am_pm_display = 2‘b10;

  10: am_pm_display = 2’b10;

  11: am_pm_display = 2‘b10;

  12: am_pm_display = 2’b01;

  13: begin am_pm_display = 2‘b01; hours = 5’b00001 end

  14: begin am_pm_display = 2‘b01; hours = 5’b00010 end

  15: begin am_pm_display = 2‘b01; hours = 5’b00011 end

  16: begin am_pm_display = 2‘b01; hours = 5’b00100 end

  17: begin am_pm_display = 2‘b01; hours = 5’b00101 end

  18: begin am_pm_display = 2‘b01; hours = 5’b00110 end

  19: begin am_pm_display = 2‘b01; hours = 5’b00111 end

  20: begin am_pm_display = 2‘b01; hours = 5’b01000 end

  21: begin am_pm_display = 2‘b01; hours = 5’b01001 end

  22: begin am_pm_display = 2‘b01; hours = 5’b01010 end

  23: begin am_pm_display = 2‘b01; hours = 5’b01011 end

  default: begin am_pm_display = 2‘bx; hours = 5’bx; end

  endcase

  else

  am_pm_display = 2‘b00;

  end

  endmodule

  module time_block (

  input wire rst,

  clk,

  hrs,

  mins,

  set_time,

  output wire [4:0] time_hr,

  output wire [5:0] time_min,

  time_sec

  );

  wire hour_s, min_s;

  time_counter counter2 ( rst, hour_s, min_s, clk, time_hr, time_min, time_sec );

  state_machine time_state ( rst, set_time, hrs, mins, clk, hour_s, min_s );

  endmodule

  module time_counter (

  input wire rst,

  hr_set,

  min_set,

  clk,

  output reg [4:0] hrs,

  output reg [5:0] mins,

  secs

  );

  always@ ( posedge clk or posedge rst )

  if( rst )

  secs 《= 0;

  else if( secs == 6‘b111011 )

  secs 《= 6’b0;

  else

  secs 《= secs + 6‘b000001;

  always@ ( posedge clk or posedge rst )

  if( rst )

  mins 《= 0;

  else if( (min_set & !hr_set) || (!hr_set & !min_set & (secs == 6’b111011)) )

  if( mins == 6‘b111011 )

  mins 《= 6’b0;

  else mins 《= mins + 6‘b000001;

  always@ ( posedge clk or posedge rst )

  if( rst )

  hrs 《= 0;

  else if( (hr_set & !min_set) ||(!hr_set & !min_set & (secs == 6’b111011) & (mins == 6‘b111011)) )

  if( hrs == 5’b10111 )

  hrs 《= 5‘b0;

  else

  hrs 《= hrs + 5’b00001;

  endmodule

  module timer (

  input wire rst,

  clk,

  alarm,

  set_time,

  hrs,

  mins,

  toggle_switch,

  mode,

  output wire speaker_out,

  output wire [1:0]am_pm_display,

  output wire [13:0] disp1,

  disp2

  );

  wire [5:0] time_min, time_sec, alarm_min, min;

  wire [4:0] time_hr, alarm_hr, hour;

  wire compare;

  time_block time_mod ( rst, clk, hrs, mins, set_time, time_hr, time_min, time_sec );

  alarm_block alarm_mod ( rst, clk, hrs, mins, alarm, alarm_hr, alarm_min );

  comparator comparator_mod ( alarm_hr, time_hr, alarm_min, time_min, compare );

  Alarm_sm_2 bell_mod ( rst, clk, compare, toggle_switch, speaker_out );

  Mux mux_mod ( alarm, mode, alarm_hr, time_hr, alarm_min, time_min, am_pm_display, hour, min );

  convertor_ckt convertor_mod ( hour, min, disp1, disp2 );

  endmodule

  module top;

  reg rst, clk, alarm, set_time, hrs, mins, toggle_switch, mode;

  wire [1:0] am_pm_display;

  wire speaker_out;

  wire [13:0] disp1, disp2;

  timer electronic_watch( rst, clk, alarm, set_time, hrs, mins, toggle_switch, mode, speaker_out, am_pm_display, disp1, disp2 );

  always begin

  clk = 0;

  #10 clk = 1;

  #10;

  end

  initial begin

  $monitor($time,,,,“disp1=%b disp2=%b am_pm_display=%b speaker_out=%b”, disp1, disp2, am_pm_display, speaker_out );

  rst = 0;

  alarm = 0;

  set_time = 0;

  hrs = 0;

  mins = 0;

  toggle_switch = 0;

  mode = 0;

  #5 rst = 1;

  //reset #4 rst = 0;

  #3000 mode = 1;//12hours system display

  #3000 mode = 0;//24hours system display

  #1200 alarm = 1; mins = 1;//set alarm minutes

  #200 mins = 0; toggle_switch = 1;//switch on

  #100 alarm = 0;

  #10000 toggle_switch = 0;//switch off

  #10000 set_time = 1; hrs = 1;//set hours

  #40 hrs = 0; #20 mins = 1;//set minutes

  #200 set_time = 0; mins =0;

  #40 alarm = 1; hrs = 1;//set alarm hours

  #40 hrs = 0; #20 mins = 1;//set alarm minutes

  #800 mins = 0; toggle_switch = 1;

  #300 alarm = 0;

  #24000 set_time = 1; hrs = 1;toggle_switch = 0;//set hours

  #240 set_time = 0; hrs = 0;

  #40 mode = 1; //12hours system display

  end

  endmodule

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分