FFT_fifo

本文介绍了一种FIFO控制模块的设计方法,通过状态机实现FIFO的读写控制,解决了采样速率与FFT写速率不匹配的问题。设计中使用了计数器来跟踪读操作,并在适当位置触发FFT的开始和结束包。

  fifo的控制属于本程序的第二大块,因为采样速率和fft的写速率不一致,所以需要加一个异步FIFO来做缓冲,采用了一个状态机来实现

FIFO的读写,状态机的第一个状态实现写FIFO,第二个状态来读fifo,这样实现了数据的缓冲,并且在合适的位置给fft开始包和结束包。

/*-----------------------------------------------------------------------

Date                :        2017-XX-XX
Description            :        Design for fifo_control.

-----------------------------------------------------------------------*/

module fifo_control
(
    //global clock
    input                    clk,            //system clock
    input                    rst_n,             //sync reset
    
    //fifo interface
    output    reg                rd_fifo_en,    
    output    reg                 wr_fifo_en,    
    input                      rdempty,
    input                      wrfull,
    
    //fft    interface
    input                    sink_ready,
    output                    sink_sop,
    output                    sink_eop,
    output                    sink_valid
    
); 


//--------------------------------
//Funtion :   读数据计数            
reg            [10:0]        read_cnt;


always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        read_cnt <= 11'd0;
    else if(rd_fifo_en)
        read_cnt <= read_cnt + 1'b1;
    else
        read_cnt <= 11'd0;
end

//--------------------------------
//Funtion :   fifo 读使能
reg                state_fifo;

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        state_fifo <= 1'd0;
        rd_fifo_en <= 1'b0;
        wr_fifo_en <= 1'b0;
    end
    else
        case(state_fifo)
        
        //写fifo
        1'd0 :
        begin
            if(wrfull && sink_ready)
            begin
                rd_fifo_en <= 1'b1;
                wr_fifo_en <= 1'b0;
                state_fifo <= 1'b1;
            end
            else
            begin
                rd_fifo_en <= 1'b0;
                wr_fifo_en <= 1'b1;
                state_fifo <= 1'b0;
            end
        end
        
        //读fifo
        1'd1 :
        begin
            if(rdempty)
            begin
                rd_fifo_en <= 1'b0;
                wr_fifo_en <= 1'b1;
                state_fifo <= 1'b0;
            end
            else
            begin
                rd_fifo_en <= 1'b1;
                wr_fifo_en <= 1'b0;
                state_fifo <= 1'b1;
            end
        end
        
        default : ;
        
        endcase
end


/* always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        rd_fifo_en <= 1'd0;
    else if(wrfull && sink_ready)
        rd_fifo_en <= 1'd1;
    else if(rdempty)
        rd_fifo_en <= 1'd0;
    else
        rd_fifo_en <= rd_fifo_en;
end

//--------------------------------
//Funtion :   fifo 写使能

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        wr_fifo_en <= 1'd1;
    else if(rdempty)
        wr_fifo_en <= 1'd1;
    else if(wrfull)
        wr_fifo_en <= 1'd0;
    else
        wr_fifo_en <= wr_fifo_en;
end */



