原创 终于把交织器调试好了

2011-7-26 09:25 1143 8 8 分类: FPGA/CPLD

哎,第六天了,终于把交织器给调试好了。还是多亏了学长的帮忙啊。有时候,学技术有人提点真是一种万幸啊。一个人在一种思维中打转往往会出不来,这时候要是有人能以另外一种思维给予提示,就会大有帮助。作为一个初学者,这条路还有很远呢,继续加油吧!!!

下面说说交织器:

交织器在通信中还是占有挺重要的地位的,尤其是对那些精度要求很高的系统。

实 际信道中产生的错误往往是突发错误或突发错误与随机错误并存,如果首先把突发错误离散成随机错误,然后再去纠随机错误,那么系统的抗干扰性能就会进一步得 到提高。交织器的作用就是将比较长的突发错误或多个突发错误离散成随机错误,即把错误离散化。交织器按交织方式可分为交织深度固定的交织器(如分组交织器 和卷积交织器)和交织深度不断变化的随机交织器;按交织对象可分为码元交织器和码段交织器(也有数据交织和比特交织的说法),这里主要讨论的是交织深度固 定的数据交织器。

一 帧有32个数据,每个数据5个bit。现在要做的就是把每一帧的32个数据打乱后输出。用的是矩阵交织,把32个数据变成4*8的矩阵,按行(顺序)往 RAM 里写数据,然后按列读出数据,这样就可以完成交织效果。即写入数据为 0,1,2,3,4,5,6,7;8,9,10,11,12,13,14,15;..........

然后读出的为0,8,16,24;1,9,17,25;..............

下面给出原代码吧。供大家交流,有什么不妥的还请不要见笑。

module interleaver(clk,rst,
                   din,
                   dataout
                   );

/*整体输入输出端口的声明*/                  
input clk,rst;
input[4:0] din;
output[4:0] dataout;

reg[4:0] dataout;

/*两个RAM端口的声明*/
reg[4:0] address_r1;
reg[4:0] address_r2;
reg we1;
reg we2;

/*地址计数的声明*/
reg[2:0] cnt1;
reg[2:0] cnt2;
reg[2:0] addr1;
reg[2:0] addr2;

/*数据选择显示的控制信号声明*/
reg temp1,wctl1;
reg temp2,wctl2;

/*整体连线的声明*/
wire[4:0] address1;
wire[4:0] address2;
wire wren1;
wire wren2;
wire[4:0] dout1;
wire[4:0] dout2;

assign address1 = address_r1;
assign address2 = address_r2;
assign wren1 = we1;
assign wren2 = we2;


/*----------------------------------------------------------*/
//数据选择显示控制
always@(posedge clk or negedge rst) begin
      if(!rst) begin
                     temp1 <= 1'b0; wctl1 <= 1'b0;
                     temp2 <= 1'b0; wctl2 <= 1'b0;
               end
      else begin
                     temp1 <= we1; wctl1 <= temp1;
                     temp2 <= we2; wctl2 <= temp2;
           end
end

//两个RAM轮流读写,每次只显示读的RAM
always@(*) begin
       if((!wctl1)&&(wctl2)) begin dataout = dout1; end
       else if((!wctl2)&&(wctl1)) begin   dataout = dout2; end
       else begin dataout = 5'bz;  end
end

/*---------------------------------------------------------*/
//第一个RAM的交织处理过程
always@(posedge clk or negedge rst) begin
        if(!rst) begin address_r1 <= 0; cnt1 <= 3'd1; we1 <= 1'b1; end
        else case(we1)
              1'b1: begin
                      if(address_r1==5'd31) begin address_r1 <= 0; we1 <= 1'b0; end
                      else address_r1 <= address_r1 + 1'b1;
                    end
              1'b0: begin   
                     if(address_r1>5'd23) begin
                        address_r1 <= addr1;
                        if(cnt1==3'd7) cnt1 <= 3'd1;
                        else if(address_r1==5'd31)begin address_r1 <= 0; we1 <= 1'b1; end
                        else cnt1 <= cnt1 + 1'b1;  
                        end
                     else begin address_r1 <= address_r1 + 5'd8;  end
                    end
              default:  address_r1 <= 5'd0;
            endcase
end

/*----------------------------------------------------------------*/
//第二个RAM的交织处理过程
always@(posedge clk or negedge rst) begin
        if(!rst) begin address_r2 <= 0;  cnt2 <= 3'd1; we2 <= 1'b0; end
        else case(we2)
               1'b1: begin
                      if(address_r2==5'd31) begin address_r2 <= 0; we2 <= 1'b0; end
                      else address_r2 <= address_r2 + 1'b1;
                     end
               1'b0: begin
                       if(address_r2>5'd23) begin
                          address_r2 <= addr2;
                          if(cnt2==3'd7) cnt2 <= 3'd1;
                          else if(address_r2==5'd31) begin address_r2 <= 0; we2 <= 1'b1; end
                          else cnt2 <= cnt2 + 1'b1;  
                          end
                       else begin address_r2 <= address_r2 + 5'd8;  end
                    end
               default: address_r2 <= 5'd0;
             endcase
end

/*---------------------------------------------------------------*/
//地址映射(数据行写入,列读出的地址变化映射)
always@(posedge clk or negedge rst) begin
   if(!rst) begin  addr1 <= 0; addr2 <= 0; end
   else
   case(cnt1)
     3'd1: addr1 <= 3'd1;
     3'd2: addr1 <= 3'd2;
     3'd3: addr1 <= 3'd3;
     3'd4: addr1 <= 3'd4;
     3'd5: addr1 <= 3'd5;
     3'd6: addr1 <= 3'd6;
     3'd7: addr1 <= 3'd7;
     default: addr1 <= 3'd0;
     endcase
     
    case(cnt2)
     3'd1: addr2 <= 3'd1;
     3'd2: addr2 <= 3'd2;
     3'd3: addr2 <= 3'd3;
     3'd4: addr2 <= 3'd4;
     3'd5: addr2 <= 3'd5;
     3'd6: addr2 <= 3'd6;
     3'd7: addr2 <= 3'd7;
     default: addr2 <= 3'd0;
     endcase
end

/*--------------------------------------------------------------*/
//两个单口RAM的例化
single_ram    single_ram_inst1 (
    .address ( address1 ),
    .clock ( clk ),
    .data ( din ),
    .wren ( wren1 ),
    .q ( dout1 )
    );
    
single_ram    single_ram_inst2 (
    .address ( address2 ),
    .clock ( clk ),
    .data ( din ),
    .wren ( wren2 ),
    .q ( dout2 )
    );

endmodule

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条