verilog语法实例学习(9)

常用的时序电路介绍


寄存器

     一个触发器可以存储一位数据,由n个触发器组成的电路可以存储n位数据,我们把这一组触发器叫做寄存器。寄存器中每个触发器共用同一个时钟。

     下面是n位寄存器的代码,我们通过一个参数定义n,在实例化时传入参数n。


module regne (D, clk,Rst_n,E,Q);
  parameter n=4;
  input [n-1:0] D;
  input clk;
  input Rst_n; //复位信号
  input E; //使能信号

  output reg [n-1:0] Q;

  always @(posedge clk,negedge Rst_n)
    if(Rst_n==0)
	   Q <= 0;
	 else if(E)
	   Q <= D;

endmodule
`timescale 1ns/1ns
`define clock_period 20

module regne_tb;
  reg [7:0] D;
  wire [7:0] Q;
  reg clk;
  reg Rst_n;
  reg E;

  regne #(.n(8)) regne(.D(D),.clk(clk),.Rst_n(Rst_n),.E(E),.Q(Q));
  always # (`clock_period/2) clk = ~clk;

  initial
  begin
    D = 4'b01010101;
	 clk = 1'b0;
	 Rst_n = 1'b1;
	 E = 1'b1;
	 #(`clock_period)
	 Rst_n = 1'b0;
	 D = 4'b10101010;
	 #(`clock_period*2)
	 E = 1'b0;
	 Rst_n = 1'b1;
	 D = 4'b00010001;
	 #(`clock_period*4)
	 E = 1'b1;
	 D = 4'b1111;
	 #(`clock_period*2)
	 D = 4'b10111011;
	 #(`clock_period*2)
	 D = 4'b10011001;
	 #(`clock_period*2)
    $stop;
  end

endmodule

image_thumb11

下面的电路能实现带使能和异步复位的n位寄存器(这儿假设是4位)。D3D2D1D0是寄存器输入值。Q3Q2Q1Q0是寄存器输出值。

image

移位寄存器

        寄存器移位可以实现整数乘法和触发,左移一位且在末位补0,相当于乘以2,右移一位可以实现除2功能。有移位功能的寄存器称作移位寄存器。

      下面的电路可以实现把自身内容右移一位的4位移位寄存器:数据以串行的方式从输入端In移入移位寄存器,在时钟的上升沿每个触发器的内容传输到下一个触发器。假设初始状态为0,在连续的8个周期内输入信号In的值分别为: 1,0,1,1,1,0,0,0,则各个寄存器状态的变化如下表:

  In Q0 Q1 Q2 Q3(out)
t0 1 0 0 0 0
t1 0 1 0 0 0
t2 1 0 1 0 0
t3 1 1 0 1 0
t4 1 1 1 0 1
t5 0 1 1 1 0
t6 0 0 1 1 1
t7 0 0 0 1 1

image


      下面的代码实现把串行的输入存储到一个寄存器,可以选择时机并行输出。电路还带有一个Load信号,如果Load=1,则移位寄存器装入初始值,否则执行移位操作。这种串行加载并行读取数据电路叫串-并转化器。

/*串行输入,并行输出寄存器
从高位输入,即从右向左输入*/
module shiftn(R,L,w,clk,Q);
  parameter n=8;
  input [n-1:0] R;//初始值
  input L; //load信号
  input w; //移入信号
  input clk;//时钟信号
  output reg [n-1:0] Q;
  integer k;

  always @(posedge clk)
  begin
    if(L)
	    Q <=R;
	 else
	 begin
	   for(k=0; k<n-1; k=k+1)
		  Q[k] <= Q[k+1];
	   Q[n-1] <= w;
	 end

  end


endmodule
`timescale 1ns/1ns
`define clock_period 20

module shiftn_tb;

  reg [7:0] R;
  reg L;
  reg w;
  reg clk;
  wire [7:0] Q;

  shiftn #(.n(8)) shitn0(.R(R),.L(L),.w(w),.clk(clk),.Q(Q));
  initial clk = 0;
  always #(`clock_period/2) clk = ~clk;

  initial
  begin
    R = 8'b00000000;
	 L = 1'b1;
	 w = 1'b0;
	 #(`clock_period)
	 L = 1'b0;
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b0;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 w = 1'b1;
	 #(`clock_period)
	 $stop;
  end

endmodule
View Code


image_thumb14

我们也可以使用拼接符操作代替for循环,实现同样的功能,而且语法更加简单。


/*串行输入,并行输出寄存器
从高位输入,即从右向左输入*/
module shiftn(R,L,w,clk,Q);
  parameter n=8;
  input [n-1:0] R;//初始值
  input L; //load信号
  input w; //移入信号
  input clk;//时钟信号
  output reg [n-1:0] Q;


  always @(posedge clk)
  begin
    if(L)
	    Q <=R;
	 else
	 begin

     Q = {w,Q[n-1:1]};
	 end

  end


endmodule

下面的电路可以实现串行输入,并行输出并行输入,串行输出;

image

posted on 2018-12-29 19:57  迈克老狼2012  阅读(843)  评论(0编辑  收藏  举报

导航