//--------------------------------
//Funtion :   sink_sop sink_eop
assign        sink_sop = (read_cnt == 1'b1) ? 1'b1 : 1'b0;
assign        sink_eop = (read_cnt == 11'd2047) ? 1'b1 : 1'b0;




assign        sink_valid = rd_fifo_en;

endmodule
    

 

转载于:https://www.cnblogs.com/bixiaopengblog/p/7265048.html

module fft_scheduler ( input clk, input rst_n, input [15:0] gate_data [0:49], input gate_valid, output reg [159:0] fft_in_tdata [0:4], output reg [3:0] fft_in_tuser [0:4], output reg fft_in_tvalid [0:4], output reg fft_in_tlast [0:4] ); // 参数定义 localparam FFT_POINTS = 512; localparam GROUPS = 5; localparam CHANNELS_PER_GROUP = 10; // 状态寄存器 reg [2:0] state [0:GROUPS-1]; reg [8:0] sample_cnt [0:GROUPS-1]; // 中间寄存器用于数据拼接 reg [15:0] temp_data [0:GROUPS-1][0:CHANNELS_PER_GROUP-1]; genvar g, c; generate for (g = 0; g < GROUPS; g = g + 1) begin : group_loop for (c = 0; c < CHANNELS_PER_GROUP; c = c + 1) begin : channel_loop always @(posedge clk or negedge rst_n) begin if (!rst_n) begin temp_data[g][c] <= 0; end else if (state[g] == 1 && sample_cnt[g] < 500) begin temp_data[g][c] <= gate_data[g*CHANNELS_PER_GROUP + c]; end else begin temp_data[g][c] <= 0; end end end // 数据拼接逻辑 ($\sum_{i=0}^{9} 16\text{位} = 160\text{位}$) always @(posedge clk or negedge rst_n) begin if (!rst_n) begin fft_in_tdata[g] <= 0; fft_in_tuser[g] <= 0; fft_in_tvalid[g] <= 0; fft_in_tlast[g] <= 0; end else begin case (state[g]) 0: begin fft_in_tvalid[g] <= 0; fft_in_tlast[g] <= 0; if (gate_valid) begin state[g] <= 1; sample_cnt[g] <= 0; end end 1: begin fft_in_tvalid[g] <= 1; fft_in_tlast[g] <= (sample_cnt[g] == FFT_POINTS-1); fft_in_tuser[g] <= sample_cnt[g][3:0]; // 静态拼接 ($160\text{位} = 16 \times 10$) fft_in_tdata[g] <= { temp_data[g][9], temp_data[g][8], temp_data[g][7], temp_data[g][6], temp_data[g][5], temp_data[g][4], temp_data[g][3], temp_data[g][2], temp_data[g][1], temp_data[g][0] }; sample_cnt[g] <= sample_cnt[g] + 1; if (sample_cnt[g] == FFT_POINTS-1) state[g] <= 2; end 2: begin fft_in_tvalid[g] <= 0; fft_in_tlast[g] <= 0; state[g] <= 0; end endcase end end end endgenerate endmodule 这个程序正确吗,这个程序是你前面给出的。我现在ILA抓取fft_in_data数据为0,ILA抓取发现state都为0
09-06
module receive# ( parameter MAX_COL ='D256, parameter MAX_ROW = 'D256, parameter MAX_CNT = 'D32, parameter MAX_RE = 'D16 , // fft 矩阵大小 parameter RE2 = 'D256, // ram最大个数 parameter M = 'D2 )( input wire sysclk, input wire i_rst , input wire [127: 0] image_data, input wire i_hsync, input wire i_vsync ); wire image_dvalid = ((i_hsync)&& (i_vsync)); reg [15: 0] cnt_col ; reg [15: 0] cnt_row ; reg wr_en_1 ; reg cnt_flag; //reg [15: 0] cnt_num ; reg rd_en_1 ; wire s_axis_config_tready_0; wire s_axis_data_tready_0; //wire [31: 0]m_axis_data_tdata_0; wire [63: 0]m_axis_data_tdata_0; wire [15: 0]m_axis_data_tuser_0; wire m_axis_data_tvalid_0; wire m_axis_data_tlast_0; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_col <= 16’d0; else if ((image_dvalid == 1’b1) && (cnt_col == MAX_CNT - 1’b1)) cnt_col <= 16’d0; else if (image_dvalid == 1’b1) cnt_col <= cnt_col + 1’b1; else cnt_col <= 16’d0; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_row <= 16’d0; else if ((image_dvalid == 1’b1) && (cnt_col == MAX_CNT - 1’b1) && (cnt_row == MAX_ROW - 1’b1)) cnt_row <= 16’d0; else if ((image_dvalid == 1’b1) && (cnt_col == MAX_CNT - 1’b1)) cnt_row <= cnt_row + 1’b1; else cnt_row <= cnt_row; always@(posedge sysclk or negedge i_rst) if(!i_rst) wr_en_1 <= 1’b0; else if ((cnt_row< MAX_RE)&& (cnt_col <M)&& (image_dvalid == 1’b1)) wr_en_1 <= 1’b1; else wr_en_1 <= 1’b0; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_flag <= 1’b0; else if ((cnt_row< MAX_RE)&& (cnt_col <MAX_RE)&& (image_dvalid == 1’b1)) cnt_flag <= 1’b1; else cnt_flag <= 1’b0; always@(posedge sysclk or negedge i_rst) if(!i_rst) rd_en_1<= 1’b0; else if (cnt_flag == 1’b1) rd_en_1 <= 1’b1; else rd_en_1<= 1’b0; wire [15: 0] dout_fifo; wire full , empty; wire [127: 0] id; assign {id[15: 0], id[31: 16],id[ 47:32], id[63:48], id[ 79:64], id[ 95:80], id[111:96], id[ 127:112]} = image_data; fifo_16x1024 fifo_inst ( .clk(sysclk), // input wire clk .srst(~i_rst), // input wire srst .din(id), // input wire [15 : 0] din .wr_en(wr_en_1), // input wire wr_en .rd_en(rd_en_1), // input wire rd_en .dout(dout_fifo), // output wire [15 : 0] dout .full(full), // output wire full .empty(empty) // output wire empty ); //ram>> fft reg [7 : 0] re_addra; reg [7: 0] re_addrb; wire [15: 0] re_dout; reg re_wea; // 开始控制 reg [5: 0] cnt_re_addrb; reg re_web; always@(posedge sysclk or negedge i_rst) if(!i_rst) re_addra <= 8’d0; else if (re_addra== RE2 - 1’b1) re_addra <= 8’d0; else if(re_wea== 1’b1) re_addra <= re_addra+ 1’b1; else re_addra <= re_addra; always@(posedge sysclk or negedge i_rst) if(!i_rst) re_addrb<= 8’d0; else if (re_addrb== RE2 - 1’b1) re_addrb <= 8’d0; else if (re_web) re_addrb <= re_addrb+ 1’b1; always@(posedge sysclk or negedge i_rst) if(!i_rst) re_wea<= 1’b0; else if (rd_en_1 && ~empty) re_wea<= 1’b1; else re_wea<= 1’b0; // 输出端口控制 wire dou_flag; assign dou_flag = s_axis_data_tready_0 && (~s_axis_config_tready_0); reg dou_flag_reg ; reg [7: 0] cnt_ram_fft; //记录已完成的行数; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_ram_fft<= 8’d0; else if((cnt_ram_fft== MAX_RE -1’b1)&& (m_axis_data_tlast_0)) cnt_ram_fft<= 8’d0; else if (m_axis_data_tlast_0 == 1’b1) cnt_ram_fft<= cnt_ram_fft+ 1’b1; else cnt_ram_fft<=cnt_ram_fft; always@(posedge sysclk or negedge i_rst) if(!i_rst) dou_flag_reg<= 1’b0; else if(dou_flag ==1’b1) dou_flag_reg<= 1’b1; else dou_flag_reg<= 1’b0; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_re_addrb<= 6’d0; else if (cnt_re_addrb == MAX_RE+ 1’b1) cnt_re_addrb<= 6’d0; else if (dou_flag && ~(dou_flag_reg)&& (cnt_ram_fft> 1’b0)&& (cnt_ram_fft< 'd16)) cnt_re_addrb<= 6’d1; else if (((cnt_row<16’d1)&& (re_wea== 1’b1))||(cnt_re_addrb!= 1’b0)) cnt_re_addrb<= cnt_re_addrb+ 1’b1; else cnt_re_addrb<= 6’d0; always@(posedge sysclk or negedge i_rst) if(!i_rst) re_web<= 1’b0; else if (cnt_re_addrb!= 1’b0 && (cnt_re_addrb< 6’d17)) re_web <= 1’b1; else re_web<= 1’b0; /* reg [2: 0] cnt_ram_fft_rst_reg ; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_ram_fft_rst_reg<= 3’d0; else if (cnt_ram_fft_rst_reg == 3’d2) cnt_ram_fft_rst_reg<= 3’d0; else if (cnt_ram_fft_rst == 3’d3) cnt_ram_fft_rst_reg <= 3’d1; else if(cnt_ram_fft_rst_reg!= 3’d0) cnt_ram_fft_rst_reg<= cnt_ram_fft_rst_reg +1’b1; else cnt_ram_fft_rst_reg<= 3’d0; */ sim_du_ram_16x256 re_ram ( .clka (sysclk), // input wire clka .ena (i_rst), // input wire ena .wea (re_wea), // input wire [0 : 0] wea .addra (re_addra), // input wire [7 : 0] addra .dina (dout_fifo), // input wire [15 : 0] dina .clkb (sysclk), // input wire clkb .enb (re_web), // input wire enb .addrb (re_addrb), // input wire [7 : 0] addrb .doutb (re_dout) // output wire [15 : 0] doutb ); // 结束控制 reg [2: 0] cnt_ram_fft_rst; reg ram_fft_rst= 1’b1; reg s_axis_data_tlast_0; always@(posedge sysclk or negedge i_rst) if(!i_rst) s_axis_data_tlast_0<= 1’b0; else if (cnt_re_addrb== 8’d17) s_axis_data_tlast_0<= 1’b1; else s_axis_data_tlast_0<= 1’b0; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt_ram_fft_rst<= 1’b0; else if (m_axis_data_tlast_0== 1’b1) cnt_ram_fft_rst<= 1’b1; else if (cnt_ram_fft_rst == 3’d3) cnt_ram_fft_rst<= 1’b0; else if(cnt_ram_fft_rst >1’b0) cnt_ram_fft_rst<= cnt_ram_fft_rst +1’b1; else cnt_ram_fft_rst<= 1’b0; always@(posedge sysclk or negedge i_rst) if(!i_rst) ram_fft_rst<= 1’b1; else if(cnt_ram_fft_rst!= 1’b0) ram_fft_rst<= 1’b0; else ram_fft_rst<= 1’b1; reg s_axis_data_tvalid_0; always@(posedge sysclk or negedge i_rst) if(!i_rst) s_axis_data_tvalid_0<= 1’b0; else if(re_web== 1’b1) s_axis_data_tvalid_0<= 1’b1; else s_axis_data_tvalid_0<= 1’b0; /* reg [24: 0] cnt; reg flag = 1’b1; always@(posedge sysclk or negedge i_rst) if(!i_rst) cnt<= 25’d0; else cnt<= cnt+1’b1; always@(posedge sysclk or negedge i_rst) if(!i_rst) flag<= 1’b1; else if ((cnt ==25’d168) ||(cnt ==25’d169) ||(cnt ==25’d170)) flag<= 1’b0; else flag <= 1’b1; */ wire event_frame_started_0,event_tlast_unexpected_0,event_tlast_missing_0,event_status_channel_halt_0,event_data_in_channel_halt_0,event_data_out_channel_halt_0; xfft_0 ram_fft ( .aclk(sysclk), // input wire aclk .aresetn(ram_fft_rst), // input wire aresetn .s_axis_config_tdata(8’b1), // input wire [7 : 0] s_axis_config_tdata .s_axis_config_tvalid(1’b1), // input wire s_axis_config_tvalid .s_axis_config_tready(s_axis_config_tready_0), // output wire s_axis_config_tready .s_axis_data_tdata({32’d0,16’b0,re_dout}), // input wire [31 : 0] s_axis_data_tdata .s_axis_data_tvalid(s_axis_data_tvalid_0), // input wire s_axis_data_tvalid .s_axis_data_tready(s_axis_data_tready_0), // output wire s_axis_data_tready .s_axis_data_tlast(s_axis_data_tlast_0), // input wire s_axis_data_tlast .m_axis_data_tdata(m_axis_data_tdata_0), // output wire [31 : 0] m_axis_data_tdata .m_axis_data_tuser(m_axis_data_tuser_0), // output wire [15 : 0] m_axis_data_tuser .m_axis_data_tvalid(m_axis_data_tvalid_0), // output wire m_axis_data_tvalid .m_axis_data_tready(1’b1), // input wire m_axis_data_tready .m_axis_data_tlast(m_axis_data_tlast_0), // output wire m_axis_data_tlast .event_frame_started(event_frame_started_0), // output wire event_frame_started .event_tlast_unexpected(event_tlast_unexpected_0), // output wire event_tlast_unexpected .event_tlast_missing(event_tlast_missing_0), // output wire event_tlast_missing .event_status_channel_halt(event_status_channel_halt_0), // output wire event_status_channel_halt .event_data_in_channel_halt(event_data_in_channel_halt_0), // output wire event_data_in_channel_halt .event_data_out_channel_halt(event_data_out_channel_halt_0) // output wire event_data_out_channel_halt );以上是一次性输入8个16位数用fftip核做傅里叶变换 为什么出来的结果只有第一位是正确的
07-12
一、数据采集层:多源人脸数据获取 该层负责从不同设备 / 渠道采集人脸原始数据,为后续模型训练与识别提供基础样本,核心功能包括: 1. 多设备适配采集 实时摄像头采集: 调用计算机内置摄像头(或外接 USB 摄像头),通过OpenCV的VideoCapture接口实时捕获视频流,支持手动触发 “拍照”(按指定快捷键如Space)或自动定时采集(如每 2 秒采集 1 张),采集时自动框选人脸区域(通过Haar级联分类器初步定位),确保样本聚焦人脸。 支持采集参数配置:可设置采集分辨率(如 640×480、1280×720)、图像格式(JPG/PNG)、单用户采集数量(如默认采集 20 张,确保样本多样性),采集过程中实时显示 “已采集数量 / 目标数量”,避免样本不足。 本地图像 / 视频导入: 支持批量导入本地人脸图像文件(支持 JPG、PNG、BMP 格式),自动过滤非图像文件;导入视频文件(MP4、AVI 格式)时,可按 “固定帧间隔”(如每 10 帧提取 1 张图像)或 “手动选择帧” 提取人脸样本,适用于无实时摄像头场景。 数据集对接: 支持接入公开人脸数据集(如 LFW、ORL),通过预设脚本自动读取数据集目录结构(按 “用户 ID - 样本图像” 分类),快速构建训练样本库,无需手动采集,降低系统开发与测试成本。 2. 采集过程辅助功能 人脸有效性校验:采集时通过OpenCV的Haar级联分类器(或MTCNN轻量级模型)实时检测图像中是否包含人脸,若未检测到人脸(如遮挡、侧脸角度过大),则弹窗提示 “未识别到人脸,请调整姿态”,避免无效样本存入。 样本标签管理:采集时需为每个样本绑定 “用户标签”(如姓名、ID 号),支持手动输入标签或从 Excel 名单批量导入标签(按 “标签 - 采集数量” 对应),采集完成后自动按 “标签 - 序号” 命名文件(如 “张三
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值