博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

导频数据插入---Verilog

Posted on 2020-06-29 21:43  沉默改良者  阅读(812)  评论(0编辑  收藏  举报

导频数据插入---Verilog

module DATA_pilot_insertion(
    input    wire          DPI_CLK,
    input    wire          DPI_RST,
    input    wire  [7:0]   DPI_DIN_RE,
    input    wire  [7:0]   DPI_DIN_IM,
    input    wire          DPI_START,
    input    wire          DPI_ND,
    input    wire  [5:0]   INDEX_IN,
    output   reg   [7:0]   DPI_RE,                       //模块输出数据实部寄存器
    output   reg   [7:0]   DPI_IM,                       //模块输出数据虚部寄存器
    output   reg           DPI_RDY                       //模块输出有效信号寄存器
);

//--------------------------------------------------------------------------
//为保证模块所有输入信号同步,在模块输入端口为所有信号加1级缓存

reg   [7:0]   DIN_RE;       //输入数据实部缓存
reg   [7:0]   DIN_IM;        //输入数据虚部缓存
reg           ND;            //输入使能信号寄存器
reg   [5:0]   INDEX;        //输入数据标号缓存

always @ (negedge DPI_RST or posedge DPI_CLK)    
begin
    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
end

//--------------------------------------------------------------------------
// 导频极性控制信号生成模块实例化

wire PPC_RST;

assign PPC_RST=RST|DPI_START;     //DPI_PPC既由全局复位信号控制,在新帧输入时也需复位


//实际上是一个初始状态为全“1”的扰码器,用来生成导频极性控制信号,如果输出“0”,则
//意味着4个导频信号的极性为“1、1、1、-1”,若输出为“1”,则表明导频信号的极性应为“-1、1、1、1”。

wire  PPC_OUT;

SCRAMBLER DPI_PPC (
    .EN(ND),                                   //ND信号作为DPI_PPC的工作触发信号。需要DPI_PPC每一个symbol
    .RST(PPC_RST),                               //输出一个极性控制信号,而ND每个Symbol拉高1次,且比DPI_START
    .OUT(PPC_OUT));                               //(用来控制DPI_PPC的复位)晚一个周期拉高。

//--------------------------------------------------------------------------
// 数据顺序调整和导频信号插入

reg   [6:0]    WA;         //DPI_RAM_RE/IM的写地址缓存
reg            WAC;        //DPI_RAM_RE/IM的写地址控制
reg            REN;        //DPI_RAM_RE/IM的读使能信号寄存器
reg            WEN;        //DPI_RAM_RE/IM的写使能信号寄存器
reg [7:0]      RAMR_DIN;        //DPI_RAM_RE的输入缓存
reg [7:0]      RAMI_DIN;        //DPI_RAM_IM的输入缓存
reg [3:0]      STATE;           //导频插入处理状态机状态寄存器
reg            DOUT_EN;         //模块输出使能信号寄存器
reg            PIEN;            //导频插入使能信号寄存器

always @ (negedge DPI_RST or posedge DPI_CLK)
begin
    if(!DPI_RST)                                 
      begin
          WAC <= 1'b0;
        WA <= 7'b0000000;
          WEN <= 1'b0;
          REN <= 1'b0;
        RAMR_DIN <= 8'b00000000;
        RAMI_DIN <= 8'b00000000;
        PIEN <= 1'b0;
        STATE <= 4'b0001;
          DOUT_EN <= 1'b0;
      end
      else 
      begin
          if (ND)    //在输入使能信号的控制下,待处理数据经过地址变换后写入DPI_RAM_RE/IM
          begin
              WA[6] <= WAC;    //将WAC信号作为RAM写地址缓存的最高位以控制数据写入RAM的不同部分,WAC为0时写入RAM的低64bytes,反之,写入RAM的高64bytes    
              case (INDEX) 
                0,1,2,3,4 :                                      WA[5:0] <= INDEX+38 ;     //对输入数据标识INDEX进行处理生成相应数据的写地址,从而将输入数据按照所需调整的顺序直接写入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 ;    // 58,59,60,61,62,63
                24,25,26,27,28,29 :                           WA[5:0] <= INDEX-23 ;    // 1,2,3,4,5,6
                30,31,32,33,34,35,36,37,38,39,40,41,42 :      WA[5:0] <= INDEX-22 ;    // 8,9,10,11....20
                43,44,45,46,47 :                              WA[5:0] <= INDEX-21 ;    // 22
           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的相应地址空间中
          begin
              if(!PPC_OUT)                                    //具体插入导频的极性由PPC_OUT控制,其值为0时插入1、-1、1、1
              begin
                   case (STATE)                                //插入过程由一个Moore有限状态机来实现                      
                       4'b0001:                                //STATE为4'b0001、4'b0010、4'b0100、4'b1000时,将各个状态应插入的导频信号及其对应
                       begin                                    //的地址信号写入RAM的写入寄存器和写地址寄存器中,同时将写使能信号拉高,状态也相应转入下一个
                           WA[5:0] <= 7;
                           RAMR_DIN <= 8'b01000000;
                        RAMI_DIN <= 8'b00000000;
                           STATE <= 4'b0010;
                       end
                       4'b0010:
                       begin
                           WA[5:0]<=21;
                           RAMR_DIN<=8'b11000000;
                           RAMI_DIN<=8'b00000000;       
                           STATE <= 4'b0100;
                       end
                       4'b0100:
                       begin
                          WA[5:0]<=43;
                        RAMR_DIN<=8'b01000000;
                        RAMI_DIN<=8'b00000000;
                        STATE<=4'b1000;
                    end
                       4'b1000:
                    begin
                              WA[5:0]<=57;
                        RAMR_DIN<=8'b01000000;
                           RAMI_DIN<=8'b00000000;
                           STATE<=4'b0001;
                           PIEN<=1'b0;                             //第4个导频输入完成时,WAC取反,准备下一Symbol数据的输入,同时将导频插入使能信号
                           REN<=1'b1;                             //拉低,完成这个symbol的导频插入操作。并将读使能信号拉高,以开始完成处理的数据的
                           WAC<=~WAC;                             //输出
                       end
                   endcase
              end
              else 
              begin
                  case (STATE)                                 //PPC_OUT为1时插入-1、1、-1、-1
                       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            
              end
          end
          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
end

//--------------------------------------------------------------------------

//周期为128的计数器单元,输出计数信号作为DPI_RAM的读地址信号,帮助完成处理的数据依次读出

wire [6:0] RA;                                    //DPI_RAM_RE/IM的读地址信号

counter_128 DPI_RAGEN (
    .Q(RA),                                       //计数器单元的输出作为RAMs的读地址信号,控制数据按顺序读出 
    .CLK(DPI_CLK),
    .CE(REN),                                      //读使能信号作为计数器单元的时钟使能信号以控制其工作
    .ACLR(RST));

//--------------------------------------------------------------------------
// DPI_RAM实例化

wire RST;

assign RST=~DPI_RST;                       //IP core的复位信号,高电平有效

wire [7:0]    RAMR_DOUT;                     //DPI_RAM_RE的输入信号
wire [7:0]    RAMI_DOUT;                     //DPI_RAM_IM的输入信号

//两块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));

//--------------------------------------------------------------------------

always @ (negedge DPI_RST or posedge DPI_CLK)
begin
    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
end

endmodule