您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页TS流嵌入控制数据的设计

TS流嵌入控制数据的设计

来源:爱go旅游网
TS流嵌入控制数据的设计

设计的要求是将控制数据嵌入到MPEG-2 TS 流中的空帧之中。相关的端口信息如下:

图中的TS_IN[7:0]、CLK、SYNC分别为MPEG-2 TS 流的数据信号、字节时钟、同步信号。时序图如下:

… … …

MPEG-2 TS流的基本单元是帧结构,分为数据帧和空帧。每帧包含188个字节,第一个字节为同步字节,即HEX“47”;空帧的标志是第二字节的低5位和第三字节全为‘1’,即HEX“1FFF”。

DIN[7:0]、CLK_W、EN分别是需要嵌入的控制数据、相应的字节时钟和数据使能。 RESET是系统的复位信号。

TS_OUT[7:0]是嵌入了控制数据的MPEG-2 TS 流,码率与输入TS流相同。

注意:CLK与CLK_W相差很大,且不同步。TS流是高速数据流(本设计假定为

10MHz),控制数据DIN是低速码流(本设计假定为300KHz)。

实现功能:本设计假定TS流的帧长为10个字节。TS流中的空帧很多,将某些空帧的数据区全换为控制数据DIN(帧同步字节和空帧标志不变),按照TS流格式进行传输。TS流数据帧中的数据和控制数据不能出现丢失。

设计要求:完成HDL的描述,用EDA开发系统完成综合、时序仿真验证。提交设计报告文档(含设计思路、HDL设计程序、综合结果、时序仿真结果及说明等)。文档为word2003或word2003的兼容版本,文档名的格式为:学号_姓名_课程设计。

报告提交截止时间:2012年5月20日,逾期不候。抄袭者计为0分。

一、 设计思想

1、 系统程序流程图

开始 Reset=1? Y N 各寄存器变量清零 是否有空帧信号? N Ts数据流保持原样输出 Y 将7个控制数据插入Ts数据流,一旦插入完毕,停止插入,ts流数据保持原样输出

2、 查找空帧程序流程图

首先根据外部输入使能信号en来存储控制数据,en是在一个clk_w(300Khz)周期内持续一个clk(10Mhz)周期的使能信号,这样就保证了在一个clk_w周期内只存一个控制数据到fifo,避免将控制数据重复存入fifo。

当en=1时,en使能信号有效,将一个控制数据存fifo,同时开始计数(cnt1=cnt1+1),以保证fifo中存有7个控制数据时,及时将其插入到Ts数据流中。

当fifo中存有7个控制数据时,发出一个控制数据准备好信号,同时将计数器及时清零(cnt1=0),这样就保证了在找空帧时,如果有en使能信号有效,就可以继续将控制数据写入fifo前7个数据的后面,fifo的深度是10,即保证控制数据不丢失。

当rdy=1; 表明fifo中已经存有7个控制数据,同时开始查找空帧,可以由同步信号标志47和47后面的两个数分别为1F和FF来判断。找到空帧后,停止在继续查找,将rdy及时清零,另外发出一个找到空帧的标志信号rd_en=1,表明在下一个clk到来时可以准备将fifo中存放的控制数据插入到Ts数据流中。

开始 en=1? Y N wr_en=1;将控制数据写入fifo,同时开始计数cnt1=cnt1+1; cnt1=7? Y N 表明fifo中存有7个控制数据时,发出一个控制数据准备好信号rdy=1;同时将计数变量清零cnt1=0; rdy=1? Y N rdy=1;开始由同步信号标志47和47后面的两个数分别为1F和FF来查找空帧 是否找到空帧? N Y 产生一个空帧准备好信号,停止查找空帧rdy=0;

3、 系统功能模块图

clk(10Mhz) din en fifo模块 7个控制数据准备好 数据 选择 模块 ts_in ts_out clk(10Mhz)

二、 设计中需注意的问题

1、 在本次设计中出现最大的问题就是fifo,首先是存储深度问题,由于我使用的fifo

主要是靠读写指针和mem来得到其深度的。这个fifo代码对于2的幂次方深度的是很容易实现的,因为这样fifo存储深度可以直接由指针的位数来控制。在本次设计中由于要实现fifo为10字节的存储深度,所以读写指针的位数为3位,而这样的话指针将在0-15之间循环移动,相关代码如下:

reg [7:0] mem [9:0]; // fifo存储深度为10 reg [3:0] rp, wp; // 读指针和写指针

为了控制好指针在0-9之间循环移动,才能实现设计要求,故需要对指针控制进行

相关修改,如下所示:

begin // 由于存储深度是10,所以必须保证写指针在0-9之间移动 if(wp<9) wp <= (wr && ~full_in) ? (wp + 1'b1) : wp; else wp <= (wr && ~full_in) ? 0 : wp; end

begin // 由于存储深度是10,所以必须保证读指针在0-9之间移动

