首页 > 技术文章 > 数据交织模块---Verilog代码

chensimin1990 2020-06-02 22:08 原文

数据交织模块---Verilog代码

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/05/25 11:50:02
// Design Name: 
// Module Name: DATA_interleaver
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module DATA_interleaver(


    input           wire                DINT_CLK,
    input           wire                DINT_RST,
    input           wire                DINT_DIN,
    input           wire                DINT_ND,
    input           wire     [8:0]      INDEX_IN,
    input           wire     [1:0]      MODE_CON,
    output          reg                 DINT_DOUT,             //output register
    output          reg                 DINT_RDY             //synchronize with output

    );



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

reg DIN;
reg ND;
reg [8:0] INDEX;
reg [1:0] MODE;

always @ (negedge DINT_RST or posedge DINT_CLK)     
begin
    if(!DINT_RST)                                 
    begin
        DIN <= 1'b0;
        ND <= 1'b0;
        INDEX <= 9'b000000000;
        MODE <= 2'b00;
    end
    else 
    begin
        if (DINT_ND)
        begin
            DIN <= DINT_DIN;
            ND <= DINT_ND;
            INDEX <= INDEX_IN;
            MODE <= MODE_CON;
        end
        else 
        begin
            DIN <= 1'b0;
            ND <= 1'b0;
            INDEX <= 9'b000000000;
        end
    end
end

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

wire RST;            //reset of IP core, enable under high leavel

assign RST=~DINT_RST;  

// counter cycle is 384 to generate read address of DINT_RAM_1

wire [9:0] Q_1;         //RCOUNT_1 counter of output

rcount_1 RCOUNT_1 (
    .Q(Q_1),
    .CLK(DINT_CLK),
    .CE(REN_1),                                           
    .ACLR(RST)
);


wire [9:0] RA_1;     //DINT_RAM_1 read address

assign RA_1 = Q_1;        

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

reg        WAC_1;      //control write address of 1st interleaver
reg [9:0]  WA_1;      //DINT_RAM_1 write address
reg        WEN_1;     //DINT_RAM_1 enable write
reg        REN_1;     //DINT_RAM_1 enable read 
reg        DIN_1;     //DINT_RAM_1 input register
reg        DINT_RDY_1;      //DINT_RAM_1 enable output


always @ (negedge DINT_RST or posedge DINT_CLK)       
begin 
    if(!DINT_RST)    
    begin
          WAC_1 <= 1'b0;
          WA_1  <= 10'b0000000000;
          WEN_1 <= 1'b0;
          DIN_1 <= 1'b0;
          REN_1 <= 1'b0;
          DINT_RDY_1 <= 1'b0;
    end
    else 
    begin
        case(MODE)
        2'b10:
        begin
            if(ND)
            begin
                if(!WAC_1)     // input data write in the BRAM first half part and the end alternatively, under control of WAC_1.         
                       WA_1 <= (INDEX[3:0]<<3)+(INDEX[3:0]<<2)+INDEX[8:4];    
                   else 
                       WA_1 <= (INDEX[3:0]<<3)+(INDEX[3:0]<<2)+INDEX[8:4]+192;                                                                               
                
                WEN_1 <= 1'b1;                                                                           
                DIN_1 <= DIN;     

                if(INDEX==191)                        
                   begin                                          
                      WAC_1<=~WAC_1;
                       REN_1<=1'b1;
                   end
            end

            else 
              begin
                  WA_1<=10'b0000000000;
                   WEN_1<=1'b0;                                                                                               
                   DIN_1<=1'b0;
              end

              if (Q_1==191 || Q_1==383)                  //finish read of BRAM
                REN_1<=1'b0;
        end
        endcase        `

        if (REN_1)                                               
            DINT_RDY_1<=1'b1;                                       
          else                                            
            DINT_RDY_1<=1'b0;                    
    end    
end 

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

wire DOUT_1;         //DINT_RAM_1 output

// BRAM: depth is 384 bits, the 1st interleaver BRAM to store the data which already adjust the order

dint_ram DINT_RAM_1 (
    .addra(WA_1),
    .addrb(RA_1),
    .clka(DINT_CLK),
    .clkb(DINT_CLK),
    .dina(DIN_1),
    .doutb(DOUT_1),
    .enb(REN_1),
    .sinitb(RST),
    .wea(WEN_1));


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

wire [4:0] Q_2;         //RCOUNT_2 counter of output

count24 WCOUNT_2 (
    .Q(Q_2),
    .CLK(DINT_CLK),
    .CE(DINT_RDY_1),
    .ACLR(RST));

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

wire [4:0] RA_2;         //DINT_RAM_2 read address

count24 RCOUNT_2 (
    .Q(RA_2),                                       
    .CLK(DINT_CLK),
    .CE(REN_2),                                    
    .ACLR(RST));


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

reg WEN_2;                 //DINT_RAM_2 enable write
reg DIN_2;                 //DINT_RAM_2 input register
reg WAC_2;                 //control write address of 2ed interleaver
reg REN_2;                 //DINT_RAM_2 enable read
reg DINT_DV;             //enable output
reg [4:0] WA_2;             //DINT_RAM_2 write address


always @ (negedge DINT_RST or posedge DINT_CLK)       
begin
    if(!DINT_RST)                                 
      begin
          WEN_2 <= 1'b0;
          DIN_2 <= 1'b0;
          WAC_2 <= 1'b0;
          WA_2 <= 5'b00000; 
          REN_2 <= 1'b0;
          DINT_DV <= 1'b0; 
          DINT_DOUT <= 1'b0;
          DINT_RDY <= 1'b0;
      end
      else 
      begin
          case(MODE)
          2'b10:
          begin
              if(DINT_RDY_1)                //input data to the 2ed interleaver after finish the 1st interleaver
              begin
                  WEN_2 <= 1'b1;                                    
                DIN_2 <= DOUT_1;
                if (WAC_2)                  //process the input data, change the write address or not with 12bits cycle alternatively, under control of WAC_2
                begin               
                     WA_2[4:1] <= Q_2[4:1];                            
                    WA_2[0]   <= ~Q_2[0];
                end 
                else 
                    WA_2 <= Q_2;
              end
              else 
              begin
                  WEN_2 <= 1'b0;
                DIN_2 <= 1'b0; 
              end

              if (Q_2==11 || Q_2==23)                          //finish write, begin to read
            begin                                            
                WAC_2<=~WAC_2;
                REN_2<=1'b1;
            end
            
            if (RA_2==23 && !DINT_RDY_1)                             
                REN_2<=1'b0;        
          end
          endcase    

         if(REN_2)                                               
            DINT_DV<=1'b1;
          else
            DINT_DV<=1'b0;

        if(DINT_DV)                                         //data output
        begin                                           
            DINT_DOUT <= DOUT_2;                                        
            DINT_RDY  <= 1'b1;                                    
        end                                             
          else
        begin
            DINT_DOUT <=1'b0;
            DINT_RDY  <=1'b0;
        end
      end
end


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

wire DOUT_2;         //DINT_RAM_2 output

// BRAM: depth is 32bits, as 2ed interleaver, change the write address too

dint_ram2 DINT_RAM_2 (
    .A(WA_2),
    .CLK(DINT_CLK),
    .D(DIN_2),
    .WE(WEN_2),
    .DPRA(RA_2),
    .QDPO_CLK(DINT_CLK),                                       
    .QDPO(DOUT_2),
    .QSPO(QSPO),                                           
    .QDPO_RST(RST));

endmodule

 

推荐阅读