基于FPGA的频带传输系统设计_基于fpga的锁相环设计
基于FPGA的频带传输系统设计由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“基于fpga的锁相环设计”。
通信系统EDA设计
基于FPGA(cyclone系列EP1C6Q240C)的时分多路频带传输系统设计
(VHDL语言描述)
指导教师:陈德宏老师
班级:通信072 姓名:汪双承
学号:079064305 同组人员:肖慧,吴敏根
陈飞,冉彪
设计时间:二零一零年六月底
目录
一、课题背景…………………………
二、任务要求…………………………
三、原理说明…………………………
四、程序与仿真………………………
五、心得体会…………………………
一、课题背景
FPGA是现场可编程门阵列的简称,FPGA的应用领域最初
为通信领域,特别是在无线通信领域里,由于具有极强的实时性,使使其对话音进行实时处理成为可能;由于它是通过面向芯片结构指令的软件编程来实现其功能的,因而仅修改软件而不需改硬件平台就可以改进系统原有设计方案或原有功能,因而具有极大的灵活性;又由于FPGA芯片并非专门为某种功能设计的,因而使用范围广、产量大、价格可以降到很低。但目前,随着信息产业和微电子技术的发展,可编程逻辑嵌入式系统设计技术已经成为信息产业最热门的技术之一,应用范围遍及航空航天、医疗、通讯、网络通讯、安防、广播、汽车电子、工业、消费类市场、测量测试等多个热门领域。并随着工艺的进步和技术的发展,向更多、更广泛的应用领域扩展。越来越多的设计也开始以ASIC转向FPGA,FPGA正以各种电子产品的形式进入了我们日常生活的各个角落。
在完成了通信原理和vhdl语言的学习后,为了理论联系实际,为了紧跟时代的步伐,作为通信专业的学生就有责任去学习和掌握FPGA技术在通信领域的应用。故开展了这次通信系统EDA课程设计。
二、任务要求
1、项目名称:时分多路数字电话频带传输系统的设计与开发
(基于FPGA cyclone系列EP1C6Q240C)
2、系统设计指标:
(A)64KB/S的A律PCM数字话音编译码器的开发设计
(B)PCM 30/32一次群时分复接与分接器的开发设计(C)正交相对四相移相键控QDPSK调制器的开发设计
3、系统框图:
4、各功能模块技术要求 A、PCM编译码器参数指标
(1)符合ITU-T G.711建议
(2)PCM编码器输入信号为:
一个13位逻辑矢量的均匀量化值:D0,D1…D12 其中:D0为极性位,取值范围在-4096~+4096之间; 一个占空比为1/32的8K/S的取样时钟信号; 一个占空比为50%的2.048KB/S的合路时钟信号;
(3)PCM编码器输出信号为:
一个8位逻辑矢量的13折线非均匀量化值:C0,C1…C7 其中:C0为极性位.C0=1为正,C0=0为负; 一个占空比为1/32的8K/S的取样时钟信号; 一个占空比为50%的2.048KB/S的合路时钟信号;
(4)PCM译码器输入信号为:
一个8位逻辑矢量的13折线非均匀量化值:C0,C1…C7 其中:C0为极性位.C0=1为正,C0=0为负; 一个占空比为1/32的8K/S的取样时钟信号; 一个占空比为50%的2.048KB/S的合路时钟信号;(5)PCM译码器输出信号为:
一个13位逻辑矢量的均匀量化值:D0,D1…D12 其中:D0为极性位,取值范围在-4096~+4096之间; 一个占空比为1/32的8K/S的取样时钟信号; 一个占空比为50%的2.048KB/S的合路时钟信号;
B、时分多路参数指标:
(1)符合 ITU-T G.704 建议
(2)
16帧,2.0 ms复帧结构F0F1F2F3F4F5F6F7F8F9F10F11F12F13F14F1532路时隙,256 bit,125 s帧结构TS***2******262728293031帧同步时隙偶帧TS0×0011011话路时隙(CH1 ~ CH15)信令时隙00001A211话路时隙(CH16 ~CH29)CH30帧同步信号488 ns复帧同步信号F1abcda备用比特bcd3.91 s奇帧TS0×1A111111CH1CH
1(3)时分复接器输入信号为:
一个8位数据总线D7~D0(即30路PCM话音并行数据
公用总线 ;
一个一次群串行位同步时钟2.048MB/S信号;(4)时分分接器输出信号为:
一个一次群串行合路数据流2.048MB/S信号;
一个30位逻辑矢量时隙脉冲信号(每位对应一路时隙脉
冲);
一个一次群串行位同步时钟2.048MB/S信号; C、QDPSK解调器参数指标:
(1)QDPSK输入信号为:
一位2.048Mb/s串行合路数据;
一位8.192Mb/s输出时钟CLK(2)QDPSK输出信号为:
一个17位逻辑矢量载波抽样值输出;
一位8.192Mb/s输出时钟CLK
(3)提示:载波频率设为8.192MHz,每个载波周期8个样点
Cos:
07fffH,06d40H,03fffH,012bfH,0000H,012bfH,03fffH,06d40H
sin: 03fffH,06d40H, 07fffH,06d40H,03fffH,012bfH,0000H,012bfH-cos: 0000H,012bfH,03fffH,06d40H,07fffH,06d40H,03fffH,012bfH-sin:
03fffH,012bfH,0000H,012bfH,03fffH,06d40H, 07fffH,06d40H
三、原理说明
A、A律PCM编译码规则
说明:由表可知,编码由十位信号可知最高位为符号位,其他最先出现1的高位决定了编码的段落码,紧接着这个高位的后四位即段落码。译码时亦有此规律而来。
B、一次群时分复、分接器原理
C、QDPSK调制器原理(1)原理框图
说明:将QDPSK看成两路2DPSK分别调制,最后合成(2)差分编码
a、b到c、d满足差分编码关系
四、程序与仿真
--PCM编码,符合ITU-T G.711建议
--一个输入为13位逻辑矢量的均匀量化值,一个8000HZ占空比为1/32的取样脉冲--输出为八位逻辑矢量的A律PCM编码,和一个8000HZ的时钟
--虽然设计要求输入输出2.048MB/S时钟,个人觉得用不上,故舍去了--quartus软件是以下标大的位为高位,所以十三位输入采用D(12)为符号位
library ieee;--程序调用的库是IEEE库
use ieee.std_logic_1164.all;--定义了std_logic,std_logic_vector类型
entity PCMencode is
port(clkin :in std_logic;--输入时钟8000HZ
D
:in std_logic_vector(12 downto 0);--std_logic_vector全拼standard_logic标准逻辑矢量
C
:out std_logic_vector(7 downto 0);
clkout:out std_logic);end PCMencode;
architecture behavior of PCMencode is begin
proce(clkin,D)begin if clkin'event and clkin='1' then
if D(11)='1' then C
elsif D(10)='1' then C
elsif D(9)='1' then C
elsif D(8)='1' then C
elsif D(7)='1' then C
elsif D(6)='1' then C
elsif D(5)='1' then C
else C
end if;end if;end proce;clkout
--PCM译码
--输入A律八位PCM编码,占空比为1/32的8000HZ的去取样时钟
--输出为十三位逻辑矢量均匀量化值,占空比为1/32的8000HZ的去取样时钟 library ieee;use ieee.std_logic_1164.all;entity PCMdecode is port(clkin:in std_logic;
C:in std_logic_vector(7 downto 0);
D:out std_logic_vector(12 downto 0);
clkout:out std_logic);
end PCMdecode;architecture behavior of PCMdecode is signal temp:std_logic_vector(2 downto 0);begin
temp
proce(clkin)
begin
if clkin'event and clkin='1' then
case temp is
when “111”=>D
when “011”=>D
when “101”=>D
when “001”=>D
when “110”=>D
when “010”=>D
when “100”=>D
when “000”=>D
when others=>D
end case;
end if;end proce;clkout
--时分复接器
--输入一个8位数据总线(即30路PCM话音并行数据共用总线),--输入一个一次群串行位同步时钟2.048MB/S信号
--输出一个一次群串行合路数据流2.048MB/S信号;一个一次群串行位同步时钟2.048MB/S信号
--一个5位时隙地址总线信号(即30路PCM话音并行地址总线)--(其说明当前输入的数据总线上是哪个时隙数据)
--此程序要特别注意器件的选择,该程序选择cyclone系列EP1C6Q240C8时得到所期望的结果
--若选用其他器件譬如Stratix II系列的器件会丢失第一路信息
library ieee;--程序所调用的库是IEEE库
use ieee.std_logic_1164.all;--定义了std_logic,std_logic_vector类型
use ieee.std_logic_unsigned.all;--用到基于std_logic,std_logic_vector类型的--无符号的算术运算 entity fujieqi is port(clkin: in std_logic;
datain: in std_logic_vector(7 downto 0);--30路语音信号输入
dataout:out std_logic;
--输出串行数据流
ads:out std_logic_vector(4 downto 0);--五位时隙总线信号
clkout:out std_logic);--输出时钟
end fujieqi;architecture behav of fujieqi is shared variable tscount:std_logic_vector(8 downto 0);--时隙计数器 shared variable bitcount:std_logic_vector(2 downto 0);--位计数器 begin p1:proce(clkin)--位时钟和时隙计数 begin if clkin'event and clkin='1' then
if bitcount=“111” then
bitcount:=“000”;
tscount:=tscount+'1';
else bitcount:=bitcount+'1';
end if;end if;end proce p1;p2:proce(clkin)variable regester:std_logic_vector(7 downto 0);--定义一个内部的寄存器,--用于寄存输入的八位数据
variable temp:std_logic_vector(7 downto 0);--定义一个中间变量,用于数据的串行输出 begin if clkin'event and clkin='1' then
ads
if bitcount=“000” then
if tscount(5 downto 0)=“000000” then
regester:=“10011011”;
--双帧计数为0时传帧同码
elsif tscount(5 downto 0)=“100000” then
regester:=“11111111”;
--双帧计数为32时传勤务信息
elsif tscount=“000010000” then
regester:=“00001111”;
--复帧计数为16时传复帧同步码
elsif tscount(4 downto 0)=“10000” then
regester:=“11111111”;
--除F0帧外,每帧的第16时隙都传信令信息
else regester:=datain;
--不满足以上条件时传语音信号
end if;
temp:=regester;
--并串转换
dataout
else
temp(7 downto 1):=temp(6 downto 0);--右移
dataout
end if;end if;clkout
--QDPSK调制器,这里采用把一路QDPSK信号分为正交的两路2PSK分别调制,最后合成--输入一位2.048MB/S合路数据流,一位8.192MB/S输入时钟,内部进程所需时钟由分频而得
--输出一位8.192MB/S时钟,一个17位逻辑矢量载波抽样值输出
--由于FPGA器件适合做乘法运算,所以相干载波由八个样点表示,那么乘法运算转为适合 FPGA--器件加法运算
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;--定义了有符号与无符号类型,及基于这些类型上的算术运算 use ieee.std_logic_unsigned.all;entity qdpsk is port(clkin8192: in std_logic;
datain:in std_logic;
clkout8192:out std_logic;
dataout: out std_logic_vector(16 downto 0));end qdpsk;architecture behavior of qdpsk is signal clk1024: std_logic;signal clk2048: std_logic;shared variable a,b,c,d: std_logic;signal n:std_logic_vector(2 downto 0);--n为一个三位的计数器,用于控制八个样点的输出 signal q:std_logic_vector(1 downto 0);--c&d结合状态
signal count:std_logic_vector(2 downto 0);--对输入时钟计数,利用该三位计数器分频得到1.024mb/s的时钟
begin p1:proce(clk1024)--串并转换
variable tem:std_logic_vector(2 downto 0);begin if(clk2048'event and clk2048='1')then if tem(0)='0' then
a:=tem(1);--偶数位
b:=tem(2);--奇数位
tem:=datain&“01”;else tem:=datain&tem(2 downto 1);end if;end if;end proce p1;
--p1:proce(clk1024)--p1进程也可以这么写,这样少一个分频,更加简洁--variable xx:std_logic_vector(1 downto 0);--begin--if clk1024'event and clk1024='1' then--
xx(1):=din;--elsif(clk1024'event and clk1024='0')then--
xx(0):=din;--
b
p2:proce(clk1024)--差分编码 variable temp:std_logic;begin temp:=(c xor d);if clk1024'event and clk1024='1' then
if temp='0' then
c:=not(b xor c);
d:=a xor d;
else
c:=a xor c;
d:=not(b xor d);
end if;
end if;end proce p2;p3:proce(clkin8192)--计数和分频并根据c&d的状态输出已调信号 begin
if clkin8192'event and clkin8192='1' then
count
clk1024
clk2048
if count=“000”then
n
else n
end if;end if;if clkin8192'event and clkin8192='1' then if q=“00” then case n is when “000” => dataout dataout dataout dataout dataout dataout dataout dataoutnull;end case;elsif q=“01” then case n is when “000” => dataout dataout dataout dataout dataout dataout dataout dataoutnull;end case;elsif q=“10” then case n is when “000” => dataout dataout dataout dataout dataout dataout dataoutdataoutnull;end case;elsif q=“11” then case n is when “000” => dataout dataout dataout dataout dataout dataout dataout dataoutnull;end case;end if;end if;end proce p3;clkout8192
--时分分接程序
--同步码捕获三次后方确认同步完成,若失步三次后重新捕获
--输入一个一次群串行合路数据流2.048MB/S信号,一个一次群串行位同步时钟2.048MB/S信号
--输出一个一次群串行合路数据流2.048MB/S信号,一个30位逻辑矢量时隙脉冲信号(每位对应一路时隙脉冲)--一个一次群串行位同步时钟2.048MB/S信号
--输出串行数据流分别于A1……A31相与即可得到各路话音信号
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;
entity fenjieqi is port(datain,clkin:in std_logic;--输入2.048MB/S的合路数据流,输入--串行位同步时钟2.048MB/S
A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A17,A18, A19,A20,A21,A22,A23,A24,A25,A26,A27,A28,A29,A30,A31:out std_logic;--输出30位逻辑矢量时隙脉冲信号,与dataout相与的结果就是所选择的一路语音--输出
clkout,dataout:out std_logic);--输出串行数据流和输出时钟 end fenjieqi;
architecture behave of fenjieqi is signal regester,singlecount:std_logic_vector(7 downto 0):=“00000000”;--regester为八位移位寄存器用于捕获同步码,singlecount为单帧计数器
signal doublecount:std_logic_vector(8 downto 0):=“000000000”;--双帧计数器以位为单位 signal catch:std_logic:='0';--同步码捕捉状态标志0表捕捉态,1表示同步态
signal syncount,lostcount:std_logic_vector(1 downto 0):=“00”;--同步计数器以位为单位--与失步计数器
begin
P1:proce(clkin)--利用移位寄存器暂存当前输入码,敏感信号为时钟上升沿--即当时钟上升沿到达时该进程执行一次
begin if clkin'event and clkin='1' then--时钟上升沿有效暂存输入数据
regester
P2:proce(clkin)--同步码捕捉,同步保持比较
begin if clkin'event and clkin='0' then--时钟下降沿有效验证是否为同步码
--及验证落后于暂存刚好半个时钟周期,敏感信号为时钟下降沿,即时钟下降沿到达一次程序执行一次
doublecount
if catch='0' then
--catch为0时为捕捉态
if syncount=“00” then
if regester=“10011011” then
syncount
--表示第一次捕捉到同步码,将其次数加一,并且让输出变为第八位
end if;
elsif doublecount=“000000110” then--已捕捉到同步码的同时验证捕获
if regester=“10011011” then
if syncount=“10” then catch
--验证同步次数达到3次时转为同步状态
else syncount
end if;
else syncount
end if;
end if;
else
--catch为1,同步态时,同步保持比较
if doublecount=“000000110” and regester/=“10011011” then
--表示同步时验证不是同步码
if lostcount=“10” then catch
--验证失步次数达到三次时转为捕捉状态
else lostcount
end if;
end if;
end if;end if;end proce P2;
P3:proce(clkin,singlecount,catch)--时钟上升沿有效,译码输出 begin if clkin'event and clkin='1' then
if catch='1' then
dataout
if singlecount>=“00000111”and singlecount
if singlecount>=“00001111”and singlecount
if singlecount>=“00010111”and singlecount
if singlecount>=“00011111”and singlecount
if singlecount>=“00100111”and singlecount
if singlecount>=“00101111”and singlecount
if singlecount>=“00110111”and singlecount
if singlecount>=“00111111”and singlecount
if singlecount>=“01000111”and singlecount
if singlecount>=“01001111”and A10
if singlecount>=“01010111”and A11
if singlecount>=“01011111”and A12
if singlecount>=“01100111”and A13
if singlecount>=“01101111”and A14
if singlecount>=“01110111”and A15
if singlecount>=“10000111”and A17
if singlecount>=“10001111”and A18
if singlecount>=“10010111”and A19
if singlecount>=“10011111”and A20
if singlecount>=“10100111”and A21
if singlecount>=“10101111”and A22
if singlecount>=“10110111”and A23
if singlecount>=“10111111”and A24
if singlecount>=“11000111”and A25
if singlecount>=“11001111”and A26
if singlecount>=“11010111”and A27
if singlecount>=“11011111”and A28
if singlecount>=“11100111”and A29
if singlecount>=“11101111”and
singlecount
singlecount
A10
A13
if singlecount>=“11110111”and A31
end if;end if;end proce P3;clkout
singlecount
A31
+
五、心得体会
这次课程设计老师十三周布置任务,我是我所在小组的组长。那时通信原理的书还有好几章没怎么看,VHDL语言我自己又没选,所以一开始压力就很大。虽然十二周就已经把vhdl语言看了些,但quartus平台还是不熟悉。十三周期中考试,十四周从网上下了些fpga的开发教程,熟悉了quartus软件,熟悉了一些小的经典程序的编写。虽然做了这些前期准备,自己真正开始课程设计的时候还是遇到了不少的困难。通信原理的书上的原理基本理解,但把它运用到课程设计中去,还是有困难。譬如说pcm编码书上用的是逐次逼近法编码,但所使用的fpga器件的编程与这个有很大不同,显的更加简单。再如QDPSK调制,虽然基本原理和书上一样,但由于是FPGA器件,把载波相乘转化成了载波抽样。让我认识到理论到实践还有很长的路要走。当作做完课程设计回头看书,反而更加清晰了。学工科就是如此,实践往往能让自己理解的更深刻,前期的伦理理解也很重要,不然不知如何下手。编程是实在的,我一直有种畏惧感,因为实践的机会少,也没什么头绪,这次编程,通过团队的合作,通过资料的参考,反复的调试仿真,让我找到可编程的一种激情,虽然程序编的不是很好,还有很多毛病,但我了解的这个流程,我比以前更加喜欢编程,也有了努力地方向。编程看再多的程序不如自己编个小程序,这才是提高编程能力的方法,要有个小项目,要尽量自己写程序。团队成员的帮助也相当重要,能发现你不能发现的问题。总之,这次课程设计收获颇多。自己的编程能力亟待加强!