if(rp<9) rp <= (rd && ~empty_in)? (rp + 1'b1): rp; else rp <= (rd && ~empty_in)? 0: rp; end

图1、fifo深度测试

2、 在本次设计中还遇到fifo的数据读出问题,因为由测试数据可以看到fifo一直只能

读出01 00 01 00 01这些控制数据,一开始怎么修改程序都没弄明白到底是哪儿出问题了,还以为控制数据没写进fifo。后来通过单步运行,一步一步查看相关寄存器值的情况,才发现fifo中存储的控制数据是正确的,指针移动也是正确的,这样就可以马上得出结论是读出的时候出现了问题,然后在主控程序里面查看调用fifo模块的代码,还是正确的,这个问题一直困扰了我好几天,后来我一直在想为什么fifo中存储的控制数据是正确的,而只读到01 00 01 00 01这些控制数据呢?那么肯定是位数不够,后来我再查看主控程序,终于让我发现了问题的所在,原来对fifo读出端口dataout没有进行定义。即dataout正确的定义和fifo模块调用如下: wire [7:0] dataout; // fifo数据输出口

//对fifo模块进行调用

Synfifo uut ( .datain(datain), .rd(rd_en), .wr(wr_en), .rst(reset), .clk(clk), .dataout(dataout) );

图2、fifo数据读出出错分析

3、 在本次设计中,对于7个控制数据的插入问题,我一开始是采用先找空帧,找到后

产生一个空帧准备好信号(null_rdy=1),然后再根据null_rdy的值是否为1来插入控制数据,代码如下:

if(null_rdy==0) ts_out=ts_in; else if(null_rdy==1) begin rd_en=1; //开始从fifo读出数据 ts_out=dataout; test=dataout; cnt3=cnt3+1; if(cnt3==7) begin cnt3=0; rd_en =0; null_rdy=0; end end

但是这样的结果是将导致数据被重复读出,如下图所示,数据41被重复读出:

图3、fifo数据重复读出出错分析

为了实现设计要求,得到正确的结果,将选择判断条件修改如下:

if(rd_en==0) ts_out=ts_in; // 如果fifo写使能信号无效,则ts流数据保持原样输出 else if(rd_en==1) begin // 如果fifo写使能信号生效,将fifo中的7个控制数据插入ts流 ts_out=dataout; fifo_out=dataout; cnt3=cnt3+1; end

if(cnt3==7) begin // 控制fifo中的7个控制数据插入ts流,一旦插入完毕,则fifo读使能信号无效,ts流数据保持原样输出 cnt3=0; rd_en=0; end

4、 在查找空帧的时候,一开始是定义了三个寄存器变量对ts流中同步信号47和后面的两个数进行存储并判断ts流中同步信号47后面的两个数是否分别为8'h1F和8'hFF。代码如下:

if(rdy==1) begin

if(sync==1) mem3[0]=ts_in; else if(cnt2==1) mem3[1]=ts_in; else if(cnt2==2) begin mem3[2]=ts_in; if((mem3[1]==8'h1F)&&(mem3[2]==8'hFF)) begin rd_en=1; rdy=0; end

end cnt2=cnt2+1; if(cnt2==3) cnt2=0; end

但这样会导致资源消耗过大,因为3个mem3寄存器组都是7位的,基本上没怎么利用。故优化如下:

if(rdy==1) begin // 当准备好信号有效时,开始查找空帧 if(sync==1) flag=0; // sync对应的是ts流中的同步信号47 else if(cnt2==1) flag=(ts_in==8'h1F)?1:0; // 判断ts流中紧跟同步信号47后面的数是否为8'h1F

else if(cnt2==2) begin flag=((ts_in==8'hFF)&&(flag==1))?1:0; // 判断ts流中同步信号47后面的两个数是否分别为8'h1F和8'hFF rd_en=flag ? 1: rd_en;// 若满足ts流中同步信号47后面的两个数分别为8'h1F和8'hFF,则找到空帧rd_en生效,开始将fifo数据读出 end

cnt2=cnt2+1; if(cnt2==3) cnt2=0; // 只考虑ts流中同步信号47和后面的两个数的情况,所以要对计数变量cnt2及时清零 end rdy= rd_en ? 0:rdy; // 找到空帧后,停止在继续查找,及时清零

5、 在本次设计中en使能信号是通过clk_w(300Khz)的下降沿来产生一个持续时间为一个clk(10Mhz)时钟周期的信号。在实际工程中,也可以通过D触发器将clk_w信号延迟一个clk时钟周期来实现。

6、 本次中所用到的ts数据流和控制数据流是通过自己手动设定的值,通过对文本文件

读取命令将数据读出来。代码如下:

$readmemh(\"tsdata.txt\ // tsdata.txt中存有100个ts数据流

$readmemh(\"controlflow.txt\ // controlflow.txt中存有28个控制数据

always@(negedge clk) begin if(i<99) begin ts_in=mem1[i]; if(ts_in==8'h47) sync = 1; else sync = 0; i=i+1; end else i=0; end

always@(negedge clk_w) begin en=1; #100 en=0; if(j<28) begin din=mem2[j]; j=j+1; end else j=0;

end

7、 需要插入的控制数据如下图所示:

图4、din中输入的控制数据流

三、 时序仿真及程序代码

1、时序仿真图

如图所示,当fifo中有7个控制数据时,将第一组制数据为01 02 03 04 55 41 23插入到ts_out数据流的空帧中,空帧位置为47 1F FF后面的7个数据,由ts_in可以看到图中是以00表示空帧位置的。

第二组插入的控制数据为56 12 78 89 56 32 21

第三组插入的控制数据为45 87 89 10 23 02 00

第四组插入的控制数据为14 55 64 99 08 01 40

2、综合结果

3、功耗分析

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务