4.9.1 循环前缀
4.9.2 加窗
4.9.3 模块的实现
Ram时序图:
由ram的时序图可以看出,ram在读取上一帧时钟的同时,开始写下一个帧;
添加16个前缀:(一组数据的后面16个)
加窗:
输出的输入的64个数据;
module CP_ADDER(CP_INR,CP_INI,CP_ND,CP_CLK,CP_RST,
CP_INDEX,CP_OUTR,CP_OUTI,CP_RDY);
input [7:0] CP_INR;
input [7:0] CP_INI;
input CP_ND;
input CP_CLK;
input CP_RST;
input [5:0] CP_INDEX;
output [7:0] CP_OUTR;
output [7:0] CP_OUTI;
output CP_RDY;
reg [7:0] CP_OUTR;
reg [7:0] CP_OUTI;
reg CP_RDY;
wire ND1; // 第一个ram的写使能信号
wire ND2; // 第二个ram的写使能信号
wire rst = ~CP_RST; // ram的复位信号,低电平有效
wire [7:0] dout1R; // ram输出缓存
wire [7:0] dout1I;
wire [7:0] dout2R;
wire [7:0] dout2I;
reg i;
reg rdy;
reg [7:0] FIRSTR1; // 用于存储第一个值
reg [7:0] FIRSTI1;
reg [7:0] FIRSTR2;
reg [7:0] FIRSTI2;
reg [5:0] q;
reg [5:0] j;
assign ND1 = CP_ND&(~i);
assign ND2 = CP_ND&i;
bram bram1r(
.a(CP_INDEX),
.d(CP_INR),
.we(ND1),
.clk(CP_CLK),
.dpra(q),
.qdpo_ce(rdy),
.qdpo_rst(rst),
.qdpo_clk(CP_CLK),
.qdpo(dout1R));
bram bram1i(
.a(CP_INDEX),
.d(CP_INI),
.we(ND1),
.clk(CP_CLK),
.dpra(q),
.qdpo_ce(rdy),
.qdpo_rst(rst),
.qdpo_clk(CP_CLK),
.qdpo(dout1I));
bram bram2r(
.a(CP_INDEX),
.d(CP_INR),
.we(ND2),
.clk(CP_CLK),
.dpra(q),
.qdpo_ce(rdy),
.qdpo_rst(rst),
.qdpo_clk(CP_CLK),
.qdpo(dout2R));
bram bram2i(
.a(CP_INDEX),
.d(CP_INI),
.we(ND2),
.clk(CP_CLK),
.dpra(q),
.qdpo_ce(rdy),
.qdpo_rst(rst),
.qdpo_clk(CP_CLK),
.qdpo(dout2I));
always @ ( negedge CP_RST or posedge CP_CLK ) // 决定使用哪组ram
begin
if ( !CP_RST )
begin
i <= 0 ;
end
else
begin
if ( CP_INDEX == 63 )
begin
i <= ~ i;
end
else
begin
i <= i;
end
end
end
always @ ( negedge CP_RST or posedge CP_CLK ) // ram的读使能信号
begin
if ( !CP_RST )
rdy <= 0;
else
begin
if ( CP_INDEX == 62 )//所有的读出时钟使能;
rdy <= 1;
if( j == 63 )
rdy <= 0 ;
end
end
always @ ( negedge CP_RST or posedge CP_CLK ) // ram的读地址
begin
if ( !CP_RST )
q <= 0;
else
begin
if ( CP_INDEX == 63 || rdy)
q <= q + 1;
else
q <= 0;
end
end
always @ ( negedge CP_RST or posedge CP_CLK )
begin
if ( !CP_RST )
j <= 0;
else
begin
if ( rdy )
j <= q ;
else
j <= 0;
end
end
always @ ( negedge CP_RST or posedge CP_CLK ) // 将符号的第一个值存起来,用于加窗
begin
if ( !CP_RST )
begin
FIRSTR1 <= 0;
FIRSTI1 <= 0;
FIRSTR2 <= 0;
FIRSTI2 <= 0;
end
else
if ( CP_INDEX == 0 )
begin
case(i)
1'b0:
begin
FIRSTR1 <= CP_INR;
FIRSTI1 <= CP_INI;
end
1'b1:
begin
FIRSTR2 <= CP_INR;
FIRSTI2 <= CP_INI;
end
default:
begin
FIRSTR1 <= 0;
FIRSTI1 <= 0;
FIRSTR2 <= 0;
FIRSTI2 <= 0;
end
endcase
end
end
always @ ( negedge CP_RST or posedge CP_CLK ) // 输出
begin
if ( !CP_RST )
begin
CP_OUTR <= 0;
CP_OUTI <= 0;
CP_RDY <= 0;
end
else
begin
if ( CP_INDEX == 48 ) // 加窗处理
begin
CP_RDY <= 1;
if ( ~i )
begin
CP_OUTR <= ( CP_INR + FIRSTR2 ) >> 1;
CP_OUTI <= ( CP_INI + FIRSTI2 ) >> 1;
end
else
begin
CP_OUTR <= ( CP_INR + FIRSTR1 ) >> 1;
CP_OUTI <= ( CP_INI + FIRSTI1 ) >> 1;
end
end
if ( CP_INDEX > 48 )
begin
CP_OUTR <= CP_INR ;
CP_OUTI <= CP_INI;
CP_RDY <= 1;
end
else
begin
if( rdy )
begin
CP_RDY <= 1;
if ( i )
begin
CP_OUTR <= dout1R ;
CP_OUTI <= dout1I ;
end
else
begin
CP_OUTR <= dout2R ;
CP_OUTI <= dout2I ;
end
end
else if ( (~rdy) && (~CP_ND) )
begin
CP_OUTR <= 0;
CP_OUTI <= 0;
CP_RDY <= 0;
end
end
end
end
endmodule