如何开网店不用自己发货,东莞响应式网站实力乐云seo,wordpress sae 上传,昌吉州建设局网站FPGA#xff1a;RS编码仿真过程
RS码是一种纠错性能很强的线性纠错码#xff0c;能够纠正随机错误和突发错误。RS码是一种多进制BCH码#xff0c;能够同时纠正多个码元错误。
之前已经记录了在MATLAB中进行rs编解码的过程#xff0c;现在利用FPGA的IP核实现RS编码的过程RS编码仿真过程
RS码是一种纠错性能很强的线性纠错码能够纠正随机错误和突发错误。RS码是一种多进制BCH码能够同时纠正多个码元错误。
之前已经记录了在MATLAB中进行rs编解码的过程现在利用FPGA的IP核实现RS编码的过程方便使用RS编码。
这个过程分成两部分来记录这篇主要记录rs编码过程。
1. 开始准备
在FPGA设计通信系统的过程中进行rs编译码需要用到rs编译码的IP核这个IP核已经分享可以直接下载。也已经通过程序自己编写编译码的过程但是完全没有必要现成的IP核用好就可以了。
同时为了更好的理解FPGA中rs编码的过程这个仿真程序的参数是可以与记录的MATLAB教程相对应的。
同时在使用IP核的重要的一步需要下载对应的pdf文档这个能够帮助更好的使用IP核编写自己的程序。
2. RS编码IP核
RS编码IP核全名 Reed-Solomon Encoder首先看这个rs编码IP核的需要设置的参数。 这里面和MATLAB仿真对应的参数设置是Symbol Width,这个对应MATLAB中的参数m,也就是符号的位宽Data Symbols(k)和Symbols Per Block(n)分别对应k和n。这里的设置注意k的限制是和n相差正偶数。简单来说就是每一次k个数据被编码然后生成n个数据每个数据的位宽是m然后参数Field Polynomial是多项式这个所对应的和MATLAB中的也是一样的这在文档中有。 然后注意剩下的参数其中第一个Code Specification参数选择第一个选项Custom其他的选项可以对应不同的协议的这个详细的可以查看文档这个直接选择Custom然后参数Scaling Factor(h)这个参数可以设置成默认的1然后注意Generator Start参数设置为1. 这两个参数的解释参照技术文档中的说法是h是生成器多项式根索引的比例因子第二个参数是生成多项式第一个根的伽罗瓦域对数这两个参数直接都设置成1就可以了。
然后再Implementation参数设置页面中需要设置的参数相对较少。 可以参考如上设置选择一个通道然后把m_axis_output_tready信号勾选上。同时注意Latency的数值是多少这个可以与生成的编码数据对应上这里main设置完为5相当于编码后的输出延时5个clk。
3. 代码编写
接下来进行代码编写直接上代码rs_encoder.v。在这里是利用自然数进行编码0-15。大体思路是用有效信号控制输入的数据使得在有效的时候依次输入0-15。这里面的ready信号和valid信号相关控制可以直接看程序和最后的仿真时序。编码的参数如上面的设置m4,n15,k3,ploy19。
timescale 1ns / 1psmodule rs_encoder(input clk, //时钟input rst_n // 复位 高电平复位
// input [7:0] data_in, // 输入的待编码数据
// output [7:0] dataout // 输出的解码数据);wire rs_encode_input_tready; // 编码输入准备信号
reg rs_encode_input_tvalid_reg; // 编码输入有效信号
reg rs_encode_input_tready_reg;
wire rs_encode_input_tlast;
reg rs_encode_input_tlast_reg;
wire[7:0] rs_encode_data;
wire rs_encode_output_tvalid;
wire rs_encode_output_tlast;
wire rs_enocde_output_tready;
reg rs_enocde_output_tready_reg;parameter K 3; // 对应MATLAB仿真中的k和n的值这个在IP核设置中已经有体现
parameter N 4; //
parameter L 15; // 编码之后的数据长度reg [3:0] datain_num; // 每一组编码的原始数据个数
reg [5:0] dataout_num; //输出编码数据的个数// 设计输入数据
reg [3:0] datain;
always(posedge clk)beginif(~rst_n)begindatain 4b0;rs_encode_input_tready_reg 1b0;rs_encode_input_tvalid_reg 1b0;rs_encode_input_tlast_reg 1b0;rs_enocde_output_tready_reg 1b0;datain_num 4b0;endelse beginrs_encode_input_tready_reg rs_encode_input_tready;rs_encode_input_tvalid_reg 1b1;if(rs_encode_input_tready 1b1 rs_encode_input_tvalid_reg 1b1)begin // 在ready 和valid信号都有效的时候才开始编码数据可以在这里计数编码的个数。datain datain 4b1;datain_num 4b1 datain_num;rs_enocde_output_tready_reg 1b1;endelse beginendend
end// 根据每一组编码的组数来确定数据顺序 控制最后一个tlast信号。
always(posedge clk)beginif(~rst_n)beginrs_encode_input_tlast_reg 1b0; // 这个信号是需要在一组中的最后一个数据时候信号处于高电平 和k的大小对应endelse beginif(datain_num K)beginrs_encode_input_tlast_reg 1b1;endelse beginrs_encode_input_tlast_reg 1b0; //然后重新置零endend
endwire [3:0] data_in;
assign data_in datain;rs_encoder_0 rs_encoder_0_ins ( //latency 5clk.aclk(clk), // input wire aclk.aresetn(rst_n), // input wire aresetn.s_axis_input_tdata(data_in), // input wire [7 : 0] s_axis_input_tdata.s_axis_input_tvalid(rs_encode_input_tvalid_reg), // input wire s_axis_input_tvalid.s_axis_input_tready(rs_encode_input_tready), // output wire s_axis_input_tready.s_axis_input_tlast(rs_encode_input_tlast_reg), // input wire s_axis_input_tlast.m_axis_output_tdata(rs_encode_data), // output wire [7 : 0] m_axis_output_tdata.m_axis_output_tvalid(rs_encode_output_tvalid), // output wire m_axis_output_tvalid.m_axis_output_tready(rs_enocde_output_tready_reg), // input wire m_axis_output_tready.m_axis_output_tlast(rs_encode_output_tlast) // output wire m_axis_output_tlast
);// 通过编码模块输出的valid信号和ready信号来记录输出数据的个数
always(posedge clk)beginif(~rst_n)begindataout_num 6b0;endelse beginif(rs_encode_output_tvalid1b1 rs_enocde_output_tready_reg1b1)begindataout_num dataout_num 6b1;if(dataout_num 6d15)begindataout_num 6b0;endendelse beginendend
endendmodule
首先利用MATLAB仿真看一下[0,1,2,3,4,5,6,7,8]这几个编码后的数据是多少在MATLAB仿真中用的是矩阵所以结果得到的也是矩阵三个数据一组所以相当于进行了三次编码 4. 仿真测试
然后添加一个testbench文件然后程序运行起来。rs_tb.v这个程序比较简单就是进行初始化设置时钟和复位信号。
timescale 1ns / 1psmodule rs_tb();reg l_clk;
reg rst_n;rs_encoder rs_test_ins(.clk(l_clk), //时钟.rst_n(rst_n) // 复位 高电平复位
// input [7:0] data_in, // 输入的待编码数据
// output [7:0] dataout // 输出的解码数据);initial l_clk 1;
always #5 l_clk !l_clk; //15.625 initial beginrst_n 0;#40;rst_n 1;#320;//#50000000;#320;
// $stop;
end
endmodule
然后运行仿真可以得到. 首先看第一个蓝色标线ready信号和valid信号同时为高此时输入的编码数据有三个,分别为0,1,2,然后经过5个clk延迟第2个蓝色标线处编码输出的ready信号和valid信号同时为高表示编码输出有效得到的编码结果为0,1,2,1,15,0,12,3,2,12,14,3,15,13,13,然后是第二组编码数据的结果3,4,5与MATLAB仿真的结果是能够对应的上的。
这个仿真中的s_tlast信号可以调整一下每输入三个数据拉高一次防止出错。
等下一部分进行rs解码的仿真。