哎,第六天了,终于把交织器给调试好了。还是多亏了学长的帮忙啊。有时候,学技术有人提点真是一种万幸啊。一个人在一种思维中打转往往会出不来,这时候要是有人能以另外一种思维给予提示,就会大有帮助。作为一个初学者,这条路还有很远呢,继续加油吧!!!
下面说说交织器:
交织器在通信中还是占有挺重要的地位的,尤其是对那些精度要求很高的系统。
实 际信道中产生的错误往往是突发错误或突发错误与随机错误并存,如果首先把突发错误离散成随机错误,然后再去纠随机错误,那么系统的抗干扰性能就会进一步得 到提高。交织器的作用就是将比较长的突发错误或多个突发错误离散成随机错误,即把错误离散化。交织器按交织方式可分为交织深度固定的交织器(如分组交织器 和卷积交织器)和交织深度不断变化的随机交织器;按交织对象可分为码元交织器和码段交织器(也有数据交织和比特交织的说法),这里主要讨论的是交织深度固 定的数据交织器。
一 帧有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条评论)
登录后参与讨论