FPGA入门系列:寄存器是如何构成的&移位寄存器

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

1.触发器

(1)有两个稳定状态(简称稳态),正好用来表示逻辑 0 和 1。

(2)在输入信号作用下,触发器的两个稳定状态可相互转换(称为状态的翻转)。输入信号消失后,新状态可长期保持下来,因此具有记忆功能,可存储二进制信息。

(3)一个触发器可存储 1 位二进制数码。

(4)触发器有记忆功能,由它构成的电路在某时刻的输出不仅取决于该时刻的输入,还与电路原来状态有关。而门电路无记忆功能,由它构成的电路在某时刻的输出完全取决于该时刻的输入,与电路原来状态无关。

(5)触发器和门电路是构成数字电路的基本单元。

2.由触发器构成寄存器

D触发器可用于存储比特信号,增加一根输入线load,可加载输入信号。
image

image
边沿触发的存储单元,在上升沿(或下降沿)数据变化,一个周期里只能变化一次。
用来暂时存放参与运算的数据和运算结果。在实际的数字系统中,通常把能够用来存储一组二进制代码的同步时序逻辑电路称为寄存器。

可以把4个1位寄存器模块组合在一起,构成4位的寄存器,同理,可以用N个1位寄存器构造成1个N位寄存器。

4个1位寄存器模块组合

N位寄存器

3.移位寄存器

移位寄存器

移位寄存器是一种在时钟脉冲的作用下,将寄存器中的数据按位移动的逻辑。

1个N位的移位寄存器包含N个触发器。在每个时钟脉冲下,数据从一个触发器移到另一个触发器。需要注意的是,在同一时钟上升沿,所有的数值都是同时移位的。

移位寄存器不但可以用来寄存数据,还可以用来实现数据的串并转换、延时、数值运算以及其他电路设计
电路主要功能:

  1. 串行输入串行输出
  2. 串行输入并行输出
  3. 并行输入串行输出

移位寄存器

在时钟边沿触发的移位寄存器:

reg [15:0] myreg;
always @(posedge clk)
  myreg <= {myreg[14:0],data_in};

在此示例中,myreg 数据向左移动,并添加 data_in,最高有效位被丢弃。

myreg移位寄存器

4.移位寄存器的应用

4.1流水灯

always @(posedge clk or negedge rst)
begin
  if (!rst) 
      dout = din;
  else
      case(ctl)
	0: dout = {dout[1], dout[8:2]}; //从左向右循环移动(右移)
	1: dout = {dout[7:1], dout[8]}; //从右向左循环移动(左移)
	2: dout = {dout [7:5], dout [8], d[3:1], dout [4]};
                                           //前4位与后4位分别循环左移
	3: dout = {dout [5], dout [8:6], dout [1], dout [4:2]};
                                           //前4位与后4位分别循环右移
    default: dout = din;

流水灯仿真

4.2 并串转换和串并转换

串行电路分类:

  1. 同步串口:SPI和I2C等
  2. 异步串口:RS232、RS485等

串行电路优点:

  1. 引脚资源消耗少
  2. 干扰小

如果与串行电路接口,通常会包含串并转换和并串转换两部分电路:

FPGA与外部接口

4.2.1串入串出移位寄存器

8位移位寄存器由8个D触发器串联构成,在时钟信号的作用下,前级的数据向后移动

串入串出移位寄存器verilog实现代码:

module shift_1(din,clk,dout);     
	input  din,clk;       
	output reg dout;     
	reg tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7;                    
	always@(posedge clk)  
      	begin	
		tmp1<=din;	
		tmp2<=tmp1;	
		tmp3<=tmp2;	
		tmp4<=tmp3;	
		tmp5<=tmp4;	
		tmp6<=tmp5;	
		tmp7<=tmp6;	
		dout<=tmp7;  
	end
endmodule

4.2.2串入并出移位寄存器

使用触发器可以实现移位寄存器对数据的串-并转换。
4位串行输入并行输出移位寄存器的逻辑电路如下图所示。该寄存器由4个同步D触发器组成,这种D触发器的CLRN端是异步清零端。

串入并出移位寄存器

串入并出移位寄存器

串入并出移位寄存器verilog实现代码:

module shift_2(din,clk,clr,q);     
	input  din,clk,clr;       
	output [3:0] q;     
	reg [3:0] q;          
	always@(posedge clk , negedge clr)  begin	
		if(clr==1’b0)		
			q<=4’b0000;	     
		else	begin
			q[0]<= din;		
			q    <=  q<<1;  
			end
	end
	endmodule 

其中always块里面,else部分可以替换:

image
等价于下面的代码:

module shift_2(din,clk,clr,q);     
	input  din,clk,clr;       
	output [3:0] q;     
	reg [3:0] q;          
	always@(posedge clk , negedge clr)  begin	
		if(clr==1’b0)		
			q<=4’b0000;	     
		else begin	
        q[0]<=din;
        q[1]<=q[0];
        q[2]<=q[1];
        q[3]<=q[2];
	end
	endmodule 

4.2.3并入串出移位寄存器

并入串出移位寄存器可以将一组二进制数并行送入一组寄存器,然后把这些数据串行从寄存器内输出。
一个同步并入串出移位寄存器的基本管脚:

  1. 并行输出输入端:data
  2. 时钟脉冲输入端:clk
  3. 加载数据端:load
  4. 串行数据输出端:dout

并入串出移位寄存器Verilog实现代码:

方法一:

module shift3 (clk,din, load,q);     
	input clk,load;     
	input [3:0] din;       
	output reg q;     
	reg [3:0] tmp;                         
	always@(posedge clk)  
	        begin	
		if(load==1’b1) 
			tmp<=din;	
		else	begin		
			tmp<=tmp<<1;		
			tmp[0]<=1’b0;	
			 q<=tmp[3]; 
      			end	
	        end
	endmodule

方法二:

module shift3 (clk,din, load,q);     
	input clk,load;     
	input [3:0] din;       
	output q;     
	reg [3:0] tmp;                         
	always@(posedge clk)  
	  if(load) 
		tmp<=din;	
	  else			
		tmp[3:1]<=tmp[2:0];//左移		
	  assign q=tmp[3]; 
      	endmodule

方法二是从最高位串行输出;若要求从最低位串行输出,则只需修改tmp[2:0]<=tmp[3:1];与assign q=tmp[0]; 即右移。

8位通用移位寄存器verilog实现代码:

module univ_shift_reg  #(parameter N=8) (     
	input  clk, reset;       
	input [1:0] ctrl;
              input [N-1:0] d;
              output [N-1:0] q );     
  reg [N-1:0]  r_reg, r_next;                    
 always@(posedge clk, posedge reset)  
    if(reset) r_reg<=0;	
    else        r_reg<= r_next;	

 always@(*)  
    case (ctrl)	
        2’b00:  r_next = r_reg;	                 //无操作
        2’b01:  r_next = {r_reg[N-2:0], d[0]};      //左移	
        2’b10:  r_next = {d[N-1], r_reg[N-1:1]}; //右移
        default: r_next= d;                                    //载入
    endcase
 assign q=r_reg;
endmodule

以上都是不带AXI协议的串并、并串转换,带有AXI Stream协议的串并、并串转换,请看文章:基于valid-ready双向握手机制的串并和并串转换

链接:https://mp.weixin.qq.com/s/9j6zz69i37CcWAnsfm1ePQ

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值