N = 64;cpLen = 16; dataLen = N - cpLen;dataIdx = reshape(modData,dataLen/N,N);
时间: 2023-10-31 19:06:49 浏览: 66
这段代码主要是将输入的调制数据 modData 按照 OFDM 调制中的数据块长度和循环前缀长度进行划分和重组。
其中,N 表示 OFDM 调制中的数据块长度,cpLen 表示循环前缀长度,dataLen 表示数据部分的长度,即 N 减去循环前缀长度。
reshape(modData,dataLen/N,N) 将 modData 进行重组,每 N 个调制数据作为一组,一共分为 dataLen/N 组,最终得到一个大小为 dataLen/N × N 的矩阵 dataIdx。
这个矩阵 dataIdx 中的每一行代表一个 OFDM 调制中的数据块,其中前 dataLen 列为数据部分,后 cpLen 列为循环前缀部分。
相关问题
unsigned int AESDecrypt(AESInfo_t *aesInfoP, unsigned char *pPlainText, const unsigned char *pCipherText, unsigned int dataLen) { unsigned int i; unsigned char *pPlainTextBack = pPlainText; if (pPlainText != pCipherText) { memcpy(pPlainText, pCipherText, dataLen); } //当mode=AES_MODE_CBC时需要从最后一块数据开始解密 pPlainText += dataLen - 4 * Nb; for (i = dataLen / (4 * Nb); i > 0 ; i--, pPlainText -= 4 * Nb) { BlockDecrypt(aesInfoP, pPlainText); if (AES_MODE_CBC == aesInfoP->mode) { if (1 == i) {//原来的第一块数据是初始变量加密的 XorBytes(pPlainText, aesInfoP->pIV, 4 * Nb); } else { XorBytes(pPlainText, pPlainText - 4 * Nb, 4 * Nb); } } } //因为数据需要16字节对齐,可能有填充数据,需要去除后面的填充数据 return AESDelPKCS7Padding(pPlainTextBack, dataLen); }具体解释
这段代码实现了AES解密函数AESDecrypt,它的参数包括一个AESInfo_t类型的结构体指针aesInfoP,一个指向解密后的明文的缓冲区pPlainText,一个指向密文的缓冲区pCipherText,以及数据长度dataLen。函数返回值为unsigned int类型。
首先,将指向明文缓冲区的指针pPlainText保存在一个指针变量pPlainTextBack中,然后判断pPlainText是否与pCipherText相等。如果不相等,则将pCipherText中的数据复制到pPlainText中。这个步骤是为了防止解密时修改密文数据。
接着,根据AES的工作模式,当mode=AES_MODE_CBC时需要从最后一块数据开始解密。因此,将pPlainText指针指向最后一块数据。然后使用循环从最后一块数据开始逐块解密,直到所有数据块都被解密。在每次解密后,如果AES的工作模式是CBC,需要对解密后的数据进行异或操作。对于最后一块数据,需要使用初始变量进行异或操作。对于其他块数据,需要使用前一块数据进行异或操作。
最后,因为数据需要16字节对齐,可能有填充数据,需要去除后面的填充数据。这个步骤使用AESDelPKCS7Padding函数实现,它返回去除填充后的数据长度。
module uart_tx( input clk, input rst_n, output reg tx, input [7:0] data, input tx_en, output tx_done, input [3:0] DataLen_wire, input isParity_wire, input ParityMode_wire ); reg busy; //线路状态指示,高为线路忙,低为线路空闲 reg send; reg wrsigbuf; reg wrsigrise; reg presult; reg [7:0] cnt; reg [3:0] DataLen = 4'd8; reg isParity = 1'b0; reg paritymode = 1'b0; reg [3:0] dataN_send = 4'd0; //记录当前将要发送的数据(亦即已发送的数据位个数) always @(negedge rst_n) begin //在rst拉低时配置数据位长度、是否使用校验位、奇偶校验 DataLen <= DataLen_wire; isParity <= isParity_wire; paritymode <= ParityMode_wire; end //检测上升沿 always @(posedge clk) begin wrsigbuf <= tx_en; wrsigrise <= (~wrsigbuf) & tx_en; end //发送结束信号 assign tx_done = ~busy; //启动串口发送程序 always @(posedge clk) begin if(wrsigrise && (~busy)) begin //当发送命令有效且线路为空闲时,启动新的数据发送 send <= 1'b1; end else if(cnt==((DataLen+2+isParity)<<4)-4) begin send <= 1'b0; end end //串口发送程序,16个时钟发送一个bit always @(posedge clk or negedge rst_n) begin if(!rst_n) begin tx <= 1'b1; busy <= 1'b0; cnt <= 8'd0; presult <= 1'b0; dataN_send <= 4'd0; end else if(send==1'b1) begin if(cnt==8'd0) begin tx <= 1'b0; //产生起始位 dataN_send <= 4'd0; presult <= paritymode; busy <= 1'b1; cnt <= cnt + 8'd1; end else if(cnt==(dataN_send+1)<<4 && dataN_send<DataLen) begin tx <= data[dataN_send]; //发送数据位 小端 presult <= data[dataN_send]^presult; busy <= 1'b1; cnt <= cnt + 8'd1; dataN_send <= dataN_send+1; end else if(cnt==(DataLen+1)<<4) begin if(isParity)begin tx <= presult; //发送奇偶校验位 busy <= 1'b1; cnt <= cnt + 8'd1; end else begin tx <= 1'b1; //发送停止位 busy <= 1'b1; cnt <= cnt + 8'd1; end end else if(cnt==((DataLen+2)<<4)-4) begin if(isParity) begin tx <= 1'b1; //发送停止位 busy <= 1'b1; cnt <= cnt + 8'd1; end else begin tx <= 1'b1; busy <= 1'b0; cnt <= cnt + 8'd1; end end else if(cnt==((DataLen+3)<<4)-4) begin tx <= 1'b1; busy <= 1'b0; cnt <= cnt + 8'd1; end else begin cnt <= cnt + 8'd1; end end else begin tx <= 1'b1; cnt <= 8'd0; busy <= 1'b0; end end endmodule
这是一个串口发送模块的Verilog代码,它可以将输入的数据通过串口发送出去。它支持配置数据位长度、是否使用校验位、奇偶校验等功能。该模块的工作原理是在clk的上升沿检测发送命令信号tx_en,如果该信号为有效且线路为空闲,就启动新的数据发送。在发送过程中,每16个时钟发送一个bit,包括起始位、数据位、校验位和停止位。发送完毕后,会发出tx_done信号。
阅读全文