一、题目背景
在数字时分多路通信系统中,为了能正确分离各路时隙信号,在发送端必须提供每帧的起始标记,在接收端检测并获取这一标志的过程称为帧同步。
帧同步有起止式同步法和插入特殊同步码组法两种。要求开机后整个系统要能很快地进人帧同步,或一旦帧失步后,能很快恢复帧同步。帧失步将使信息丢失,对于语音通信来讲,人耳不易察觉出小于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