基于FPGA的帧同步设计

一、题目背景

在数字时分多路通信系统中,为了能正确分离各路时隙信号,在发送端必须提供每帧的起始标记,在接收端检测并获取这一标志的过程称为帧同步。

帧同步有起止式同步法和插入特殊同步码组法两种。要求开机后整个系统要能很快地进人帧同步,或一旦帧失步后,能很快恢复帧同步。帧失步将使信息丢失,对于语音通信来讲,人耳不易察觉出小于100 ms的通信中断,所以一般认为帧同步恢复时间在几十毫秒量级是允许的。本次实验将对于PRBS15的特定码流检测,并采用32767个比特作为帧长。最后用PRBS7来模拟实际中传输误码的情况。

二、任务要求

串行比特流信号输入后,输出帧同步信号,同时输出指示信号。当找到帧同步头,输出同步后数据,指示灯亮;否则,输出数据为 0,指示灯灭。当输入使能信号 为高电平时,信号输入帧同步模块,完成帧同步检测后,当找不到帧同步头,输出数据为 0,指示灯灭;当找到帧同步头,输出同步后数据,out_frame_en 输出为 1,指示灯亮。

三、所需设备和软件

FPGA AX309开发板、PC机、ISE、Modelsim、VHDL/Verilog、示波器。

四、设计思路

首先利用伪随机序列原理产生两组数据(根据帧格式设定长度),一组包含帧同步头(这里采用PRBS15作为信源 1),另一组为随机数(这里采用PRBS7作为干扰信号信源 2)。在拨码开关作用下分别选择信源 1 或信源 2 作为信号。帧同步模块对输入进来的信号进行相关运算,检测帧同步头的起始位置,完成帧同步检测后,如果找不到帧同步头,输出数据为 0指示灯灭;当找到帧同步头,输出同步后数据, 输出为1,指示灯亮。并通过Modelsim仿真,及下载到电路板上示波器观察波形。

五、模块设计及相关代码

1.PRBS15码型发成模块(同时包含BPRS7码型切换)

基本原理:PRBS码即伪随机码,常用于高速串行通道的测试。其对于信道来说,码型看上去像是随机的,没有规律的出现,但实际上的码型是由生成多项式确定了的,并且有重复周期。下图为PRBS7码的线性反馈移位寄存器发生原理:

PRBS15模块代码

module PRBS15(
	input clk,
	input rst_n,
	input key,
	output reg out);         //最终输出
reg tag;                       //状态标志位
reg[15:1]PRBS15;      //15位寄存器作为PRBS 15码型发生器
reg[7:1]PRBS7;       //7位寄存器作为PRBS 15码型发生器
always@(negedge rst_n or negedge key)
begin
if(rst_n==0)
	tag<=0;
else
	tag<=~tag;         //按键按下时标志位切换状态
end		
always@(posedge clk or negedge rst_n)
begin
if(rst_n==0)
	begin
	out<=0;
	PRBS15<=1;
	PRBS7<=1;
	end
else if(tag==0)
	begin
	PRBS15<={PRBS15[14:1],PRBS15[1]};     
	PRBS15[1]<=(PRBS15[15]^PRBS15[14]);     //根据线性反馈移位寄存器,将输出码型送到out
	out<=PRBS15[15];
	end
else if(tag)     //标志位为1代表按键按下,切换码型到out
	begin
	PRBS7<={PRBS7[6:1],PRBS7[1]};
	PRBS7[1]<=(PRBS7[7]^PRBS7[6]);       //原理同PRBS15,
	out<=PRBS7[7];
	end
end
endmodule

modelsim仿真如下

PRBS15码在这里插入图片描述
PRBS15和PRBS7切换在这里插入图片描述

2.前导码检测

基本原理:每一帧的前15位作为检测位,若符合要求,则为一次同步。前十五位为000000000000001,故采用状态机检测需要15个状态。这里采用三段式状态机。

module stm1(
	input din,clk,RST,
	output reg tag1,
	output reg dout);
parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8,
          s9=9,s10=10,s11=11,s12=12,s13=13,s14=14,s15=15;//定义15个状态    
	reg [3:0] pr_state,nx_state;                          
	reg [15:1]cnt;
always @(posedge clk or negedge RST)      //第一段状态完成状态转移
begin
if (RST==0)
        pr_state<=s0;
else
	pr_state<=nx_state;            

end
always @(posedge clk or negedge RST)  //第二段完整判断状态转移条件,描述状态规律
 begin                               
if (RST==0)
	pr_state=s0;
else
	pr_state=nx_state;
