4.7.1导频的位置和极性
4.7.2导频插入模块的硬件结构
4.7.3 导频插入模块的实现
matlab:
%6 映射与插入导频
function out1= insert(PPC_OUT,d)
% pn=[1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,1,1,-1,1,1,-1,1,1,1,1,1,1,-1,1,...
% 1,1,-1,1,1,-1,-1,1,1,1,-1,1,-1,-1,-1,1,-1,1,-1,-1,1,-1,-1,1,1,1,1,1,-1,-1,1,1,...
% -1,-1,1,-1,1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,-1,1,-1,1,-1,1,...
% -1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1];%used to scramble the pilot
end
% 导频插入;
if(PPC_OUT==0)
insert=[1 -1 1 1];
else
insert=[-1 1 -1 -1];
end
i=1;
k=1;
for i=1:5
out(i)=d(i);
i=i+1;
end
for i=6
out(i)=insert(1);
i=i+1;
end
for i=7:19
out(i)=d(i-1);
i=i+1;
end
for i=20
out(i)=insert(2);
i=i+1;
end
for i=21:26
out(i)=d(i-2);
i=i+1;
end
for i=27
out(i)=0;
end
for i=28:33
out(i)=d(i);
i=i+1;
end
for i=34
out(i)=insert(3);
i=i+1;
end
for i=35:47
out(i)=d(i-3);
i=i+1;
end
for i=48
out(i)=insert(4);
i=i+1;
end
for i=49:53
out(i)=d(i-4);
i=i+1;
end
if(i==54)
i=1;
end
for k=1:26
out1(k+37)=out(k)
k=k+1;
end
for k=27:37
out1(k)=0;
k=k+1;
end
for k=28:53
out1(k-27)=out(k)
k=k+1;
end
if(k==54)
k=0;
end
代码:
module DATA_pilot_insertion(DPI_DIN_RE,DPI_DIN_IM,INDEX_IN,DPI_ND,DPI_START,DPI_RST,
DPI_CLK,DPI_RE,DPI_IM,DPI_RDY);
input [7:0] DPI_DIN_RE;
input [7:0] DPI_DIN_IM;
input [5:0] INDEX_IN;
input DPI_ND;
input DPI_START;
input DPI_RST;
input DPI_CLK;
output [7:0] DPI_RE;
output [7:0] DPI_IM;
output DPI_RDY;
//******************************************************************************//
reg [7:0] DIN_RE; //输入数据实部缓存
reg [7:0] DIN_IM; //输入数据虚部缓存
reg ND; //输入使能信号寄存器
reg [5:0] INDEX; //输入数据标号缓存
reg [6:0] WA; //DPI_RAM_RE/IM的写地址缓存
reg [7:0] RAMR_DIN; //DPI_RAM_RE的输入缓存
reg [7:0] RAMI_DIN; //DPI_RAM_IM的输入缓存
reg REN; //DPI_RAM_RE/IM的读使能信号寄存器
reg WEN; //DPI_RAM_RE/IM的写使能信号寄存器
reg WAC; //DPI_RAM_RE/IM的写地址控制藕偶拇嫫?
reg PIEN; //导频插入使能信号寄存器
reg [3:0] STATE; //导频插入处理状态机状态寄存器
reg DOUT_EN; //模块输出使能信号寄存器
reg [7:0] DPI_RE; //模块输出数据实部寄存器
reg [7:0] DPI_IM; //模块输出数据虚部寄存器
reg DPI_RDY; //模块输出有效信号寄存器
wire [6:0] RA; //DPI_RAM_RE/IM的读地址信号
wire [7:0] RAMR_DOUT; //DPI_RAM_RE的输入信号
wire [7:0] RAMI_DOUT; //DPI_RAM_IM的输入信号
wire RST;
wire PPC_RST;
assign RST=~DPI_RST; //IP core的复位信号,高电平有效
assign PPC_RST=RST|DPI_START; //DPI_PPC既由全局复位信号控制,在新帧输入时也需复位
/**********************************************************************************/
/**************************** 输入信号缓存 ****************************/
//为保证模块所有输入信号同步,在模块输入端口为所有信号加1级缓存
always @ (negedge DPI_RST or posedge DPI_CLK)
if (!DPI_RST)
begin
DIN_RE<=8'b00000000;
DIN_IM<=8'b00000000;
ND<=1'b0;
INDEX<=6'b000000;
end
else
begin
if (DPI_ND)
begin
DIN_RE<=DPI_DIN_RE;
DIN_IM<=DPI_DIN_IM;
ND<=DPI_ND;
INDEX<=INDEX_IN;
end
else
begin
DIN_RE<=8'b00000000;
DIN_IM<=8'b00000000;
ND<=1'b0;
INDEX<=6'b000000;
end
end
/**********************************************************************************/
/**************************** DPI_RAM实例化 ****************************/
//两块1024bits(128×8bits)的双口块RAM,作为模块的存储器(数据实部和虚部各用一块),
//存放调整好顺序的数据信号和导频信号。为了实时处理数据的需要,RAM的存储深度为两个
//symbol的长度,每两个symbol依次写入前一半和后一半的地址空间中,保证前一symbol的读出
//与后一symbol的写入不发生冲突
dpi_ram DPI_RAM_RE (
.addra(WA),
.addrb(RA),
.clka(DPI_CLK),
.clkb(DPI_CLK),
.dina(RAMR_DIN),
.doutb(RAMR_DOUT),
.enb(REN),
.sinitb(RST),
.wea(WEN));
dpi_ram DPI_RAM_IM (
.addra(WA),
.addrb(RA),
.clka(DPI_CLK),
.clkb(DPI_CLK),
.dina(RAMI_DIN),
.doutb(RAMI_DOUT),
.enb(REN),
.sinitb(RST),
.wea(WEN));
/**********************************************************************************/
/******************* 导频极性控制信号生成模块实例化 *********************/
//实际上是一个初始状态为全“1”的扰码器,用来生成导频极性控制信号,如果输出“0”,则
//意味着4个导频信号的极性为“1、1、1、-1”,若输出为“1”,则表明导频信号的极性应为“-1、
//1、1、1”。
SCRAMBLER DPI_PPC (
//ND信号作为DPI_PPC的工作触发信号。需要DPI_PPC每一个symbol
//输出一个极性控制信号,而ND每个Symbol拉高1次,且比DPI_START
////(用来控制DPI_PPC的复位)晚一个周期拉高。
.(SCRAM_SEED(7'b1111111),
.SCRAM_CLK(DPI_CLK),
.SCRAM_DIN(1'b1),
.SCRAM_LOAD(1'b1),
.SCRAM_ND(ND),
.SCRAM_RST(PPC_RST),
.SCRAM_DOUT(PPC_OUT),
.SCRAM_RDY(SCRAM_RDY));
/**********************************************************************************/
/******************* 数据顺序调整和导频信号插入 ***********************/
always @ (negedge DPI_RST or posedge DPI_CLK)
if (!DPI_RST)
begin
WAC<=1'b0;
WA<=7'b0000000;
WEN<=1'b0;
RAMR_DIN<=8'b00000000;
RAMI_DIN<=8'b00000000;
PIEN<=1'b0;
STATE<=4'b0001;
REN<=1'b0;
DOUT_EN<=1'b0;
end
else
begin
if (ND) //在输入使能信号的控制下,待处理数据经过地址变换后写入DPI_RAM_RE/IM
begin
WA[6]<=WAC; //将WAC信号作为RAM写地址缓存的最高位以控制数据写入RAM的不同部分,WAC
case (INDEX) //为0时写入RAM的低64bytes,反之,写入RAM的高64bytes
0,1,2,3,4 : //对输入数据标识INDEX进行处理生成相应数据的写地址,从而将输入数据按照
WA[5:0]<=INDEX+38 ; //所需调整的顺序直接写入RAMs中
5,6,7,8,9,10,11,12,13,14,15,16,17 :
WA[5:0]<=INDEX+39 ;
18,19,20,21,22,23 :
WA[5:0]<=INDEX+40 ;
24,25,26,27,28,29 :
WA[5:0]<=INDEX-23 ;
30,31,32,33,34,35,36,37,38,39,40,41,42 :
WA[5:0]<=INDEX-22 ;
43,44,45,46,47 :
WA[5:0]<=INDEX-21 ;
default :
WA[5:0]<=0;
endcase
WEN<=1'b1; //生成写地址信号的同时,将写使能信号置高,并将数据写入RAMs的数据写入寄存器
RAMR_DIN<=DIN_RE;
RAMI_DIN<=DIN_IM;
if (INDEX==47)
PIEN<=1'b1; //数据写入操作完成后,将PIEN拉高,模块开始进行导频插入操作
end
else if (PIEN) //在PIEN的控制下,导频信号被写入RAM的相应地址空间中
if (!PPC_OUT) //具体插入导频的极性由PPC_OUT控制,其值为0时插入1、-1、1、1
case (STATE) //插入过程由一个Moore有限状态机来实现
4'b0001: //STATE为4'b0001、4'b0010、4'b0100、4'b1000时,将各个状态应插入的导频信号及其对应
begin //的地址信号写入RAM的写入寄存器和写地址寄存器中,同时将写使能信号拉高,状态也相应
WA[5:0]<=7; //转入下一个
RAMR_DIN<=8'b01000000; //导频实部为1
RAMI_DIN<=8'b00000000;
STATE<=4'b0010;
end
4'b0010:
begin
WA[5:0]<=21;
RAMR_DIN<=8'b11000000; //导频实部为-1
RAMI_DIN<=8'b00000000;
STATE<=4'b0100;
end
4'b0100:
begin
WA[5:0]<=43;
RAMR_DIN<=8'b01000000; //导频实部为1
RAMI_DIN<=8'b00000000;
STATE<=4'b1000;
end
4'b1000:
begin
WA[5:0]<=57;
RAMR_DIN<=8'b01000000; //导频实部为1
RAMI_DIN<=8'b00000000;
STATE<=4'b0001;
PIEN<=1'b0; //第4个导频输入完成时,WAC取反,准备下一Symbol数据的输入,同时将导频插入使能信号
REN<=1'b1; //拉低,完成这个symbol的导频插入操作。并将读使能信号拉高,以开始完成处理的数据的
WAC<=~WAC; //输出
end
endcase
else //PPC_OUT为1时插入-1、1、-1、-1
case (STATE)
4'b0001:
begin
WA[5:0]<=7;
RAMR_DIN<=8'b11000000;
RAMI_DIN<=8'b00000000;
STATE<=4'b0010;
end
4'b0010:
begin
WA[5:0]<=21;
RAMR_DIN<=8'b01000000;
RAMI_DIN<=8'b00000000;
STATE<=4'b0100;
end
4'b0100:
begin
WA[5:0]<=43;
RAMR_DIN<=8'b11000000;
RAMI_DIN<=8'b00000000;
STATE<=4'b1000;
end
4'b1000:
begin
WA[5:0]<=57;
RAMR_DIN<=8'b11000000;
RAMI_DIN<=8'b00000000;
STATE<=4'b0001;
PIEN<=1'b0;
REN<=1'b1;
WAC<=~WAC;
end
endcase
else
begin
WA[5:0]<=10'b000000;
WEN<=1'b0;
RAMR_DIN<=8'b00000000;
RAMI_DIN<=8'b00000000;
end
if (RA==63 || RA==127) //根据读地址信号判断读操作是否完成,以将读使能信号拉低。注意,由于每2个symbol
REN<=1'b0; //的数据共用一个存储器,所以它们的读操作完成对应不同的RA值
if (REN) //数据读出存储器
DOUT_EN<=1'b1; //在读出使能信号的控制下RAM开始输出数据,同时将输出使能信号拉高。因为IP核输出
else //数据刚好比读使能信号晚一个时钟,因此与第一级输出使能信号同步
DOUT_EN<=1'b0;
end
/**********************************************************************************/
/**************************** DPI_COUNT实例化 ****************************/
//周期为128的计数器单元,输出计数信号作为DPI_RAM的读地址信号,帮助完成处理的数据依次读出
counter_128 DPI_RAGEN (
.Q(RA), //计数器单元的输出作为RAMs的读地址信号,控制数据按顺序读出
.CLK(DPI_CLK),
.CE(REN), //读使能信号作为计数器单元的时钟使能信号以控制其工作
.ACLR(RST));
/**********************************************************************************/
/**************************** 数据输出控制 ****************************/
always @ (negedge DPI_RST or posedge DPI_CLK)
if (!DPI_RST)
begin
DPI_RE<=8'b00000000;
DPI_IM<=8'b00000000;
DPI_RDY<=1'b0;
end
else
begin
if (DOUT_EN) //数据数出
begin //在输出使能信号的控制下将数据DINT_RAM_2输出的数据写入其
DPI_RE<=RAMR_DOUT; //输出寄存器中,同时将这一级的输出有效信号拉高
DPI_IM<=RAMI_DOUT;
DPI_RDY<=1'b1;
end
else
begin
DPI_RE<=8'b00000000;
DPI_IM<=8'b00000000;
DPI_RDY<=1'b0;
end
end
endmodule
扰码模块:
module SCRAMBLER(EN,RST,OUT);
input EN;
input RST;
output OUT;
reg OUT;
reg [7:1] SCRAMBLER;
always @(negedge RST or posedge EN)
begin
if(!RST)
begin
OUT <= 0;
SCRAMBLER <= 7'b1111111;
end
else
begin
OUT <= SCRAMBLER[7] +SCRAMBLER[4];
SCRAMBLER <= {SCRAMBLER[6:1],SCRAMBLER[7]+SCRAMBLER[4]};
end
end
endmodule
tb:
`timescale 1ns/1ns
module DATA_pilot_insertion_tb();
reg [7:0] DPI_DIN_RE;
reg [7:0] DPI_DIN_IM;
reg [5:0] INDEX_IN;
reg DPI_ND;
reg DPI_START;
reg DPI_RST;
reg DPI_CLK;
wire [7:0] DPI_RE;
wire [7:0] DPI_IM;
wire DPI_RDY;
DATA_pilot_insertion DATA_pilot_insertion_inst(
.DPI_DIN_RE(DPI_DIN_RE),
.DPI_DIN_IM(DPI_DIN_IM),
.INDEX_IN(INDEX_IN),
.DPI_ND(DPI_ND),
.DPI_START(DPI_START),
.DPI_RST(DPI_RST),
.DPI_CLK(DPI_CLK),
.DPI_RE(DPI_RE),
.DPI_IM(DPI_IM),
.DPI_RDY(DPI_RDY));
integer i=0;
initial begin
INDEX_IN = 0;
DPI_ND = 0;
DPI_START = 0;
DPI_RST = 0;
DPI_CLK=0;
DPI_DIN_RE = 8'b0;
DPI_DIN_IM = 8'b0;
#20.1
DPI_START = 1;
DPI_RST = 1;
for (i=0;i<48;i=i+1)
begin
#10
DPI_ND = 1;
INDEX_IN = INDEX_IN+1;
DPI_DIN_RE ={$random}%8;
DPI_DIN_IM ={$random}%8;
end
DPI_ND = 0;
#100000
$stop;
end
always #5 DPI_CLK=~DPI_CLK;
endmodule
结果可知:由48个数据变成了52个数据;
中间27-37个数据为0;