end
always @(*)
begin        
case(pr_state)
	s0:if(!din)
	  nx_state<=s1;
          else nx_state<=s0;
	s1:if(!din)
          nx_state<=s2;
          else
          nx_state<=s0;
	s2:if(!din)
          nx_state<=s3;
          else
          nx_state<=s0;
	s3:if(!din)
          nx_state<=s4;
          else
          nx_state<=s0;
	s4:if(!din)
          nx_state<=s5;
          else
          nx_state<=s0;
	s5:if(!din)
          nx_state<=s6;
          else
          nx_state<=s0;
	s6:if(!din)
          nx_state<=s7;
          else
          nx_state<=s0;
	s7:if(!din)
          nx_state<=s8;
          else
          nx_state<=s0;
	s8:if(!din)
          nx_state<=s9;
          else
          nx_state<=s0;
	s9:if(!din)
          nx_state<=s10;
          else
          nx_state<=s0;
	s10:if(!din)
          nx_state<=s11;
          else
          nx_state<=s0;
	s11:if(!din)
          nx_state<=s12;
          else
          nx_state<=s0;
	s12:if(!din)
          nx_state<=s13;
          else
          nx_state<=s0;
	s13:if(!din)
          nx_state<=s14;
          else
          nx_state<=s0;
	s14:if(din)
          nx_state<=s15;
          else
          nx_state<=s0;
	s15:nx_state<=s0;
endcase
end
always @(posedge clk or negedge RST) //第三个状态机输出:当达到第15个状态时,输出
begin                      //一个同步信号
if(RST==0)
	out<=0;
else
	begin
	if(nx_state==s15)
		dout<=1;
        else
                dout<=0;
        end
always@(posedge clk or negedge RST )   //将同步信号优化,拉长保持当前帧状态,方便
begin                             //后面同步状态检测   
if(RST==0||dout==1)
	begin
        cnt<=0;
        tag1<=1;
        end          
else if(cnt==32700)         //通过计数器延长标志
        begin
        cnt<=0;
        tag1<=0;
        end  
else 
	cnt<=cnt+1;
end
endmodule

modelsim仿真如下

dout输出

在这里插入图片描述

tag输出

在这里插入图片描述

3.同步状态机

基本原理:通过检测上一个模块传来的标志信号,检测是否连续三次有同步信号,若连续检测到三次则判定同步,若过程中出现一次误码,则进入失警状态,若下次仍能检测到同步信号,则回到同步状态,否则判定失帧。同样使用三段式。状态转移图如下:
在这里插入图片描述

module stm2(   
	input clk,   
	input rst_n,
        input clk15,
        input tag1,
        output reg led);
        //帧检测
        parameter s0=0,s1=1,s2=2,s3=3,s4=4;
        reg [2:0] pr_state,nx_state;                  //定义5个状态
always @(posedge clk or negedge rst_n)        //第一段状态转移
begin
if(rst_n==0)
	pr_state<=s0;
else
	pr_state<=nx_state;
end          
always @(negedge clk15 or negedge rst_n)  //第二段状态检测
begin
if (rst_n==0)
	nx_state<=s0;
else
case(pr_state)
	s0:if(tag1)
          nx_state<=s1;
          else
          nx_state<=s0;
	s1:if(tag1)
          nx_state<=s2;
          else
          nx_state<=s0;
	s2:if(tag1)
          nx_state<=s3;
          else
          nx_state<=s0;
	s3:if(tag1)
          nx_state<=s3;
          else
          nx_state<=s4;
	s4:if(tag1)
          nx_state<=s3;
          else
          nx_state<=s0;
endcase
end         
always @(posedge clk or negedge rst_n)    //第三段状态输出
begin
if(rst_n==0)
	led<=0;
else
	begin
	if(nx_state==s3||nx_state==s4)
        	led<=1;
        else
                led<=0;
        end
endmodule

modelsim仿真如下

在这里插入图片描述

4.分频时钟检查信号

module f(
	input        clk,
	input        rst_n,
	input        dout,   
	output       reg clk15);	
reg [15:0] cnt;
always@(posedge clk or negedge rst_n )
begin
if(rst_n==0||dout==1)
	begin
        cnt<=0;
        clk15<=1;
        end
else if(cnt==16383)
        begin
        cnt<=0;
        clk15<=~clk15;
        end  
else 
        cnt<=cnt+1;
end
endmodule

5.引脚约束文件

NET "clk" LOC = T8 | TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;
NET rst_n  LOC = L3 | IOSTANDARD ="LVCMOS33";
## reset pushbutton
NET key    LOC = C3 | IOSTANDARD ="LVCMOS33"; ## KEY1
########LED Pin define###################
NET led    LOC = P4 | IOSTANDARD ="LVCMOS33"; ## LED1
NET out1   LOC = H15 | IOSTANDARD= "LVCMOS33"; ## LED1
NET dout   LOC = C10 | IOSTANDARD= "LVCMOS33"; ## dout
NET clk1   LOC = C15 | IOSTANDARD = "LVCMOS33"; ## clk

6.测试文件

module tb;
// Inputs
reg clk;
reg rst_n;
reg key;
// Outputs
wire led;
// Instantiate the Unit Under Test (UUT)
top uut (
	.clk(clk), 
	.rst_n(rst_n), 
	.key(key), 
	.led(led));		
initial begin

// Initialize Inputs
clk = 0;
rst_n = 0;
key = 1;
// Wait 100 ns for global reset to finish
#100      rst_n=1;
end
always #10 clk=~clk;
always #3000000 key=~key;
endmodule

采用数字示波器显示最终结果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值